#24
authoradam <adamansky@gmail.com>
Tue, 18 Jun 2013 18:03:43 +0000 (01:03 +0700)
committeradam <adamansky@gmail.com>
Tue, 18 Jun 2013 18:03:43 +0000 (01:03 +0700)
nejdb/Ejdb.DB/EJDB.cs
nejdb/Ejdb.DB/EJDBQCursor.cs [new file with mode: 0644]
nejdb/Ejdb.DB/EJDBQuery.cs
nejdb/Ejdb.DB/EJDBQueryException.cs [new file with mode: 0644]
nejdb/nejdb.csproj
nejdb/nejdb.userprefs
tcejdb/ejdb.c
tcejdb/ejdb.h

index 197d5f4..32a4aa1 100644 (file)
@@ -57,17 +57,18 @@ namespace Ejdb.DB {
                public const string EJDB_LIB_NAME = "tcejdb";
 
                IntPtr _db = IntPtr.Zero;
-               #region Functions
+               //
+               #region NativeRefs
                [DllImport(EJDB_LIB_NAME, EntryPoint="ejdbnew")]
-               static extern IntPtr _ejdbnew();
+               internal static extern IntPtr _ejdbnew();
 
                [DllImport(EJDB_LIB_NAME, EntryPoint="ejdbdel")]
-               static extern IntPtr _ejdbdel([In] IntPtr db);
+               internal static extern IntPtr _ejdbdel([In] IntPtr db);
 
                [DllImport(EJDB_LIB_NAME, EntryPoint="ejdbopen")]
-               static extern bool _ejdbopen([In] IntPtr db, [In] IntPtr path, int mode);
+               internal static extern bool _ejdbopen([In] IntPtr db, [In] IntPtr path, int mode);
 
-               static bool _ejdbopen(IntPtr db, string path, int mode) {
+               internal static bool _ejdbopen(IntPtr db, string path, int mode) {
                        IntPtr pptr = UnixMarshal.StringToHeap(path, Encoding.UTF8);
                        try {
                                return _ejdbopen(db, pptr, mode);
@@ -77,21 +78,21 @@ namespace Ejdb.DB {
                }
 
                [DllImport(EJDB_LIB_NAME, EntryPoint="ejdbclose")]
-               static extern bool _ejdbclose([In] IntPtr db);
+               internal static extern bool _ejdbclose([In] IntPtr db);
 
                [DllImport(EJDB_LIB_NAME, EntryPoint="ejdbisopen")]
-               static extern bool _ejdbisopen([In] IntPtr db);
+               internal static extern bool _ejdbisopen([In] IntPtr db);
 
                [DllImport(EJDB_LIB_NAME, EntryPoint="ejdbecode")]
-               static extern int _ejdbecode([In] IntPtr db);
+               internal static extern int _ejdbecode([In] IntPtr db);
 
                [DllImport(EJDB_LIB_NAME, EntryPoint="ejdberrmsg")]
-               static extern IntPtr _ejdberrmsg(int ecode);
+               internal static extern IntPtr _ejdberrmsg(int ecode);
 
                [DllImport(EJDB_LIB_NAME, EntryPoint="ejdbgetcoll")]
-               static extern IntPtr _ejdbgetcoll([In] IntPtr db, [In] IntPtr cname);
+               internal static extern IntPtr _ejdbgetcoll([In] IntPtr db, [In] IntPtr cname);
 
-               static IntPtr _ejdbgetcoll(IntPtr db, string cname) {
+               internal static IntPtr _ejdbgetcoll(IntPtr db, string cname) {
                        IntPtr cptr = UnixMarshal.StringToHeap(cname, Encoding.UTF8);
                        try {
                                return _ejdbgetcoll(db, cptr);
@@ -101,9 +102,9 @@ namespace Ejdb.DB {
                }
 
                [DllImport(EJDB_LIB_NAME, EntryPoint="ejdbcreatecoll")]
-               static extern IntPtr _ejdbcreatecoll([In] IntPtr db, [In] IntPtr cname, ref EJDBCollectionOptionsN? opts);
+               internal static extern IntPtr _ejdbcreatecoll([In] IntPtr db, [In] IntPtr cname, ref EJDBCollectionOptionsN? opts);
 
-               static IntPtr _ejdbcreatecoll(IntPtr db, String cname, EJDBCollectionOptionsN? opts) {
+               internal static IntPtr _ejdbcreatecoll(IntPtr db, String cname, EJDBCollectionOptionsN? opts) {
                        IntPtr cptr = UnixMarshal.StringToHeap(cname, Encoding.UTF8);
                        try {
                                return _ejdbcreatecoll(db, cptr, ref opts);
@@ -113,16 +114,16 @@ namespace Ejdb.DB {
                }
                //EJDB_EXPORT bool ejdbsavebson3(EJCOLL *jcoll, void *bsdata, bson_oid_t *oid, bool merge);
                [DllImport(EJDB_LIB_NAME, EntryPoint="ejdbsavebson3")]
-               static extern bool _ejdbsavebson([In] IntPtr coll, [In] byte[] bsdata, [Out] byte[] oid, [In] bool merge);
+               internal static extern bool _ejdbsavebson([In] IntPtr coll, [In] byte[] bsdata, [Out] byte[] oid, [In] bool merge);
                //EJDB_EXPORT bson* ejdbloadbson(EJCOLL *coll, const bson_oid_t *oid);
                [DllImport(EJDB_LIB_NAME, EntryPoint="ejdbloadbson")]
-               static extern IntPtr _ejdbloadbson([In] IntPtr coll, [In] byte[] oid);
+               internal static extern IntPtr _ejdbloadbson([In] IntPtr coll, [In] byte[] oid);
                //EJDB_EXPORT const char* bson_data2(const bson *b, int *bsize);
                [DllImport(EJDB_LIB_NAME, EntryPoint="bson_data2")]
-               static extern IntPtr _bson_data2([In] IntPtr bsptr, out int size);
+               internal static extern IntPtr _bson_data2([In] IntPtr bsptr, out int size);
                //EJDB_EXPORT void bson_del(bson *b);
                [DllImport(EJDB_LIB_NAME, EntryPoint="bson_del")]
-               static extern void _bson_del([In] IntPtr bsptr);
+               internal static extern void _bson_del([In] IntPtr bsptr);
                #endregion
                /// <summary>
                /// Gets the last DB error code or <c>null</c> if underlying native database object does not exist.
@@ -264,11 +265,19 @@ namespace Ejdb.DB {
                /// <returns>The query object.</returns>
                /// <param name="qdoc">BSON query spec.</param>
                public EJDBQuery CreateQuery(BSONDocument qdoc) {
-                       return new EJDBQuery(qdoc);
+                       CheckDisposed();
+                       return new EJDBQuery(this, qdoc);
                }
                //.//////////////////////////////////////////////////////////////////
                //                                               Private staff                                                     //     
                //.//////////////////////////////////////////////////////////////////
+               internal IntPtr DBPtr {
+                       get {
+                               CheckDisposed();
+                               return _db;
+                       }
+               }
+
                byte[] BsonPtrIntoByteArray(IntPtr bsptr, bool deletebsptr = true) {
                        if (bsptr == IntPtr.Zero) {
                                return new byte[0];
@@ -283,7 +292,7 @@ namespace Ejdb.DB {
                        return bsdata;
                }
 
-               void CheckDisposed() {
+               internal void CheckDisposed() {
                        if (_db == IntPtr.Zero) {
                                throw new ObjectDisposedException("Database is disposed");
                        }
diff --git a/nejdb/Ejdb.DB/EJDBQCursor.cs b/nejdb/Ejdb.DB/EJDBQCursor.cs
new file mode 100644 (file)
index 0000000..b81a0ca
--- /dev/null
@@ -0,0 +1,105 @@
+// ============================================================================================
+//   .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.Runtime.InteropServices;
+using System.Collections.Generic;
+using Ejdb.BSON;
+
+namespace Ejdb.DB {
+
+       /// <summary>
+       /// Query result set container.
+       /// </summary>
+       public class EJDBQCursor : IDisposable, IEnumerable<BSONIterator> {
+               //optional query execution log buffer
+               string _log;
+               //current cursor position
+               int _pos;
+               //cursor length
+               int _len;
+               //Pointer to the result set list
+               IntPtr _qresptr;
+               //EJDB_EXPORT void ejdbqresultdispose(EJQRESULT qr);
+               [DllImport(EJDB.EJDB_LIB_NAME, EntryPoint="ejdbqresultdispose")]
+               static extern void _ejdbqresultdispose([In] IntPtr qres);
+               //const void* ejdbqresultbsondata(EJQRESULT qr, int pos, int *size)
+               [DllImport(EJDB.EJDB_LIB_NAME, EntryPoint="ejdbqresultbsondata")]
+               static extern IntPtr _ejdbqresultbsondata([In] IntPtr qres, [In] int pos, out int size);
+
+               /// <summary>
+               /// Gets the number of result records stored in this cursor.
+               /// </summary>
+               public int Length {
+                       get {
+                               return _len;
+                       }
+               }
+
+               /// <summary>
+               /// Gets optional query execution log.
+               /// </summary>
+               /// <value>The log.</value>
+               public string Log {
+                       get {
+                               return _log;
+                       }
+               }
+
+               internal EJDBQCursor(IntPtr qresptr, int len, string log = null) {
+                       _qresptr = qresptr;
+                       _log = log;
+                       _len = len;
+               }
+
+               public BSONIterator Next() {
+                       if (_qresptr == IntPtr.Zero || _pos >= _len) {
+                               return null;
+                       }
+                       //static extern IntPtr _ejdbqresultbsondata([In] IntPtr qres, [In] int idx, out int size)
+                       int size;
+                       IntPtr bsdataptr = _ejdbqresultbsondata(_qresptr, _pos, out size);
+                       if (bsdataptr == IntPtr.Zero) {
+                               return null;
+                       }
+                       byte[] bsdata = new byte[size];
+                       Marshal.Copy(bsdataptr, bsdata, 0, bsdata.Length);
+                       _pos++;
+                       return new BSONIterator(bsdata);
+               }
+
+               public IEnumerator<BSONIterator> GetEnumerator() {
+                       BSONIterator it;
+                       while ((it = Next()) != null) {
+                               yield return it;
+                       }
+               }
+
+               System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
+                       return GetEnumerator();
+               }
+
+               public void Dispose() {
+                       _log = null;
+                       _pos = 0;
+                       if (_qresptr != IntPtr.Zero) {
+                               //static extern void _ejdbqresultdispose([In] IntPtr qres);
+                               _ejdbqresultdispose(_qresptr);
+                               _qresptr = IntPtr.Zero;
+                       }
+               }
+       }
+}
+
index 1e69891..4213c0a 100644 (file)
 // ============================================================================================
 using System;
 using Ejdb.BSON;
+using System.Runtime.InteropServices;
 
 namespace Ejdb.DB {
 
+       /// <summary>
+       /// EJDB query.
+       /// </summary>
        public class EJDBQuery : IDisposable {
 
-               IntPtr _qptr;
+               //Query search mode flags in ejdbqryexecute()
+               /// <summary>
+               /// Query only count(*)
+               /// </summary>
+               public const int JBQRYCOUNT_FLAG = 1;
 
-               internal EJDBQuery(BSONDocument qdoc) {
+               /// <summary>
+               /// Fetch first record only.
+               /// </summary>
+               public const int JBQRYFINDONE_FLAG = 1 << 1;
+
+               /// <summary>
+               /// Explain query execution and 
+               /// store query execution log into <see cref="Ejdb.DB.EJDBQCursor#Log"/>
+               /// </summary>
+               public const int EXPLAIN_FLAG = 1 << 16;
+
+               /// <summary>
+               /// EJDB query object <c>EJQ</c> pointer.
+               /// </summary>
+               IntPtr _qptr = IntPtr.Zero;
+
+               /// <summary>
+               /// Database reference.
+               /// </summary>
+               EJDB _jb;
+
+               /// <summary>
+               /// Last used query hints document.
+               /// </summary>
+               BSONDocument _hints;
+               //
+               #region NativeRefs
+               //EJDB_EXPORT void ejdbquerydel(EJQ *q);
+               [DllImport(EJDB.EJDB_LIB_NAME, EntryPoint="ejdbquerydel")]
+               static extern void _ejdbquerydel([In] IntPtr qptr);
+               //EJDB_EXPORT EJQ* ejdbcreatequery2(EJDB *jb, void *qbsdata);
+               [DllImport(EJDB.EJDB_LIB_NAME, EntryPoint="ejdbcreatequery2")]
+               static extern IntPtr _ejdbcreatequery([In] IntPtr jb, [In] byte[] bsdata);
+               //EJDB_EXPORT EJQ* ejdbqueryhints(EJDB *jb, EJQ *q, void *hintsbsdata)
+               [DllImport(EJDB.EJDB_LIB_NAME, EntryPoint="ejdbqueryhints")]
+               static extern IntPtr _ejdbqueryhints([In] IntPtr jb, [In] IntPtr qptr, [In] byte[] bsdata);
+               //EJDB_EXPORT EJQ* ejdbqueryaddor(EJDB *jb, EJQ *q, void *orbsdata)
+               [DllImport(EJDB.EJDB_LIB_NAME, EntryPoint="ejdbqueryaddor")]
+               static extern IntPtr _ejdbqueryaddor([In] IntPtr jb, [In] IntPtr qptr, [In] byte[] bsdata);
+               //EJDB_EXPORT EJQRESULT ejdbqryexecute(EJCOLL *jcoll, const EJQ *q, uint32_t *count, int qflags, TCXSTR *log)
+               [DllImport(EJDB.EJDB_LIB_NAME, EntryPoint="ejdbqryexecute")]
+               static extern IntPtr _ejdbqryexecute([In] IntPtr jcoll, [In] IntPtr q, out int count, [In] int qflags, [In] IntPtr logxstr);
+               #endregion
+               internal EJDBQuery(EJDB jb, BSONDocument qdoc) {
+                       _qptr = _ejdbcreatequery(jb.DBPtr, qdoc.ToByteArray());
+                       if (_qptr == IntPtr.Zero) {
+                               throw new EJDBQueryException(jb);
+                       }
+                       _jb = jb;
+               }
+
+               /// <summary>
+               /// Append OR joined restriction to this query.
+               /// </summary>
+               /// <returns>This query object.</returns>
+               /// <param name="doc">Query document.</param>
+               public EJDBQuery AppendOR(BSONDocument doc) {
+                       CheckDisposed();
+                       //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) {
+                               throw new EJDBQueryException(_jb);
+                       }
+                       return  this;
+               }
+
+               /// <summary>
+               /// Sets the query hints. 
+               /// </summary>
+               /// <remarks>
+               /// Replaces previous hints associated with this query.
+               /// </remarks>
+               /// <returns>This query object.</returns>
+               /// <param name="hints">Hints document.</param>
+               public EJDBQuery SetHints(BSONDocument hints) {
+                       CheckDisposed();
+                       //static extern IntPtr _ejdbqueryhints([In] IntPtr jb, [In] IntPtr qptr, [In] byte[] bsdata);
+                       IntPtr qptr = _ejdbqueryhints(_jb.DBPtr, _qptr, hints.ToByteArray());
+                       if (qptr == IntPtr.Zero) {
+                               throw new EJDBQueryException(_jb);
+                       }
+                       _hints = hints;
+                       return this;
+               }
+
+               public EJDBQCursor Find(string cname, int flags = 0) {
+                       IntPtr cptr = EJDB._ejdbgetcoll(_jb.DBPtr, cname);
+                       if (cptr == IntPtr.Zero) {
+                               return new EJDBQCursor(IntPtr.Zero, 0);
+                       }
+                       //static extern IntPtr _ejdbqryexecute([In] IntPtr jcoll, [In] IntPtr q, out int count, [In] int qflags, [In] IntPtr logxstr);
+                       //todo
+                       //return new EJDBQCursor();
+                       return null;
+               }
+
+               public BSONIterator FinOne(string cname, int flags = 0) {
+                       using (EJDBQCursor cur = Find(cname, flags | JBQRYFINDONE_FLAG)) {
+                               return cur.Next();
+                       }
+               }
+
+               public int Count(string cname, int flags = 0) {
+                       using (EJDBQCursor cur = Find(cname, flags | JBQRYCOUNT_FLAG)) {
+                               return cur.Length;
+                       }
+               }
+
+               public int Update(string cname, int flags = 0) {
+                       using (EJDBQCursor cur = Find(cname, flags | JBQRYCOUNT_FLAG)) {
+                               return cur.Length;
+                       }
                }
 
                public void Dispose() {
-                       throw new NotImplementedException();
+                       if (_qptr != IntPtr.Zero) {
+                               //static extern void _ejdbquerydel([In] IntPtr qptr);
+                               _ejdbquerydel(_qptr);
+                               _qptr = IntPtr.Zero;
+                       }
+                       if (_jb != null) {
+                               _jb = null;
+                       }
+                       _hints = null;
+               }
+
+               internal void CheckDisposed() {
+                       if (_jb == null || _qptr == IntPtr.Zero) {
+                               throw new ObjectDisposedException("Query object is disposed");
+                       }
                }
        }
 }
diff --git a/nejdb/Ejdb.DB/EJDBQueryException.cs b/nejdb/Ejdb.DB/EJDBQueryException.cs
new file mode 100644 (file)
index 0000000..fc92d12
--- /dev/null
@@ -0,0 +1,25 @@
+// ============================================================================================
+//   .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.DB {
+
+       public class EJDBQueryException : EJDBException {
+               public EJDBQueryException(EJDB db) : base(db) {
+               }
+       }
+}
+
index aceb9c7..8a7fbdc 100644 (file)
@@ -65,6 +65,8 @@
     <Compile Include="Ejdb.DB\EJDBException.cs" />
     <Compile Include="Ejdb.Tests\TestEJDB.cs" />
     <Compile Include="Ejdb.DB\EJDBQuery.cs" />
+    <Compile Include="Ejdb.DB\EJDBQueryException.cs" />
+    <Compile Include="Ejdb.DB\EJDBQCursor.cs" />
   </ItemGroup>
   <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
   <ItemGroup>
index 78732cb..258944f 100644 (file)
@@ -1,16 +1,13 @@
 <Properties>
   <MonoDevelop.Ide.Workspace ActiveConfiguration="Debug" />
-  <MonoDevelop.Ide.Workbench ActiveDocument="Ejdb.DB/EJDB.cs">
+  <MonoDevelop.Ide.Workbench ActiveDocument="Ejdb.DB/EJDBQuery.cs">
     <Files>
-      <File FileName="Ejdb.DB/EJDB.cs" Line="266" Column="13" />
-      <File FileName="Ejdb.BSON/BSONType.cs" Line="1" Column="1" />
-      <File FileName="Ejdb.Tests/TestEJDB.cs" Line="53" Column="23" />
-      <File FileName="Ejdb.BSON/BSONDocument.cs" Line="1" Column="1" />
-      <File FileName="Ejdb.BSON/BSONOid.cs" Line="1" Column="1" />
-      <File FileName="Ejdb.BSON/BSONIterator.cs" Line="326" Column="3" />
-      <File FileName="Ejdb.Tests/TestBSON.cs" Line="15" Column="49" />
-      <File FileName="Ejdb.DB/EJDBQuery.cs" Line="31" Column="3" />
-      <File FileName="Ejdb.DB/EJDBException.cs" Line="1" Column="1" />
+      <File FileName="Ejdb.DB/EJDB.cs" Line="281" Column="37" />
+      <File FileName="Ejdb.BSON/BSONIterator.cs" Line="25" Column="2" />
+      <File FileName="Ejdb.DB/EJDBQuery.cs" Line="25" Column="38" />
+      <File FileName="Ejdb.DB/EJDBQueryException.cs" Line="21" Column="48" />
+      <File FileName="Ejdb.DB/EJDBQCursor.cs" Line="67" Column="18" />
+      <File FileName="Ejdb.BSON/BSONDocument.cs" Line="63" Column="3" />
     </Files>
     <Pads>
       <Pad Id="ProjectPad">
@@ -20,7 +17,7 @@
             <Node name="References" expanded="True" />
             <Node name="Ejdb.BSON" expanded="True" />
             <Node name="Ejdb.DB" expanded="True">
-              <Node name="EJDB.cs" selected="True" />
+              <Node name="EJDBQuery.cs" selected="True" />
             </Node>
             <Node name="Ejdb.IO" expanded="True" />
             <Node name="Ejdb.JSON" expanded="True" />
           <Value>_input.BaseStream.Position</Value>
         </State>
       </Pad>
-      <Pad Id="MonoDevelop.NUnit.TestPad">
-        <State expanded="True" selected="True" />
-      </Pad>
       <Pad Id="ConnectionManagerPad">
         <State selected="True" />
       </Pad>
+      <Pad Id="MonoDevelop.NUnit.TestPad">
+        <State expanded="True" selected="True">
+          <Node name="nejdb" expanded="True">
+            <Node name="Ejdb" expanded="True">
+              <Node name="Tests" expanded="True">
+                <Node name="TestBSON" expanded="True" />
+                <Node name="TestEJDB" expanded="True" />
+              </Node>
+            </Node>
+          </Node>
+        </State>
+      </Pad>
     </Pads>
   </MonoDevelop.Ide.Workbench>
   <MonoDevelop.Ide.DebuggingService.Breakpoints>
index 4cdde67..e902816 100644 (file)
@@ -746,9 +746,14 @@ int ejdbqresultnum(EJQRESULT qr) {
     return qr ? tclistnum(qr) : 0;
 }
 
-const void* ejdbqresultbsondata(EJQRESULT qr, int idx) {
-    if (!qr || idx < 0) return NULL;
-    return tclistval2(qr, idx);
+const void* ejdbqresultbsondata(EJQRESULT qr, int pos, int *size) {
+    if (!qr || pos < 0) {
+        *size = 0;
+        return NULL;
+    }
+    const void *bsdata = tclistval2(qr, pos);
+    *size = (bsdata != NULL) ? bson_size2(bsdata) : 0;
+    return bsdata;
 }
 
 void ejdbqresultdispose(EJQRESULT qr) {
@@ -3101,6 +3106,8 @@ static bool _qrypreprocess(EJCOLL *jcoll, EJQ *ejq, int qflags, EJQF **mqf,
         if (BSON_IS_NUM_TYPE(bt)) {
             int64_t v = bson_iterator_long(&it);
             ejq->max = (uint32_t) ((v < 0) ? 0 : v);
+        } else if (qflags & JBQRYFINDONE) {
+            ejq->max = (uint32_t) 1;
         }
         if (!(qflags & JBQRYCOUNT)) {
             bt = bson_find(&it, ejq->hints, "$fields"); //Collect required fields
index aaa580b..e01bde7 100644 (file)
@@ -83,7 +83,8 @@ enum { /** Index modes, index types. */
 };
 
 enum { /*< Query search mode flags in ejdbqryexecute() */
-    JBQRYCOUNT = 1 /*< Query only count(*) */
+    JBQRYCOUNT = 1, /*< Query only count(*) */
+    JBQRYFINDONE = 1 << 1 /*< Fetch first record only */
 };
 
 EJDB_EXPORT bool ejdbisvalidoidstr(const char *oid);
@@ -432,12 +433,12 @@ EJDB_EXPORT EJQRESULT ejdbqryexecute(EJCOLL *jcoll, const EJQ *q, uint32_t *coun
 EJDB_EXPORT int ejdbqresultnum(EJQRESULT qr);
 
 /**
- * Gets the pointer of query result BSON data buffer at the specified index `idx`.
+ * Gets the pointer of query result BSON data buffer at the specified position `pos`.
  * If `qr` is `NULL` or `idx` is put of index range then the `NULL` pointer will be returned.
  * @param qr Query result set object.
- * @param idx Zero based index of the record.
+ * @param pos Zero based position of the record.
  */
-EJDB_EXPORT const void* ejdbqresultbsondata(EJQRESULT qr, int idx);
+EJDB_EXPORT const void* ejdbqresultbsondata(EJQRESULT qr, int pos, int *size);
 
 /**
  * Disposes the query result set and frees a records buffers.