Working on lua documentation
authoradam <adamansky@gmail.com>
Wed, 20 Mar 2013 10:30:11 +0000 (17:30 +0700)
committeradam <adamansky@gmail.com>
Wed, 20 Mar 2013 10:30:11 +0000 (17:30 +0700)
luaejdb/doc/index.html
luaejdb/ejdb.lua
luaejdb/ejdb.luadoc
luaejdb/test/t1.lua
node/ejdb.js

index 0fd9211..fb6e468 100644 (file)
        <td class="summary">Save/update specified JSON objects in the collection.</td>
        </tr>
        <tr>
-       <td class="name" nowrap><a href="#DB:find">DB:find&nbsp;(cname, q)</a></td>
+       <td class="name" nowrap><a href="#DB:find">DB:find&nbsp;(cname, q, flags)</a></td>
        <td class="summary">Execute query on collection.</td>
        </tr>
        <tr>
+       <td class="name" nowrap><a href="#DB:findOne">DB:findOne&nbsp;(cname, q)</a></td>
+       <td class="summary">Same as <a href="index.html#DB:find">DB:find</a> but retrieves only first matching JSON object.</td>
+       </tr>
+       <tr>
+       <td class="name" nowrap><a href="#DB:update">DB:update&nbsp;(cname, q)</a></td>
+       <td class="summary">Convenient method to execute update queries.</td>
+       </tr>
+       <tr>
+       <td class="name" nowrap><a href="#DB:count">DB:count&nbsp;(cname, q)</a></td>
+       <td class="summary">Convenient <code>count(*)</code> operation.</td>
+       </tr>
+       <tr>
+       <td class="name" nowrap><a href="#RS:object">RS:object&nbsp;(i)</a></td>
+       <td class="summary">Returns result set lua table object at specified position <code>i</code></td>
+       </tr>
+       <tr>
+       <td class="name" nowrap><a href="#RS:field">RS:field&nbsp;(i, name)</a></td>
+       <td class="summary">Returns field value of lua object at specified position <code>i</code></td>
+       </tr>
+       <tr>
+       <td class="name" nowrap><a href="#RS.__len">RS.__len&nbsp;()</a></td>
+       <td class="summary">Length of result set.</td>
+       </tr>
+       <tr>
+       <td class="name" nowrap><a href="#Q:F">Q:F&nbsp;(fname)</a></td>
+       <td class="summary">Set current field for the next operation during query building.</td>
+       </tr>
+       <tr>
        <td class="name" nowrap><a href="#Q:Eq">Q:Eq&nbsp;(val)</a></td>
-       <td class="summary">Field eq restriction.</td>
+       <td class="summary">Field equality restriction.</td>
        </tr>
        <tr>
        <td class="name" nowrap><a href="#Q:ElemMatch">Q:ElemMatch&nbsp;(val)</a></td>
        <td class="name" nowrap><a href="#Q:Lte">Q:Lte&nbsp;(val)</a></td>
        <td class="summary">Lesser than or equal (val &lt;= arg)</td>
        </tr>
+       <tr>
+       <td class="name" nowrap><a href="#Q:Icase">Q:Icase&nbsp;(val)</a></td>
+       <td class="summary">Case insensitive string matching</td>
+       </tr>
+       <tr>
+       <td class="name" nowrap><a href="#Q:Begin">Q:Begin&nbsp;(val)</a></td>
+       <td class="summary">String starts with prefix</td>
+       </tr>
+       <tr>
+       <td class="name" nowrap><a href="#Q:In">Q:In&nbsp;(val)</a></td>
+       <td class="summary">Field value matched any value of specified in <code>val</code> table.</td>
+       </tr>
+       <tr>
+       <td class="name" nowrap><a href="#Q:NotIn">Q:NotIn&nbsp;(val)</a></td>
+       <td class="summary">Negation of <a href="index.html#Q:In">Q:In</a></td>
+       </tr>
+       <tr>
+       <td class="name" nowrap><a href="#Q:Bt">Q:Bt&nbsp;(n1, n2)</a></td>
+       <td class="summary">Between for number types</td>
+       </tr>
+       <tr>
+       <td class="name" nowrap><a href="#Q:StrAnd">Q:StrAnd&nbsp;(val)</a></td>
+       <td class="summary">String tokens(or string array vals) matches <strong>all</strong> tokens in specified <code>val</code> array.</td>
+       </tr>
+       <tr>
+       <td class="name" nowrap><a href="#Q:StrOr">Q:StrOr&nbsp;(val)</a></td>
+       <td class="summary">String tokens(or string array vals) matches <strong>any</strong> token in specified array.</td>
+       </tr>
+       <tr>
+       <td class="name" nowrap><a href="#Q:Inc">Q:Inc&nbsp;(val)</a></td>
+       <td class="summary">Increment current field.</td>
+       </tr>
+       <tr>
+       <td class="name" nowrap><a href="#Q:Set">Q:Set&nbsp;(val)</a></td>
+       <td class="summary">Set fields to values.</td>
+       </tr>
+       <tr>
+       <td class="name" nowrap><a href="#Q:Upsert">Q:Upsert&nbsp;(val)</a></td>
+       <td class="summary">Atomic upsert.</td>
+       </tr>
+       <tr>
+       <td class="name" nowrap><a href="#Q:AddToSet">Q:AddToSet&nbsp;(val)</a></td>
+       <td class="summary">Atomically adds <code>val</code> to the <code>array field</code> only if <code>val</code> not in the array already.</td>
+       </tr>
+       <tr>
+       <td class="name" nowrap><a href="#Q:AddToSetAll">Q:AddToSetAll&nbsp;(val)</a></td>
+       <td class="summary">Atomically performs <code>set union</code> with values in <code>val</code> for specified array field.</td>
+       </tr>
+       <tr>
+       <td class="name" nowrap><a href="#Q:Pull">Q:Pull&nbsp;(val)</a></td>
+       <td class="summary">Atomically removes all occurrences of <code>val</code> from field, if field is an array.</td>
+       </tr>
+       <tr>
+       <td class="name" nowrap><a href="#Q:PullAll">Q:PullAll&nbsp;(val)</a></td>
+       <td class="summary">Atomically performs <code>set substraction</code> of values in <code>val</code> for specified array field.</td>
+       </tr>
+       <tr>
+       <td class="name" nowrap><a href="#Q:DropAll">Q:DropAll&nbsp;()</a></td>
+       <td class="summary">In-place record removal operation.</td>
+       </tr>
+       <tr>
+       <td class="name" nowrap><a href="#Q:Join">Q:Join&nbsp;(cname, fpath)</a></td>
+       <td class="summary">Make <a href="https://github.com/Softmotions/ejdb/wiki/Collection-joins">collection join</a>
+ for select queries.</td>
+       </tr>
+       <tr>
+       <td class="name" nowrap><a href="#Q:Or">Q:Or&nbsp;(...)</a></td>
+       <td class="summary">Add <em>OR</em> joined query restrictions.</td>
+       </tr>
+       <tr>
+       <td class="name" nowrap><a href="#Q:Skip">Q:Skip&nbsp;(val)</a></td>
+       <td class="summary">Sets number of skipped records in the result set.</td>
+       </tr>
+       <tr>
+       <td class="name" nowrap><a href="#Q:Max">Q:Max&nbsp;(val)</a></td>
+       <td class="summary">Sets max number of records in the result set.</td>
+       </tr>
+       <tr>
+       <td class="name" nowrap><a href="#Q:OrderBy">Q:OrderBy&nbsp;(...)</a></td>
+       <td class="summary">Set sorting rules for query results.</td>
+       </tr>
+       <tr>
+       <td class="name" nowrap><a href="#Q:Fields">Q:Fields&nbsp;(...)</a></td>
+       <td class="summary">Sets fields to be included in resulting objects.</td>
+       </tr>
+       <tr>
+       <td class="name" nowrap><a href="#Q:NotFields">Q:NotFields&nbsp;(...)</a></td>
+       <td class="summary">Sets fields to be excluded from resulting objects.</td>
+       </tr>
 </table>
 <h2><a href="#Tables">Tables</a></h2>
 <table class="function_list">
        <td class="name" nowrap><a href="#DB">DB</a></td>
        <td class="summary">Database itself.</td>
        </tr>
+       <tr>
+       <td class="name" nowrap><a href="#RS">RS</a></td>
+       <td class="summary">Result set cursor object.</td>
+       </tr>
 </table>
 
 <br/>
     </dt>
     <dd>
     Opens EJDB database.
- <code><code>w</code></code> Open as a writer <br/>
- <code><code>r</code></code> Open as a reader <br/>
- <code><code>c</code></code> Create db if it not exists <br/>
- <code><code>t</code></code> Truncate existing db <br/>
- <code><code>s</code></code> Sycn db after each transaction <br/>
- Default open mode: <code><code>rws</code></code>
 
     <h3>Parameters:</h3>
     <ul>
         <li><span class="parameter">path</span>
-         {String} Database main file</li>
+            <span class="types"><a class="type" href="http://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
+         Database main file</li>
         <li><span class="parameter">mode</span>
-         {String?} Database open mode flags:<br/></li>
+            <span class="types">optional <a class="type" href="http://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
+         Database open mode flags:<br/>
+ <code><code>w</code></code> Open as a writer <br/>
+ <code><code>r</code></code> Open as a reader <br/>
+ <code><code>c</code></code> Create db if it not exists <br/>
+ <code><code>t</code></code> Truncate existing db <br/>
+ <code><code>s</code></code> Sycn db after each transaction <br/>
+ Default open mode: <code><code>rwcs</code></code></li>
     </ul>
 
     <h3>Returns:</h3>
     <h3>Parameters:</h3>
     <ul>
         <li><span class="parameter">val</span>
-         {String} 24 hex chars BSON_OID</li>
+            <span class="types"><a class="type" href="http://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
+         24 hex chars BSON_OID</li>
     </ul>
 
 
     <h3>Parameters:</h3>
     <ul>
         <li><span class="parameter">re</span>
