public int cachedrecords;
}
+ /// <summary>
+ /// EJDB database native wrapper.
+ /// </summary>
public class EJDB : IDisposable {
- //Open modes
+ //.//////////////////////////////////////////////////////////////////
+ // Native open modes
+ //.//////////////////////////////////////////////////////////////////
+ /// <summary>
+ /// Open as a reader.
+ /// </summary>
public const int JBOREADER = 1 << 0;
+ /// <summary>
+ /// Open as a writer.
+ /// </summary>
public const int JBOWRITER = 1 << 1;
+ /// <summary>
+ /// Create if db file not exists.
+ /// </summary>
public const int JBOCREAT = 1 << 2;
+ /// <summary>
+ /// Truncate db on open.
+ /// </summary>
public const int JBOTRUNC = 1 << 3;
+ /// <summary>
+ /// Open without locking.
+ /// </summary>
public const int JBONOLCK = 1 << 4;
+ /// <summary>
+ /// Lock without blocking.
+ /// </summary>
public const int JBOLCKNB = 1 << 5;
+ /// <summary>
+ /// Synchronize every transaction with storage.
+ /// </summary>
public const int JBOTSYNC = 1 << 6;
+ /// <summary>
+ /// The default open mode <c>(JBOWRITER | JBOCREAT)</c>
+ /// </summary>
public const int DEFAULT_OPEN_MODE = (JBOWRITER | JBOCREAT);
+ //.//////////////////////////////////////////////////////////////////
+ // Native index operations & types (ejdb.h)
+ //.//////////////////////////////////////////////////////////////////
+ /// <summary>
+ /// Drop index.
+ /// </summary>
+ const int JBIDXDROP = 1 << 0;
+
+ /// <summary>
+ /// Drop index for all types.
+ /// </summary>
+ const int JBIDXDROPALL = 1 << 1;
+
+ /// <summary>
+ /// Optimize indexes.
+ /// </summary>
+ const int JBIDXOP = 1 << 2;
+
+ /// <summary>
+ /// Rebuild index.
+ /// </summary>
+ const int JBIDXREBLD = 1 << 3;
+ /// <summary>
+ /// Number index.
+ /// </summary>
+ const int JBIDXNUM = 1 << 4;
+
+ /// <summary>
+ /// String index.
+ /// </summary>
+ const int JBIDXSTR = 1 << 5;
+
+ /// <summary>
+ /// Array token index.
+ /// </summary>
+ const int JBIDXARR = 1 << 6;
+
+ /// <summary>
+ /// Case insensitive string index.
+ /// </summary>
+ const int JBIDXISTR = 1 << 7;
+
+ /// <summary>
+ /// Name if EJDB library
+ /// </summary>
public const string EJDB_LIB_NAME = "tcejdb";
+ /// <summary>
+ /// Pointer to the native EJDB instance.
+ /// </summary>
IntPtr _db = IntPtr.Zero;
- //
+ //.//////////////////////////////////////////////////////////////////
+ // Native functions refs
+ //.//////////////////////////////////////////////////////////////////
#region NativeRefs
[DllImport(EJDB_LIB_NAME, EntryPoint="ejdbnew")]
internal static extern IntPtr _ejdbnew();
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);
//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
/// <summary>
/// Gets the last DB error code or <c>null</c> if underlying native database object does not exist.
}
/// <summary>
+ /// Gets description of EJDB database and its collections.
+ /// </summary>
+ /// <value>The DB meta.</value>
+ public BSONDocument DBMeta {
+ get {
+ CheckDisposed(true);
+ //internal static extern IntPtr ejdbmeta([In] IntPtr db);
+ //IntPtr bsptr =
+
+
+ BSONDocument meta = new BSONDocument();
+ return meta;
+ }
+ }
+
+ /// <summary>
/// Initializes a new instance of the <see cref="Ejdb.DB.EJDB"/> class.
/// </summary>
/// <param name="path">The main database file path.</param>
}
/// <summary>
+ /// Removes collection indetified by <c>cname</c>.
+ /// </summary>
+ /// <returns><c>false</c>, if error occurred.</returns>
+ /// <param name="cname">Name of the collection.</param>
+ /// <param name="unlink">If set to <c>true</c> then the collection data file will be removed.</param>
+ public bool DropCollection(string cname, bool unlink = false) {
+ CheckDisposed();
+ return _ejdbrmcoll(_db, cname, unlink);
+ }
+
+ /// <summary>
+ /// Synchronize entire EJDB database and
+ /// all of its collections with storage.
+ /// </summary>
+ /// <returns><c>false</c>, if error occurred.</returns>
+ public bool Sync() {
+ CheckDisposed();
+ //internal static extern bool _ejdbsyncdb([In] IntPtr db);
+ return _ejdbsyncdb(_db);
+ }
+
+ /// <summary>
+ /// Synchronize content of a EJDB collection database with the file on device.
+ /// </summary>
+ /// <returns><c>false</c>, if error occurred.</returns>
+ /// <param name="cname">Name of collection.</param>
+ 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);
+ }
+
+ /// <summary>
+ /// DROP indexes of all types for JSON field path.
+ /// </summary>
+ /// <returns><c>false</c>, if error occurred.</returns>
+ /// <param name="cname">Name of collection.</param>
+ /// <param name="ipath">JSON indexed field path</param>
+ public bool DropIndexes(string cname, string ipath) {
+ return IndexOperation(cname, ipath, JBIDXDROPALL);
+ }
+
+ /// <summary>
+ /// OPTIMIZE indexes of all types for JSON field path.
+ /// </summary>
+ /// <remarks>
+ /// Performs B+ tree index file optimization.
+ /// </remarks>
+ /// <returns><c>false</c>, if error occurred.</returns>
+ /// <param name="cname">Name of collection.</param>
+ /// <param name="ipath">JSON indexed field path</param>
+ public bool OptimizeIndexes(string cname, string ipath) {
+ return IndexOperation(cname, ipath, JBIDXOP);
+ }
+
+ /// <summary>
+ /// Ensure index presence of String type for JSON field path.
+ /// </summary>
+ /// <returns><c>false</c>, if error occurred.</returns>
+ /// <param name="cname">Name of collection.</param>
+ /// <param name="ipath">JSON indexed field path</param>
+ public bool EnsureStringIndex(string cname, string ipath) {
+ return IndexOperation(cname, ipath, JBIDXSTR);
+ }
+
+ /// <summary>
+ /// Rebuild index of String type for JSON field path.
+ /// </summary>
+ /// <returns><c>false</c>, if error occurred.</returns>
+ /// <param name="cname">Name of collection.</param>
+ /// <param name="ipath">JSON indexed field path</param>
+ public bool RebuildStringIndex(string cname, string ipath) {
+ return IndexOperation(cname, ipath, JBIDXSTR | JBIDXREBLD);
+ }
+
+ /// <summary>
+ /// Drop index of String type for JSON field path.
+ /// </summary>
+ /// <returns><c>false</c>, if error occurred.</returns>
+ /// <param name="cname">Name of collection.</param>
+ /// <param name="ipath">JSON indexed field path</param>
+ public bool DropStringIndex(string cname, string ipath) {
+ return IndexOperation(cname, ipath, JBIDXSTR | JBIDXDROP);
+ }
+
+ /// <summary>
+ /// Ensure case insensitive String index for JSON field path.
+ /// </summary>
+ /// <returns><c>false</c>, if error occurred.</returns>
+ /// <param name="cname">Name of collection.</param>
+ /// <param name="ipath">JSON indexed field path</param>
+ public bool EnsureIStringIndex(string cname, string ipath) {
+ return IndexOperation(cname, ipath, JBIDXISTR);
+ }
+
+ /// <summary>
+ /// Rebuild case insensitive String index for JSON field path.
+ /// </summary>
+ /// <returns><c>false</c>, if error occurred.</returns>
+ /// <param name="cname">Name of collection.</param>
+ /// <param name="ipath">JSON indexed field path</param>
+ public bool RebuildIStringIndex(string cname, string ipath) {
+ return IndexOperation(cname, ipath, JBIDXISTR | JBIDXREBLD);
+ }
+
+ /// <summary>
+ /// Drop case insensitive String index for JSON field path.
+ /// </summary>
+ /// <returns><c>false</c>, if error occurred.</returns>
+ /// <param name="cname">Name of collection.</param>
+ /// <param name="ipath">JSON indexed field path</param>
+ public bool DropIStringIndex(string cname, string ipath) {
+ return IndexOperation(cname, ipath, JBIDXISTR | JBIDXDROP);
+ }
+
+ /// <summary>
+ /// Ensure index presence of Number type for JSON field path.
+ /// </summary>
+ /// <returns><c>false</c>, if error occurred.</returns>
+ /// <param name="cname">Name of collection.</param>
+ /// <param name="ipath">JSON indexed field path</param>
+ public bool EnsureNumberIndex(string cname, string ipath) {
+ return IndexOperation(cname, ipath, JBIDXNUM);
+ }
+
+ /// <summary>
+ /// Rebuild index of Number type for JSON field path.
+ /// </summary>
+ /// <returns><c>false</c>, if error occurred.</returns>
+ /// <param name="cname">Name of collection.</param>
+ /// <param name="ipath">JSON indexed field path</param>
+ public bool RebuildNumberIndex(string cname, string ipath) {
+ return IndexOperation(cname, ipath, JBIDXNUM | JBIDXREBLD);
+ }
+
+ /// <summary>
+ /// Drop index of Number type for JSON field path.
+ /// </summary>
+ /// <returns><c>false</c>, if error occurred.</returns>
+ /// <param name="cname">Name of collection.</param>
+ /// <param name="ipath">JSON indexed field path</param>
+ public bool DropNumberIndex(string cname, string ipath) {
+ return IndexOperation(cname, ipath, JBIDXNUM | JBIDXDROP);
+ }
+
+ /// <summary>
+ /// Ensure index presence of Array type for JSON field path.
+ /// </summary>
+ /// <returns><c>false</c>, if error occurred.</returns>
+ /// <param name="cname">Name of collection.</param>
+ /// <param name="ipath">JSON indexed field path</param>
+ public bool EnsureArrayIndex(string cname, string ipath) {
+ return IndexOperation(cname, ipath, JBIDXARR);
+ }
+
+ /// <summary>
+ /// Rebuild index of Array type for JSON field path.
+ /// </summary>
+ /// <returns><c>false</c>, if error occurred.</returns>
+ /// <param name="cname">Name of collection.</param>
+ /// <param name="ipath">JSON indexed field path</param>
+ public bool RebuildArrayIndex(string cname, string ipath) {
+ return IndexOperation(cname, ipath, JBIDXARR | JBIDXREBLD);
+ }
+
+ /// <summary>
+ /// Drop index of Array type for JSON field path.
+ /// </summary>
+ /// <returns><c>false</c>, if error occurred.</returns>
+ /// <param name="cname">Name of collection.</param>
+ /// <param name="ipath">JSON indexed field path</param>
+ public bool DropArrayIndex(string cname, string ipath) {
+ return IndexOperation(cname, ipath, JBIDXARR | JBIDXDROP);
+ }
+
+ /// <summary>
/// Save the BSON document doc into the collection.
/// </summary>
/// <param name="cname">Name of collection.</param>
}
/// <summary>
+ /// Removes stored objects from the collection.
+ /// </summary>
+ /// <param name="cname">Name of collection.</param>
+ /// <param name="oids">Object identifiers.</param>
+ 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;
+ }
+
+ /// <summary>
/// Creates the query.
/// </summary>
/// <returns>The query object.</returns>
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");
+ }
+ }
}
}
}
/// </summary>
/// <returns>This query object.</returns>
/// <param name="doc">Query document.</param>
- 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) {
+++ /dev/null
-// ============================================================================================
-// .NET API for EJDB database library http://ejdb.org
-// Copyright (C) 2012-2013 Softmotions Ltd <info@softmotions.com>
-//
-// 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() {
- }
- }
-}
-
+++ /dev/null
-// ============================================================================================
-// .NET API for EJDB database library http://ejdb.org
-// Copyright (C) 2012-2013 Softmotions Ltd <info@softmotions.com>
-//
-// 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<JSONElement>, IDisposable {
-
- BinaryReader _input;
-
- public JSONReader(Stream jstream) {
- this._input = new BinaryReader(jstream);
- }
-
- public IEnumerator<JSONElement> GetEnumerator() {
-
-
-
- yield return new JSONElement();
- }
-
- System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
- return GetEnumerator();
- }
-
- public void Dispose() {
- if (_input != null) {
- _input.Close();
- _input = null;
- }
- }
- }
-}
-
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();
}
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();
<Private>False</Private>
</Reference>
<Reference Include="System.Core" />
- <Reference Include="System.Runtime.Serialization" />
<Reference Include="Mono.Posix" />
</ItemGroup>
<ItemGroup>
<Compile Include="Ejdb.BSON\BSONBinData.cs" />
<Compile Include="Ejdb.BSON\BSONDocument.cs" />
<Compile Include="Ejdb.BSON\BSONConstants.cs" />
- <Compile Include="Ejdb.JSON\JSONReader.cs" />
- <Compile Include="Ejdb.JSON\JSONElement.cs" />
<Compile Include="Ejdb.DB\EJDBException.cs" />
<Compile Include="Ejdb.Tests\TestEJDB.cs" />
<Compile Include="Ejdb.DB\EJDBQuery.cs" />
<Folder Include="Ejdb.IO\" />
<Folder Include="Ejdb.Utils\" />
<Folder Include="Ejdb.BSON\" />
- <Folder Include="Ejdb.JSON\" />
</ItemGroup>
<ProjectExtensions>
<MonoDevelop>
<Properties>
<MonoDevelop.Ide.Workspace ActiveConfiguration="Debug" />
- <MonoDevelop.Ide.Workbench ActiveDocument="Ejdb.Tests/TestEJDB.cs">
+ <MonoDevelop.Ide.Workbench ActiveDocument="Ejdb.DB/EJDB.cs">
<Files>
- <File FileName="Ejdb.DB/EJDB.cs" Line="295" Column="16" />
- <File FileName="Ejdb.DB/EJDBQuery.cs" Line="286" Column="16" />
- <File FileName="Ejdb.DB/EJDBQCursor.cs" Line="71" Column="60" />
- <File FileName="Ejdb.BSON/BSONDocument.cs" Line="224" Column="35" />
- <File FileName="Ejdb.Tests/TestEJDB.cs" Line="112" Column="4" />
- <File FileName="Ejdb.BSON/BSONRegexp.cs" Line="53" Column="3" />
- <File FileName="Ejdb.BSON/BSONIterator.cs" Line="133" Column="20" />
+ <File FileName="Ejdb.DB/EJDB.cs" Line="278" Column="17" />
+ <File FileName="Ejdb.DB/EJDBQuery.cs" Line="124" Column="5" />
+ <File FileName="Ejdb.DB/EJDBQCursor.cs" Line="1" Column="1" />
+ <File FileName="Ejdb.BSON/BSONDocument.cs" Line="1" Column="1" />
+ <File FileName="Ejdb.Tests/TestEJDB.cs" Line="77" Column="29" />
+ <File FileName="Ejdb.BSON/BSONRegexp.cs" Line="1" Column="1" />
+ <File FileName="Ejdb.BSON/BSONIterator.cs" Line="1" Column="1" />
+ <File FileName="Ejdb.JSON/JSONElement.cs" Line="15" Column="96" />
+ <File FileName="Ejdb.BSON/BSONType.cs" Line="20" Column="29" />
</Files>
<Pads>
<Pad Id="ProjectPad">
<Node name="Ejdb.BSON" expanded="True" />
<Node name="Ejdb.DB" expanded="True" />
<Node name="Ejdb.IO" expanded="True" />
- <Node name="Ejdb.JSON" expanded="True" />
- <Node name="Ejdb.Tests" expanded="True">
- <Node name="TestEJDB.cs" selected="True" />
- </Node>
+ <Node name="Ejdb.Tests" expanded="True" />
<Node name="Ejdb.Utils" expanded="True" />
</Node>
</State>
<State selected="True" />
</Pad>
<Pad Id="MonoDevelop.NUnit.TestPad">
- <State expanded="True" selected="True">
+ <State expanded="True">
<Node name="nejdb" expanded="True">
<Node name="Ejdb" expanded="True">
<Node name="Tests" expanded="True">
- <Node name="TestEJDB" expanded="True" />
+ <Node name="TestBSON" expanded="True" />
+ <Node name="TestEJDB" expanded="True" selected="True" />
</Node>
</Node>
</Node>
static Handle<Value> s_db_meta(const Arguments& args) {
HandleScope scope;
NodeEJDB *njb = ObjectWrap::Unwrap< NodeEJDB > (args.This());
- Local<Object> 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<Array> 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<Object> 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<Object> 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<Array> 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<Object> 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<Object> ret = toV8Object(&it);
+ bson_del(meta);
return scope.Close(ret);
}
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);
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
*************************************************************************************************/
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);
/**
* 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);
/** 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 */