From 4a98e911b97a5d00d194a31260e9ba73c58447c7 Mon Sep 17 00:00:00 2001 From: mbdavid Date: Fri, 6 Feb 2015 11:39:47 -0200 Subject: [PATCH 01/96] Rename classes/method to be more like MongoDB official driver API --- LiteDB.Shell/Commands/Close.cs | 4 +- LiteDB.Shell/Commands/Comment.cs | 4 +- LiteDB.Shell/Commands/Help.cs | 6 +- LiteDB.Shell/Commands/Pretty.cs | 4 +- LiteDB.Shell/Commands/Quit.cs | 4 +- LiteDB.Shell/Commands/Spool.cs | 4 +- LiteDB.Shell/Program.cs | 8 +- .../Collections/LiteCollection.Delete.cs} | 54 ++++++++----- .../Collections/LiteCollection.Drop.cs} | 12 +-- .../Collections/LiteCollection.Find.cs} | 16 ++-- .../Collections/LiteCollection.Include.cs} | 6 +- .../Collections/LiteCollection.Index.cs} | 20 ++--- .../Collections/LiteCollection.Insert.cs} | 24 +++--- .../Collections/LiteCollection.Update.cs} | 22 ++--- .../Collections/LiteCollection.cs} | 20 +++-- .../GridFS/LiteFileInfo.cs} | 30 ++++--- .../GridFS}/LiteFileStream.cs | 20 ++--- .../GridFS/LiteGridFS.Delete.cs} | 10 +-- .../GridFS/LiteGridFS.Download.cs} | 10 +-- .../GridFS/LiteGridFS.Find.cs} | 26 +++--- LiteDB/Database/GridFS/LiteGridFS.Upload.cs | 81 +++++++++++++++++++ LiteDB/Database/GridFS/LiteGridFS.cs | 25 ++++++ .../LiteDatabase.cs} | 69 ++++++++++++---- LiteDB/{Engine => Database}/Tools/Bulk.cs | 6 +- LiteDB/{Engine => Database}/Tools/Info.cs | 2 +- .../{Engine => Database}/Tools/UserVersion.cs | 2 +- .../Engine/FileStorage/FileStorage.Upload.cs | 68 ---------------- LiteDB/Engine/FileStorage/FileStorage.cs | 25 ------ LiteDB/LiteDB.csproj | 41 +++++----- LiteDB/Properties/AssemblyInfo.cs | 9 +-- LiteDB/Query/Query.cs | 10 +-- LiteDB/Query/QueryAll.cs | 4 +- LiteDB/Query/QueryAnd.cs | 8 +- LiteDB/Query/QueryBetween.cs | 4 +- LiteDB/Query/QueryEquals.cs | 4 +- LiteDB/Query/QueryGreater.cs | 4 +- LiteDB/Query/QueryIn.cs | 4 +- LiteDB/Query/QueryLess.cs | 4 +- LiteDB/Query/QueryNot.cs | 4 +- LiteDB/Query/QueryOr.cs | 8 +- LiteDB/Query/QueryStartsWith.cs | 4 +- .../Commands/Collections/BaseCollection.cs | 6 +- LiteDB/Shell/Commands/Collections/Bulk.cs | 4 +- LiteDB/Shell/Commands/Collections/Count.cs | 4 +- LiteDB/Shell/Commands/Collections/Delete.cs | 4 +- LiteDB/Shell/Commands/Collections/Drop.cs | 4 +- .../Shell/Commands/Collections/DropIndex.cs | 4 +- .../Shell/Commands/Collections/EnsureIndex.cs | 4 +- LiteDB/Shell/Commands/Collections/Exec.cs | 10 +-- LiteDB/Shell/Commands/Collections/Find.cs | 4 +- LiteDB/Shell/Commands/Collections/Indexes.cs | 4 +- LiteDB/Shell/Commands/Collections/Insert.cs | 4 +- LiteDB/Shell/Commands/Collections/Update.cs | 4 +- LiteDB/Shell/Commands/Files/BaseFile.cs | 2 +- LiteDB/Shell/Commands/Files/Delete.cs | 6 +- LiteDB/Shell/Commands/Files/Download.cs | 6 +- LiteDB/Shell/Commands/Files/Find.cs | 10 +-- LiteDB/Shell/Commands/Files/Update.cs | 13 +-- LiteDB/Shell/Commands/Files/Upload.cs | 6 +- .../{IShellCommand.cs => ILiteCommand.cs} | 4 +- LiteDB/Shell/Commands/LiteCommandResult.cs | 69 ++++++++++++++++ LiteDB/Shell/Commands/Others/Dump.cs | 4 +- LiteDB/Shell/Commands/Others/Info.cs | 4 +- .../Shell/Commands/Others/ShowCollections.cs | 6 +- LiteDB/Shell/Commands/Transactions/Begin.cs | 4 +- LiteDB/Shell/Commands/Transactions/Commit.cs | 4 +- .../Shell/Commands/Transactions/Rollback.cs | 4 +- LiteDB/Shell/LiteShell.cs | 20 ++--- LiteDB/Utils/ConnectionString.cs | 2 +- LiteDB/Utils/DumpDatabase.cs | 6 +- LiteDB/Utils/LiteException.cs | 2 +- UnitTest/FindOrderTest.cs | 2 +- UnitTest/IncludeTest.cs | 4 +- UnitTest/LinqTest.cs | 4 +- UnitTest/PageTest.cs | 10 +-- UnitTest/PerfTest.cs | 8 +- UnitTest/StressTest.cs | 10 +-- UnitTest/Utils/Dump.cs | 4 +- UnitTest/VersionTest.cs | 4 +- WebShell/Commands/Help.cs | 4 +- WebShell/api.ashx | 2 +- 81 files changed, 560 insertions(+), 410 deletions(-) rename LiteDB/{Engine/Collections/Collection.Delete.cs => Database/Collections/LiteCollection.Delete.cs} (58%) rename LiteDB/{Engine/Collections/Collection.Drop.cs => Database/Collections/LiteCollection.Drop.cs} (74%) rename LiteDB/{Engine/Collections/Collection.Find.cs => Database/Collections/LiteCollection.Find.cs} (89%) rename LiteDB/{Engine/Collections/Collection.Include.cs => Database/Collections/LiteCollection.Include.cs} (79%) rename LiteDB/{Engine/Collections/Collection.Index.cs => Database/Collections/LiteCollection.Index.cs} (86%) rename LiteDB/{Engine/Collections/Collection.Insert.cs => Database/Collections/LiteCollection.Insert.cs} (77%) rename LiteDB/{Engine/Collections/Collection.Update.cs => Database/Collections/LiteCollection.Update.cs} (76%) rename LiteDB/{Engine/Collections/Collection.cs => Database/Collections/LiteCollection.cs} (73%) rename LiteDB/{Engine/FileStorage/FileEntry.cs => Database/GridFS/LiteFileInfo.cs} (79%) rename LiteDB/{Engine/FileStorage => Database/GridFS}/LiteFileStream.cs (86%) rename LiteDB/{Engine/FileStorage/FileStorage.Delete.cs => Database/GridFS/LiteGridFS.Delete.cs} (75%) rename LiteDB/{Engine/FileStorage/FileStorage.Download.cs => Database/GridFS/LiteGridFS.Download.cs} (81%) rename LiteDB/{Engine/FileStorage/FileStorage.Find.cs => Database/GridFS/LiteGridFS.Find.cs} (56%) create mode 100644 LiteDB/Database/GridFS/LiteGridFS.Upload.cs create mode 100644 LiteDB/Database/GridFS/LiteGridFS.cs rename LiteDB/{Engine/LiteEngine.cs => Database/LiteDatabase.cs} (67%) rename LiteDB/{Engine => Database}/Tools/Bulk.cs (89%) rename LiteDB/{Engine => Database}/Tools/Info.cs (96%) rename LiteDB/{Engine => Database}/Tools/UserVersion.cs (97%) delete mode 100644 LiteDB/Engine/FileStorage/FileStorage.Upload.cs delete mode 100644 LiteDB/Engine/FileStorage/FileStorage.cs rename LiteDB/Shell/Commands/{IShellCommand.cs => ILiteCommand.cs} (61%) create mode 100644 LiteDB/Shell/Commands/LiteCommandResult.cs diff --git a/LiteDB.Shell/Commands/Close.cs b/LiteDB.Shell/Commands/Close.cs index 25ba09a6e..9cf95d920 100644 --- a/LiteDB.Shell/Commands/Close.cs +++ b/LiteDB.Shell/Commands/Close.cs @@ -6,14 +6,14 @@ namespace LiteDB.Shell.Commands { - internal class Close : IShellCommand + internal class Close : ILiteCommand { public bool IsCommand(StringScanner s) { return s.Scan(@"close$").Length > 0; } - public void Execute(LiteEngine db, StringScanner s, Display display) + public void Execute(LiteDatabase db, StringScanner s, Display display) { db.Dispose(); } diff --git a/LiteDB.Shell/Commands/Comment.cs b/LiteDB.Shell/Commands/Comment.cs index eada1b1ec..28a3383b3 100644 --- a/LiteDB.Shell/Commands/Comment.cs +++ b/LiteDB.Shell/Commands/Comment.cs @@ -6,14 +6,14 @@ namespace LiteDB.Shell.Commands { - internal class Comment : IShellCommand + internal class Comment : ILiteCommand { public bool IsCommand(StringScanner s) { return s.Match(@"--"); } - public void Execute(LiteEngine db, StringScanner s, Display display) + public void Execute(LiteDatabase db, StringScanner s, Display display) { } } diff --git a/LiteDB.Shell/Commands/Help.cs b/LiteDB.Shell/Commands/Help.cs index a0ff42bc5..24a95fc0b 100644 --- a/LiteDB.Shell/Commands/Help.cs +++ b/LiteDB.Shell/Commands/Help.cs @@ -6,14 +6,14 @@ namespace LiteDB.Shell.Commands { - internal class Help : IShellCommand + internal class Help : ILiteCommand { public bool IsCommand(StringScanner s) { return s.Scan(@"help$").Length > 0; } - public void Execute(LiteEngine db, StringScanner s, Display d) + public void Execute(LiteDatabase db, StringScanner s, Display d) { d.WriteResult("Shell commands"); d.WriteResult("=============="); @@ -48,7 +48,7 @@ public void Execute(LiteEngine db, StringScanner s, Display d) d.WriteHelp("> db..find [top N]", "Show all documents. Can limit results in N documents"); d.WriteHelp("> db..find [top N] ", "Show filtered documents based on index search"); d.WriteHelp("> db..count ", "Show count rows according query filter"); - d.WriteHelp("> db..exec { Action }", "Execute C# code for each document based on filter."); + d.WriteHelp("> db..exec { Action }", "Execute C# code for each document based on filter."); d.WriteHelp("> db..ensureIndex [unique]", "Create a new index document field"); d.WriteHelp("> db..indexes", "List all indexes in this collection"); d.WriteHelp("> db..drop", "Drop collection and destroy all documents inside"); diff --git a/LiteDB.Shell/Commands/Pretty.cs b/LiteDB.Shell/Commands/Pretty.cs index a4c6b9362..c4d8e76e5 100644 --- a/LiteDB.Shell/Commands/Pretty.cs +++ b/LiteDB.Shell/Commands/Pretty.cs @@ -6,14 +6,14 @@ namespace LiteDB.Shell.Commands { - internal class Pretty : IShellCommand + internal class Pretty : ILiteCommand { public bool IsCommand(StringScanner s) { return s.Scan(@"pretty\s*").Length > 0; } - public void Execute(LiteEngine db, StringScanner s, Display display) + public void Execute(LiteDatabase db, StringScanner s, Display display) { display.Pretty = !(s.Scan(@"off\s*").Length > 0); } diff --git a/LiteDB.Shell/Commands/Quit.cs b/LiteDB.Shell/Commands/Quit.cs index 94a6b0fc9..63a559d0f 100644 --- a/LiteDB.Shell/Commands/Quit.cs +++ b/LiteDB.Shell/Commands/Quit.cs @@ -6,14 +6,14 @@ namespace LiteDB.Shell.Commands { - internal class Quit : IShellCommand + internal class Quit : ILiteCommand { public bool IsCommand(StringScanner s) { return s.Match(@"(quit|exit)$"); } - public void Execute(LiteEngine db, StringScanner s, Display display) + public void Execute(LiteDatabase db, StringScanner s, Display display) { Environment.Exit(0); } diff --git a/LiteDB.Shell/Commands/Spool.cs b/LiteDB.Shell/Commands/Spool.cs index 66cd35265..ab925cd2f 100644 --- a/LiteDB.Shell/Commands/Spool.cs +++ b/LiteDB.Shell/Commands/Spool.cs @@ -7,7 +7,7 @@ namespace LiteDB.Shell.Commands { - internal class Spool : IShellCommand + internal class Spool : ILiteCommand { private TextWriter _writer; @@ -16,7 +16,7 @@ public bool IsCommand(StringScanner s) return s.Scan(@"spo(ol)?\s*").Length > 0; } - public void Execute(LiteEngine db, StringScanner s, Display display) + public void Execute(LiteDatabase db, StringScanner s, Display display) { if(s.Scan("false|off").Length > 0 && _writer != null) { diff --git a/LiteDB.Shell/Program.cs b/LiteDB.Shell/Program.cs index 2df0f4c4e..1e350cd2e 100644 --- a/LiteDB.Shell/Program.cs +++ b/LiteDB.Shell/Program.cs @@ -25,7 +25,7 @@ static void Main(string[] args) { try { - shell.Engine = new LiteEngine(args[0]); + shell.Database = new LiteDatabase(args[0]); } catch (Exception ex) { @@ -44,12 +44,12 @@ static void Main(string[] args) { if (cmd.StartsWith("open ")) { - if (shell.Engine != null) + if (shell.Database != null) { - shell.Engine.Dispose(); + shell.Database.Dispose(); } - shell.Engine = new LiteEngine(cmd.Substring(5)); + shell.Database = new LiteDatabase(cmd.Substring(5)); } else { diff --git a/LiteDB/Engine/Collections/Collection.Delete.cs b/LiteDB/Database/Collections/LiteCollection.Delete.cs similarity index 58% rename from LiteDB/Engine/Collections/Collection.Delete.cs rename to LiteDB/Database/Collections/LiteCollection.Delete.cs index 73f0e63bc..94f12bb11 100644 --- a/LiteDB/Engine/Collections/Collection.Delete.cs +++ b/LiteDB/Database/Collections/LiteCollection.Delete.cs @@ -7,15 +7,15 @@ namespace LiteDB { - public partial class Collection + public partial class LiteCollection { /// - /// Delete a document in collection using Document Id - returns false if not found document + /// Remove an document in collection using Document Id - returns false if not found document /// public virtual bool Delete(object id) { // start transaction - _engine.Transaction.Begin(); + this.Database.Transaction.Begin(); try { @@ -24,37 +24,40 @@ public virtual bool Delete(object id) // if collection not exists, document do not exists too if (col == null) { - _engine.Transaction.Abort(); + this.Database.Transaction.Abort(); return false; } // find indexNode using PK index - var node = _engine.Indexer.FindOne(col.PK, id); + var node = this.Database.Indexer.FindOne(col.PK, id); // if not found, abort transaction and returns false if (node == null) { - _engine.Transaction.Abort(); + this.Database.Transaction.Abort(); return false; } - this.Delete(col, node); + this.Remove(col, node); - _engine.Transaction.Commit(); + this.Database.Transaction.Commit(); return true; } catch (Exception ex) { - _engine.Transaction.Rollback(); + this.Database.Transaction.Rollback(); throw ex; } } + /// + /// Remove all document based on a Query object. Returns removed document counts + /// public virtual int Delete(Query query) { // start transaction - _engine.Transaction.Begin(); + this.Database.Transaction.Begin(); try { @@ -63,51 +66,60 @@ public virtual int Delete(Query query) // no collection, no document - abort trans if (col == null) { - _engine.Transaction.Abort(); + this.Database.Transaction.Abort(); return 0; } var count = 0; // find nodes - var nodes = query.Run(_engine, col); + var nodes = query.Run(this.Database, col); foreach (var node in nodes) { - this.Delete(col, node); + this.Remove(col, node); count++; } // no deletes, just abort transaction (no writes) if (count == 0) { - _engine.Transaction.Abort(); + this.Database.Transaction.Abort(); return 0; } - _engine.Transaction.Commit(); + this.Database.Transaction.Commit(); return count; } catch (Exception ex) { - _engine.Transaction.Rollback(); + this.Database.Transaction.Rollback(); throw ex; } } /// - /// Delete document based on a LINQ query. + /// Remove all document based on a LINQ query. Returns removed document counts /// public virtual int Delete(Expression> predicate) { return this.Delete(QueryVisitor.Visit(predicate)); } - internal virtual void Delete(CollectionPage col, IndexNode node) + /// + /// Remove all documents on this collection. Returns removed document counts + /// + /// + public virtual int DeleteAll() + { + return this.Delete(Query.All()); + } + + internal virtual void Remove(CollectionPage col, IndexNode node) { // read dataBlock - var dataBlock = _engine.Data.Read(node.DataBlock, false); + var dataBlock = this.Database.Data.Read(node.DataBlock, false); // lets remove all indexes that point to this in dataBlock for (byte i = 0; i < col.Indexes.Length; i++) @@ -116,12 +128,12 @@ internal virtual void Delete(CollectionPage col, IndexNode node) if (!index.IsEmpty) { - _engine.Indexer.Delete(index, dataBlock.IndexRef[i]); + this.Database.Indexer.Delete(index, dataBlock.IndexRef[i]); } } // remove object data - _engine.Data.Delete(col, node.DataBlock); + this.Database.Data.Delete(col, node.DataBlock); } } } diff --git a/LiteDB/Engine/Collections/Collection.Drop.cs b/LiteDB/Database/Collections/LiteCollection.Drop.cs similarity index 74% rename from LiteDB/Engine/Collections/Collection.Drop.cs rename to LiteDB/Database/Collections/LiteCollection.Drop.cs index 0386a27d5..9a07f04dd 100644 --- a/LiteDB/Engine/Collections/Collection.Drop.cs +++ b/LiteDB/Database/Collections/LiteCollection.Drop.cs @@ -6,7 +6,7 @@ namespace LiteDB { - public partial class Collection + public partial class LiteCollection { /// /// Drop a collection deleting all documents and indexes @@ -14,7 +14,7 @@ public partial class Collection public virtual bool Drop() { // start transaction - _engine.Transaction.Begin(); + this.Database.Transaction.Begin(); try { @@ -23,7 +23,7 @@ public virtual bool Drop() // if collection not exists, no drop if (col == null) { - _engine.Transaction.Abort(); + this.Database.Transaction.Abort(); return false; } @@ -31,17 +31,17 @@ public virtual bool Drop() this.Delete(Query.All()); // delete all pages/indexes heads - _engine.Collections.Drop(col); + this.Database.Collections.Drop(col); _pageID = uint.MaxValue; - _engine.Transaction.Commit(); + this.Database.Transaction.Commit(); return true; } catch (Exception ex) { - _engine.Transaction.Rollback(); + this.Database.Transaction.Rollback(); throw ex; } } diff --git a/LiteDB/Engine/Collections/Collection.Find.cs b/LiteDB/Database/Collections/LiteCollection.Find.cs similarity index 89% rename from LiteDB/Engine/Collections/Collection.Find.cs rename to LiteDB/Database/Collections/LiteCollection.Find.cs index b3b113a6e..4c94f6000 100644 --- a/LiteDB/Engine/Collections/Collection.Find.cs +++ b/LiteDB/Database/Collections/LiteCollection.Find.cs @@ -7,7 +7,7 @@ namespace LiteDB { - public partial class Collection + public partial class LiteCollection { /// /// Find a document using Document Id. Returns null if not found. @@ -20,11 +20,11 @@ public T FindById(object id) if (col == null) return default(T); - var node = _engine.Indexer.FindOne(col.PK, id); + var node = this.Database.Indexer.FindOne(col.PK, id); if (node == null) return default(T); - var dataBlock = _engine.Data.Read(node.DataBlock, true); + var dataBlock = this.Database.Data.Read(node.DataBlock, true); var doc = BsonSerializer.Deserialize(dataBlock.Key, dataBlock.Buffer); @@ -63,11 +63,11 @@ public IEnumerable Find(Query query) if (col == null) yield break; - var nodes = query.Run(_engine, col); + var nodes = query.Run(this.Database, col); foreach (var node in nodes) { - var dataBlock = _engine.Data.Read(node.DataBlock, true); + var dataBlock = this.Database.Data.Read(node.DataBlock, true); var doc = BsonSerializer.Deserialize(dataBlock.Key, dataBlock.Buffer); @@ -91,7 +91,7 @@ public IEnumerable Find(Expression> predicate) /// /// Returns all documents inside collection. /// - public IEnumerable All() + public IEnumerable FindAll() { return this.Find(Query.All()); } @@ -119,7 +119,7 @@ public int Count(Query query) if (col == null) return 0; - return query.Run(_engine, col).Count(); + return query.Run(this.Database, col).Count(); } /// @@ -141,7 +141,7 @@ public bool Exists(Query query) if (col == null) return false; - return query.Run(_engine, col).FirstOrDefault() != null; + return query.Run(this.Database, col).FirstOrDefault() != null; } /// diff --git a/LiteDB/Engine/Collections/Collection.Include.cs b/LiteDB/Database/Collections/LiteCollection.Include.cs similarity index 79% rename from LiteDB/Engine/Collections/Collection.Include.cs rename to LiteDB/Database/Collections/LiteCollection.Include.cs index d87bce5bc..db853b59a 100644 --- a/LiteDB/Engine/Collections/Collection.Include.cs +++ b/LiteDB/Database/Collections/LiteCollection.Include.cs @@ -6,17 +6,17 @@ namespace LiteDB { - public partial class Collection + public partial class LiteCollection { /// /// Run an include action in each document returned by Find(), FindById(), FindOne() and All() methods. Useful for load reference documents when nedded. /// Returns a new Collection with this action included /// - public Collection Include(Action action) + public LiteCollection Include(Action action) { if (action == null) throw new ArgumentNullException("action"); - var col = new Collection(_engine, Name); + var col = new LiteCollection(this.Database, Name); col._pageID = _pageID; col._includes.AddRange(_includes); diff --git a/LiteDB/Engine/Collections/Collection.Index.cs b/LiteDB/Database/Collections/LiteCollection.Index.cs similarity index 86% rename from LiteDB/Engine/Collections/Collection.Index.cs rename to LiteDB/Database/Collections/LiteCollection.Index.cs index 65a80ae45..60c370c03 100644 --- a/LiteDB/Engine/Collections/Collection.Index.cs +++ b/LiteDB/Database/Collections/LiteCollection.Index.cs @@ -9,7 +9,7 @@ namespace LiteDB { - public partial class Collection + public partial class LiteCollection { /// /// Create a new permanent index in all documents inside this collections if index not exists already. Returns true if index was created or false if already exits @@ -37,14 +37,14 @@ public virtual bool EnsureIndex(string field, bool unique = false) }; // start transaction - _engine.Transaction.Begin(); + this.Database.Transaction.Begin(); try { // if not collection yet, create a new now if (col == null) { - col = _engine.Collections.Add(this.Name); + col = this.Database.Collections.Add(this.Name); _pageID = col.PageID; } @@ -52,15 +52,15 @@ public virtual bool EnsureIndex(string field, bool unique = false) var slot = col.GetFreeIndex(); // create index head - var index = _engine.Indexer.CreateIndex(col.Indexes[slot]); + var index = this.Database.Indexer.CreateIndex(col.Indexes[slot]); index.Field = field; index.Unique = unique; // read all objects (read from PK index) - foreach (var node in _engine.Indexer.FindAll(col.PK)) + foreach (var node in this.Database.Indexer.FindAll(col.PK)) { - var dataBlock = _engine.Data.Read(node.DataBlock, true); + var dataBlock = this.Database.Data.Read(node.DataBlock, true); // read object var doc = BsonSerializer.Deserialize(dataBlock.Key, dataBlock.Buffer); @@ -68,7 +68,7 @@ public virtual bool EnsureIndex(string field, bool unique = false) // adding index var key = BsonSerializer.GetFieldValue(doc, field); - var newNode = _engine.Indexer.AddNode(index, key); + var newNode = this.Database.Indexer.AddNode(index, key); // adding this new index Node to indexRef dataBlock.IndexRef[slot] = newNode.Position; @@ -80,11 +80,11 @@ public virtual bool EnsureIndex(string field, bool unique = false) dataBlock.Page.IsDirty = true; } - _engine.Transaction.Commit(); + this.Database.Transaction.Commit(); } catch (Exception ex) { - _engine.Transaction.Rollback(); + this.Database.Transaction.Rollback(); throw ex; } @@ -108,7 +108,7 @@ public virtual bool EnsureIndex(Expression> property, bool unique /// public IEnumerable GetIndexes() { - _engine.Transaction.AvoidDirtyRead(); + this.Database.Transaction.AvoidDirtyRead(); var col = this.GetCollectionPage(false); diff --git a/LiteDB/Engine/Collections/Collection.Insert.cs b/LiteDB/Database/Collections/LiteCollection.Insert.cs similarity index 77% rename from LiteDB/Engine/Collections/Collection.Insert.cs rename to LiteDB/Database/Collections/LiteCollection.Insert.cs index ab9a2ae85..733cbf608 100644 --- a/LiteDB/Engine/Collections/Collection.Insert.cs +++ b/LiteDB/Database/Collections/LiteCollection.Insert.cs @@ -6,7 +6,7 @@ namespace LiteDB { - public partial class Collection + public partial class LiteCollection { /// /// Insert a new document to this collection. Document Id must be a new value in collection @@ -23,17 +23,17 @@ public virtual void Insert(T doc) // serialize object var bytes = BsonSerializer.Serialize(doc); - _engine.Transaction.Begin(); + this.Database.Transaction.Begin(); try { var col = this.GetCollectionPage(true); // storage in data pages - returns dataBlock address - var dataBlock = _engine.Data.Insert(col, new IndexKey(id), bytes); + var dataBlock = this.Database.Data.Insert(col, new IndexKey(id), bytes); // store id in a PK index [0 array] - var pk = _engine.Indexer.AddNode(col.PK, id); + var pk = this.Database.Indexer.AddNode(col.PK, id); // do links between index <-> data block pk.DataBlock = dataBlock.Position; @@ -48,7 +48,7 @@ public virtual void Insert(T doc) { var key = BsonSerializer.GetFieldValue(doc, index.Field); - var node = _engine.Indexer.AddNode(index, key); + var node = this.Database.Indexer.AddNode(index, key); // point my index to data object node.DataBlock = dataBlock.Position; @@ -58,11 +58,11 @@ public virtual void Insert(T doc) } } - _engine.Transaction.Commit(); + this.Database.Transaction.Commit(); } catch (Exception ex) { - _engine.Transaction.Rollback(); + this.Database.Transaction.Rollback(); throw ex; } } @@ -70,24 +70,24 @@ public virtual void Insert(T doc) /// /// Insert an array of new documents to this collection. Document Id must be a new value in collection /// - public virtual void Insert(IEnumerable docs) + public virtual void InsertBatch(IEnumerable docs) { if (docs == null) throw new ArgumentNullException("docs"); + this.Database.Transaction.Begin(); + try { - _engine.Transaction.Begin(); - foreach (var doc in docs) { this.Insert(doc); } - _engine.Transaction.Commit(); + this.Database.Transaction.Commit(); } catch (Exception ex) { - _engine.Transaction.Rollback(); + this.Database.Transaction.Rollback(); throw ex; } } diff --git a/LiteDB/Engine/Collections/Collection.Update.cs b/LiteDB/Database/Collections/LiteCollection.Update.cs similarity index 76% rename from LiteDB/Engine/Collections/Collection.Update.cs rename to LiteDB/Database/Collections/LiteCollection.Update.cs index 9597cdeba..8bb3da322 100644 --- a/LiteDB/Engine/Collections/Collection.Update.cs +++ b/LiteDB/Database/Collections/LiteCollection.Update.cs @@ -6,7 +6,7 @@ namespace LiteDB { - public partial class Collection + public partial class LiteCollection { /// /// Update a document in this collection. Returns false if not found document in collection @@ -24,7 +24,7 @@ public virtual bool Update(T doc) var bytes = BsonSerializer.Serialize(doc); // start transaction - _engine.Transaction.Begin(); + this.Database.Transaction.Begin(); try { @@ -33,22 +33,22 @@ public virtual bool Update(T doc) // if no collection, no updates if (col == null) { - _engine.Transaction.Abort(); + this.Database.Transaction.Abort(); return false; } // find indexNode from pk index - var indexNode = _engine.Indexer.FindOne(col.PK, id); + var indexNode = this.Database.Indexer.FindOne(col.PK, id); // if not found document, no updates if (indexNode == null) { - _engine.Transaction.Abort(); + this.Database.Transaction.Abort(); return false; } // update data storage - var dataBlock = _engine.Data.Update(col, indexNode.DataBlock, bytes); + var dataBlock = this.Database.Data.Update(col, indexNode.DataBlock, bytes); // delete/insert indexes - do not touch on PK for (byte i = 1; i < col.Indexes.Length; i++) @@ -59,16 +59,16 @@ public virtual bool Update(T doc) { var key = BsonSerializer.GetFieldValue(doc, index.Field); - var node = _engine.Indexer.GetNode(dataBlock.IndexRef[i]); + var node = this.Database.Indexer.GetNode(dataBlock.IndexRef[i]); // check if my index node was changed if (node.Key.CompareTo(new IndexKey(key)) != 0) { // remove old index node - _engine.Indexer.Delete(index, node.Position); + this.Database.Indexer.Delete(index, node.Position); // and add a new one - var newNode = _engine.Indexer.AddNode(index, key); + var newNode = this.Database.Indexer.AddNode(index, key); // point my index to data object newNode.DataBlock = dataBlock.Position; @@ -81,13 +81,13 @@ public virtual bool Update(T doc) } } - _engine.Transaction.Commit(); + this.Database.Transaction.Commit(); return true; } catch (Exception ex) { - _engine.Transaction.Rollback(); + this.Database.Transaction.Rollback(); throw ex; } } diff --git a/LiteDB/Engine/Collections/Collection.cs b/LiteDB/Database/Collections/LiteCollection.cs similarity index 73% rename from LiteDB/Engine/Collections/Collection.cs rename to LiteDB/Database/Collections/LiteCollection.cs index 2730bfcc7..ea731a933 100644 --- a/LiteDB/Engine/Collections/Collection.cs +++ b/LiteDB/Database/Collections/LiteCollection.cs @@ -6,11 +6,10 @@ namespace LiteDB { - public partial class Collection + public partial class LiteCollection where T : new() { private uint _pageID; - private LiteEngine _engine; private List> _includes; /// @@ -18,10 +17,15 @@ public partial class Collection /// public string Name { get; private set; } - internal Collection(LiteEngine engine, string name) + /// + /// Gets database object reference + /// + public LiteDatabase Database { get; private set; } + + internal LiteCollection(LiteDatabase db, string name) { this.Name = name; - _engine = engine; + this.Database = db; _pageID = uint.MaxValue; _includes = new List>(); } @@ -35,20 +39,20 @@ internal CollectionPage GetCollectionPage(bool addIfNotExits) // use this moment to check if data file was changed (if in transaction, do nothing) if (addIfNotExits == false) { - _engine.Transaction.AvoidDirtyRead(); + this.Database.Transaction.AvoidDirtyRead(); } // _pageID never change, even if data file was changed if (_pageID == uint.MaxValue) { - var col = _engine.Collections.Get(this.Name); + var col = this.Database.Collections.Get(this.Name); if (col == null) { // create a new collection only if if (addIfNotExits) { - col = _engine.Collections.Add(this.Name); + col = this.Database.Collections.Add(this.Name); } else { @@ -61,7 +65,7 @@ internal CollectionPage GetCollectionPage(bool addIfNotExits) return col; } - return _engine.Pager.GetPage(_pageID); + return this.Database.Pager.GetPage(_pageID); } } } diff --git a/LiteDB/Engine/FileStorage/FileEntry.cs b/LiteDB/Database/GridFS/LiteFileInfo.cs similarity index 79% rename from LiteDB/Engine/FileStorage/FileEntry.cs rename to LiteDB/Database/GridFS/LiteFileInfo.cs index c3e074135..d9210a9ab 100644 --- a/LiteDB/Engine/FileStorage/FileEntry.cs +++ b/LiteDB/Database/GridFS/LiteFileInfo.cs @@ -11,7 +11,7 @@ namespace LiteDB /// /// Represets a file inside storage collection /// - public class FileEntry + public class LiteFileInfo { /// /// File id have a specific format - it's like file path. @@ -30,14 +30,14 @@ public class FileEntry public DateTime UploadDate { get; internal set; } public BsonObject Metadata { get; set; } - private LiteEngine _engine; + private LiteDatabase _db; - public FileEntry(string id) + public LiteFileInfo(string id) : this(id, id) { } - public FileEntry(string id, string filename) + public LiteFileInfo(string id, string filename) { if (!Regex.IsMatch(id, ID_PATTERN)) throw new LiteException("Invalid file id format."); @@ -49,9 +49,9 @@ public FileEntry(string id, string filename) this.Metadata = new BsonObject(); } - internal FileEntry(LiteEngine engine, BsonDocument doc) + internal LiteFileInfo(LiteDatabase db, BsonDocument doc) { - _engine = engine; + _db = db; this.Id = doc.Id.ToString(); this.Filename = doc["filename"].AsString; @@ -84,13 +84,13 @@ internal IEnumerable CreateChunks(Stream stream) var read = 0; var index = 0; - while ((read = stream.Read(buffer, 0, FileEntry.CHUNK_SIZE)) > 0) + while ((read = stream.Read(buffer, 0, LiteFileInfo.CHUNK_SIZE)) > 0) { this.Length += (long)read; var chunk = new BsonDocument { - Id = string.Format("{0}\\{1}", this.Id, index++) // index zero based + Id = GetChunckId(this.Id, index++) // index zero based }; if (read != CHUNK_SIZE) @@ -110,14 +110,22 @@ internal IEnumerable CreateChunks(Stream stream) yield break; } + /// + /// Returns chunck Id for a file + /// + internal static string GetChunckId(string fileId, int index) + { + return string.Format("{0}\\{1:00000}", fileId, index); + } + /// /// Open file stream to read from database /// public LiteFileStream OpenRead() { - if (_engine == null) throw new LiteException("This FileEntry instance don't have reference to LiteEngine database"); + if (_db == null) throw new LiteException("This FileEntry instance don't have reference to database"); - return new LiteFileStream(_engine, this); + return new LiteFileStream(_db, this); } /// @@ -125,7 +133,7 @@ public LiteFileStream OpenRead() /// public void SaveAs(string filename, bool overwritten = true) { - if (_engine == null) throw new LiteException("This FileEntry instance don't have reference to LiteEngine database"); + if (_db == null) throw new LiteException("This FileEntry instance don't have reference to database"); using (var file = new FileStream(filename, overwritten ? FileMode.Create : FileMode.CreateNew)) { diff --git a/LiteDB/Engine/FileStorage/LiteFileStream.cs b/LiteDB/Database/GridFS/LiteFileStream.cs similarity index 86% rename from LiteDB/Engine/FileStorage/LiteFileStream.cs rename to LiteDB/Database/GridFS/LiteFileStream.cs index e2ed11e58..79945c4b5 100644 --- a/LiteDB/Engine/FileStorage/LiteFileStream.cs +++ b/LiteDB/Database/GridFS/LiteFileStream.cs @@ -9,8 +9,8 @@ namespace LiteDB { public class LiteFileStream : Stream { - private LiteEngine _engine; - private FileEntry _entry; + private LiteDatabase _db; + private LiteFileInfo _file; private readonly long _streamLength = 0; private long _streamPosition = 0; @@ -19,12 +19,12 @@ public class LiteFileStream : Stream private byte[] _currentChunkData = null; private int _positionInChunk = 0; - internal LiteFileStream(LiteEngine engine, FileEntry entry) + internal LiteFileStream(LiteDatabase db, LiteFileInfo file) { - _engine = engine; - _entry = entry; + _db = db; + _file = file; - if (entry.Length == 0) + if (file.Length == 0) { throw new LiteException("This file has no content or is corrupted"); } @@ -37,7 +37,7 @@ internal LiteFileStream(LiteEngine engine, FileEntry entry) /// /// Get file information /// - public FileEntry FileEntry { get { return _entry; } } + public LiteFileInfo FileInfo { get { return _file; } } public override long Length { get { return _streamLength; } } @@ -84,12 +84,12 @@ public override int Read(byte[] buffer, int offset, int count) private byte[] GetChunkData(int index) { // avoid too many extend pages on memory - _engine.Cache.RemoveExtendPages(); + _db.Cache.RemoveExtendPages(); // check if there is no more chunks in this file - var chunks = _engine.GetCollection("_chunks"); + var chunks = _db.GetCollection("_chunks"); - var chunk = chunks.FindById(_entry.Id + "\\" + index); + var chunk = chunks.FindById(LiteFileInfo.GetChunckId(_file.Id, index)); // if chunk is null there is no more chunks return chunk == null ? null : chunk["data"].AsByteArray; diff --git a/LiteDB/Engine/FileStorage/FileStorage.Delete.cs b/LiteDB/Database/GridFS/LiteGridFS.Delete.cs similarity index 75% rename from LiteDB/Engine/FileStorage/FileStorage.Delete.cs rename to LiteDB/Database/GridFS/LiteGridFS.Delete.cs index a793e451d..9aa4f7ffd 100644 --- a/LiteDB/Engine/FileStorage/FileStorage.Delete.cs +++ b/LiteDB/Database/GridFS/LiteGridFS.Delete.cs @@ -8,7 +8,7 @@ namespace LiteDB { - public partial class FileStorage + public partial class LiteGridFS { /// /// Delete a file inside datafile and all metadata related @@ -17,11 +17,11 @@ public bool Delete(string id) { if (string.IsNullOrEmpty(id)) throw new ArgumentNullException("id"); - if (_engine.Transaction.IsInTransaction) + if (this.Database.Transaction.IsInTransaction) throw new LiteException("Files can't be used inside a transaction."); // remove file reference in _files - var d = _files.Delete(id); + var d = this.Files.Delete(id); // if not found, just return false if(d == false) return false; @@ -30,9 +30,9 @@ public bool Delete(string id) while (true) { - var del = _chunks.Delete(id + "\\" + (index ++)); + var del = Chunks.Delete(LiteFileInfo.GetChunckId(id, index++)); - _engine.Cache.RemoveExtendPages(); + this.Database.Cache.RemoveExtendPages(); if (del == false) break; } diff --git a/LiteDB/Engine/FileStorage/FileStorage.Download.cs b/LiteDB/Database/GridFS/LiteGridFS.Download.cs similarity index 81% rename from LiteDB/Engine/FileStorage/FileStorage.Download.cs rename to LiteDB/Database/GridFS/LiteGridFS.Download.cs index 0f4dd4f85..67328e4ec 100644 --- a/LiteDB/Engine/FileStorage/FileStorage.Download.cs +++ b/LiteDB/Database/GridFS/LiteGridFS.Download.cs @@ -6,7 +6,7 @@ namespace LiteDB { - public partial class FileStorage + public partial class LiteGridFS { /// /// Copy all file content to a steam @@ -31,21 +31,21 @@ public LiteFileStream OpenRead(string id) { if (string.IsNullOrEmpty(id)) throw new ArgumentNullException("id"); - var doc = _files.FindById(id); + var doc = this.Files.FindById(id); if (doc == null) return null; - return this.OpenRead(new FileEntry(doc)); + return this.OpenRead(new LiteFileInfo(doc)); } /// /// Load data inside storage and returns as Stream /// - internal LiteFileStream OpenRead(FileEntry entry) + internal LiteFileStream OpenRead(LiteFileInfo entry) { if (entry == null) throw new ArgumentNullException("entry"); - return new LiteFileStream(_engine, entry); + return new LiteFileStream(this.Database, entry); } } } diff --git a/LiteDB/Engine/FileStorage/FileStorage.Find.cs b/LiteDB/Database/GridFS/LiteGridFS.Find.cs similarity index 56% rename from LiteDB/Engine/FileStorage/FileStorage.Find.cs rename to LiteDB/Database/GridFS/LiteGridFS.Find.cs index c3c5c6aaa..beaf86ed9 100644 --- a/LiteDB/Engine/FileStorage/FileStorage.Find.cs +++ b/LiteDB/Database/GridFS/LiteGridFS.Find.cs @@ -8,41 +8,49 @@ namespace LiteDB { - public partial class FileStorage + public partial class LiteGridFS { /// /// Find a file inside datafile and returns FileEntry instance. Returns null if not found /// - public FileEntry FindById(string id) + public LiteFileInfo FindById(string id) { if (string.IsNullOrEmpty(id)) throw new ArgumentNullException("id"); - var doc = _files.FindById(id); + var doc = this.Files.FindById(id); if (doc == null) return null; - return new FileEntry(_engine, doc); + return new LiteFileInfo(Database, doc); } /// /// Returns all FileEntry founded starting with id passed. /// - public IEnumerable Find(string startsWith) + public IEnumerable Find(string startsWith) { var result = string.IsNullOrEmpty(startsWith) ? - _files.Find(Query.All()) : - _files.Find(Query.StartsWith("_id", startsWith)); + this.Files.Find(Query.All()) : + this.Files.Find(Query.StartsWith("_id", startsWith)); foreach (var doc in result) { - yield return new FileEntry(_engine, doc); + yield return new LiteFileInfo(this.Database, doc); } } + /// + /// Returns if a file exisits in database + /// + public bool Exists(string id) + { + return this.Files.Exists(Query.EQ("_id", id)); + } + /// /// Returns all FileEntry inside database /// - public IEnumerable All() + public IEnumerable FindAll() { return this.Find(null); } diff --git a/LiteDB/Database/GridFS/LiteGridFS.Upload.cs b/LiteDB/Database/GridFS/LiteGridFS.Upload.cs new file mode 100644 index 000000000..cf3d5c00c --- /dev/null +++ b/LiteDB/Database/GridFS/LiteGridFS.Upload.cs @@ -0,0 +1,81 @@ +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.IO; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; + +namespace LiteDB +{ + public partial class LiteGridFS + { + /// + /// Insert a new file content inside datafile in _files collection + /// + public LiteFileInfo Upload(LiteFileInfo file, Stream stream) + { + if (file == null) throw new ArgumentNullException("id"); + if (stream == null) throw new ArgumentNullException("stream"); + + // no transaction allowed + if (this.Database.Transaction.IsInTransaction) + throw new LiteException("Files can´t be used inside a transaction."); + + file.UploadDate = DateTime.Now; + + // insert file in _files collections with 0 file length + this.Files.Insert(file.AsDocument); + + // for each chunk, insert as a chunk document + foreach (var chunk in file.CreateChunks(stream)) + { + this.Chunks.Insert(chunk); + + // clear extend pages in cache to avoid too many use of memory in big files + this.Database.Cache.RemoveExtendPages(); + } + + // update fileLength to confirm full file length stored in disk + this.Files.Update(file.AsDocument); + + return file; + } + + public LiteFileInfo Upload(string id, Stream stream) + { + return this.Upload(new LiteFileInfo(id), stream); + } + + public LiteFileInfo Upload(string id, string filename) + { + using (var stream = new FileStream(filename, FileMode.Open, FileAccess.Read)) + { + return this.Upload(new LiteFileInfo(id, filename), stream); + } + } + + /// + /// Upload a file to FileStorage using Path.GetFilename as file Id + /// + public LiteFileInfo Upload(string filename) + { + using (var stream = new FileStream(filename, FileMode.Open, FileAccess.Read)) + { + return this.Upload(new LiteFileInfo(Path.GetFileName(filename), filename), stream); + } + } + + /// + /// Update metada on a file. File must exisits + /// + public bool SetMetadata(string id, BsonObject metadata) + { + var file = this.FindById(id); + if (file == null) return false; + file.Metadata = metadata; + this.Files.Update(file.AsDocument); + return true; + } + } +} diff --git a/LiteDB/Database/GridFS/LiteGridFS.cs b/LiteDB/Database/GridFS/LiteGridFS.cs new file mode 100644 index 000000000..cbf4fb384 --- /dev/null +++ b/LiteDB/Database/GridFS/LiteGridFS.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; + +namespace LiteDB +{ + /// + /// Storage is a special collection to store files/streams. + /// + public partial class LiteGridFS + { + public LiteCollection Files { get; private set; } + public LiteCollection Chunks { get; private set; } + public LiteDatabase Database { get; private set; } + + internal LiteGridFS(LiteDatabase db) + { + this.Database = db; + this.Files = this.Database.GetCollection("_files"); + this.Chunks = this.Database.GetCollection("_chunks"); + } + } +} diff --git a/LiteDB/Engine/LiteEngine.cs b/LiteDB/Database/LiteDatabase.cs similarity index 67% rename from LiteDB/Engine/LiteEngine.cs rename to LiteDB/Database/LiteDatabase.cs index d52d01fe4..6fce505d0 100644 --- a/LiteDB/Engine/LiteEngine.cs +++ b/LiteDB/Database/LiteDatabase.cs @@ -7,9 +7,9 @@ namespace LiteDB { /// - /// The LiteDB engine. Used for create a LiteDB instance and use all storage resoures. It's the database connection engine. + /// The LiteDB database. Used for create a LiteDB instance and use all storage resoures. It's the database connection /// - public partial class LiteEngine : IDisposable + public partial class LiteDatabase : IDisposable { #region Properties + Ctor @@ -34,10 +34,10 @@ public partial class LiteEngine : IDisposable internal CollectionService Collections { get; private set; } /// - /// Starts LiteDB engine. Open database file or create a new one if not exits + /// Starts LiteDB database. Open database file or create a new one if not exits /// /// Full filename or connection string - public LiteEngine(string connectionString) + public LiteDatabase(string connectionString) { this.ConnectionString = new ConnectionString(connectionString); @@ -77,43 +77,84 @@ public LiteEngine(string connectionString) /// Get a collection using a strong typed POCO class. If collection does not exits, create a new one. /// /// Collection name (case insensitive) - public Collection GetCollection(string name) + public LiteCollection GetCollection(string name) where T : new() { - return new Collection(this, name); + return new LiteCollection(this, name); } /// /// Get a collection using a generic BsonDocument. If collection does not exits, create a new one. /// /// Collection name (case insensitive) - public Collection GetCollection(string name) + public LiteCollection GetCollection(string name) { - return new Collection(this, name); + return new LiteCollection(this, name); } /// /// Get all collections name inside this database. /// - public string[] GetCollections() + public IEnumerable GetCollectionNames() { this.Transaction.AvoidDirtyRead(); - return this.Collections.GetAll().Select(x => x.CollectionName).ToArray(); + return this.Collections.GetAll().Select(x => x.CollectionName); + } + + /// + /// Checks if a collection exists on database. Collection name is case unsensitive + /// + public bool CollectionExists(string name) + { + this.Transaction.AvoidDirtyRead(); + + return this.Collections.Get(name) != null; + } + + /// + /// Rename a collection. Returns false if oldName does not exists or newName already exists + /// + public bool RenameCollection(string oldName, string newName) + { + this.Transaction.Begin(); + + try + { + var col = this.Collections.Get(oldName); + + if (col == null || this.CollectionExists(newName)) + { + this.Transaction.Abort(); + return false; + } + + col.CollectionName = newName; + col.IsDirty = true; + + this.Transaction.Commit(); + } + catch (Exception ex) + { + this.Transaction.Rollback(); + throw ex; + } + + return true; } #endregion - #region Files Storage + #region GridFS - private FileStorage _files = null; + private LiteGridFS _gridfs = null; /// /// Returns a special collection for storage files/stream inside datafile /// - public FileStorage FileStorage + public LiteGridFS GridFS { - get { return _files ?? (_files = new FileStorage(this)); } + get { return _gridfs ?? (_gridfs = new LiteGridFS(this)); } } #endregion diff --git a/LiteDB/Engine/Tools/Bulk.cs b/LiteDB/Database/Tools/Bulk.cs similarity index 89% rename from LiteDB/Engine/Tools/Bulk.cs rename to LiteDB/Database/Tools/Bulk.cs index 00d36d50c..268ef1636 100644 --- a/LiteDB/Engine/Tools/Bulk.cs +++ b/LiteDB/Database/Tools/Bulk.cs @@ -6,7 +6,7 @@ namespace LiteDB { - public partial class LiteEngine + public partial class LiteDatabase { /// /// Bulk documents to a collection - use data chunks for most efficient insert @@ -26,14 +26,14 @@ public static int Bulk(string connectionString, string collectionName, IEnume { var buff = buffer; - using (var db = new LiteEngine(connectionString)) + using (var db = new LiteDatabase(connectionString)) { var col = db.GetCollection(collectionName); var more = true; db.BeginTrans(); - while ((more = enumerator.MoveNext()) && buff > 0) + while (buff > 0 && (more = enumerator.MoveNext())) { col.Insert(enumerator.Current); buff--; diff --git a/LiteDB/Engine/Tools/Info.cs b/LiteDB/Database/Tools/Info.cs similarity index 96% rename from LiteDB/Engine/Tools/Info.cs rename to LiteDB/Database/Tools/Info.cs index d19efda4b..26e13a5b5 100644 --- a/LiteDB/Engine/Tools/Info.cs +++ b/LiteDB/Database/Tools/Info.cs @@ -6,7 +6,7 @@ namespace LiteDB { - public partial class LiteEngine + public partial class LiteDatabase { /// /// Get all database information diff --git a/LiteDB/Engine/Tools/UserVersion.cs b/LiteDB/Database/Tools/UserVersion.cs similarity index 97% rename from LiteDB/Engine/Tools/UserVersion.cs rename to LiteDB/Database/Tools/UserVersion.cs index a9c8c3000..573b6f9b5 100644 --- a/LiteDB/Engine/Tools/UserVersion.cs +++ b/LiteDB/Database/Tools/UserVersion.cs @@ -6,7 +6,7 @@ namespace LiteDB { - public partial class LiteEngine + public partial class LiteDatabase { /// /// Virtual method for update database when a new version (from coneection string) was setted diff --git a/LiteDB/Engine/FileStorage/FileStorage.Upload.cs b/LiteDB/Engine/FileStorage/FileStorage.Upload.cs deleted file mode 100644 index 36d01e15c..000000000 --- a/LiteDB/Engine/FileStorage/FileStorage.Upload.cs +++ /dev/null @@ -1,68 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.IO; -using System.Linq; -using System.Text; -using System.Text.RegularExpressions; - -namespace LiteDB -{ - public partial class FileStorage - { - /// - /// Insert a new file content inside datafile in _files collection - /// - public FileEntry Upload(FileEntry file, Stream stream) - { - if (file == null) throw new ArgumentNullException("id"); - if (stream == null) throw new ArgumentNullException("stream"); - - // no transaction allowed - if (_engine.Transaction.IsInTransaction) - throw new LiteException("Files can´t be used inside a transaction."); - - file.UploadDate = DateTime.Now; - - // insert file in _files collections with 0 file length - _files.Insert(file.AsDocument); - - // for each chunk, insert as a chunk document - foreach (var chunk in file.CreateChunks(stream)) - { - _chunks.Insert(chunk); - - // clear extend pages in cache to avoid too many use of memory in big files - _engine.Cache.RemoveExtendPages(); - } - - // update fileLength to confirm full file length stored in disk - _files.Update(file.AsDocument); - - return file; - } - - public FileEntry Upload(string id, Stream stream) - { - return this.Upload(new FileEntry(id), stream); - } - - public FileEntry Upload(string id, string filename) - { - using (var stream = new FileStream(filename, FileMode.Open, FileAccess.Read)) - { - return this.Upload(new FileEntry(id, filename), stream); - } - } - - /// - /// Update a file entry on storage - do not change file content, only filename/metadata will be update - /// - public bool Update(FileEntry file) - { - if (file == null) throw new ArgumentNullException("file"); - - return _files.Update(file.AsDocument); - } - } -} diff --git a/LiteDB/Engine/FileStorage/FileStorage.cs b/LiteDB/Engine/FileStorage/FileStorage.cs deleted file mode 100644 index da9a5686d..000000000 --- a/LiteDB/Engine/FileStorage/FileStorage.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; - -namespace LiteDB -{ - /// - /// Storage is a special collection to store files/streams. - /// - public partial class FileStorage - { - private Collection _files; - private Collection _chunks; - private LiteEngine _engine; - - internal FileStorage(LiteEngine engine) - { - _engine = engine; - _files = _engine.GetCollection("_files"); - _chunks = _engine.GetCollection("_chunks"); - } - } -} diff --git a/LiteDB/LiteDB.csproj b/LiteDB/LiteDB.csproj index da2ebbaa4..32dfab0c2 100644 --- a/LiteDB/LiteDB.csproj +++ b/LiteDB/LiteDB.csproj @@ -45,11 +45,11 @@ - - - - - + + + + + @@ -69,19 +69,19 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + @@ -104,13 +104,14 @@ + - + @@ -140,7 +141,7 @@ - + diff --git a/LiteDB/Properties/AssemblyInfo.cs b/LiteDB/Properties/AssemblyInfo.cs index 54b3f1647..d4cbd1701 100644 --- a/LiteDB/Properties/AssemblyInfo.cs +++ b/LiteDB/Properties/AssemblyInfo.cs @@ -3,7 +3,7 @@ using System.Runtime.InteropServices; [assembly: AssemblyTitle("LiteDB")] -[assembly: AssemblyDescription("LiteDB - A .NET NoSQL Document Store in a single data file")] +[assembly: AssemblyDescription("LiteDB - A lightweight embedded .NET NoSQL document store in a single datafile")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("Maurício David")] [assembly: AssemblyProduct("LiteDB")] @@ -13,8 +13,7 @@ [assembly: ComVisible(false)] [assembly: Guid("54989b5c-4bcf-4d58-b8ba-9b014a324f76")] -[assembly: AssemblyVersion("0.9.0.0")] -[assembly: AssemblyFileVersion("0.9.0.0")] +[assembly: AssemblyVersion("0.10.0.0")] +[assembly: AssemblyFileVersion("0.10.0.0")] -[assembly: InternalsVisibleTo("UnitTest")] -[assembly: InternalsVisibleTo("LiteDB.Shell")] \ No newline at end of file +[assembly: InternalsVisibleTo("UnitTest")] \ No newline at end of file diff --git a/LiteDB/Query/Query.cs b/LiteDB/Query/Query.cs index fac4009a7..5672d3407 100644 --- a/LiteDB/Query/Query.cs +++ b/LiteDB/Query/Query.cs @@ -108,7 +108,7 @@ public static Query In(string field, params object[] values) /// /// Returns objects that exists in ALL queries results. /// - public static Query AND(Query left, Query right) + public static Query And(Query left, Query right) { return new QueryAnd(left, right); } @@ -116,7 +116,7 @@ public static Query AND(Query left, Query right) /// /// Returns objects that exists in ANY queries results. /// - public static Query OR(Query left, Query right) + public static Query Or(Query left, Query right) { return new QueryOr(left, right); } @@ -124,15 +124,15 @@ public static Query OR(Query left, Query right) #region Execute Query // used for execute in results (AND/OR) - internal abstract IEnumerable Execute(LiteEngine engine, CollectionIndex index); + internal abstract IEnumerable Execute(LiteDatabase db, CollectionIndex index); - internal virtual IEnumerable Run(LiteEngine engine, CollectionPage col) + internal virtual IEnumerable Run(LiteDatabase db, CollectionPage col) { var index = col.Indexes.FirstOrDefault(x => x.Field.Equals(this.Field, StringComparison.InvariantCultureIgnoreCase)); if (index == null) throw new LiteException(string.Format("Index '{0}.{1}' not found. Use EnsureIndex to create a new index.", col.CollectionName, this.Field)); - return this.Execute(engine, index); + return this.Execute(db, index); } #endregion diff --git a/LiteDB/Query/QueryAll.cs b/LiteDB/Query/QueryAll.cs index d9f5b265d..3e10ece2c 100644 --- a/LiteDB/Query/QueryAll.cs +++ b/LiteDB/Query/QueryAll.cs @@ -18,9 +18,9 @@ public QueryAll(string field) { } - internal override IEnumerable Execute(LiteEngine engine, CollectionIndex index) + internal override IEnumerable Execute(LiteDatabase db, CollectionIndex index) { - return engine.Indexer.FindAll(index); + return db.Indexer.FindAll(index); } } } diff --git a/LiteDB/Query/QueryAnd.cs b/LiteDB/Query/QueryAnd.cs index 9a1565264..419bbd04d 100644 --- a/LiteDB/Query/QueryAnd.cs +++ b/LiteDB/Query/QueryAnd.cs @@ -19,15 +19,15 @@ public QueryAnd(Query left, Query right) } // Never runs in AND/OR queries - internal override IEnumerable Execute(LiteEngine engine, CollectionIndex index) + internal override IEnumerable Execute(LiteDatabase db, CollectionIndex index) { return null; } - internal override IEnumerable Run(LiteEngine engine, CollectionPage col) + internal override IEnumerable Run(LiteDatabase db, CollectionPage col) { - var left = this.Left.Run(engine, col); - var right = this.Right.Run(engine, col); + var left = this.Left.Run(db, col); + var right = this.Right.Run(db, col); return left.Intersect(right, new IndexNodeComparer()); } diff --git a/LiteDB/Query/QueryBetween.cs b/LiteDB/Query/QueryBetween.cs index ecd3f3d79..6f0040edd 100644 --- a/LiteDB/Query/QueryBetween.cs +++ b/LiteDB/Query/QueryBetween.cs @@ -18,9 +18,9 @@ public QueryBetween(string field, object start, object end) this.End = end; } - internal override IEnumerable Execute(LiteEngine engine, CollectionIndex index) + internal override IEnumerable Execute(LiteDatabase db, CollectionIndex index) { - return engine.Indexer.FindBetween(index, this.Start, this.End); + return db.Indexer.FindBetween(index, this.Start, this.End); } } } diff --git a/LiteDB/Query/QueryEquals.cs b/LiteDB/Query/QueryEquals.cs index 17800e68d..b5335a85c 100644 --- a/LiteDB/Query/QueryEquals.cs +++ b/LiteDB/Query/QueryEquals.cs @@ -16,9 +16,9 @@ public QueryEquals(string field, object value) this.Value = value; } - internal override IEnumerable Execute(LiteEngine engine, CollectionIndex index) + internal override IEnumerable Execute(LiteDatabase db, CollectionIndex index) { - return engine.Indexer.FindEquals(index, this.Value); + return db.Indexer.FindEquals(index, this.Value); } } } diff --git a/LiteDB/Query/QueryGreater.cs b/LiteDB/Query/QueryGreater.cs index 3fa3ac689..54b18422b 100644 --- a/LiteDB/Query/QueryGreater.cs +++ b/LiteDB/Query/QueryGreater.cs @@ -18,9 +18,9 @@ public QueryGreater(string field, object value, bool orEquals) this.OrEquals = orEquals; } - internal override IEnumerable Execute(LiteEngine engine, CollectionIndex index) + internal override IEnumerable Execute(LiteDatabase db, CollectionIndex index) { - return engine.Indexer.FindGreaterThan(index, this.Value, this.OrEquals); + return db.Indexer.FindGreaterThan(index, this.Value, this.OrEquals); } } } diff --git a/LiteDB/Query/QueryIn.cs b/LiteDB/Query/QueryIn.cs index 683efd519..8e4c8baa5 100644 --- a/LiteDB/Query/QueryIn.cs +++ b/LiteDB/Query/QueryIn.cs @@ -16,9 +16,9 @@ public QueryIn(string field, object[] values) this.Values = values; } - internal override IEnumerable Execute(LiteEngine engine, CollectionIndex index) + internal override IEnumerable Execute(LiteDatabase db, CollectionIndex index) { - return engine.Indexer.FindIn(index, this.Values); + return db.Indexer.FindIn(index, this.Values); } } } diff --git a/LiteDB/Query/QueryLess.cs b/LiteDB/Query/QueryLess.cs index 39a020e10..1c893b9ac 100644 --- a/LiteDB/Query/QueryLess.cs +++ b/LiteDB/Query/QueryLess.cs @@ -18,9 +18,9 @@ public QueryLess(string field, object value, bool orEquals) this.OrEquals = orEquals; } - internal override IEnumerable Execute(LiteEngine engine, CollectionIndex index) + internal override IEnumerable Execute(LiteDatabase db, CollectionIndex index) { - return engine.Indexer.FindLessThan(index, this.Value, this.OrEquals); + return db.Indexer.FindLessThan(index, this.Value, this.OrEquals); } } } diff --git a/LiteDB/Query/QueryNot.cs b/LiteDB/Query/QueryNot.cs index 1576b54ce..e8568be38 100644 --- a/LiteDB/Query/QueryNot.cs +++ b/LiteDB/Query/QueryNot.cs @@ -16,9 +16,9 @@ public QueryNot(string field, object value) this.Value = value; } - internal override IEnumerable Execute(LiteEngine engine, CollectionIndex index) + internal override IEnumerable Execute(LiteDatabase db, CollectionIndex index) { - return engine.Indexer.FindAll(index).Where(x => x.Key.CompareTo(new IndexKey(this.Value)) != 0); + return db.Indexer.FindAll(index).Where(x => x.Key.CompareTo(new IndexKey(this.Value)) != 0); } } } diff --git a/LiteDB/Query/QueryOr.cs b/LiteDB/Query/QueryOr.cs index a2766c229..86d26c01c 100644 --- a/LiteDB/Query/QueryOr.cs +++ b/LiteDB/Query/QueryOr.cs @@ -19,15 +19,15 @@ public QueryOr(Query left, Query right) } // Never runs in AND/OR queries - internal override IEnumerable Execute(LiteEngine engine, CollectionIndex index) + internal override IEnumerable Execute(LiteDatabase db, CollectionIndex index) { return null; } - internal override IEnumerable Run(LiteEngine engine, CollectionPage col) + internal override IEnumerable Run(LiteDatabase db, CollectionPage col) { - var left = this.Left.Run(engine, col); - var right = this.Right.Run(engine, col); + var left = this.Left.Run(db, col); + var right = this.Right.Run(db, col); return left.Union(right, new IndexNodeComparer()); } diff --git a/LiteDB/Query/QueryStartsWith.cs b/LiteDB/Query/QueryStartsWith.cs index 3209cb72f..c02f53e4f 100644 --- a/LiteDB/Query/QueryStartsWith.cs +++ b/LiteDB/Query/QueryStartsWith.cs @@ -16,9 +16,9 @@ public QueryStartsWith(string field, string value) this.Value = value; } - internal override IEnumerable Execute(LiteEngine engine, CollectionIndex index) + internal override IEnumerable Execute(LiteDatabase db, CollectionIndex index) { - return engine.Indexer.FindStarstWith(index, this.Value); + return db.Indexer.FindStarstWith(index, this.Value); } } } diff --git a/LiteDB/Shell/Commands/Collections/BaseCollection.cs b/LiteDB/Shell/Commands/Collections/BaseCollection.cs index da13cae4a..1ddfab18a 100644 --- a/LiteDB/Shell/Commands/Collections/BaseCollection.cs +++ b/LiteDB/Shell/Commands/Collections/BaseCollection.cs @@ -10,7 +10,7 @@ public class BaseCollection /// /// Read collection name from db.(colname).(command) /// - public Collection ReadCollection(LiteEngine db, StringScanner s) + public LiteCollection ReadCollection(LiteDatabase db, StringScanner s) { return db.GetCollection(s.Scan(@"db\.(\w+)\.\w+\s*", 1)); } @@ -60,8 +60,8 @@ private Query ReadInlineQuery(StringScanner s) if(oper.Length == 0) throw new ApplicationException("Invalid query operator"); return oper == "and" ? - Query.AND(left, this.ReadInlineQuery(s)) : - Query.OR(left, this.ReadInlineQuery(s)); + Query.And(left, this.ReadInlineQuery(s)) : + Query.Or(left, this.ReadInlineQuery(s)); } private Query ReadOneQuery(StringScanner s) diff --git a/LiteDB/Shell/Commands/Collections/Bulk.cs b/LiteDB/Shell/Commands/Collections/Bulk.cs index 7821f757f..10425bb68 100644 --- a/LiteDB/Shell/Commands/Collections/Bulk.cs +++ b/LiteDB/Shell/Commands/Collections/Bulk.cs @@ -7,14 +7,14 @@ namespace LiteDB.Shell.Commands { - public class CollectionBulk : BaseCollection, IShellCommand + public class CollectionBulk : BaseCollection, ILiteCommand { public bool IsCommand(StringScanner s) { return this.IsCollectionCommand(s, "bulk"); } - public void Execute(LiteEngine db, StringScanner s, Display display) + public void Execute(LiteDatabase db, StringScanner s, Display display) { if (db == null) throw new LiteException("No database"); diff --git a/LiteDB/Shell/Commands/Collections/Count.cs b/LiteDB/Shell/Commands/Collections/Count.cs index d3635236e..e5d4314f0 100644 --- a/LiteDB/Shell/Commands/Collections/Count.cs +++ b/LiteDB/Shell/Commands/Collections/Count.cs @@ -6,14 +6,14 @@ namespace LiteDB.Shell.Commands { - public class CollectionCount : BaseCollection, IShellCommand + public class CollectionCount : BaseCollection, ILiteCommand { public bool IsCommand(StringScanner s) { return this.IsCollectionCommand(s, "count"); } - public void Execute(LiteEngine db, StringScanner s, Display display) + public void Execute(LiteDatabase db, StringScanner s, Display display) { if (db == null) throw new LiteException("No database"); diff --git a/LiteDB/Shell/Commands/Collections/Delete.cs b/LiteDB/Shell/Commands/Collections/Delete.cs index 4074d9d75..009bf4d50 100644 --- a/LiteDB/Shell/Commands/Collections/Delete.cs +++ b/LiteDB/Shell/Commands/Collections/Delete.cs @@ -6,14 +6,14 @@ namespace LiteDB.Shell.Commands { - public class CollectionDelete : BaseCollection, IShellCommand + public class CollectionDelete : BaseCollection, ILiteCommand { public bool IsCommand(StringScanner s) { return this.IsCollectionCommand(s, "delete"); } - public void Execute(LiteEngine db, StringScanner s, Display display) + public void Execute(LiteDatabase db, StringScanner s, Display display) { if (db == null) throw new LiteException("No database"); diff --git a/LiteDB/Shell/Commands/Collections/Drop.cs b/LiteDB/Shell/Commands/Collections/Drop.cs index c447f3326..2def0e84c 100644 --- a/LiteDB/Shell/Commands/Collections/Drop.cs +++ b/LiteDB/Shell/Commands/Collections/Drop.cs @@ -6,14 +6,14 @@ namespace LiteDB.Shell.Commands { - public class CollectionDrop : BaseCollection, IShellCommand + public class CollectionDrop : BaseCollection, ILiteCommand { public bool IsCommand(StringScanner s) { return this.IsCollectionCommand(s, "drop"); } - public void Execute(LiteEngine db, StringScanner s, Display display) + public void Execute(LiteDatabase db, StringScanner s, Display display) { if (db == null) throw new LiteException("No database"); diff --git a/LiteDB/Shell/Commands/Collections/DropIndex.cs b/LiteDB/Shell/Commands/Collections/DropIndex.cs index 5008532cb..2806a0466 100644 --- a/LiteDB/Shell/Commands/Collections/DropIndex.cs +++ b/LiteDB/Shell/Commands/Collections/DropIndex.cs @@ -6,14 +6,14 @@ namespace LiteDB.Shell.Commands { - public class CollectionDropIndex : BaseCollection, IShellCommand + public class CollectionDropIndex : BaseCollection, ILiteCommand { public bool IsCommand(StringScanner s) { return this.IsCollectionCommand(s, "drop[iI]ndex"); } - public void Execute(LiteEngine db, StringScanner s, Display display) + public void Execute(LiteDatabase db, StringScanner s, Display display) { if (db == null) throw new LiteException("No database"); diff --git a/LiteDB/Shell/Commands/Collections/EnsureIndex.cs b/LiteDB/Shell/Commands/Collections/EnsureIndex.cs index cb32308b4..e5f44ddc2 100644 --- a/LiteDB/Shell/Commands/Collections/EnsureIndex.cs +++ b/LiteDB/Shell/Commands/Collections/EnsureIndex.cs @@ -6,14 +6,14 @@ namespace LiteDB.Shell.Commands { - public class CollectionEnsureIndex : BaseCollection, IShellCommand + public class CollectionEnsureIndex : BaseCollection, ILiteCommand { public bool IsCommand(StringScanner s) { return this.IsCollectionCommand(s, "ensure[iI]ndex"); } - public void Execute(LiteEngine db, StringScanner s, Display display) + public void Execute(LiteDatabase db, StringScanner s, Display display) { if (db == null) throw new LiteException("No database"); diff --git a/LiteDB/Shell/Commands/Collections/Exec.cs b/LiteDB/Shell/Commands/Collections/Exec.cs index bfc98f68f..dc88673e7 100644 --- a/LiteDB/Shell/Commands/Collections/Exec.cs +++ b/LiteDB/Shell/Commands/Collections/Exec.cs @@ -8,14 +8,14 @@ namespace LiteDB.Shell.Commands { - class CollectionExec : BaseCollection, IShellCommand + class CollectionExec : BaseCollection, ILiteCommand { public bool IsCommand(StringScanner s) { return this.IsCollectionCommand(s, "exec"); } - public void Execute(LiteEngine db, StringScanner s, Display display) + public void Execute(LiteDatabase db, StringScanner s, Display display) { if (db == null) throw new LiteException("No database"); @@ -57,10 +57,10 @@ public static void DoWork( object id, BsonDocument doc, Collection col, - LiteEngine db) { [code] } + LiteDatabase db) { [code] } }"; - public static Action, LiteEngine> GetCode(StringScanner s) + public static Action, LiteDatabase> GetCode(StringScanner s) { var str = s.Scan(@".*"); var code = CODE_TEMPLATE.Replace("[code]", str); @@ -87,7 +87,7 @@ public static Action, LiteEngine> var program = assembly.GetType("Program"); var method = program.GetMethod("DoWork"); - return new Action, LiteEngine>((id, doc, col, db) => + return new Action, LiteDatabase>((id, doc, col, db) => { method.Invoke(null, new object[] { id, doc, col, db }); }); diff --git a/LiteDB/Shell/Commands/Collections/Find.cs b/LiteDB/Shell/Commands/Collections/Find.cs index 003f15d99..ea5e8f7b5 100644 --- a/LiteDB/Shell/Commands/Collections/Find.cs +++ b/LiteDB/Shell/Commands/Collections/Find.cs @@ -6,14 +6,14 @@ namespace LiteDB.Shell.Commands { - public class CollectionFind : BaseCollection, IShellCommand + public class CollectionFind : BaseCollection, ILiteCommand { public bool IsCommand(StringScanner s) { return this.IsCollectionCommand(s, "find"); } - public void Execute(LiteEngine db, StringScanner s, Display display) + public void Execute(LiteDatabase db, StringScanner s, Display display) { if (db == null) throw new LiteException("No database"); diff --git a/LiteDB/Shell/Commands/Collections/Indexes.cs b/LiteDB/Shell/Commands/Collections/Indexes.cs index b283735b6..7077e51d7 100644 --- a/LiteDB/Shell/Commands/Collections/Indexes.cs +++ b/LiteDB/Shell/Commands/Collections/Indexes.cs @@ -6,14 +6,14 @@ namespace LiteDB.Shell.Commands { - public class CollectionIndexes : BaseCollection, IShellCommand + public class CollectionIndexes : BaseCollection, ILiteCommand { public bool IsCommand(StringScanner s) { return this.IsCollectionCommand(s, "indexes$"); } - public void Execute(LiteEngine db, StringScanner s, Display display) + public void Execute(LiteDatabase db, StringScanner s, Display display) { if (db == null) throw new LiteException("No database"); diff --git a/LiteDB/Shell/Commands/Collections/Insert.cs b/LiteDB/Shell/Commands/Collections/Insert.cs index c7f72b27c..8f329ed1a 100644 --- a/LiteDB/Shell/Commands/Collections/Insert.cs +++ b/LiteDB/Shell/Commands/Collections/Insert.cs @@ -6,14 +6,14 @@ namespace LiteDB.Shell.Commands { - public class CollectionInsert : BaseCollection, IShellCommand + public class CollectionInsert : BaseCollection, ILiteCommand { public bool IsCommand(StringScanner s) { return this.IsCollectionCommand(s, "insert"); } - public void Execute(LiteEngine db, StringScanner s, Display display) + public void Execute(LiteDatabase db, StringScanner s, Display display) { if (db == null) throw new LiteException("No database"); diff --git a/LiteDB/Shell/Commands/Collections/Update.cs b/LiteDB/Shell/Commands/Collections/Update.cs index 4b704abba..04df6323a 100644 --- a/LiteDB/Shell/Commands/Collections/Update.cs +++ b/LiteDB/Shell/Commands/Collections/Update.cs @@ -6,14 +6,14 @@ namespace LiteDB.Shell.Commands { - public class CollectionUpdate : BaseCollection, IShellCommand + public class CollectionUpdate : BaseCollection, ILiteCommand { public bool IsCommand(StringScanner s) { return this.IsCollectionCommand(s, "update"); } - public void Execute(LiteEngine db, StringScanner s, Display display) + public void Execute(LiteDatabase db, StringScanner s, Display display) { if (db == null) throw new LiteException("No database"); diff --git a/LiteDB/Shell/Commands/Files/BaseFile.cs b/LiteDB/Shell/Commands/Files/BaseFile.cs index 820a164fa..7f395886d 100644 --- a/LiteDB/Shell/Commands/Files/BaseFile.cs +++ b/LiteDB/Shell/Commands/Files/BaseFile.cs @@ -17,7 +17,7 @@ public bool IsFileCommand(StringScanner s, string command) /// public string ReadId(StringScanner s) { - return s.Scan(FileEntry.ID_PATTERN.Substring(1, FileEntry.ID_PATTERN.Length - 2)); + return s.Scan(LiteFileInfo.ID_PATTERN.Substring(1, LiteFileInfo.ID_PATTERN.Length - 2)); } } } diff --git a/LiteDB/Shell/Commands/Files/Delete.cs b/LiteDB/Shell/Commands/Files/Delete.cs index 24afc28e3..da1a4fe26 100644 --- a/LiteDB/Shell/Commands/Files/Delete.cs +++ b/LiteDB/Shell/Commands/Files/Delete.cs @@ -7,20 +7,20 @@ namespace LiteDB.Shell.Commands { - public class FileDelete : BaseFile, IShellCommand + public class FileDelete : BaseFile, ILiteCommand { public bool IsCommand(StringScanner s) { return this.IsFileCommand(s, "delete"); } - public void Execute(LiteEngine db, StringScanner s, Display display) + public void Execute(LiteDatabase db, StringScanner s, Display display) { if (db == null) throw new LiteException("No database"); var id = this.ReadId(s); - display.WriteBson(db.FileStorage.Delete(id)); + display.WriteBson(db.GridFS.Delete(id)); } } } diff --git a/LiteDB/Shell/Commands/Files/Download.cs b/LiteDB/Shell/Commands/Files/Download.cs index 93227377f..ee398fd15 100644 --- a/LiteDB/Shell/Commands/Files/Download.cs +++ b/LiteDB/Shell/Commands/Files/Download.cs @@ -7,21 +7,21 @@ namespace LiteDB.Shell.Commands { - public class FileDownload : BaseFile, IShellCommand + public class FileDownload : BaseFile, ILiteCommand { public bool IsCommand(StringScanner s) { return this.IsFileCommand(s, "download"); } - public void Execute(LiteEngine db, StringScanner s, Display display) + public void Execute(LiteDatabase db, StringScanner s, Display display) { if (db == null) throw new LiteException("No database"); var id = this.ReadId(s); var filename = s.Scan(@"\s*.*").Trim(); - var file = db.FileStorage.FindById(id); + var file = db.GridFS.FindById(id); if (file != null) { diff --git a/LiteDB/Shell/Commands/Files/Find.cs b/LiteDB/Shell/Commands/Files/Find.cs index a443a54fd..f7fe894a6 100644 --- a/LiteDB/Shell/Commands/Files/Find.cs +++ b/LiteDB/Shell/Commands/Files/Find.cs @@ -6,20 +6,20 @@ namespace LiteDB.Shell.Commands { - public class FileFind : BaseFile, IShellCommand + public class FileFind : BaseFile, ILiteCommand { public bool IsCommand(StringScanner s) { return this.IsFileCommand(s, "find"); } - public void Execute(LiteEngine db, StringScanner s, Display display) + public void Execute(LiteDatabase db, StringScanner s, Display display) { if (db == null) throw new LiteException("No database"); if (s.HasTerminated) { - display.WriteBson(db.FileStorage.All().Select(x => x.AsDocument)); + display.WriteBson(db.GridFS.FindAll().Select(x => x.AsDocument)); } else { @@ -27,11 +27,11 @@ public void Execute(LiteEngine db, StringScanner s, Display display) if (id.EndsWith("*") || id.EndsWith("%")) { - display.WriteBson(db.FileStorage.Find(id.Substring(0, id.Length - 1)).Select(x => x.AsDocument)); + display.WriteBson(db.GridFS.Find(id.Substring(0, id.Length - 1)).Select(x => x.AsDocument)); } else { - var file = db.FileStorage.FindById(id); + var file = db.GridFS.FindById(id); if (file != null) { diff --git a/LiteDB/Shell/Commands/Files/Update.cs b/LiteDB/Shell/Commands/Files/Update.cs index 02c0a8276..a1971c796 100644 --- a/LiteDB/Shell/Commands/Files/Update.cs +++ b/LiteDB/Shell/Commands/Files/Update.cs @@ -7,27 +7,22 @@ namespace LiteDB.Shell.Commands { - public class FileUpdate : BaseFile, IShellCommand + public class FileUpdate : BaseFile, ILiteCommand { public bool IsCommand(StringScanner s) { return this.IsFileCommand(s, "update"); } - public void Execute(LiteEngine db, StringScanner s, Display display) + public void Execute(LiteDatabase db, StringScanner s, Display display) { if (db == null) throw new LiteException("No database"); var id = this.ReadId(s); - var file = db.FileStorage.FindById(id); - if (file == null) return; + var result = db.GridFS.SetMetadata(id, new JsonReader().ReadValue(s).AsObject); - file.Metadata = new JsonReader().ReadValue(s).AsObject; - - db.FileStorage.Update(file); - - display.WriteBson(file.AsDocument); + display.WriteBson(result); } } } diff --git a/LiteDB/Shell/Commands/Files/Upload.cs b/LiteDB/Shell/Commands/Files/Upload.cs index 04734acb2..6401f1cb7 100644 --- a/LiteDB/Shell/Commands/Files/Upload.cs +++ b/LiteDB/Shell/Commands/Files/Upload.cs @@ -7,14 +7,14 @@ namespace LiteDB.Shell.Commands { - public class FileUpload : BaseFile, IShellCommand + public class FileUpload : BaseFile, ILiteCommand { public bool IsCommand(StringScanner s) { return this.IsFileCommand(s, "upload"); } - public void Execute(LiteEngine db, StringScanner s, Display display) + public void Execute(LiteDatabase db, StringScanner s, Display display) { if (db == null) throw new LiteException("No database"); @@ -24,7 +24,7 @@ public void Execute(LiteEngine db, StringScanner s, Display display) if (!File.Exists(filename)) throw new IOException("File " + filename + " not found"); - var file = db.FileStorage.Upload(id, filename); + var file = db.GridFS.Upload(id, filename); display.WriteBson(file.AsDocument); } diff --git a/LiteDB/Shell/Commands/IShellCommand.cs b/LiteDB/Shell/Commands/ILiteCommand.cs similarity index 61% rename from LiteDB/Shell/Commands/IShellCommand.cs rename to LiteDB/Shell/Commands/ILiteCommand.cs index a03517135..eeed4c759 100644 --- a/LiteDB/Shell/Commands/IShellCommand.cs +++ b/LiteDB/Shell/Commands/ILiteCommand.cs @@ -5,9 +5,9 @@ namespace LiteDB.Shell { - public interface IShellCommand + public interface ILiteCommand { bool IsCommand(StringScanner s); - void Execute(LiteEngine db, StringScanner s, Display display); + void Execute(LiteDatabase db, StringScanner s, Display display); } } diff --git a/LiteDB/Shell/Commands/LiteCommandResult.cs b/LiteDB/Shell/Commands/LiteCommandResult.cs new file mode 100644 index 000000000..b9cba6d2a --- /dev/null +++ b/LiteDB/Shell/Commands/LiteCommandResult.cs @@ -0,0 +1,69 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace LiteDB.Shell +{ + public enum LiteCommandResponseType { Error, Void, Text, BsonValue, BsonDocument, BsonDocuments } + + /// + /// Represent a result from a command shell + /// + public class LiteCommandResult + { + public LiteCommandResponseType ResponseType { get; private set; } + + public bool Ok { get; private set; } + + public BsonValue Response { get; private set; } + + public string ResponseText { get; private set; } + + public string ErrorMessage { get; private set; } + + #region Response Converters + + public BsonValue ToBson() + { + return (BsonValue)this.Response; + } + + public BsonDocument ToBsonDocument() + { + return (BsonDocument)this.Response; + } + + public IEnumerable ToBsonDocuments() + { + return (IEnumerable)this.Response; + } + + public string ToText() + { + return (string)this.Response; + } + + #endregion + + #region Static Constructors + + internal static LiteCommandResult Error(Exception ex) + { + return new LiteCommandResult { Ok = false, ResponseType = LiteCommandResponseType.Error, ErrorMessage = ex.Message }; + } + + internal static LiteCommandResult Text(string text) + { + return new LiteCommandResult { Ok = true, ResponseType = LiteCommandResponseType.Text, Response = text }; + } + + internal static LiteCommandResult Bson(BsonValue value) + { + return new LiteCommandResult { Ok = true, ResponseType = LiteCommandResponseType.BsonValue, Response = value }; + } + + #endregion + + } +} diff --git a/LiteDB/Shell/Commands/Others/Dump.cs b/LiteDB/Shell/Commands/Others/Dump.cs index a44f21ad1..fea26f11d 100644 --- a/LiteDB/Shell/Commands/Others/Dump.cs +++ b/LiteDB/Shell/Commands/Others/Dump.cs @@ -6,14 +6,14 @@ namespace LiteDB.Shell.Commands { - public class Dump : IShellCommand + public class Dump : ILiteCommand { public bool IsCommand(StringScanner s) { return s.Scan(@"dump\s*").Length > 0; } - public void Execute(LiteEngine db, StringScanner s, Display display) + public void Execute(LiteDatabase db, StringScanner s, Display display) { if (db == null) throw new LiteException("No database"); diff --git a/LiteDB/Shell/Commands/Others/Info.cs b/LiteDB/Shell/Commands/Others/Info.cs index a2465c6a2..c812d348f 100644 --- a/LiteDB/Shell/Commands/Others/Info.cs +++ b/LiteDB/Shell/Commands/Others/Info.cs @@ -6,14 +6,14 @@ namespace LiteDB.Shell.Commands { - public class Info : IShellCommand + public class Info : ILiteCommand { public bool IsCommand(StringScanner s) { return s.Match(@"db\.info$"); } - public void Execute(LiteEngine db, StringScanner s, Display display) + public void Execute(LiteDatabase db, StringScanner s, Display display) { if (db == null) throw new LiteException("No database"); diff --git a/LiteDB/Shell/Commands/Others/ShowCollections.cs b/LiteDB/Shell/Commands/Others/ShowCollections.cs index f74d97f46..38702dc4a 100644 --- a/LiteDB/Shell/Commands/Others/ShowCollections.cs +++ b/LiteDB/Shell/Commands/Others/ShowCollections.cs @@ -6,18 +6,18 @@ namespace LiteDB.Shell.Commands { - public class ShowCollections : IShellCommand + public class ShowCollections : ILiteCommand { public bool IsCommand(StringScanner s) { return s.Match(@"show\scollections"); } - public void Execute(LiteEngine db, StringScanner s, Display display) + public void Execute(LiteDatabase db, StringScanner s, Display display) { if (db == null) throw new LiteException("No database"); - display.WriteResult(string.Join("\n", db.GetCollections().OrderBy(x => x).ToArray())); + display.WriteResult(string.Join("\n", db.GetCollectionNames().OrderBy(x => x).ToArray())); } } } diff --git a/LiteDB/Shell/Commands/Transactions/Begin.cs b/LiteDB/Shell/Commands/Transactions/Begin.cs index d991ed53d..0c637a992 100644 --- a/LiteDB/Shell/Commands/Transactions/Begin.cs +++ b/LiteDB/Shell/Commands/Transactions/Begin.cs @@ -6,14 +6,14 @@ namespace LiteDB.Shell.Commands { - public class Begin : IShellCommand + public class Begin : ILiteCommand { public bool IsCommand(StringScanner s) { return s.Scan(@"begin(\s+trans)?$").Length > 0; } - public void Execute(LiteEngine db, StringScanner s, Display display) + public void Execute(LiteDatabase db, StringScanner s, Display display) { if (db == null) throw new LiteException("No database"); diff --git a/LiteDB/Shell/Commands/Transactions/Commit.cs b/LiteDB/Shell/Commands/Transactions/Commit.cs index 6549c2d91..ba477f151 100644 --- a/LiteDB/Shell/Commands/Transactions/Commit.cs +++ b/LiteDB/Shell/Commands/Transactions/Commit.cs @@ -6,14 +6,14 @@ namespace LiteDB.Shell.Commands { - public class Commit : IShellCommand + public class Commit : ILiteCommand { public bool IsCommand(StringScanner s) { return s.Scan(@"commit(\s+trans)?$").Length > 0; } - public void Execute(LiteEngine db, StringScanner s, Display display) + public void Execute(LiteDatabase db, StringScanner s, Display display) { if (db == null) throw new LiteException("No database"); diff --git a/LiteDB/Shell/Commands/Transactions/Rollback.cs b/LiteDB/Shell/Commands/Transactions/Rollback.cs index 4ed7c7915..3e1670876 100644 --- a/LiteDB/Shell/Commands/Transactions/Rollback.cs +++ b/LiteDB/Shell/Commands/Transactions/Rollback.cs @@ -6,14 +6,14 @@ namespace LiteDB.Shell.Commands { - public class Rollback : IShellCommand + public class Rollback : ILiteCommand { public bool IsCommand(StringScanner s) { return s.Scan(@"rollback(\s+trans)?$").Length > 0; } - public void Execute(LiteEngine db, StringScanner s, Display display) + public void Execute(LiteDatabase db, StringScanner s, Display display) { if (db == null) throw new LiteException("No database"); diff --git a/LiteDB/Shell/LiteShell.cs b/LiteDB/Shell/LiteShell.cs index f1c7e987b..013d35e7f 100644 --- a/LiteDB/Shell/LiteShell.cs +++ b/LiteDB/Shell/LiteShell.cs @@ -9,17 +9,17 @@ namespace LiteDB.Shell { public class LiteShell : IDisposable { - private List _commands = new List(); + private List _commands = new List(); public LiteShell() { this.Display = new Display(); } - public LiteShell(LiteEngine db, StringBuilder sb, bool pretty = true) + public LiteShell(LiteDatabase db, StringBuilder sb, bool pretty = true) : this() { - this.Engine = db; + this.Database = db; var writer = new StringWriter(sb); this.Display.TextWriters.Add(writer); @@ -27,7 +27,7 @@ public LiteShell(LiteEngine db, StringBuilder sb, bool pretty = true) this.RegisterAll(); } - public LiteEngine Engine { get; set; } + public LiteDatabase Database { get; set; } public Display Display { get; set; } /// @@ -35,21 +35,21 @@ public LiteShell(LiteEngine db, StringBuilder sb, bool pretty = true) /// public void RegisterAll() { - _commands = new List(); + _commands = new List(); - var type = typeof(IShellCommand); + var type = typeof(ILiteCommand); var types = AppDomain.CurrentDomain.GetAssemblies() .SelectMany(s => s.GetTypes()) .Where(p => type.IsAssignableFrom(p) && p.IsClass); foreach (var t in types) { - _commands.Add((IShellCommand)Activator.CreateInstance(t)); + _commands.Add((ILiteCommand)Activator.CreateInstance(t)); } } public void Register() - where T : IShellCommand, new() + where T : ILiteCommand, new() { _commands.Add(new T()); } @@ -64,7 +64,7 @@ public void Run(string command) { if (cmd.IsCommand(s)) { - cmd.Execute(this.Engine, s, this.Display); + cmd.Execute(this.Database, s, this.Display); return; } } @@ -74,7 +74,7 @@ public void Run(string command) public void Dispose() { - if (this.Engine != null) this.Engine.Dispose(); + if (this.Database != null) this.Database.Dispose(); } } } diff --git a/LiteDB/Utils/ConnectionString.cs b/LiteDB/Utils/ConnectionString.cs index 43f9421fa..66210f28a 100644 --- a/LiteDB/Utils/ConnectionString.cs +++ b/LiteDB/Utils/ConnectionString.cs @@ -33,7 +33,7 @@ public class ConnectionString /// /// Define, in connection string, the user database version. When you increse this value - /// LiteEngine will run OnUpdate method for each new version. If defined, must be >= 1. Default: 1 + /// LiteDatabase will run OnUpdate method for each new version. If defined, must be >= 1. Default: 1 /// public int UserVersion { get; private set; } diff --git a/LiteDB/Utils/DumpDatabase.cs b/LiteDB/Utils/DumpDatabase.cs index 3eb4fb7bd..2b7331df7 100644 --- a/LiteDB/Utils/DumpDatabase.cs +++ b/LiteDB/Utils/DumpDatabase.cs @@ -12,7 +12,7 @@ namespace LiteDB /// internal class DumpDatabase { - public static string Pages(LiteEngine db, bool mem) + public static string Pages(LiteDatabase db, bool mem) { var sb = new StringBuilder(); @@ -43,7 +43,7 @@ public static string Pages(LiteEngine db, bool mem) return sb.ToString(); } - private static T ReadPage(LiteEngine db, uint pageID, bool mem) + private static T ReadPage(LiteDatabase db, uint pageID, bool mem) where T : BasePage, new() { if (mem && pageID == 0) return (T)(object)db.Cache.Header; @@ -51,7 +51,7 @@ private static T ReadPage(LiteEngine db, uint pageID, bool mem) return mem ? db.Pager.GetPage(pageID) : db.Disk.ReadPage(pageID); } - public static string Index(LiteEngine db, string collection, string field, int size = 5) + public static string Index(LiteDatabase db, string collection, string field, int size = 5) { var sbs = new StringBuilder[IndexNode.MAX_LEVEL_LENGTH + 1]; var first = true; diff --git a/LiteDB/Utils/LiteException.cs b/LiteDB/Utils/LiteException.cs index e07b2621a..8714ac7e1 100644 --- a/LiteDB/Utils/LiteException.cs +++ b/LiteDB/Utils/LiteException.cs @@ -13,7 +13,7 @@ public class LiteException : Exception { public int ErrorCode { get; private set; } - internal LiteException(string message) + public LiteException(string message) : base(message) { } diff --git a/UnitTest/FindOrderTest.cs b/UnitTest/FindOrderTest.cs index 9384473d0..b1b88a9fa 100644 --- a/UnitTest/FindOrderTest.cs +++ b/UnitTest/FindOrderTest.cs @@ -21,7 +21,7 @@ public class FindOrderTest [TestMethod] public void Find_Order() { - using (var db = new LiteEngine(DB.Path())) + using (var db = new LiteDatabase(DB.Path())) { var col = db.GetCollection("order"); col.EnsureIndex("Text"); diff --git a/UnitTest/IncludeTest.cs b/UnitTest/IncludeTest.cs index 7c2de8561..b2eb65a78 100644 --- a/UnitTest/IncludeTest.cs +++ b/UnitTest/IncludeTest.cs @@ -14,7 +14,7 @@ public class IncludeTest [TestMethod] public void Include_Test() { - using (var db = new LiteEngine(DB.Path())) + using (var db = new LiteDatabase(DB.Path())) { var customer1 = new Customer { CustomerId = Guid.NewGuid(), Name = "Mauricio" }; var order1 = new Order { OrderKey = 1, Date = DateTime.Now, CustomerId = customer1.CustomerId }; @@ -31,7 +31,7 @@ public void Include_Test() var query = orders .Include((x) => x.Customer = customers.FindById(x.CustomerId)) - .All() + .FindAll() .Select(x => new { x.OrderKey, Cust = x.Customer.Name, CustomerInstance = x.Customer }) .FirstOrDefault(); diff --git a/UnitTest/LinqTest.cs b/UnitTest/LinqTest.cs index 25e511c79..40b1393a3 100644 --- a/UnitTest/LinqTest.cs +++ b/UnitTest/LinqTest.cs @@ -14,7 +14,7 @@ public class LinqTest [TestMethod] public void Linq_Test() { - using (var db = new LiteEngine(DB.Path())) + using (var db = new LiteDatabase(DB.Path())) { var c1 = new Customer { CustomerId = Guid.NewGuid(), Name = "Mauricio", CreationDate = new DateTime(2015, 1, 1) }; var c2 = new Customer { CustomerId = Guid.NewGuid(), Name = "Malafaia", CreationDate = new DateTime(2015, 1, 1) }; @@ -26,7 +26,7 @@ public void Linq_Test() col.EnsureIndex(x => x.Name, true); col.EnsureIndex(x => x.CreationDate); - col.Insert(new Customer[] { c1, c2, c3, c4 }); + col.InsertBatch(new Customer[] { c1, c2, c3, c4 }); var past = -30; diff --git a/UnitTest/PageTest.cs b/UnitTest/PageTest.cs index 16ceb2909..7976c6cda 100644 --- a/UnitTest/PageTest.cs +++ b/UnitTest/PageTest.cs @@ -22,7 +22,7 @@ public void Init() [TestMethod] public void Page_PrevNext_Test() { - using (var db = new LiteEngine(DB.Path())) + using (var db = new LiteDatabase(DB.Path())) { var k = 1; @@ -50,17 +50,17 @@ public void Page_PrevNext_Test() Dump.Pages(db, "After clear"); - db.FileStorage.Upload("my/foto1.jpg", new MemoryStream(new byte[1024*50])); + db.GridFS.Upload("my/foto1.jpg", new MemoryStream(new byte[1024*50])); } - using (var db = new LiteEngine(DB.Path(false))) + using (var db = new LiteDatabase(DB.Path(false))) { Dump.Pages(db, "After File"); } } - private void PopulateCollection(string name, LiteEngine db, int k) + private void PopulateCollection(string name, LiteDatabase db, int k) { var col = db.GetCollection(name); col.EnsureIndex("Updates"); @@ -105,7 +105,7 @@ private void PopulateCollection(string name, LiteEngine db, int k) } - private void Verify(string name, LiteEngine db, int k) + private void Verify(string name, LiteDatabase db, int k) { var col = db.GetCollection(name); diff --git a/UnitTest/PerfTest.cs b/UnitTest/PerfTest.cs index aa2a7712f..d97df34e8 100644 --- a/UnitTest/PerfTest.cs +++ b/UnitTest/PerfTest.cs @@ -17,11 +17,11 @@ public void Perf_Test() { var path = DB.Path(true, "test.db"); - using (var db = new LiteEngine("journal=true;filename=" + path)) + using (var db = new LiteDatabase("journal=true;filename=" + path)) { db.BeginTrans(); var col = db.GetCollection("posts"); - col.Insert(Post.GetData(20000)); + col.InsertBatch(Post.GetData(20000)); db.Commit(); } } @@ -31,13 +31,13 @@ public void PerfFile_Test() { var path = DB.Path(true, "test.db"); - using (var db = new LiteEngine("journal=false;filename=" + path)) + using (var db = new LiteDatabase("journal=false;filename=" + path)) { var bytes = new byte[150 * 1024 * 1024]; using (var m = new MemoryStream(bytes)) { - db.FileStorage.Upload("myfile", m); + db.GridFS.Upload("myfile", m); } } } diff --git a/UnitTest/StressTest.cs b/UnitTest/StressTest.cs index aa7da65a8..d5103602b 100644 --- a/UnitTest/StressTest.cs +++ b/UnitTest/StressTest.cs @@ -27,10 +27,10 @@ public void Stress_Test() var rnd = new Random(DateTime.Now.Second); var N = 100; - var a = new LiteEngine(file); - var b = new LiteEngine(file); - var c = new LiteEngine(file); - var d = new LiteEngine(file); + var a = new LiteDatabase(file); + var b = new LiteDatabase(file); + var c = new LiteDatabase(file); + var d = new LiteDatabase(file); // Task A -> Insert 100 documents var ta = Task.Factory.StartNew(() => @@ -75,7 +75,7 @@ public void Stress_Test() // Now, test data Task.WaitAll(ta, tb); //, tb, tc); - using (var db = new LiteEngine(file)) + using (var db = new LiteDatabase(file)) { var col = db.GetCollection("col1"); Assert.AreEqual(1, col.Count()); diff --git a/UnitTest/Utils/Dump.cs b/UnitTest/Utils/Dump.cs index 238aeb7a8..e56983e78 100644 --- a/UnitTest/Utils/Dump.cs +++ b/UnitTest/Utils/Dump.cs @@ -14,7 +14,7 @@ public static void Info(string text) Debug.Print(string.Format("== [ {0} ] ", text).PadRight(120, '=')); } - public static void Pages(LiteEngine db, string text = "Page Dump") + public static void Pages(LiteDatabase db, string text = "Page Dump") { var sb = new StringBuilder(); @@ -44,7 +44,7 @@ public static void Pages(LiteEngine db, string text = "Page Dump") Debug.Print(sb.ToString()); } - public static void Index(LiteEngine db, CollectionIndex index, int size = 5) + public static void Index(LiteDatabase db, CollectionIndex index, int size = 5) { var sbs = new StringBuilder[IndexNode.MAX_LEVEL_LENGTH + 1]; var first = true; diff --git a/UnitTest/VersionTest.cs b/UnitTest/VersionTest.cs index 3e14bbb0b..9aa37de3c 100644 --- a/UnitTest/VersionTest.cs +++ b/UnitTest/VersionTest.cs @@ -8,7 +8,7 @@ namespace UnitTest { - public class VersionDB : LiteEngine + public class VersionDB : LiteDatabase { public VersionDB(string connectionString) : base(connectionString) @@ -33,7 +33,7 @@ protected override void OnVersionUpdate(int newVersion) } } - public Collection Customers { get { return this.GetCollection("curtomers"); } } + public LiteCollection Customers { get { return this.GetCollection("curtomers"); } } } [TestClass] diff --git a/WebShell/Commands/Help.cs b/WebShell/Commands/Help.cs index d43a21616..b50e90fdc 100644 --- a/WebShell/Commands/Help.cs +++ b/WebShell/Commands/Help.cs @@ -6,14 +6,14 @@ namespace LiteDB.Shell.Commands { - public class Help : IShellCommand + public class Help : ILiteCommand { public bool IsCommand(StringScanner s) { return s.Scan(@"help$").Length > 0; } - public void Execute(LiteEngine db, StringScanner s, Display d) + public void Execute(LiteDatabase db, StringScanner s, Display d) { d.WriteResult("Web Shell Commands - try offline version for more commands"); d.WriteResult("=========================================================="); diff --git a/WebShell/api.ashx b/WebShell/api.ashx index 00dc5afec..727fbac55 100644 --- a/WebShell/api.ashx +++ b/WebShell/api.ashx @@ -38,7 +38,7 @@ public class WebShell : IHttpHandler shell.Register(); shell.Display.Pretty = true; - shell.Engine = new LiteDB.LiteEngine(filename); + shell.Database = new LiteDB.LiteDatabase(filename); shell.Display.TextWriters.Add(context.Response.Output); shell.Run(command); From 8d550b6014912a74a1e7c2755c0a669748f2dc60 Mon Sep 17 00:00:00 2001 From: mbdavid Date: Fri, 6 Feb 2015 17:38:25 -0200 Subject: [PATCH 02/96] Change shell structure --- LiteDB.Shell/Commands/Close.cs | 12 +- LiteDB.Shell/Commands/Comment.cs | 6 +- LiteDB.Shell/Commands/Ed.cs | 36 ++++ LiteDB.Shell/Commands/Help.cs | 162 ++++++++++-------- LiteDB.Shell/Commands/Open.cs | 28 +++ LiteDB.Shell/Commands/Pretty.cs | 6 +- LiteDB.Shell/Commands/Quit.cs | 6 +- LiteDB.Shell/Commands/Run.cs | 28 +++ LiteDB.Shell/Commands/Spool.cs | 15 +- LiteDB.Shell/Commands/Timer.cs | 23 +++ LiteDB.Shell/ConsoleCommand.cs | 47 +++++ {LiteDB/Shell => LiteDB.Shell}/Display.cs | 48 +++--- LiteDB.Shell/InputCommand.cs | 70 ++------ LiteDB.Shell/LiteDB.Shell.csproj | 6 + LiteDB.Shell/Program.cs | 42 +++-- LiteDB/Database/LiteDatabase.cs | 1 + LiteDB/Document/BsonArray.cs | 13 ++ LiteDB/Document/BsonDocument.cs | 9 +- LiteDB/LiteDB.csproj | 26 ++- .../Serializer/{ => Bson}/BsonIdAttribute.cs | 0 .../{ => Bson}/BsonIgnoreAttribute.cs | 0 .../Serializer/{ => Bson}/BsonSerializer.cs | 28 ++- .../Serializer/{JsonEx => Json}/JsonReader.cs | 0 .../JsonEx.cs => Json/JsonSerializer.cs} | 4 +- .../Serializer/{JsonEx => Json}/JsonWriter.cs | 26 ++- LiteDB/Serializer/fastBinaryJSON/BJSON.cs | 2 +- .../Serializer/fastBinaryJSON/Reflection.cs | 2 +- LiteDB/Shell/Commands/Collections/Bulk.cs | 6 +- LiteDB/Shell/Commands/Collections/Count.cs | 4 +- LiteDB/Shell/Commands/Collections/Delete.cs | 4 +- LiteDB/Shell/Commands/Collections/Drop.cs | 6 +- .../Shell/Commands/Collections/DropIndex.cs | 7 +- .../Shell/Commands/Collections/EnsureIndex.cs | 4 +- LiteDB/Shell/Commands/Collections/Exec.cs | 6 +- LiteDB/Shell/Commands/Collections/Find.cs | 5 +- LiteDB/Shell/Commands/Collections/Indexes.cs | 7 +- LiteDB/Shell/Commands/Collections/Insert.cs | 4 +- LiteDB/Shell/Commands/Collections/Update.cs | 6 +- .../BaseFile.cs => GridFS/BaseGridFS.cs} | 2 +- .../Commands/{Files => GridFS}/Delete.cs | 6 +- .../Commands/{Files => GridFS}/Download.cs | 9 +- .../Shell/Commands/{Files => GridFS}/Find.cs | 17 +- .../Commands/{Files => GridFS}/Update.cs | 9 +- .../Commands/{Files => GridFS}/Upload.cs | 6 +- LiteDB/Shell/Commands/ILiteCommand.cs | 2 +- LiteDB/Shell/Commands/LiteCommandResult.cs | 69 -------- LiteDB/Shell/Commands/Others/Dump.cs | 14 +- LiteDB/Shell/Commands/Others/Info.cs | 4 +- .../Shell/Commands/Others/ShowCollections.cs | 6 +- LiteDB/Shell/Commands/Transactions/Begin.cs | 4 +- LiteDB/Shell/Commands/Transactions/Commit.cs | 4 +- .../Shell/Commands/Transactions/Rollback.cs | 4 +- LiteDB/Shell/LiteShell.cs | 22 +-- LiteDB/Storage/Services/CacheService.cs | 7 +- LiteDB/Utils/DumpDatabase.cs | 8 +- UnitTest/JsonTest.cs | 4 +- WebShell/Commands/Help.cs | 59 +++++-- 57 files changed, 552 insertions(+), 409 deletions(-) create mode 100644 LiteDB.Shell/Commands/Ed.cs create mode 100644 LiteDB.Shell/Commands/Open.cs create mode 100644 LiteDB.Shell/Commands/Run.cs create mode 100644 LiteDB.Shell/Commands/Timer.cs create mode 100644 LiteDB.Shell/ConsoleCommand.cs rename {LiteDB/Shell => LiteDB.Shell}/Display.cs (62%) rename LiteDB/Serializer/{ => Bson}/BsonIdAttribute.cs (100%) rename LiteDB/Serializer/{ => Bson}/BsonIgnoreAttribute.cs (100%) rename LiteDB/Serializer/{ => Bson}/BsonSerializer.cs (89%) rename LiteDB/Serializer/{JsonEx => Json}/JsonReader.cs (100%) rename LiteDB/Serializer/{JsonEx/JsonEx.cs => Json/JsonSerializer.cs} (97%) rename LiteDB/Serializer/{JsonEx => Json}/JsonWriter.cs (93%) rename LiteDB/Shell/Commands/{Files/BaseFile.cs => GridFS/BaseGridFS.cs} (94%) rename LiteDB/Shell/Commands/{Files => GridFS}/Delete.cs (69%) rename LiteDB/Shell/Commands/{Files => GridFS}/Download.cs (74%) rename LiteDB/Shell/Commands/{Files => GridFS}/Find.cs (58%) rename LiteDB/Shell/Commands/{Files => GridFS}/Update.cs (62%) rename LiteDB/Shell/Commands/{Files => GridFS}/Upload.cs (78%) delete mode 100644 LiteDB/Shell/Commands/LiteCommandResult.cs diff --git a/LiteDB.Shell/Commands/Close.cs b/LiteDB.Shell/Commands/Close.cs index 9cf95d920..e1cb6af20 100644 --- a/LiteDB.Shell/Commands/Close.cs +++ b/LiteDB.Shell/Commands/Close.cs @@ -6,16 +6,20 @@ namespace LiteDB.Shell.Commands { - internal class Close : ILiteCommand + internal class Close : ConsoleCommand { - public bool IsCommand(StringScanner s) + public override bool IsCommand(StringScanner s) { return s.Scan(@"close$").Length > 0; } - public void Execute(LiteDatabase db, StringScanner s, Display display) + public override void Execute(LiteShell shell, StringScanner s, Display display, InputCommand input) { - db.Dispose(); + if (shell.Database == null) throw new LiteException("No database"); + + shell.Database.Dispose(); + + shell.Database = null; } } } diff --git a/LiteDB.Shell/Commands/Comment.cs b/LiteDB.Shell/Commands/Comment.cs index 28a3383b3..6eda44ef7 100644 --- a/LiteDB.Shell/Commands/Comment.cs +++ b/LiteDB.Shell/Commands/Comment.cs @@ -6,14 +6,14 @@ namespace LiteDB.Shell.Commands { - internal class Comment : ILiteCommand + internal class Comment : ConsoleCommand { - public bool IsCommand(StringScanner s) + public override bool IsCommand(StringScanner s) { return s.Match(@"--"); } - public void Execute(LiteDatabase db, StringScanner s, Display display) + public override void Execute(LiteShell shell, StringScanner s, Display display, InputCommand input) { } } diff --git a/LiteDB.Shell/Commands/Ed.cs b/LiteDB.Shell/Commands/Ed.cs new file mode 100644 index 000000000..ef6369ded --- /dev/null +++ b/LiteDB.Shell/Commands/Ed.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Text; + +namespace LiteDB.Shell.Commands +{ + internal class Ed : ConsoleCommand + { + public override bool IsCommand(StringScanner s) + { + return s.Match(@"ed$"); + } + + public override void Execute(LiteShell shell, StringScanner s, Display display, InputCommand input) + { + var temp = Path.GetTempPath() + "LiteDB.Shell.txt"; + + File.WriteAllText(temp, input.Last.Replace("\n", Environment.NewLine)); + + Process.Start("notepad.exe", temp).WaitForExit(); + + var text = File.ReadAllText(temp); + + if (text == input.Last) return; + + foreach (var line in text.Split('\n')) + { + input.Queue.Enqueue(line); + } + } + } +} diff --git a/LiteDB.Shell/Commands/Help.cs b/LiteDB.Shell/Commands/Help.cs index 24a95fc0b..595e5cf82 100644 --- a/LiteDB.Shell/Commands/Help.cs +++ b/LiteDB.Shell/Commands/Help.cs @@ -13,77 +13,99 @@ public bool IsCommand(StringScanner s) return s.Scan(@"help$").Length > 0; } - public void Execute(LiteDatabase db, StringScanner s, Display d) + public BsonValue Execute(LiteDatabase db, StringScanner s) { - d.WriteResult("Shell commands"); - d.WriteResult("=============="); - - d.WriteHelp("> open ", "Open a new database"); - d.WriteHelp("> close", "Close current database"); - d.WriteHelp("> run ", "Run commands inside filename"); - d.WriteHelp("> pretty on|off", "Turns on/off pretty json format"); - d.WriteHelp("> timer", "Show timer before prompt"); - d.WriteHelp("> ed", "Open nodepad with last command to edit and execute"); - d.WriteHelp("> spool on|off", "Spool all output in a spool file"); - d.WriteHelp("> -- comment", "Do nothing, its just a comment"); - d.WriteHelp("> //", "Support for multi line command"); - d.WriteHelp("> exit", "Close LiteDB shell"); - - d.WriteResult(""); - d.WriteResult("Transaction commands"); - d.WriteResult("===================="); - - d.WriteHelp("> begin", "Begins a new transaction"); - d.WriteHelp("> commit", "Commit current transaction"); - d.WriteHelp("> rollback", "Rollback current transaction"); - - d.WriteResult(""); - d.WriteResult("Collections commands"); - d.WriteResult("===================="); - - d.WriteHelp("> db..insert ", "Insert a new document into collection"); - d.WriteHelp("> db..update ", "Update a document inside collection"); - d.WriteHelp("> db..delete ", "Delete documents using a filter clausule (see find)"); - d.WriteHelp("> db..bulk ", "Bulk insert a json file as documents"); - d.WriteHelp("> db..find [top N]", "Show all documents. Can limit results in N documents"); - d.WriteHelp("> db..find [top N] ", "Show filtered documents based on index search"); - d.WriteHelp("> db..count ", "Show count rows according query filter"); - d.WriteHelp("> db..exec { Action }", "Execute C# code for each document based on filter."); - d.WriteHelp("> db..ensureIndex [unique]", "Create a new index document field"); - d.WriteHelp("> db..indexes", "List all indexes in this collection"); - d.WriteHelp("> db..drop", "Drop collection and destroy all documents inside"); - d.WriteHelp("> db..dropIndex ", "Drop a index and make index area free to use with another index"); - d.WriteHelp(" = [=|>|>=|<|<=|!=|like|between] ", "Filter query syntax"); - d.WriteHelp(" = ( [and|or] [and|or] ...)", "Multi queries syntax"); - d.WriteHelp(" = {_id: ... , key: value, key1: value1 }", "Represent a json (extended version) for a BsonDocument. See special data types"); - d.WriteHelp("JsonEx Date", "{ mydate: { $date :\"2015-01-01T23:59:59Z\"} }"); - d.WriteHelp("JsonEx Guid", "{ myguid: { $guid :\"3a1c34b3-9f66-4d8e-975a-d545d898a4ba\"} }"); - d.WriteHelp("JsonEx Binary", "{ mydata: { $binary :\"base64 byte array\"} }"); - - d.WriteResult(""); - d.WriteResult("File storage commands"); - d.WriteResult("====================="); - - d.WriteHelp("> fs.find", "List all files on datafile"); - d.WriteHelp("> fs.find ", "List file info from a key. Supports * for starts with key"); - d.WriteHelp("> fs.upload ", "Insert a new file inside database"); - d.WriteHelp("> fs.download ", "Save a file to disk passing a file key and filename"); - d.WriteHelp("> fs.update {key:value}", "Update metadata file"); - d.WriteHelp("> fs.delete ", "Remove a file inside database"); - - d.WriteResult(""); - d.WriteResult("Other commands"); - d.WriteResult("=============="); - - d.WriteHelp("> db.info", "Get database informations"); - d.WriteHelp("> dump", "Display dump database information"); - - d.WriteResult(""); - d.WriteResult("Try:"); - d.WriteResult(" > db.customers.insert { _id:1, name:\"John Doe\", age: 37 }"); - d.WriteResult(" > db.customers.ensureIndex name"); - d.WriteResult(" > db.customers.find name like \"J\""); - d.WriteResult(" > db.customers.find _id > 0"); + var sb = new StringBuilder(); + + this.Write(sb, "Shell commands"); + this.Write(sb, "=============="); + + this.Write(sb, "> open ", "Open a new database"); + this.Write(sb, "> close", "Close current database"); + this.Write(sb, "> run ", "Run commands inside filename"); + this.Write(sb, "> pretty on|off", "Turns on/off pretty json format"); + this.Write(sb, "> timer", "Show timer before prompt"); + this.Write(sb, "> ed", "Open nodepad with last command to edit and execute"); + this.Write(sb, "> spool on|off", "Spool all output in a spool file"); + this.Write(sb, "> -- comment", "Do nothing, its just a comment"); + this.Write(sb, "> //", "Support for multi line command"); + this.Write(sb, "> exit", "Close LiteDB shell"); + + this.Write(sb); + this.Write(sb, "Transaction commands"); + this.Write(sb, "===================="); + + this.Write(sb, "> begin", "Begins a new transaction"); + this.Write(sb, "> commit", "Commit current transaction"); + this.Write(sb, "> rollback", "Rollback current transaction"); + + this.Write(sb); + this.Write(sb, "Collections commands"); + this.Write(sb, "===================="); + + this.Write(sb, "> db..insert ", "Insert a new document into collection"); + this.Write(sb, "> db..update ", "Update a document inside collection"); + this.Write(sb, "> db..delete ", "Delete documents using a filter clausule (see find)"); + this.Write(sb, "> db..bulk ", "Bulk insert a json file as documents"); + this.Write(sb, "> db..find [top N]", "Show all documents. Can limit results in N documents"); + this.Write(sb, "> db..find [top N] ", "Show filtered documents based on index search"); + this.Write(sb, "> db..count ", "Show count rows according query filter"); + this.Write(sb, "> db..exec { Action }", "Execute C# code for each document based on filter."); + this.Write(sb, "> db..ensureIndex [unique]", "Create a new index document field"); + this.Write(sb, "> db..indexes", "List all indexes in this collection"); + this.Write(sb, "> db..drop", "Drop collection and destroy all documents inside"); + this.Write(sb, "> db..dropIndex ", "Drop a index and make index area free to use with another index"); + this.Write(sb, " = [=|>|>=|<|<=|!=|like|between] ", "Filter query syntax"); + this.Write(sb, " = ( [and|or] [and|or] ...)", "Multi queries syntax"); + this.Write(sb, " = {_id: ... , key: value, key1: value1 }", "Represent a json (extended version) for a BsonDocument. See special data types"); + this.Write(sb, "JsonEx Date", "{ mydate: { $date :\"2015-01-01T23:59:59Z\"} }"); + this.Write(sb, "JsonEx Guid", "{ myguid: { $guid :\"3a1c34b3-9f66-4d8e-975a-d545d898a4ba\"} }"); + this.Write(sb, "JsonEx Binary", "{ mydata: { $binary :\"base64 byte array\"} }"); + + this.Write(sb); + this.Write(sb, "File storage commands"); + this.Write(sb, "====================="); + + this.Write(sb, "> fs.find", "List all files on datafile"); + this.Write(sb, "> fs.find ", "List file info from a key. Supports * for starts with key"); + this.Write(sb, "> fs.upload ", "Insert a new file inside database"); + this.Write(sb, "> fs.download ", "Save a file to disk passing a file key and filename"); + this.Write(sb, "> fs.update {key:value}", "Update metadata file"); + this.Write(sb, "> fs.delete ", "Remove a file inside database"); + + this.Write(sb); + this.Write(sb, "Other commands"); + this.Write(sb, "=============="); + + this.Write(sb, "> db.info", "Get database informations"); + this.Write(sb, "> dump", "Display dump database information"); + + this.Write(sb); + this.Write(sb, "Try:"); + this.Write(sb, " > db.customers.insert { _id:1, name:\"John Doe\", age: 37 }"); + this.Write(sb, " > db.customers.ensureIndex name"); + this.Write(sb, " > db.customers.find name like \"J\""); + this.Write(sb, " > db.customers.find _id > 0"); + + return sb.ToString(); + } + + private void Write(StringBuilder sb, string line1 = null, string line2 = null) + { + if (string.IsNullOrEmpty(line1)) + { + sb.AppendLine(); + } + else + { + sb.AppendLine(line1); + + if (!string.IsNullOrEmpty(line2)) + { + sb.AppendLine(" " + line2); + sb.AppendLine(); + } + } } } } diff --git a/LiteDB.Shell/Commands/Open.cs b/LiteDB.Shell/Commands/Open.cs new file mode 100644 index 000000000..42de91564 --- /dev/null +++ b/LiteDB.Shell/Commands/Open.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; + +namespace LiteDB.Shell.Commands +{ + internal class Open : ConsoleCommand + { + public override bool IsCommand(StringScanner s) + { + return s.Scan(@"open\s+").Length > 0; + } + + public override void Execute(LiteShell shell, StringScanner s, Display display, InputCommand input) + { + var filename = s.Scan(@".+"); + + if (shell.Database != null) + { + shell.Database.Dispose(); + } + + shell.Database = new LiteDatabase(filename); + } + } +} diff --git a/LiteDB.Shell/Commands/Pretty.cs b/LiteDB.Shell/Commands/Pretty.cs index c4d8e76e5..267e72920 100644 --- a/LiteDB.Shell/Commands/Pretty.cs +++ b/LiteDB.Shell/Commands/Pretty.cs @@ -6,14 +6,14 @@ namespace LiteDB.Shell.Commands { - internal class Pretty : ILiteCommand + internal class Pretty : ConsoleCommand { - public bool IsCommand(StringScanner s) + public override bool IsCommand(StringScanner s) { return s.Scan(@"pretty\s*").Length > 0; } - public void Execute(LiteDatabase db, StringScanner s, Display display) + public override void Execute(LiteShell shell, StringScanner s, Display display, InputCommand input) { display.Pretty = !(s.Scan(@"off\s*").Length > 0); } diff --git a/LiteDB.Shell/Commands/Quit.cs b/LiteDB.Shell/Commands/Quit.cs index 63a559d0f..e8a1fc055 100644 --- a/LiteDB.Shell/Commands/Quit.cs +++ b/LiteDB.Shell/Commands/Quit.cs @@ -6,14 +6,14 @@ namespace LiteDB.Shell.Commands { - internal class Quit : ILiteCommand + internal class Quit : ConsoleCommand { - public bool IsCommand(StringScanner s) + public override bool IsCommand(StringScanner s) { return s.Match(@"(quit|exit)$"); } - public void Execute(LiteDatabase db, StringScanner s, Display display) + public override void Execute(LiteShell shell, StringScanner s, Display display, InputCommand input) { Environment.Exit(0); } diff --git a/LiteDB.Shell/Commands/Run.cs b/LiteDB.Shell/Commands/Run.cs new file mode 100644 index 000000000..d93167858 --- /dev/null +++ b/LiteDB.Shell/Commands/Run.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Text; + +namespace LiteDB.Shell.Commands +{ + internal class Run : ConsoleCommand + { + public override bool IsCommand(StringScanner s) + { + return s.Scan(@"run\s+").Length > 0; + } + + public override void Execute(LiteShell shell, StringScanner s, Display display, InputCommand input) + { + var filename = s.Scan(@".+").Trim(); + + foreach (var line in File.ReadAllLines(filename)) + { + input.Queue.Enqueue(line); + } + } + } +} diff --git a/LiteDB.Shell/Commands/Spool.cs b/LiteDB.Shell/Commands/Spool.cs index ab925cd2f..1def94a72 100644 --- a/LiteDB.Shell/Commands/Spool.cs +++ b/LiteDB.Shell/Commands/Spool.cs @@ -7,16 +7,16 @@ namespace LiteDB.Shell.Commands { - internal class Spool : ILiteCommand + internal class Spool : ConsoleCommand { private TextWriter _writer; - public bool IsCommand(StringScanner s) + public override bool IsCommand(StringScanner s) { return s.Scan(@"spo(ol)?\s*").Length > 0; } - public void Execute(LiteDatabase db, StringScanner s, Display display) + public override void Execute(LiteShell shell, StringScanner s, Display display, InputCommand input) { if(s.Scan("false|off").Length > 0 && _writer != null) { @@ -27,13 +27,14 @@ public void Execute(LiteDatabase db, StringScanner s, Display display) } else if(_writer == null) { - if (db == null) throw new LiteException("No database"); + if (shell.Database == null) throw new LiteException("No database"); - var path = - Path.Combine(Path.GetDirectoryName(db.ConnectionString.Filename), - string.Format("{0}-spool-{1:yyyy-MM-dd-HH-mm}.txt", Path.GetFileNameWithoutExtension(db.ConnectionString.Filename), DateTime.Now)); + var dbfilename = shell.Database.ConnectionString.Filename; + var path = Path.Combine(Path.GetDirectoryName(dbfilename), + string.Format("{0}-spool-{1:yyyy-MM-dd-HH-mm}.txt", Path.GetFileNameWithoutExtension(dbfilename), DateTime.Now)); _writer = File.CreateText(path); + display.TextWriters.Add(_writer); } } diff --git a/LiteDB.Shell/Commands/Timer.cs b/LiteDB.Shell/Commands/Timer.cs new file mode 100644 index 000000000..adaf43e07 --- /dev/null +++ b/LiteDB.Shell/Commands/Timer.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Text; + +namespace LiteDB.Shell.Commands +{ + internal class Timer : ConsoleCommand + { + public override bool IsCommand(StringScanner s) + { + return s.Match(@"timer$"); + } + + public override void Execute(LiteShell shell, StringScanner s, Display display, InputCommand input) + { + input.Timer.Start(); + } + } +} diff --git a/LiteDB.Shell/ConsoleCommand.cs b/LiteDB.Shell/ConsoleCommand.cs new file mode 100644 index 000000000..e9ea6a8a1 --- /dev/null +++ b/LiteDB.Shell/ConsoleCommand.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace LiteDB.Shell +{ + public abstract class ConsoleCommand + { + public abstract bool IsCommand(StringScanner s); + public abstract void Execute(LiteShell shell, StringScanner s, Display display, InputCommand input); + + private static List Commands = new List(); + + static ConsoleCommand() + { + var type = typeof(ConsoleCommand); + var types = AppDomain.CurrentDomain.GetAssemblies() + .SelectMany(s => s.GetTypes()) + .Where(p => type.IsAssignableFrom(p) && p.IsClass && !p.IsAbstract); + + foreach (var t in types) + { + Commands.Add((ConsoleCommand)Activator.CreateInstance(t)); + } + } + + /// + /// If command is a console command, execute and returns true - if not, just returns false + /// + public static bool TryExecute(string command, LiteShell shell, Display display, InputCommand input) + { + var s = new StringScanner(command); + + foreach (var cmd in Commands) + { + if (cmd.IsCommand(s)) + { + cmd.Execute(shell, s, display, input); + return true; + } + } + + return false; + } + } +} diff --git a/LiteDB/Shell/Display.cs b/LiteDB.Shell/Display.cs similarity index 62% rename from LiteDB/Shell/Display.cs rename to LiteDB.Shell/Display.cs index e4f0e6300..9f1454c25 100644 --- a/LiteDB/Shell/Display.cs +++ b/LiteDB.Shell/Display.cs @@ -29,11 +29,6 @@ public void WritePrompt(string text) this.Write(ConsoleColor.White, text); } - public void WriteResult(string text) - { - this.WriteLine(ConsoleColor.DarkCyan, text); - } - public void WriteInfo(string text) { this.WriteLine(ConsoleColor.Gray, text); @@ -44,31 +39,36 @@ public void WriteError(string err) this.WriteLine(ConsoleColor.Red, err); } - public void WriteHelp(string line1, string line2) - { - this.WriteLine(ConsoleColor.Cyan, line1); - this.WriteLine(ConsoleColor.DarkCyan, " " + line2); - } - - public void WriteBson(BsonValue result) - { - this.WriteLine(ConsoleColor.DarkCyan, JsonEx.Serialize(result, this.Pretty, false)); - } - - public void WriteBson(IEnumerable result) - where T : BsonValue + public void WriteResult(BsonValue result) { var index = 0; - foreach (var doc in result) + if (result.IsNull) return; + + if (result.IsObject) { - this.Write(ConsoleColor.Cyan, string.Format("[{0}]:{1}", ++index, this.Pretty ? Environment.NewLine : " ")); - this.WriteBson(doc); + this.WriteLine(ConsoleColor.DarkCyan, JsonSerializer.Serialize(result, this.Pretty, false)); } - - if (index == 0) + else if (result.IsArray) + { + foreach (var doc in result.AsArray) + { + this.Write(ConsoleColor.Cyan, string.Format("[{0}]:{1}", ++index, this.Pretty ? Environment.NewLine : " ")); + this.WriteLine(ConsoleColor.DarkCyan, JsonSerializer.Serialize(doc, this.Pretty, false)); + } + + if (index == 0) + { + this.WriteLine(ConsoleColor.DarkCyan, "no documents"); + } + } + else if(result.Type == BsonType.String) + { + this.WriteLine(ConsoleColor.DarkCyan, result.AsString); + } + else { - this.WriteLine(ConsoleColor.DarkCyan, "no documents"); + this.WriteLine(ConsoleColor.DarkCyan, JsonSerializer.Serialize(result, this.Pretty, false)); } } diff --git a/LiteDB.Shell/InputCommand.cs b/LiteDB.Shell/InputCommand.cs index 1f1d55b4d..14361128e 100644 --- a/LiteDB.Shell/InputCommand.cs +++ b/LiteDB.Shell/InputCommand.cs @@ -9,21 +9,23 @@ namespace LiteDB.Shell { public class InputCommand { - private Queue _queue; - private string _last = ""; - private Stopwatch _timer = new Stopwatch(); + public Queue Queue { get; set; } + public string Last { get; set; } + public Stopwatch Timer { get; set; } public InputCommand() { - _queue = new Queue(); + this.Queue = new Queue(); + this.Last = ""; + this.Timer = new Stopwatch(); } public string ReadCommand() { - if (_timer.IsRunning) + if (this.Timer.IsRunning) { Console.ForegroundColor = ConsoleColor.DarkYellow; - Console.Write(_timer.ElapsedMilliseconds.ToString("0000") + " "); + Console.Write(this.Timer.ElapsedMilliseconds.ToString("0000") + " "); } Console.ForegroundColor = ConsoleColor.White; @@ -50,28 +52,12 @@ public string ReadCommand() cmd = cmd.Trim(); - if (cmd == "ed") - { - this.OpenNotepad(); - return null; - } - else if (cmd == "timer") - { - _timer.Start(); - return null; - } - else if (cmd.StartsWith("run ")) - { - this.RunCommand(cmd.Substring(4)); - return null; - } + this.Last = cmd; - _last = cmd; - - if (_timer.IsRunning) + if (this.Timer.IsRunning) { - _timer.Reset(); - _timer.Start(); + this.Timer.Reset(); + this.Timer.Start(); } return cmd.Trim(); @@ -84,9 +70,9 @@ private string ReadLine() { Console.ForegroundColor = ConsoleColor.Gray; - if (_queue.Count > 0) + if (this.Queue.Count > 0) { - var cmd = _queue.Dequeue(); + var cmd = this.Queue.Dequeue(); Console.WriteLine(cmd); return cmd; } @@ -95,33 +81,5 @@ private string ReadLine() return Console.ReadLine(); } } - - /// - /// Open notepad and add each line as a new command - /// - private void OpenNotepad() - { - var temp = Path.GetTempPath() + "LiteDB.Shell.txt"; - - File.WriteAllText(temp, _last.Replace("\n", Environment.NewLine)); - - Process.Start("notepad.exe", temp).WaitForExit(); - - foreach (var line in File.ReadAllLines(temp)) - { - _queue.Enqueue(line); - } - } - - /// - /// Open a file and get each line as a new command - /// - private void RunCommand(string filename) - { - foreach (var line in File.ReadAllLines(filename.Trim())) - { - _queue.Enqueue(line); - } - } } } diff --git a/LiteDB.Shell/LiteDB.Shell.csproj b/LiteDB.Shell/LiteDB.Shell.csproj index 2ce170ef2..48763e114 100644 --- a/LiteDB.Shell/LiteDB.Shell.csproj +++ b/LiteDB.Shell/LiteDB.Shell.csproj @@ -53,12 +53,18 @@ + + + + + + diff --git a/LiteDB.Shell/Program.cs b/LiteDB.Shell/Program.cs index 1e350cd2e..e600e95db 100644 --- a/LiteDB.Shell/Program.cs +++ b/LiteDB.Shell/Program.cs @@ -13,12 +13,13 @@ static void Main(string[] args) { var shell = new LiteShell(); var input = new InputCommand(); + var display = new Display(); shell.RegisterAll(); - shell.Display.TextWriters.Add(Console.Out); + display.TextWriters.Add(Console.Out); // show welcome message - shell.Display.WriteWelcome(); + display.WriteWelcome(); // if has a argument, its database file - try open if (args.Length > 0) @@ -29,7 +30,7 @@ static void Main(string[] args) } catch (Exception ex) { - shell.Display.WriteError(ex.Message); + display.WriteError(ex.Message); } } @@ -42,25 +43,38 @@ static void Main(string[] args) try { - if (cmd.StartsWith("open ")) - { - if (shell.Database != null) - { - shell.Database.Dispose(); - } + var isConsoleCommand = ConsoleCommand.TryExecute(cmd, shell, display, input); - shell.Database = new LiteDatabase(cmd.Substring(5)); - } - else + if (isConsoleCommand == false) { - shell.Run(cmd); + var result = shell.Run(cmd); + + display.WriteResult(result); } } catch (Exception ex) { - shell.Display.WriteError(ex.Message); + display.WriteError(ex.Message); } } } + + static void Open(LiteShell shell, string command, Display display) + { + if (shell.Database != null) + { + shell.Database.Dispose(); + } + + shell.Database = new LiteDatabase(command.Substring(5)); + } + + static void Spool(LiteShell shell, string command, Display display) + { + } + + static void Help(Display display) + { + } } } diff --git a/LiteDB/Database/LiteDatabase.cs b/LiteDB/Database/LiteDatabase.cs index 6fce505d0..28a9074d9 100644 --- a/LiteDB/Database/LiteDatabase.cs +++ b/LiteDB/Database/LiteDatabase.cs @@ -192,6 +192,7 @@ public void Rollback() public void Dispose() { this.Disk.Dispose(); + this.Cache.Dispose(); } } } diff --git a/LiteDB/Document/BsonArray.cs b/LiteDB/Document/BsonArray.cs index 0692f6810..a430bca18 100644 --- a/LiteDB/Document/BsonArray.cs +++ b/LiteDB/Document/BsonArray.cs @@ -58,5 +58,18 @@ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return this.GetEnumerator(); } + + public static BsonArray FromEnumerable(IEnumerable array) + where T : BsonValue + { + var result = new BsonArray(); + + foreach (var item in array) + { + result.Add(item); + } + + return result; + } } } diff --git a/LiteDB/Document/BsonDocument.cs b/LiteDB/Document/BsonDocument.cs index d968a8a0e..4dbad856a 100644 --- a/LiteDB/Document/BsonDocument.cs +++ b/LiteDB/Document/BsonDocument.cs @@ -24,12 +24,13 @@ public BsonDocument(BsonValue value) : base(value.AsObject.RawValue) { if (!this.HasKey("_id")) throw new ArgumentException("BsonDocument must have an _id key"); - - this.Id = this["_id"].RawValue; - this.RemoveKey("_id"); } - public object Id { get; set; } + public object Id + { + get { return this["_id"].RawValue; } + set { this["_id"] = new BsonValue(value); } + } internal BsonDocument(Dictionary obj) : base(obj) diff --git a/LiteDB/LiteDB.csproj b/LiteDB/LiteDB.csproj index 32dfab0c2..a3a68b622 100644 --- a/LiteDB/LiteDB.csproj +++ b/LiteDB/LiteDB.csproj @@ -61,8 +61,8 @@ - - + + @@ -88,10 +88,10 @@ - - - - + + + + @@ -104,13 +104,12 @@ - - - - - - - + + + + + + @@ -118,7 +117,6 @@ - diff --git a/LiteDB/Serializer/BsonIdAttribute.cs b/LiteDB/Serializer/Bson/BsonIdAttribute.cs similarity index 100% rename from LiteDB/Serializer/BsonIdAttribute.cs rename to LiteDB/Serializer/Bson/BsonIdAttribute.cs diff --git a/LiteDB/Serializer/BsonIgnoreAttribute.cs b/LiteDB/Serializer/Bson/BsonIgnoreAttribute.cs similarity index 100% rename from LiteDB/Serializer/BsonIgnoreAttribute.cs rename to LiteDB/Serializer/Bson/BsonIgnoreAttribute.cs diff --git a/LiteDB/Serializer/BsonSerializer.cs b/LiteDB/Serializer/Bson/BsonSerializer.cs similarity index 89% rename from LiteDB/Serializer/BsonSerializer.cs rename to LiteDB/Serializer/Bson/BsonSerializer.cs index 0f9a4130f..7c1edbce8 100644 --- a/LiteDB/Serializer/BsonSerializer.cs +++ b/LiteDB/Serializer/Bson/BsonSerializer.cs @@ -25,25 +25,19 @@ static BsonSerializer() public static byte[] Serialize(object obj) { if (obj == null) throw new ArgumentNullException("obj"); - byte[] bytes; - if(obj is BsonDocument) - { - bytes = fastBinaryJSON.BJSON.ToBJSON(((BsonDocument)obj).RawValue); - } - else + // add parameters on serialization to ignore BsonIgnoreAttribute + Id attribute + var param = new fastBinaryJSON.BJSONParameters { - // add parameters on serialization to ignore BsonIgnoreAttribute + Id attribute - var param = new fastBinaryJSON.BJSONParameters - { - UseExtensions = false, - UsingGlobalTypes = false, - IgnoreAttributes = new List { typeof(BsonIgnoreAttribute) }, - IgnoreProperty = GetIdProperty(obj.GetType()) - }; - - bytes = fastBinaryJSON.BJSON.ToBJSON(obj, param); - } + UseExtensions = false, + UsingGlobalTypes = false, + IgnoreAttributes = new List { typeof(BsonIgnoreAttribute) }, + IgnoreProperty = obj is BsonDocument ? "_id" : GetIdProperty(obj.GetType()).Name + }; + + var bytes = fastBinaryJSON.BJSON.ToBJSON( + obj is BsonDocument ? ((BsonDocument)obj).RawValue : obj, + param); if (bytes.Length > BsonDocument.MAX_DOCUMENT_SIZE) { diff --git a/LiteDB/Serializer/JsonEx/JsonReader.cs b/LiteDB/Serializer/Json/JsonReader.cs similarity index 100% rename from LiteDB/Serializer/JsonEx/JsonReader.cs rename to LiteDB/Serializer/Json/JsonReader.cs diff --git a/LiteDB/Serializer/JsonEx/JsonEx.cs b/LiteDB/Serializer/Json/JsonSerializer.cs similarity index 97% rename from LiteDB/Serializer/JsonEx/JsonEx.cs rename to LiteDB/Serializer/Json/JsonSerializer.cs index 03290aa2c..93c4ab8f4 100644 --- a/LiteDB/Serializer/JsonEx/JsonEx.cs +++ b/LiteDB/Serializer/Json/JsonSerializer.cs @@ -7,9 +7,9 @@ namespace LiteDB { /// - /// Static class for serialize/deserialize BsonDocuments into JsonEx (extended json format) + /// Static class for serialize/deserialize BsonDocuments into Json extended format /// - public class JsonEx + public class JsonSerializer { /// /// Serialize a BsonDocument (or any BsonValue) into a JsonEx string diff --git a/LiteDB/Serializer/JsonEx/JsonWriter.cs b/LiteDB/Serializer/Json/JsonWriter.cs similarity index 93% rename from LiteDB/Serializer/JsonEx/JsonWriter.cs rename to LiteDB/Serializer/Json/JsonWriter.cs index 7b8d76fd5..a2ecbdf18 100644 --- a/LiteDB/Serializer/JsonEx/JsonWriter.cs +++ b/LiteDB/Serializer/Json/JsonWriter.cs @@ -28,14 +28,7 @@ public string Serialize(BsonValue value) _indent = 0; _spacer = _pretty ? " " : ""; - if (value is BsonDocument) - { - this.WriteObject(value.AsObject, (value as BsonDocument).Id); - } - else - { - this.WriteValue(value); - } + this.WriteValue(value); return _sb.ToString().Trim(); } @@ -52,7 +45,7 @@ private void WriteValue(BsonValue value) } else if (value.Type == BsonType.Object) { - this.WriteObject(value.AsObject, null); + this.WriteObject(value.AsObject); } else if (value.Type == BsonType.Byte) { @@ -88,19 +81,24 @@ private void WriteValue(BsonValue value) } } - private void WriteObject(BsonObject obj, object docId) + private void WriteObject(BsonObject obj) { var hasData = obj.Keys.Length > 0; this.WriteStartBlock("{", hasData); - if (docId != null) + var index = 0; + + var keys = new List(obj.Keys); + + // just for add _id as first place + if (keys.Contains("_id")) { - this.WriteKeyValue("_id", new BsonValue(docId), hasData); + keys.Remove("_id"); + keys.Insert(0, "_id"); } - var index = 0; - foreach (var key in obj.Keys) + foreach (var key in keys) { this.WriteKeyValue(key, obj[key], index++ < obj.Keys.Length - 1); } diff --git a/LiteDB/Serializer/fastBinaryJSON/BJSON.cs b/LiteDB/Serializer/fastBinaryJSON/BJSON.cs index 81d46f914..660cf86f8 100644 --- a/LiteDB/Serializer/fastBinaryJSON/BJSON.cs +++ b/LiteDB/Serializer/fastBinaryJSON/BJSON.cs @@ -89,7 +89,7 @@ public sealed class BJSONParameters /// /// Ignore this property when serialize object (CHANGE TO ** LITEDB **) /// - public PropertyInfo IgnoreProperty = null; + public string IgnoreProperty = null; /// /// If you have parametric and no default constructor for you classes (default = False) /// diff --git a/LiteDB/Serializer/fastBinaryJSON/Reflection.cs b/LiteDB/Serializer/fastBinaryJSON/Reflection.cs index 60f98b3ad..8f2a1cf1f 100644 --- a/LiteDB/Serializer/fastBinaryJSON/Reflection.cs +++ b/LiteDB/Serializer/fastBinaryJSON/Reflection.cs @@ -498,7 +498,7 @@ internal Getters[] GetGetters(Type type, BJSONParameters param) foreach (PropertyInfo p in props) { // CHANGED FOR ** LITEDB ** IgnoreProperty - if (param.IgnoreProperty != null && p.MetadataToken == param.IgnoreProperty.MetadataToken && p.Module.Equals(param.IgnoreProperty.Module)) continue; + if (param.IgnoreProperty != null && p.Name == param.IgnoreProperty) continue; if (!p.CanWrite && param.ShowReadOnlyProperties == false) continue; if (param.IgnoreAttributes != null) { diff --git a/LiteDB/Shell/Commands/Collections/Bulk.cs b/LiteDB/Shell/Commands/Collections/Bulk.cs index 10425bb68..e39fbe36f 100644 --- a/LiteDB/Shell/Commands/Collections/Bulk.cs +++ b/LiteDB/Shell/Commands/Collections/Bulk.cs @@ -14,14 +14,14 @@ public bool IsCommand(StringScanner s) return this.IsCollectionCommand(s, "bulk"); } - public void Execute(LiteDatabase db, StringScanner s, Display display) + public BsonValue Execute(LiteDatabase db, StringScanner s) { if (db == null) throw new LiteException("No database"); var col = this.ReadCollection(db, s); var filename = s.Scan(@".*"); var json = File.ReadAllText(filename, Encoding.UTF8); - var docs = JsonEx.DeserializeArray(json); + var docs = JsonSerializer.DeserializeArray(json); var count = 0; db.BeginTrans(); @@ -34,7 +34,7 @@ public void Execute(LiteDatabase db, StringScanner s, Display display) db.Commit(); - display.WriteBson(count); + return count; } } } diff --git a/LiteDB/Shell/Commands/Collections/Count.cs b/LiteDB/Shell/Commands/Collections/Count.cs index e5d4314f0..7a0ea5efa 100644 --- a/LiteDB/Shell/Commands/Collections/Count.cs +++ b/LiteDB/Shell/Commands/Collections/Count.cs @@ -13,14 +13,14 @@ public bool IsCommand(StringScanner s) return this.IsCollectionCommand(s, "count"); } - public void Execute(LiteDatabase db, StringScanner s, Display display) + public BsonValue Execute(LiteDatabase db, StringScanner s) { if (db == null) throw new LiteException("No database"); var col = this.ReadCollection(db, s); var query = this.ReadQuery(s); - display.WriteBson(col.Count(query)); + return col.Count(query); } } } diff --git a/LiteDB/Shell/Commands/Collections/Delete.cs b/LiteDB/Shell/Commands/Collections/Delete.cs index 009bf4d50..f729999fc 100644 --- a/LiteDB/Shell/Commands/Collections/Delete.cs +++ b/LiteDB/Shell/Commands/Collections/Delete.cs @@ -13,14 +13,14 @@ public bool IsCommand(StringScanner s) return this.IsCollectionCommand(s, "delete"); } - public void Execute(LiteDatabase db, StringScanner s, Display display) + public BsonValue Execute(LiteDatabase db, StringScanner s) { if (db == null) throw new LiteException("No database"); var col = this.ReadCollection(db, s); var query = this.ReadQuery(s); - display.WriteBson(col.Delete(query)); + return col.Delete(query); } } } diff --git a/LiteDB/Shell/Commands/Collections/Drop.cs b/LiteDB/Shell/Commands/Collections/Drop.cs index 2def0e84c..f22fece16 100644 --- a/LiteDB/Shell/Commands/Collections/Drop.cs +++ b/LiteDB/Shell/Commands/Collections/Drop.cs @@ -13,11 +13,13 @@ public bool IsCommand(StringScanner s) return this.IsCollectionCommand(s, "drop"); } - public void Execute(LiteDatabase db, StringScanner s, Display display) + public BsonValue Execute(LiteDatabase db, StringScanner s) { if (db == null) throw new LiteException("No database"); - display.WriteBson(this.ReadCollection(db, s).Drop()); + var col = this.ReadCollection(db, s); + + return col.Drop(); } } } diff --git a/LiteDB/Shell/Commands/Collections/DropIndex.cs b/LiteDB/Shell/Commands/Collections/DropIndex.cs index 2806a0466..2f29a531f 100644 --- a/LiteDB/Shell/Commands/Collections/DropIndex.cs +++ b/LiteDB/Shell/Commands/Collections/DropIndex.cs @@ -13,11 +13,14 @@ public bool IsCommand(StringScanner s) return this.IsCollectionCommand(s, "drop[iI]ndex"); } - public void Execute(LiteDatabase db, StringScanner s, Display display) + public BsonValue Execute(LiteDatabase db, StringScanner s) { if (db == null) throw new LiteException("No database"); - display.WriteBson(this.ReadCollection(db, s).DropIndex(s.Scan(@"\w+(.\w+)*").Trim())); + var col = this.ReadCollection(db, s); + var index = s.Scan(@"\w+(.\w+)*").Trim(); + + return col.DropIndex(index); } } } diff --git a/LiteDB/Shell/Commands/Collections/EnsureIndex.cs b/LiteDB/Shell/Commands/Collections/EnsureIndex.cs index e5f44ddc2..9cc10360d 100644 --- a/LiteDB/Shell/Commands/Collections/EnsureIndex.cs +++ b/LiteDB/Shell/Commands/Collections/EnsureIndex.cs @@ -13,7 +13,7 @@ public bool IsCommand(StringScanner s) return this.IsCollectionCommand(s, "ensure[iI]ndex"); } - public void Execute(LiteDatabase db, StringScanner s, Display display) + public BsonValue Execute(LiteDatabase db, StringScanner s) { if (db == null) throw new LiteException("No database"); @@ -21,7 +21,7 @@ public void Execute(LiteDatabase db, StringScanner s, Display display) var field = s.Scan(@"\w+(.\w+)*"); var unique = s.Scan(@"\s*unique$"); - display.WriteBson(col.EnsureIndex(field, unique.Length > 0)); + return col.EnsureIndex(field, unique.Length > 0); } } } diff --git a/LiteDB/Shell/Commands/Collections/Exec.cs b/LiteDB/Shell/Commands/Collections/Exec.cs index dc88673e7..ce1590c23 100644 --- a/LiteDB/Shell/Commands/Collections/Exec.cs +++ b/LiteDB/Shell/Commands/Collections/Exec.cs @@ -15,7 +15,7 @@ public bool IsCommand(StringScanner s) return this.IsCollectionCommand(s, "exec"); } - public void Execute(LiteDatabase db, StringScanner s, Display display) + public BsonValue Execute(LiteDatabase db, StringScanner s) { if (db == null) throw new LiteException("No database"); @@ -36,7 +36,7 @@ public void Execute(LiteDatabase db, StringScanner s, Display display) db.Commit(); - display.WriteBson(docs.Length); + return docs.Length; } catch (Exception ex) { @@ -56,7 +56,7 @@ public class Program { public static void DoWork( object id, BsonDocument doc, - Collection col, + LiteCollection col, LiteDatabase db) { [code] } }"; diff --git a/LiteDB/Shell/Commands/Collections/Find.cs b/LiteDB/Shell/Commands/Collections/Find.cs index ea5e8f7b5..de340aabd 100644 --- a/LiteDB/Shell/Commands/Collections/Find.cs +++ b/LiteDB/Shell/Commands/Collections/Find.cs @@ -13,15 +13,16 @@ public bool IsCommand(StringScanner s) return this.IsCollectionCommand(s, "find"); } - public void Execute(LiteDatabase db, StringScanner s, Display display) + public BsonValue Execute(LiteDatabase db, StringScanner s) { if (db == null) throw new LiteException("No database"); var col = this.ReadCollection(db, s); var top = this.ReadTop(s); var query = this.ReadQuery(s); + var docs = col.Find(query).Take(top); - display.WriteBson(col.Find(query).Take(top)); + return BsonArray.FromEnumerable(docs); } } } diff --git a/LiteDB/Shell/Commands/Collections/Indexes.cs b/LiteDB/Shell/Commands/Collections/Indexes.cs index 7077e51d7..56f96c57d 100644 --- a/LiteDB/Shell/Commands/Collections/Indexes.cs +++ b/LiteDB/Shell/Commands/Collections/Indexes.cs @@ -13,11 +13,14 @@ public bool IsCommand(StringScanner s) return this.IsCollectionCommand(s, "indexes$"); } - public void Execute(LiteDatabase db, StringScanner s, Display display) + public BsonValue Execute(LiteDatabase db, StringScanner s) { if (db == null) throw new LiteException("No database"); - display.WriteBson(this.ReadCollection(db, s).GetIndexes()); + var col = this.ReadCollection(db, s); + var docs = col.GetIndexes(); + + return BsonArray.FromEnumerable(docs); } } } diff --git a/LiteDB/Shell/Commands/Collections/Insert.cs b/LiteDB/Shell/Commands/Collections/Insert.cs index 8f329ed1a..1313736fe 100644 --- a/LiteDB/Shell/Commands/Collections/Insert.cs +++ b/LiteDB/Shell/Commands/Collections/Insert.cs @@ -13,7 +13,7 @@ public bool IsCommand(StringScanner s) return this.IsCollectionCommand(s, "insert"); } - public void Execute(LiteDatabase db, StringScanner s, Display display) + public BsonValue Execute(LiteDatabase db, StringScanner s) { if (db == null) throw new LiteException("No database"); @@ -21,6 +21,8 @@ public void Execute(LiteDatabase db, StringScanner s, Display display) var value = new JsonReader().ReadValue(s); col.Insert(new BsonDocument(value)); + + return BsonValue.Null; } } } diff --git a/LiteDB/Shell/Commands/Collections/Update.cs b/LiteDB/Shell/Commands/Collections/Update.cs index 04df6323a..c963e32f9 100644 --- a/LiteDB/Shell/Commands/Collections/Update.cs +++ b/LiteDB/Shell/Commands/Collections/Update.cs @@ -13,14 +13,14 @@ public bool IsCommand(StringScanner s) return this.IsCollectionCommand(s, "update"); } - public void Execute(LiteDatabase db, StringScanner s, Display display) + public BsonValue Execute(LiteDatabase db, StringScanner s) { if (db == null) throw new LiteException("No database"); var col = this.ReadCollection(db, s); - var value = new JsonReader().ReadValue(s); + var doc = new BsonDocument(new JsonReader().ReadValue(s)); - display.WriteBson(col.Update(new BsonDocument(value))); + return col.Update(doc); } } } diff --git a/LiteDB/Shell/Commands/Files/BaseFile.cs b/LiteDB/Shell/Commands/GridFS/BaseGridFS.cs similarity index 94% rename from LiteDB/Shell/Commands/Files/BaseFile.cs rename to LiteDB/Shell/Commands/GridFS/BaseGridFS.cs index 7f395886d..402a07105 100644 --- a/LiteDB/Shell/Commands/Files/BaseFile.cs +++ b/LiteDB/Shell/Commands/GridFS/BaseGridFS.cs @@ -5,7 +5,7 @@ namespace LiteDB.Shell.Commands { - public class BaseFile + public class BaseGridFS { public bool IsFileCommand(StringScanner s, string command) { diff --git a/LiteDB/Shell/Commands/Files/Delete.cs b/LiteDB/Shell/Commands/GridFS/Delete.cs similarity index 69% rename from LiteDB/Shell/Commands/Files/Delete.cs rename to LiteDB/Shell/Commands/GridFS/Delete.cs index da1a4fe26..6274f5ff2 100644 --- a/LiteDB/Shell/Commands/Files/Delete.cs +++ b/LiteDB/Shell/Commands/GridFS/Delete.cs @@ -7,20 +7,20 @@ namespace LiteDB.Shell.Commands { - public class FileDelete : BaseFile, ILiteCommand + public class FileDelete : BaseGridFS, ILiteCommand { public bool IsCommand(StringScanner s) { return this.IsFileCommand(s, "delete"); } - public void Execute(LiteDatabase db, StringScanner s, Display display) + public BsonValue Execute(LiteDatabase db, StringScanner s) { if (db == null) throw new LiteException("No database"); var id = this.ReadId(s); - display.WriteBson(db.GridFS.Delete(id)); + return db.GridFS.Delete(id); } } } diff --git a/LiteDB/Shell/Commands/Files/Download.cs b/LiteDB/Shell/Commands/GridFS/Download.cs similarity index 74% rename from LiteDB/Shell/Commands/Files/Download.cs rename to LiteDB/Shell/Commands/GridFS/Download.cs index ee398fd15..394d1fb0c 100644 --- a/LiteDB/Shell/Commands/Files/Download.cs +++ b/LiteDB/Shell/Commands/GridFS/Download.cs @@ -7,14 +7,14 @@ namespace LiteDB.Shell.Commands { - public class FileDownload : BaseFile, ILiteCommand + public class FileDownload : BaseGridFS, ILiteCommand { public bool IsCommand(StringScanner s) { return this.IsFileCommand(s, "download"); } - public void Execute(LiteDatabase db, StringScanner s, Display display) + public BsonValue Execute(LiteDatabase db, StringScanner s) { if (db == null) throw new LiteException("No database"); @@ -26,11 +26,12 @@ public void Execute(LiteDatabase db, StringScanner s, Display display) if (file != null) { file.SaveAs(filename, true); - display.WriteBson(file.AsDocument); + + return file.AsDocument; } else { - display.WriteBson(false); + return false; } } } diff --git a/LiteDB/Shell/Commands/Files/Find.cs b/LiteDB/Shell/Commands/GridFS/Find.cs similarity index 58% rename from LiteDB/Shell/Commands/Files/Find.cs rename to LiteDB/Shell/Commands/GridFS/Find.cs index f7fe894a6..118448698 100644 --- a/LiteDB/Shell/Commands/Files/Find.cs +++ b/LiteDB/Shell/Commands/GridFS/Find.cs @@ -6,20 +6,22 @@ namespace LiteDB.Shell.Commands { - public class FileFind : BaseFile, ILiteCommand + public class FileFind : BaseGridFS, ILiteCommand { public bool IsCommand(StringScanner s) { return this.IsFileCommand(s, "find"); } - public void Execute(LiteDatabase db, StringScanner s, Display display) + public BsonValue Execute(LiteDatabase db, StringScanner s) { if (db == null) throw new LiteException("No database"); if (s.HasTerminated) { - display.WriteBson(db.GridFS.FindAll().Select(x => x.AsDocument)); + var files = db.GridFS.FindAll().Select(x => x.AsDocument); + + return BsonArray.FromEnumerable(files); } else { @@ -27,16 +29,15 @@ public void Execute(LiteDatabase db, StringScanner s, Display display) if (id.EndsWith("*") || id.EndsWith("%")) { - display.WriteBson(db.GridFS.Find(id.Substring(0, id.Length - 1)).Select(x => x.AsDocument)); + var files = db.GridFS.Find(id.Substring(0, id.Length - 1)).Select(x => x.AsDocument); + + return BsonArray.FromEnumerable(files); } else { var file = db.GridFS.FindById(id); - if (file != null) - { - display.WriteBson(file.AsDocument); - } + return file != null ? file.AsDocument : BsonValue.Null; } } } diff --git a/LiteDB/Shell/Commands/Files/Update.cs b/LiteDB/Shell/Commands/GridFS/Update.cs similarity index 62% rename from LiteDB/Shell/Commands/Files/Update.cs rename to LiteDB/Shell/Commands/GridFS/Update.cs index a1971c796..34eb9a05e 100644 --- a/LiteDB/Shell/Commands/Files/Update.cs +++ b/LiteDB/Shell/Commands/GridFS/Update.cs @@ -7,22 +7,21 @@ namespace LiteDB.Shell.Commands { - public class FileUpdate : BaseFile, ILiteCommand + public class FileUpdate : BaseGridFS, ILiteCommand { public bool IsCommand(StringScanner s) { return this.IsFileCommand(s, "update"); } - public void Execute(LiteDatabase db, StringScanner s, Display display) + public BsonValue Execute(LiteDatabase db, StringScanner s) { if (db == null) throw new LiteException("No database"); var id = this.ReadId(s); + var metadata = new JsonReader().ReadValue(s).AsObject; - var result = db.GridFS.SetMetadata(id, new JsonReader().ReadValue(s).AsObject); - - display.WriteBson(result); + return db.GridFS.SetMetadata(id, metadata); } } } diff --git a/LiteDB/Shell/Commands/Files/Upload.cs b/LiteDB/Shell/Commands/GridFS/Upload.cs similarity index 78% rename from LiteDB/Shell/Commands/Files/Upload.cs rename to LiteDB/Shell/Commands/GridFS/Upload.cs index 6401f1cb7..74134603b 100644 --- a/LiteDB/Shell/Commands/Files/Upload.cs +++ b/LiteDB/Shell/Commands/GridFS/Upload.cs @@ -7,14 +7,14 @@ namespace LiteDB.Shell.Commands { - public class FileUpload : BaseFile, ILiteCommand + public class FileUpload : BaseGridFS, ILiteCommand { public bool IsCommand(StringScanner s) { return this.IsFileCommand(s, "upload"); } - public void Execute(LiteDatabase db, StringScanner s, Display display) + public BsonValue Execute(LiteDatabase db, StringScanner s) { if (db == null) throw new LiteException("No database"); @@ -26,7 +26,7 @@ public void Execute(LiteDatabase db, StringScanner s, Display display) var file = db.GridFS.Upload(id, filename); - display.WriteBson(file.AsDocument); + return file.AsDocument; } } } diff --git a/LiteDB/Shell/Commands/ILiteCommand.cs b/LiteDB/Shell/Commands/ILiteCommand.cs index eeed4c759..6cb9593ed 100644 --- a/LiteDB/Shell/Commands/ILiteCommand.cs +++ b/LiteDB/Shell/Commands/ILiteCommand.cs @@ -8,6 +8,6 @@ namespace LiteDB.Shell public interface ILiteCommand { bool IsCommand(StringScanner s); - void Execute(LiteDatabase db, StringScanner s, Display display); + BsonValue Execute(LiteDatabase db, StringScanner s); } } diff --git a/LiteDB/Shell/Commands/LiteCommandResult.cs b/LiteDB/Shell/Commands/LiteCommandResult.cs deleted file mode 100644 index b9cba6d2a..000000000 --- a/LiteDB/Shell/Commands/LiteCommandResult.cs +++ /dev/null @@ -1,69 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace LiteDB.Shell -{ - public enum LiteCommandResponseType { Error, Void, Text, BsonValue, BsonDocument, BsonDocuments } - - /// - /// Represent a result from a command shell - /// - public class LiteCommandResult - { - public LiteCommandResponseType ResponseType { get; private set; } - - public bool Ok { get; private set; } - - public BsonValue Response { get; private set; } - - public string ResponseText { get; private set; } - - public string ErrorMessage { get; private set; } - - #region Response Converters - - public BsonValue ToBson() - { - return (BsonValue)this.Response; - } - - public BsonDocument ToBsonDocument() - { - return (BsonDocument)this.Response; - } - - public IEnumerable ToBsonDocuments() - { - return (IEnumerable)this.Response; - } - - public string ToText() - { - return (string)this.Response; - } - - #endregion - - #region Static Constructors - - internal static LiteCommandResult Error(Exception ex) - { - return new LiteCommandResult { Ok = false, ResponseType = LiteCommandResponseType.Error, ErrorMessage = ex.Message }; - } - - internal static LiteCommandResult Text(string text) - { - return new LiteCommandResult { Ok = true, ResponseType = LiteCommandResponseType.Text, Response = text }; - } - - internal static LiteCommandResult Bson(BsonValue value) - { - return new LiteCommandResult { Ok = true, ResponseType = LiteCommandResponseType.BsonValue, Response = value }; - } - - #endregion - - } -} diff --git a/LiteDB/Shell/Commands/Others/Dump.cs b/LiteDB/Shell/Commands/Others/Dump.cs index fea26f11d..8211142e0 100644 --- a/LiteDB/Shell/Commands/Others/Dump.cs +++ b/LiteDB/Shell/Commands/Others/Dump.cs @@ -13,18 +13,26 @@ public bool IsCommand(StringScanner s) return s.Scan(@"dump\s*").Length > 0; } - public void Execute(LiteDatabase db, StringScanner s, Display display) + public BsonValue Execute(LiteDatabase db, StringScanner s) { if (db == null) throw new LiteException("No database"); + var result = new StringBuilder(); if (s.HasTerminated || s.Match("mem$")) { - display.WriteResult(DumpDatabase.Pages(db, s.Match("mem$"))); + var mem = s.Match("mem$"); + + result = DumpDatabase.Pages(db, mem); } else { - display.WriteResult(DumpDatabase.Index(db, s.Scan(@"\w+"), s.Scan(@"\s+\w+").Trim())); + var col = s.Scan(@"\w+"); + var field = s.Scan(@"\s+\w+").Trim(); + + result = DumpDatabase.Index(db, col, field); } + + return result.ToString(); } } } diff --git a/LiteDB/Shell/Commands/Others/Info.cs b/LiteDB/Shell/Commands/Others/Info.cs index c812d348f..21e6400e8 100644 --- a/LiteDB/Shell/Commands/Others/Info.cs +++ b/LiteDB/Shell/Commands/Others/Info.cs @@ -13,11 +13,11 @@ public bool IsCommand(StringScanner s) return s.Match(@"db\.info$"); } - public void Execute(LiteDatabase db, StringScanner s, Display display) + public BsonValue Execute(LiteDatabase db, StringScanner s) { if (db == null) throw new LiteException("No database"); - display.WriteBson(db.GetDatabaseInfo()); + return db.GetDatabaseInfo(); } } } diff --git a/LiteDB/Shell/Commands/Others/ShowCollections.cs b/LiteDB/Shell/Commands/Others/ShowCollections.cs index 38702dc4a..986481474 100644 --- a/LiteDB/Shell/Commands/Others/ShowCollections.cs +++ b/LiteDB/Shell/Commands/Others/ShowCollections.cs @@ -13,11 +13,13 @@ public bool IsCommand(StringScanner s) return s.Match(@"show\scollections"); } - public void Execute(LiteDatabase db, StringScanner s, Display display) + public BsonValue Execute(LiteDatabase db, StringScanner s) { if (db == null) throw new LiteException("No database"); - display.WriteResult(string.Join("\n", db.GetCollectionNames().OrderBy(x => x).ToArray())); + var cols = db.GetCollectionNames().OrderBy(x => x).ToArray(); + + return string.Join("\n", cols); } } } diff --git a/LiteDB/Shell/Commands/Transactions/Begin.cs b/LiteDB/Shell/Commands/Transactions/Begin.cs index 0c637a992..b3fc865fa 100644 --- a/LiteDB/Shell/Commands/Transactions/Begin.cs +++ b/LiteDB/Shell/Commands/Transactions/Begin.cs @@ -13,11 +13,13 @@ public bool IsCommand(StringScanner s) return s.Scan(@"begin(\s+trans)?$").Length > 0; } - public void Execute(LiteDatabase db, StringScanner s, Display display) + public BsonValue Execute(LiteDatabase db, StringScanner s) { if (db == null) throw new LiteException("No database"); db.BeginTrans(); + + return BsonValue.Null; } } } diff --git a/LiteDB/Shell/Commands/Transactions/Commit.cs b/LiteDB/Shell/Commands/Transactions/Commit.cs index ba477f151..c5a1c0bb9 100644 --- a/LiteDB/Shell/Commands/Transactions/Commit.cs +++ b/LiteDB/Shell/Commands/Transactions/Commit.cs @@ -13,11 +13,13 @@ public bool IsCommand(StringScanner s) return s.Scan(@"commit(\s+trans)?$").Length > 0; } - public void Execute(LiteDatabase db, StringScanner s, Display display) + public BsonValue Execute(LiteDatabase db, StringScanner s) { if (db == null) throw new LiteException("No database"); db.Commit(); + + return BsonValue.Null; } } } diff --git a/LiteDB/Shell/Commands/Transactions/Rollback.cs b/LiteDB/Shell/Commands/Transactions/Rollback.cs index 3e1670876..52e1a0773 100644 --- a/LiteDB/Shell/Commands/Transactions/Rollback.cs +++ b/LiteDB/Shell/Commands/Transactions/Rollback.cs @@ -13,11 +13,13 @@ public bool IsCommand(StringScanner s) return s.Scan(@"rollback(\s+trans)?$").Length > 0; } - public void Execute(LiteDatabase db, StringScanner s, Display display) + public BsonValue Execute(LiteDatabase db, StringScanner s) { if (db == null) throw new LiteException("No database"); db.Rollback(); + + return BsonValue.Null; } } } diff --git a/LiteDB/Shell/LiteShell.cs b/LiteDB/Shell/LiteShell.cs index 013d35e7f..11efc59b0 100644 --- a/LiteDB/Shell/LiteShell.cs +++ b/LiteDB/Shell/LiteShell.cs @@ -13,22 +13,9 @@ public class LiteShell : IDisposable public LiteShell() { - this.Display = new Display(); - } - - public LiteShell(LiteDatabase db, StringBuilder sb, bool pretty = true) - : this() - { - this.Database = db; - - var writer = new StringWriter(sb); - this.Display.TextWriters.Add(writer); - this.Display.Pretty = pretty; - this.RegisterAll(); } public LiteDatabase Database { get; set; } - public Display Display { get; set; } /// /// Register all commands: search for all classes that implements IShellCommand @@ -54,9 +41,9 @@ public void Register() _commands.Add(new T()); } - public void Run(string command) + public BsonValue Run(string command) { - if (string.IsNullOrEmpty(command)) return; + if (string.IsNullOrEmpty(command)) return BsonValue.Null; var s = new StringScanner(command); @@ -64,12 +51,11 @@ public void Run(string command) { if (cmd.IsCommand(s)) { - cmd.Execute(this.Database, s, this.Display); - return; + return cmd.Execute(this.Database, s); } } - throw new ApplicationException("Command ´" + command + "´ is not a valid command"); + throw new LiteException("Command ´" + command + "´ is not a valid command"); } public void Dispose() diff --git a/LiteDB/Storage/Services/CacheService.cs b/LiteDB/Storage/Services/CacheService.cs index 2de9c2b7e..1e7b80b5e 100644 --- a/LiteDB/Storage/Services/CacheService.cs +++ b/LiteDB/Storage/Services/CacheService.cs @@ -11,7 +11,7 @@ namespace LiteDB /// Represent all cache system and track dirty pages. All pages that load and need to be track for /// dirty (to be persist after) must be added in this class. /// - internal class CacheService + internal class CacheService : IDisposable { // a very simple dictionary for pages cache and track private SortedDictionary _cache; @@ -131,5 +131,10 @@ public IEnumerable GetDirtyPages() yield return page; } } + + public void Dispose() + { + this.Clear(null); + } } } diff --git a/LiteDB/Utils/DumpDatabase.cs b/LiteDB/Utils/DumpDatabase.cs index 2b7331df7..85ce7cc9b 100644 --- a/LiteDB/Utils/DumpDatabase.cs +++ b/LiteDB/Utils/DumpDatabase.cs @@ -12,7 +12,7 @@ namespace LiteDB /// internal class DumpDatabase { - public static string Pages(LiteDatabase db, bool mem) + public static StringBuilder Pages(LiteDatabase db, bool mem) { var sb = new StringBuilder(); @@ -40,7 +40,7 @@ public static string Pages(LiteDatabase db, bool mem) sb.AppendLine(); } - return sb.ToString(); + return sb; } private static T ReadPage(LiteDatabase db, uint pageID, bool mem) @@ -51,7 +51,7 @@ private static T ReadPage(LiteDatabase db, uint pageID, bool mem) return mem ? db.Pager.GetPage(pageID) : db.Disk.ReadPage(pageID); } - public static string Index(LiteDatabase db, string collection, string field, int size = 5) + public static StringBuilder Index(LiteDatabase db, string collection, string field, int size = 5) { var sbs = new StringBuilder[IndexNode.MAX_LEVEL_LENGTH + 1]; var first = true; @@ -119,7 +119,7 @@ public static string Index(LiteDatabase db, string collection, string field, int s.AppendLine(sbs[i].ToString()); } - return s.ToString(); + return s; } private static string Limit(string text, int size) diff --git a/UnitTest/JsonTest.cs b/UnitTest/JsonTest.cs index ef5df8665..08c04da6c 100644 --- a/UnitTest/JsonTest.cs +++ b/UnitTest/JsonTest.cs @@ -43,9 +43,9 @@ public void Json_Test() { var o = CreateDoc(); - var json = JsonEx.Serialize(o, true); + var json = JsonSerializer.Serialize(o, true); - var d = JsonEx.Deserialize(json); + var d = JsonSerializer.Deserialize(json); Assert.AreEqual(d["Date"].AsDateTime, o["Date"].AsDateTime); Assert.AreEqual(d["CustomerId"].AsGuid, o["CustomerId"].AsGuid); diff --git a/WebShell/Commands/Help.cs b/WebShell/Commands/Help.cs index b50e90fdc..c91c54c47 100644 --- a/WebShell/Commands/Help.cs +++ b/WebShell/Commands/Help.cs @@ -13,26 +13,47 @@ public bool IsCommand(StringScanner s) return s.Scan(@"help$").Length > 0; } - public void Execute(LiteDatabase db, StringScanner s, Display d) + public BsonValue Execute(LiteDatabase db, StringScanner s) { - d.WriteResult("Web Shell Commands - try offline version for more commands"); - d.WriteResult("=========================================================="); - - d.WriteHelp("> db..insert ", "Insert a new document into collection"); - d.WriteHelp("> db..update ", "Update a document inside collection"); - d.WriteHelp("> db..delete ", "Delete documents using a filter clausule (see find)"); - d.WriteHelp("> db..find [top N] ", "Show filtered documents based on index search"); - d.WriteHelp("> db..count ", "Show count rows according query filter"); - d.WriteHelp("> db..ensureIndex [unique]", "Create a new index document field"); - d.WriteHelp("> db..indexes", "List all indexes in this collection"); - d.WriteHelp(" = [=|>|>=|<|<=|!=|like|between] ", "Filter query syntax"); - d.WriteHelp(" = ( [and|or] [and|or] ...)", "Multi queries syntax"); - - d.WriteResult("Try:"); - d.WriteResult(" > db.customers.insert { _id:1, name:\"John Doe\", age: 37 }"); - d.WriteResult(" > db.customers.ensureIndex name"); - d.WriteResult(" > db.customers.find name like \"John\""); - d.WriteResult(" > db.customers.find top 10 (name like \"John\" and _id between [0, 100])"); + var sb = new StringBuilder(); + + this.Write(sb, "Web Shell Commands - try offline version for more commands"); + this.Write(sb, "=========================================================="); + + this.Write(sb, "> db..insert ", "Insert a new document into collection"); + this.Write(sb, "> db..update ", "Update a document inside collection"); + this.Write(sb, "> db..delete ", "Delete documents using a filter clausule (see find)"); + this.Write(sb, "> db..find [top N] ", "Show filtered documents based on index search"); + this.Write(sb, "> db..count ", "Show count rows according query filter"); + this.Write(sb, "> db..ensureIndex [unique]", "Create a new index document field"); + this.Write(sb, "> db..indexes", "List all indexes in this collection"); + this.Write(sb, " = [=|>|>=|<|<=|!=|like|between] ", "Filter query syntax"); + this.Write(sb, " = ( [and|or] [and|or] ...)", "Multi queries syntax"); + + this.Write(sb, "Try:"); + this.Write(sb, " > db.customers.insert { _id:1, name:\"John Doe\", age: 37 }"); + this.Write(sb, " > db.customers.ensureIndex name"); + this.Write(sb, " > db.customers.find name like \"John\""); + this.Write(sb, " > db.customers.find top 10 (name like \"John\" and _id between [0, 100])"); + + return sb.ToString(); + } + + private void Write(StringBuilder sb, string line1 = null, string line2 = null) + { + if (string.IsNullOrEmpty(line1)) + { + sb.AppendLine(); + } + else + { + sb.AppendLine(line1); + + if (!string.IsNullOrEmpty(line2)) + { + sb.AppendLine(" " + line2); + } + } } } } From 6da043a735b319355327a9e30a425804ce47d1a6 Mon Sep 17 00:00:00 2001 From: mbdavid Date: Sat, 7 Feb 2015 12:22:39 -0200 Subject: [PATCH 03/96] Minor code fix --- LiteDB/Document/BsonObject.cs | 8 ++++ LiteDB/Document/BsonValue.cs | 51 +++++++++++++++++++++++- LiteDB/Serializer/Json/JsonSerializer.cs | 10 ++--- LiteDB/Serializer/Json/JsonWriter.cs | 8 ++-- LiteDB/Shell/LiteShell.cs | 2 +- 5 files changed, 68 insertions(+), 11 deletions(-) diff --git a/LiteDB/Document/BsonObject.cs b/LiteDB/Document/BsonObject.cs index 93738b0bf..87f8c5efe 100644 --- a/LiteDB/Document/BsonObject.cs +++ b/LiteDB/Document/BsonObject.cs @@ -42,6 +42,14 @@ public BsonObject Add(string key, object value) /// public string[] Keys { get { return this.RawValue.Keys.ToArray(); } } + /// + /// Returns if object contains a named property + /// + public bool ContainsKey(string name) + { + return this.ContainsKey(name); + } + /// /// Check if this object has a specific key /// diff --git a/LiteDB/Document/BsonValue.cs b/LiteDB/Document/BsonValue.cs index 33d104ace..049b451a0 100644 --- a/LiteDB/Document/BsonValue.cs +++ b/LiteDB/Document/BsonValue.cs @@ -215,11 +215,20 @@ public BsonObject AsObject { get { - if(!this.IsObject) throw new LiteException("Value is not an object"); + if (!this.IsObject) throw new LiteException("Value is not an object"); return new BsonObject((Dictionary)this.RawValue); } } + public BsonDocument AsDocument + { + get + { + if (!this.IsObject) throw new LiteException("Value is not an document"); + return new BsonDocument(this); + } + } + public byte AsByte { get { return this.Type == BsonType.Byte ? (byte)this.RawValue : default(byte); } @@ -335,6 +344,11 @@ public bool IsObject get { return this.Type == BsonType.Object; } } + public bool IsDocument + { + get { return this.Type == BsonType.Object && !this["_id"].IsNull; } + } + public bool IsNumber { get @@ -352,6 +366,41 @@ public bool IsNumber } } + public bool IsByte + { + get { return this.Type == BsonType.Byte; } + } + + public bool IsByteArray + { + get { return this.Type == BsonType.ByteArray; } + } + + public bool IsChar + { + get { return this.Type == BsonType.Char; } + } + + public bool IsBoolean + { + get { return this.Type == BsonType.Boolean; } + } + + public bool IsString + { + get { return this.Type == BsonType.String; } + } + + public bool IsGuid + { + get { return this.Type == BsonType.Guid; } + } + + public bool IsDateTime + { + get { return this.Type == BsonType.DateTime; } + } + #endregion #region Operators diff --git a/LiteDB/Serializer/Json/JsonSerializer.cs b/LiteDB/Serializer/Json/JsonSerializer.cs index 93c4ab8f4..63df5e61b 100644 --- a/LiteDB/Serializer/Json/JsonSerializer.cs +++ b/LiteDB/Serializer/Json/JsonSerializer.cs @@ -14,15 +14,15 @@ public class JsonSerializer /// /// Serialize a BsonDocument (or any BsonValue) into a JsonEx string /// - public static string Serialize(BsonValue value, bool pretty = false, bool showbinary = true) + public static string Serialize(BsonValue value, bool pretty = false, bool showBinary = true) { - var writer = new JsonWriter(pretty, showbinary); + var writer = new JsonWriter(pretty, showBinary); return writer.Serialize(value); } /// - /// Convert a JsonEx string into a BsonValue + /// Convert a Json string into a BsonValue /// public static BsonValue Deserialize(string json) { @@ -32,7 +32,7 @@ public static BsonValue Deserialize(string json) } /// - /// Convert a JsonEx string into a BsonValue based type (BsonObject, BsonArray or BsonDocument) + /// Convert a Json string into a BsonValue based type (BsonObject, BsonArray or BsonDocument) /// public static T Deserialize(string json) where T : BsonValue @@ -58,7 +58,7 @@ public static T Deserialize(string json) } /// - /// Deserialize a JSON as an IEnumerable of BsonValue based class + /// Deserialize a Json as an IEnumerable of BsonValue based class /// public static IEnumerable DeserializeArray(string json) where T : BsonValue diff --git a/LiteDB/Serializer/Json/JsonWriter.cs b/LiteDB/Serializer/Json/JsonWriter.cs index a2ecbdf18..d51831828 100644 --- a/LiteDB/Serializer/Json/JsonWriter.cs +++ b/LiteDB/Serializer/Json/JsonWriter.cs @@ -14,12 +14,12 @@ internal class JsonWriter private int _indent; private string _spacer; private bool _pretty; - private bool _showbinary; + private bool _showBinary; - public JsonWriter(bool pretty, bool showbinary) + public JsonWriter(bool pretty, bool showBinary) { _pretty = pretty; - _showbinary = showbinary; + _showBinary = showBinary; } public string Serialize(BsonValue value) @@ -53,7 +53,7 @@ private void WriteValue(BsonValue value) } else if (value.Type == BsonType.ByteArray) { - this.WriteExtendDataType("$binary", _showbinary ? System.Convert.ToBase64String(value.AsByteArray) : "-- " + value.AsByteArray.Length + " bytes --"); + this.WriteExtendDataType("$binary", _showBinary ? System.Convert.ToBase64String(value.AsByteArray) : "-- " + value.AsByteArray.Length + " bytes --"); } else if (value.Type == BsonType.Char) { diff --git a/LiteDB/Shell/LiteShell.cs b/LiteDB/Shell/LiteShell.cs index 11efc59b0..c5552c473 100644 --- a/LiteDB/Shell/LiteShell.cs +++ b/LiteDB/Shell/LiteShell.cs @@ -18,7 +18,7 @@ public LiteShell() public LiteDatabase Database { get; set; } /// - /// Register all commands: search for all classes that implements IShellCommand + /// Register all commands: search for all classes that implements ILiteCommand /// public void RegisterAll() { From ea672ec1e4a9cf04af1b089a4acb8fd71e34bae7 Mon Sep 17 00:00:00 2001 From: mbdavid Date: Sun, 8 Feb 2015 09:26:09 -0200 Subject: [PATCH 04/96] Add readline to spool on shell --- LiteDB.Shell/Commands/Spool.cs | 3 ++ LiteDB.Shell/InputCommand.cs | 34 ++++++++++++++++--- .../Shell/Commands/Others/ShowCollections.cs | 2 +- 3 files changed, 33 insertions(+), 6 deletions(-) diff --git a/LiteDB.Shell/Commands/Spool.cs b/LiteDB.Shell/Commands/Spool.cs index 1def94a72..0317a3fad 100644 --- a/LiteDB.Shell/Commands/Spool.cs +++ b/LiteDB.Shell/Commands/Spool.cs @@ -21,6 +21,7 @@ public override void Execute(LiteShell shell, StringScanner s, Display display, if(s.Scan("false|off").Length > 0 && _writer != null) { display.TextWriters.Remove(_writer); + input.OnWrite = null; _writer.Flush(); _writer.Dispose(); _writer = null; @@ -36,6 +37,8 @@ public override void Execute(LiteShell shell, StringScanner s, Display display, _writer = File.CreateText(path); display.TextWriters.Add(_writer); + + input.OnWrite = (t) => _writer.Write(t); } } } diff --git a/LiteDB.Shell/InputCommand.cs b/LiteDB.Shell/InputCommand.cs index 14361128e..ba5904bd9 100644 --- a/LiteDB.Shell/InputCommand.cs +++ b/LiteDB.Shell/InputCommand.cs @@ -13,6 +13,8 @@ public class InputCommand public string Last { get; set; } public Stopwatch Timer { get; set; } + public Action OnWrite { get; set; } + public InputCommand() { this.Queue = new Queue(); @@ -25,11 +27,11 @@ public string ReadCommand() if (this.Timer.IsRunning) { Console.ForegroundColor = ConsoleColor.DarkYellow; - Console.Write(this.Timer.ElapsedMilliseconds.ToString("0000") + " "); + this.Write(this.Timer.ElapsedMilliseconds.ToString("0000") + " "); } Console.ForegroundColor = ConsoleColor.White; - Console.Write("> "); + this.Write("> "); var cmd = this.ReadLine(); @@ -40,8 +42,13 @@ public string ReadCommand() while (!cmd.EndsWith("/")) { + if (this.Timer.IsRunning) + { + this.Write(" "); + } + Console.ForegroundColor = ConsoleColor.White; - Console.Write("| "); + this.Write("| "); var line = this.ReadLine(); cmd += line; @@ -73,12 +80,29 @@ private string ReadLine() if (this.Queue.Count > 0) { var cmd = this.Queue.Dequeue(); - Console.WriteLine(cmd); + this.Write(cmd + Environment.NewLine); return cmd; } else { - return Console.ReadLine(); + var cmd = Console.ReadLine(); + + if (this.OnWrite != null) + { + this.OnWrite(cmd + Environment.NewLine); + } + + return cmd; + } + } + + private void Write(string text) + { + Console.Write(text); + + if (this.OnWrite != null) + { + this.OnWrite(text); } } } diff --git a/LiteDB/Shell/Commands/Others/ShowCollections.cs b/LiteDB/Shell/Commands/Others/ShowCollections.cs index 986481474..503007562 100644 --- a/LiteDB/Shell/Commands/Others/ShowCollections.cs +++ b/LiteDB/Shell/Commands/Others/ShowCollections.cs @@ -19,7 +19,7 @@ public BsonValue Execute(LiteDatabase db, StringScanner s) var cols = db.GetCollectionNames().OrderBy(x => x).ToArray(); - return string.Join("\n", cols); + return string.Join(Environment.NewLine, cols); } } } From 2211a31ac4f68b2423194a09a3aec11266cc9ff8 Mon Sep 17 00:00:00 2001 From: mbdavid Date: Sun, 8 Feb 2015 20:55:32 -0200 Subject: [PATCH 05/96] Drop collection and Drop index done right: 20000 documents = from 46s to 150ms --- .../Collections/LiteCollection.Delete.cs | 4 +- .../Collections/LiteCollection.Drop.cs | 9 ++-- .../Collections/LiteCollection.Index.cs | 46 +++++++++++++++++-- .../Collections/LiteCollection.Insert.cs | 8 ++-- .../Collections/LiteCollection.Update.cs | 4 +- LiteDB/Database/Tools/UserVersion.cs | 4 +- LiteDB/Shell/Commands/Collections/Drop.cs | 2 +- LiteDB/Storage/Services/CollectionService.cs | 31 +++++++++++-- LiteDB/Storage/Services/IndexService.cs | 21 +++++++++ LiteDB/Storage/Structures/CollectionIndex.cs | 8 ++++ 10 files changed, 114 insertions(+), 23 deletions(-) diff --git a/LiteDB/Database/Collections/LiteCollection.Delete.cs b/LiteDB/Database/Collections/LiteCollection.Delete.cs index 94f12bb11..01c1488b3 100644 --- a/LiteDB/Database/Collections/LiteCollection.Delete.cs +++ b/LiteDB/Database/Collections/LiteCollection.Delete.cs @@ -44,10 +44,10 @@ public virtual bool Delete(object id) return true; } - catch (Exception ex) + catch { this.Database.Transaction.Rollback(); - throw ex; + throw; } } diff --git a/LiteDB/Database/Collections/LiteCollection.Drop.cs b/LiteDB/Database/Collections/LiteCollection.Drop.cs index 9a07f04dd..30c58b9e8 100644 --- a/LiteDB/Database/Collections/LiteCollection.Drop.cs +++ b/LiteDB/Database/Collections/LiteCollection.Drop.cs @@ -27,10 +27,7 @@ public virtual bool Drop() return false; } - // delete all data - this.Delete(Query.All()); - - // delete all pages/indexes heads + // delete all data pages + indexes pages this.Database.Collections.Drop(col); _pageID = uint.MaxValue; @@ -39,10 +36,10 @@ public virtual bool Drop() return true; } - catch (Exception ex) + catch { this.Database.Transaction.Rollback(); - throw ex; + throw; } } } diff --git a/LiteDB/Database/Collections/LiteCollection.Index.cs b/LiteDB/Database/Collections/LiteCollection.Index.cs index 60c370c03..477cbd093 100644 --- a/LiteDB/Database/Collections/LiteCollection.Index.cs +++ b/LiteDB/Database/Collections/LiteCollection.Index.cs @@ -82,10 +82,10 @@ public virtual bool EnsureIndex(string field, bool unique = false) this.Database.Transaction.Commit(); } - catch (Exception ex) + catch { this.Database.Transaction.Rollback(); - throw ex; + throw; } return true; @@ -122,7 +122,47 @@ public IEnumerable GetIndexes() /// public bool DropIndex(string field) { - throw new NotImplementedException(); + // start transaction + this.Database.Transaction.Begin(); + + try + { + var col = this.GetCollectionPage(false); + + // if collection not exists, no drop + if (col == null) + { + this.Database.Transaction.Abort(); + return false; + } + + // search for index reference - do not delelte "_id" index + var index = col.Indexes.FirstOrDefault(x => x.Field.Equals(field, StringComparison.InvariantCultureIgnoreCase)); + + if (index == null || field.Equals("_id", StringComparison.InvariantCultureIgnoreCase)) + { + this.Database.Transaction.Abort(); + return false; + } + + // delete all data pages + indexes pages + this.Database.Indexer.DropIndex(index); + + // clear index reference + index.Clear(); + + // save collection page + col.IsDirty = true; + + this.Database.Transaction.Commit(); + + return true; + } + catch + { + this.Database.Transaction.Rollback(); + throw; + } } } } diff --git a/LiteDB/Database/Collections/LiteCollection.Insert.cs b/LiteDB/Database/Collections/LiteCollection.Insert.cs index 733cbf608..612e73904 100644 --- a/LiteDB/Database/Collections/LiteCollection.Insert.cs +++ b/LiteDB/Database/Collections/LiteCollection.Insert.cs @@ -60,10 +60,10 @@ public virtual void Insert(T doc) this.Database.Transaction.Commit(); } - catch (Exception ex) + catch { this.Database.Transaction.Rollback(); - throw ex; + throw; } } @@ -85,10 +85,10 @@ public virtual void InsertBatch(IEnumerable docs) this.Database.Transaction.Commit(); } - catch (Exception ex) + catch { this.Database.Transaction.Rollback(); - throw ex; + throw; } } } diff --git a/LiteDB/Database/Collections/LiteCollection.Update.cs b/LiteDB/Database/Collections/LiteCollection.Update.cs index 8bb3da322..b99b736f4 100644 --- a/LiteDB/Database/Collections/LiteCollection.Update.cs +++ b/LiteDB/Database/Collections/LiteCollection.Update.cs @@ -85,10 +85,10 @@ public virtual bool Update(T doc) return true; } - catch (Exception ex) + catch { this.Database.Transaction.Rollback(); - throw ex; + throw; } } } diff --git a/LiteDB/Database/Tools/UserVersion.cs b/LiteDB/Database/Tools/UserVersion.cs index 573b6f9b5..064c29234 100644 --- a/LiteDB/Database/Tools/UserVersion.cs +++ b/LiteDB/Database/Tools/UserVersion.cs @@ -44,10 +44,10 @@ private void UpdateDatabaseVersion() this.Transaction.Commit(); } - catch (Exception ex) + catch { this.Transaction.Rollback(); - throw ex; + throw; } } } diff --git a/LiteDB/Shell/Commands/Collections/Drop.cs b/LiteDB/Shell/Commands/Collections/Drop.cs index f22fece16..70167614d 100644 --- a/LiteDB/Shell/Commands/Collections/Drop.cs +++ b/LiteDB/Shell/Commands/Collections/Drop.cs @@ -10,7 +10,7 @@ public class CollectionDrop : BaseCollection, ILiteCommand { public bool IsCommand(StringScanner s) { - return this.IsCollectionCommand(s, "drop"); + return this.IsCollectionCommand(s, "drop$"); } public BsonValue Execute(LiteDatabase db, StringScanner s) diff --git a/LiteDB/Storage/Services/CollectionService.cs b/LiteDB/Storage/Services/CollectionService.cs index 1a2caebb7..c09ab1d34 100644 --- a/LiteDB/Storage/Services/CollectionService.cs +++ b/LiteDB/Storage/Services/CollectionService.cs @@ -72,20 +72,45 @@ public IEnumerable GetAll() return _pager.GetSeqPages(1); // PageID 1 = Master Collection } + /// + /// Drop a collection - remove all data pages + indexes pages + /// public void Drop(CollectionPage col) { - // delete all index pages + // add all pages to delete + var pages = new HashSet(); + + // search for all data page and index page for (byte i = 0; i < col.Indexes.Length; i++) { var index = col.Indexes[i]; if (!index.IsEmpty) { - _pager.DeletePage(index.HeadNode.PageID); + // get all nodes from index + var nodes = _indexer.FindAll(index); + + foreach (var node in nodes) + { + if(i == 0) + { + // if PK index, add data pages too + pages.Add(node.DataBlock.PageID); + } + + // add index page to delete list page + pages.Add(node.Position.PageID); + } } } - // ajust page pointers + // and now, lets delete all this pages + foreach (var pageID in pages) + { + _pager.DeletePage(pageID); + } + + // ajust collection page pointers if (col.PrevPageID != uint.MaxValue) { var prev = _pager.GetPage(col.PrevPageID); diff --git a/LiteDB/Storage/Services/IndexService.cs b/LiteDB/Storage/Services/IndexService.cs index af59540eb..9287f8133 100644 --- a/LiteDB/Storage/Services/IndexService.cs +++ b/LiteDB/Storage/Services/IndexService.cs @@ -51,6 +51,27 @@ public CollectionIndex CreateIndex(CollectionIndex index) return index; } + /// + /// Drop all indexes pages + /// + public void DropIndex(CollectionIndex index) + { + var pages = new HashSet(); + var nodes = this.FindAll(index); + + // get reference for pageID from all index nodes + foreach (var node in nodes) + { + pages.Add(node.Position.PageID); + } + + // now delete all pages + foreach (var page in pages) + { + _pager.DeletePage(page); + } + } + /// /// Insert a new node index inside a index. Use skip list /// diff --git a/LiteDB/Storage/Structures/CollectionIndex.cs b/LiteDB/Storage/Structures/CollectionIndex.cs index a7232cdaf..5b112d0ab 100644 --- a/LiteDB/Storage/Structures/CollectionIndex.cs +++ b/LiteDB/Storage/Structures/CollectionIndex.cs @@ -50,6 +50,14 @@ public bool IsEmpty public CollectionPage Page { get; set; } public CollectionIndex() + { + this.Clear(); + } + + /// + /// Clear all index information + /// + public void Clear() { this.Field = string.Empty; this.Unique = false; From 24983e28b4e999d675f7651d7b0dbc946c4cca90 Mon Sep 17 00:00:00 2001 From: mbdavid Date: Sun, 8 Feb 2015 21:32:41 -0200 Subject: [PATCH 06/96] Add slot info on index --- .../Database/Collections/LiteCollection.Delete.cs | 15 +++------------ .../Database/Collections/LiteCollection.Index.cs | 15 +++++++++++++-- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/LiteDB/Database/Collections/LiteCollection.Delete.cs b/LiteDB/Database/Collections/LiteCollection.Delete.cs index 01c1488b3..02dc39a97 100644 --- a/LiteDB/Database/Collections/LiteCollection.Delete.cs +++ b/LiteDB/Database/Collections/LiteCollection.Delete.cs @@ -38,7 +38,7 @@ public virtual bool Delete(object id) return false; } - this.Remove(col, node); + this.Delete(col, node); this.Database.Transaction.Commit(); @@ -77,7 +77,7 @@ public virtual int Delete(Query query) foreach (var node in nodes) { - this.Remove(col, node); + this.Delete(col, node); count++; } @@ -107,16 +107,7 @@ public virtual int Delete(Expression> predicate) return this.Delete(QueryVisitor.Visit(predicate)); } - /// - /// Remove all documents on this collection. Returns removed document counts - /// - /// - public virtual int DeleteAll() - { - return this.Delete(Query.All()); - } - - internal virtual void Remove(CollectionPage col, IndexNode node) + internal virtual void Delete(CollectionPage col, IndexNode node) { // read dataBlock var dataBlock = this.Database.Data.Read(node.DataBlock, false); diff --git a/LiteDB/Database/Collections/LiteCollection.Index.cs b/LiteDB/Database/Collections/LiteCollection.Index.cs index 477cbd093..0bcaec1da 100644 --- a/LiteDB/Database/Collections/LiteCollection.Index.cs +++ b/LiteDB/Database/Collections/LiteCollection.Index.cs @@ -112,9 +112,20 @@ public IEnumerable GetIndexes() var col = this.GetCollectionPage(false); - if (col == null) return new List(); + if (col == null) yield break; - return col.Indexes.Where(x => !x.IsEmpty).Select(x => new BsonObject().Add("field", x.Field).Add("unique", x.Unique)); + for (var i = 0; i < CollectionIndex.INDEX_PER_COLLECTION; i++) + { + var index = col.Indexes[i]; + + if (!index.IsEmpty) + { + yield return new BsonDocument() + .Add("slot", i) + .Add("field", index.Field) + .Add("unique", index.Unique); + } + } } /// From 6b6067a5f3c147622c7c6775039122b8924c9aaf Mon Sep 17 00:00:00 2001 From: mbdavid Date: Mon, 9 Feb 2015 11:32:28 -0200 Subject: [PATCH 07/96] Bug fix on drop collection - delete extend pages too --- LiteDB/Database/LiteDatabase.cs | 2 +- LiteDB/Storage/Services/CollectionService.cs | 12 +++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/LiteDB/Database/LiteDatabase.cs b/LiteDB/Database/LiteDatabase.cs index 28a9074d9..babc60e1e 100644 --- a/LiteDB/Database/LiteDatabase.cs +++ b/LiteDB/Database/LiteDatabase.cs @@ -64,7 +64,7 @@ public LiteDatabase(string connectionString) this.Data = new DataService(this.Disk, this.Cache, this.Pager); - this.Collections = new CollectionService(this.Pager, this.Indexer); + this.Collections = new CollectionService(this.Pager, this.Indexer, this.Data); this.UpdateDatabaseVersion(); } diff --git a/LiteDB/Storage/Services/CollectionService.cs b/LiteDB/Storage/Services/CollectionService.cs index c09ab1d34..2bce1c7f3 100644 --- a/LiteDB/Storage/Services/CollectionService.cs +++ b/LiteDB/Storage/Services/CollectionService.cs @@ -11,11 +11,13 @@ internal class CollectionService { private PageService _pager; private IndexService _indexer; + private DataService _data; - public CollectionService(PageService pager, IndexService indexer) + public CollectionService(PageService pager, IndexService indexer, DataService data) { _pager = pager; _indexer = indexer; + _data = data; } /// @@ -96,6 +98,14 @@ public void Drop(CollectionPage col) { // if PK index, add data pages too pages.Add(node.DataBlock.PageID); + + // read datablock to check if there is any extended page + var block = _data.Read(node.DataBlock, false); + + if (block.ExtendPageID != uint.MaxValue) + { + _pager.DeletePage(block.ExtendPageID, true); + } } // add index page to delete list page From 0bfbb27f10420f628701c55d0f87676f60ea89b0 Mon Sep 17 00:00:00 2001 From: mbdavid Date: Mon, 9 Feb 2015 19:50:34 -0200 Subject: [PATCH 08/96] Review class names with MongoDB - do not accept all names --- LiteDB.Shell/Commands/Help.cs | 1 + .../Collections/LiteCollection.Insert.cs | 2 +- .../LiteCollection.InsertBulk.cs} | 27 +++++++++------- .../{GridFS => FileStorage}/LiteFileInfo.cs | 0 .../LiteFileStorage.Delete.cs} | 2 +- .../LiteFileStorage.Download.cs} | 2 +- .../LiteFileStorage.Find.cs} | 2 +- .../LiteFileStorage.Upload.cs} | 2 +- .../LiteFileStorage.cs} | 4 +-- .../{GridFS => FileStorage}/LiteFileStream.cs | 0 LiteDB/Database/LiteDatabase.cs | 16 +++++++--- .../Tools/{Info.cs => GetDatabaseInfo.cs} | 0 LiteDB/Database/Tools/RunCommand.cs | 28 ++++++++++++++++ LiteDB/LiteDB.csproj | 32 ++++++++++--------- LiteDB/Shell/Commands/Collections/Bulk.cs | 13 +------- LiteDB/Shell/Commands/Collections/Count.cs | 2 +- LiteDB/Shell/Commands/Collections/Rename.cs | 26 +++++++++++++++ .../BaseFileStorage.cs} | 2 +- .../Commands/{GridFS => FileStoage}/Delete.cs | 4 +-- .../{GridFS => FileStoage}/Download.cs | 4 +-- .../Commands/{GridFS => FileStoage}/Find.cs | 8 ++--- .../Commands/{GridFS => FileStoage}/Update.cs | 4 +-- .../Commands/{GridFS => FileStoage}/Upload.cs | 4 +-- UnitTest/PageTest.cs | 2 +- UnitTest/PerfTest.cs | 2 +- 25 files changed, 123 insertions(+), 66 deletions(-) rename LiteDB/Database/{Tools/Bulk.cs => Collections/LiteCollection.InsertBulk.cs} (55%) rename LiteDB/Database/{GridFS => FileStorage}/LiteFileInfo.cs (100%) rename LiteDB/Database/{GridFS/LiteGridFS.Delete.cs => FileStorage/LiteFileStorage.Delete.cs} (96%) rename LiteDB/Database/{GridFS/LiteGridFS.Download.cs => FileStorage/LiteFileStorage.Download.cs} (97%) rename LiteDB/Database/{GridFS/LiteGridFS.Find.cs => FileStorage/LiteFileStorage.Find.cs} (97%) rename LiteDB/Database/{GridFS/LiteGridFS.Upload.cs => FileStorage/LiteFileStorage.Upload.cs} (98%) rename LiteDB/Database/{GridFS/LiteGridFS.cs => FileStorage/LiteFileStorage.cs} (87%) rename LiteDB/Database/{GridFS => FileStorage}/LiteFileStream.cs (100%) rename LiteDB/Database/Tools/{Info.cs => GetDatabaseInfo.cs} (100%) create mode 100644 LiteDB/Database/Tools/RunCommand.cs create mode 100644 LiteDB/Shell/Commands/Collections/Rename.cs rename LiteDB/Shell/Commands/{GridFS/BaseGridFS.cs => FileStoage/BaseFileStorage.cs} (94%) rename LiteDB/Shell/Commands/{GridFS => FileStoage}/Delete.cs (82%) rename LiteDB/Shell/Commands/{GridFS => FileStoage}/Download.cs (87%) rename LiteDB/Shell/Commands/{GridFS => FileStoage}/Find.cs (75%) rename LiteDB/Shell/Commands/{GridFS => FileStoage}/Update.cs (82%) rename LiteDB/Shell/Commands/{GridFS => FileStoage}/Upload.cs (85%) diff --git a/LiteDB.Shell/Commands/Help.cs b/LiteDB.Shell/Commands/Help.cs index 595e5cf82..f5a83085a 100644 --- a/LiteDB.Shell/Commands/Help.cs +++ b/LiteDB.Shell/Commands/Help.cs @@ -55,6 +55,7 @@ public BsonValue Execute(LiteDatabase db, StringScanner s) this.Write(sb, "> db..indexes", "List all indexes in this collection"); this.Write(sb, "> db..drop", "Drop collection and destroy all documents inside"); this.Write(sb, "> db..dropIndex ", "Drop a index and make index area free to use with another index"); + this.Write(sb, "> db..rename ", "Rename a collection"); this.Write(sb, " = [=|>|>=|<|<=|!=|like|between] ", "Filter query syntax"); this.Write(sb, " = ( [and|or] [and|or] ...)", "Multi queries syntax"); this.Write(sb, " = {_id: ... , key: value, key1: value1 }", "Represent a json (extended version) for a BsonDocument. See special data types"); diff --git a/LiteDB/Database/Collections/LiteCollection.Insert.cs b/LiteDB/Database/Collections/LiteCollection.Insert.cs index 612e73904..1c1e59bf0 100644 --- a/LiteDB/Database/Collections/LiteCollection.Insert.cs +++ b/LiteDB/Database/Collections/LiteCollection.Insert.cs @@ -70,7 +70,7 @@ public virtual void Insert(T doc) /// /// Insert an array of new documents to this collection. Document Id must be a new value in collection /// - public virtual void InsertBatch(IEnumerable docs) + public virtual void Insert(IEnumerable docs) { if (docs == null) throw new ArgumentNullException("docs"); diff --git a/LiteDB/Database/Tools/Bulk.cs b/LiteDB/Database/Collections/LiteCollection.InsertBulk.cs similarity index 55% rename from LiteDB/Database/Tools/Bulk.cs rename to LiteDB/Database/Collections/LiteCollection.InsertBulk.cs index 268ef1636..5cefdcd85 100644 --- a/LiteDB/Database/Tools/Bulk.cs +++ b/LiteDB/Database/Collections/LiteCollection.InsertBulk.cs @@ -6,18 +6,16 @@ namespace LiteDB { - public partial class LiteDatabase + public partial class LiteCollection { /// /// Bulk documents to a collection - use data chunks for most efficient insert /// - public static int Bulk(string connectionString, string collectionName, IEnumerable docs, int buffer = 2000) - where T : new() + public int InsertBulk(IEnumerable docs, int buffer = 2000) { - if(string.IsNullOrEmpty(connectionString)) throw new ArgumentNullException("connectionString"); - if(string.IsNullOrEmpty(collectionName)) throw new ArgumentNullException("collectionName"); - if(docs == null) throw new ArgumentNullException("collectionName"); + if(docs == null) throw new ArgumentNullException("docs"); if(buffer < 100) throw new ArgumentException("buffer must be bigger than 100"); + if (this.Database.Transaction.IsInTransaction) throw new LiteException("InsertBulk doesn't supports transaction."); var enumerator = docs.GetEnumerator(); var count = 0; @@ -26,27 +24,32 @@ public static int Bulk(string connectionString, string collectionName, IEnume { var buff = buffer; - using (var db = new LiteDatabase(connectionString)) + this.Database.Transaction.Begin(); + + try { - var col = db.GetCollection(collectionName); var more = true; - db.BeginTrans(); - while (buff > 0 && (more = enumerator.MoveNext())) { - col.Insert(enumerator.Current); + this.Insert(enumerator.Current); buff--; count++; } - db.Commit(); + this.Database.Transaction.Commit(); + this.Database.Cache.Clear(null); if (more == false) { return count; } } + catch + { + this.Database.Rollback(); + throw; + } } } } diff --git a/LiteDB/Database/GridFS/LiteFileInfo.cs b/LiteDB/Database/FileStorage/LiteFileInfo.cs similarity index 100% rename from LiteDB/Database/GridFS/LiteFileInfo.cs rename to LiteDB/Database/FileStorage/LiteFileInfo.cs diff --git a/LiteDB/Database/GridFS/LiteGridFS.Delete.cs b/LiteDB/Database/FileStorage/LiteFileStorage.Delete.cs similarity index 96% rename from LiteDB/Database/GridFS/LiteGridFS.Delete.cs rename to LiteDB/Database/FileStorage/LiteFileStorage.Delete.cs index 9aa4f7ffd..e43027782 100644 --- a/LiteDB/Database/GridFS/LiteGridFS.Delete.cs +++ b/LiteDB/Database/FileStorage/LiteFileStorage.Delete.cs @@ -8,7 +8,7 @@ namespace LiteDB { - public partial class LiteGridFS + public partial class LiteFileStorage { /// /// Delete a file inside datafile and all metadata related diff --git a/LiteDB/Database/GridFS/LiteGridFS.Download.cs b/LiteDB/Database/FileStorage/LiteFileStorage.Download.cs similarity index 97% rename from LiteDB/Database/GridFS/LiteGridFS.Download.cs rename to LiteDB/Database/FileStorage/LiteFileStorage.Download.cs index 67328e4ec..55e39fc7b 100644 --- a/LiteDB/Database/GridFS/LiteGridFS.Download.cs +++ b/LiteDB/Database/FileStorage/LiteFileStorage.Download.cs @@ -6,7 +6,7 @@ namespace LiteDB { - public partial class LiteGridFS + public partial class LiteFileStorage { /// /// Copy all file content to a steam diff --git a/LiteDB/Database/GridFS/LiteGridFS.Find.cs b/LiteDB/Database/FileStorage/LiteFileStorage.Find.cs similarity index 97% rename from LiteDB/Database/GridFS/LiteGridFS.Find.cs rename to LiteDB/Database/FileStorage/LiteFileStorage.Find.cs index beaf86ed9..1e6a5c726 100644 --- a/LiteDB/Database/GridFS/LiteGridFS.Find.cs +++ b/LiteDB/Database/FileStorage/LiteFileStorage.Find.cs @@ -8,7 +8,7 @@ namespace LiteDB { - public partial class LiteGridFS + public partial class LiteFileStorage { /// /// Find a file inside datafile and returns FileEntry instance. Returns null if not found diff --git a/LiteDB/Database/GridFS/LiteGridFS.Upload.cs b/LiteDB/Database/FileStorage/LiteFileStorage.Upload.cs similarity index 98% rename from LiteDB/Database/GridFS/LiteGridFS.Upload.cs rename to LiteDB/Database/FileStorage/LiteFileStorage.Upload.cs index cf3d5c00c..05a526395 100644 --- a/LiteDB/Database/GridFS/LiteGridFS.Upload.cs +++ b/LiteDB/Database/FileStorage/LiteFileStorage.Upload.cs @@ -8,7 +8,7 @@ namespace LiteDB { - public partial class LiteGridFS + public partial class LiteFileStorage { /// /// Insert a new file content inside datafile in _files collection diff --git a/LiteDB/Database/GridFS/LiteGridFS.cs b/LiteDB/Database/FileStorage/LiteFileStorage.cs similarity index 87% rename from LiteDB/Database/GridFS/LiteGridFS.cs rename to LiteDB/Database/FileStorage/LiteFileStorage.cs index cbf4fb384..55b3f7b52 100644 --- a/LiteDB/Database/GridFS/LiteGridFS.cs +++ b/LiteDB/Database/FileStorage/LiteFileStorage.cs @@ -9,13 +9,13 @@ namespace LiteDB /// /// Storage is a special collection to store files/streams. /// - public partial class LiteGridFS + public partial class LiteFileStorage { public LiteCollection Files { get; private set; } public LiteCollection Chunks { get; private set; } public LiteDatabase Database { get; private set; } - internal LiteGridFS(LiteDatabase db) + internal LiteFileStorage(LiteDatabase db) { this.Database = db; this.Files = this.Database.GetCollection("_files"); diff --git a/LiteDB/Database/GridFS/LiteFileStream.cs b/LiteDB/Database/FileStorage/LiteFileStream.cs similarity index 100% rename from LiteDB/Database/GridFS/LiteFileStream.cs rename to LiteDB/Database/FileStorage/LiteFileStream.cs diff --git a/LiteDB/Database/LiteDatabase.cs b/LiteDB/Database/LiteDatabase.cs index babc60e1e..1858cbb4f 100644 --- a/LiteDB/Database/LiteDatabase.cs +++ b/LiteDB/Database/LiteDatabase.cs @@ -112,6 +112,14 @@ public bool CollectionExists(string name) return this.Collections.Get(name) != null; } + /// + /// Drop a collection and all data + indexes + /// + public bool DropCollection(string name) + { + return this.GetCollection(name).Drop(); + } + /// /// Rename a collection. Returns false if oldName does not exists or newName already exists /// @@ -145,16 +153,16 @@ public bool RenameCollection(string oldName, string newName) #endregion - #region GridFS + #region FileStorage - private LiteGridFS _gridfs = null; + private LiteFileStorage _fs = null; /// /// Returns a special collection for storage files/stream inside datafile /// - public LiteGridFS GridFS + public LiteFileStorage FileStorage { - get { return _gridfs ?? (_gridfs = new LiteGridFS(this)); } + get { return _fs ?? (_fs = new LiteFileStorage(this)); } } #endregion diff --git a/LiteDB/Database/Tools/Info.cs b/LiteDB/Database/Tools/GetDatabaseInfo.cs similarity index 100% rename from LiteDB/Database/Tools/Info.cs rename to LiteDB/Database/Tools/GetDatabaseInfo.cs diff --git a/LiteDB/Database/Tools/RunCommand.cs b/LiteDB/Database/Tools/RunCommand.cs new file mode 100644 index 000000000..5ae377a8d --- /dev/null +++ b/LiteDB/Database/Tools/RunCommand.cs @@ -0,0 +1,28 @@ +using LiteDB.Shell; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; + +namespace LiteDB +{ + public partial class LiteDatabase + { + private LiteShell _shell = null; + + /// + /// Run a shell command in current database. Returns a BsonValue as result + /// + public BsonValue RunCommand(string command) + { + if (_shell == null) + { + _shell = new LiteShell(); + _shell.RegisterAll(); + _shell.Database = this; + } + return _shell.Run(command); + } + } +} diff --git a/LiteDB/LiteDB.csproj b/LiteDB/LiteDB.csproj index a3a68b622..77d48a934 100644 --- a/LiteDB/LiteDB.csproj +++ b/LiteDB/LiteDB.csproj @@ -47,9 +47,10 @@ - + + - + @@ -75,13 +76,13 @@ - - - - - - - + + + + + + + @@ -94,6 +95,7 @@ + @@ -104,12 +106,12 @@ - - - - - - + + + + + + diff --git a/LiteDB/Shell/Commands/Collections/Bulk.cs b/LiteDB/Shell/Commands/Collections/Bulk.cs index e39fbe36f..2e0220d4a 100644 --- a/LiteDB/Shell/Commands/Collections/Bulk.cs +++ b/LiteDB/Shell/Commands/Collections/Bulk.cs @@ -22,19 +22,8 @@ public BsonValue Execute(LiteDatabase db, StringScanner s) var filename = s.Scan(@".*"); var json = File.ReadAllText(filename, Encoding.UTF8); var docs = JsonSerializer.DeserializeArray(json); - var count = 0; - db.BeginTrans(); - - foreach (var doc in docs) - { - count++; - col.Insert(doc); - } - - db.Commit(); - - return count; + return col.InsertBulk(docs); } } } diff --git a/LiteDB/Shell/Commands/Collections/Count.cs b/LiteDB/Shell/Commands/Collections/Count.cs index 7a0ea5efa..974a941a3 100644 --- a/LiteDB/Shell/Commands/Collections/Count.cs +++ b/LiteDB/Shell/Commands/Collections/Count.cs @@ -6,7 +6,7 @@ namespace LiteDB.Shell.Commands { - public class CollectionCount : BaseCollection, ILiteCommand + public class CollectionRename : BaseCollection, ILiteCommand { public bool IsCommand(StringScanner s) { diff --git a/LiteDB/Shell/Commands/Collections/Rename.cs b/LiteDB/Shell/Commands/Collections/Rename.cs new file mode 100644 index 000000000..c0705575f --- /dev/null +++ b/LiteDB/Shell/Commands/Collections/Rename.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; + +namespace LiteDB.Shell.Commands +{ + public class CollectionCount : BaseCollection, ILiteCommand + { + public bool IsCommand(StringScanner s) + { + return this.IsCollectionCommand(s, "rename"); + } + + public BsonValue Execute(LiteDatabase db, StringScanner s) + { + if (db == null) throw new LiteException("No database"); + + var col = this.ReadCollection(db, s); + var newName = s.Scan(@"\w+"); + + return db.RenameCollection(col.Name, newName); + } + } +} diff --git a/LiteDB/Shell/Commands/GridFS/BaseGridFS.cs b/LiteDB/Shell/Commands/FileStoage/BaseFileStorage.cs similarity index 94% rename from LiteDB/Shell/Commands/GridFS/BaseGridFS.cs rename to LiteDB/Shell/Commands/FileStoage/BaseFileStorage.cs index 402a07105..e19116513 100644 --- a/LiteDB/Shell/Commands/GridFS/BaseGridFS.cs +++ b/LiteDB/Shell/Commands/FileStoage/BaseFileStorage.cs @@ -5,7 +5,7 @@ namespace LiteDB.Shell.Commands { - public class BaseGridFS + public class BaseFileStorage { public bool IsFileCommand(StringScanner s, string command) { diff --git a/LiteDB/Shell/Commands/GridFS/Delete.cs b/LiteDB/Shell/Commands/FileStoage/Delete.cs similarity index 82% rename from LiteDB/Shell/Commands/GridFS/Delete.cs rename to LiteDB/Shell/Commands/FileStoage/Delete.cs index 6274f5ff2..fe30eac5a 100644 --- a/LiteDB/Shell/Commands/GridFS/Delete.cs +++ b/LiteDB/Shell/Commands/FileStoage/Delete.cs @@ -7,7 +7,7 @@ namespace LiteDB.Shell.Commands { - public class FileDelete : BaseGridFS, ILiteCommand + public class FileDelete : BaseFileStorage, ILiteCommand { public bool IsCommand(StringScanner s) { @@ -20,7 +20,7 @@ public BsonValue Execute(LiteDatabase db, StringScanner s) var id = this.ReadId(s); - return db.GridFS.Delete(id); + return db.FileStorage.Delete(id); } } } diff --git a/LiteDB/Shell/Commands/GridFS/Download.cs b/LiteDB/Shell/Commands/FileStoage/Download.cs similarity index 87% rename from LiteDB/Shell/Commands/GridFS/Download.cs rename to LiteDB/Shell/Commands/FileStoage/Download.cs index 394d1fb0c..7bc1a9cf9 100644 --- a/LiteDB/Shell/Commands/GridFS/Download.cs +++ b/LiteDB/Shell/Commands/FileStoage/Download.cs @@ -7,7 +7,7 @@ namespace LiteDB.Shell.Commands { - public class FileDownload : BaseGridFS, ILiteCommand + public class FileDownload : BaseFileStorage, ILiteCommand { public bool IsCommand(StringScanner s) { @@ -21,7 +21,7 @@ public BsonValue Execute(LiteDatabase db, StringScanner s) var id = this.ReadId(s); var filename = s.Scan(@"\s*.*").Trim(); - var file = db.GridFS.FindById(id); + var file = db.FileStorage.FindById(id); if (file != null) { diff --git a/LiteDB/Shell/Commands/GridFS/Find.cs b/LiteDB/Shell/Commands/FileStoage/Find.cs similarity index 75% rename from LiteDB/Shell/Commands/GridFS/Find.cs rename to LiteDB/Shell/Commands/FileStoage/Find.cs index 118448698..0b7db3676 100644 --- a/LiteDB/Shell/Commands/GridFS/Find.cs +++ b/LiteDB/Shell/Commands/FileStoage/Find.cs @@ -6,7 +6,7 @@ namespace LiteDB.Shell.Commands { - public class FileFind : BaseGridFS, ILiteCommand + public class FileFind : BaseFileStorage, ILiteCommand { public bool IsCommand(StringScanner s) { @@ -19,7 +19,7 @@ public BsonValue Execute(LiteDatabase db, StringScanner s) if (s.HasTerminated) { - var files = db.GridFS.FindAll().Select(x => x.AsDocument); + var files = db.FileStorage.FindAll().Select(x => x.AsDocument); return BsonArray.FromEnumerable(files); } @@ -29,13 +29,13 @@ public BsonValue Execute(LiteDatabase db, StringScanner s) if (id.EndsWith("*") || id.EndsWith("%")) { - var files = db.GridFS.Find(id.Substring(0, id.Length - 1)).Select(x => x.AsDocument); + var files = db.FileStorage.Find(id.Substring(0, id.Length - 1)).Select(x => x.AsDocument); return BsonArray.FromEnumerable(files); } else { - var file = db.GridFS.FindById(id); + var file = db.FileStorage.FindById(id); return file != null ? file.AsDocument : BsonValue.Null; } diff --git a/LiteDB/Shell/Commands/GridFS/Update.cs b/LiteDB/Shell/Commands/FileStoage/Update.cs similarity index 82% rename from LiteDB/Shell/Commands/GridFS/Update.cs rename to LiteDB/Shell/Commands/FileStoage/Update.cs index 34eb9a05e..a111269a9 100644 --- a/LiteDB/Shell/Commands/GridFS/Update.cs +++ b/LiteDB/Shell/Commands/FileStoage/Update.cs @@ -7,7 +7,7 @@ namespace LiteDB.Shell.Commands { - public class FileUpdate : BaseGridFS, ILiteCommand + public class FileUpdate : BaseFileStorage, ILiteCommand { public bool IsCommand(StringScanner s) { @@ -21,7 +21,7 @@ public BsonValue Execute(LiteDatabase db, StringScanner s) var id = this.ReadId(s); var metadata = new JsonReader().ReadValue(s).AsObject; - return db.GridFS.SetMetadata(id, metadata); + return db.FileStorage.SetMetadata(id, metadata); } } } diff --git a/LiteDB/Shell/Commands/GridFS/Upload.cs b/LiteDB/Shell/Commands/FileStoage/Upload.cs similarity index 85% rename from LiteDB/Shell/Commands/GridFS/Upload.cs rename to LiteDB/Shell/Commands/FileStoage/Upload.cs index 74134603b..c40a9d63f 100644 --- a/LiteDB/Shell/Commands/GridFS/Upload.cs +++ b/LiteDB/Shell/Commands/FileStoage/Upload.cs @@ -7,7 +7,7 @@ namespace LiteDB.Shell.Commands { - public class FileUpload : BaseGridFS, ILiteCommand + public class FileUpload : BaseFileStorage, ILiteCommand { public bool IsCommand(StringScanner s) { @@ -24,7 +24,7 @@ public BsonValue Execute(LiteDatabase db, StringScanner s) if (!File.Exists(filename)) throw new IOException("File " + filename + " not found"); - var file = db.GridFS.Upload(id, filename); + var file = db.FileStorage.Upload(id, filename); return file.AsDocument; } diff --git a/UnitTest/PageTest.cs b/UnitTest/PageTest.cs index 7976c6cda..ed32c4ca0 100644 --- a/UnitTest/PageTest.cs +++ b/UnitTest/PageTest.cs @@ -50,7 +50,7 @@ public void Page_PrevNext_Test() Dump.Pages(db, "After clear"); - db.GridFS.Upload("my/foto1.jpg", new MemoryStream(new byte[1024*50])); + db.FileStorage.Upload("my/foto1.jpg", new MemoryStream(new byte[1024*50])); } using (var db = new LiteDatabase(DB.Path(false))) diff --git a/UnitTest/PerfTest.cs b/UnitTest/PerfTest.cs index d97df34e8..24501420b 100644 --- a/UnitTest/PerfTest.cs +++ b/UnitTest/PerfTest.cs @@ -37,7 +37,7 @@ public void PerfFile_Test() using (var m = new MemoryStream(bytes)) { - db.GridFS.Upload("myfile", m); + db.FileStorage.Upload("myfile", m); } } } From f5f792a883a7dba193c8303cf36d60ba1902bd07 Mon Sep 17 00:00:00 2001 From: mbdavid Date: Mon, 9 Feb 2015 21:38:14 -0200 Subject: [PATCH 09/96] Better shell support --- LiteDB.Shell/Commands/Help.cs | 176 +++++++++--------- LiteDB.Shell/Display.cs | 18 ++ LiteDB.Shell/LiteDB.Shell.csproj | 2 +- LiteDB.Shell/Program.cs | 21 +-- LiteDB/Database/Tools/RunCommand.cs | 4 +- LiteDB/LiteDB.csproj | 2 +- .../Commands/Collections/BaseCollection.cs | 2 +- LiteDB/Shell/Commands/Collections/Bulk.cs | 4 +- LiteDB/Shell/Commands/Collections/Count.cs | 10 +- LiteDB/Shell/Commands/Collections/Delete.cs | 4 +- LiteDB/Shell/Commands/Collections/Drop.cs | 4 +- .../Shell/Commands/Collections/DropIndex.cs | 4 +- .../Shell/Commands/Collections/EnsureIndex.cs | 4 +- LiteDB/Shell/Commands/Collections/Exec.cs | 4 +- LiteDB/Shell/Commands/Collections/Find.cs | 4 +- LiteDB/Shell/Commands/Collections/Indexes.cs | 4 +- LiteDB/Shell/Commands/Collections/Insert.cs | 4 +- LiteDB/Shell/Commands/Collections/Rename.cs | 10 +- LiteDB/Shell/Commands/Collections/Update.cs | 4 +- .../Commands/FileStoage/BaseFileStorage.cs | 2 +- LiteDB/Shell/Commands/FileStoage/Delete.cs | 4 +- LiteDB/Shell/Commands/FileStoage/Download.cs | 4 +- LiteDB/Shell/Commands/FileStoage/Find.cs | 4 +- LiteDB/Shell/Commands/FileStoage/Update.cs | 4 +- LiteDB/Shell/Commands/FileStoage/Upload.cs | 4 +- LiteDB/Shell/Commands/Others/Dump.cs | 3 +- LiteDB/Shell/Commands/Others/Info.cs | 4 +- .../Shell/Commands/Others/ShowCollections.cs | 4 +- LiteDB/Shell/Commands/Transactions/Begin.cs | 4 +- LiteDB/Shell/Commands/Transactions/Commit.cs | 4 +- .../Shell/Commands/Transactions/Rollback.cs | 4 +- LiteDB/Shell/LiteShell.cs | 36 ++-- WebShell/Commands/Help.cs | 59 ------ WebShell/WebShell.csproj | 1 - WebShell/api.ashx | 13 +- 35 files changed, 153 insertions(+), 286 deletions(-) delete mode 100644 WebShell/Commands/Help.cs diff --git a/LiteDB.Shell/Commands/Help.cs b/LiteDB.Shell/Commands/Help.cs index f5a83085a..117c578a2 100644 --- a/LiteDB.Shell/Commands/Help.cs +++ b/LiteDB.Shell/Commands/Help.cs @@ -6,106 +6,104 @@ namespace LiteDB.Shell.Commands { - internal class Help : ILiteCommand + internal class Help : ConsoleCommand { - public bool IsCommand(StringScanner s) + public override bool IsCommand(StringScanner s) { - return s.Scan(@"help$").Length > 0; + return s.Scan(@"help\s*").Length > 0; } - public BsonValue Execute(LiteDatabase db, StringScanner s) + public override void Execute(LiteShell shell, StringScanner s, Display d, InputCommand input) { var sb = new StringBuilder(); + var full = s.Match("full"); - this.Write(sb, "Shell commands"); - this.Write(sb, "=============="); - - this.Write(sb, "> open ", "Open a new database"); - this.Write(sb, "> close", "Close current database"); - this.Write(sb, "> run ", "Run commands inside filename"); - this.Write(sb, "> pretty on|off", "Turns on/off pretty json format"); - this.Write(sb, "> timer", "Show timer before prompt"); - this.Write(sb, "> ed", "Open nodepad with last command to edit and execute"); - this.Write(sb, "> spool on|off", "Spool all output in a spool file"); - this.Write(sb, "> -- comment", "Do nothing, its just a comment"); - this.Write(sb, "> //", "Support for multi line command"); - this.Write(sb, "> exit", "Close LiteDB shell"); - - this.Write(sb); - this.Write(sb, "Transaction commands"); - this.Write(sb, "===================="); - - this.Write(sb, "> begin", "Begins a new transaction"); - this.Write(sb, "> commit", "Commit current transaction"); - this.Write(sb, "> rollback", "Rollback current transaction"); - - this.Write(sb); - this.Write(sb, "Collections commands"); - this.Write(sb, "===================="); - - this.Write(sb, "> db..insert ", "Insert a new document into collection"); - this.Write(sb, "> db..update ", "Update a document inside collection"); - this.Write(sb, "> db..delete ", "Delete documents using a filter clausule (see find)"); - this.Write(sb, "> db..bulk ", "Bulk insert a json file as documents"); - this.Write(sb, "> db..find [top N]", "Show all documents. Can limit results in N documents"); - this.Write(sb, "> db..find [top N] ", "Show filtered documents based on index search"); - this.Write(sb, "> db..count ", "Show count rows according query filter"); - this.Write(sb, "> db..exec { Action }", "Execute C# code for each document based on filter."); - this.Write(sb, "> db..ensureIndex [unique]", "Create a new index document field"); - this.Write(sb, "> db..indexes", "List all indexes in this collection"); - this.Write(sb, "> db..drop", "Drop collection and destroy all documents inside"); - this.Write(sb, "> db..dropIndex ", "Drop a index and make index area free to use with another index"); - this.Write(sb, "> db..rename ", "Rename a collection"); - this.Write(sb, " = [=|>|>=|<|<=|!=|like|between] ", "Filter query syntax"); - this.Write(sb, " = ( [and|or] [and|or] ...)", "Multi queries syntax"); - this.Write(sb, " = {_id: ... , key: value, key1: value1 }", "Represent a json (extended version) for a BsonDocument. See special data types"); - this.Write(sb, "JsonEx Date", "{ mydate: { $date :\"2015-01-01T23:59:59Z\"} }"); - this.Write(sb, "JsonEx Guid", "{ myguid: { $guid :\"3a1c34b3-9f66-4d8e-975a-d545d898a4ba\"} }"); - this.Write(sb, "JsonEx Binary", "{ mydata: { $binary :\"base64 byte array\"} }"); - - this.Write(sb); - this.Write(sb, "File storage commands"); - this.Write(sb, "====================="); - - this.Write(sb, "> fs.find", "List all files on datafile"); - this.Write(sb, "> fs.find ", "List file info from a key. Supports * for starts with key"); - this.Write(sb, "> fs.upload ", "Insert a new file inside database"); - this.Write(sb, "> fs.download ", "Save a file to disk passing a file key and filename"); - this.Write(sb, "> fs.update {key:value}", "Update metadata file"); - this.Write(sb, "> fs.delete ", "Remove a file inside database"); - - this.Write(sb); - this.Write(sb, "Other commands"); - this.Write(sb, "=============="); - - this.Write(sb, "> db.info", "Get database informations"); - this.Write(sb, "> dump", "Display dump database information"); - - this.Write(sb); - this.Write(sb, "Try:"); - this.Write(sb, " > db.customers.insert { _id:1, name:\"John Doe\", age: 37 }"); - this.Write(sb, " > db.customers.ensureIndex name"); - this.Write(sb, " > db.customers.find name like \"J\""); - this.Write(sb, " > db.customers.find _id > 0"); - - return sb.ToString(); - } - - private void Write(StringBuilder sb, string line1 = null, string line2 = null) - { - if (string.IsNullOrEmpty(line1)) + if (!full) { - sb.AppendLine(); + d.WriteHelp("Basic Shell Commands - try `help full` for all commands"); + d.WriteHelp("======================================================="); + + d.WriteHelp("> db..insert ", "Insert a new document into collection"); + d.WriteHelp("> db..update ", "Update a document inside collection"); + d.WriteHelp("> db..delete ", "Delete documents using a filter clausule (see find)"); + d.WriteHelp("> db..find [top N] ", "Show filtered documents based on index search"); + d.WriteHelp("> db..count ", "Show count rows according query filter"); + d.WriteHelp("> db..ensureIndex [unique]", "Create a new index document field"); + d.WriteHelp("> db..indexes", "List all indexes in this collection"); + d.WriteHelp(" = [=|>|>=|<|<=|!=|like|between] ", "Filter query syntax"); + d.WriteHelp(" = ( [and|or] [and|or] ...)", "Multi queries syntax"); + + d.WriteHelp("Try:"); + d.WriteHelp(" > db.customers.insert { _id:1, name:\"John Doe\", age: 37 }"); + d.WriteHelp(" > db.customers.ensureIndex name"); + d.WriteHelp(" > db.customers.find name like \"John\""); + d.WriteHelp(" > db.customers.find top 10 (name like \"John\" and _id between [0, 100])"); } else { - sb.AppendLine(line1); - - if (!string.IsNullOrEmpty(line2)) - { - sb.AppendLine(" " + line2); - sb.AppendLine(); - } + d.WriteHelp("Shell commands"); + d.WriteHelp("=============="); + + d.WriteHelp("> open ", "Open a new database"); + d.WriteHelp("> close", "Close current database"); + d.WriteHelp("> run ", "Run commands inside filename"); + d.WriteHelp("> pretty on|off", "Turns on/off pretty json format"); + d.WriteHelp("> timer", "Show timer before prompt"); + d.WriteHelp("> ed", "Open nodepad with last command to edit and execute"); + d.WriteHelp("> spool on|off", "Spool all output in a spool file"); + d.WriteHelp("> -- comment", "Do nothing, its just a comment"); + d.WriteHelp("> //", "Support for multi line command"); + d.WriteHelp("> exit", "Close LiteDB shell"); + + d.WriteHelp(); + d.WriteHelp("Transaction commands"); + d.WriteHelp("===================="); + + d.WriteHelp("> begin", "Begins a new transaction"); + d.WriteHelp("> commit", "Commit current transaction"); + d.WriteHelp("> rollback", "Rollback current transaction"); + + d.WriteHelp(); + d.WriteHelp("Collections commands"); + d.WriteHelp("===================="); + + d.WriteHelp("> db..insert ", "Insert a new document into collection"); + d.WriteHelp("> db..update ", "Update a document inside collection"); + d.WriteHelp("> db..delete ", "Delete documents using a filter clausule (see find)"); + d.WriteHelp("> db..bulk ", "Bulk insert a json file as documents"); + d.WriteHelp("> db..find [top N]", "Show all documents. Can limit results in N documents"); + d.WriteHelp("> db..find [top N] ", "Show filtered documents based on index search"); + d.WriteHelp("> db..count ", "Show count rows according query filter"); + d.WriteHelp("> db..exec { Action }", "Execute C# code for each document based on filter."); + d.WriteHelp("> db..ensureIndex [unique]", "Create a new index document field"); + d.WriteHelp("> db..indexes", "List all indexes in this collection"); + d.WriteHelp("> db..drop", "Drop collection and destroy all documents inside"); + d.WriteHelp("> db..dropIndex ", "Drop a index and make index area free to use with another index"); + d.WriteHelp("> db..rename ", "Rename a collection"); + d.WriteHelp(" = [=|>|>=|<|<=|!=|like|between] ", "Filter query syntax"); + d.WriteHelp(" = ( [and|or] [and|or] ...)", "Multi queries syntax"); + d.WriteHelp(" = {_id: ... , key: value, key1: value1 }", "Represent a json (extended version) for a BsonDocument. See special data types"); + d.WriteHelp("JsonEx Date", "{ mydate: { $date :\"2015-01-01T23:59:59Z\"} }"); + d.WriteHelp("JsonEx Guid", "{ myguid: { $guid :\"3a1c34b3-9f66-4d8e-975a-d545d898a4ba\"} }"); + d.WriteHelp("JsonEx Binary", "{ mydata: { $binary :\"base64 byte array\"} }"); + + d.WriteHelp(); + d.WriteHelp("File storage commands"); + d.WriteHelp("====================="); + + d.WriteHelp("> fs.find", "List all files on datafile"); + d.WriteHelp("> fs.find ", "List file info from a key. Supports * for starts with key"); + d.WriteHelp("> fs.upload ", "Insert a new file inside database"); + d.WriteHelp("> fs.download ", "Save a file to disk passing a file key and filename"); + d.WriteHelp("> fs.update {key:value}", "Update metadata file"); + d.WriteHelp("> fs.delete ", "Remove a file inside database"); + + d.WriteHelp(); + d.WriteHelp("Other commands"); + d.WriteHelp("=============="); + + d.WriteHelp("> db.info", "Get database informations"); + d.WriteHelp("> dump", "Display dump database information"); } } } diff --git a/LiteDB.Shell/Display.cs b/LiteDB.Shell/Display.cs index 9f1454c25..d6282c38c 100644 --- a/LiteDB.Shell/Display.cs +++ b/LiteDB.Shell/Display.cs @@ -39,6 +39,24 @@ public void WriteError(string err) this.WriteLine(ConsoleColor.Red, err); } + public void WriteHelp(string line1 = null, string line2 = null) + { + if (string.IsNullOrEmpty(line1)) + { + this.WriteLine(""); + } + else + { + this.WriteLine(ConsoleColor.Cyan, line1); + + if (!string.IsNullOrEmpty(line2)) + { + this.WriteLine(ConsoleColor.DarkCyan, " " + line2); + this.WriteLine(""); + } + } + } + public void WriteResult(BsonValue result) { var index = 0; diff --git a/LiteDB.Shell/LiteDB.Shell.csproj b/LiteDB.Shell/LiteDB.Shell.csproj index 48763e114..820afaf9e 100644 --- a/LiteDB.Shell/LiteDB.Shell.csproj +++ b/LiteDB.Shell/LiteDB.Shell.csproj @@ -53,6 +53,7 @@ + @@ -60,7 +61,6 @@ - diff --git a/LiteDB.Shell/Program.cs b/LiteDB.Shell/Program.cs index e600e95db..4a1a08ae7 100644 --- a/LiteDB.Shell/Program.cs +++ b/LiteDB.Shell/Program.cs @@ -11,11 +11,10 @@ class Program { static void Main(string[] args) { - var shell = new LiteShell(); + var shell = new LiteShell(null); var input = new InputCommand(); var display = new Display(); - shell.RegisterAll(); display.TextWriters.Add(Console.Out); // show welcome message @@ -58,23 +57,5 @@ static void Main(string[] args) } } } - - static void Open(LiteShell shell, string command, Display display) - { - if (shell.Database != null) - { - shell.Database.Dispose(); - } - - shell.Database = new LiteDatabase(command.Substring(5)); - } - - static void Spool(LiteShell shell, string command, Display display) - { - } - - static void Help(Display display) - { - } } } diff --git a/LiteDB/Database/Tools/RunCommand.cs b/LiteDB/Database/Tools/RunCommand.cs index 5ae377a8d..fa2c1293d 100644 --- a/LiteDB/Database/Tools/RunCommand.cs +++ b/LiteDB/Database/Tools/RunCommand.cs @@ -18,9 +18,7 @@ public BsonValue RunCommand(string command) { if (_shell == null) { - _shell = new LiteShell(); - _shell.RegisterAll(); - _shell.Database = this; + _shell = new LiteShell(this); } return _shell.Run(command); } diff --git a/LiteDB/LiteDB.csproj b/LiteDB/LiteDB.csproj index 77d48a934..840cf0dc2 100644 --- a/LiteDB/LiteDB.csproj +++ b/LiteDB/LiteDB.csproj @@ -95,8 +95,8 @@ - + diff --git a/LiteDB/Shell/Commands/Collections/BaseCollection.cs b/LiteDB/Shell/Commands/Collections/BaseCollection.cs index 1ddfab18a..8b6ec7dcf 100644 --- a/LiteDB/Shell/Commands/Collections/BaseCollection.cs +++ b/LiteDB/Shell/Commands/Collections/BaseCollection.cs @@ -5,7 +5,7 @@ namespace LiteDB.Shell.Commands { - public class BaseCollection + internal class BaseCollection { /// /// Read collection name from db.(colname).(command) diff --git a/LiteDB/Shell/Commands/Collections/Bulk.cs b/LiteDB/Shell/Commands/Collections/Bulk.cs index 2e0220d4a..df5aefd2b 100644 --- a/LiteDB/Shell/Commands/Collections/Bulk.cs +++ b/LiteDB/Shell/Commands/Collections/Bulk.cs @@ -7,7 +7,7 @@ namespace LiteDB.Shell.Commands { - public class CollectionBulk : BaseCollection, ILiteCommand + internal class CollectionBulk : BaseCollection, ILiteCommand { public bool IsCommand(StringScanner s) { @@ -16,8 +16,6 @@ public bool IsCommand(StringScanner s) public BsonValue Execute(LiteDatabase db, StringScanner s) { - if (db == null) throw new LiteException("No database"); - var col = this.ReadCollection(db, s); var filename = s.Scan(@".*"); var json = File.ReadAllText(filename, Encoding.UTF8); diff --git a/LiteDB/Shell/Commands/Collections/Count.cs b/LiteDB/Shell/Commands/Collections/Count.cs index 974a941a3..07022b9de 100644 --- a/LiteDB/Shell/Commands/Collections/Count.cs +++ b/LiteDB/Shell/Commands/Collections/Count.cs @@ -6,21 +6,19 @@ namespace LiteDB.Shell.Commands { - public class CollectionRename : BaseCollection, ILiteCommand + internal class CollectionCount : BaseCollection, ILiteCommand { public bool IsCommand(StringScanner s) { - return this.IsCollectionCommand(s, "count"); + return this.IsCollectionCommand(s, "rename"); } public BsonValue Execute(LiteDatabase db, StringScanner s) { - if (db == null) throw new LiteException("No database"); - var col = this.ReadCollection(db, s); - var query = this.ReadQuery(s); + var newName = s.Scan(@"\w+"); - return col.Count(query); + return db.RenameCollection(col.Name, newName); } } } diff --git a/LiteDB/Shell/Commands/Collections/Delete.cs b/LiteDB/Shell/Commands/Collections/Delete.cs index f729999fc..355310b8f 100644 --- a/LiteDB/Shell/Commands/Collections/Delete.cs +++ b/LiteDB/Shell/Commands/Collections/Delete.cs @@ -6,7 +6,7 @@ namespace LiteDB.Shell.Commands { - public class CollectionDelete : BaseCollection, ILiteCommand + internal class CollectionDelete : BaseCollection, ILiteCommand { public bool IsCommand(StringScanner s) { @@ -15,8 +15,6 @@ public bool IsCommand(StringScanner s) public BsonValue Execute(LiteDatabase db, StringScanner s) { - if (db == null) throw new LiteException("No database"); - var col = this.ReadCollection(db, s); var query = this.ReadQuery(s); diff --git a/LiteDB/Shell/Commands/Collections/Drop.cs b/LiteDB/Shell/Commands/Collections/Drop.cs index 70167614d..21d145513 100644 --- a/LiteDB/Shell/Commands/Collections/Drop.cs +++ b/LiteDB/Shell/Commands/Collections/Drop.cs @@ -6,7 +6,7 @@ namespace LiteDB.Shell.Commands { - public class CollectionDrop : BaseCollection, ILiteCommand + internal class CollectionDrop : BaseCollection, ILiteCommand { public bool IsCommand(StringScanner s) { @@ -15,8 +15,6 @@ public bool IsCommand(StringScanner s) public BsonValue Execute(LiteDatabase db, StringScanner s) { - if (db == null) throw new LiteException("No database"); - var col = this.ReadCollection(db, s); return col.Drop(); diff --git a/LiteDB/Shell/Commands/Collections/DropIndex.cs b/LiteDB/Shell/Commands/Collections/DropIndex.cs index 2f29a531f..95f446893 100644 --- a/LiteDB/Shell/Commands/Collections/DropIndex.cs +++ b/LiteDB/Shell/Commands/Collections/DropIndex.cs @@ -6,7 +6,7 @@ namespace LiteDB.Shell.Commands { - public class CollectionDropIndex : BaseCollection, ILiteCommand + internal class CollectionDropIndex : BaseCollection, ILiteCommand { public bool IsCommand(StringScanner s) { @@ -15,8 +15,6 @@ public bool IsCommand(StringScanner s) public BsonValue Execute(LiteDatabase db, StringScanner s) { - if (db == null) throw new LiteException("No database"); - var col = this.ReadCollection(db, s); var index = s.Scan(@"\w+(.\w+)*").Trim(); diff --git a/LiteDB/Shell/Commands/Collections/EnsureIndex.cs b/LiteDB/Shell/Commands/Collections/EnsureIndex.cs index 9cc10360d..e1b7520c3 100644 --- a/LiteDB/Shell/Commands/Collections/EnsureIndex.cs +++ b/LiteDB/Shell/Commands/Collections/EnsureIndex.cs @@ -6,7 +6,7 @@ namespace LiteDB.Shell.Commands { - public class CollectionEnsureIndex : BaseCollection, ILiteCommand + internal class CollectionEnsureIndex : BaseCollection, ILiteCommand { public bool IsCommand(StringScanner s) { @@ -15,8 +15,6 @@ public bool IsCommand(StringScanner s) public BsonValue Execute(LiteDatabase db, StringScanner s) { - if (db == null) throw new LiteException("No database"); - var col = this.ReadCollection(db, s); var field = s.Scan(@"\w+(.\w+)*"); var unique = s.Scan(@"\s*unique$"); diff --git a/LiteDB/Shell/Commands/Collections/Exec.cs b/LiteDB/Shell/Commands/Collections/Exec.cs index ce1590c23..830be3fe8 100644 --- a/LiteDB/Shell/Commands/Collections/Exec.cs +++ b/LiteDB/Shell/Commands/Collections/Exec.cs @@ -8,7 +8,7 @@ namespace LiteDB.Shell.Commands { - class CollectionExec : BaseCollection, ILiteCommand + internal class CollectionExec : BaseCollection, ILiteCommand { public bool IsCommand(StringScanner s) { @@ -17,8 +17,6 @@ public bool IsCommand(StringScanner s) public BsonValue Execute(LiteDatabase db, StringScanner s) { - if (db == null) throw new LiteException("No database"); - var col = this.ReadCollection(db, s); var query = s.Match("{") ? Query.All() : this.ReadQuery(s); var code = DynamicCode.GetCode(s); diff --git a/LiteDB/Shell/Commands/Collections/Find.cs b/LiteDB/Shell/Commands/Collections/Find.cs index de340aabd..b5ad53d54 100644 --- a/LiteDB/Shell/Commands/Collections/Find.cs +++ b/LiteDB/Shell/Commands/Collections/Find.cs @@ -6,7 +6,7 @@ namespace LiteDB.Shell.Commands { - public class CollectionFind : BaseCollection, ILiteCommand + internal class CollectionFind : BaseCollection, ILiteCommand { public bool IsCommand(StringScanner s) { @@ -15,8 +15,6 @@ public bool IsCommand(StringScanner s) public BsonValue Execute(LiteDatabase db, StringScanner s) { - if (db == null) throw new LiteException("No database"); - var col = this.ReadCollection(db, s); var top = this.ReadTop(s); var query = this.ReadQuery(s); diff --git a/LiteDB/Shell/Commands/Collections/Indexes.cs b/LiteDB/Shell/Commands/Collections/Indexes.cs index 56f96c57d..497d9519a 100644 --- a/LiteDB/Shell/Commands/Collections/Indexes.cs +++ b/LiteDB/Shell/Commands/Collections/Indexes.cs @@ -6,7 +6,7 @@ namespace LiteDB.Shell.Commands { - public class CollectionIndexes : BaseCollection, ILiteCommand + internal class CollectionIndexes : BaseCollection, ILiteCommand { public bool IsCommand(StringScanner s) { @@ -15,8 +15,6 @@ public bool IsCommand(StringScanner s) public BsonValue Execute(LiteDatabase db, StringScanner s) { - if (db == null) throw new LiteException("No database"); - var col = this.ReadCollection(db, s); var docs = col.GetIndexes(); diff --git a/LiteDB/Shell/Commands/Collections/Insert.cs b/LiteDB/Shell/Commands/Collections/Insert.cs index 1313736fe..9004a3c6f 100644 --- a/LiteDB/Shell/Commands/Collections/Insert.cs +++ b/LiteDB/Shell/Commands/Collections/Insert.cs @@ -6,7 +6,7 @@ namespace LiteDB.Shell.Commands { - public class CollectionInsert : BaseCollection, ILiteCommand + internal class CollectionInsert : BaseCollection, ILiteCommand { public bool IsCommand(StringScanner s) { @@ -15,8 +15,6 @@ public bool IsCommand(StringScanner s) public BsonValue Execute(LiteDatabase db, StringScanner s) { - if (db == null) throw new LiteException("No database"); - var col = this.ReadCollection(db, s); var value = new JsonReader().ReadValue(s); diff --git a/LiteDB/Shell/Commands/Collections/Rename.cs b/LiteDB/Shell/Commands/Collections/Rename.cs index c0705575f..b5de7f384 100644 --- a/LiteDB/Shell/Commands/Collections/Rename.cs +++ b/LiteDB/Shell/Commands/Collections/Rename.cs @@ -6,21 +6,19 @@ namespace LiteDB.Shell.Commands { - public class CollectionCount : BaseCollection, ILiteCommand + internal class CollectionRename : BaseCollection, ILiteCommand { public bool IsCommand(StringScanner s) { - return this.IsCollectionCommand(s, "rename"); + return this.IsCollectionCommand(s, "count"); } public BsonValue Execute(LiteDatabase db, StringScanner s) { - if (db == null) throw new LiteException("No database"); - var col = this.ReadCollection(db, s); - var newName = s.Scan(@"\w+"); + var query = this.ReadQuery(s); - return db.RenameCollection(col.Name, newName); + return col.Count(query); } } } diff --git a/LiteDB/Shell/Commands/Collections/Update.cs b/LiteDB/Shell/Commands/Collections/Update.cs index c963e32f9..34067467d 100644 --- a/LiteDB/Shell/Commands/Collections/Update.cs +++ b/LiteDB/Shell/Commands/Collections/Update.cs @@ -6,7 +6,7 @@ namespace LiteDB.Shell.Commands { - public class CollectionUpdate : BaseCollection, ILiteCommand + internal class CollectionUpdate : BaseCollection, ILiteCommand { public bool IsCommand(StringScanner s) { @@ -15,8 +15,6 @@ public bool IsCommand(StringScanner s) public BsonValue Execute(LiteDatabase db, StringScanner s) { - if (db == null) throw new LiteException("No database"); - var col = this.ReadCollection(db, s); var doc = new BsonDocument(new JsonReader().ReadValue(s)); diff --git a/LiteDB/Shell/Commands/FileStoage/BaseFileStorage.cs b/LiteDB/Shell/Commands/FileStoage/BaseFileStorage.cs index e19116513..0463bf861 100644 --- a/LiteDB/Shell/Commands/FileStoage/BaseFileStorage.cs +++ b/LiteDB/Shell/Commands/FileStoage/BaseFileStorage.cs @@ -5,7 +5,7 @@ namespace LiteDB.Shell.Commands { - public class BaseFileStorage + internal class BaseFileStorage { public bool IsFileCommand(StringScanner s, string command) { diff --git a/LiteDB/Shell/Commands/FileStoage/Delete.cs b/LiteDB/Shell/Commands/FileStoage/Delete.cs index fe30eac5a..3cf6768cb 100644 --- a/LiteDB/Shell/Commands/FileStoage/Delete.cs +++ b/LiteDB/Shell/Commands/FileStoage/Delete.cs @@ -7,7 +7,7 @@ namespace LiteDB.Shell.Commands { - public class FileDelete : BaseFileStorage, ILiteCommand + internal class FileDelete : BaseFileStorage, ILiteCommand { public bool IsCommand(StringScanner s) { @@ -16,8 +16,6 @@ public bool IsCommand(StringScanner s) public BsonValue Execute(LiteDatabase db, StringScanner s) { - if (db == null) throw new LiteException("No database"); - var id = this.ReadId(s); return db.FileStorage.Delete(id); diff --git a/LiteDB/Shell/Commands/FileStoage/Download.cs b/LiteDB/Shell/Commands/FileStoage/Download.cs index 7bc1a9cf9..438e9268e 100644 --- a/LiteDB/Shell/Commands/FileStoage/Download.cs +++ b/LiteDB/Shell/Commands/FileStoage/Download.cs @@ -7,7 +7,7 @@ namespace LiteDB.Shell.Commands { - public class FileDownload : BaseFileStorage, ILiteCommand + internal class FileDownload : BaseFileStorage, ILiteCommand { public bool IsCommand(StringScanner s) { @@ -16,8 +16,6 @@ public bool IsCommand(StringScanner s) public BsonValue Execute(LiteDatabase db, StringScanner s) { - if (db == null) throw new LiteException("No database"); - var id = this.ReadId(s); var filename = s.Scan(@"\s*.*").Trim(); diff --git a/LiteDB/Shell/Commands/FileStoage/Find.cs b/LiteDB/Shell/Commands/FileStoage/Find.cs index 0b7db3676..4609c400c 100644 --- a/LiteDB/Shell/Commands/FileStoage/Find.cs +++ b/LiteDB/Shell/Commands/FileStoage/Find.cs @@ -6,7 +6,7 @@ namespace LiteDB.Shell.Commands { - public class FileFind : BaseFileStorage, ILiteCommand + internal class FileFind : BaseFileStorage, ILiteCommand { public bool IsCommand(StringScanner s) { @@ -15,8 +15,6 @@ public bool IsCommand(StringScanner s) public BsonValue Execute(LiteDatabase db, StringScanner s) { - if (db == null) throw new LiteException("No database"); - if (s.HasTerminated) { var files = db.FileStorage.FindAll().Select(x => x.AsDocument); diff --git a/LiteDB/Shell/Commands/FileStoage/Update.cs b/LiteDB/Shell/Commands/FileStoage/Update.cs index a111269a9..886c73451 100644 --- a/LiteDB/Shell/Commands/FileStoage/Update.cs +++ b/LiteDB/Shell/Commands/FileStoage/Update.cs @@ -7,7 +7,7 @@ namespace LiteDB.Shell.Commands { - public class FileUpdate : BaseFileStorage, ILiteCommand + internal class FileUpdate : BaseFileStorage, ILiteCommand { public bool IsCommand(StringScanner s) { @@ -16,8 +16,6 @@ public bool IsCommand(StringScanner s) public BsonValue Execute(LiteDatabase db, StringScanner s) { - if (db == null) throw new LiteException("No database"); - var id = this.ReadId(s); var metadata = new JsonReader().ReadValue(s).AsObject; diff --git a/LiteDB/Shell/Commands/FileStoage/Upload.cs b/LiteDB/Shell/Commands/FileStoage/Upload.cs index c40a9d63f..474f72a89 100644 --- a/LiteDB/Shell/Commands/FileStoage/Upload.cs +++ b/LiteDB/Shell/Commands/FileStoage/Upload.cs @@ -7,7 +7,7 @@ namespace LiteDB.Shell.Commands { - public class FileUpload : BaseFileStorage, ILiteCommand + internal class FileUpload : BaseFileStorage, ILiteCommand { public bool IsCommand(StringScanner s) { @@ -16,8 +16,6 @@ public bool IsCommand(StringScanner s) public BsonValue Execute(LiteDatabase db, StringScanner s) { - if (db == null) throw new LiteException("No database"); - var id = this.ReadId(s); var filename = Path.GetFullPath(s.Scan(@"\s*.*").Trim()); diff --git a/LiteDB/Shell/Commands/Others/Dump.cs b/LiteDB/Shell/Commands/Others/Dump.cs index 8211142e0..0a17f65fc 100644 --- a/LiteDB/Shell/Commands/Others/Dump.cs +++ b/LiteDB/Shell/Commands/Others/Dump.cs @@ -6,7 +6,7 @@ namespace LiteDB.Shell.Commands { - public class Dump : ILiteCommand + internal class Dump : ILiteCommand { public bool IsCommand(StringScanner s) { @@ -15,7 +15,6 @@ public bool IsCommand(StringScanner s) public BsonValue Execute(LiteDatabase db, StringScanner s) { - if (db == null) throw new LiteException("No database"); var result = new StringBuilder(); if (s.HasTerminated || s.Match("mem$")) diff --git a/LiteDB/Shell/Commands/Others/Info.cs b/LiteDB/Shell/Commands/Others/Info.cs index 21e6400e8..80a2dc00c 100644 --- a/LiteDB/Shell/Commands/Others/Info.cs +++ b/LiteDB/Shell/Commands/Others/Info.cs @@ -6,7 +6,7 @@ namespace LiteDB.Shell.Commands { - public class Info : ILiteCommand + internal class Info : ILiteCommand { public bool IsCommand(StringScanner s) { @@ -15,8 +15,6 @@ public bool IsCommand(StringScanner s) public BsonValue Execute(LiteDatabase db, StringScanner s) { - if (db == null) throw new LiteException("No database"); - return db.GetDatabaseInfo(); } } diff --git a/LiteDB/Shell/Commands/Others/ShowCollections.cs b/LiteDB/Shell/Commands/Others/ShowCollections.cs index 503007562..52df5ddcc 100644 --- a/LiteDB/Shell/Commands/Others/ShowCollections.cs +++ b/LiteDB/Shell/Commands/Others/ShowCollections.cs @@ -6,7 +6,7 @@ namespace LiteDB.Shell.Commands { - public class ShowCollections : ILiteCommand + internal class ShowCollections : ILiteCommand { public bool IsCommand(StringScanner s) { @@ -15,8 +15,6 @@ public bool IsCommand(StringScanner s) public BsonValue Execute(LiteDatabase db, StringScanner s) { - if (db == null) throw new LiteException("No database"); - var cols = db.GetCollectionNames().OrderBy(x => x).ToArray(); return string.Join(Environment.NewLine, cols); diff --git a/LiteDB/Shell/Commands/Transactions/Begin.cs b/LiteDB/Shell/Commands/Transactions/Begin.cs index b3fc865fa..9ce130a99 100644 --- a/LiteDB/Shell/Commands/Transactions/Begin.cs +++ b/LiteDB/Shell/Commands/Transactions/Begin.cs @@ -6,7 +6,7 @@ namespace LiteDB.Shell.Commands { - public class Begin : ILiteCommand + internal class Begin : ILiteCommand { public bool IsCommand(StringScanner s) { @@ -15,8 +15,6 @@ public bool IsCommand(StringScanner s) public BsonValue Execute(LiteDatabase db, StringScanner s) { - if (db == null) throw new LiteException("No database"); - db.BeginTrans(); return BsonValue.Null; diff --git a/LiteDB/Shell/Commands/Transactions/Commit.cs b/LiteDB/Shell/Commands/Transactions/Commit.cs index c5a1c0bb9..388444a16 100644 --- a/LiteDB/Shell/Commands/Transactions/Commit.cs +++ b/LiteDB/Shell/Commands/Transactions/Commit.cs @@ -6,7 +6,7 @@ namespace LiteDB.Shell.Commands { - public class Commit : ILiteCommand + internal class Commit : ILiteCommand { public bool IsCommand(StringScanner s) { @@ -15,8 +15,6 @@ public bool IsCommand(StringScanner s) public BsonValue Execute(LiteDatabase db, StringScanner s) { - if (db == null) throw new LiteException("No database"); - db.Commit(); return BsonValue.Null; diff --git a/LiteDB/Shell/Commands/Transactions/Rollback.cs b/LiteDB/Shell/Commands/Transactions/Rollback.cs index 52e1a0773..cf07cb7c6 100644 --- a/LiteDB/Shell/Commands/Transactions/Rollback.cs +++ b/LiteDB/Shell/Commands/Transactions/Rollback.cs @@ -6,7 +6,7 @@ namespace LiteDB.Shell.Commands { - public class Rollback : ILiteCommand + internal class Rollback : ILiteCommand { public bool IsCommand(StringScanner s) { @@ -15,8 +15,6 @@ public bool IsCommand(StringScanner s) public BsonValue Execute(LiteDatabase db, StringScanner s) { - if (db == null) throw new LiteException("No database"); - db.Rollback(); return BsonValue.Null; diff --git a/LiteDB/Shell/LiteShell.cs b/LiteDB/Shell/LiteShell.cs index c5552c473..b71120cc9 100644 --- a/LiteDB/Shell/LiteShell.cs +++ b/LiteDB/Shell/LiteShell.cs @@ -7,22 +7,16 @@ namespace LiteDB.Shell { - public class LiteShell : IDisposable + public class LiteShell { - private List _commands = new List(); - - public LiteShell() - { - } + public List Commands { get; set; } public LiteDatabase Database { get; set; } - /// - /// Register all commands: search for all classes that implements ILiteCommand - /// - public void RegisterAll() + public LiteShell(LiteDatabase db) { - _commands = new List(); + this.Database = db; + this.Commands = new List(); var type = typeof(ILiteCommand); var types = AppDomain.CurrentDomain.GetAssemblies() @@ -31,36 +25,30 @@ public void RegisterAll() foreach (var t in types) { - _commands.Add((ILiteCommand)Activator.CreateInstance(t)); + this.Commands.Add((ILiteCommand)Activator.CreateInstance(t)); } } - public void Register() - where T : ILiteCommand, new() - { - _commands.Add(new T()); - } - public BsonValue Run(string command) { if (string.IsNullOrEmpty(command)) return BsonValue.Null; var s = new StringScanner(command); - foreach (var cmd in _commands) + foreach (var cmd in this.Commands) { if (cmd.IsCommand(s)) { + if (this.Database == null) + { + throw new LiteException("No database. Use `open ` to open/create database"); + } + return cmd.Execute(this.Database, s); } } throw new LiteException("Command ´" + command + "´ is not a valid command"); } - - public void Dispose() - { - if (this.Database != null) this.Database.Dispose(); - } } } diff --git a/WebShell/Commands/Help.cs b/WebShell/Commands/Help.cs deleted file mode 100644 index c91c54c47..000000000 --- a/WebShell/Commands/Help.cs +++ /dev/null @@ -1,59 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Linq; -using System.Text; - -namespace LiteDB.Shell.Commands -{ - public class Help : ILiteCommand - { - public bool IsCommand(StringScanner s) - { - return s.Scan(@"help$").Length > 0; - } - - public BsonValue Execute(LiteDatabase db, StringScanner s) - { - var sb = new StringBuilder(); - - this.Write(sb, "Web Shell Commands - try offline version for more commands"); - this.Write(sb, "=========================================================="); - - this.Write(sb, "> db..insert ", "Insert a new document into collection"); - this.Write(sb, "> db..update ", "Update a document inside collection"); - this.Write(sb, "> db..delete ", "Delete documents using a filter clausule (see find)"); - this.Write(sb, "> db..find [top N] ", "Show filtered documents based on index search"); - this.Write(sb, "> db..count ", "Show count rows according query filter"); - this.Write(sb, "> db..ensureIndex [unique]", "Create a new index document field"); - this.Write(sb, "> db..indexes", "List all indexes in this collection"); - this.Write(sb, " = [=|>|>=|<|<=|!=|like|between] ", "Filter query syntax"); - this.Write(sb, " = ( [and|or] [and|or] ...)", "Multi queries syntax"); - - this.Write(sb, "Try:"); - this.Write(sb, " > db.customers.insert { _id:1, name:\"John Doe\", age: 37 }"); - this.Write(sb, " > db.customers.ensureIndex name"); - this.Write(sb, " > db.customers.find name like \"John\""); - this.Write(sb, " > db.customers.find top 10 (name like \"John\" and _id between [0, 100])"); - - return sb.ToString(); - } - - private void Write(StringBuilder sb, string line1 = null, string line2 = null) - { - if (string.IsNullOrEmpty(line1)) - { - sb.AppendLine(); - } - else - { - sb.AppendLine(line1); - - if (!string.IsNullOrEmpty(line2)) - { - sb.AppendLine(" " + line2); - } - } - } - } -} diff --git a/WebShell/WebShell.csproj b/WebShell/WebShell.csproj index 3968e0a03..80f7d90c7 100644 --- a/WebShell/WebShell.csproj +++ b/WebShell/WebShell.csproj @@ -58,7 +58,6 @@ - diff --git a/WebShell/api.ashx b/WebShell/api.ashx index 727fbac55..1d5782a9c 100644 --- a/WebShell/api.ashx +++ b/WebShell/api.ashx @@ -24,18 +24,7 @@ public class WebShell : IHttpHandler using (var shell = new LiteShell()) { // accept only a subset commands - shell.Register(); - shell.Register(); - shell.Register(); - shell.Register(); - shell.Register(); - shell.Register(); - shell.Register(); - shell.Register(); - shell.Register(); - shell.Register(); - shell.Register(); - shell.Register(); + shell.WebMode = true; shell.Display.Pretty = true; shell.Database = new LiteDB.LiteDatabase(filename); From ed7411fa58be3fffad3b8375690df7fc4ca29c14 Mon Sep 17 00:00:00 2001 From: mbdavid Date: Tue, 10 Feb 2015 14:51:29 -0200 Subject: [PATCH 10/96] Remove WebShell from solution --- LiteDB/Database/Tools/GetDatabaseInfo.cs | 4 + WebShell/Properties/AssemblyInfo.cs | 35 ------- WebShell/WebShell.csproj | 113 ----------------------- WebShell/api.ashx | 45 --------- WebShell/index.html | 109 ---------------------- 5 files changed, 4 insertions(+), 302 deletions(-) delete mode 100644 WebShell/Properties/AssemblyInfo.cs delete mode 100644 WebShell/WebShell.csproj delete mode 100644 WebShell/api.ashx delete mode 100644 WebShell/index.html diff --git a/LiteDB/Database/Tools/GetDatabaseInfo.cs b/LiteDB/Database/Tools/GetDatabaseInfo.cs index 26e13a5b5..dcf22da87 100644 --- a/LiteDB/Database/Tools/GetDatabaseInfo.cs +++ b/LiteDB/Database/Tools/GetDatabaseInfo.cs @@ -27,6 +27,10 @@ public BsonObject GetDatabaseInfo() info["pagesInCache"] = this.Cache.PagesInCache; info["dirtyPages"] = this.Cache.GetDirtyPages().Count(); + //TODO: Add collections info + // Add indexes info + // Add storage used/free info + return info; } } diff --git a/WebShell/Properties/AssemblyInfo.cs b/WebShell/Properties/AssemblyInfo.cs deleted file mode 100644 index c5337b61a..000000000 --- a/WebShell/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("WebShell")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("WebShell")] -[assembly: AssemblyCopyright("Copyright © 2015")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("fdebc8d1-9be0-433d-985c-b54c8c4487d2")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Revision and Build Numbers -// by using the '*' as shown below: -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/WebShell/WebShell.csproj b/WebShell/WebShell.csproj deleted file mode 100644 index 80f7d90c7..000000000 --- a/WebShell/WebShell.csproj +++ /dev/null @@ -1,113 +0,0 @@ - - - - - Debug - AnyCPU - - - 2.0 - {D5C5126F-1D96-4543-A6CC-D323C2E53FC5} - {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} - Library - Properties - WebShell - WebShell - v4.5 - true - - - - - - - true - full - false - bin\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\ - TRACE - prompt - 4 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {e808051a-83b7-4fa9-b004-d064ea162b60} - LiteDB - - - - - - - - - - - 10.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - - - - - - - - - False - True - 49446 - / - http://localhost:55834/ - False - False - - - False - - - - - - \ No newline at end of file diff --git a/WebShell/api.ashx b/WebShell/api.ashx deleted file mode 100644 index 1d5782a9c..000000000 --- a/WebShell/api.ashx +++ /dev/null @@ -1,45 +0,0 @@ -<%@ WebHandler Language="C#" Class="WebShell" %> -using System; -using System.Web; -using System.Linq; -using System.Text; -using System.Text.RegularExpressions; -using LiteDB; -using LiteDB.Shell; -using LiteDB.Shell.Commands; - -public class WebShell : IHttpHandler -{ - public void ProcessRequest (HttpContext context) - { - var db = context.Request.Form["db"]; - var command = context.Request.Form["cmd"]; - - try - { - if (!Regex.IsMatch(db, @"^db_\d{13}$")) throw new ArgumentException("Invalid database name"); - - var filename = context.Server.MapPath("~/App_Data/" + db + ".db"); - - using (var shell = new LiteShell()) - { - // accept only a subset commands - shell.WebMode = true; - - shell.Display.Pretty = true; - shell.Database = new LiteDB.LiteDatabase(filename); - shell.Display.TextWriters.Add(context.Response.Output); - - shell.Run(command); - } - } - catch(Exception ex) - { - context.Response.Clear(); - context.Response.Write("ERROR: " + ex.Message); - } - } - - public bool IsReusable { get { return false; } } - -} \ No newline at end of file diff --git a/WebShell/index.html b/WebShell/index.html deleted file mode 100644 index 8c9ab136e..000000000 --- a/WebShell/index.html +++ /dev/null @@ -1,109 +0,0 @@ - - - - LiteDB Web Shell - - - - - - - -

LiteDB Web Shell - (Download offline version) -

- -
-
- Welcome to LiteDB Web Shell - Version 0.8

- Getting started with `help`

-
-
- -
-
- - - - - - From 1f468b879a2ba36b43a44286dc8e4766902ba914 Mon Sep 17 00:00:00 2001 From: mbdavid Date: Tue, 10 Feb 2015 14:51:29 -0200 Subject: [PATCH 11/96] Remove WebShell from solution --- LiteDB.sln | 6 -- LiteDB/Database/Tools/GetDatabaseInfo.cs | 4 + WebShell/Properties/AssemblyInfo.cs | 35 ------- WebShell/WebShell.csproj | 113 ----------------------- WebShell/api.ashx | 45 --------- WebShell/index.html | 109 ---------------------- 6 files changed, 4 insertions(+), 308 deletions(-) delete mode 100644 WebShell/Properties/AssemblyInfo.cs delete mode 100644 WebShell/WebShell.csproj delete mode 100644 WebShell/api.ashx delete mode 100644 WebShell/index.html diff --git a/LiteDB.sln b/LiteDB.sln index ae7427d4b..746d0c3f5 100644 --- a/LiteDB.sln +++ b/LiteDB.sln @@ -7,8 +7,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTest", "UnitTest\UnitTe EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LiteDB.Shell", "LiteDB.Shell\LiteDB.Shell.csproj", "{5C46B331-F4DC-469D-B370-532E67CBA808}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebShell", "WebShell\WebShell.csproj", "{D5C5126F-1D96-4543-A6CC-D323C2E53FC5}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -27,10 +25,6 @@ Global {5C46B331-F4DC-469D-B370-532E67CBA808}.Debug|Any CPU.Build.0 = Debug|Any CPU {5C46B331-F4DC-469D-B370-532E67CBA808}.Release|Any CPU.ActiveCfg = Release|Any CPU {5C46B331-F4DC-469D-B370-532E67CBA808}.Release|Any CPU.Build.0 = Release|Any CPU - {D5C5126F-1D96-4543-A6CC-D323C2E53FC5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D5C5126F-1D96-4543-A6CC-D323C2E53FC5}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D5C5126F-1D96-4543-A6CC-D323C2E53FC5}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D5C5126F-1D96-4543-A6CC-D323C2E53FC5}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/LiteDB/Database/Tools/GetDatabaseInfo.cs b/LiteDB/Database/Tools/GetDatabaseInfo.cs index 26e13a5b5..dcf22da87 100644 --- a/LiteDB/Database/Tools/GetDatabaseInfo.cs +++ b/LiteDB/Database/Tools/GetDatabaseInfo.cs @@ -27,6 +27,10 @@ public BsonObject GetDatabaseInfo() info["pagesInCache"] = this.Cache.PagesInCache; info["dirtyPages"] = this.Cache.GetDirtyPages().Count(); + //TODO: Add collections info + // Add indexes info + // Add storage used/free info + return info; } } diff --git a/WebShell/Properties/AssemblyInfo.cs b/WebShell/Properties/AssemblyInfo.cs deleted file mode 100644 index c5337b61a..000000000 --- a/WebShell/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("WebShell")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("WebShell")] -[assembly: AssemblyCopyright("Copyright © 2015")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("fdebc8d1-9be0-433d-985c-b54c8c4487d2")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Revision and Build Numbers -// by using the '*' as shown below: -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/WebShell/WebShell.csproj b/WebShell/WebShell.csproj deleted file mode 100644 index 80f7d90c7..000000000 --- a/WebShell/WebShell.csproj +++ /dev/null @@ -1,113 +0,0 @@ - - - - - Debug - AnyCPU - - - 2.0 - {D5C5126F-1D96-4543-A6CC-D323C2E53FC5} - {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} - Library - Properties - WebShell - WebShell - v4.5 - true - - - - - - - true - full - false - bin\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\ - TRACE - prompt - 4 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {e808051a-83b7-4fa9-b004-d064ea162b60} - LiteDB - - - - - - - - - - - 10.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - - - - - - - - - False - True - 49446 - / - http://localhost:55834/ - False - False - - - False - - - - - - \ No newline at end of file diff --git a/WebShell/api.ashx b/WebShell/api.ashx deleted file mode 100644 index 1d5782a9c..000000000 --- a/WebShell/api.ashx +++ /dev/null @@ -1,45 +0,0 @@ -<%@ WebHandler Language="C#" Class="WebShell" %> -using System; -using System.Web; -using System.Linq; -using System.Text; -using System.Text.RegularExpressions; -using LiteDB; -using LiteDB.Shell; -using LiteDB.Shell.Commands; - -public class WebShell : IHttpHandler -{ - public void ProcessRequest (HttpContext context) - { - var db = context.Request.Form["db"]; - var command = context.Request.Form["cmd"]; - - try - { - if (!Regex.IsMatch(db, @"^db_\d{13}$")) throw new ArgumentException("Invalid database name"); - - var filename = context.Server.MapPath("~/App_Data/" + db + ".db"); - - using (var shell = new LiteShell()) - { - // accept only a subset commands - shell.WebMode = true; - - shell.Display.Pretty = true; - shell.Database = new LiteDB.LiteDatabase(filename); - shell.Display.TextWriters.Add(context.Response.Output); - - shell.Run(command); - } - } - catch(Exception ex) - { - context.Response.Clear(); - context.Response.Write("ERROR: " + ex.Message); - } - } - - public bool IsReusable { get { return false; } } - -} \ No newline at end of file diff --git a/WebShell/index.html b/WebShell/index.html deleted file mode 100644 index 8c9ab136e..000000000 --- a/WebShell/index.html +++ /dev/null @@ -1,109 +0,0 @@ - - - - LiteDB Web Shell - - - - - - - -

LiteDB Web Shell - (Download offline version) -

- -
-
- Welcome to LiteDB Web Shell - Version 0.8

- Getting started with `help`

-
-
- -
-
- - - - - - From 1aade15e9ca635126010108669cfcaede510d9fb Mon Sep 17 00:00:00 2001 From: mbdavid Date: Wed, 11 Feb 2015 11:05:40 -0200 Subject: [PATCH 12/96] Bug fix: Query with Id property converts to _id internal Fix readme --- LiteDB/Database/Collections/LiteCollection.Delete.cs | 2 +- LiteDB/Database/Collections/LiteCollection.Find.cs | 6 +++--- ...ion.InsertBulk.cs => LiteCollection.InsertBatch.cs} | 2 +- LiteDB/LiteDB.csproj | 2 +- LiteDB/Query/Query.cs | 8 +++++++- LiteDB/Query/QueryAnd.cs | 6 +++--- LiteDB/Query/QueryOr.cs | 6 +++--- LiteDB/Shell/Commands/Collections/Bulk.cs | 2 +- README.md | 10 +++++----- UnitTest/LinqTest.cs | 2 ++ 10 files changed, 27 insertions(+), 19 deletions(-) rename LiteDB/Database/Collections/{LiteCollection.InsertBulk.cs => LiteCollection.InsertBatch.cs} (95%) diff --git a/LiteDB/Database/Collections/LiteCollection.Delete.cs b/LiteDB/Database/Collections/LiteCollection.Delete.cs index 02dc39a97..4ad280c7e 100644 --- a/LiteDB/Database/Collections/LiteCollection.Delete.cs +++ b/LiteDB/Database/Collections/LiteCollection.Delete.cs @@ -73,7 +73,7 @@ public virtual int Delete(Query query) var count = 0; // find nodes - var nodes = query.Run(this.Database, col); + var nodes = query.Run(this.Database, col); foreach (var node in nodes) { diff --git a/LiteDB/Database/Collections/LiteCollection.Find.cs b/LiteDB/Database/Collections/LiteCollection.Find.cs index 4c94f6000..18d59354d 100644 --- a/LiteDB/Database/Collections/LiteCollection.Find.cs +++ b/LiteDB/Database/Collections/LiteCollection.Find.cs @@ -63,7 +63,7 @@ public IEnumerable Find(Query query) if (col == null) yield break; - var nodes = query.Run(this.Database, col); + var nodes = query.Run(this.Database, col); foreach (var node in nodes) { @@ -119,7 +119,7 @@ public int Count(Query query) if (col == null) return 0; - return query.Run(this.Database, col).Count(); + return query.Run(this.Database, col).Count(); } /// @@ -141,7 +141,7 @@ public bool Exists(Query query) if (col == null) return false; - return query.Run(this.Database, col).FirstOrDefault() != null; + return query.Run(this.Database, col).FirstOrDefault() != null; } /// diff --git a/LiteDB/Database/Collections/LiteCollection.InsertBulk.cs b/LiteDB/Database/Collections/LiteCollection.InsertBatch.cs similarity index 95% rename from LiteDB/Database/Collections/LiteCollection.InsertBulk.cs rename to LiteDB/Database/Collections/LiteCollection.InsertBatch.cs index 5cefdcd85..91e00f6d2 100644 --- a/LiteDB/Database/Collections/LiteCollection.InsertBulk.cs +++ b/LiteDB/Database/Collections/LiteCollection.InsertBatch.cs @@ -11,7 +11,7 @@ public partial class LiteCollection /// /// Bulk documents to a collection - use data chunks for most efficient insert /// - public int InsertBulk(IEnumerable docs, int buffer = 2000) + public int InsertBatch(IEnumerable docs, int buffer = 2000) { if(docs == null) throw new ArgumentNullException("docs"); if(buffer < 100) throw new ArgumentException("buffer must be bigger than 100"); diff --git a/LiteDB/LiteDB.csproj b/LiteDB/LiteDB.csproj index 840cf0dc2..8025e279c 100644 --- a/LiteDB/LiteDB.csproj +++ b/LiteDB/LiteDB.csproj @@ -47,7 +47,7 @@ - + diff --git a/LiteDB/Query/Query.cs b/LiteDB/Query/Query.cs index 5672d3407..b2dafd6be 100644 --- a/LiteDB/Query/Query.cs +++ b/LiteDB/Query/Query.cs @@ -126,8 +126,14 @@ public static Query Or(Query left, Query right) // used for execute in results (AND/OR) internal abstract IEnumerable Execute(LiteDatabase db, CollectionIndex index); - internal virtual IEnumerable Run(LiteDatabase db, CollectionPage col) + internal virtual IEnumerable Run(LiteDatabase db, CollectionPage col) { + var type = typeof(T); + var idAttr = type == typeof(BsonDocument) ? "_id" : BsonSerializer.GetIdProperty(type).Name; + + // if you are running a query with Id attribute, lets convert to _id + if (this.Field == idAttr) this.Field = "_id"; + var index = col.Indexes.FirstOrDefault(x => x.Field.Equals(this.Field, StringComparison.InvariantCultureIgnoreCase)); if (index == null) throw new LiteException(string.Format("Index '{0}.{1}' not found. Use EnsureIndex to create a new index.", col.CollectionName, this.Field)); diff --git a/LiteDB/Query/QueryAnd.cs b/LiteDB/Query/QueryAnd.cs index 419bbd04d..b40dea5b1 100644 --- a/LiteDB/Query/QueryAnd.cs +++ b/LiteDB/Query/QueryAnd.cs @@ -24,10 +24,10 @@ internal override IEnumerable Execute(LiteDatabase db, CollectionInde return null; } - internal override IEnumerable Run(LiteDatabase db, CollectionPage col) + internal override IEnumerable Run(LiteDatabase db, CollectionPage col) { - var left = this.Left.Run(db, col); - var right = this.Right.Run(db, col); + var left = this.Left.Run(db, col); + var right = this.Right.Run(db, col); return left.Intersect(right, new IndexNodeComparer()); } diff --git a/LiteDB/Query/QueryOr.cs b/LiteDB/Query/QueryOr.cs index 86d26c01c..a41223b2c 100644 --- a/LiteDB/Query/QueryOr.cs +++ b/LiteDB/Query/QueryOr.cs @@ -24,10 +24,10 @@ internal override IEnumerable Execute(LiteDatabase db, CollectionInde return null; } - internal override IEnumerable Run(LiteDatabase db, CollectionPage col) + internal override IEnumerable Run(LiteDatabase db, CollectionPage col) { - var left = this.Left.Run(db, col); - var right = this.Right.Run(db, col); + var left = this.Left.Run(db, col); + var right = this.Right.Run(db, col); return left.Union(right, new IndexNodeComparer()); } diff --git a/LiteDB/Shell/Commands/Collections/Bulk.cs b/LiteDB/Shell/Commands/Collections/Bulk.cs index df5aefd2b..97c698f14 100644 --- a/LiteDB/Shell/Commands/Collections/Bulk.cs +++ b/LiteDB/Shell/Commands/Collections/Bulk.cs @@ -21,7 +21,7 @@ public BsonValue Execute(LiteDatabase db, StringScanner s) var json = File.ReadAllText(filename, Encoding.UTF8); var docs = JsonSerializer.DeserializeArray(json); - return col.InsertBulk(docs); + return col.InsertBatch(docs); } } } diff --git a/README.md b/README.md index 64919e564..d205097a2 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ A quick example for store and search documents: ```C# // Open data file (or create if not exits) -using(var db = new LiteEngine(@"C:\Temp\MyData.db")) +using(var db = new LiteDatabase(@"C:\Temp\MyData.db")) { // Get a collection (or create, if not exits) var col = db.GetCollection("customers"); @@ -121,10 +121,10 @@ With `BsonDocument` you can create any complex document schema. ## Collections - the store -LiteDB organize documents in stores (called in LiteDB as collections). Each collection has a unique name and contains documents with same schema/type. You can get a strong typed collection or a generic `BsonDocument` collections, using `GetCollection` from `LiteEngine` instance. +LiteDB organize documents in stores (called in LiteDB as collections). Each collection has a unique name and contains documents with same schema/type. You can get a strong typed collection or a generic `BsonDocument` collections, using `GetCollection` from `LiteDatabase` instance. ```C# -var db = new LiteEngine(stringConnection); +var db = new LiteDatabase(stringConnection); // Get a strong typed collection var customers = db.GetCollection("Customers"); @@ -185,7 +185,7 @@ For simplicity, LiteDB do not support concurrency transactions. LiteDB locks you After commit method called, LiteDB store all dirty pages to disk. This operations is a fail torelance. Before write direct to disk, LiteDB create a temp file (called journal file) to store all dirty pages. If there is any error during write data file, journaling save a redo log file with database dirty pages, to recovery your datafile when datafile open again. ```C# -using(var db = new LiteEngine(dbpath)) +using(var db = new LiteDatabase(dbpath)) { db.BeginTrans(); @@ -219,7 +219,7 @@ db.FileStorage.Download("my_key.png", stream); ## Connection String -Connection string options to initialize LiteEngine class: +Connection string options to initialize `LiteDatabase` class: - **Filename**: Path for datafile. You can use only path as connection string (required) - **Timeout**: timeout for wait for unlock datafile (default: 00:01:00) diff --git a/UnitTest/LinqTest.cs b/UnitTest/LinqTest.cs index 40b1393a3..c46f0f316 100644 --- a/UnitTest/LinqTest.cs +++ b/UnitTest/LinqTest.cs @@ -31,6 +31,8 @@ public void Linq_Test() var past = -30; // simple + Assert.AreEqual(1, col.Count(x => x.CustomerId == c1.CustomerId)); + Assert.AreEqual(1, col.Count(x => x.Name == "Chris")); Assert.AreEqual(2, col.Count(x => x.CreationDate == new DateTime(2015, 1, 1))); Assert.AreEqual(1, col.Count(x => x.Name.StartsWith("mal"))); From 98dfe2f5a20d006965168171e856c3bb8aa3e4ac Mon Sep 17 00:00:00 2001 From: mbdavid Date: Wed, 11 Feb 2015 13:49:37 -0200 Subject: [PATCH 13/96] Add regular expressions in objects on JsonReader - getting faster json parser --- ...tBatch.cs => LiteCollection.InsertBulk.cs} | 2 +- LiteDB/LiteDB.csproj | 2 +- LiteDB/Serializer/Json/JsonReader.cs | 120 +++++++++++------- LiteDB/Shell/Commands/Collections/Bulk.cs | 2 +- LiteDB/Utils/StringScanner.cs | 24 +++- UnitTest/JsonTest.cs | 9 ++ UnitTest/LinqTest.cs | 2 +- UnitTest/PerfTest.cs | 2 +- 8 files changed, 109 insertions(+), 54 deletions(-) rename LiteDB/Database/Collections/{LiteCollection.InsertBatch.cs => LiteCollection.InsertBulk.cs} (95%) diff --git a/LiteDB/Database/Collections/LiteCollection.InsertBatch.cs b/LiteDB/Database/Collections/LiteCollection.InsertBulk.cs similarity index 95% rename from LiteDB/Database/Collections/LiteCollection.InsertBatch.cs rename to LiteDB/Database/Collections/LiteCollection.InsertBulk.cs index 91e00f6d2..f22873100 100644 --- a/LiteDB/Database/Collections/LiteCollection.InsertBatch.cs +++ b/LiteDB/Database/Collections/LiteCollection.InsertBulk.cs @@ -11,7 +11,7 @@ public partial class LiteCollection /// /// Bulk documents to a collection - use data chunks for most efficient insert /// - public int InsertBatch(IEnumerable docs, int buffer = 2000) + public int InsertBulk(IEnumerable docs, int buffer = 32768) { if(docs == null) throw new ArgumentNullException("docs"); if(buffer < 100) throw new ArgumentException("buffer must be bigger than 100"); diff --git a/LiteDB/LiteDB.csproj b/LiteDB/LiteDB.csproj index 8025e279c..840cf0dc2 100644 --- a/LiteDB/LiteDB.csproj +++ b/LiteDB/LiteDB.csproj @@ -47,7 +47,7 @@ - + diff --git a/LiteDB/Serializer/Json/JsonReader.cs b/LiteDB/Serializer/Json/JsonReader.cs index e7b10f2a7..2753c7200 100644 --- a/LiteDB/Serializer/Json/JsonReader.cs +++ b/LiteDB/Serializer/Json/JsonReader.cs @@ -3,6 +3,7 @@ using System.Globalization; using System.Linq; using System.Text; +using System.Text.RegularExpressions; namespace LiteDB { @@ -10,6 +11,25 @@ internal class JsonReader { internal static NumberFormatInfo _enUS = new CultureInfo("en-US").NumberFormat; + #region Regular expressions + + private static Regex SPACE = new Regex(@"^\s*"); + private static Regex NULL = new Regex(@"^null"); + private static Regex BEGIN_ARRAY = new Regex(@"^\["); + private static Regex END_ARRAY = new Regex(@"^\]"); + private static Regex EXT_DATA = new Regex(@"^{\s*[""]?\$\w+[""]?\s*:\s*""[^""]*""\s*}"); + private static Regex BEGIN_DOC = new Regex(@"^\{"); + private static Regex END_DOC = new Regex(@"^\}"); + private static Regex BEGIN_STRING = new Regex("^\""); + private static Regex STRING = new Regex(@"(?:[^""\\]|\\.)*"); + private static Regex NUMBER = new Regex(@"^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?"); + private static Regex BOOLEAN = new Regex(@"^(true|false)"); + private static Regex KEY = new Regex(@"^[\w$]+"); + private static Regex KEY_VALUE_SEP = new Regex(@"\s*:\s*"); + private static Regex COMMA = new Regex(@"^,"); + + #endregion + public BsonValue Deserialize(string json) { if(string.IsNullOrEmpty(json)) return new BsonObject(); @@ -21,35 +41,35 @@ public BsonValue Deserialize(string json) internal BsonValue ReadValue(StringScanner s) { - s.Scan(@"\s*"); + s.Scan(SPACE); - if (s.Scan("null").Length > 0) + if (s.Scan(NULL).Length > 0) { return BsonValue.Null; } - else if (s.Match(@"\[")) + else if (s.Match(BEGIN_ARRAY)) { return this.ReadArray(s); } - else if (s.Match(@"{\s*[""]?\$\w+[""]?\s*:\s*""[^""]*""\s*}")) + else if (s.Match(EXT_DATA)) { return this.ReadExtendDataType(s); } - else if (s.Match(@"{")) + else if (s.Match(BEGIN_DOC)) { return this.ReadObject(s); } - else if (s.Match("\"")) + else if (s.Match(BEGIN_STRING)) { return new BsonValue(this.ReadString(s)); } - else if (s.Match(@"[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?")) + else if (s.Match(BOOLEAN)) { - return this.ReadNumber(s); + return new BsonValue(bool.Parse(s.Scan(BOOLEAN))); } - else if (s.Match(@"(true|false)")) + else if (s.Match(NUMBER)) { - return new BsonValue(bool.Parse(s.Scan("(true|false)"))); + return this.ReadNumber(s); } throw new ArgumentException("String is not a valid JsonEx"); @@ -59,28 +79,22 @@ private BsonObject ReadObject(StringScanner s) { var obj = new BsonObject(); - s.Scan(@"\s*{"); + s.Scan(BEGIN_DOC); - while (!s.Match(@"\s*}")) + while (!s.Match(END_DOC)) { - s.Scan(@"\s*"); - - // accept key without " - var key = s.Match(@"[\w$]+") ? - s.Scan(@"[\w$]+") : this.ReadString(s); + var key = this.ReadKey(s); - if (key.Trim().Length == 0) throw new ArgumentException("Invalid json object key"); + s.Scan(KEY_VALUE_SEP); - s.Scan(@"\s*:\s*"); + obj[key] = this.ReadValue(s); - var value = this.ReadValue(s); + s.Scan(SPACE); - obj[key] = value; - - if(s.Scan(@"\s*,").Length == 0) break; + if(s.Scan(COMMA).Length == 0) break; } - if (s.Scan(@"\s*}").Length == 0) throw new ArgumentException("Missing close json object symbol"); + if (s.Scan(END_DOC).Length == 0) throw new ArgumentException("Missing close json object symbol"); return obj; } @@ -89,18 +103,18 @@ private BsonArray ReadArray(StringScanner s) { var arr = new BsonArray(); - s.Scan(@"\s*\["); + s.Scan(BEGIN_ARRAY); - while(!s.Match(@"\s*\]")) + while(!s.Match(END_ARRAY)) { - var value = this.ReadValue(s); + arr.Add(this.ReadValue(s)); - arr.Add(value); + s.Scan(SPACE); - if(s.Scan(@"\s*,").Length == 0) break; + if(s.Scan(COMMA).Length == 0) break; } - if(s.Scan(@"\s*\]").Length == 0) throw new ArgumentException("Missing close json array symbol"); + if(s.Scan(END_ARRAY).Length == 0) throw new ArgumentException("Missing close json array symbol"); return arr; } @@ -109,27 +123,31 @@ public IEnumerable ReadEnumerable(string json) { var s = new StringScanner(json); - if (s.Scan(@"\s*\[").Length == 0) throw new ArgumentException("String is not a json array"); + s.Scan(SPACE); + + if (s.Scan(BEGIN_ARRAY).Length == 0) throw new ArgumentException("String is not a json array"); - while (!s.Match(@"\s*\]")) + while (!s.Match(END_ARRAY)) { yield return this.ReadValue(s); - if (s.Scan(@"\s*,").Length == 0) break; + s.Scan(SPACE); + + if (s.Scan(COMMA).Length == 0) break; } - if (s.Scan(@"\s*\]").Length == 0) throw new ArgumentException("Missing close json array symbol"); + if (s.Scan(END_ARRAY).Length == 0) throw new ArgumentException("Missing close json array symbol"); yield break; } private string ReadString(StringScanner s) { - if(s.Scan(@"\s*\""").Length == 0) throw new ArgumentException("Invalid json string"); + if(s.Scan(BEGIN_STRING).Length == 0) throw new ArgumentException("Invalid json string"); - var str = s.ScanUntil(@"(?:[^""\\]|\\.)*"); + var str = s.ScanUntil(STRING); - if (s.Scan("\"").Length == 0) throw new ArgumentException("Invalid json string"); + if (s.Scan(BEGIN_STRING).Length == 0) throw new ArgumentException("Invalid json string"); return str; } @@ -137,7 +155,7 @@ private string ReadString(StringScanner s) private BsonValue ReadNumber(StringScanner s) { var nf = CultureInfo.InvariantCulture.NumberFormat; - var value = s.Scan(@"[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?"); + var value = s.Scan(NUMBER); if (value.Contains(".")) { @@ -151,15 +169,16 @@ private BsonValue ReadNumber(StringScanner s) private BsonValue ReadExtendDataType(StringScanner s) { - s.Scan(@"\{\s*"); - var dataType = s.Match(@"[$\w]+") ? s.Scan(@"[$\w]+") : this.ReadString(s); - s.Scan(@"\s*:\s*"); + s.Scan(BEGIN_DOC); + var key = this.ReadKey(s); + s.Scan(KEY_VALUE_SEP); var value = this.ReadString(s); - s.Scan(@"\s*}"); + s.Scan(SPACE); + s.Scan(END_DOC); try { - switch (dataType) + switch (key) { case "$date": return new BsonValue(DateTime.Parse(value)); case "$guid": return new BsonValue(new Guid(value)); @@ -168,10 +187,21 @@ private BsonValue ReadExtendDataType(StringScanner s) } catch (Exception ex) { - throw new FormatException("Invalid " + dataType + " value in " + value, ex); + throw new FormatException("Invalid " + key + " key in " + value, ex); } - throw new ArgumentException("Invalid JSON extended format"); + throw new ArgumentException("Invalid json extended format"); + } + + private string ReadKey(StringScanner s) + { + s.Scan(SPACE); + + var key = s.Scan(KEY); + + if (key.Length == 0) key = this.ReadString(s); + + return key; } } } diff --git a/LiteDB/Shell/Commands/Collections/Bulk.cs b/LiteDB/Shell/Commands/Collections/Bulk.cs index 97c698f14..df5aefd2b 100644 --- a/LiteDB/Shell/Commands/Collections/Bulk.cs +++ b/LiteDB/Shell/Commands/Collections/Bulk.cs @@ -21,7 +21,7 @@ public BsonValue Execute(LiteDatabase db, StringScanner s) var json = File.ReadAllText(filename, Encoding.UTF8); var docs = JsonSerializer.DeserializeArray(json); - return col.InsertBatch(docs); + return col.InsertBulk(docs); } } } diff --git a/LiteDB/Utils/StringScanner.cs b/LiteDB/Utils/StringScanner.cs index f6cbbfc21..743cf0947 100644 --- a/LiteDB/Utils/StringScanner.cs +++ b/LiteDB/Utils/StringScanner.cs @@ -34,7 +34,11 @@ public bool HasTerminated public string Scan(string pattern) { - var regex = new Regex((pattern.StartsWith("^") ? "" : "^") + pattern, RegexOptions.IgnorePatternWhitespace); + return this.Scan(new Regex((pattern.StartsWith("^") ? "" : "^") + pattern, RegexOptions.IgnorePatternWhitespace)); + } + + public string Scan(Regex regex) + { var match = regex.Match(this.Source, this.Index, this.Source.Length - this.Index); if (match.Success) @@ -53,7 +57,11 @@ public string Scan(string pattern) /// public string Scan(string pattern, int group) { - var regex = new Regex((pattern.StartsWith("^") ? "" : "^") + pattern, RegexOptions.IgnorePatternWhitespace); + return this.Scan(new Regex((pattern.StartsWith("^") ? "" : "^") + pattern, RegexOptions.IgnorePatternWhitespace), group); + } + + public string Scan(Regex regex, int group) + { var match = regex.Match(this.Source, this.Index, this.Source.Length - this.Index); if (match.Success) @@ -69,7 +77,11 @@ public string Scan(string pattern, int group) public string ScanUntil(string pattern) { - var regex = new Regex(pattern, RegexOptions.IgnorePatternWhitespace); + return this.ScanUntil(new Regex(pattern, RegexOptions.IgnorePatternWhitespace)); + } + + public string ScanUntil(Regex regex) + { var match = regex.Match(this.Source, this.Index, this.Source.Length - this.Index); if (match.Success) @@ -86,7 +98,11 @@ public string ScanUntil(string pattern) public bool Match(string pattern) { - var regex = new Regex((pattern.StartsWith("^") ? "": "^") + pattern, RegexOptions.IgnorePatternWhitespace); + return this.Match(new Regex((pattern.StartsWith("^") ? "" : "^") + pattern, RegexOptions.IgnorePatternWhitespace)); + } + + public bool Match(Regex regex) + { var match = regex.Match(this.Source, this.Index, this.Source.Length - this.Index); return match.Success; } diff --git a/UnitTest/JsonTest.cs b/UnitTest/JsonTest.cs index 08c04da6c..112262545 100644 --- a/UnitTest/JsonTest.cs +++ b/UnitTest/JsonTest.cs @@ -56,5 +56,14 @@ public void Json_Test() } + [TestMethod] + public void Json_Perf_Test() + { + var f = @"C:\Github\LiteDB_dev\LiteDB.Shell\bin\Debug\test-20000.json"; + var json = File.ReadAllText(f); + + JsonSerializer.Deserialize(json); + } + } } diff --git a/UnitTest/LinqTest.cs b/UnitTest/LinqTest.cs index c46f0f316..d413e3712 100644 --- a/UnitTest/LinqTest.cs +++ b/UnitTest/LinqTest.cs @@ -26,7 +26,7 @@ public void Linq_Test() col.EnsureIndex(x => x.Name, true); col.EnsureIndex(x => x.CreationDate); - col.InsertBatch(new Customer[] { c1, c2, c3, c4 }); + col.InsertBulk(new Customer[] { c1, c2, c3, c4 }); var past = -30; diff --git a/UnitTest/PerfTest.cs b/UnitTest/PerfTest.cs index 24501420b..ad8736a09 100644 --- a/UnitTest/PerfTest.cs +++ b/UnitTest/PerfTest.cs @@ -21,7 +21,7 @@ public void Perf_Test() { db.BeginTrans(); var col = db.GetCollection("posts"); - col.InsertBatch(Post.GetData(20000)); + col.InsertBulk(Post.GetData(20000)); db.Commit(); } } From ebeb0ec5d995666eaa1011e061e762a594554264 Mon Sep 17 00:00:00 2001 From: mbdavid Date: Wed, 11 Feb 2015 22:25:23 -0200 Subject: [PATCH 14/96] Add limit and skip on find shell query --- LiteDB.Shell/Commands/Help.cs | 14 ++++++------- LiteDB/LiteDB.csproj | 2 +- .../Commands/Collections/BaseCollection.cs | 21 ++++++++++++++----- LiteDB/Shell/Commands/Collections/Count.cs | 6 +++--- LiteDB/Shell/Commands/Collections/Find.cs | 7 ++++--- LiteDB/Shell/Commands/Collections/Rename.cs | 6 +++--- 6 files changed, 34 insertions(+), 22 deletions(-) diff --git a/LiteDB.Shell/Commands/Help.cs b/LiteDB.Shell/Commands/Help.cs index 117c578a2..8ec431ccc 100644 --- a/LiteDB.Shell/Commands/Help.cs +++ b/LiteDB.Shell/Commands/Help.cs @@ -26,7 +26,7 @@ public override void Execute(LiteShell shell, StringScanner s, Display d, InputC d.WriteHelp("> db..insert ", "Insert a new document into collection"); d.WriteHelp("> db..update ", "Update a document inside collection"); d.WriteHelp("> db..delete ", "Delete documents using a filter clausule (see find)"); - d.WriteHelp("> db..find [top N] ", "Show filtered documents based on index search"); + d.WriteHelp("> db..find [skip N][limit N]", "Show filtered documents based on index search"); d.WriteHelp("> db..count ", "Show count rows according query filter"); d.WriteHelp("> db..ensureIndex [unique]", "Create a new index document field"); d.WriteHelp("> db..indexes", "List all indexes in this collection"); @@ -37,7 +37,7 @@ public override void Execute(LiteShell shell, StringScanner s, Display d, InputC d.WriteHelp(" > db.customers.insert { _id:1, name:\"John Doe\", age: 37 }"); d.WriteHelp(" > db.customers.ensureIndex name"); d.WriteHelp(" > db.customers.find name like \"John\""); - d.WriteHelp(" > db.customers.find top 10 (name like \"John\" and _id between [0, 100])"); + d.WriteHelp(" > db.customers.find (name like \"John\" and _id between [0, 100]) limit 10"); } else { @@ -71,8 +71,8 @@ public override void Execute(LiteShell shell, StringScanner s, Display d, InputC d.WriteHelp("> db..update ", "Update a document inside collection"); d.WriteHelp("> db..delete ", "Delete documents using a filter clausule (see find)"); d.WriteHelp("> db..bulk ", "Bulk insert a json file as documents"); - d.WriteHelp("> db..find [top N]", "Show all documents. Can limit results in N documents"); - d.WriteHelp("> db..find [top N] ", "Show filtered documents based on index search"); + d.WriteHelp("> db..find [skip N][limit N]", "Show all documents. Can limit/skip results"); + d.WriteHelp("> db..find [skip N][limit N]", "Show filtered documents based on index search. See syntax below"); d.WriteHelp("> db..count ", "Show count rows according query filter"); d.WriteHelp("> db..exec { Action }", "Execute C# code for each document based on filter."); d.WriteHelp("> db..ensureIndex [unique]", "Create a new index document field"); @@ -83,9 +83,9 @@ public override void Execute(LiteShell shell, StringScanner s, Display d, InputC d.WriteHelp(" = [=|>|>=|<|<=|!=|like|between] ", "Filter query syntax"); d.WriteHelp(" = ( [and|or] [and|or] ...)", "Multi queries syntax"); d.WriteHelp(" = {_id: ... , key: value, key1: value1 }", "Represent a json (extended version) for a BsonDocument. See special data types"); - d.WriteHelp("JsonEx Date", "{ mydate: { $date :\"2015-01-01T23:59:59Z\"} }"); - d.WriteHelp("JsonEx Guid", "{ myguid: { $guid :\"3a1c34b3-9f66-4d8e-975a-d545d898a4ba\"} }"); - d.WriteHelp("JsonEx Binary", "{ mydata: { $binary :\"base64 byte array\"} }"); + d.WriteHelp("Json Date", "{ mydate: { $date :\"2015-01-01T23:59:59Z\"} }"); + d.WriteHelp("Json Guid", "{ myguid: { $guid :\"3a1c34b3-9f66-4d8e-975a-d545d898a4ba\"} }"); + d.WriteHelp("Json Binary", "{ mydata: { $binary :\"base64 byte array\"} }"); d.WriteHelp(); d.WriteHelp("File storage commands"); diff --git a/LiteDB/LiteDB.csproj b/LiteDB/LiteDB.csproj index 840cf0dc2..77d48a934 100644 --- a/LiteDB/LiteDB.csproj +++ b/LiteDB/LiteDB.csproj @@ -95,8 +95,8 @@ - + diff --git a/LiteDB/Shell/Commands/Collections/BaseCollection.cs b/LiteDB/Shell/Commands/Collections/BaseCollection.cs index 8b6ec7dcf..ef90c2d8d 100644 --- a/LiteDB/Shell/Commands/Collections/BaseCollection.cs +++ b/LiteDB/Shell/Commands/Collections/BaseCollection.cs @@ -20,19 +20,30 @@ public bool IsCollectionCommand(StringScanner s, string command) return s.Match(@"db\.\w+\." + command); } - public int ReadTop(StringScanner s) + public IEnumerable ReadSkipLimit(StringScanner s, IEnumerable docs) { - if (s.Match(@"top\s+\d+\s*")) + if (s.Match(@"skip\s+\d+")) { - return Convert.ToInt32(s.Scan(@"top\s+(\d+)\s*", 1)); + docs = docs.Skip(Convert.ToInt32(s.Scan(@"skip\s+(\d+)\s*", 1))); } - return int.MaxValue; + if (s.Match(@"limit\s+\d+")) + { + docs = docs.Take(Convert.ToInt32(s.Scan(@"limit\s+(\d+)\s*", 1))); + } + + // skip can be before or after limit command + if (s.Match(@"skip\s+\d+")) + { + docs = docs.Skip(Convert.ToInt32(s.Scan(@"skip\s+(\d+)\s*", 1))); + } + + return docs; } public Query ReadQuery(StringScanner s) { - if (s.HasTerminated) + if (s.HasTerminated || s.Match(@"skip\s+\d") || s.Match(@"limit\s+\d")) { return Query.All(); } diff --git a/LiteDB/Shell/Commands/Collections/Count.cs b/LiteDB/Shell/Commands/Collections/Count.cs index 07022b9de..689b2b858 100644 --- a/LiteDB/Shell/Commands/Collections/Count.cs +++ b/LiteDB/Shell/Commands/Collections/Count.cs @@ -10,15 +10,15 @@ internal class CollectionCount : BaseCollection, ILiteCommand { public bool IsCommand(StringScanner s) { - return this.IsCollectionCommand(s, "rename"); + return this.IsCollectionCommand(s, "count"); } public BsonValue Execute(LiteDatabase db, StringScanner s) { var col = this.ReadCollection(db, s); - var newName = s.Scan(@"\w+"); + var query = this.ReadQuery(s); - return db.RenameCollection(col.Name, newName); + return col.Count(query); } } } diff --git a/LiteDB/Shell/Commands/Collections/Find.cs b/LiteDB/Shell/Commands/Collections/Find.cs index b5ad53d54..216661c02 100644 --- a/LiteDB/Shell/Commands/Collections/Find.cs +++ b/LiteDB/Shell/Commands/Collections/Find.cs @@ -16,11 +16,12 @@ public bool IsCommand(StringScanner s) public BsonValue Execute(LiteDatabase db, StringScanner s) { var col = this.ReadCollection(db, s); - var top = this.ReadTop(s); var query = this.ReadQuery(s); - var docs = col.Find(query).Take(top); + var docs = col.Find(query); - return BsonArray.FromEnumerable(docs); + var result = this.ReadSkipLimit(s, docs); + + return BsonArray.FromEnumerable(result); } } } diff --git a/LiteDB/Shell/Commands/Collections/Rename.cs b/LiteDB/Shell/Commands/Collections/Rename.cs index b5de7f384..0a418d0ce 100644 --- a/LiteDB/Shell/Commands/Collections/Rename.cs +++ b/LiteDB/Shell/Commands/Collections/Rename.cs @@ -10,15 +10,15 @@ internal class CollectionRename : BaseCollection, ILiteCommand { public bool IsCommand(StringScanner s) { - return this.IsCollectionCommand(s, "count"); + return this.IsCollectionCommand(s, "rename"); } public BsonValue Execute(LiteDatabase db, StringScanner s) { var col = this.ReadCollection(db, s); - var query = this.ReadQuery(s); + var newName = s.Scan(@"\w+"); - return col.Count(query); + return db.RenameCollection(col.Name, newName); } } } From 7c4ab2735a324a37bea49a7b0c90b4e5819231e8 Mon Sep 17 00:00:00 2001 From: mbdavid Date: Thu, 12 Feb 2015 09:22:34 -0200 Subject: [PATCH 15/96] Bugfix on limit/skip in shell + change journal filename --- LiteDB/Serializer/Json/JsonReader.cs | 16 +++++----- .../Commands/Collections/BaseCollection.cs | 30 +++++++------------ LiteDB/Shell/Commands/Collections/Find.cs | 10 +++++-- LiteDB/Storage/Services/JournalService.cs | 27 ++++++++--------- 4 files changed, 40 insertions(+), 43 deletions(-) diff --git a/LiteDB/Serializer/Json/JsonReader.cs b/LiteDB/Serializer/Json/JsonReader.cs index 2753c7200..074628cc3 100644 --- a/LiteDB/Serializer/Json/JsonReader.cs +++ b/LiteDB/Serializer/Json/JsonReader.cs @@ -13,7 +13,7 @@ internal class JsonReader #region Regular expressions - private static Regex SPACE = new Regex(@"^\s*"); + private static Regex WHITESPACE = new Regex(@"^\s*"); private static Regex NULL = new Regex(@"^null"); private static Regex BEGIN_ARRAY = new Regex(@"^\["); private static Regex END_ARRAY = new Regex(@"^\]"); @@ -41,7 +41,7 @@ public BsonValue Deserialize(string json) internal BsonValue ReadValue(StringScanner s) { - s.Scan(SPACE); + s.Scan(WHITESPACE); if (s.Scan(NULL).Length > 0) { @@ -89,7 +89,7 @@ private BsonObject ReadObject(StringScanner s) obj[key] = this.ReadValue(s); - s.Scan(SPACE); + s.Scan(WHITESPACE); if(s.Scan(COMMA).Length == 0) break; } @@ -109,7 +109,7 @@ private BsonArray ReadArray(StringScanner s) { arr.Add(this.ReadValue(s)); - s.Scan(SPACE); + s.Scan(WHITESPACE); if(s.Scan(COMMA).Length == 0) break; } @@ -123,7 +123,7 @@ public IEnumerable ReadEnumerable(string json) { var s = new StringScanner(json); - s.Scan(SPACE); + s.Scan(WHITESPACE); if (s.Scan(BEGIN_ARRAY).Length == 0) throw new ArgumentException("String is not a json array"); @@ -131,7 +131,7 @@ public IEnumerable ReadEnumerable(string json) { yield return this.ReadValue(s); - s.Scan(SPACE); + s.Scan(WHITESPACE); if (s.Scan(COMMA).Length == 0) break; } @@ -173,7 +173,7 @@ private BsonValue ReadExtendDataType(StringScanner s) var key = this.ReadKey(s); s.Scan(KEY_VALUE_SEP); var value = this.ReadString(s); - s.Scan(SPACE); + s.Scan(WHITESPACE); s.Scan(END_DOC); try @@ -195,7 +195,7 @@ private BsonValue ReadExtendDataType(StringScanner s) private string ReadKey(StringScanner s) { - s.Scan(SPACE); + s.Scan(WHITESPACE); var key = s.Scan(KEY); diff --git a/LiteDB/Shell/Commands/Collections/BaseCollection.cs b/LiteDB/Shell/Commands/Collections/BaseCollection.cs index ef90c2d8d..24200f3aa 100644 --- a/LiteDB/Shell/Commands/Collections/BaseCollection.cs +++ b/LiteDB/Shell/Commands/Collections/BaseCollection.cs @@ -20,25 +20,23 @@ public bool IsCollectionCommand(StringScanner s, string command) return s.Match(@"db\.\w+\." + command); } - public IEnumerable ReadSkipLimit(StringScanner s, IEnumerable docs) + public void ReadSkipLimit(StringScanner s, ref int? skip, ref int? limit) { - if (s.Match(@"skip\s+\d+")) + if (s.Match(@"\s*skip\s+\d+")) { - docs = docs.Skip(Convert.ToInt32(s.Scan(@"skip\s+(\d+)\s*", 1))); + skip = Convert.ToInt32(s.Scan(@"\s*skip\s+(\d+)\s*", 1)); } - if (s.Match(@"limit\s+\d+")) + if (s.Match(@"\s*limit\s+\d+")) { - docs = docs.Take(Convert.ToInt32(s.Scan(@"limit\s+(\d+)\s*", 1))); + limit = Convert.ToInt32(s.Scan(@"\s*limit\s+(\d+)\s*", 1)); } // skip can be before or after limit command - if (s.Match(@"skip\s+\d+")) + if (s.Match(@"\s*skip\s+\d+")) { - docs = docs.Skip(Convert.ToInt32(s.Scan(@"skip\s+(\d+)\s*", 1))); + skip = Convert.ToInt32(s.Scan(@"\s*skip\s+(\d+)\s*", 1)); } - - return docs; } public Query ReadQuery(StringScanner s) @@ -47,26 +45,20 @@ public Query ReadQuery(StringScanner s) { return Query.All(); } - else if(s.Scan(@"\(").Length > 0) - { - return this.ReadInlineQuery(s); - } - else - { - return this.ReadOneQuery(s); - } + + return this.ReadInlineQuery(s); } private Query ReadInlineQuery(StringScanner s) { var left = this.ReadOneQuery(s); - if (s.Scan(@"\s*\)\s*").Length > 0) + if (s.Match(@"\s+(and|or)\s+") == false) { return left; } - var oper = s.Scan(@"\s*(and|or)\s*").Trim(); + var oper = s.Scan(@"\s+(and|or)\s+").Trim(); if(oper.Length == 0) throw new ApplicationException("Invalid query operator"); diff --git a/LiteDB/Shell/Commands/Collections/Find.cs b/LiteDB/Shell/Commands/Collections/Find.cs index 216661c02..36a26a400 100644 --- a/LiteDB/Shell/Commands/Collections/Find.cs +++ b/LiteDB/Shell/Commands/Collections/Find.cs @@ -18,10 +18,16 @@ public BsonValue Execute(LiteDatabase db, StringScanner s) var col = this.ReadCollection(db, s); var query = this.ReadQuery(s); var docs = col.Find(query); + int? skip = null; + int? limit = null; - var result = this.ReadSkipLimit(s, docs); + this.ReadSkipLimit(s, ref skip, ref limit); - return BsonArray.FromEnumerable(result); + // skip and limit must be in order: "skip" then "limit" + if (skip.HasValue) docs = docs.Skip(skip.Value); + if (limit.HasValue) docs = docs.Take(limit.Value); + + return BsonArray.FromEnumerable(docs); } } } diff --git a/LiteDB/Storage/Services/JournalService.cs b/LiteDB/Storage/Services/JournalService.cs index 97fdcef2a..27ee42dfd 100644 --- a/LiteDB/Storage/Services/JournalService.cs +++ b/LiteDB/Storage/Services/JournalService.cs @@ -83,11 +83,6 @@ private void WritePageInJournal(BinaryWriter writer, BasePage page) // Write page header page.WriteHeader(writer); - if (page.FreeBytes < 0) - { - throw new Exception("No-way!"); - } - // write content except for empty pages if (page.PageType != PageType.Empty) { @@ -99,7 +94,7 @@ private void WritePageInJournal(BinaryWriter writer, BasePage page) } /// - /// Get a new journal file to write or check if exits one. Append (index) if journal file exists (when OS do not deleted yet - check better OS support) + /// Get a new journal file to write or check if exits one. If exists, test durint timeout - can be another process deleting /// public static string GetJournalFilename(ConnectionString connectionString, bool newFile) { @@ -107,23 +102,27 @@ public static string GetJournalFilename(ConnectionString connectionString, bool var filename = Path.GetFileNameWithoutExtension(connectionString.Filename) + "-journal"; var ext = Path.GetExtension(connectionString.Filename); + var journal = Path.Combine(dir, filename + ext); + if (newFile) { - var file = ""; - var index = 0; + var timeout = DateTime.Now.Add(connectionString.Timeout); - while (File.Exists(file = Path.Combine(dir, filename + (index > 0 ? index.ToString() : "") + ext))) + while (DateTime.Now < timeout) { - index++; + if (!File.Exists(journal)) + { + return journal; + } + + System.Threading.Thread.Sleep(250); } - return file; + throw new LiteException("There is a jounal file. Please reopen database"); } else { - var files = Directory.GetFiles(dir, filename + "*" + ext, SearchOption.TopDirectoryOnly); - - return files.Length > 0 ? files.Last() : null; + return File.Exists(journal) ? journal : null; } } } From a995e008261caee6bdb8574cfb62610b68e0b85c Mon Sep 17 00:00:00 2001 From: mbdavid Date: Fri, 13 Feb 2015 16:40:00 -0200 Subject: [PATCH 16/96] JsonWriter using TextWriter --- LiteDB/Serializer/Json/JsonReader.cs | 2 -- LiteDB/Serializer/Json/JsonSerializer.cs | 19 ++++++++--- LiteDB/Serializer/Json/JsonWriter.cs | 41 +++++++++++------------- 3 files changed, 33 insertions(+), 29 deletions(-) diff --git a/LiteDB/Serializer/Json/JsonReader.cs b/LiteDB/Serializer/Json/JsonReader.cs index 074628cc3..40547fe05 100644 --- a/LiteDB/Serializer/Json/JsonReader.cs +++ b/LiteDB/Serializer/Json/JsonReader.cs @@ -9,8 +9,6 @@ namespace LiteDB { internal class JsonReader { - internal static NumberFormatInfo _enUS = new CultureInfo("en-US").NumberFormat; - #region Regular expressions private static Regex WHITESPACE = new Regex(@"^\s*"); diff --git a/LiteDB/Serializer/Json/JsonSerializer.cs b/LiteDB/Serializer/Json/JsonSerializer.cs index 63df5e61b..86ea31615 100644 --- a/LiteDB/Serializer/Json/JsonSerializer.cs +++ b/LiteDB/Serializer/Json/JsonSerializer.cs @@ -1,24 +1,33 @@ using System; using System.Collections.Generic; using System.Globalization; +using System.IO; using System.Linq; using System.Text; namespace LiteDB { /// - /// Static class for serialize/deserialize BsonDocuments into Json extended format + /// Static class for serialize/deserialize BsonDocuments into json extended format /// public class JsonSerializer { /// - /// Serialize a BsonDocument (or any BsonValue) into a JsonEx string + /// Serialize a BsonDocument (or any BsonValue) into a json string /// - public static string Serialize(BsonValue value, bool pretty = false, bool showBinary = true) + public static string Serialize(BsonValue value, bool pretty = false, bool writeBinary = true) { - var writer = new JsonWriter(pretty, showBinary); + var sb = new StringBuilder(); - return writer.Serialize(value); + using (var w = new StringWriter(sb)) + { + var writer = new JsonWriter(w); + writer.Pretty = pretty; + writer.WriteBinary = writeBinary; + writer.Serialize(value); + } + + return sb.ToString(); } /// diff --git a/LiteDB/Serializer/Json/JsonWriter.cs b/LiteDB/Serializer/Json/JsonWriter.cs index d51831828..843b30408 100644 --- a/LiteDB/Serializer/Json/JsonWriter.cs +++ b/LiteDB/Serializer/Json/JsonWriter.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Globalization; +using System.IO; using System.Linq; using System.Text; @@ -8,29 +9,25 @@ namespace LiteDB { internal class JsonWriter { - private const int TAB_SIZE = 4; + private const int INDENT_SIZE = 4; - private StringBuilder _sb; + private TextWriter _writer; private int _indent; - private string _spacer; - private bool _pretty; - private bool _showBinary; - public JsonWriter(bool pretty, bool showBinary) + private string Spacer { get { return this.Pretty ? " " : ""; } } + public bool Pretty { get; set; } + public bool WriteBinary { get; set; } + + public JsonWriter(TextWriter writer) { - _pretty = pretty; - _showBinary = showBinary; + _writer = writer; } - public string Serialize(BsonValue value) + public void Serialize(BsonValue value) { - _sb = new StringBuilder(); _indent = 0; - _spacer = _pretty ? " " : ""; this.WriteValue(value); - - return _sb.ToString().Trim(); } private void WriteValue(BsonValue value) @@ -53,7 +50,7 @@ private void WriteValue(BsonValue value) } else if (value.Type == BsonType.ByteArray) { - this.WriteExtendDataType("$binary", _showBinary ? System.Convert.ToBase64String(value.AsByteArray) : "-- " + value.AsByteArray.Length + " bytes --"); + this.WriteExtendDataType("$binary", this.WriteBinary ? Convert.ToBase64String(value.AsByteArray) : "-- " + value.AsByteArray.Length + " bytes --"); } else if (value.Type == BsonType.Char) { @@ -179,23 +176,23 @@ private void WriteString(string s) private void Write(object obj) { - _sb.Append(obj); + _writer.Write(obj); } private void WriteFormat(string format, params object[] args) { - _sb.AppendFormat(format, args); + _writer.Write(format, args); } private void WriteExtendDataType(string type, string value) { - this.WriteFormat("{{{0}\"{1}\":{0}\"{2}\"{0}}}", _spacer, type, value); + this.WriteFormat("{{{0}\"{1}\":{0}\"{2}\"{0}}}", this.Spacer, type, value); } private void WriteKeyValue(string key, BsonValue value, bool comma) { this.WriteIndent(); - this.WriteFormat("\"{0}\":{1}", key, _spacer); + this.WriteFormat("\"{0}\":{1}", key, this.Spacer); if ((value.IsObject && value.AsObject.Keys.Length > 0) || (value.IsArray && value.AsArray.Length > 0)) { @@ -243,17 +240,17 @@ private void WriteEndBlock(string str, bool hasData) private void WriteNewLine() { - if (_pretty) + if (this.Pretty) { - _sb.AppendLine(); + _writer.WriteLine(); } } private void WriteIndent() { - if (_pretty) + if (this.Pretty) { - _sb.Append("".PadRight(_indent * TAB_SIZE, ' ')); + _writer.Write("".PadRight(_indent * INDENT_SIZE, ' ')); } } } From 86e8a7f27d5e50071c877b918a0e51c18a302d99 Mon Sep 17 00:00:00 2001 From: mbdavid Date: Fri, 13 Feb 2015 23:24:17 -0200 Subject: [PATCH 17/96] Fix var name --- LiteDB/Serializer/Json/JsonReader.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/LiteDB/Serializer/Json/JsonReader.cs b/LiteDB/Serializer/Json/JsonReader.cs index 40547fe05..e7609f264 100644 --- a/LiteDB/Serializer/Json/JsonReader.cs +++ b/LiteDB/Serializer/Json/JsonReader.cs @@ -23,7 +23,7 @@ internal class JsonReader private static Regex NUMBER = new Regex(@"^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?"); private static Regex BOOLEAN = new Regex(@"^(true|false)"); private static Regex KEY = new Regex(@"^[\w$]+"); - private static Regex KEY_VALUE_SEP = new Regex(@"\s*:\s*"); + private static Regex COLON = new Regex(@"\s*:\s*"); private static Regex COMMA = new Regex(@"^,"); #endregion @@ -51,7 +51,7 @@ internal BsonValue ReadValue(StringScanner s) } else if (s.Match(EXT_DATA)) { - return this.ReadExtendDataType(s); + return this.ReadExtendDataType(s); // must precede ReadObject } else if (s.Match(BEGIN_DOC)) { @@ -83,7 +83,7 @@ private BsonObject ReadObject(StringScanner s) { var key = this.ReadKey(s); - s.Scan(KEY_VALUE_SEP); + s.Scan(COLON); obj[key] = this.ReadValue(s); @@ -169,7 +169,7 @@ private BsonValue ReadExtendDataType(StringScanner s) { s.Scan(BEGIN_DOC); var key = this.ReadKey(s); - s.Scan(KEY_VALUE_SEP); + s.Scan(COLON); var value = this.ReadString(s); s.Scan(WHITESPACE); s.Scan(END_DOC); From 38f3db9a10c07f5005443b20766f74323e32e025 Mon Sep 17 00:00:00 2001 From: mbdavid Date: Sat, 14 Feb 2015 23:28:02 -0200 Subject: [PATCH 18/96] BsonWriter + BsonReader - no mapper yet --- .../Collections/LiteCollection.Delete.cs | 11 +- .../Collections/LiteCollection.Find.cs | 23 +- .../Collections/LiteCollection.Index.cs | 26 +- .../Collections/LiteCollection.Insert.cs | 32 +- .../Collections/LiteCollection.Update.cs | 47 +- LiteDB/Database/FileStorage/LiteFileInfo.cs | 2 +- LiteDB/Database/FileStorage/LiteFileStream.cs | 2 +- LiteDB/Database/LiteDatabase.cs | 4 + LiteDB/Document/BsonArray.cs | 19 +- LiteDB/Document/BsonDocument.cs | 36 +- LiteDB/Document/BsonObject.cs | 17 +- LiteDB/Document/BsonType.cs | 18 +- LiteDB/Document/BsonValue.cs | 306 ++----- .../Mapper}/BsonIdAttribute.cs | 0 .../Mapper}/BsonIgnoreAttribute.cs | 0 LiteDB/Document/Mapper/BsonMapper.cs | 36 + LiteDB/LiteDB.csproj | 16 +- LiteDB/Query/Query.cs | 8 +- LiteDB/Query/QueryAnd.cs | 6 +- LiteDB/Query/QueryOr.cs | 6 +- LiteDB/Serializer/Bson/BsonReader.cs | 143 ++++ LiteDB/Serializer/Bson/BsonSerializer.cs | 196 +---- LiteDB/Serializer/Bson/BsonWriter.cs | 157 ++++ LiteDB/Serializer/Json/JsonReader.cs | 5 +- LiteDB/Serializer/Json/JsonSerializer.cs | 52 +- LiteDB/Serializer/Json/JsonWriter.cs | 48 +- LiteDB/Serializer/fastBinaryJSON/BJSON.cs | 772 ------------------ .../Serializer/fastBinaryJSON/BJsonParser.cs | 288 ------- .../fastBinaryJSON/BJsonSerializer.cs | 621 -------------- LiteDB/Serializer/fastBinaryJSON/Getters.cs | 11 - .../Serializer/fastBinaryJSON/Reflection.cs | 569 ------------- .../fastBinaryJSON/SafeDictionary.cs | 132 --- LiteDB/Serializer/fastBinaryJSON/_README.txt | 5 - LiteDB/Shell/Commands/Collections/Bulk.cs | 4 +- LiteDB/Shell/Commands/Collections/Insert.cs | 2 +- LiteDB/Shell/Commands/Collections/Update.cs | 2 +- LiteDB/Storage/Pages/CollectionPage.cs | 14 +- LiteDB/Storage/Pages/DataPage.cs | 2 - LiteDB/Storage/Services/CollectionService.cs | 38 +- LiteDB/Storage/Services/DataService.cs | 8 +- LiteDB/Storage/Services/IndexService.cs | 5 +- LiteDB/Storage/Structures/CollectionIndex.cs | 5 + LiteDB/Storage/Structures/DataBlock.cs | 8 +- LiteDB/Storage/Structures/IndexKey.cs | 60 +- LiteDB/Utils/BinaryReaderExtensions.cs | 15 - LiteDB/Utils/BinaryWriterExtensions.cs | 38 +- LiteDB/Utils/DictionaryExtensions.cs | 9 - UnitTest/BsonTest.cs | 68 ++ UnitTest/DocumentTest.cs | 42 +- UnitTest/JsonTest.cs | 8 +- UnitTest/PageTest.cs | 9 - UnitTest/UnitTest.csproj | 2 +- UnitTest/Utils/Dump.cs | 211 ----- 53 files changed, 737 insertions(+), 3427 deletions(-) rename LiteDB/{Serializer/Bson => Document/Mapper}/BsonIdAttribute.cs (100%) rename LiteDB/{Serializer/Bson => Document/Mapper}/BsonIgnoreAttribute.cs (100%) create mode 100644 LiteDB/Document/Mapper/BsonMapper.cs create mode 100644 LiteDB/Serializer/Bson/BsonReader.cs create mode 100644 LiteDB/Serializer/Bson/BsonWriter.cs delete mode 100644 LiteDB/Serializer/fastBinaryJSON/BJSON.cs delete mode 100644 LiteDB/Serializer/fastBinaryJSON/BJsonParser.cs delete mode 100644 LiteDB/Serializer/fastBinaryJSON/BJsonSerializer.cs delete mode 100644 LiteDB/Serializer/fastBinaryJSON/Getters.cs delete mode 100644 LiteDB/Serializer/fastBinaryJSON/Reflection.cs delete mode 100644 LiteDB/Serializer/fastBinaryJSON/SafeDictionary.cs delete mode 100644 LiteDB/Serializer/fastBinaryJSON/_README.txt create mode 100644 UnitTest/BsonTest.cs delete mode 100644 UnitTest/Utils/Dump.cs diff --git a/LiteDB/Database/Collections/LiteCollection.Delete.cs b/LiteDB/Database/Collections/LiteCollection.Delete.cs index 4ad280c7e..ec4f1a8ae 100644 --- a/LiteDB/Database/Collections/LiteCollection.Delete.cs +++ b/LiteDB/Database/Collections/LiteCollection.Delete.cs @@ -73,7 +73,7 @@ public virtual int Delete(Query query) var count = 0; // find nodes - var nodes = query.Run(this.Database, col); + var nodes = query.Run(this.Database, col); foreach (var node in nodes) { @@ -113,14 +113,9 @@ internal virtual void Delete(CollectionPage col, IndexNode node) var dataBlock = this.Database.Data.Read(node.DataBlock, false); // lets remove all indexes that point to this in dataBlock - for (byte i = 0; i < col.Indexes.Length; i++) + foreach (var index in col.GetIndexes(true)) { - var index = col.Indexes[i]; - - if (!index.IsEmpty) - { - this.Database.Indexer.Delete(index, dataBlock.IndexRef[i]); - } + this.Database.Indexer.Delete(index, dataBlock.IndexRef[index.Slot]); } // remove object data diff --git a/LiteDB/Database/Collections/LiteCollection.Find.cs b/LiteDB/Database/Collections/LiteCollection.Find.cs index 18d59354d..d5554499d 100644 --- a/LiteDB/Database/Collections/LiteCollection.Find.cs +++ b/LiteDB/Database/Collections/LiteCollection.Find.cs @@ -26,14 +26,16 @@ public T FindById(object id) var dataBlock = this.Database.Data.Read(node.DataBlock, true); - var doc = BsonSerializer.Deserialize(dataBlock.Key, dataBlock.Buffer); + var doc = BsonSerializer.Deserialize(dataBlock.Buffer).AsDocument; + + var obj = this.Database.Mapper.ToObject(doc); foreach (var action in _includes) { - action(doc); + action(obj); } - return doc; + return obj; } /// @@ -63,20 +65,23 @@ public IEnumerable Find(Query query) if (col == null) yield break; - var nodes = query.Run(this.Database, col); + var nodes = query.Run(this.Database, col); foreach (var node in nodes) { var dataBlock = this.Database.Data.Read(node.DataBlock, true); - var doc = BsonSerializer.Deserialize(dataBlock.Key, dataBlock.Buffer); + var doc = BsonSerializer.Deserialize(dataBlock.Buffer).AsDocument; + + // get object from BsonDocument + var obj = this.Database.Mapper.ToObject(doc); foreach (var action in _includes) { - action(doc); + action(obj); } - yield return doc; + yield return obj; } } @@ -119,7 +124,7 @@ public int Count(Query query) if (col == null) return 0; - return query.Run(this.Database, col).Count(); + return query.Run(this.Database, col).Count(); } /// @@ -141,7 +146,7 @@ public bool Exists(Query query) if (col == null) return false; - return query.Run(this.Database, col).FirstOrDefault() != null; + return query.Run(this.Database, col).FirstOrDefault() != null; } /// diff --git a/LiteDB/Database/Collections/LiteCollection.Index.cs b/LiteDB/Database/Collections/LiteCollection.Index.cs index 0bcaec1da..cfe3bf841 100644 --- a/LiteDB/Database/Collections/LiteCollection.Index.cs +++ b/LiteDB/Database/Collections/LiteCollection.Index.cs @@ -48,11 +48,8 @@ public virtual bool EnsureIndex(string field, bool unique = false) _pageID = col.PageID; } - // get index slot - var slot = col.GetFreeIndex(); - // create index head - var index = this.Database.Indexer.CreateIndex(col.Indexes[slot]); + var index = this.Database.Indexer.CreateIndex(col); index.Field = field; index.Unique = unique; @@ -63,15 +60,15 @@ public virtual bool EnsureIndex(string field, bool unique = false) var dataBlock = this.Database.Data.Read(node.DataBlock, true); // read object - var doc = BsonSerializer.Deserialize(dataBlock.Key, dataBlock.Buffer); + var doc = BsonSerializer.Deserialize(dataBlock.Buffer).AsDocument; // adding index - var key = BsonSerializer.GetFieldValue(doc, field); + var key = doc.GetFieldValue(field); var newNode = this.Database.Indexer.AddNode(index, key); // adding this new index Node to indexRef - dataBlock.IndexRef[slot] = newNode.Position; + dataBlock.IndexRef[index.Slot] = newNode.Position; // link index node to datablock newNode.DataBlock = dataBlock.Position; @@ -114,17 +111,12 @@ public IEnumerable GetIndexes() if (col == null) yield break; - for (var i = 0; i < CollectionIndex.INDEX_PER_COLLECTION; i++) + foreach(var index in col.GetIndexes(true)) { - var index = col.Indexes[i]; - - if (!index.IsEmpty) - { - yield return new BsonDocument() - .Add("slot", i) - .Add("field", index.Field) - .Add("unique", index.Unique); - } + yield return new BsonObject() + .Add("slot", index.Slot) + .Add("field", index.Field) + .Add("unique", index.Unique); } } diff --git a/LiteDB/Database/Collections/LiteCollection.Insert.cs b/LiteDB/Database/Collections/LiteCollection.Insert.cs index 1c1e59bf0..709948b3e 100644 --- a/LiteDB/Database/Collections/LiteCollection.Insert.cs +++ b/LiteDB/Database/Collections/LiteCollection.Insert.cs @@ -11,14 +11,13 @@ public partial class LiteCollection /// /// Insert a new document to this collection. Document Id must be a new value in collection /// - public virtual void Insert(T doc) + public virtual void Insert(T document) { - if (doc == null) throw new ArgumentNullException("doc"); + if (document == null) throw new ArgumentNullException("document"); - // gets document Id - var id = BsonSerializer.GetIdValue(doc); + var doc = this.Database.Mapper.ToDocument(document); - if (id == null) throw new LiteException("Document Id can't be null"); + if (doc.Id == null) throw new LiteException("Document Id can't be null"); // serialize object var bytes = BsonSerializer.Serialize(doc); @@ -30,32 +29,27 @@ public virtual void Insert(T doc) var col = this.GetCollectionPage(true); // storage in data pages - returns dataBlock address - var dataBlock = this.Database.Data.Insert(col, new IndexKey(id), bytes); + var dataBlock = this.Database.Data.Insert(col, bytes); // store id in a PK index [0 array] - var pk = this.Database.Indexer.AddNode(col.PK, id); + var pk = this.Database.Indexer.AddNode(col.PK, doc.Id); // do links between index <-> data block pk.DataBlock = dataBlock.Position; dataBlock.IndexRef[0] = pk.Position; // for each index, insert new IndexNode - for (byte i = 1; i < col.Indexes.Length; i++) + foreach(var index in col.GetIndexes(false)) { - var index = col.Indexes[i]; + var key = doc.GetFieldValue(index.Field); - if (!index.IsEmpty) - { - var key = BsonSerializer.GetFieldValue(doc, index.Field); + var node = this.Database.Indexer.AddNode(index, key); - var node = this.Database.Indexer.AddNode(index, key); + // point my index to data object + node.DataBlock = dataBlock.Position; - // point my index to data object - node.DataBlock = dataBlock.Position; - - // point my dataBlock - dataBlock.IndexRef[i] = node.Position; - } + // point my dataBlock + dataBlock.IndexRef[index.Slot] = node.Position; } this.Database.Transaction.Commit(); diff --git a/LiteDB/Database/Collections/LiteCollection.Update.cs b/LiteDB/Database/Collections/LiteCollection.Update.cs index b99b736f4..1dadd15f6 100644 --- a/LiteDB/Database/Collections/LiteCollection.Update.cs +++ b/LiteDB/Database/Collections/LiteCollection.Update.cs @@ -11,14 +11,14 @@ public partial class LiteCollection /// /// Update a document in this collection. Returns false if not found document in collection /// - public virtual bool Update(T doc) + public virtual bool Update(T document) { - if (doc == null) throw new ArgumentNullException("doc"); + if (document == null) throw new ArgumentNullException("document"); - // gets document Id - var id = BsonSerializer.GetIdValue(doc); + // get BsonDocument from object + var doc = this.Database.Mapper.ToDocument(document); - if (id == null) throw new LiteException("Document Id can't be null"); + if (doc.Id == null) throw new LiteException("Document Id can't be null"); // serialize object var bytes = BsonSerializer.Serialize(doc); @@ -38,7 +38,7 @@ public virtual bool Update(T doc) } // find indexNode from pk index - var indexNode = this.Database.Indexer.FindOne(col.PK, id); + var indexNode = this.Database.Indexer.FindOne(col.PK, doc.Id); // if not found document, no updates if (indexNode == null) @@ -51,33 +51,28 @@ public virtual bool Update(T doc) var dataBlock = this.Database.Data.Update(col, indexNode.DataBlock, bytes); // delete/insert indexes - do not touch on PK - for (byte i = 1; i < col.Indexes.Length; i++) + foreach (var index in col.GetIndexes(false)) { - var index = col.Indexes[i]; + var key = doc.GetFieldValue(index.Field); - if (!index.IsEmpty) - { - var key = BsonSerializer.GetFieldValue(doc, index.Field); - - var node = this.Database.Indexer.GetNode(dataBlock.IndexRef[i]); + var node = this.Database.Indexer.GetNode(dataBlock.IndexRef[index.Slot]); - // check if my index node was changed - if (node.Key.CompareTo(new IndexKey(key)) != 0) - { - // remove old index node - this.Database.Indexer.Delete(index, node.Position); + // check if my index node was changed + if (node.Key.CompareTo(new IndexKey(key)) != 0) + { + // remove old index node + this.Database.Indexer.Delete(index, node.Position); - // and add a new one - var newNode = this.Database.Indexer.AddNode(index, key); + // and add a new one + var newNode = this.Database.Indexer.AddNode(index, key); - // point my index to data object - newNode.DataBlock = dataBlock.Position; + // point my index to data object + newNode.DataBlock = dataBlock.Position; - // point my dataBlock - dataBlock.IndexRef[i] = newNode.Position; + // point my dataBlock + dataBlock.IndexRef[index.Slot] = newNode.Position; - dataBlock.Page.IsDirty = true; - } + dataBlock.Page.IsDirty = true; } } diff --git a/LiteDB/Database/FileStorage/LiteFileInfo.cs b/LiteDB/Database/FileStorage/LiteFileInfo.cs index d9210a9ab..9e42b834d 100644 --- a/LiteDB/Database/FileStorage/LiteFileInfo.cs +++ b/LiteDB/Database/FileStorage/LiteFileInfo.cs @@ -56,7 +56,7 @@ internal LiteFileInfo(LiteDatabase db, BsonDocument doc) this.Id = doc.Id.ToString(); this.Filename = doc["filename"].AsString; this.MimeType = doc["mimeType"].AsString; - this.Length = doc["length"].AsLong; + this.Length = doc["length"].AsInt64; this.UploadDate = doc["uploadDate"].AsDateTime; this.Metadata = doc["metadata"].AsObject; } diff --git a/LiteDB/Database/FileStorage/LiteFileStream.cs b/LiteDB/Database/FileStorage/LiteFileStream.cs index 79945c4b5..bc9508131 100644 --- a/LiteDB/Database/FileStorage/LiteFileStream.cs +++ b/LiteDB/Database/FileStorage/LiteFileStream.cs @@ -92,7 +92,7 @@ private byte[] GetChunkData(int index) var chunk = chunks.FindById(LiteFileInfo.GetChunckId(_file.Id, index)); // if chunk is null there is no more chunks - return chunk == null ? null : chunk["data"].AsByteArray; + return chunk == null ? null : chunk["data"].AsBinary; } #region Not supported operations diff --git a/LiteDB/Database/LiteDatabase.cs b/LiteDB/Database/LiteDatabase.cs index 1858cbb4f..310382158 100644 --- a/LiteDB/Database/LiteDatabase.cs +++ b/LiteDB/Database/LiteDatabase.cs @@ -33,12 +33,16 @@ public partial class LiteDatabase : IDisposable internal CollectionService Collections { get; private set; } + public BsonMapper Mapper { get; private set; } + /// /// Starts LiteDB database. Open database file or create a new one if not exits /// /// Full filename or connection string public LiteDatabase(string connectionString) { + this.Mapper = new BsonMapper(); + this.ConnectionString = new ConnectionString(connectionString); if (!File.Exists(this.ConnectionString.Filename)) diff --git a/LiteDB/Document/BsonArray.cs b/LiteDB/Document/BsonArray.cs index a430bca18..aea6a1868 100644 --- a/LiteDB/Document/BsonArray.cs +++ b/LiteDB/Document/BsonArray.cs @@ -11,18 +11,25 @@ namespace LiteDB public class BsonArray : BsonValue, IEnumerable { public BsonArray() - : base(new List()) + : base(new List()) { } - internal BsonArray(List array) + public BsonArray(int capacity) + : base(new List(capacity)) + { + } + + public BsonArray(List array) : base(array) { } public void Add(BsonValue value) { - this.RawValue.Add(value == null ? null : value.RawValue); + if (value == null) value = BsonValue.Null; + + this.RawValue.Add(value); } public void Remove(int index) @@ -30,7 +37,7 @@ public void Remove(int index) this.RawValue.RemoveAt(index); } - public int Length + public int Count { get { @@ -38,11 +45,11 @@ public int Length } } - public new List RawValue + public new List RawValue { get { - return (List)base.RawValue; + return (List)base.RawValue; } } diff --git a/LiteDB/Document/BsonDocument.cs b/LiteDB/Document/BsonDocument.cs index 4dbad856a..9409374d2 100644 --- a/LiteDB/Document/BsonDocument.cs +++ b/LiteDB/Document/BsonDocument.cs @@ -20,8 +20,8 @@ public BsonDocument() { } - public BsonDocument(BsonValue value) - : base(value.AsObject.RawValue) + public BsonDocument(BsonObject value) + : base(value.RawValue) { if (!this.HasKey("_id")) throw new ArgumentException("BsonDocument must have an _id key"); } @@ -32,9 +32,39 @@ public object Id set { this["_id"] = new BsonValue(value); } } - internal BsonDocument(Dictionary obj) + public BsonDocument(Dictionary obj) : base(obj) { } + + /// + /// Get value from a field - supports dotted name: Customer.Address.Street + /// + public object GetFieldValue(string fieldName) + { + // supports parent.child.name + var names = fieldName.Split('.'); + + if (names.Length == 1) + { + return this[fieldName].RawValue; + } + + var value = this.AsObject; + + foreach (var name in names) + { + if (value[name].IsObject) + { + value = value[name].AsObject; + } + else + { + return null; + } + } + + return value.RawValue; + } } } diff --git a/LiteDB/Document/BsonObject.cs b/LiteDB/Document/BsonObject.cs index 87f8c5efe..525465515 100644 --- a/LiteDB/Document/BsonObject.cs +++ b/LiteDB/Document/BsonObject.cs @@ -11,29 +11,34 @@ namespace LiteDB public class BsonObject : BsonValue { public BsonObject() - : base(new Dictionary()) + : base(new Dictionary()) { } - internal BsonObject(Dictionary obj) + public BsonObject(int capacity) + : base(new Dictionary(capacity)) + { + } + + public BsonObject(Dictionary obj) : base(obj) { } - public new Dictionary RawValue + public new Dictionary RawValue { get { - return (Dictionary)base.RawValue; + return (Dictionary)base.RawValue; } } /// /// Add fields in fluent api /// - public BsonObject Add(string key, object value) + public BsonObject Add(string key, BsonValue value) { - this[key] = new BsonValue(value); + this[key] = value; return this; } diff --git a/LiteDB/Document/BsonType.cs b/LiteDB/Document/BsonType.cs index ff61706e6..0f07bcc86 100644 --- a/LiteDB/Document/BsonType.cs +++ b/LiteDB/Document/BsonType.cs @@ -11,27 +11,15 @@ namespace LiteDB public enum BsonType { Null, - Array, Object, - Byte, - ByteArray, - Char, + Binary, Boolean, String, - - Short, - Int, - Long, - UShort, - UInt, - ULong, - - Float, + Int32, + Int64, Double, - Decimal, - DateTime, Guid } diff --git a/LiteDB/Document/BsonValue.cs b/LiteDB/Document/BsonValue.cs index 049b451a0..3ba3db424 100644 --- a/LiteDB/Document/BsonValue.cs +++ b/LiteDB/Document/BsonValue.cs @@ -25,33 +25,21 @@ public BsonValue() this.Type = BsonType.Null; } - public BsonValue(List value) + public BsonValue(List value) { this.Type = BsonType.Array; this.RawValue = value; } - public BsonValue(Dictionary value) + public BsonValue(Dictionary value) { this.Type = BsonType.Object; this.RawValue = value; } - public BsonValue(byte value) - { - this.Type = BsonType.Byte; - this.RawValue = value; - } - public BsonValue(byte[] value) { - this.Type = BsonType.ByteArray; - this.RawValue = value; - } - - public BsonValue(char value) - { - this.Type = BsonType.Char; + this.Type = BsonType.Binary; this.RawValue = value; } @@ -67,45 +55,15 @@ public BsonValue(string value) this.RawValue = value; } - public BsonValue(short value) - { - this.Type = BsonType.Short; - this.RawValue = value; - } - public BsonValue(int value) { - this.Type = BsonType.Int; + this.Type = BsonType.Int32; this.RawValue = value; } public BsonValue(long value) { - this.Type = BsonType.Long; - this.RawValue = value; - } - - public BsonValue(ushort value) - { - this.Type = BsonType.UShort; - this.RawValue = value; - } - - public BsonValue(uint value) - { - this.Type = BsonType.UInt; - this.RawValue = value; - } - - public BsonValue(ulong value) - { - this.Type = BsonType.ULong; - this.RawValue = value; - } - - public BsonValue(float value) - { - this.Type = BsonType.Float; + this.Type = BsonType.Int64; this.RawValue = value; } @@ -115,12 +73,6 @@ public BsonValue(double value) this.RawValue = value; } - public BsonValue(decimal value) - { - this.Type = BsonType.Decimal; - this.RawValue = value; - } - public BsonValue(DateTime value) { this.Type = BsonType.DateTime; @@ -146,26 +98,19 @@ public BsonValue(object value) if (value == null) this.Type = BsonType.Null; else if (value is List) this.Type = BsonType.Array; else if (value is Dictionary) this.Type = BsonType.Object; - else if (value is byte) this.Type = BsonType.Byte; - else if (value is byte[]) this.Type = BsonType.ByteArray; - else if (value is char) this.Type = BsonType.Char; + else if (value is byte[]) this.Type = BsonType.Binary; else if (value is bool) this.Type = BsonType.Boolean; else if (value is string) this.Type = BsonType.String; - else if (value is short) this.Type = BsonType.Short; - else if (value is int) this.Type = BsonType.Int; - else if (value is long) this.Type = BsonType.Long; - else if (value is ushort) this.Type = BsonType.UShort; - else if (value is uint) this.Type = BsonType.UInt; - else if (value is ulong) this.Type = BsonType.ULong; - else if (value is float) this.Type = BsonType.Float; + else if (value is int) this.Type = BsonType.Int32; + else if (value is long) this.Type = BsonType.Int64; else if (value is double) this.Type = BsonType.Double; - else if (value is decimal) this.Type = BsonType.Decimal; else if (value is DateTime) this.Type = BsonType.DateTime; else if (value is Guid) this.Type = BsonType.Guid; else if (value is BsonValue) { - this.Type = ((BsonValue)value).Type; - this.RawValue = ((BsonValue)value).RawValue; + var v = (BsonValue)value; + this.Type = v.Type; + this.RawValue = v.RawValue; } else throw new InvalidCastException("Value is not a valid data type"); } @@ -178,11 +123,11 @@ public BsonValue this[string name] { get { - return new BsonValue(this.AsObject.RawValue.Get(name)); + return this.AsObject.RawValue.Get(name); } set { - this.AsObject.RawValue[name] = (value == null ? null : value.RawValue); + this.AsObject.RawValue[name] = value == null ? BsonValue.Null : value; } } @@ -190,11 +135,11 @@ public BsonValue this[int index] { get { - return new BsonValue(this.AsArray.RawValue.ElementAt(index)); + return this.AsArray.RawValue.ElementAt(index); } set { - this.AsArray.RawValue[index] = (value == null ? null : value.RawValue); + this.AsArray.RawValue[index] = value == null ? BsonValue.Null : value; } } @@ -207,7 +152,7 @@ public BsonArray AsArray get { if (!this.IsArray) throw new LiteException("Value is not an array"); - return new BsonArray((List)this.RawValue); + return new BsonArray((List)this.RawValue); } } @@ -216,7 +161,7 @@ public BsonObject AsObject get { if (!this.IsObject) throw new LiteException("Value is not an object"); - return new BsonObject((Dictionary)this.RawValue); + return new BsonObject((Dictionary)this.RawValue); } } @@ -225,94 +170,46 @@ public BsonDocument AsDocument get { if (!this.IsObject) throw new LiteException("Value is not an document"); - return new BsonDocument(this); + return new BsonDocument(this.AsObject); } } - public byte AsByte - { - get { return this.Type == BsonType.Byte ? (byte)this.RawValue : default(byte); } - set { this.Type = BsonType.Byte; this.RawValue = value; } - } - - public byte[] AsByteArray - { - get { return this.Type == BsonType.ByteArray ? (byte[])this.RawValue : default(byte[]); } - set { this.Type = BsonType.ByteArray; this.RawValue = value; } - } - - public char AsChar + public Byte[] AsBinary { - get { return this.Type == BsonType.Char ? (char)this.RawValue : default(char); } - set { this.Type = BsonType.Char; this.RawValue = value; } + get { return this.Type == BsonType.Binary ? (Byte[])this.RawValue : default(Byte[]); } + set { this.Type = BsonType.Binary; this.RawValue = value; } } public bool AsBoolean { - get { return this.Type == BsonType.Boolean ? (bool)this.RawValue : default(bool); } + get { return this.Type == BsonType.Boolean ? (Boolean)this.RawValue : default(Boolean); } set { this.Type = BsonType.Boolean; this.RawValue = value; } } public string AsString { - get { return this.Type != BsonType.Null ? this.RawValue.ToString() : default(string); } + get { return this.Type != BsonType.Null ? (String)this.RawValue : default(String); } set { this.Type = value == null ? BsonType.Null : BsonType.String; this.RawValue = value; } } - public short AsShort - { - get { return this.IsNumber ? Convert.ToInt16(this.RawValue) : default(short); } - set { this.Type = BsonType.Short; this.RawValue = value; } - } - - public int AsInt - { - get { return this.IsNumber ? Convert.ToInt32(this.RawValue) : default(int); } - set { this.Type = BsonType.Int; this.RawValue = value; } - } - - public long AsLong - { - get { return this.IsNumber ? Convert.ToInt64(this.RawValue) : default(long); } - set { this.Type = BsonType.Long; this.RawValue = value; } - } - - public ushort AsUShort - { - get { return this.IsNumber ? Convert.ToUInt16(this.RawValue) : default(ushort); } - set { this.Type = BsonType.UShort; this.RawValue = value; } - } - - public uint AsUInt - { - get { return this.IsNumber ? Convert.ToUInt32(this.RawValue) : default(uint); } - set { this.Type = BsonType.UInt; this.RawValue = value; } - } - - public ulong AsULong + public int AsInt32 { - get { return this.IsNumber ? Convert.ToUInt64(this.RawValue) : default(ulong); } - set { this.Type = BsonType.ULong; this.RawValue = value; } + get { return this.IsNumber ? Convert.ToInt32(this.RawValue) : default(Int32); } + set { this.Type = BsonType.Int32; this.RawValue = value; } } - public float AsFloat + public long AsInt64 { - get { return this.IsNumber ? Convert.ToSingle(this.RawValue) : default(float); } - set { this.Type = BsonType.Float; this.RawValue = value; } + get { return this.IsNumber ? Convert.ToInt64(this.RawValue) : default(Int64); } + set { this.Type = BsonType.Int64; this.RawValue = value; } } public double AsDouble { - get { return this.IsNumber ? Convert.ToDouble(this.RawValue) : default(double); } + get { return this.IsNumber ? Convert.ToDouble(this.RawValue) : default(Double); } set { this.Type = BsonType.Double; this.RawValue = value; } } - public decimal AsDecimal - { - get { return this.IsNumber ? Convert.ToDecimal(this.RawValue) : default(decimal); } - set { this.Type = BsonType.Decimal; this.RawValue = value; } - } - public DateTime AsDateTime { get { return this.Type == BsonType.DateTime ? (DateTime)this.RawValue : default(DateTime); } @@ -349,36 +246,29 @@ public bool IsDocument get { return this.Type == BsonType.Object && !this["_id"].IsNull; } } - public bool IsNumber + public bool IsInt32 { - get - { - return - this.Type == BsonType.Short || - this.Type == BsonType.Int || - this.Type == BsonType.Long || - this.Type == BsonType.UShort || - this.Type == BsonType.UInt || - this.Type == BsonType.ULong || - this.Type == BsonType.Float || - this.Type == BsonType.Double || - this.Type == BsonType.Decimal; - } + get { return this.Type == BsonType.Int32; } } - public bool IsByte + public bool IsInt64 { - get { return this.Type == BsonType.Byte; } + get { return this.Type == BsonType.Int64; } } - public bool IsByteArray + public bool IsDouble { - get { return this.Type == BsonType.ByteArray; } + get { return this.Type == BsonType.Double; } } - public bool IsChar + public bool IsNumber + { + get { return this.IsInt32 || this.IsInt64 || this.IsDouble; } + } + + public bool IsBinary { - get { return this.Type == BsonType.Char; } + get { return this.Type == BsonType.Binary; } } public bool IsBoolean @@ -405,142 +295,62 @@ public bool IsDateTime #region Operators - public static implicit operator byte(BsonValue value) - { - return value.AsByte; - } - - public static implicit operator BsonValue(byte value) - { - return new BsonValue(value); - } - - public static implicit operator byte[](BsonValue value) - { - return value.AsByteArray; - } - - public static implicit operator BsonValue(byte[] value) - { - return new BsonValue(value); - } - - public static implicit operator char(BsonValue value) + public static implicit operator Byte[](BsonValue value) { - return value.AsChar; + return value.AsBinary; } - public static implicit operator BsonValue(char value) + public static implicit operator BsonValue(Byte[] value) { return new BsonValue(value); } - public static implicit operator bool(BsonValue value) + public static implicit operator Boolean(BsonValue value) { return value.AsBoolean; } - public static implicit operator BsonValue(bool value) + public static implicit operator BsonValue(Boolean value) { return new BsonValue(value); } - public static implicit operator string(BsonValue value) + public static implicit operator String(BsonValue value) { return value.AsString; } - public static implicit operator BsonValue(string value) - { - return new BsonValue(value); - } - - public static implicit operator short(BsonValue value) - { - return value.AsShort; - } - - public static implicit operator BsonValue(short value) - { - return new BsonValue(value); - } - - public static implicit operator int(BsonValue value) - { - return value.AsInt; - } - - public static implicit operator BsonValue(int value) - { - return new BsonValue(value); - } - - public static implicit operator long(BsonValue value) - { - return value.AsLong; - } - - public static implicit operator BsonValue(long value) - { - return new BsonValue(value); - } - - public static implicit operator ushort(BsonValue value) - { - return value.AsUShort; - } - - public static implicit operator BsonValue(ushort value) - { - return new BsonValue(value); - } - - public static implicit operator uint(BsonValue value) - { - return value.AsUInt; - } - - public static implicit operator BsonValue(uint value) + public static implicit operator BsonValue(String value) { return new BsonValue(value); } - public static implicit operator ulong(BsonValue value) + public static implicit operator Int32(BsonValue value) { - return value.AsULong; + return value.AsInt32; } - public static implicit operator BsonValue(ulong value) + public static implicit operator BsonValue(Int32 value) { return new BsonValue(value); } - public static implicit operator float(BsonValue value) + public static implicit operator Int64(BsonValue value) { - return value.AsFloat; + return value.AsInt64; } - public static implicit operator BsonValue(float value) + public static implicit operator BsonValue(Int64 value) { return new BsonValue(value); } - public static implicit operator double(BsonValue value) + public static implicit operator Double(BsonValue value) { return value.AsDouble; } - public static implicit operator BsonValue(double value) - { - return new BsonValue(value); - } - - public static implicit operator decimal(BsonValue value) - { - return value.AsDecimal; - } - - public static implicit operator BsonValue(decimal value) + public static implicit operator BsonValue(Double value) { return new BsonValue(value); } diff --git a/LiteDB/Serializer/Bson/BsonIdAttribute.cs b/LiteDB/Document/Mapper/BsonIdAttribute.cs similarity index 100% rename from LiteDB/Serializer/Bson/BsonIdAttribute.cs rename to LiteDB/Document/Mapper/BsonIdAttribute.cs diff --git a/LiteDB/Serializer/Bson/BsonIgnoreAttribute.cs b/LiteDB/Document/Mapper/BsonIgnoreAttribute.cs similarity index 100% rename from LiteDB/Serializer/Bson/BsonIgnoreAttribute.cs rename to LiteDB/Document/Mapper/BsonIgnoreAttribute.cs diff --git a/LiteDB/Document/Mapper/BsonMapper.cs b/LiteDB/Document/Mapper/BsonMapper.cs new file mode 100644 index 000000000..5e47332f7 --- /dev/null +++ b/LiteDB/Document/Mapper/BsonMapper.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Text; + +namespace LiteDB +{ + /// + /// Class that converts POCO class to/from BsonDocument + /// + public class BsonMapper + { + public T ToObject(BsonDocument doc) + where T : new() + { + var type = typeof(T); + + // if T is BsonDocument, just return them + if (type == typeof(BsonDocument)) return (T)(object)doc; + + + return default(T); + } + + public BsonDocument ToDocument(object obj) + { + // if object is BsonDocument, just return them + if (obj is BsonDocument) return (BsonDocument)obj; + + + return null; + } + } +} diff --git a/LiteDB/LiteDB.csproj b/LiteDB/LiteDB.csproj index 77d48a934..b39c72dcf 100644 --- a/LiteDB/LiteDB.csproj +++ b/LiteDB/LiteDB.csproj @@ -62,14 +62,8 @@ - - - - - - - - + + @@ -90,9 +84,12 @@ + + + @@ -153,9 +150,6 @@ - - -