-         {String} Regular expression</li>
+            <span class="types"><a class="type" href="http://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
+         Regular expression</li>
         <li><span class="parameter">opts</span>
-         {String} Regular expression flags</li>
+            <span class="types">optional <a class="type" href="http://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
+         Regular expression flags</li>
     </ul>
 
     <h3>Returns:</h3>
     <h3>Parameters:</h3>
     <ul>
         <li><span class="parameter">cname</span>
-         {String} Name of collection.</li>
+            <span class="types"><a class="type" href="http://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
+         Name of collection.</li>
         <li><span class="parameter">obj</span>
-         Lua table or <a href="#Q">Q</a> represents JSON object.</li>
+            <span class="types"><a class="type" href="http://www.lua.org/manual/5.1/manual.html#5.5">table</a> or <a class="type" href="index.html#Q">Q</a></span>
+         represents JSON object.</li>
         <li><span class="parameter">...</span>
          If last argument is True a saved object will be merged with who's</li>
     </ul>
 </dd>
     <dt>
     <a name = "DB:find"></a>
-    <strong>DB:find&nbsp;(cname, q)</strong>
+    <strong>DB:find&nbsp;(cname, q, flags)</strong>
     </dt>
     <dd>
 
 <p>Execute query on collection. </p>
 
-<p> EJDB queries inspired by MongoDB (mongodb.org) and follows same philosophy.
- - Supported queries:</p>
-<pre><code>- Simple matching of String OR Number OR Array value:
+<p> EJDB queries inspired by MongoDB (mongodb.org) and follows same philosophy.</p>
+
+<p> Queries and query hints can be constructed by <a href="index.html#Q">Q</a> query/json builder.</p>
+<pre><code>- Supported queries:
+- Simple matching of String OR Number OR Array value:
     -   {'fpath' : 'val', ...}
 - $not Negate operation.
     -   {'fpath' : {'$not' : val}} //Field not equal to val
 </code></pre></li>
 </ul>
 
-<p>  NOTE: It is better to execute update queries with <code>$onlycount=true</code> hint flag</p>
+<p>  <strong>NOTE:</strong> It is better to execute update queries with <code>$onlycount=true</code> hint flag</p>
 <pre><code>    or use the special `update()` method to avoid unnecessarily data fetching.
 </code></pre>
-<p>  NOTE: Negate operations: $not and $nin not using indexes</p>
+
+<p>  <strong>NOTE:</strong> Negate operations: $not and $nin not using indexes</p>
 <pre><code>    so they can be slow in comparison to other matching operations.
 </code></pre>
-<p>  NOTE: Only one index can be used in search query operation.
-  NOTE: If callback is not provided this function will be synchronous.</p>
 
-<p>  QUERY HINTS (specified by <code>hints</code> argument):</p>
+<p>  <strong>NOTE:</strong> Only one index can be used in search query operation.</p>
+
+<p>  <strong>NOTE:</strong> If callback is not provided this function will be synchronous.</p>
+
+<p>  <strong>QUERY HINTS</strong> specified by calling <a href="index.html#Q:Skip">Q:Skip</a> <a href="index.html#Q:Max">Q:Max</a>, <a href="index.html#Q:OrderBy">Q:OrderBy</a>, <a href="index.html#Q:Fields">Q:Fields</a>:</p>
 <pre><code>- $max Maximum number in the result set
 - $skip Number of skipped results in the result set
 - $orderby Sorting order of query fields.
-- $onlycount true|false If `true` only count of matching records will be returned
-                        without placing records in result set.
 - $fields Set subset of fetched fields.
     If field presented in $orderby clause it will be forced to include in resulting records.
     Example:
@@ -700,11 +831,33 @@ end
     <h3>Parameters:</h3>
     <ul>
         <li><span class="parameter">cname</span>
-         {String} Name of collection</li>
+            <span class="types"><a class="type" href="http://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
+         Name of collection</li>
         <li><span class="parameter">q</span>
-         {table|Q} JSON query object</li>
+            <span class="types"><a class="type" href="index.html#Q">Q</a></span>
+         JSON query object</li>
+        <li><span class="parameter">flags</span>
+            <span class="types"><a class="type" href="http://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
+
+<p> Query control flags:</p>
+<pre><code>`c`: only count of matching records will be returned without placing records in result set.
+`l`: return query execution log
+</code></pre>
+</li>
     </ul>
 
+    <h3>Returns:</h3>
+    <ol>
+        <li>
+          <span class="types"><a class="type" href="index.html#RS">RS</a></span>
+        result set, it will be <code>nil</code> if <code>c</code> flag presented in the control <code>flags</code></li>
+        <li>
+          <span class="types"><span class="type">number</span></span>
+        Count of matched/updated records</li>
+        <li>
+          <span class="types">optional <a class="type" href="http://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
+        Query execution log if <code>l</code> flag presented in the control <code>flags</code></li>
+    </ol>
 
 
     <h3>see also:</h3>
@@ -712,25 +865,188 @@ end
          <a href="index.html#Q">Q</a>
     </ul>
 
+    <h3>Usage:</h3>
+    <ul>
+        <li><pre class="example">db:find(<span class="string">"mycoll"</span>, Q(<span class="string">"foo"</span>, <span class="string">"bar"</span>)) =&gt; {<span class="string">"foo"</span> : <span class="string">"bar"</span>}</pre></li>
+        <li><pre class="example">db:find(<span class="string">"mycoll"</span>, Q(<span class="string">"foo"</span>, <span class="string">"bar"</span>):Max(<span class="number">10</span>)) -- Limit results up to <span class="number">10</span> records</pre></li>
+        <li><pre class="example">db:find(<span class="string">"parrots2"</span>, Q(<span class="string">"likes"</span>, <span class="string">"toys"</span>):OrderBy(<span class="string">"name asc"</span>, <span class="string">"age desc"</span>))</pre></li>
+        <li><pre class="example">db:find(<span class="string">"parrots2"</span>, Q():F(<span class="string">"likes"</span>):Eq(<span class="string">"toys"</span>):OrderBy({ name = <span class="number">1</span> }, { age = -<span class="number">1</span> }))</pre></li>
+    </ul>
 
 </dd>
     <dt>
-    <a name = "Q:Eq"></a>
-    <strong>Q:Eq&nbsp;(val)</strong>
+    <a name = "DB:findOne"></a>
+    <strong>DB:findOne&nbsp;(cname, q)</strong>
     </dt>
     <dd>
+    Same as <a href="index.html#DB:find">DB:find</a> but retrieves only first matching JSON object.
+
+    <h3>Parameters:</h3>
+    <ul>
+        <li><span class="parameter">cname</span>
+            <span class="types"><a class="type" href="http://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
+         Name of collection</li>
+        <li><span class="parameter">q</span>
+            <span class="types"><a class="type" href="index.html#Q">Q</a></span>
+         JSON query object</li>
+    </ul>
+
+    <h3>Returns:</h3>
+    <ol>
+        <li>
+          <span class="types"><a class="type" href="http://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
+        Lua table constructed from matched BSON record or <code>nil</code> of record not found</li>
+        <li>
+          <span class="types"><span class="type">number</span></span>
+        Count of matched/updated records</li>
+        <li>
+          <span class="types">optional <a class="type" href="http://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
+        Query execution log if <code>l</code> flag presented in the control <code>flags</code></li>
+    </ol>
+
 
-<p>Field eq restriction. </p>
-<pre><code>{fname : fval}
-</code></pre>
 
 
+</dd>
+    <dt>
+    <a name = "DB:update"></a>
+    <strong>DB:update&nbsp;(cname, q)</strong>
+    </dt>
+    <dd>
+    Convenient method to execute update queries.
+
     <h3>Parameters:</h3>
     <ul>
-        <li><span class="parameter">val</span>
+        <li><span class="parameter">cname</span>
+            <span class="types"><a class="type" href="http://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
+         Name of collection</li>
+        <li><span class="parameter">q</span>
+            <span class="types"><a class="type" href="index.html#Q">Q</a></span>
+         JSON query object</li>
+    </ul>
+
+    <h3>Returns:</h3>
+    <ol>
+        <li>
+          <span class="types"><span class="type">number</span></span>
+        Count of matched/updated records</li>
+        <li>
+          <span class="types">optional <a class="type" href="http://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
+        Query execution log if <code>l</code> flag presented in the control <code>flags</code></li>
+    </ol>
 
 
-</li>
+
+
+</dd>
+    <dt>
+    <a name = "DB:count"></a>
+    <strong>DB:count&nbsp;(cname, q)</strong>
+    </dt>
+    <dd>
+    Convenient <code>count(*)</code> operation.
+
+    <h3>Parameters:</h3>
+    <ul>
+        <li><span class="parameter">cname</span>
+            <span class="types"><a class="type" href="http://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
+         Name of collection</li>
+        <li><span class="parameter">q</span>
+            <span class="types"><a class="type" href="index.html#Q">Q</a></span>
+         JSON query object</li>
+    </ul>
+
+    <h3>Returns:</h3>
+    <ol>
+        <li>
+          <span class="types"><span class="type">number</span></span>
+        Count of matched/updated records</li>
+        <li>
+          <span class="types">optional <a class="type" href="http://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
+        Query execution log if <code>l</code> flag presented in the control <code>flags</code></li>
+    </ol>
+
+
+
+
+</dd>
+    <dt>
+    <a name = "RS:object"></a>
+    <strong>RS:object&nbsp;(i)</strong>
+    </dt>
+    <dd>
+    Returns result set lua table object at specified position <code>i</code>
+
+    <h3>Parameters:</h3>
+    <ul>
+        <li><span class="parameter">i</span>
+            <span class="types"><span class="type">number</span></span>
+         Position of record in the result set</li>
+    </ul>
+
+    <h3>Returns:</h3>
+    <ol>
+
+          <span class="types"><a class="type" href="http://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
+        Resulting lua object constructed from BSON record.
+    </ol>
+
+
+
+
+</dd>
+    <dt>
+    <a name = "RS:field"></a>
+    <strong>RS:field&nbsp;(i, name)</strong>
+    </dt>
+    <dd>
+    Returns field value of lua object at specified position <code>i</code>
+
+    <h3>Parameters:</h3>
+    <ul>
+        <li><span class="parameter">i</span>
+            <span class="types"><span class="type">number</span></span>
+         Position of record in the result set</li>
+        <li><span class="parameter">name</span>
+            <span class="types"><a class="type" href="http://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
+         JSON field name</li>
+    </ul>
+
+    <h3>Returns:</h3>
+    <ol>
+
+        Value of field
+    </ol>
+
+
+
+
+</dd>
+    <dt>
+    <a name = "RS.__len"></a>
+    <strong>RS.__len&nbsp;()</strong>
+    </dt>
+    <dd>
+    Length of result set.
+
+
+
+
+
+
+</dd>
+    <dt>
+    <a name = "Q:F"></a>
+    <strong>Q:F&nbsp;(fname)</strong>
+    </dt>
+    <dd>
+    Set current field for the next operation during query building.
+
+    <h3>Parameters:</h3>
+    <ul>
+        <li><span class="parameter">fname</span>
+            <span class="types"><a class="type" href="http://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
+         JSON field path</li>
     </ul>
 
 
