From: adam Date: Thu, 20 Jun 2013 10:37:57 +0000 (+0700) Subject: #24 X-Git-Tag: v1.2.12~276^2~21^2~2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=87ac7052452177a2cb71823671b44db89ea890e9;p=platform%2Fupstream%2Fejdb.git #24 --- diff --git a/nejdb/Ejdb.DB/EJDB.cs b/nejdb/Ejdb.DB/EJDB.cs index 94cbf50..5bacc00 100644 --- a/nejdb/Ejdb.DB/EJDB.cs +++ b/nejdb/Ejdb.DB/EJDB.cs @@ -36,28 +36,107 @@ namespace Ejdb.DB { public int cachedrecords; } + /// + /// EJDB database native wrapper. + /// public class EJDB : IDisposable { - //Open modes + //.////////////////////////////////////////////////////////////////// + // Native open modes + //.////////////////////////////////////////////////////////////////// + /// + /// Open as a reader. + /// public const int JBOREADER = 1 << 0; + /// + /// Open as a writer. + /// public const int JBOWRITER = 1 << 1; + /// + /// Create if db file not exists. + /// public const int JBOCREAT = 1 << 2; + /// + /// Truncate db on open. + /// public const int JBOTRUNC = 1 << 3; + /// + /// Open without locking. + /// public const int JBONOLCK = 1 << 4; + /// + /// Lock without blocking. + /// public const int JBOLCKNB = 1 << 5; + /// + /// Synchronize every transaction with storage. + /// public const int JBOTSYNC = 1 << 6; + /// + /// The default open mode (JBOWRITER | JBOCREAT) + /// public const int DEFAULT_OPEN_MODE = (JBOWRITER | JBOCREAT); + //.////////////////////////////////////////////////////////////////// + // Native index operations & types (ejdb.h) + //.////////////////////////////////////////////////////////////////// + /// + /// Drop index. + /// + const int JBIDXDROP = 1 << 0; + + /// + /// Drop index for all types. + /// + const int JBIDXDROPALL = 1 << 1; + + /// + /// Optimize indexes. + /// + const int JBIDXOP = 1 << 2; + + /// + /// Rebuild index. + /// + const int JBIDXREBLD = 1 << 3; + /// + /// Number index. + /// + const int JBIDXNUM = 1 << 4; + + /// + /// String index. + /// + const int JBIDXSTR = 1 << 5; + + /// + /// Array token index. + /// + const int JBIDXARR = 1 << 6; + + /// + /// Case insensitive string index. + /// + const int JBIDXISTR = 1 << 7; + + /// + /// Name if EJDB library + /// public const string EJDB_LIB_NAME = "tcejdb"; + /// + /// Pointer to the native EJDB instance. + /// IntPtr _db = IntPtr.Zero; - // + //.////////////////////////////////////////////////////////////////// + // Native functions refs + //.////////////////////////////////////////////////////////////////// #region NativeRefs [DllImport(EJDB_LIB_NAME, EntryPoint="ejdbnew")] internal static extern IntPtr _ejdbnew(); @@ -112,6 +191,18 @@ namespace Ejdb.DB { UnixMarshal.FreeHeap(cptr); } } + //EJDB_EXPORT bool ejdbrmcoll(EJDB *jb, const char *colname, bool unlinkfile); + [DllImport(EJDB_LIB_NAME, EntryPoint="ejdbrmcoll")] + internal static extern bool _ejdbrmcoll([In] IntPtr db, [In] IntPtr cname, bool unlink); + + internal static bool _ejdbrmcoll(IntPtr db, string cname, bool unlink) { + IntPtr cptr = UnixMarshal.StringToHeap(cname, Encoding.UTF8); + try { + return _ejdbrmcoll(db, cptr, unlink); + } finally { + UnixMarshal.FreeHeap(cptr); + } + } //EJDB_EXPORT bool ejdbsavebson3(EJCOLL *jcoll, void *bsdata, bson_oid_t *oid, bool merge); [DllImport(EJDB_LIB_NAME, EntryPoint="ejdbsavebson3")] internal static extern bool _ejdbsavebson([In] IntPtr coll, [In] byte[] bsdata, [Out] byte[] oid, [In] bool merge); @@ -124,6 +215,30 @@ namespace Ejdb.DB { //EJDB_EXPORT void bson_del(bson *b); [DllImport(EJDB_LIB_NAME, EntryPoint="bson_del")] internal static extern void _bson_del([In] IntPtr bsptr); + //EJDB_EXPORT bool ejdbrmbson(EJCOLL *coll, bson_oid_t *oid); + [DllImport(EJDB_LIB_NAME, EntryPoint="ejdbrmbson")] + internal static extern bool _ejdbrmbson([In] IntPtr cptr, [In] byte[] oid); + //EJDB_EXPORT bool ejdbsyncdb(EJDB *jb) + [DllImport(EJDB_LIB_NAME, EntryPoint="ejdbsyncdb")] + internal static extern bool _ejdbsyncdb([In] IntPtr db); + //EJDB_EXPORT bool ejdbsyncoll(EJDB *jb) + [DllImport(EJDB_LIB_NAME, EntryPoint="ejdbsyncoll")] + internal static extern bool _ejdbsyncoll([In] IntPtr coll); + //EJDB_EXPORT bool ejdbsetindex(EJCOLL *coll, const char *ipath, int flags); + [DllImport(EJDB_LIB_NAME, EntryPoint="ejdbsetindex")] + internal static extern bool _ejdbsetindex([In] IntPtr coll, [In] IntPtr ipathptr, int flags); + //EJDB_EXPORT bson* ejdbmeta(EJDB *jb) + [DllImport(EJDB_LIB_NAME, EntryPoint="ejdbmeta")] + internal static extern IntPtr _ejdbmeta([In] IntPtr db); + + internal static bool _ejdbsetindex(IntPtr coll, string ipath, int flags) { + IntPtr ipathptr = UnixMarshal.StringToHeap(ipath, Encoding.UTF8); + try { + return _ejdbsetindex(coll, ipathptr, flags); + } finally { + UnixMarshal.FreeHeap(ipathptr); + } + } #endregion /// /// Gets the last DB error code or null if underlying native database object does not exist. @@ -159,6 +274,22 @@ namespace Ejdb.DB { } /// + /// Gets description of EJDB database and its collections. + /// + /// The DB meta. + public BSONDocument DBMeta { + get { + CheckDisposed(true); + //internal static extern IntPtr ejdbmeta([In] IntPtr db); + //IntPtr bsptr = + + + BSONDocument meta = new BSONDocument(); + return meta; + } + } + + /// /// Initializes a new instance of the class. /// /// The main database file path. @@ -211,6 +342,186 @@ namespace Ejdb.DB { } /// + /// Removes collection indetified by cname. + /// + /// false, if error occurred. + /// Name of the collection. + /// If set to true then the collection data file will be removed. + public bool DropCollection(string cname, bool unlink = false) { + CheckDisposed(); + return _ejdbrmcoll(_db, cname, unlink); + } + + /// + /// Synchronize entire EJDB database and + /// all of its collections with storage. + /// + /// false, if error occurred. + public bool Sync() { + CheckDisposed(); + //internal static extern bool _ejdbsyncdb([In] IntPtr db); + return _ejdbsyncdb(_db); + } + + /// + /// Synchronize content of a EJDB collection database with the file on device. + /// + /// false, if error occurred. + /// Name of collection. + public bool SyncCollection(string cname) { + CheckDisposed(); + IntPtr cptr = _ejdbgetcoll(_db, cname); + if (cptr == IntPtr.Zero) { + return true; + } + //internal static extern bool _ejdbsyncoll([In] IntPtr coll); + return _ejdbsyncoll(cptr); + } + + /// + /// DROP indexes of all types for JSON field path. + /// + /// false, if error occurred. + /// Name of collection. + /// JSON indexed field path + public bool DropIndexes(string cname, string ipath) { + return IndexOperation(cname, ipath, JBIDXDROPALL); + } + + /// + /// OPTIMIZE indexes of all types for JSON field path. + /// + /// + /// Performs B+ tree index file optimization. + /// + /// false, if error occurred. + /// Name of collection. + /// JSON indexed field path + public bool OptimizeIndexes(string cname, string ipath) { + return IndexOperation(cname, ipath, JBIDXOP); + } + + /// + /// Ensure index presence of String type for JSON field path. + /// + /// false, if error occurred. + /// Name of collection. + /// JSON indexed field path + public bool EnsureStringIndex(string cname, string ipath) { + return IndexOperation(cname, ipath, JBIDXSTR); + } + + /// + /// Rebuild index of String type for JSON field path. + /// + /// false, if error occurred. + /// Name of collection. + /// JSON indexed field path + public bool RebuildStringIndex(string cname, string ipath) { + return IndexOperation(cname, ipath, JBIDXSTR | JBIDXREBLD); + } + + /// + /// Drop index of String type for JSON field path. + /// + /// false, if error occurred. + /// Name of collection. + /// JSON indexed field path + public bool DropStringIndex(string cname, string ipath) { + return IndexOperation(cname, ipath, JBIDXSTR | JBIDXDROP); + } + + /// + /// Ensure case insensitive String index for JSON field path. + /// + /// false, if error occurred. + /// Name of collection. + /// JSON indexed field path + public bool EnsureIStringIndex(string cname, string ipath) { + return IndexOperation(cname, ipath, JBIDXISTR); + } + + /// + /// Rebuild case insensitive String index for JSON field path. + /// + /// false, if error occurred. + /// Name of collection. + /// JSON indexed field path + public bool RebuildIStringIndex(string cname, string ipath) { + return IndexOperation(cname, ipath, JBIDXISTR | JBIDXREBLD); + } + + /// + /// Drop case insensitive String index for JSON field path. + /// + /// false, if error occurred. + /// Name of collection. + /// JSON indexed field path + public bool DropIStringIndex(string cname, string ipath) { + return IndexOperation(cname, ipath, JBIDXISTR | JBIDXDROP); + } + + /// + /// Ensure index presence of Number type for JSON field path. + /// + /// false, if error occurred. + /// Name of collection. + /// JSON indexed field path + public bool EnsureNumberIndex(string cname, string ipath) { + return IndexOperation(cname, ipath, JBIDXNUM); + } + + /// + /// Rebuild index of Number type for JSON field path. + /// + /// false, if error occurred. + /// Name of collection. + /// JSON indexed field path + public bool RebuildNumberIndex(string cname, string ipath) { + return IndexOperation(cname, ipath, JBIDXNUM | JBIDXREBLD); + } + + /// + /// Drop index of Number type for JSON field path. + /// + /// false, if error occurred. + /// Name of collection. + /// JSON indexed field path + public bool DropNumberIndex(string cname, string ipath) { + return IndexOperation(cname, ipath, JBIDXNUM | JBIDXDROP); + } + + /// + /// Ensure index presence of Array type for JSON field path. + /// + /// false, if error occurred. + /// Name of collection. + /// JSON indexed field path + public bool EnsureArrayIndex(string cname, string ipath) { + return IndexOperation(cname, ipath, JBIDXARR); + } + + /// + /// Rebuild index of Array type for JSON field path. + /// + /// false, if error occurred. + /// Name of collection. + /// JSON indexed field path + public bool RebuildArrayIndex(string cname, string ipath) { + return IndexOperation(cname, ipath, JBIDXARR | JBIDXREBLD); + } + + /// + /// Drop index of Array type for JSON field path. + /// + /// false, if error occurred. + /// Name of collection. + /// JSON indexed field path + public bool DropArrayIndex(string cname, string ipath) { + return IndexOperation(cname, ipath, JBIDXARR | JBIDXDROP); + } + + /// /// Save the BSON document doc into the collection. /// /// Name of collection. @@ -287,6 +598,26 @@ namespace Ejdb.DB { } /// + /// Removes stored objects from the collection. + /// + /// Name of collection. + /// Object identifiers. + public bool Remove(string cname, params BSONOid[] oids) { + CheckDisposed(); + IntPtr cptr = _ejdbgetcoll(_db, cname); + if (cptr == IntPtr.Zero) { + return true; + } + //internal static extern bool _ejdbrmbson([In] IntPtr cptr, [In] byte[] oid); + foreach (var oid in oids) { + if (!_ejdbrmbson(cptr, oid.ToBytes())) { + return false; + } + } + return true; + } + + /// /// Creates the query. /// /// The query object. @@ -325,10 +656,25 @@ namespace Ejdb.DB { return bsdata; } - internal void CheckDisposed() { + bool IndexOperation(string cname, string ipath, int flags) { + CheckDisposed(true); + IntPtr cptr = _ejdbgetcoll(_db, cname); + if (cptr == IntPtr.Zero) { + return true; + } + //internal static bool _ejdbsetindex(IntPtr coll, string ipath, int flags) + return _ejdbsetindex(cptr, ipath, flags); + } + + internal void CheckDisposed(bool checkopen = false) { if (_db == IntPtr.Zero) { throw new ObjectDisposedException("Database is disposed"); } + if (checkopen) { + if (!IsOpen) { + throw new ObjectDisposedException("Operation on closed EJDB instance"); + } + } } } } diff --git a/nejdb/Ejdb.DB/EJDBQuery.cs b/nejdb/Ejdb.DB/EJDBQuery.cs index 16415bb..6a948f8 100644 --- a/nejdb/Ejdb.DB/EJDBQuery.cs +++ b/nejdb/Ejdb.DB/EJDBQuery.cs @@ -124,8 +124,9 @@ namespace Ejdb.DB { /// /// This query object. /// Query document. - public EJDBQuery AppendOR(BSONDocument doc) { + public EJDBQuery AddOR(object docobj) { CheckDisposed(); + BSONDocument doc = BSONDocument.ValueOf(docobj); //static extern IntPtr _ejdbqueryaddor([In] IntPtr jb, [In] IntPtr qptr, [In] byte[] bsdata); IntPtr qptr = _ejdbqueryaddor(_jb.DBPtr, _qptr, doc.ToByteArray()); if (qptr == IntPtr.Zero) { diff --git a/nejdb/Ejdb.JSON/JSONElement.cs b/nejdb/Ejdb.JSON/JSONElement.cs deleted file mode 100644 index 39cfad3..0000000 --- a/nejdb/Ejdb.JSON/JSONElement.cs +++ /dev/null @@ -1,25 +0,0 @@ -// ============================================================================================ -// .NET API for EJDB database library http://ejdb.org -// Copyright (C) 2012-2013 Softmotions Ltd -// -// This file is part of EJDB. -// EJDB is free software; you can redistribute it and/or modify it under the terms of -// the GNU Lesser General Public License as published by the Free Software Foundation; either -// version 2.1 of the License or any later version. EJDB is distributed in the hope -// that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public -// License for more details. -// You should have received a copy of the GNU Lesser General Public License along with EJDB; -// if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, -// Boston, MA 02111-1307 USA. -// ============================================================================================ -using System; - -namespace Ejdb.JSON { - - public class JSONElement { - public JSONElement() { - } - } -} - diff --git a/nejdb/Ejdb.JSON/JSONReader.cs b/nejdb/Ejdb.JSON/JSONReader.cs deleted file mode 100644 index ac8f116..0000000 --- a/nejdb/Ejdb.JSON/JSONReader.cs +++ /dev/null @@ -1,49 +0,0 @@ -// ============================================================================================ -// .NET API for EJDB database library http://ejdb.org -// Copyright (C) 2012-2013 Softmotions Ltd -// -// This file is part of EJDB. -// EJDB is free software; you can redistribute it and/or modify it under the terms of -// the GNU Lesser General Public License as published by the Free Software Foundation; either -// version 2.1 of the License or any later version. EJDB is distributed in the hope -// that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public -// License for more details. -// You should have received a copy of the GNU Lesser General Public License along with EJDB; -// if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, -// Boston, MA 02111-1307 USA. -// ============================================================================================ -using System; -using System.IO; -using System.Collections.Generic; - -namespace Ejdb.JSON { - - public class JSONReader : IEnumerable, IDisposable { - - BinaryReader _input; - - public JSONReader(Stream jstream) { - this._input = new BinaryReader(jstream); - } - - public IEnumerator GetEnumerator() { - - - - yield return new JSONElement(); - } - - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { - return GetEnumerator(); - } - - public void Dispose() { - if (_input != null) { - _input.Close(); - _input = null; - } - } - } -} - diff --git a/nejdb/Ejdb.Tests/TestEJDB.cs b/nejdb/Ejdb.Tests/TestEJDB.cs index 0b11d37..192302a 100644 --- a/nejdb/Ejdb.Tests/TestEJDB.cs +++ b/nejdb/Ejdb.Tests/TestEJDB.cs @@ -64,6 +64,17 @@ namespace Ejdb.Tests { BSONDocument doc2 = it.ToBSONDocument(); Assert.AreEqual(doc.ToDebugDataString(), doc2.ToDebugDataString()); Assert.IsTrue(doc == doc2); + + Assert.AreEqual(1, jb.CreateQueryFor("mycoll").Count()); + Assert.IsTrue(jb.Remove("mycoll", doc["_id"] as BSONOid)); + Assert.AreEqual(0, jb.CreateQueryFor("mycoll").Count()); + + jb.Save("mycoll", doc); + Assert.AreEqual(1, jb.CreateQueryFor("mycoll").Count()); + Assert.IsTrue(jb.DropCollection("mycoll")); + Assert.AreEqual(0, jb.CreateQueryFor("mycoll").Count()); + + Assert.IsTrue(jb.Sync()); jb.Dispose(); } @@ -149,6 +160,18 @@ namespace Ejdb.Tests { Assert.AreEqual("Grenny", doc["name"]); Assert.AreEqual(1, doc["age"]); } + q.Dispose(); + + q = jb.CreateQueryFor("parrots"); + Assert.AreEqual(2, q.Count()); + q.AddOR(new{ + name = "Grenny" + }); + Assert.AreEqual(1, q.Count()); + q.AddOR(new{ + name = "Bounty" + }); + Assert.AreEqual(2, q.Count()); q.Dispose(); jb.Dispose(); diff --git a/nejdb/nejdb.csproj b/nejdb/nejdb.csproj index 715da57..0b3b68b 100644 --- a/nejdb/nejdb.csproj +++ b/nejdb/nejdb.csproj @@ -37,7 +37,6 @@ False - @@ -60,8 +59,6 @@ - - @@ -77,7 +74,6 @@ - diff --git a/nejdb/nejdb.userprefs b/nejdb/nejdb.userprefs index 9f80e0d..36c0d1a 100644 --- a/nejdb/nejdb.userprefs +++ b/nejdb/nejdb.userprefs @@ -1,14 +1,16 @@  - + - - - - - - - + + + + + + + + + @@ -19,10 +21,7 @@ - - - - + @@ -39,11 +38,12 @@ - + - + + diff --git a/node/ejdb_native.cc b/node/ejdb_native.cc index 58297ba..fd9b58a 100644 --- a/node/ejdb_native.cc +++ b/node/ejdb_native.cc @@ -837,65 +837,17 @@ namespace ejdb { static Handle s_db_meta(const Arguments& args) { HandleScope scope; NodeEJDB *njb = ObjectWrap::Unwrap< NodeEJDB > (args.This()); - Local ret = Object::New(); if (!ejdbisopen(njb->m_jb)) { return scope.Close(ThrowException(Exception::Error(String::New("Operation on closed EJDB instance")))); } - TCLIST *cols = ejdbgetcolls(njb->m_jb); - if (!cols) { + bson *meta = ejdbmeta(njb->m_jb); + if (!meta) { return scope.Close(ThrowException(Exception::Error(String::New(njb->_jb_error_msg())))); } - Local cinfo = Array::New(); - for (int i = 0; i < TCLISTNUM(cols); ++i) { - EJCOLL *coll = (EJCOLL*) TCLISTVALPTR(cols, i); - assert(coll); - if (!ejcollockmethod(coll, false)) continue; - Local cm = Object::New(); - cm->Set(sym_name, String::New(coll->cname, coll->cnamesz)); - cm->Set(sym_file, String::New(coll->tdb->hdb->path)); - cm->Set(sym_records, Integer::NewFromUnsigned((uint32_t) coll->tdb->hdb->rnum)); - Local opts = Object::New(); - opts->Set(sym_buckets, Integer::NewFromUnsigned((uint32_t) coll->tdb->hdb->bnum)); - opts->Set(sym_cachedrecords, Integer::NewFromUnsigned(coll->tdb->hdb->rcnum)); - opts->Set(sym_large, Boolean::New(coll->tdb->opts & TDBTLARGE)); - opts->Set(sym_compressed, Boolean::New((coll->tdb->opts & TDBTDEFLATE) ? true : false)); - cm->Set(sym_options, opts); - Local indexes = Array::New(); - int ic = 0; - for (int j = 0; j < coll->tdb->inum; ++j) { - TDBIDX *idx = (coll->tdb->idxs + j); - assert(idx); - if (idx->type != TDBITLEXICAL && idx->type != TDBITDECIMAL && idx->type != TDBITTOKEN) { - continue; - } - Local imeta = Object::New(); - imeta->Set(sym_field, String::New(idx->name + 1)); - imeta->Set(sym_iname, String::New(idx->name)); - switch (idx->type) { - case TDBITLEXICAL: - imeta->Set(sym_type, String::New("lexical")); - break; - case TDBITDECIMAL: - imeta->Set(sym_type, String::New("decimal")); - break; - case TDBITTOKEN: - imeta->Set(sym_type, String::New("token")); - break; - } - TCBDB *idb = (TCBDB*) idx->db; - if (idb) { - imeta->Set(sym_records, Integer::NewFromUnsigned((uint32_t) idb->rnum)); - imeta->Set(sym_file, String::New(idb->hdb->path)); - } - indexes->Set(Integer::New(ic++), imeta); - } - cm->Set(sym_indexes, indexes); - cinfo->Set(Integer::New(i), cm); - ejcollunlockmethod(coll); - } - tclistdel(cols); - ret->Set(sym_file, String::New(njb->m_jb->metadb->hdb->path)); - ret->Set(String::New("collections"), cinfo); + bson_iterator it; + bson_iterator_init(&it, meta); + Handle ret = toV8Object(&it); + bson_del(meta); return scope.Close(ret); } diff --git a/tcejdb/ejdb.c b/tcejdb/ejdb.c index b22ec52..c569ef7 100644 --- a/tcejdb/ejdb.c +++ b/tcejdb/ejdb.c @@ -524,7 +524,7 @@ EJQ* ejdbqueryaddor(EJDB *jb, EJQ *q, const void *orbsdata) { if (q->orqobjsnum == 1) { TCMALLOC(q->orqobjs, sizeof (*(q->orqobjs)) * q->orqobjsnum); } else { - TCREALLOC(q->orqobjs, q->orqobjs, q->orqobjsnum); + TCREALLOC(q->orqobjs, q->orqobjs, sizeof (*(q->orqobjs)) * q->orqobjsnum); } q->orqobjs[q->orqobjsnum - 1] = *oq; //copy TCFREE(oq); @@ -868,6 +868,76 @@ bool ejdbtranstatus(EJCOLL *jcoll, bool *txactive) { return true; } +bson* ejdbmeta(EJDB *jb) { + if (!JBISOPEN(jb)) { + _ejdbsetecode(jb, TCEINVALID, __FILE__, __LINE__, __func__); + return NULL; + } + char nbuff[TCNUMBUFSIZ]; + bson *bs = bson_create(); + bson_init(bs); + bson_append_string(bs, "file", jb->metadb->hdb->path); + bson_append_start_array(bs, "collections"); + TCLIST *cols = ejdbgetcolls(jb); + for (int i = 0; i < TCLISTNUM(cols); ++i) { + if (!JBISOPEN(jb)) { + break; + } + EJCOLL *coll = (EJCOLL*) TCLISTVALPTR(cols, i); + if (!coll || !_ejcollockmethod(coll, false)) continue; + bson_numstrn(nbuff, TCNUMBUFSIZ, i); + bson_append_start_object(bs, nbuff); //coll obj + bson_append_string_n(bs, "name", coll->cname, coll->cnamesz); + bson_append_string(bs, "file", coll->tdb->hdb->path); + bson_append_long(bs, "records", coll->tdb->hdb->rnum); + + bson_append_start_object(bs, "options"); //coll.options + bson_append_long(bs, "buckets", coll->tdb->hdb->bnum); + bson_append_long(bs, "cachedrecords", coll->tdb->hdb->rcnum); + bson_append_bool(bs, "large", (coll->tdb->opts & TDBTLARGE)); + bson_append_bool(bs, "compressed", (coll->tdb->opts & TDBTDEFLATE)); + bson_append_finish_object(bs); //eof coll.options + + bson_append_start_array(bs, "indexes"); //coll.indexes[] + for (int j = 0; j < coll->tdb->inum; ++j) { + TDBIDX *idx = (coll->tdb->idxs + j); + if (idx->type != TDBITLEXICAL && + idx->type != TDBITDECIMAL && + idx->type != TDBITTOKEN) { + continue; + } + bson_numstrn(nbuff, TCNUMBUFSIZ, j); + bson_append_start_object(bs, nbuff); //coll.indexes.index + bson_append_string(bs, "field", idx->name + 1); + bson_append_string(bs, "iname", idx->name); + switch (idx->type) { + case TDBITLEXICAL: + bson_append_string(bs, "type", "lexical"); + break; + case TDBITDECIMAL: + bson_append_string(bs, "type", "decimal"); + break; + case TDBITTOKEN: + bson_append_string(bs, "type", "token"); + break; + } + TCBDB *idb = (TCBDB*) idx->db; + if (idb) { + bson_append_long(bs, "records", idb->rnum); + bson_append_string(bs, "file", idb->hdb->path); + } + bson_append_finish_object(bs); //eof coll.indexes.index + } + bson_append_finish_array(bs); //eof coll.indexes[] + bson_append_finish_object(bs); //eof coll + _ejcollunlockmethod(coll); + } + bson_append_finish_array(bs); //eof collections + bson_finish(bs); + tclistdel(cols); + return bs; +} + /************************************************************************************************* * private features *************************************************************************************************/ @@ -3103,7 +3173,7 @@ static bool _qrypreprocess(EJCOLL *jcoll, EJQ *ejq, int qflags, EJQF **mqf, ejq->skip = (uint32_t) ((v < 0) ? 0 : v); } bt = bson_find(&it, ejq->hints, "$max"); - if (qflags & JBQRYFINDONE) { + if (qflags & JBQRYFINDONE) { ejq->max = (uint32_t) 1; } else if (BSON_IS_NUM_TYPE(bt)) { int64_t v = bson_iterator_long(&it); diff --git a/tcejdb/ejdb.h b/tcejdb/ejdb.h index 85f8f96..69b4fd0 100644 --- a/tcejdb/ejdb.h +++ b/tcejdb/ejdb.h @@ -468,7 +468,7 @@ EJDB_EXPORT bool ejdbsyncoll(EJCOLL *jcoll); /** * Synchronize entire EJDB database and - * all its collections with storage. + * all of its collections with storage. * @param jb Database hand */ EJDB_EXPORT bool ejdbsyncdb(EJDB *jb); @@ -485,6 +485,9 @@ EJDB_EXPORT bool ejdbtranabort(EJCOLL *coll); /** Get current transaction status, it will be placed into txActive*/ EJDB_EXPORT bool ejdbtranstatus(EJCOLL *jcoll, bool *txactive); +/** Gets description of EJDB database and its collections. */ +EJDB_EXPORT bson* ejdbmeta(EJDB *jb); + EJDB_EXTERN_C_END #endif /* EJDB_H */