Search Unity

  1. Unity 2019.1 is now released.
    Dismiss Notice

iBoxDB -Lightweight Embedded Database

Discussion in 'Assets and Asset Store' started by Bruce3D, Dec 13, 2013.

  1. Bruce3D

    Bruce3D

    Joined:
    Sep 6, 2013
    Posts:
    54
    iBoxDB.NET is a lightweight and pure .net database, compatible with Unity. it can help developers to save and load complex data with high efficiency.


    Why iBoxDB?
    iBoxDB includes almost all traditional database's features, and simplifies it, the footprint is less than 200KB.

    32bit, 64bit, ARM, x86, systems are shared the same library,users don't need to do any modification before compilation.

    Embeddable, data can be saved locally, and don't need the System.Data library.

    Replicable, updated data can be replicated from server to clinet or opposite.

    Speed, benchmark test shows the CRUD methods as fast as native C++ database. and NO C pointer it might modify application's main memory directly

    Memory saver, iBoxDB loads data when it's required. developers don't need to load all data to memory when game's started, it will save many memories.

    NoSQL, 'insert' 'update' operations don't need to write SQL.

    CS and JS languages are supported


    Install
    copy iBoxDB.NET2.dll to Assets/Plugins
    No dependencies.

    Download
    http://www.iboxdb.com/
    The zip file includes a demo.
     
    Last edited: Jul 24, 2017
    EMGPY likes this.
  2. Bruce3D

    Bruce3D

    Joined:
    Sep 6, 2013
    Posts:
    54
    Updated v1.6.5 compatible with the new phone features of Unity3D 4.3

    Install
    copy iBoxDB.net2.dll to Assets/Plugins
    No dependencies.
     
    Last edited: Nov 4, 2017
  3. Bruce3D

    Bruce3D

    Joined:
    Sep 6, 2013
    Posts:
    54
    iBoxDB.NET v1.7 Released
    What's new
    UpdateIncrement
    Selecting Tracer
     
    Last edited: Nov 4, 2017
  4. Jacob-Williams

    Jacob-Williams

    Joined:
    Jan 30, 2009
    Posts:
    267
    I am surprised there hasn't been any traction on this thread. I downloaded this last night to use as an item database for a game I am working on, and it's incredibly fast and powerful. This is a great solution for those looking to get away from a strict SQL syntax and have a database that "just works". I haven't built anything with it just yet, but I am excited about using Linq to grab database objects - it's going to be a huge help. Great job, Bruce - keep up the good work!
     
  5. bjornrun

    bjornrun

    Joined:
    Oct 29, 2013
    Posts:
    87
    Support for WebPlayer? Home page says support for in-memory DB, so it seems possible...
    How to add a new backend - for example remote storage?
    The dlls included in the download (eg. Lib/NetDB/iBoxDB.dll), are they built from the provided source?
     
  6. ZJP

    ZJP

    Joined:
    Jan 22, 2010
    Posts:
    2,646
    Thanks. Bookmarked. ;)
     
  7. GuardianArchangelJohn

    GuardianArchangelJohn

    Joined:
    May 3, 2014
    Posts:
    48
    I tried getting this working with 4.5.5 on Unity Basic on a Windows Store Universal 8.1 app using the .NET 2 dll and I get several errors related to methods in System.IO being referenced but not available. Any ideas? I target .NET 2 instead of Subset as well.
     
  8. Bruce3D

    Bruce3D

    Joined:
    Sep 6, 2013
    Posts:
    54
    Updated, Compatible with Windows Store App 8.1
     
    Last edited: Nov 4, 2017
  9. jason-fisher

    jason-fisher

    Joined:
    Mar 19, 2014
    Posts:
    133
    A multi-threaded benchmark that compares dictionaries, hash tables, iBoxDB and SQLite would go a long way.
     
  10. zyzyx

    zyzyx

    Joined:
    Jul 9, 2012
    Posts:
    222
    Is this compatible with android and ios?
     
  11. jason-fisher

    jason-fisher

    Joined:
    Mar 19, 2014
    Posts:
    133
    Yes, iBoxDB is written in C# and Java. The C# DLL will run on either. You can also run the Java version on Android, but I'm not exactly sure how you would integrate that into Unity.
     
  12. zyzyx

    zyzyx

    Joined:
    Jul 9, 2012
    Posts:
    222
    Thanks!
    Are there tools to quickly inspect dbs or do I have to write my own?
     
  13. jason-fisher

    jason-fisher

    Joined:
    Mar 19, 2014
    Posts:
    133
    haven't gotten that far, but I thought I saw the binary format described in the docs somewhere
     
  14. Bruce3D

    Bruce3D

    Joined:
    Sep 6, 2013
    Posts:
    54
    WebGL(Preview) iBoxDB on Chrome
    5.0p1 publishing settings -> enable exceptions : FULL ->Build.
    http://www.iboxdb.com/
    js.png
     
    jason-fisher likes this.
  15. ZJP

    ZJP

    Joined:
    Jan 22, 2010
    Posts:
    2,646
    This is, maybe, the 'problem' : no Unity examples. :(
     
  16. mowentian

    mowentian

    Joined:
    Dec 25, 2014
    Posts:
    3
    Unity example is UnityDBCS
     
    ZJP likes this.
  17. mowentian

    mowentian

    Joined:
    Dec 25, 2014
    Posts:
    3
    sorry, but i got problems work with ios il2cpp on unity version 5.0.0f4.
    while running the example, i got following error logs, wish you will help me, thanks:

    Initialize engine version: 5.0.0f4 (5b98b70ebeb9)

    ArgumentException: An element with the same key already exists in the dictionary.

    at Boo.Lang.Runtime.DynamicDispatching.Dispatcher.EndInvoke (IAsyncResult result) [0x00000] in <filename unknown>:0

    at Boo.Lang.Runtime.DynamicDispatching.Dispatcher.EndInvoke (IAsyncResult result) [0x00000] in <filename unknown>:0

    at Boo.Lang.Runtime.DynamicDispatching.Dispatcher.EndInvoke (IAsyncResult result) [0x00000] in <filename unknown>:0

    at Boo.Lang.Runtime.DynamicDispatching.Dispatcher.EndInvoke (IAsyncResult result) [0x00000] in <filename unknown>:0

    at Boo.Lang.Runtime.DynamicDispatching.Dispatcher.EndInvoke (IAsyncResult result) [0x00000] in <filename unknown>:0

    at iBoxDB.ByteCodes.Class51..ctor () [0x00000] in <filename unknown>:0

    at iBoxDB.ByteCodes.Class4.method_2 (Interface2 interface2_0) [0x00000] in <filename unknown>:0

    at Boo.Lang.Runtime.DynamicDispatching.Dispatcher.EndInvoke (IAsyncResult result) [0x00000] in <filename unknown>:0

    at Boo.Lang.Runtime.DynamicDispatching.Dispatcher.EndInvoke (IAsyncResult result) [0x00000] in <filename unknown>:0

    at Boo.Lang.Runtime.DynamicDispatching.Dispatcher.EndInvoke (IAsyncResult result) [0x00000] in <filename unknown>:0

    at Boo.Lang.Runtime.DynamicDispatching.Dispatcher.EndInvoke (IAsyncResult result) [0x00000] in <filename unknown>:0

    at iBoxDB.ByteCodes.Class134.method_0 () [0x00000] in <filename unknown>:0

    at iBoxDB.ByteCodes.Class134.method_1 () [0x00000] in <filename unknown>:0

    at iBoxDB.ByteCodes.Class140..ctor (iBoxDB.ByteCodes.Class134 class134_1) [0x00000] in <filename unknown>:0

    at iBoxDB.ByteCodes.Class134.GetEnumerator () [0x00000] in <filename unknown>:0

    at SqoDemoRunner.Update () [0x00000] in <filename unknown>:0

    at Boo.Lang.Runtime.DynamicDispatching.Dispatcher.EndInvoke (IAsyncResult result) [0x00000] in <filename unknown>:0

    at Boo.Lang.Runtime.DynamicDispatching.Dispatcher.EndInvoke (IAsyncResult result) [0x00000] in <filename unknown>:0

    at SqoDemoRunner.Update () [0x00000] in <filename unknown>:0

    at Boo.Lang.Runtime.DynamicDispatching.Dispatcher.EndInvoke (IAsyncResult result) [0x00000] in <filename unknown>:0

    at SqoDemoRunner.Update () [0x00000] in <filename unknown>:0

    at iBoxDB.LocalServer.IBox.SelectCount (System.String QL, System.Object[] arguments) [0x00000] in <filename unknown>:0

    at iBoxDB.LocalServer.AutoBox.SelectCount (System.String QL, System.Object[] arguments) [0x00000] in <filename unknown>:0

    at UnityDBCS.Start () [0x00000] in <filename unknown>:0

    at System.Linq.jvm.Runner.<.cctor>b__0 (System.Reflection.MethodInfo m) [0x00000] in <filename unknown>:0

    System.Linq.jvm.Runner:<.cctor>b__0(MethodInfo)


    (Filename: currently not available on il2cpp Line: -1)
     
  18. Bruce3D

    Bruce3D

    Joined:
    Sep 6, 2013
    Posts:
    54
    use 5.0P2+ http://unity3d.com/unity/qa/patch-releases
     
    Last edited: Apr 3, 2016
  19. aigam

    aigam

    Joined:
    Dec 31, 2005
    Posts:
    170
    Great project!
    Thanks
     
  20. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    2,012
    Hi Bruce,

    I have a few questions:
    1. In your example UnityDBCS, I don't see any db.Close() or release, can you queue up multiple queries for performance boosts? What's the most efficient way to do, say 1000 queries?
    2. In this line db.Select<Player>("from Players where Score >= ? order by Score desc", 0), why the '?', in mySQL I can do "from Players where Score >= 0 order by Score desc" (I think)
    3. Is the file format compatible with SQLite? I'd like to use Azure Sqlite Store synch.
     
    Last edited: May 22, 2015
  21. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    2,012
    Don't know how to multithread iBox so I did it linear.
    x100k players insert in iBox takes 1.3 seconds
    x100k Dictionary <int, Player> add it takes 0.01 seconds, same for hashtable
    so it's a 100 fold slower, how does it compare to sqlite? Don't know yet as I haven't gotten around yet to adding #-sqlite to a unity project. Have you?

    UPDATE: I added the excellent SQLite4Unity and did a similar benchmark with 100k insert. Time is 1.6 seconds inside a transaction.
     
    Last edited: May 22, 2015
  22. Bruce3D

    Bruce3D

    Joined:
    Sep 6, 2013
    Posts:
    54
    1.using GetDatabase().Dispose() to close the DB is the first choice,but not necessary for ACID DB.
    Each query has its own context the Box created by application's code, the DB doesn't queue it.

    2. use '?' to prevent SQL injection

    3. not compatible with SQLite but as most NoSQL DB, iBoxDB supports hot distribution with transactions by using the IBoxRecycler interface. details in iBoxDB.cs-MasterMasterSlave.
     
  23. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    2,012
    Thanks for the replies Bruce.
    1. In sqlite, if I want to speed things up I box my queries in a transaction. Is there such thing in iBox?
    2. Can ? be replaced by variable names and then Bind the values by name instead of listing the args[] at the end of the query?
    3. Can iBoxRecycler be used in the Azure SQlite auto synch?

     
    Last edited: May 22, 2015
  24. Bruce3D

    Bruce3D

    Joined:
    Sep 6, 2013
    Posts:
    54
    1. Packaging operations into a transaction is an universal solution for speed up, but only works with independent operation. iBoxDB prefers using multiple threads with multiple Boxes.

    2.In zip-/EXSrc/NET/Query/BoxQueryHelper.cs has a helper class can be used to bind name, 'Where( "GameType==?GT") ... .SetArg("?GT", "ACT") ...', users can make any style of helper class.

    3.IBoxRecycler can be used to make private cross platform synchronizing service easily, but not compatible with SQLite interface.
     
  25. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    2,012
    1. ex of non Independent is insert and querry?, and by thread boxes, do you mean:
      Code (CSharp):
      1. this.StartCoroutineAsync(BoxQuerry1());
      2. this.StartCoroutineAsync(BoxQuerry2());
      3. etc...
      4. Ienumerator BoxQueery()
      5. {
      6.   using(var box = db.Cube())
      7.   {                          
      8.      //select, insert, update, delete ...
      9.      var result = box.Commit();
      10.   }
      11. }
    2. System.Dynamic does not exist in System, must be a .Net thing, also wouldn't dynamic language runtime be a problem with IL2CPP?
    3. Do you have an example handy?
     
  26. Bruce3D

    Bruce3D

    Joined:
    Sep 6, 2013
    Posts:
    54
    1.Yes, tran_1:if value>100 then insert(), tran_2:if value>100 then rollback, this two transactions can't be packaged in one.
    2.iBoxDB supports many platforms, if the local platform doesn't have the class, remove the line.
    3.First, log all updates. the following code uses the Debug.Log() to log Boxes.
    Code (CSharp):
    1. public class Base64Recycler: IBoxRecycler{
    2.         public void OnReceived (Socket socket, BoxData outBox, bool normal)
    3.         {
    4.             if (socket.DestAddress != long.MaxValue)
    5.             {
    6.                 var data = Convert.ToBase64String(outBox.ToBytes());
    7.                 Debug.Log(data);
    8.             }
    9.         }
    10.         public void Dispose ()
    11.         {
    12.         }
    13. }
    Second, Open() with Base64Recycler.
    Code (CSharp):
    1. DB server = new DB(10);
    2. server.GetConfig ().EnsureTable<Player>("Players", "ID");
    3. server.SetBoxRecycler(new Base64Recycler());
    4.  
    5. auto = server.Open();
    Third, update data, example auto.Insert("Players", player);
    Fourth, create a synch service, for example here "http://forum.unity3d.com/", then post the logs here.
    Fifth, read from here to synchronize the devices when app's starting
    Code (CSharp):
    1. foreach: x = from http://forum.unity3d.com/...
    2. var sbox = new BoxData(Convert.FromBase64String(x));
    3. var cr = sbox.MasterReplicate(auto.GetDatabase());
    if had many devices and working at same time, use GUID or snowflake-like-UUID as Table ID.
     
    Last edited: Nov 4, 2017
  27. ZJP

    ZJP

    Joined:
    Jan 22, 2010
    Posts:
    2,646
    Hi,

    The default name of the base is "db3.box". it's there a way to change this name?
     
  28. Bruce3D

    Bruce3D

    Joined:
    Sep 6, 2013
    Posts:
    54
    has 2 ways
    1.All names with same prefix
    Code (CSharp):
    1. DB.Root (Application.persistentDataPath);
    2. BoxFileStreamConfig.RootPath += "MyApp_";
    2. Customize the name
    Code (CSharp):
    1. public class MyServer : LocalDatabaseServer
    2. {
    3.         protected override string GetNameByAddr (long address)
    4.         {
    5.             switch (address) {
    6.             case 10:
    7.                 return "AppDB10.xdb";
    8.             }
    9.             return base.GetNameByAddr (address);
    10.         }
    11.  
    12.         protected override DatabaseConfig BuildDatabaseConfig (long address)
    13.         {
    14.             switch (address) {
    15.             case 10:
    16.                 var fc = new BoxFileStreamConfig ();
    17.                 fc.EnsureTable<Player> ("Players", "ID");
    18.                 return fc;
    19.             }
    20.             return null;
    21.         }
    22. }
    23.  
    24. var appdb = (new MyServer()).GetInstance(10);
     
    Last edited: Nov 4, 2017
  29. ZJP

    ZJP

    Joined:
    Jan 22, 2010
    Posts:
    2,646
    Thanks for the reply. :cool:
     
  30. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    2,012
    Does your replicator converts the database into a string64 and back? Like database serialization?

    I see you have a memory mapped file mode which seems very fast, how resilient is it to forced app shut down like it is the case on ios? Does the data get elegantly truncated? not-so-elegantly corrupted?
     
    Last edited: Jun 3, 2015
  31. Bruce3D

    Bruce3D

    Joined:
    Sep 6, 2013
    Posts:
    54
    1. Yes.
    2. The default mode isn't memory mapped file, i'm glad someone understands the limitation of mmf. mmf was used for cache purpose or deployed on a highly stable server.
     
  32. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    2,012
    Cool, I'll leave it to default on app, I use it as embeded db, like sqlite.

    More questions:
    I'm trying to automate ID increment in your unity example so I add a server config like such: server.GetConfig().EnsureUpdateIncrementIndex<Player>("Players", "ID"); but this is returning an error "
    UnexpectedException: DB:UpdateIncrementContract Index ID" What's the right way to have ID be a key, index and auto increment?
    (for index I use server.GetConfig().EnsureIndex<Player>("Players", "Score","Name"); )

    Also what are threadcount and batchcount I see in the database setup?
     
  33. Bruce3D

    Bruce3D

    Joined:
    Sep 6, 2013
    Posts:
    54
    use NewId( x, 1) to get the increasing value, set the ID = box.NewId(x,1).
    UpdateIncrement is different from AutoIncrement. UpdateIncrement will increase the value when record is inserted or updated, AutoIncrement only be triggered by Insert. iBoxDB doesn't support AutoIncrement because it has NewId(),
    threadcount and batchcount are used to test the DB, not belong to the DB.
    Code (CSharp):
    1. void Test(){
    2.   for( var b=0; b<batchcount ; b++){
    3.      box.....
    4.   }
    5.   box.commit();
    6. }
    7.  
    8. for( var t=0; t<threadcount; t++){
    9.   AddToThreadPool(Test);
    10. }
    11.  
     
    Last edited: Nov 4, 2017
  34. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    2,012
    Gotcha on the ID, Why don't you support AutoIncrement and force use of explicit call?
    Also the social graph data type is interesting, do you have example of how to create and access that?
     
  35. Bruce3D

    Bruce3D

    Joined:
    Sep 6, 2013
    Posts:
    54
    Here has another style of AutoIncrement, put the explicit call in the constructor
    Code (CSharp):
    1. class MyClass{
    2.    public MyClass(){ // Default Constructor for Select }
    3.    public MyClass(Box box){
    4.      //AutoIncrement Constructor for Insert
    5.      this.ID = box.NewID( x, 1);
    6.    }
    7. }
     
    Last edited: Nov 4, 2017
    laurentlavigne likes this.
  36. rodsordi

    rodsordi

    Joined:
    Feb 19, 2014
    Posts:
    2
    Is it possible to work with relations between objects?
     
  37. Bruce3D

    Bruce3D

    Joined:
    Sep 6, 2013
    Posts:
    54
    Use a Model with Box can wrap any type of relationship

    Code (CSharp):
    1. public class Model : IDisposable
    2. {
    3.      IBox box;
    4.      public Model()
    5.      {
    6.         box = db.Cube();
    7.      }
    8.      public void Dispose()
    9.      {
    10.          box.Dispose();
    11.      }
    12.      public User Find(long id)
    13.      {
    14.           User u = box
    15.              .Bind(typeof(User).Name, id)
    16.              .Select<User>();
    17.           if (u != null) { u.Owner = box; }
    18.           return u;
    19.      }
    20.      ...
    21. }
    22.  
    23. public class User
    24. {
    25.     [NotColumn]
    26.     internal IBox Owner;
    27.     public User()
    28.     {
    29.         Items = new Collection(this);
    30.     }
    31.      public long ID = 0;
    32.      public string Name;
    33.      Collection Items;
    34. }
    35.  
    36. public class Collection
    37. {
    38.    private User main;
    39.    public Collection(User main)
    40.    {
    41.       this.main = main;
    42.    }
    43.    public Item Add(Item item)
    44.    {
    45.       item.UserID = main.ID;
    46.       item.ItemID = main.Owner.NewId(1, 1);
    47.       main.Owner.Bind(typeof(Item).Name)
    48.               .Insert(item);
    49.             return item;
    50.     }
    51.     ...
    52. }
     
    Last edited: Nov 4, 2017
  38. Badult

    Badult

    Joined:
    Jan 28, 2014
    Posts:
    2
    Hi. Is it possible to load data from streamingAssetsPath?
    I get errors on Android when I change DB.Root() to streamingAssetsPath
     
    Last edited: Aug 19, 2015
  39. Bruce3D

    Bruce3D

    Joined:
    Sep 6, 2013
    Posts:
    54
    use class WWW()
    Code (CSharp):
    1. // create DB
    2. // copy the file to StreamingAssets, remove *.swp
    3. // use bytes(byte[]) to new()
    4. private IEnumerator Load ()
    5. {
    6.     if (Application.streamingAssetsPath.Contains ("://")) {
    7.         var filePath = Path.Combine (Application.streamingAssetsPath, "db3.box");
    8.         var www = new WWW (filePath);
    9.         yield return www;
    10.         db = new DB (www.bytes);      
    11.     } else {
    12.         DB.Root (Application.streamingAssetsPath);
    13.         db = new DB (3);
    14.     }
    15.     db.MinConfig().FileIncSize = 1;
    16.     auto = db.Open();
    17.      ...
    18.     DrawToString();
    19. }
    20.  
    21. _context =  "";
    22. StartCoroutine(Load());
    23. return;
    because it is compressed into the .apk file on Android.
    http://docs.unity3d.com/ScriptReference/Application-streamingAssetsPath.html
     
    Last edited: Nov 4, 2017
  40. Badult

    Badult

    Joined:
    Jan 28, 2014
    Posts:
    2
    Thank you very much.
    Is there any documentation or source code for us to learn iBoxDB?
     
  41. rimiki

    rimiki

    Joined:
    Dec 30, 2014
    Posts:
    102
    Is there any documentation to follow some steps to use idBoxDB with Unity 3D ?
     
  42. Bruce3D

    Bruce3D

    Joined:
    Sep 6, 2013
    Posts:
    54
    Hello rimiki
    It doesn't need to setup environment and connect, it works like a standard component, just new the class DB(), then use the AutoBox to update whatever data you wanted instead of XYZUV...
    the example in net2/UnityDBCS.cs, copy to the project with the only DLL, everything is done.
     
  43. rimiki

    rimiki

    Joined:
    Dec 30, 2014
    Posts:
    102
    At first I need to create database through sql server for example, right?
     
  44. rimiki

    rimiki

    Joined:
    Dec 30, 2014
    Posts:
    102
    Excuse me but I'm a beginner in Database, so I didn't understand a lot your answer.
     
  45. Bruce3D

    Bruce3D

    Joined:
    Sep 6, 2013
    Posts:
    54
    iBoxDB has a lightweight local db engine inside, cross platform supported. when new DB(x) is called, a database file will be created automatically. when EnsureTable() is called, a Table will be created automatically.
     
    Last edited: Nov 4, 2017
  46. zibas

    zibas

    Joined:
    Sep 15, 2010
    Posts:
    29
    Been having fun with iBoxDB. Very impressive! Is there a way to use the memory mapped files functionality in Unity? I'd like to avoid disk writes.
     
  47. Bruce3D

    Bruce3D

    Joined:
    Sep 6, 2013
    Posts:
    54
    HI,
    has 4 ways to avoid disk writes, for different purpose.
    1. use a normal container to store data
    Code (CSharp):
    1. WriteDataToTempList(....){  templist.Replace(...); }
    2. Flush(){
    3.   if ( templist.Count > 5 || templist.force )
    4.    templist.FlushToDB(db);
    5. }
    2. if it is a small DB, use Memory Mode
    Code (CSharp):
    1. Start(){
    2. byte[] data = ReadDBDataFromFile();
    3. server = new DB(data);
    4. ....
    5. }
    6.  
    7. Save(){
    8. byte[] data = server.GetBuffer();
    9. WriteDBDataToFile(data);
    10. }
    3. use two DBs, Memory and File
    Code (CSharp):
    1. public class MyAutoBox
    2. {
    3.   public DB.AutoBox memdb;
    4.   public DB.AutoBox db;
    5.  
    6.   public MyAutoBox()
    7.   {
    8.     DB memserver = new DB(new byte[0]);
    9.     //....
    10.     memdb = memserver.Open();
    11.  
    12.     DB server = new DB (1);
    13.     //....
    14.     db = server.Open ();
    15.   }
    16.  
    17.   public void Replace(...)
    18.   {
    19.       memdb.Replace(...)
    20.    }
    21.  
    22.   public T SelectKey(...)
    23.   {
    24.        var r =    memdb.SelectKey(...)
    25.        if ( r == null){  return db.SelectKey(...); }
    26.   }
    27.  
    28.    public T Select()
    29.    {
    30.        var memdata = memdb.Select();
    31.        var filedata = db.Select();
    32.        return CombinAndRemoveEqualID(memdata,filedata);
    33.    }
    34.  
    35.    public void Flush(){
    36.        FlushToInOneTransaction(memdb,db);                  
    37.    }
    38. }
    4 use C# to implement an MMF system.
    Code (CSharp):
    1. class MemoryLevel meml;
    2. class FileLevel filel;
    3. Override IBStream.Read() .Write() .Flush() methods
    4.  
    5. Write(...){
    6.    lock( x ){
    7.      meml.Write(...);
    8.    }
    9. }
    10. Read()
    11. {
    12.    var memdata = meml.Read();
    13.    var filedata = filel.Read();
    14.    return CombinMemory(memdata,filedata);
    15. }
    16.  
    17. Flush(){
    18.    lock( x ){
    19.     if ( meml.CacheSize > 1024*1024*10 || meml.force  ){
    20.       meml.FlushToFileInOneTransaction(filel);
    21.     }else return;
    22.    }
    23. }
    24.  
    25. IntervalFlush(Flush,1000);
    26.  
    27. public class MyMMFConfig : DatabaseConfig
    28. {
    29.    public override SwapType GetSwapType ()
    30.    {
    31.       //disable File Swap, the MemoryLevel as a Memory Swap
    32.       return SwapType.None;
    33.    }
    34.    public override IBStream CreateStream(string path, StreamAccess access)
    35.   {
    36.       return MyMMFIBStream(...);
    37.   }
    38.    public override bool ExistsStream(string path){ ...}
    39.  
    40. }
    41.  
    42. public class MyMMFServer : LocalDatabaseServer
    43. {
    44.     protected override DatabaseConfig BuildDatabaseConfig (long address)
    45.     {
    46.             switch (address) {
    47.             case 10:
    48.                 var fc = new MyMMFConfig ();
    49.                 fc.EnsureTable<Player> ("Players", "ID");
    50.                 return fc;
    51.             }
    52.             return null;
    53.     }
    54. }
    55. var appdb = (new MyMMFServer()).GetInstance(10);
    56.  
    BTW, MMF might lose data when poweroff.
     
    Last edited: Nov 4, 2017
    zibas likes this.
  48. zibas

    zibas

    Joined:
    Sep 15, 2010
    Posts:
    29
    Very helpful! Thank you!
     
  49. jimmyxu

    jimmyxu

    Joined:
    Oct 8, 2015
    Posts:
    2
    Hi, great work. I have a couple of questions:

    1) Can you provide an example on how to delete a DB (and an example on how to drop a table)?

    2) I tried storing objects that contain strings, Dictionary<string, string>, and Dictionary<string, obj> into the DB. I verified that the object, along with its strings are stored correctly, but none of the Dictionary fields can be stored/retrieved -- they come back as null when I fetch the object from the DB. Is this correct?

    Thanks!
     
  50. Bruce3D

    Bruce3D

    Joined:
    Sep 6, 2013
    Posts:
    54
    Hi,
    1 Delete DB, delete the files in Application.persistentDataPath or use iBoxDB.DBDebug.DDebug.DeleteDBFiles(idbFile).
    2 Drap Table, unsupported, the unstructured table can be used to store other things. and normally, the DB auto created in user's doesn't include the Table you have removed from codes.
    3 Complex Object, have to Cast the objects by yourself or delay initialize the ComplexObjects.
    Code (CSharp):
    1. public class StringDictionary
    2. {
    3.         public long ID;
    4.         public Dictionary<string, object> dict = new Dictionary<string, object>();
    5.         public byte[] moreClass ; // or MemoryStream
    6.  
    7.         public string this[string name]
    8.         {
    9.             get
    10.             {
    11.                 return (string)dict[name];
    12.             }
    13.             set
    14.             {
    15.                 dict[name] = value;
    16.             }
    17.         }
    18.  
    19.         public ComplexClass Complex
    20.         {
    21.             get
    22.             {
    23.                 return Convert(moreClass);
    24.             }
    25.             set
    26.             {
    27.                moreClass = Convert(value);
    28.             }
    29.         }
    30.  
    31. }
    http://www.iboxdb.com/
     
    Last edited: Nov 13, 2015