@@ -738,23 +1054,49 @@ end
 
     <h3>Usage:</h3>
     <ul>
-        <li><pre class="example">Q():F(<span class="string">"fname"</span>):Eq(&lt;fval&gt;)</pre></li>
-        <li><pre class="example">Q(<span class="string">"fname"</span>, &lt;fval&gt;)</pre></li>
+        <pre class="example">Q:F(<span class="string">"name"</span>):Eq(<span class="string">"andy"</span>):F(<span class="string">"age"</span>):Gt(<span class="number">30</span>) =&gt; {<span class="string">"name"</span> : <span class="string">"andy"</span>, <span class="string">"age"</span> : {<span class="string">"$gt"</span> : <span class="number">30</span>}}</pre>
     </ul>
 
 </dd>
     <dt>
-    <a name = "Q:ElemMatch"></a>
-    <strong>Q:ElemMatch&nbsp;(val)</strong>
+    <a name = "Q:Eq"></a>
+    <strong>Q:Eq&nbsp;(val)</strong>
     </dt>
     <dd>
+    Field equality restriction.
+ All usage samples represent same thing: <code>{"fname" : fval}</code>
 
-<p>Element match construction. </p>
-<pre><code>- $elemMatch The $elemMatch operator matches more than one component within an array element.
-  -    { array: { $elemMatch: { value1 : 1, value2 : { $gt: 1 } } } }
-    Restriction: only one $elemMatch allowed in context of one array field.
-</code></pre>
+    <h3>Parameters:</h3>
+    <ul>
+        <li><span class="parameter">val</span>
+         any BSON value as Lua object including <a href="index.html#Q">Q</a> instances.</li>
+    </ul>
+
+    <h3>Returns:</h3>
+    <ol>
+
+        Self <a href="index.html#Q">Q</a>
+    </ol>
+
+
+
+    <h3>Usage:</h3>
+    <ul>
+        <li><pre class="example">Q():F(<span class="string">"fname"</span>):Eq(fval)</pre></li>
+        <li><pre class="example">Q(<span class="string">"fname"</span>, fval)</pre></li>
+        <li><pre class="example">Q():F(<span class="string">"fname"</span>, fval)</pre></li>
+    </ul>
 
+</dd>
+    <dt>
+    <a name = "Q:ElemMatch"></a>
+    <strong>Q:ElemMatch&nbsp;(val)</strong>
+    </dt>
+    <dd>
+    Element match construction.
+ - $elemMatch The $elemMatch operator matches more than one component within an array element.
+ -    { array: { $elemMatch: { value1 : 1, value2 : { $gt: 1 } } } }
+ Restriction: only one $elemMatch allowed in context of one array field.
 
     <h3>Parameters:</h3>
     <ul>
@@ -764,6 +1106,11 @@ end
 </li>
     </ul>
 
+    <h3>Returns:</h3>
+    <ol>
+
+        Self <a href="index.html#Q">Q</a>
+    </ol>
 
 
 
@@ -784,6 +1131,11 @@ end
 </li>
     </ul>
 
+    <h3>Returns:</h3>
+    <ol>
+
+        Self <a href="index.html#Q">Q</a>
+    </ol>
 
 
 
@@ -803,11 +1155,17 @@ end
     <h3>Parameters:</h3>
     <ul>
         <li><span class="parameter">val</span>
+            <span class="types"><span class="type">number</span></span>
 
 
 </li>
     </ul>
 
+    <h3>Returns:</h3>
+    <ol>
+
+        Self <a href="index.html#Q">Q</a>
+    </ol>
 
 
 
@@ -827,11 +1185,17 @@ end
     <h3>Parameters:</h3>
     <ul>
         <li><span class="parameter">val</span>
+            <span class="types"><span class="type">number</span></span>
 
 
 </li>
     </ul>
 
+    <h3>Returns:</h3>
+    <ol>
+
+        Self <a href="index.html#Q">Q</a>
+    </ol>
 
 
 
@@ -851,11 +1215,17 @@ end
     <h3>Parameters:</h3>
     <ul>
         <li><span class="parameter">val</span>
+            <span class="types"><span class="type">number</span></span>
 
 
 </li>
     </ul>
 
+    <h3>Returns:</h3>
+    <ol>
+
+        Self <a href="index.html#Q">Q</a>
+    </ol>
 
 
 
@@ -875,11 +1245,17 @@ end
     <h3>Parameters:</h3>
     <ul>
         <li><span class="parameter">val</span>
+            <span class="types"><span class="type">number</span></span>
 
 
 </li>
     </ul>
 
+    <h3>Returns:</h3>
+    <ol>
+
+        Self <a href="index.html#Q">Q</a>
+    </ol>
 
 
 
@@ -889,32 +1265,699 @@ end
     </ul>
 
 </dd>
-</dl>
-    <h2><a name="Tables"></a>Tables</h2>
-    <dl class="function">
     <dt>
-    <a name = "Q"></a>
-    <strong>Q</strong>
+    <a name = "Q:Icase"></a>
+    <strong>Q:Icase&nbsp;(val)</strong>
     </dt>
     <dd>
-    Query/JSON builder is used to create EJDB queries or JSON objects with
- preserverd keys order (Unlike lua tables). </p>
+    Case insensitive string matching
 
-<p> Examples:
+    <h3>Parameters:</h3>
+    <ul>
+        <li><span class="parameter">val</span>
+            <span class="types"><a class="type" href="http://www.lua.org/manual/5.1/manual.html#5.4">string</a>, <a class="type" href="http://www.lua.org/manual/5.1/manual.html#5.5">table</a> or <a class="type" href="index.html#Q">Q</a></span>
 
 
+</li>
+    </ul>
 
+    <h3>Returns:</h3>
+    <ol>
 
-    <h3>see also:</h3>
-    <ul>
-         <li><a href="index.html#Q:Eq">Q:Eq</a></li>
-         <li><a href="index.html#Q:ElemMatch">Q:ElemMatch</a></li>
-         <li><a href="index.html#Q:Not">Q:Not</a></li>
-         <li><a href="index.html#Q:Gt">Q:Gt</a></li>
-         <li><a href="index.html#Q:Gte">Q:Gte</a></li>
-         <li><a href="index.html#Q:Lt">Q:Lt</a></li>
-         <li><a href="index.html#Q:Lte">Q:Lte</a></li>
-    </ul>
+        Self <a href="index.html#Q">Q</a>
+    </ol>
+
+
+
+    <h3>Usage:</h3>
+    <ul>
+        <li><pre class="example">Q():F(<span class="string">"name"</span>):Icase(<span class="string">"aNdY"</span>) =&gt; {<span class="string">"name"</span> : {<span class="string">"$icase"</span> : <span class="string">"aNdY"</span>}}</pre></li>
+        <li><pre class="example">Q():F(<span class="string">"name"</span>):Icase({[$<span class="keyword">in</span>] = {<span class="string">"aNdY"</span>, <span class="string">"AnTon"</span>}}) =&gt; {<span class="string">"name"</span> : {<span class="string">"$icase"</span> : {<span class="string">"$in"</span> : [<span class="string">"aNdY"</span>, <span class="string">"AnTon"</span>]}}}</pre></li>
+    </ul>
+
+</dd>
+    <dt>
+    <a name = "Q:Begin"></a>
+    <strong>Q:Begin&nbsp;(val)</strong>
+    </dt>
+    <dd>
+    String starts with prefix
+
+    <h3>Parameters:</h3>
+    <ul>
+        <li><span class="parameter">val</span>
+            <span class="types"><a class="type" href="http://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
+
+
+</li>
+    </ul>
+
+    <h3>Returns:</h3>
+    <ol>
+
+        Self <a href="index.html#Q">Q</a>
+    </ol>
+
+
+
+    <h3>Usage:</h3>
+    <ul>
+        <pre class="example">Q():F(<span class="string">"fpath"</span>):Begin(<span class="string">"prefix"</span>) =&gt; {<span class="string">"fpath"</span> : {<span class="string">"$begin"</span> : <span class="string">"prefix"</span>}}</pre>
+    </ul>
+
+</dd>
+    <dt>
+    <a name = "Q:In"></a>
+    <strong>Q:In&nbsp;(val)</strong>
+    </dt>
+    <dd>
+    Field value matched any value of specified in <code>val</code> table.
+
+    <h3>Parameters:</h3>
+    <ul>
+        <li><span class="parameter">val</span>
+            <span class="types"><a class="type" href="http://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
+          Not empty lua array of values.</li>
+    </ul>
+
+    <h3>Returns:</h3>
+    <ol>
+
+        Self <a href="index.html#Q">Q</a>
+    </ol>
+
+
+
+    <h3>Usage:</h3>
+    <ul>
+        <pre class="example">Q():F(<span class="string">"fpath"</span>):In({<span class="string">"val1"</span>, <span class="string">"val2"</span>, <span class="string">"val3"</span>}) =&gt; {<span class="string">"fpath"</span> : {<span class="string">"$in"</span> : [<span class="string">"val1"</span>, <span class="string">"val2"</span>, <span class="string">"val3"</span>]}}</pre>
+    </ul>
+
+</dd>
+    <dt>
+    <a name = "Q:NotIn"></a>
+    <strong>Q:NotIn&nbsp;(val)</strong>
+    </dt>
+    <dd>
+    Negation of <a href="index.html#Q:In">Q:In</a>
+
+    <h3>Parameters:</h3>
+    <ul>
+        <li><span class="parameter">val</span>
+
+
+</li>
+    </ul>
+
+    <h3>Returns:</h3>
+    <ol>
+
+        Self <a href="index.html#Q">Q</a>
+    </ol>
+
+
+    <h3>see also:</h3>
+    <ul>
+         <a href="index.html#Q:In">Q:In</a>
+    </ul>
+
+
+</dd>
+    <dt>
+    <a name = "Q:Bt"></a>
+    <strong>Q:Bt&nbsp;(n1, n2)</strong>
+    </dt>
+    <dd>
+    Between for number types
+
+    <h3>Parameters:</h3>
+    <ul>
+        <li><span class="parameter">n1</span>
+            <span class="types"><span class="type">number</span></span>
+
+
+</li>
+        <li><span class="parameter">n2</span>
+            <span class="types"><span class="type">number</span></span>
+
+
+</li>
+    </ul>
+
+    <h3>Returns:</h3>
+    <ol>
+
+        Self <a href="index.html#Q">Q</a>
+    </ol>
+
+
+
+    <h3>Usage:</h3>
+    <ul>
+        <pre class="example">Q():F(<span class="string">"age"</span>):Bt(<span class="number">10</span>, <span class="number">20</span>) =&gt; {<span class="string">"age"</span> : {<span class="string">"$bt"</span> : [<span class="number">10</span>, <span class="number">20</span>]}}</pre>
+    </ul>
+
+</dd>
+    <dt>
+    <a name = "Q:StrAnd"></a>
+    <strong>Q:StrAnd&nbsp;(val)</strong>
+    </dt>
+    <dd>
+    String tokens(or string array vals) matches <strong>all</strong> tokens in specified <code>val</code> array.
+
+    <h3>Parameters:</h3>
+    <ul>
+        <li><span class="parameter">val</span>
+            <span class="types"><a class="type" href="http://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
+         Array of tokens to match.</li>
+    </ul>
+
+    <h3>Returns:</h3>
+    <ol>
+
+        Self <a href="index.html#Q">Q</a>
+    </ol>
+
+
+
+    <h3>Usage:</h3>
+    <ul>
+        <pre class="example">Q():F(<span class="string">"description"</span>):StrAnd({<span class="string">"foo"</span>, <span class="string">"bar"</span>}) -- descripton contains all tokens: <span class="string">'foo'</span> <span class="keyword">and</span> <span class="string">'bar'</span></pre>
+    </ul>
+
+</dd>
+    <dt>
+    <a name = "Q:StrOr"></a>
+    <strong>Q:StrOr&nbsp;(val)</strong>
+    </dt>
+    <dd>
+    String tokens(or string array vals) matches <strong>any</strong> token in specified array.
+
+    <h3>Parameters:</h3>
+    <ul>
+        <li><span class="parameter">val</span>
+            <span class="types"><a class="type" href="http://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
+         Array of tokens to match.</li>
+    </ul>
+
+    <h3>Returns:</h3>
+    <ol>
+
+        Self <a href="index.html#Q">Q</a>
+    </ol>
+
+
+
+    <h3>Usage:</h3>
+    <ul>
+        <pre class="example">Q():F(<span class="string">"description"</span>):StrOr({<span class="string">"foo"</span>, <span class="string">"bar"</span>}) -- descripton contains all tokens: <span class="string">'foo'</span> <span class="keyword">or</span> <span class="string">'bar'</span></pre>
+    </ul>
+
+</dd>
+    <dt>
+    <a name = "Q:Inc"></a>
+    <strong>Q:Inc&nbsp;(val)</strong>
+    </dt>
+    <dd>
+    Increment current field.  Only number types are supported.
+
+    <h3>Parameters:</h3>
+    <ul>
+        <li><span class="parameter">val</span>
+            <span class="types"><span class="type">number</span></span>
+
+
+</li>
+    </ul>
+
+    <h3>Returns:</h3>
+    <ol>
+
+        Self <a href="index.html#Q">Q</a>
+    </ol>
+
+
+    <h3>see also:</h3>
+    <ul>
+         <a href="index.html#Q:F">Q:F</a>
+    </ul>
+
+    <h3>Usage:</h3>
+    <ul>
+        <pre class="example">Q():F(<span class="string">"count"</span>):Inc(<span class="number">1</span>):F(<span class="string">"age"</span>):Inc(-<span class="number">20</span>) =&gt; {<span class="string">"$inc"</span> : {<span class="string">"count"</span> : <span class="number">1</span>, <span class="string">"age"</span> : -<span class="number">20</span>}}</pre>
+    </ul>
+
+</dd>
+    <dt>
+    <a name = "Q:Set"></a>
+    <strong>Q:Set&nbsp;(val)</strong>
+    </dt>
+    <dd>
+    Set fields to values.
+
+    <h3>Parameters:</h3>
+    <ul>
+        <li><span class="parameter">val</span>
+            <span class="types"><a class="type" href="http://www.lua.org/manual/5.1/manual.html#5.5">table</a> or <a class="type" href="index.html#Q">Q</a></span>
+         Table of fields to set</li>
+    </ul>
+
+    <h3>Returns:</h3>
+    <ol>
+
+        Self <a href="index.html#Q">Q</a>
+    </ol>
+
+
+
+    <h3>Usage:</h3>
+    <ul>
+        <pre class="example">Q():Set({age = <span class="number">20</span>, count = <span class="number">1</span>}) =&gt; {<span class="string">"$set"</span> : {<span class="string">"age"</span> : <span class="number">20</span>, count : <span class="number">1</span>}}</pre>
+    </ul>
+
+</dd>
+    <dt>
+    <a name = "Q:Upsert"></a>
+    <strong>Q:Upsert&nbsp;(val)</strong>
+    </dt>
+    <dd>
+    Atomic upsert.
+ If matching records are found it will be <code>$set</code> operation,
+ otherwise new record will be inserted with fields specified by <code>val</code> table.
+
+    <h3>Parameters:</h3>
+    <ul>
+        <li><span class="parameter">val</span>
+            <span class="types"><a class="type" href="http://www.lua.org/manual/5.1/manual.html#5.5">table</a> or <a class="type" href="index.html#Q">Q</a></span>
+         Table of fields to set/insert
+ Insert {"foo" : "bar"} if this object does not exists:</li>
+    </ul>
+
+    <h3>Returns:</h3>
+    <ol>
+
+        Self <a href="index.html#Q">Q</a>
+    </ol>
+
+
+
+    <h3>Usage:</h3>
+    <ul>
+        <li><pre class="example">Q(<span class="string">"foo"</span>,<span class="string">"bar"</span>):Upsert(Q(<span class="string">"foo"</span>, <span class="string">"bar"</span>)) =&gt; {<span class="string">"foo"</span> : <span class="string">"bar"</span>, <span class="string">"$upsert"</span> : {<span class="string">"foo"</span> : <span class="string">"bar"</span>}}</pre></li>
+        <li><pre class="example">Q(<span class="string">"foo"</span>,<span class="string">"bar"</span>):Upsert({foo =<span class="string">"bar"</span>}) =&gt; {<span class="string">"foo"</span> : <span class="string">"bar"</span>, <span class="string">"$upsert"</span> : {<span class="string">"foo"</span> : <span class="string">"bar"</span>}}</pre></li>
+    </ul>
+
+</dd>
+    <dt>
+    <a name = "Q:AddToSet"></a>
+    <strong>Q:AddToSet&nbsp;(val)</strong>
+    </dt>
+    <dd>
+    Atomically adds <code>val</code> to the <code>array field</code> only if <code>val</code> not in the array already.
+ If containing array is missing it will be created.
+
+    <h3>Parameters:</h3>
+    <ul>
+        <li><span class="parameter">val</span>
+         Value to add</li>
+    </ul>
+
+    <h3>Returns:</h3>
+    <ol>
+
+        Self <a href="index.html#Q">Q</a>
+    </ol>
+
+
+
+    <h3>Usage:</h3>
+    <ul>
+        <pre class="example">Q():F(<span class="string">"tags"</span>):AddToSet(<span class="string">"red"</span>) =&gt; {<span class="string">"$addToSet"</span> : {<span class="string">"tags"</span> : <span class="string">"red"</span>}}</pre>
+    </ul>
+
+</dd>
+    <dt>
+    <a name = "Q:AddToSetAll"></a>
+    <strong>Q:AddToSetAll&nbsp;(val)</strong>
+    </dt>
+    <dd>
+    Atomically performs <code>set union</code> with values in <code>val</code> for specified array field.
+
+    <h3>Parameters:</h3>
+    <ul>
+        <li><span class="parameter">val</span>
+            <span class="types"><a class="type" href="http://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
+         Array of values to add</li>
+    </ul>
+
+    <h3>Returns:</h3>
+    <ol>
+
+        Self <a href="index.html#Q">Q</a>
+    </ol>
+
+
+    <h3>see also:</h3>
+    <ul>
+         <a href="index.html#Q:F">Q:F</a>
+    </ul>
+
+    <h3>Usage:</h3>
+    <ul>
+        <pre class="example">Q():F(<span class="string">"tags"</span>):AddToSetAll({<span class="string">"red"</span>, <span class="string">"green"</span>})</pre>
+    </ul>
+
+</dd>
+    <dt>
+    <a name = "Q:Pull"></a>
+    <strong>Q:Pull&nbsp;(val)</strong>
+    </dt>
+    <dd>
+    Atomically removes all occurrences of <code>val</code> from field, if field is an array.
+
+    <h3>Parameters:</h3>
+    <ul>
+        <li><span class="parameter">val</span>
+         Value to remove</li>
+    </ul>
+
+    <h3>Returns:</h3>
+    <ol>
+
+        Self <a href="index.html#Q">Q</a>
+    </ol>
+
+
+    <h3>see also:</h3>
+    <ul>
+         <a href="index.html#Q:F">Q:F</a>
+    </ul>
+
+    <h3>Usage:</h3>
+    <ul>
+        <pre class="example">Q():F(<span class="string">"tags"</span>):Pull(<span class="string">"red"</span>) =&gt; {<span class="string">"$pull"</span> : {<span class="string">"tags"</span> : <span class="string">"red"</span>}}</pre>
+    </ul>
+
+</dd>
+    <dt>
+    <a name = "Q:PullAll"></a>
+    <strong>Q:PullAll&nbsp;(val)</strong>
+    </dt>
+    <dd>
+    Atomically performs <code>set substraction</code> of values in <code>val</code> for specified array field.
+
+    <h3>Parameters:</h3>
+    <ul>
+        <li><span class="parameter">val</span>
+            <span class="types"><a class="type" href="http://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
+         Array of values to remove from array field</li>
+    </ul>
+
+    <h3>Returns:</h3>
+    <ol>
+
+        Self <a href="index.html#Q">Q</a>
+    </ol>
+
+
+    <h3>see also:</h3>
+    <ul>
+         <a href="index.html#Q:F">Q:F</a>
+    </ul>
+
+    <h3>Usage:</h3>
+    <ul>
+        <pre class="example">Q():F(<span class="string">"tags"</span>):PullAll({<span class="string">"red"</span>, <span class="string">"green"</span>}) =&gt; {<span class="string">"$pullAll"</span> : {<span class="string">"tags"</span> : [<span class="string">"red"</span>, <span class="string">"green"</span>]}}</pre>
+    </ul>
+
+</dd>
+    <dt>
+    <a name = "Q:DropAll"></a>
+    <strong>Q:DropAll&nbsp;()</strong>
+    </dt>
+    <dd>
+    In-place record removal operation.
+
+
+    <h3>Returns:</h3>
+    <ol>
+
+        Self <a href="index.html#Q">Q</a>
+    </ol>
+
+
+
+    <h3>Usage:</h3>
+    <ul>
+        <pre class="example">db:update(Q():F(<span class="string">"name"</span>, <span class="string">"andy"</span>):DropAll()) -- Removes all records with name eq <span class="string">'andy'</span></pre>
+    </ul>
+
+</dd>
+    <dt>
+    <a name = "Q:Join"></a>
+    <strong>Q:Join&nbsp;(cname, fpath)</strong>
+    </dt>
+    <dd>
+    Make <a href="https://github.com/Softmotions/ejdb/wiki/Collection-joins">collection join</a>
+ for select queries.
+
+    <h3>Parameters:</h3>
+    <ul>
+        <li><span class="parameter">cname</span>
+            <span class="types"><a class="type" href="http://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
+         Name for joined collection</li>
+        <li><span class="parameter">fpath</span>
+            <span class="types"><a class="type" href="http://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
+         Name of field with BSON OIDs of joined objects</li>
+    </ul>
+
+    <h3>Returns:</h3>
+    <ol>
+
+        Self <a href="index.html#Q">Q</a>
+    </ol>
+
+
+
+
+</dd>
+    <dt>
+    <a name = "Q:Or"></a>
+    <strong>Q:Or&nbsp;(...)</strong>
+    </dt>
+    <dd>
+    Add <em>OR</em> joined query restrictions.
+
+    <h3>Parameters:</h3>
+    <ul>
+        <li><span class="parameter">...</span>
+            <span class="types"><a class="type" href="http://www.lua.org/manual/5.1/manual.html#5.5">table</a> or <a class="type" href="index.html#Q">Q</a></span>
+         List of OR joined restrictions</li>
+    </ul>
+
+    <h3>Returns:</h3>
+    <ol>
+
+        Self <a href="index.html#Q">Q</a>
+    </ol>
+
+
+
+    <h3>Usage:</h3>
+    <ul>
+        <pre class="example">Q():Or(Q(<span class="string">"name"</span>, <span class="string">"anton"</span>), Q(<span class="string">"name"</span>, <span class="string">"andy"</span>))
+    Find records with <span class="string">"name"</span> field eq <span class="string">"anton"</span> <span class="keyword">or</span> <span class="string">"andy"</span></pre>
+    </ul>
+
+</dd>
+    <dt>
+    <a name = "Q:Skip"></a>
+    <strong>Q:Skip&nbsp;(val)</strong>
+    </dt>
+    <dd>
+    Sets number of skipped records in the result set.
+
+    <h3>Parameters:</h3>
+    <ul>
+        <li><span class="parameter">val</span>
+            <span class="types"><span class="type">number</span></span>
+
+
+</li>
+    </ul>
+
+    <h3>Returns:</h3>
+    <ol>
+
+        Self <a href="index.html#Q">Q</a>
+    </ol>
+
+
+
+
+</dd>
+    <dt>
+    <a name = "Q:Max"></a>
+    <strong>Q:Max&nbsp;(val)</strong>
+    </dt>
+    <dd>
+    Sets max number of records in the result set.
+
+    <h3>Parameters:</h3>
+    <ul>
+        <li><span class="parameter">val</span>
+            <span class="types"><span class="type">number</span></span>
+
+
+</li>
+    </ul>
+
+    <h3>Returns:</h3>
+    <ol>
+
+        Self <a href="index.html#Q">Q</a>
+    </ol>
+
+
+
+
+</dd>
+    <dt>
+    <a name = "Q:OrderBy"></a>
+    <strong>Q:OrderBy&nbsp;(...)</strong>
+    </dt>
+    <dd>
+    Set sorting rules for query results.
+ tparam table|string
+
+    <h3>Parameters:</h3>
+    <ul>
+        <li><span class="parameter">...</span>
+
+
+</li>
+    </ul>
+
+
+
+
+    <h3>Usage:</h3>
+    <ul>
+        <li><pre class="example">Q:OrderBy(<span class="string">"name asc"</span>, <span class="string">"age desc"</span>) =&gt; ORDER BY name ASC, age dESC</pre></li>
+        <li><pre class="example">Q:OrderBy({name = <span class="number">1</span>}, {age = -<span class="number">1</span>}) =&gt; ORDER BY name ASC, age dESC</pre></li>
+    </ul>
+
+</dd>
+    <dt>
+    <a name = "Q:Fields"></a>
+    <strong>Q:Fields&nbsp;(...)</strong>
+    </dt>
+    <dd>
+    Sets fields to be included in resulting objects.
+ If field presented in $orderby clause it will be forced to include in resulting records.
+
+    <h3>Parameters:</h3>
+    <ul>
+        <li><span class="parameter">...</span>
+            <span class="types"><a class="type" href="http://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
+         Fields to be included in fetched objects.</li>
+    </ul>
+
+    <h3>Returns:</h3>
+    <ol>
+
+        Self <a href="index.html#Q">Q</a>
+    </ol>
+
+
+
+    <h3>Usage:</h3>
+    <ul>
+        <pre class="example">Q:Fields(<span class="string">"name"</span>, <span class="string">"age"</span>)</pre>
+    </ul>
+
+</dd>
+    <dt>
+    <a name = "Q:NotFields"></a>
+    <strong>Q:NotFields&nbsp;(...)</strong>
+    </dt>
+    <dd>
+    Sets fields to be excluded from resulting objects.
+
+    <h3>Parameters:</h3>
+    <ul>
+        <li><span class="parameter">...</span>
+            <span class="types"><a class="type" href="http://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
+         Fields to be excluded from fetched objects.</li>
+    </ul>
+
+    <h3>Returns:</h3>
+    <ol>
+
+        Self <a href="index.html#Q">Q</a>
+    </ol>
+
+
+
+    <h3>Usage:</h3>
+    <ul>
+        <pre class="example">Q:NotFields(<span class="string">"name"</span>, <span class="string">"description"</span>)</pre>
+    </ul>
+
+</dd>
+</dl>
+    <h2><a name="Tables"></a>Tables</h2>
+    <dl class="function">
+    <dt>
+    <a name = "Q"></a>
+    <strong>Q</strong>
+    </dt>
+    <dd>
+    Query/JSON builder is used to create EJDB queries or JSON objects with
+ preserverd keys order (Unlike lua tables).
+ <a href="index.html#Q">Q</a> <strong>can be used to construct BSON objects as well as queries.</strong></p>
+
+<p> Examples:
+
+
+
+
+    <h3>see also:</h3>
+    <ul>
+         <li><a href="index.html#Q:F">Q:F</a></li>
+         <li><a href="index.html#Q:Eq">Q:Eq</a></li>
+         <li><a href="index.html#Q:ElemMatch">Q:ElemMatch</a></li>
+         <li><a href="index.html#Q:Not">Q:Not</a></li>
+         <li><a href="index.html#Q:Gt">Q:Gt</a></li>
+         <li><a href="index.html#Q:Gte">Q:Gte</a></li>
+         <li><a href="index.html#Q:Lt">Q:Lt</a></li>
+         <li><a href="index.html#Q:Lte">Q:Lte</a></li>
+         <li><a href="index.html#Q:Icase">Q:Icase</a></li>
+         <li><a href="index.html#Q:Begin">Q:Begin</a></li>
+         <li><a href="index.html#Q:In">Q:In</a></li>
+         <li><a href="index.html#Q:NotIn">Q:NotIn</a></li>
+         <li><a href="index.html#Q:Bt">Q:Bt</a></li>
+         <li><a href="index.html#Q:StrAnd">Q:StrAnd</a></li>
+         <li><a href="index.html#Q:StrOr">Q:StrOr</a></li>
+         <li><a href="index.html#Q:Inc">Q:Inc</a></li>
+         <li><a href="index.html#Q:Set">Q:Set</a></li>
+         <li><a href="index.html#Q:AddToSet">Q:AddToSet</a></li>
+         <li><a href="index.html#Q:AddToSetAll">Q:AddToSetAll</a></li>
+         <li><a href="index.html#Q:Pull">Q:Pull</a></li>
+         <li><a href="index.html#Q:PullAll">Q:PullAll</a></li>
+         <li><a href="index.html#Q:Upsert">Q:Upsert</a></li>
+         <li><a href="index.html#Q:Upsert">Q:Upsert</a></li>
+         <li><a href="index.html#Q:DropAll">Q:DropAll</a></li>
+         <li><a href="index.html#Q:Join">Q:Join</a></li>
+         <li><a href="index.html#Q:Or">Q:Or</a></li>
+         <li><a href="index.html#Q:Skip">Q:Skip</a></li>
+         <li><a href="index.html#Q:Skip">Q:Skip</a></li>
+         <li><a href="index.html#Q:Max">Q:Max</a></li>
+         <li><a href="index.html#Q:OrderBy">Q:OrderBy</a></li>
+         <li><a href="index.html#Q:Fields">Q:Fields</a></li>
+         <li><a href="index.html#Q:Fields">Q:Fields</a></li>
+         <li><a href="index.html#Q:NotFields">Q:NotFields</a></li>
+    </ul>
 
     <h3>Usage:</h3>
     <ul>
@@ -938,6 +1981,59 @@ end
 
 
 </dd>
+    <dt>
+    <a name = "RS"></a>
+    <strong>RS</strong>
+    </dt>
+    <dd>
+
+<p>Result set cursor object.
+ Usage:</p>
+<pre><code>#res - length of result set
+res[i] - BSON representations of object as lua string
+res:object(i) - Lua table constructed from BSON data
+res:field(i, &lt;field name&gt;) - Lua value of fetched BSON object
+res() - Creates iterator for pairs (obj, idx)
+      where obj - Lua table constructed from BSON data
+            idx - Index of fetched object in the result set
+</code></pre>
+
+<p> Examples:</p>
+<pre><code>for i = 1, #res do
+  local ob = res:object(i)
+  ...
+end
+</code></pre>
+
+<p> OR</p>
+
+<pre><code>for i = 1, #res do
+  res:field(i, "json field name")
+  ...
+end
+</code></pre>
+
+<p> OR</p>
+
+<pre><code>for vobj, idx in res() do
+  -- vobj is a lua table representation of fetched json object
+  vobj["json field name"]
+  ...
+end
+</code></pre>
+
+
+
+
+
+    <h3>see also:</h3>
+    <ul>
+         <li><a href="index.html#RS:object">RS:object</a></li>
+         <li><a href="index.html#RS:field">RS:field</a></li>
+    </ul>
+
+
+</dd>
 </dl>
 
 
index b294c99..25be60f 100644 (file)
@@ -260,16 +260,17 @@ function B:_init(fname, ...)
   return self
 end
 
-function B:_checkop()
+function B:_checkOp()
   assert(type(self._field) == "string")
 end
 
-function B:_setop(op, val, ...)
-  self:_checkop()
+function B:_setOp(op, val, ...)
+  self:_checkOp()
   local types, replace = ...
   local ttypes = type(types)
   if (ttypes == "string") then
-    assert(type(val) == types, "Invalid query argument field: " .. self._field .. " val: " .. inspect(val))
+    assert(type(val) == types, "Invalid query argument field: " .. self._field ..
+                               " It should have '" .. types .. "' type," .. " got: " .. inspect(val))
   elseif (ttypes == "function") then
     assert(types(val), "Invalid query argument field: " .. self._field .. " val: " .. inspect(val))
   elseif (ttypes == "table") then
@@ -296,12 +297,33 @@ function B:_setop(op, val, ...)
   elseif replace then
     for i = 2, #olist do olist[i] = nil end
   end
-  if (op == nil) then
+  if op == nil then
     table.insert(olist, setmetatable({ val }, mtBVal))
   else
-    table.insert(olist, { op, val })
+    local found = false
+    for i = 2, #olist do
+      if olist[i][1] == op then -- found previous added op
+        found = true
+        olist[i][2] = val -- replace old value
+        break
+      end
+    end
+    if not found then
+      table.insert(olist, { op, val })
+    end
   end
   self._bson = nil
+  return self
+end
+
+function B:_invertOp(op, val, ...)
+  local pf = self._field;
+  assert(type(op) == "string", "Operation must be a string")
+  assert(type(pf) == "string", "You should set field before by Q:F('fname')")
+  self._field = op
+  self:_setOp(pf, val, ...)
+  self._field = pf
+  return self
 end
 
 function B:_toOpVal(op, val)
@@ -317,12 +339,13 @@ function B:_hintOp(op, val, ...)
     self._hints = B()
   end
   self._hints:_rootOp(op, val, ...)
+  return self
 end
 
 function B:_rootOp(name, val, ...)
   local types = ...
   self:F(name)
-  self:_setop(nil, val, types, true)
+  self:_setOp(nil, val, types, true)
   self:F(nil)
   return self
 end
@@ -340,55 +363,61 @@ end
 -- Generic key=value
 function B:KV(key, val)
   self:F(key);
-  self:_setop(nil, val, nil, true)
+  self:_setOp(nil, val, nil, true)
   return self
 end
 
-function B:Eq(val) self:_setop(nil, val, nil, true) return self end
+function B:Eq(val) return self:_setOp(nil, val, nil, true) end
 
-function B:ElemMatch(val) self:_setop("$elemMatch", val) return self end
+function B:ElemMatch(val) return self:_setOp("$elemMatch", val) end
 
-function B:Not(val) self:_setop("$not", val) return self end
+function B:Not(val) return self:_setOp("$not", val) end
 
-function B:Gt(val) self:_setop("$gt", val) return self end
+function B:Gt(val) return self:_setOp("$gt", val, "number") end
 
-function B:Gte(val) self:_setop("$gte", val) return self end
+function B:Gte(val) return self:_setOp("$gte", val, "number") end
 
-function B:Lt(val) self:_setop("$lt", val) return self end
+function B:Lt(val) return self:_setOp("$lt", val, "number") end
 
-function B:Lte(val) self:_setop("$lte", val) return self end
+function B:Lte(val) return self:_setOp("$lte", val, "number") end
 
-function B:Icase(val) self:_setop("$icase", val) return self end
+function B:Icase(val) return self:_setOp("$icase", val) end
 
-function B:Begin(val) self:_setop("$begin", val) return self end
+function B:Begin(val) return self:_setOp("$begin", val, "string") end
 
-function B:In(val) self:_setop("$in", val) return self end
+function B:In(val) return self:_setOp("$in", val, "table") end
 
-function B:NotIn(val) self:_setop("$nin", val) return self end
+function B:NotIn(val) return self:_setOp("$nin", val, "table") end
 
-function B:Bt(val) self:_setop("$bt", val) return self end
+function B:Bt(n1, n2) return self:_setOp("$bt", { n1, n2 }) end
 
-function B:StrAnd(val) self:_setop("$strand", val) return self end
+function B:StrAnd(val) return self:_setOp("$strand", val, "table") end
 
-function B:StrOr(val) self:_setop("$strand", val) return self end
+function B:StrOr(val) return self:_setOp("$stror", val, "table") end
 
-function B:Inc(val) self:_setop("$inc", val) return self end
+function B:Inc(val) return self:_invertOp("$inc", val, "number") end
 
-function B:Set(val) return self:_rootOp("$set", val) end
+function B:Set(val) return self:_rootOp("$set", val, "table") end
 
-function B:AddToSet(val) return self:_rootOp("$addToSet", val) end
+function B:AddToSet(val) return self:_invertOp("$addToSet", val) end
 
-function B:AddToSetAll(val) return self:_rootOp("$addToSetAll", val) end
+function B:AddToSetAll(val) return self:_invertOp("$addToSetAll", val, "table") end
 
-function B:Pull(val) return self:_rootOp("$pull", val) end
+function B:Pull(val) return self:_invertOp("$pull", val) end
 
-function B:PullAll(val) return self:_rootOp("$pullAll", val) end
+function B:PullAll(val) return self:_invertOp("$pullAll", val, "table")  end
 
-function B:Upsert(val) return self:_rootOp("$upsert", val) end
+function B:Upsert(val) return self:_rootOp("$upsert", val, "table") end
 
 function B:DropAll() return self:_rootOp("$dropall", true) end
 
-function B:Do(val) return self:_rootOp("$do", val) end
+function B:Do(val) return self:_rootOp("$do", val, "table") end
+
+function B:Join(cname, fpath)
+  assert(type(cname) == "string", "Type of #1 arg must be string")
+  assert(type(fpath) == "string", "Type of #2 arg must be string")
+  return self:_rootOp("$do", { [fpath] = { ["join"] = cname } })
+end
 
 function B:Or(...)
   self._or = self._or or {}
index 2246f83..d0e3022 100644 (file)
@@ -7,6 +7,7 @@ local ejdb = {}
 
 --- Query/JSON builder is used to create EJDB queries or JSON objects with
 -- preserverd keys order (Unlike lua tables).
+-- @{Q} **can be used to construct BSON objects as well as queries.**
 -- @class table
 -- @name Q
 --
@@ -15,6 +16,7 @@ local ejdb = {}
 -- @usage Q("likes", "toys"):OrderBy("name asc", "age desc")
 -- @usage Q("name", "Andy"):F("_id"):Eq("510f7fa91ad6270a00000000"):F("age"):Gt(20):Lt(40):F("score"):In({ 11, 22.12333, 1362835380447, db.toNull() }):Max(232)
 -- @usage Q():Or(Q("foo", "bar"), Q("foo", "bar6")):OrderBy({ foo = 1 })
+-- @see Q:F
 -- @see Q:Eq
 -- @see Q:ElemMatch
 -- @see Q:Not
@@ -38,7 +40,7 @@ local ejdb = {}
 -- @see Q:Upsert
 -- @see Q:Upsert
 -- @see Q:DropAll
--- @see Q:Do
+-- @see Q:Join
 -- @see Q:Or
 -- @see Q:Skip
 -- @see Q:Skip
@@ -56,10 +58,47 @@ local Q = {}
 -- @name DB
 local DB = {}
 
+---
+-- Result set cursor object.
+-- @class table
+-- @name RS
+-- Usage:
+--    #res - length of result set
+--    res[i] - BSON representations of object as lua string
+--    res:object(i) - Lua table constructed from BSON data
+--    res:field(i, <field name>) - Lua value of fetched BSON object
+--    res() - Creates iterator for pairs (obj, idx)
+--          where obj - Lua table constructed from BSON data
+--                idx - Index of fetched object in the result set
+--
+-- Examples:
+--    for i = 1, #res do
+--      local ob = res:object(i)
+--      ...
+--    end
+--
+-- OR
+--
+--    for i = 1, #res do
+--      res:field(i, "json field name")
+--      ...
+--    end
+--
+-- OR
+--
+--    for vobj, idx in res() do
+--      -- vobj is a lua table representation of fetched json object
+--      vobj["json field name"]
+--      ...
+--    end
+-- @see RS:object
+-- @see RS:field
+local RS = {}
+
 --- Opens EJDB database.
 -- @usage local db = ejdb.open("foodb", "wrc")
--- @param path {String} Database main file
--- @param mode {String?} Database open mode flags:<br/>
+-- @tparam string path Database main file
+-- @tparam ?string mode Database open mode flags:<br/>
 -- <code>`w`</code> Open as a writer <br/>
 -- <code>`r`</code> Open as a reader <br/>
 -- <code>`c`</code> Create db if it not exists <br/>
@@ -74,7 +113,7 @@ function ejdb.open(path, mode) end
 function ejdb.close() end
 
 --- Converts string OID into BSON oid table.
--- @param val {String} 24 hex chars BSON_OID
+-- @tparam string val 24 hex chars BSON_OID
 function ejdb.toOID(val) end
 
 --- Converts os.time table (or number of seconds since epoch) into BSON_DATE.
@@ -87,8 +126,8 @@ function ejdb.toDate(val) end
 function ejdb.toDateNow() end
 
 --- Builds BSON_REGEX value
--- @param re {String} Regular expression
--- @param opts {String} Regular expression flags
+-- @tparam string re Regular expression
+-- @tparam ?string opts Regular expression flags
 -- @return BSON_REGEX table value
 function ejdb.toRegexp(re, opts) end
 
@@ -137,8 +176,8 @@ function DB.toUndefined() end
 -- Each persistent object has unique identifier (OID) placed in the `_id` property.
 -- If a saved object does not have `_id` it will be autogenerated.
 -- To identify and update object it should contains `_id` property.
--- @param cname {String} Name of collection.
--- @param obj Lua table or <a href="#Q">Q</a> represents JSON object.
+-- @tparam string cname Name of collection.
+-- @tparam table|Q obj represents JSON object.
 -- @param ... If last argument is True a saved object will be merged with who's
 -- already persisted in db.
 -- @usage dQ:save("parrots2", {foo = "bar"})
@@ -148,7 +187,9 @@ function DB:save(cname, obj, ...) end
 --- Execute query on collection.
 --
 -- EJDB queries inspired by MongoDB (mongodb.org) and follows same philosophy.
--- - Supported queries:
+--
+-- Queries and query hints can be constructed by @{Q} query/json builder.
+--    - Supported queries:
 --    - Simple matching of String OR Number OR Array value:
 --        -   {'fpath' : 'val', ...}
 --    - $not Negate operation.
@@ -206,19 +247,20 @@ function DB:save(cname, obj, ...) end
 --         Where 'fpath' value points to object's OIDs from 'collectionname'. Its value
 --         can be OID, string representation of OID or array of this pointers.
 --
---  NOTE: It is better to execute update queries with `$onlycount=true` hint flag
+--  **NOTE:** It is better to execute update queries with `$onlycount=true` hint flag
 --        or use the special `update()` method to avoid unnecessarily data fetching.
---  NOTE: Negate operations: $not and $nin not using indexes
+--
+--  **NOTE:** Negate operations: $not and $nin not using indexes
 --        so they can be slow in comparison to other matching operations.
---  NOTE: Only one index can be used in search query operation.
---  NOTE: If callback is not provided this function will be synchronous.
 --
---  QUERY HINTS (specified by `hints` argument):
+--  **NOTE:** Only one index can be used in search query operation.
+--
+--  **NOTE:** If callback is not provided this function will be synchronous.
+--
+--  **QUERY HINTS** specified by calling @{Q:Skip} @{Q:Max}, @{Q:OrderBy}, @{Q:Fields}:
 --    - $max Maximum number in the result set
 --    - $skip Number of skipped results in the result set
 --    - $orderby Sorting order of query fields.
---    - $onlycount true|false If `true` only count of matching records will be returned
---                            without placing records in result set.
 --    - $fields Set subset of fetched fields.
 --        If field presented in $orderby clause it will be forced to include in resulting records.
 --        Example:
@@ -264,88 +306,254 @@ function DB:save(cname, obj, ...) end
 --    end
 --
 --
--- @param cname {String} Name of collection
--- @param q {table|Q} JSON query object
+-- @tparam string cname Name of collection
+-- @tparam Q q JSON query object
+-- @string flags Query control flags:
+--    `c`: only count of matching records will be returned without placing records in result set.
+--    `l`: return query execution log
+-- @treturn RS result set, it will be `nil` if `c` flag presented in the control `flags`
+-- @treturn number Count of matched/updated records
+-- @treturn ?string Query execution log if `l` flag presented in the control `flags`
+-- @usage db:find("mycoll", Q("foo", "bar")) => {"foo" : "bar"}
+-- @usage db:find("mycoll", Q("foo", "bar"):Max(10)) -- Limit results up to 10 records
+-- @usage db:find("parrots2", Q("likes", "toys"):OrderBy("name asc", "age desc"))
+-- @usage db:find("parrots2", Q():F("likes"):Eq("toys"):OrderBy({ name = 1 }, { age = -1 }))
 -- @see Q
 --
-function DB:find(cname, q, ...) end
+function DB:find(cname, q, flags) end
+
+--- Same as @{DB:find} but retrieves only first matching JSON object.
+-- @tparam string cname Name of collection
+-- @tparam Q q JSON query object
+-- @treturn table Lua table constructed from matched BSON record or `nil` of record not found
+-- @treturn number Count of matched/updated records
+-- @treturn ?string Query execution log if `l` flag presented in the control `flags`
+
+function DB:findOne(cname, q, ...) end
+
+--- Convenient method to execute update queries.
+-- @tparam string cname Name of collection
+-- @tparam Q q JSON query object
+-- @treturn number Count of matched/updated records
+-- @treturn ?string Query execution log if `l` flag presented in the control `flags`
+
+function DB:update(cname, q, ...) end
+
+--- Convenient `count(*)` operation.
+-- @tparam string cname Name of collection
+-- @tparam Q q JSON query object
+-- @treturn number Count of matched/updated records
+-- @treturn ?string Query execution log if `l` flag presented in the control `flags`
+
+function DB:count(cname, q, ...) end
+
 
+--- Returns result set lua table object at specified position `i`
+-- @tparam number i Position of record in the result set
+-- @treturn table Resulting lua object constructed from BSON record.
+function RS:object(i) end
 
 
---- Field eq restriction.
---    {fname : fval}
--- @usage Q():F("fname"):Eq(<fval>)
--- @usage Q("fname", <fval>)
+--- Returns field value of lua object at specified position `i`
+-- @tparam number i Position of record in the result set
+-- @tparam string name JSON field name
+-- @return Value of field
+function RS:field(i, name) end
+
+--- Length of result set.
+function RS.__len() end
+
+
+--- Set current field for the next operation during query building.
+-- @string fname JSON field path
+-- @usage Q:F("name"):Eq("andy"):F("age"):Gt(30) => {"name" : "andy", "age" : {"$gt" : 30}}
+function Q:F(fname) end
+
+--- Field equality restriction.
+-- @param val any BSON value as Lua object including @{Q} instances.
+-- All usage samples represent same thing: `{"fname" : fval}`
+-- @usage Q():F("fname"):Eq(fval)
+-- @usage Q("fname", fval)
+-- @usage Q():F("fname", fval)
+-- @return Self @{Q}
 function Q:Eq(val) self:_setop(nil, val, nil, true) end
 
 --- Element match construction.
---    - $elemMatch The $elemMatch operator matches more than one component within an array element.
---      -    { array: { $elemMatch: { value1 : 1, value2 : { $gt: 1 } } } }
---        Restriction: only one $elemMatch allowed in context of one array field.
+-- - $elemMatch The $elemMatch operator matches more than one component within an array element.
+-- -    { array: { $elemMatch: { value1 : 1, value2 : { $gt: 1 } } } }
+-- Restriction: only one $elemMatch allowed in context of one array field.
+-- @return Self @{Q}
 function Q:ElemMatch(val) end
 
 --- The $not negatiation for `val` block
 -- @usage Q():Not(Q("foo", "bar")) => {"$not" : {"foo" : "bar"}}
+-- @return Self @{Q}
 function Q:Not(val) end
 
 --- Greater than (val > arg)
+-- @number val
 -- @usage Q():F("age"):Gt(29) => {"age" : {"$gt" : 29}}
+-- @return Self @{Q}
 function Q:Gt(val) end
 
 --- Greater than or equal (val >= arg)
+-- @number val
 -- @usage Q():F("age"):Gt(29) => {"age" : {"$gte" : 29}}
+-- @return Self @{Q}
 function Q:Gte(val) end
 
 --- Lesser than (val < arg)
+-- @number val
 -- @usage Q():F("age"):Lt(29) => {"age" : {"$lt" : 29}}
+-- @return Self @{Q}
 function Q:Lt(val) end
 
 --- Lesser than or equal (val <= arg)
+-- @number val
 -- @usage Q():F("age"):Lt(29) => {"age" : {"$lte" : 29}}
+-- @return Self @{Q}
 function Q:Lte(val) end
 
+--- Case insensitive string matching
+-- @tparam string|table|Q val
+-- @usage Q():F("name"):Icase("aNdY") => {"name" : {"$icase" : "aNdY"}}
+-- @usage Q():F("name"):Icase({[$in] = {"aNdY", "AnTon"}}) => {"name" : {"$icase" : {"$in" : ["aNdY", "AnTon"]}}}
+-- @return Self @{Q}
 function Q:Icase(val) end
 
+--- String starts with prefix
+-- @string val
+-- @usage Q():F("fpath"):Begin("prefix") => {"fpath" : {"$begin" : "prefix"}}
+-- @return Self @{Q}
 function Q:Begin(val) end
 
+--- Field value matched any value of specified in `val` table.
+-- @tparam table val  Not empty lua array of values.
+-- @usage Q():F("fpath"):In({"val1", "val2", "val3"}) => {"fpath" : {"$in" : ["val1", "val2", "val3"]}}
+-- @return Self @{Q}
 function Q:In(val) end
 
+--- Negation of @{Q:In}
+-- @see Q:In
+-- @return Self @{Q}
 function Q:NotIn(val) end
 
-function Q:Bt(val) end
-
-function Q:StrAnd(val)  end
-
+--- Between for number types
+-- @number n1
+-- @number n2
+-- @usage Q():F("age"):Bt(10, 20) => {"age" : {"$bt" : [10, 20]}}
+-- @return Self @{Q}
+function Q:Bt(n1, n2) end
+
+--- String tokens(or string array vals) matches **all** tokens in specified `val` array.
+-- @tparam table val Array of tokens to match.
+-- @usage Q():F("description"):StrAnd({"foo", "bar"}) -- descripton contains all tokens: 'foo' and 'bar'
+-- @return Self @{Q}
+function Q:StrAnd(val) end
+
+--- String tokens(or string array vals) matches **any** token in specified array.
+-- @tparam table val Array of tokens to match.
+-- @usage Q():F("description"):StrOr({"foo", "bar"}) -- descripton contains all tokens: 'foo' or 'bar'
+-- @return Self @{Q}
 function Q:StrOr(val) end
 
+--- Increment current field. Only number types are supported.
+-- @number val
+-- @usage Q():F("count"):Inc(1):F("age"):Inc(-20) => {"$inc" : {"count" : 1, "age" : -20}}
+-- @return Self @{Q}
+-- @see Q:F
 function Q:Inc(val) end
 
+--- Set fields to values.
+-- @tparam table|Q val Table of fields to set
+-- @usage Q():Set({age = 20, count = 1}) => {"$set" : {"age" : 20, count : 1}}
+-- @return Self @{Q}
 function Q:Set(val) end
 
-function Q:AddToSet(val) end
+--- Atomic upsert.
+-- If matching records are found it will be `$set` operation,
+-- otherwise new record will be inserted with fields specified by `val` table.
+-- @tparam table|Q val Table of fields to set/insert
+-- Insert {"foo" : "bar"} if this object does not exists:
+-- @usage Q("foo","bar"):Upsert(Q("foo", "bar")) => {"foo" : "bar", "$upsert" : {"foo" : "bar"}}
+-- @usage Q("foo","bar"):Upsert({foo ="bar"}) => {"foo" : "bar", "$upsert" : {"foo" : "bar"}}
+-- @return Self @{Q}
+function Q:Upsert(val) end
 
-function Q:AddToSetAll(val)  end
+--- Atomically adds `val` to the `array field` only if `val` not in the array already.
+-- If containing array is missing it will be created.
+-- @param val Value to add
+-- @usage Q():F("tags"):AddToSet("red") => {"$addToSet" : {"tags" : "red"}}
+-- @return Self @{Q}
+function Q:AddToSet(val) end
 
+--- Atomically performs `set union` with values in `val` for specified array field.
+-- @tparam table val Array of values to add
+-- @usage Q():F("tags"):AddToSetAll({"red", "green"})
+-- @see Q:F
+-- @return Self @{Q}
+function Q:AddToSetAll(val) end
+
+--- Atomically removes all occurrences of `val` from field, if field is an array.
+-- @param val Value to remove
+-- @usage Q():F("tags"):Pull("red") => {"$pull" : {"tags" : "red"}}
+-- @see Q:F
+-- @return Self @{Q}
 function Q:Pull(val) end
 
+--- Atomically performs `set substraction` of values in `val` for specified array field.
+-- @tparam table val Array of values to remove from array field
+-- @usage Q():F("tags"):PullAll({"red", "green"}) => {"$pullAll" : {"tags" : ["red", "green"]}}
+-- @see Q:F
+-- @return Self @{Q}
 function Q:PullAll(val) end
 
-function Q:Upsert(val) end
-
+--- In-place record removal operation.
+-- @usage db:update(Q():F("name", "andy"):DropAll()) -- Removes all records with name eq 'andy'
+-- @return Self @{Q}
 function Q:DropAll() end
 
-function Q:Do(val) end
-
+--- Make <a href="https://github.com/Softmotions/ejdb/wiki/Collection-joins">collection join</a>
+-- for select queries.
+-- @string cname Name for joined collection
+-- @string fpath Name of field with BSON OIDs of joined objects
+-- @return Self @{Q}
+function Q:Join(cname, fpath) end
+
+--- Add *OR* joined query restrictions.
+-- @tparam table|Q ... List of OR joined restrictions
+-- @usage Q():Or(Q("name", "anton"), Q("name", "andy"))
+--    Find records with "name" field eq "anton" or "andy"
+-- @return Self @{Q}
 function Q:Or(...) end
 
+--- Sets number of skipped records in the result set.
+-- @number val
+-- @return Self @{Q}
 function Q:Skip(val) end
 
+--- Sets max number of records in the result set.
+-- @number val
+-- @return Self @{Q}
 function Q:Max(val) end
 
+--- Set sorting rules for query results.
+-- tparam table|string
+-- @usage Q:OrderBy("name asc", "age desc") => ORDER BY name ASC, age dESC
+-- @usage Q:OrderBy({name = 1}, {age = -1}) => ORDER BY name ASC, age dESC
 function Q:OrderBy(...) end
 
+--- Sets fields to be included in resulting objects.
+-- If field presented in $orderby clause it will be forced to include in resulting records.
+-- @string ... Fields to be included in fetched objects.
+-- @usage Q:Fields("name", "age")
+-- @return Self @{Q}
 function Q:Fields(...) end
 
+--- Sets fields to be excluded from resulting objects.
+-- @string ... Fields to be excluded from fetched objects.
+-- @usage Q:NotFields("name", "description")
+-- @return Self @{Q}
 function Q:NotFields(...) end
 
 
index 14369c6..59d2dcb 100644 (file)
@@ -191,18 +191,23 @@ assert(log:find("MAIN IDX: 'NONE'"))
 assert(db:getTransactionStatus("mycoll") == false)
 db:beginTransaction("mycoll")
 assert(db:getTransactionStatus("mycoll") == true)
-db:save("mycoll", {name=1})
+db:save("mycoll", { name = 1 })
 assert(db:findOne("mycoll", Q("name", 1)));
 db:rollbackTransaction("mycoll")
 assert(db:getTransactionStatus("mycoll") == false)
 assert(db:findOne("mycoll", Q("name", 1)) == nil);
 
-assert(db:update("ecoll", Q("k1", "v1"):Upsert({k1="v1"})) == 1)
+assert(db:update("ecoll", Q("k1", "v1"):Upsert({ k1 = "v1", k2 = 1, k3 = 2 })) == 1)
 assert(db:update("ecoll", Q("k1", "v1"):Upsert(Q("k1", "v2"))) == 1)
 assert(db:count("ecoll", Q("k1", "v2")) == 1)
 
+-- test $inc
+assert(db:update("ecoll", Q("k1", "v2"):F("k2"):Inc(1):F("k3"):Inc(-2)) == 1);
+assert(db:count("ecoll", Q():F("k2", 2):F("k3", 0)) == 1)
+
 db:ensureStringIndex("mycoll", "foo")
 
+print(ejdb.print_bson(Q():F("tags"):AddToSetAll({"red", "green"}):toBSON()))
 --print(inspect(db:getDBMeta()))
 
 db:dropCollection("ecoll", true);
index c58f935..31d4b3c 100644 (file)
@@ -333,7 +333,7 @@ function parseQueryArgs(args) {
  *          - {.., '$inc' : {'field1' : number, ...,  'field1' : number}
  *      $dropall In-place record removal operation.
  *          - {.., '$dropall' : true}
- *      $addToSet Atomically adds value to the array only if its not in the array already.
+ *      $addToSet Atomically adds value to the array only if value not in the array already.
  *                  If containing array is missing it will be created.
  *          - {.., '$addToSet' : {'fpath' : val1, 'fpathN' : valN, ...}}
  *      $addToSetAll Batch version if $addToSet
@@ -414,7 +414,7 @@ EJDB.prototype.find = function() {
 };
 
 /**
- * Same as #find() but retrieves only one matching JSON object.
+ * Same as #find() but retrieves only first matching JSON object.
  * If callback is not provided this function will be synchronous.
  *
  * Call variations of findOne():