Remove transpiling, drop node < 4, start moving tests to mocha/chai
This commit is contained in:
parent
6a9c67b924
commit
6b0be21782
@ -4,11 +4,10 @@ sudo: false
|
|||||||
node_js:
|
node_js:
|
||||||
- "iojs"
|
- "iojs"
|
||||||
- "node"
|
- "node"
|
||||||
|
- "5.1"
|
||||||
|
- "5.0"
|
||||||
- "4.1"
|
- "4.1"
|
||||||
- "4.0"
|
- "4.0"
|
||||||
- "0.12"
|
|
||||||
- "0.11"
|
|
||||||
- "0.10"
|
|
||||||
|
|
||||||
before_script:
|
before_script:
|
||||||
- npm install -g gulp
|
- npm install -g gulp
|
||||||
@ -19,3 +18,7 @@ before_script:
|
|||||||
- psql test postgres -f ./tests/sql/pgsql.sql
|
- psql test postgres -f ./tests/sql/pgsql.sql
|
||||||
|
|
||||||
script: gulp
|
script: gulp
|
||||||
|
|
||||||
|
matrix:
|
||||||
|
allow_failures:
|
||||||
|
- node_js: iojs
|
201
docs/index.html
201
docs/index.html
@ -31,16 +31,6 @@
|
|||||||
class='block bold'>
|
class='block bold'>
|
||||||
State
|
State
|
||||||
</a>
|
</a>
|
||||||
<a
|
|
||||||
href='#State'
|
|
||||||
class='block bold'>
|
|
||||||
State
|
|
||||||
</a>
|
|
||||||
<a
|
|
||||||
href='#_appendMap'
|
|
||||||
class='block bold'>
|
|
||||||
_appendMap
|
|
||||||
</a>
|
|
||||||
<a
|
<a
|
||||||
href='#helpers'
|
href='#helpers'
|
||||||
class='block bold'>
|
class='block bold'>
|
||||||
@ -313,62 +303,6 @@
|
|||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
</div><div class='py1'><section class='py2 clearfix'>
|
|
||||||
<h2 id='State' class='mt0'>
|
|
||||||
State<span class='gray'>(Driver, driver)</span>
|
|
||||||
</h2>
|
|
||||||
|
|
||||||
<h4>Parameters</h4>
|
|
||||||
<ul class='suppress-p-margin'>
|
|
||||||
<li> <strong>Driver</strong>
|
|
||||||
:
|
|
||||||
<span class='force-inline'>
|
|
||||||
<p>The driver object for the database in use</p>
|
|
||||||
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
<li> <strong>driver</strong>
|
|
||||||
:
|
|
||||||
<span class='force-inline'>
|
|
||||||
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</section>
|
|
||||||
</div><div class='py1'><section class='py2 clearfix'>
|
|
||||||
<h2 id='_appendMap' class='mt0'>
|
|
||||||
_appendMap<span class='gray'>(conjunction, string, type)</span>
|
|
||||||
</h2>
|
|
||||||
<p>Append a clause to the query map</p>
|
|
||||||
|
|
||||||
<h4>Parameters</h4>
|
|
||||||
<ul class='suppress-p-margin'>
|
|
||||||
<li><code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String">String</a></code> <strong>conjunction</strong>
|
|
||||||
:
|
|
||||||
<span class='force-inline'>
|
|
||||||
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
<li><code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String">String</a></code> <strong>string</strong>
|
|
||||||
:
|
|
||||||
<span class='force-inline'>
|
|
||||||
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
<li><code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String">String</a></code> <strong>type</strong>
|
|
||||||
:
|
|
||||||
<span class='force-inline'>
|
|
||||||
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<h4>Returns</h4>
|
|
||||||
<code><code>void</code></code>
|
|
||||||
|
|
||||||
<span class='force-inline'>
|
|
||||||
|
|
||||||
</span>
|
|
||||||
</section>
|
|
||||||
</div><div class='py1'><section class='py2 clearfix'>
|
</div><div class='py1'><section class='py2 clearfix'>
|
||||||
<h2 id='helpers' class='mt0'>
|
<h2 id='helpers' class='mt0'>
|
||||||
helpers<span class='gray'>(o)</span>
|
helpers<span class='gray'>(o)</span>
|
||||||
@ -429,8 +363,9 @@ function name, eg isNumber</p>
|
|||||||
</ul>
|
</ul>
|
||||||
<h4>Returns</h4>
|
<h4>Returns</h4>
|
||||||
<code><code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array">Array</a></code></code>
|
<code><code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array">Array</a></code></code>
|
||||||
|
:
|
||||||
<span class='force-inline'>
|
<span class='force-inline'>
|
||||||
|
<p>The new array of plucked values</p>
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
</section>
|
</section>
|
||||||
@ -458,14 +393,16 @@ function name, eg isNumber</p>
|
|||||||
<li><code>mixed</code> <strong>obj</strong>
|
<li><code>mixed</code> <strong>obj</strong>
|
||||||
:
|
:
|
||||||
<span class='force-inline'>
|
<span class='force-inline'>
|
||||||
|
<p>Object to test</p>
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<h4>Returns</h4>
|
<h4>Returns</h4>
|
||||||
<code><code>bool</code></code>
|
<code><code>bool</code></code>
|
||||||
|
:
|
||||||
<span class='force-inline'>
|
<span class='force-inline'>
|
||||||
|
<p>Is object scalar</p>
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
</section>
|
</section>
|
||||||
@ -576,14 +513,16 @@ in the passed array</p>
|
|||||||
<li><code>mixed</code> <strong>o</strong>
|
<li><code>mixed</code> <strong>o</strong>
|
||||||
:
|
:
|
||||||
<span class='force-inline'>
|
<span class='force-inline'>
|
||||||
|
<p>Object to type check</p>
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<h4>Returns</h4>
|
<h4>Returns</h4>
|
||||||
<code><code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String">String</a></code></code>
|
<code><code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String">String</a></code></code>
|
||||||
|
:
|
||||||
<span class='force-inline'>
|
<span class='force-inline'>
|
||||||
|
<p>Type of the object</p>
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
</section>
|
</section>
|
||||||
@ -611,14 +550,16 @@ in the passed array</p>
|
|||||||
<li><code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String">String</a></code> <strong>str</strong>
|
<li><code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String">String</a></code> <strong>str</strong>
|
||||||
:
|
:
|
||||||
<span class='force-inline'>
|
<span class='force-inline'>
|
||||||
|
<p>The string to modify</p>
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<h4>Returns</h4>
|
<h4>Returns</h4>
|
||||||
<code><code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String">String</a></code></code>
|
<code><code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String">String</a></code></code>
|
||||||
|
:
|
||||||
<span class='force-inline'>
|
<span class='force-inline'>
|
||||||
|
<p>The modified string</p>
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
</section>
|
</section>
|
||||||
@ -651,22 +592,16 @@ in the passed array</p>
|
|||||||
</section>
|
</section>
|
||||||
</div><div class='py1'><section class='py2 clearfix'>
|
</div><div class='py1'><section class='py2 clearfix'>
|
||||||
<h2 id='constructor' class='mt0'>
|
<h2 id='constructor' class='mt0'>
|
||||||
constructor<span class='gray'>(Driver, driver)</span>
|
constructor<span class='gray'>(driver)</span>
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<h4>Parameters</h4>
|
<h4>Parameters</h4>
|
||||||
<ul class='suppress-p-margin'>
|
<ul class='suppress-p-margin'>
|
||||||
<li> <strong>Driver</strong>
|
<li><code>Driver</code> <strong>driver</strong>
|
||||||
:
|
:
|
||||||
<span class='force-inline'>
|
<span class='force-inline'>
|
||||||
<p>The driver object for the database in use</p>
|
<p>The driver object for the database in use</p>
|
||||||
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
<li> <strong>driver</strong>
|
|
||||||
:
|
|
||||||
<span class='force-inline'>
|
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
@ -738,14 +673,16 @@ in the passed array</p>
|
|||||||
<li><code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array">Array</a></code> <strong>array</strong>
|
<li><code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array">Array</a></code> <strong>array</strong>
|
||||||
:
|
:
|
||||||
<span class='force-inline'>
|
<span class='force-inline'>
|
||||||
|
<p>Set of possible matches</p>
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<h4>Returns</h4>
|
<h4>Returns</h4>
|
||||||
<code><code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array">Array</a></code> or </code>
|
<code><code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array">Array</a></code> or </code>
|
||||||
|
:
|
||||||
<span class='force-inline'>
|
<span class='force-inline'>
|
||||||
|
<p>Filtered set of possible matches</p>
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
</section>
|
</section>
|
||||||
@ -767,8 +704,9 @@ in the passed array</p>
|
|||||||
</ul>
|
</ul>
|
||||||
<h4>Returns</h4>
|
<h4>Returns</h4>
|
||||||
<code><code><a href="#QueryBuilder">QueryBuilder</a></code></code>
|
<code><code><a href="#QueryBuilder">QueryBuilder</a></code></code>
|
||||||
|
:
|
||||||
<span class='force-inline'>
|
<span class='force-inline'>
|
||||||
|
<p>The Query Builder object, for chaining</p>
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
</section>
|
</section>
|
||||||
@ -842,8 +780,9 @@ in the passed array</p>
|
|||||||
</ul>
|
</ul>
|
||||||
<h4>Returns</h4>
|
<h4>Returns</h4>
|
||||||
<code><code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String">String</a></code></code>
|
<code><code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String">String</a></code></code>
|
||||||
|
:
|
||||||
<span class='force-inline'>
|
<span class='force-inline'>
|
||||||
|
<p>The compiled sql statement</p>
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
</section>
|
</section>
|
||||||
@ -873,8 +812,9 @@ in the passed array</p>
|
|||||||
</ul>
|
</ul>
|
||||||
<h4>Returns</h4>
|
<h4>Returns</h4>
|
||||||
<code><code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String">String</a></code></code>
|
<code><code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String">String</a></code></code>
|
||||||
|
:
|
||||||
<span class='force-inline'>
|
<span class='force-inline'>
|
||||||
|
<p>The compiled sql statement</p>
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
</section>
|
</section>
|
||||||
@ -904,8 +844,9 @@ in the passed array</p>
|
|||||||
</ul>
|
</ul>
|
||||||
<h4>Returns</h4>
|
<h4>Returns</h4>
|
||||||
<code><code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String">String</a></code></code>
|
<code><code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String">String</a></code></code>
|
||||||
|
:
|
||||||
<span class='force-inline'>
|
<span class='force-inline'>
|
||||||
|
<p>The compiled sql statement</p>
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
</section>
|
</section>
|
||||||
@ -935,8 +876,9 @@ in the passed array</p>
|
|||||||
</ul>
|
</ul>
|
||||||
<h4>Returns</h4>
|
<h4>Returns</h4>
|
||||||
<code><code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String">String</a></code></code>
|
<code><code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String">String</a></code></code>
|
||||||
|
:
|
||||||
<span class='force-inline'>
|
<span class='force-inline'>
|
||||||
|
<p>The compiled sql statement</p>
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
</section>
|
</section>
|
||||||
@ -951,14 +893,16 @@ in the passed array</p>
|
|||||||
<li><code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String">String</a></code> or <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array">Array</a></code> <strong>field</strong>
|
<li><code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String">String</a></code> or <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array">Array</a></code> <strong>field</strong>
|
||||||
:
|
:
|
||||||
<span class='force-inline'>
|
<span class='force-inline'>
|
||||||
|
<p>The name of the field to group by</p>
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<h4>Returns</h4>
|
<h4>Returns</h4>
|
||||||
<code><code><a href="#QueryBuilder">QueryBuilder</a></code></code>
|
<code><code><a href="#QueryBuilder">QueryBuilder</a></code></code>
|
||||||
|
:
|
||||||
<span class='force-inline'>
|
<span class='force-inline'>
|
||||||
|
<p>The Query Builder object, for chaining</p>
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
</section>
|
</section>
|
||||||
@ -970,8 +914,9 @@ in the passed array</p>
|
|||||||
|
|
||||||
<h4>Returns</h4>
|
<h4>Returns</h4>
|
||||||
<code><code><a href="#QueryBuilder">QueryBuilder</a></code></code>
|
<code><code><a href="#QueryBuilder">QueryBuilder</a></code></code>
|
||||||
|
:
|
||||||
<span class='force-inline'>
|
<span class='force-inline'>
|
||||||
|
<p>The Query Builder object, for chaining</p>
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
</section>
|
</section>
|
||||||
@ -983,8 +928,9 @@ in the passed array</p>
|
|||||||
|
|
||||||
<h4>Returns</h4>
|
<h4>Returns</h4>
|
||||||
<code><code><a href="#QueryBuilder">QueryBuilder</a></code></code>
|
<code><code><a href="#QueryBuilder">QueryBuilder</a></code></code>
|
||||||
|
:
|
||||||
<span class='force-inline'>
|
<span class='force-inline'>
|
||||||
|
<p>The Query Builder object, for chaining</p>
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
</section>
|
</section>
|
||||||
@ -1007,8 +953,9 @@ If there are no matches, return null</p>
|
|||||||
</ul>
|
</ul>
|
||||||
<h4>Returns</h4>
|
<h4>Returns</h4>
|
||||||
<code><code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array">Array</a></code> or </code>
|
<code><code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array">Array</a></code> or </code>
|
||||||
|
:
|
||||||
<span class='force-inline'>
|
<span class='force-inline'>
|
||||||
|
<p>List of operators</p>
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
</section>
|
</section>
|
||||||
@ -1037,8 +984,9 @@ If there are no matches, return null</p>
|
|||||||
</ul>
|
</ul>
|
||||||
<h4>Returns</h4>
|
<h4>Returns</h4>
|
||||||
<code><code><a href="#QueryBuilder">QueryBuilder</a></code></code>
|
<code><code><a href="#QueryBuilder">QueryBuilder</a></code></code>
|
||||||
|
:
|
||||||
<span class='force-inline'>
|
<span class='force-inline'>
|
||||||
|
<p>The Query Builder object, for chaining</p>
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
</section>
|
</section>
|
||||||
@ -1151,8 +1099,9 @@ If there are no matches, return null</p>
|
|||||||
</ul>
|
</ul>
|
||||||
<h4>Returns</h4>
|
<h4>Returns</h4>
|
||||||
<code><code><a href="#QueryBuilder">QueryBuilder</a></code></code>
|
<code><code><a href="#QueryBuilder">QueryBuilder</a></code></code>
|
||||||
|
:
|
||||||
<span class='force-inline'>
|
<span class='force-inline'>
|
||||||
|
<p>The Query Builder object, for chaining</p>
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
</section>
|
</section>
|
||||||
@ -1189,8 +1138,9 @@ If there are no matches, return null</p>
|
|||||||
</ul>
|
</ul>
|
||||||
<h4>Returns</h4>
|
<h4>Returns</h4>
|
||||||
<code><code><a href="#QueryBuilder">QueryBuilder</a></code></code>
|
<code><code><a href="#QueryBuilder">QueryBuilder</a></code></code>
|
||||||
|
:
|
||||||
<span class='force-inline'>
|
<span class='force-inline'>
|
||||||
|
<p>The Query Builder object, for chaining</p>
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
</section>
|
</section>
|
||||||
@ -1219,8 +1169,9 @@ If there are no matches, return null</p>
|
|||||||
</ul>
|
</ul>
|
||||||
<h4>Returns</h4>
|
<h4>Returns</h4>
|
||||||
<code><code><a href="#QueryBuilder">QueryBuilder</a></code></code>
|
<code><code><a href="#QueryBuilder">QueryBuilder</a></code></code>
|
||||||
|
:
|
||||||
<span class='force-inline'>
|
<span class='force-inline'>
|
||||||
|
<p>The Query Builder object, for chaining</p>
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
</section>
|
</section>
|
||||||
@ -1257,8 +1208,9 @@ If there are no matches, return null</p>
|
|||||||
</ul>
|
</ul>
|
||||||
<h4>Returns</h4>
|
<h4>Returns</h4>
|
||||||
<code><code><a href="#QueryBuilder">QueryBuilder</a></code></code>
|
<code><code><a href="#QueryBuilder">QueryBuilder</a></code></code>
|
||||||
|
:
|
||||||
<span class='force-inline'>
|
<span class='force-inline'>
|
||||||
|
<p>The Query Builder object, for chaining</p>
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
</section>
|
</section>
|
||||||
@ -1271,8 +1223,9 @@ prefixed with 'OR'</p>
|
|||||||
|
|
||||||
<h4>Returns</h4>
|
<h4>Returns</h4>
|
||||||
<code><code><a href="#QueryBuilder">QueryBuilder</a></code></code>
|
<code><code><a href="#QueryBuilder">QueryBuilder</a></code></code>
|
||||||
|
:
|
||||||
<span class='force-inline'>
|
<span class='force-inline'>
|
||||||
|
<p>The Query Builder object, for chaining</p>
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
</section>
|
</section>
|
||||||
@ -1301,8 +1254,9 @@ prefixed with 'OR'</p>
|
|||||||
</ul>
|
</ul>
|
||||||
<h4>Returns</h4>
|
<h4>Returns</h4>
|
||||||
<code><code><a href="#QueryBuilder">QueryBuilder</a></code></code>
|
<code><code><a href="#QueryBuilder">QueryBuilder</a></code></code>
|
||||||
|
:
|
||||||
<span class='force-inline'>
|
<span class='force-inline'>
|
||||||
|
<p>The Query Builder object, for chaining</p>
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
</section>
|
</section>
|
||||||
@ -1339,8 +1293,9 @@ prefixed with 'OR'</p>
|
|||||||
</ul>
|
</ul>
|
||||||
<h4>Returns</h4>
|
<h4>Returns</h4>
|
||||||
<code><code><a href="#QueryBuilder">QueryBuilder</a></code></code>
|
<code><code><a href="#QueryBuilder">QueryBuilder</a></code></code>
|
||||||
|
:
|
||||||
<span class='force-inline'>
|
<span class='force-inline'>
|
||||||
|
<p>The Query Builder object, for chaining</p>
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
</section>
|
</section>
|
||||||
@ -1353,8 +1308,9 @@ prefixed with 'OR NOT'</p>
|
|||||||
|
|
||||||
<h4>Returns</h4>
|
<h4>Returns</h4>
|
||||||
<code><code><a href="#QueryBuilder">QueryBuilder</a></code></code>
|
<code><code><a href="#QueryBuilder">QueryBuilder</a></code></code>
|
||||||
|
:
|
||||||
<span class='force-inline'>
|
<span class='force-inline'>
|
||||||
|
<p>The Query Builder object, for chaining</p>
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
</section>
|
</section>
|
||||||
@ -1391,8 +1347,9 @@ prefixed with 'OR NOT'</p>
|
|||||||
</ul>
|
</ul>
|
||||||
<h4>Returns</h4>
|
<h4>Returns</h4>
|
||||||
<code><code><a href="#QueryBuilder">QueryBuilder</a></code></code>
|
<code><code><a href="#QueryBuilder">QueryBuilder</a></code></code>
|
||||||
|
:
|
||||||
<span class='force-inline'>
|
<span class='force-inline'>
|
||||||
|
<p>The Query Builder object, for chaining</p>
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
</section>
|
</section>
|
||||||
@ -1421,8 +1378,9 @@ prefixed with 'OR NOT'</p>
|
|||||||
</ul>
|
</ul>
|
||||||
<h4>Returns</h4>
|
<h4>Returns</h4>
|
||||||
<code><code><a href="#QueryBuilder">QueryBuilder</a></code></code>
|
<code><code><a href="#QueryBuilder">QueryBuilder</a></code></code>
|
||||||
|
:
|
||||||
<span class='force-inline'>
|
<span class='force-inline'>
|
||||||
|
<p>The Query Builder object, for chaining</p>
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
</section>
|
</section>
|
||||||
@ -1451,8 +1409,9 @@ prefixed with 'OR NOT'</p>
|
|||||||
</ul>
|
</ul>
|
||||||
<h4>Returns</h4>
|
<h4>Returns</h4>
|
||||||
<code><code><a href="#QueryBuilder">QueryBuilder</a></code></code>
|
<code><code><a href="#QueryBuilder">QueryBuilder</a></code></code>
|
||||||
|
:
|
||||||
<span class='force-inline'>
|
<span class='force-inline'>
|
||||||
|
<p>The Query Builder object, for chaining</p>
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
</section>
|
</section>
|
||||||
@ -1467,14 +1426,16 @@ prefixed with 'OR NOT'</p>
|
|||||||
<li><code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String">String</a></code> <strong>field</strong>
|
<li><code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String">String</a></code> <strong>field</strong>
|
||||||
:
|
:
|
||||||
<span class='force-inline'>
|
<span class='force-inline'>
|
||||||
|
<p>The name of the field</p>
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<h4>Returns</h4>
|
<h4>Returns</h4>
|
||||||
<code><code><a href="#QueryBuilder">QueryBuilder</a></code></code>
|
<code><code><a href="#QueryBuilder">QueryBuilder</a></code></code>
|
||||||
|
:
|
||||||
<span class='force-inline'>
|
<span class='force-inline'>
|
||||||
|
<p>The Query Builder object, for chaining</p>
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
</section>
|
</section>
|
||||||
@ -1489,14 +1450,16 @@ prefixed with 'OR NOT'</p>
|
|||||||
<li><code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String">String</a></code> <strong>field</strong>
|
<li><code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String">String</a></code> <strong>field</strong>
|
||||||
:
|
:
|
||||||
<span class='force-inline'>
|
<span class='force-inline'>
|
||||||
|
<p>The name of the field</p>
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<h4>Returns</h4>
|
<h4>Returns</h4>
|
||||||
<code><code><a href="#QueryBuilder">QueryBuilder</a></code></code>
|
<code><code><a href="#QueryBuilder">QueryBuilder</a></code></code>
|
||||||
|
:
|
||||||
<span class='force-inline'>
|
<span class='force-inline'>
|
||||||
|
<p>The Query Builder object, for chaining</p>
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
</section>
|
</section>
|
||||||
@ -1525,8 +1488,9 @@ prefixed with 'OR NOT'</p>
|
|||||||
</ul>
|
</ul>
|
||||||
<h4>Returns</h4>
|
<h4>Returns</h4>
|
||||||
<code><code><a href="#QueryBuilder">QueryBuilder</a></code></code>
|
<code><code><a href="#QueryBuilder">QueryBuilder</a></code></code>
|
||||||
|
:
|
||||||
<span class='force-inline'>
|
<span class='force-inline'>
|
||||||
|
<p>The Query Builder object, for chaining</p>
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
</section>
|
</section>
|
||||||
@ -1556,8 +1520,9 @@ prefixed with 'OR NOT'</p>
|
|||||||
</ul>
|
</ul>
|
||||||
<h4>Returns</h4>
|
<h4>Returns</h4>
|
||||||
<code><code><a href="#QueryBuilder">QueryBuilder</a></code></code>
|
<code><code><a href="#QueryBuilder">QueryBuilder</a></code></code>
|
||||||
|
:
|
||||||
<span class='force-inline'>
|
<span class='force-inline'>
|
||||||
|
<p>The Query Builder object, for chaining</p>
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
</section>
|
</section>
|
||||||
@ -1572,14 +1537,16 @@ prefixed with 'OR NOT'</p>
|
|||||||
<li><code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String">String</a></code> <strong>sql</strong>
|
<li><code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String">String</a></code> <strong>sql</strong>
|
||||||
:
|
:
|
||||||
<span class='force-inline'>
|
<span class='force-inline'>
|
||||||
|
<p>Join sql to parse</p>
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<h4>Returns</h4>
|
<h4>Returns</h4>
|
||||||
<code><code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object">Object</a></code></code>
|
<code><code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object">Object</a></code></code>
|
||||||
|
:
|
||||||
<span class='force-inline'>
|
<span class='force-inline'>
|
||||||
|
<p>Join condition components</p>
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
</section>
|
</section>
|
||||||
@ -1594,12 +1561,14 @@ prefixed with 'OR NOT'</p>
|
|||||||
<li><code>Driver</code> <strong>driver</strong>
|
<li><code>Driver</code> <strong>driver</strong>
|
||||||
:
|
:
|
||||||
<span class='force-inline'>
|
<span class='force-inline'>
|
||||||
|
<p>The current db driver</p>
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
<li><code><a href="#State">State</a></code> <strong>state</strong>
|
<li><code><a href="#State">State</a></code> <strong>state</strong>
|
||||||
:
|
:
|
||||||
<span class='force-inline'>
|
<span class='force-inline'>
|
||||||
|
<p>Query Builder state object</p>
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
@ -1643,8 +1612,9 @@ prefixed with 'OR NOT'</p>
|
|||||||
</ul>
|
</ul>
|
||||||
<h4>Returns</h4>
|
<h4>Returns</h4>
|
||||||
<code><code><a href="#QueryBuilder">QueryBuilder</a></code></code>
|
<code><code><a href="#QueryBuilder">QueryBuilder</a></code></code>
|
||||||
|
:
|
||||||
<span class='force-inline'>
|
<span class='force-inline'>
|
||||||
|
<p>The Query Builder object, for chaining</p>
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
</section>
|
</section>
|
||||||
@ -1673,8 +1643,9 @@ prefixed with 'OR NOT'</p>
|
|||||||
</ul>
|
</ul>
|
||||||
<h4>Returns</h4>
|
<h4>Returns</h4>
|
||||||
<code><code><a href="#QueryBuilder">QueryBuilder</a></code></code>
|
<code><code><a href="#QueryBuilder">QueryBuilder</a></code></code>
|
||||||
|
:
|
||||||
<span class='force-inline'>
|
<span class='force-inline'>
|
||||||
|
<p>The Query Builder object, for chaining</p>
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
</section>
|
</section>
|
||||||
@ -1740,8 +1711,9 @@ prefixed with 'OR NOT'</p>
|
|||||||
</ul>
|
</ul>
|
||||||
<h4>Returns</h4>
|
<h4>Returns</h4>
|
||||||
<code><code><a href="#QueryBuilder">QueryBuilder</a></code></code>
|
<code><code><a href="#QueryBuilder">QueryBuilder</a></code></code>
|
||||||
|
:
|
||||||
<span class='force-inline'>
|
<span class='force-inline'>
|
||||||
|
<p>The Query Builder object, for chaining</p>
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
</section>
|
</section>
|
||||||
@ -1770,8 +1742,9 @@ prefixed with 'OR NOT'</p>
|
|||||||
</ul>
|
</ul>
|
||||||
<h4>Returns</h4>
|
<h4>Returns</h4>
|
||||||
<code><code><a href="#QueryBuilder">QueryBuilder</a></code></code>
|
<code><code><a href="#QueryBuilder">QueryBuilder</a></code></code>
|
||||||
|
:
|
||||||
<span class='force-inline'>
|
<span class='force-inline'>
|
||||||
|
<p>The Query Builder object, for chaining</p>
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
</section>
|
</section>
|
||||||
@ -1786,14 +1759,16 @@ prefixed with 'OR NOT'</p>
|
|||||||
<li><code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String">String</a></code> <strong>field</strong>
|
<li><code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String">String</a></code> <strong>field</strong>
|
||||||
:
|
:
|
||||||
<span class='force-inline'>
|
<span class='force-inline'>
|
||||||
|
<p>The name so the field that is not to be null</p>
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<h4>Returns</h4>
|
<h4>Returns</h4>
|
||||||
<code><code><a href="#QueryBuilder">QueryBuilder</a></code></code>
|
<code><code><a href="#QueryBuilder">QueryBuilder</a></code></code>
|
||||||
|
:
|
||||||
<span class='force-inline'>
|
<span class='force-inline'>
|
||||||
|
<p>The Query Builder object, for chaining</p>
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
</section>
|
</section>
|
||||||
@ -1815,8 +1790,9 @@ prefixed with 'OR NOT'</p>
|
|||||||
</ul>
|
</ul>
|
||||||
<h4>Returns</h4>
|
<h4>Returns</h4>
|
||||||
<code><code><a href="#QueryBuilder">QueryBuilder</a></code></code>
|
<code><code><a href="#QueryBuilder">QueryBuilder</a></code></code>
|
||||||
|
:
|
||||||
<span class='force-inline'>
|
<span class='force-inline'>
|
||||||
|
<p>The Query Builder object, for chaining</p>
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
</section>
|
</section>
|
||||||
@ -1845,8 +1821,9 @@ prefixed with 'OR NOT'</p>
|
|||||||
</ul>
|
</ul>
|
||||||
<h4>Returns</h4>
|
<h4>Returns</h4>
|
||||||
<code><code><a href="#QueryBuilder">QueryBuilder</a></code></code>
|
<code><code><a href="#QueryBuilder">QueryBuilder</a></code></code>
|
||||||
|
:
|
||||||
<span class='force-inline'>
|
<span class='force-inline'>
|
||||||
|
<p>The Query Builder object, for chaining</p>
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
</section>
|
</section>
|
||||||
|
188
gulpfile.js
188
gulpfile.js
@ -1,94 +1,72 @@
|
|||||||
var babel = require('gulp-babel'),
|
'use strict';
|
||||||
concat = require('gulp-concat'),
|
|
||||||
documentation = require('gulp-documentation'),
|
const documentation = require('gulp-documentation'),
|
||||||
eslint = require('gulp-eslint'),
|
eslint = require('gulp-eslint'),
|
||||||
gulp = require('gulp'),
|
gulp = require('gulp'),
|
||||||
istanbul = require('gulp-babel-istanbul'),
|
istanbul = require('gulp-istanbul'),
|
||||||
nodeunit_runner = require('gulp-nodeunit-runner'),
|
mocha = require('gulp-mocha'),
|
||||||
sloc = require('gulp-sloc'),
|
pipe = require('gulp-pipe'),
|
||||||
sourcemaps = require('gulp-sourcemaps');
|
sloc = require('gulp-sloc');
|
||||||
|
|
||||||
gulp.task('transpile', function() {
|
const SRC_FILES = ['lib/**/*.js'];
|
||||||
return gulp.src('src/**/*.js')
|
const TEST_FILES = ['test/**/*_test.js'];
|
||||||
.pipe(sourcemaps.init())
|
|
||||||
.pipe(babel({
|
const ESLINT_SETTINGS = {
|
||||||
presets: ['es2015'],
|
"env": {
|
||||||
plugins: ['transform-es2015-modules-commonjs']
|
"node": true,
|
||||||
}))
|
"es6": true
|
||||||
.pipe(sourcemaps.write('.'))
|
},
|
||||||
.pipe(gulp.dest('lib'));
|
"rules": {
|
||||||
|
"arrow-parens": [2, "as-needed"],
|
||||||
|
"no-console": [1],
|
||||||
|
"no-constant-condition": [1],
|
||||||
|
"no-extra-semi": [1],
|
||||||
|
"no-func-assign": [1],
|
||||||
|
"no-unexpected-multiline" : [2],
|
||||||
|
"radix": [2],
|
||||||
|
"no-with": [2],
|
||||||
|
"no-eval": [2],
|
||||||
|
"no-unreachable": [1],
|
||||||
|
"no-irregular-whitespace": [1],
|
||||||
|
"no-new-wrappers": [2],
|
||||||
|
"no-new-func": [2],
|
||||||
|
"curly" : [2, "multi-line"],
|
||||||
|
"no-implied-eval": [2],
|
||||||
|
"no-invalid-this": [2],
|
||||||
|
"constructor-super": [2],
|
||||||
|
"no-dupe-args": [2],
|
||||||
|
"no-dupe-keys": [2],
|
||||||
|
"no-dupe-class-members": [2],
|
||||||
|
"no-this-before-super": [2],
|
||||||
|
"prefer-arrow-callback": [1],
|
||||||
|
"no-var": [2],
|
||||||
|
"valid-jsdoc": [1],
|
||||||
|
"strict": [2, "global"],
|
||||||
|
"callback-return": [1]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
gulp.task('lint', () => {
|
||||||
|
return pipe(gulp.src(SRC_FILES), [
|
||||||
|
eslint(ESLINT_SETTINGS),
|
||||||
|
eslint.format(),
|
||||||
|
eslint.failAfterError()
|
||||||
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task('lint', function() {
|
gulp.task('lint-tests', ['lint'], () => {
|
||||||
return gulp.src('src/**/*.js')
|
return pipe(gulp.src(TEST_FILES), [
|
||||||
.pipe(eslint({
|
eslint(ESLINT_SETTINGS),
|
||||||
"env": {
|
eslint.format(),
|
||||||
"node": true,
|
eslint.failAfterError()
|
||||||
"es6": true
|
]);
|
||||||
},
|
|
||||||
"ecmaFeatures": {
|
|
||||||
"arrowFunctions": true,
|
|
||||||
"blockBindings": true,
|
|
||||||
"classes": true,
|
|
||||||
"defaultParams": true,
|
|
||||||
"destructuring": true,
|
|
||||||
"forOf": true,
|
|
||||||
"modules": true
|
|
||||||
},
|
|
||||||
"rules": {
|
|
||||||
"radix": [2],
|
|
||||||
"no-with": [2],
|
|
||||||
"no-eval": [2],
|
|
||||||
"no-unreachable": [2],
|
|
||||||
"no-irregular-whitespace": [1],
|
|
||||||
"no-new-wrappers": [2],
|
|
||||||
"curly" : [2, "multi-line"],
|
|
||||||
"no-implied-eval": [2],
|
|
||||||
"no-invalid-this": [2],
|
|
||||||
"constructor-super": [2],
|
|
||||||
"no-dupe-class-members": [2],
|
|
||||||
"no-this-before-super": [2],
|
|
||||||
"prefer-arrow-callback": [1],
|
|
||||||
"no-var": [1],
|
|
||||||
"valid-jsdoc": [1]
|
|
||||||
}
|
|
||||||
}))
|
|
||||||
.pipe(eslint.format())
|
|
||||||
.pipe(eslint.failAfterError());
|
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task('lint-tests', ['lint'], function() {
|
gulp.task('sloc', () => gulp.src(SRC_FILES).pipe(sloc()));
|
||||||
return gulp.src('tests/**/*.js')
|
gulp.task('test-sloc', () => gulp.src(TEST_FILES).pipe(sloc()));
|
||||||
.pipe(eslint({
|
|
||||||
"env": {
|
|
||||||
"node": true
|
|
||||||
},
|
|
||||||
"rules": {
|
|
||||||
"radix": [2],
|
|
||||||
"no-with": [2],
|
|
||||||
"no-eval": [2],
|
|
||||||
"no-unreachable": [1],
|
|
||||||
"no-irregular-whitespace": [1],
|
|
||||||
"curly" : [2, "multi-line"],
|
|
||||||
"no-implied-eval": [2],
|
|
||||||
"no-invalid-this": [2],
|
|
||||||
"no-dupe-class-members": [2],
|
|
||||||
"block-scoped-var": [2]
|
|
||||||
}
|
|
||||||
}))
|
|
||||||
.pipe(eslint.format())
|
|
||||||
.pipe(eslint.failAfterError());
|
|
||||||
});
|
|
||||||
|
|
||||||
gulp.task('sloc', ['transpile'], function() {
|
gulp.task('docs', () => {
|
||||||
gulp.src(['src/**/*.js'])
|
gulp.src('./lib/QueryBuilder.js')
|
||||||
.pipe(sloc());
|
|
||||||
gulp.src(['lib/**/*.js'])
|
|
||||||
.pipe(sloc());
|
|
||||||
})
|
|
||||||
|
|
||||||
gulp.task('docs', ['transpile'], function() {
|
|
||||||
gulp.src('./src/QueryBuilder.js')
|
|
||||||
.pipe(documentation({format: 'html'}))
|
.pipe(documentation({format: 'html'}))
|
||||||
.pipe(gulp.dest('docs'));
|
.pipe(gulp.dest('docs'));
|
||||||
/*gulp.src('./lib/QueryBuilder.js')
|
/*gulp.src('./lib/QueryBuilder.js')
|
||||||
@ -96,28 +74,32 @@ gulp.task('docs', ['transpile'], function() {
|
|||||||
.pipe(gulp.dest('api-docs'));*/
|
.pipe(gulp.dest('api-docs'));*/
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task('nodeunit', ['transpile', 'lint-tests'], function() {
|
gulp.task('mocha', ['lint-tests', 'sloc'], () => {
|
||||||
return gulp.src(['tests/**/*_test.js'])
|
return gulp.src(TEST_FILES)
|
||||||
.pipe(nodeunit_runner());
|
.pipe(mocha({
|
||||||
|
ui: 'tdd',
|
||||||
|
bail: true,
|
||||||
|
//reporter: 'dot',
|
||||||
|
//reporter: 'landing',
|
||||||
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task('fast-test', ['transpile', 'lint-tests'], function() {
|
gulp.task('test', ['test-sloc', 'lint-tests'], function(cb) {
|
||||||
return gulp.src(['tests/**/*_test.js'])
|
return pipe(gulp.src(SRC_FILES), [
|
||||||
.pipe(nodeunit_runner());
|
istanbul(),
|
||||||
});
|
istanbul.hookRequire()
|
||||||
|
]).on('finish', () => {
|
||||||
gulp.task('test', ['transpile', 'lint-tests'], function(cb) {
|
pipe(gulp.src(TEST_FILES), [
|
||||||
return gulp.src(['lib/**/*.js'])
|
mocha({
|
||||||
.pipe(istanbul())
|
ui: 'tdd',
|
||||||
.pipe(istanbul.hookRequire())
|
bail: true
|
||||||
.on('finish', function () {
|
}),
|
||||||
gulp.src(['tests/**/*_test.js'])
|
istanbul.writeReports({
|
||||||
.pipe(nodeunit_runner())
|
dir: './coverage',
|
||||||
.pipe(istanbul.writeReports({
|
reporters: ['lcov', 'lcovonly', 'html', 'text']
|
||||||
dir: './coverage',
|
})
|
||||||
reporters: ['lcov', 'lcovonly', 'html', 'text']
|
]);
|
||||||
}));
|
});
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task('default', ['lint', 'sloc', 'docs', 'test']);
|
gulp.task('default', ['lint', 'sloc', 'docs', 'test']);
|
@ -1,42 +1,26 @@
|
|||||||
'use strict'
|
'use strict';
|
||||||
|
|
||||||
/** @module Adapter */
|
/** @module Adapter */
|
||||||
;
|
module.exports = class Adapter {
|
||||||
|
|
||||||
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
|
||||||
|
|
||||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
||||||
|
|
||||||
module.exports = (function () {
|
|
||||||
/**
|
/**
|
||||||
* Invoke an adapter
|
* Invoke an adapter
|
||||||
*
|
*
|
||||||
* @param {Object} instance - The connection objec
|
* @param {Object} instance - The connection objec
|
||||||
* @return {void}
|
* @return {void}
|
||||||
*/
|
*/
|
||||||
|
constructor(instance) {
|
||||||
function Adapter(instance) {
|
|
||||||
_classCallCheck(this, Adapter);
|
|
||||||
|
|
||||||
this.instance = instance;
|
this.instance = instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run the sql query as a prepared statement
|
* Run the sql query as a prepared statement
|
||||||
*
|
*
|
||||||
* @param {String} sql - The sql with placeholders
|
* @param {String} sql - The sql with placeholders
|
||||||
* @param {Array} params - The values to insert into the query
|
* @param {Array} params - The values to insert into the query
|
||||||
* @param {Function} callback - Callback to run when a response is recieved
|
* @param {Function} callback - Callback to run when a response is recieved
|
||||||
* @return {void}
|
* @return {void}
|
||||||
*/
|
*/
|
||||||
|
execute(/*sql, params, callback*/) {
|
||||||
_createClass(Adapter, [{
|
throw new Error("Correct adapter not defined for query execution");
|
||||||
key: "execute",
|
}
|
||||||
value: function execute() /*sql, params, callback*/{
|
}
|
||||||
throw new Error("Correct adapter not defined for query execution");
|
|
||||||
}
|
|
||||||
}]);
|
|
||||||
|
|
||||||
return Adapter;
|
|
||||||
})();
|
|
||||||
//# sourceMappingURL=Adapter.js.map
|
|
@ -1 +0,0 @@
|
|||||||
{"version":3,"sources":["Adapter.js"],"names":[],"mappings":"AAAA;;;AAAY,CAAC;;;;;;AAGb,MAAM,CAAC,OAAO;;;;;;;;AAOb,UAPsB,OAAO,CAOjB,QAAQ,EAAE;wBAPA,OAAO;;AAQ5B,MAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;EACzB;;;;;;;;;;AAAA;cATqB,OAAO;;qDAmBM;AAClC,SAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;GACnE;;;QArBqB,OAAO;IAsB7B,CAAA","file":"Adapter.js","sourcesContent":["'use strict';\n\n/** @module Adapter */\nmodule.exports = class Adapter {\n\t/**\n\t * Invoke an adapter\n\t *\n\t * @param {Object} instance - The connection objec\n\t * @return {void}\n\t */\n\tconstructor(instance) {\n\t\tthis.instance = instance;\n\t}\n\n\t/**\n\t * Run the sql query as a prepared statement\n\t *\n\t * @param {String} sql - The sql with placeholders\n\t * @param {Array} params - The values to insert into the query\n\t * @param {Function} callback - Callback to run when a response is recieved\n\t * @return {void}\n\t */\n\texecute(/*sql, params, callback*/) {\n\t\tthrow new Error(\"Correct adapter not defined for query execution\");\n\t}\n}"],"sourceRoot":"/source/"}
|
|
@ -1,78 +1,84 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var _helpers = require('./helpers');
|
let helpers = require('./helpers');
|
||||||
|
|
||||||
var _helpers2 = _interopRequireDefault(_helpers);
|
|
||||||
|
|
||||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base Database Driver
|
* Base Database Driver
|
||||||
*
|
*
|
||||||
* @module driver
|
* @module driver
|
||||||
*/
|
*/
|
||||||
var d = {
|
let d = {
|
||||||
identifierStartChar: '"',
|
identifierStartChar: '"',
|
||||||
identifierEndChar: '"',
|
identifierEndChar: '"',
|
||||||
tablePrefix: null,
|
tablePrefix: null,
|
||||||
hasTruncate: true,
|
hasTruncate: true,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Low level function for naive quoting of strings
|
* Low level function for naive quoting of strings
|
||||||
* @param {String} str
|
|
||||||
* @return {String}
|
* @param {String} str - The sql fragment to quote
|
||||||
* @private
|
* @return {String} - The quoted sql fragment
|
||||||
*/
|
* @private
|
||||||
_quote: function _quote(str) {
|
*/
|
||||||
return _helpers2.default.isString(str) && !(str.startsWith(d.identifierStartChar) || str.endsWith(d.identifierEndChar)) ? d.identifierStartChar + str + d.identifierEndChar : str;
|
_quote: function(str) {
|
||||||
|
return (helpers.isString(str) && ! (str.startsWith(d.identifierStartChar) || str.endsWith(d.identifierEndChar)))
|
||||||
|
? `${d.identifierStartChar}${str}${d.identifierEndChar}`
|
||||||
|
: str;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the limit clause
|
* Set the limit clause
|
||||||
* @param {String} sql
|
|
||||||
* @param {Number} limit
|
|
||||||
* @param {Number|null} offset
|
|
||||||
* @return {String}
|
|
||||||
*/
|
|
||||||
limit: function limit(sql, _limit, offset) {
|
|
||||||
sql += " LIMIT " + _limit;
|
|
||||||
|
|
||||||
if (_helpers2.default.isNumber(offset)) {
|
* @param {String} sql - SQL statement to modify
|
||||||
sql += " OFFSET " + offset;
|
* @param {Number} limit - Maximum number of rows to fetch
|
||||||
|
* @param {Number|null} offset - Number of rows to skip
|
||||||
|
* @return {String} - Modified SQL statement
|
||||||
|
*/
|
||||||
|
limit: function(sql, limit, offset) {
|
||||||
|
sql += ` LIMIT ${limit}`;
|
||||||
|
|
||||||
|
if (helpers.isNumber(offset))
|
||||||
|
{
|
||||||
|
sql += ` OFFSET ${offset}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return sql;
|
return sql;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Quote database table name, and set prefix
|
* Quote database table name, and set prefix
|
||||||
*
|
*
|
||||||
* @param {String} table
|
* @param {String} table - Table name to quote
|
||||||
* @return {String}
|
* @return {String} - Quoted table name
|
||||||
*/
|
*/
|
||||||
quoteTable: function quoteTable(table) {
|
quoteTable: function(table) {
|
||||||
// Quote after prefix
|
// Quote after prefix
|
||||||
return d.quoteIdentifiers(table);
|
return d.quoteIdentifiers(table);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use the driver's escape character to quote identifiers
|
* Use the driver's escape character to quote identifiers
|
||||||
*
|
*
|
||||||
* @param {String|Array}
|
* @param {String|String[]} - String or array of strings to quote identifiers
|
||||||
* @return {String|Array}
|
* @return {String|String[]} - Quoted identifier(s)
|
||||||
*/
|
*/
|
||||||
quoteIdentifiers: function quoteIdentifiers(str) {
|
quoteIdentifiers: function(str) {
|
||||||
var hiers, raw;
|
let hiers, raw;
|
||||||
var pattern = new RegExp(d.identifierStartChar + '(' + '([a-zA-Z0-9_]+)' + '(\((.*?)\))' + ')' + d.identifierEndChar, 'ig');
|
let pattern = new RegExp(
|
||||||
|
`${d.identifierStartChar}(`
|
||||||
|
+ '([a-zA-Z0-9_]+)' + '(\((.*?)\))'
|
||||||
|
+ `)${d.identifierEndChar}`, 'ig');
|
||||||
|
|
||||||
// Recurse for arrays of identifiiers
|
// Recurse for arrays of identifiiers
|
||||||
if (Array.isArray(str)) {
|
if (Array.isArray(str))
|
||||||
|
{
|
||||||
return str.map(d.quoteIdentifiers);
|
return str.map(d.quoteIdentifiers);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle commas
|
// Handle commas
|
||||||
if (str.includes(',')) {
|
if (str.includes(','))
|
||||||
var parts = str.split(',').map(_helpers2.default.stringTrim);
|
{
|
||||||
|
let parts = str.split(',').map(helpers.stringTrim);
|
||||||
str = parts.map(d.quoteIdentifiers).join(',');
|
str = parts.map(d.quoteIdentifiers).join(',');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,14 +87,15 @@ var d = {
|
|||||||
raw = hiers.join('.');
|
raw = hiers.join('.');
|
||||||
|
|
||||||
// Fix functions
|
// Fix functions
|
||||||
if (raw.includes('(') && raw.includes(')')) {
|
if (raw.includes('(') && raw.includes(')'))
|
||||||
var funcs = pattern.exec(raw);
|
{
|
||||||
|
let funcs = pattern.exec(raw);
|
||||||
|
|
||||||
// Unquote the function
|
// Unquote the function
|
||||||
raw = raw.replace(funcs[0], funcs[1]);
|
raw = raw.replace(funcs[0], funcs[1]);
|
||||||
|
|
||||||
// Quote the identifiers inside of the parens
|
// Quote the identifiers inside of the parens
|
||||||
var inParens = funcs[3].substring(1, funcs[3].length - 1);
|
let inParens = funcs[3].substring(1, funcs[3].length -1);
|
||||||
raw = raw.replace(inParens, d.quoteIdentifiers(inParens));
|
raw = raw.replace(inParens, d.quoteIdentifiers(inParens));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,13 +103,15 @@ var d = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SQL to truncate the passed table
|
* SQL to truncate the passed table
|
||||||
*
|
*
|
||||||
* @param {String} table
|
* @param {String} table - Table to truncate
|
||||||
* @return {String} - sql
|
* @return {String} - Truncation SQL
|
||||||
*/
|
*/
|
||||||
truncate: function truncate(table) {
|
truncate: function(table) {
|
||||||
var sql = d.hasTruncate ? 'TRUNCATE ' : 'DELETE FROM ';
|
let sql = (d.hasTruncate)
|
||||||
|
? 'TRUNCATE '
|
||||||
|
: 'DELETE FROM ';
|
||||||
|
|
||||||
sql += d.quoteTable(table);
|
sql += d.quoteTable(table);
|
||||||
|
|
||||||
@ -110,24 +119,24 @@ var d = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SQL to insert a group of rows
|
* SQL to insert a group of rows
|
||||||
*
|
*
|
||||||
* @param {String} table - The table to insert to
|
* @param {String} table - The table to insert to
|
||||||
* @param {Array} [data] - The array of object containing data to insert
|
* @param {Array} [data] - The array of object containing data to insert
|
||||||
* @return {String}
|
* @return {String} - Query and data to insert
|
||||||
*/
|
*/
|
||||||
insertBatch: function insertBatch(table, data) {
|
insertBatch: function(table, data) {
|
||||||
var vals = [],
|
let vals = [],
|
||||||
fields = Object.keys(data[0]),
|
fields = Object.keys(data[0]),
|
||||||
sql = "",
|
sql = "",
|
||||||
params = [],
|
params = [],
|
||||||
paramString = "",
|
paramString = "",
|
||||||
paramList = [];
|
paramList = [];
|
||||||
|
|
||||||
// Get the data values to insert, so they can
|
// Get the data values to insert, so they can
|
||||||
// be parameterized
|
// be parameterized
|
||||||
data.forEach(function (obj) {
|
data.forEach(obj => {
|
||||||
Object.keys(obj).forEach(function (key) {
|
Object.keys(obj).forEach(key => {
|
||||||
vals.push(obj[key]);
|
vals.push(obj[key]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -136,7 +145,9 @@ var d = {
|
|||||||
// object inserted
|
// object inserted
|
||||||
table = d.quoteTable(table);
|
table = d.quoteTable(table);
|
||||||
|
|
||||||
sql += "INSERT INTO " + table + " (" + d.quoteIdentifiers(fields).join(",") + ") VALUES ";
|
sql += `INSERT INTO ${table} (`
|
||||||
|
+ d.quoteIdentifiers(fields).join(",")
|
||||||
|
+ ") VALUES ";
|
||||||
|
|
||||||
// Create placeholder groups
|
// Create placeholder groups
|
||||||
params = Array(fields.length).fill('?');
|
params = Array(fields.length).fill('?');
|
||||||
@ -154,4 +165,3 @@ var d = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
module.exports = d;
|
module.exports = d;
|
||||||
//# sourceMappingURL=DriverBase.js.map
|
|
||||||
|
File diff suppressed because one or more lines are too long
@ -1,22 +1,18 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var _DriverBase = require('./DriverBase');
|
let driverBase = require('./DriverBase'),
|
||||||
|
getArgs = require('getargs');
|
||||||
|
|
||||||
var _DriverBase2 = _interopRequireDefault(_DriverBase);
|
module.exports = class DriverClass {
|
||||||
|
constructor(/* properties:object */) {
|
||||||
|
let args = getArgs('[properties]:object', arguments);
|
||||||
|
|
||||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
args.properties = args.properties || {};
|
||||||
|
|
||||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
Object.keys(driverBase).forEach(key => {
|
||||||
|
this[key] = (Object.keys(args.properties).indexOf(key) !== -1)
|
||||||
module.exports = function DriverClass() {
|
? args.properties[key]
|
||||||
var _this = this;
|
: driverBase[key];
|
||||||
|
});
|
||||||
var properties = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
|
}
|
||||||
|
}
|
||||||
_classCallCheck(this, DriverClass);
|
|
||||||
|
|
||||||
Object.keys(_DriverBase2.default).forEach(function (key) {
|
|
||||||
_this[key] = Object.keys(properties).indexOf(key) !== -1 ? properties[key] : _DriverBase2.default[key];
|
|
||||||
});
|
|
||||||
};
|
|
||||||
//# sourceMappingURL=DriverClass.js.map
|
|
@ -1 +0,0 @@
|
|||||||
{"version":3,"sources":["DriverClass.js"],"names":[],"mappings":"AAAA,YAAY,CAAC;;;;;;;;;;AAIb,MAAM,CAAC,OAAO,GACb,SADsB,WAAW,GACJ;;;KAAjB,UAAU,yDAAG,EAAE;;uBADL,WAAW;;AAEhC,OAAM,CAAC,IAAI,sBAAY,CAAC,OAAO,CAAC,UAAC,GAAG,EAAK;AACxC,QAAK,GAAG,CAAC,GAAG,AAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GACrD,UAAU,CAAC,GAAG,CAAC,GACf,qBAAW,GAAG,CAAC,CAAC;EACnB,CAAC,CAAC;CACH,AACD,CAAA","file":"DriverClass.js","sourcesContent":["'use strict';\n\nimport driverBase from './DriverBase';\n\nmodule.exports = class DriverClass {\n\tconstructor(properties = {}) {\n\t\tObject.keys(driverBase).forEach((key) => {\n\t\t\tthis[key] = (Object.keys(properties).indexOf(key) !== -1)\n\t\t\t\t? properties[key]\n\t\t\t\t: driverBase[key];\n\t\t});\n\t}\n}"],"sourceRoot":"/source/"}
|
|
135
lib/NodeQuery.js
135
lib/NodeQuery.js
@ -1,103 +1,74 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
let instance = null;
|
||||||
|
let fs = require('fs'),
|
||||||
var _fs = require('fs');
|
helpers = require('./helpers'),
|
||||||
|
QueryBuilder = require('./QueryBuilder');
|
||||||
var _fs2 = _interopRequireDefault(_fs);
|
|
||||||
|
|
||||||
var _helpers = require('./helpers');
|
|
||||||
|
|
||||||
var _helpers2 = _interopRequireDefault(_helpers);
|
|
||||||
|
|
||||||
var _QueryBuilder = require('./QueryBuilder');
|
|
||||||
|
|
||||||
var _QueryBuilder2 = _interopRequireDefault(_QueryBuilder);
|
|
||||||
|
|
||||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
||||||
|
|
||||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
||||||
|
|
||||||
var instance = null;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @module NodeQuery
|
* @module NodeQuery
|
||||||
*/
|
*/
|
||||||
|
class NodeQuery {
|
||||||
var NodeQuery = (function () {
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*/
|
*
|
||||||
|
* @return {void}
|
||||||
function NodeQuery() {
|
*/
|
||||||
_classCallCheck(this, NodeQuery);
|
constructor() {
|
||||||
|
|
||||||
this.instance = null;
|
this.instance = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a query builder object
|
* Create a query builder object
|
||||||
*
|
*
|
||||||
* @memberOf NodeQuery
|
* @memberOf NodeQuery
|
||||||
* @param {String} drivername - The name of the database type, eg. mysql or pg
|
* @param {String} driverType - The name of the database type, eg. mysql or pg
|
||||||
* @param {Object} connObject - A connection object from the database library you are connecting with
|
* @param {Object} connObject - A connection object from the database library you are connecting with
|
||||||
* @param {String} [connLib] - The name of the db connection library you are using, eg. mysql or mysql2. Optional if the same as drivername
|
* @param {String} [connLib] - The name of the db connection library you are using, eg. mysql or mysql2. Optional if the same as drivername
|
||||||
* @return {QueryBuilder}
|
* @return {QueryBuilder} - The Query Builder object
|
||||||
*/
|
*/
|
||||||
|
init(driverType, connObject, connLib) {
|
||||||
|
connLib = connLib || driverType;
|
||||||
|
|
||||||
_createClass(NodeQuery, [{
|
let paths = {
|
||||||
key: 'init',
|
driver: `${__dirname}/drivers/` + helpers.upperCaseFirst(driverType),
|
||||||
value: function init(driverType, connObject, connLib) {
|
adapter: `${__dirname}/adapters/${connLib}`
|
||||||
connLib = connLib || driverType;
|
};
|
||||||
|
|
||||||
var paths = {
|
Object.keys(paths).forEach(type => {
|
||||||
driver: __dirname + '/drivers/' + _helpers2.default.upperCaseFirst(driverType),
|
if ( ! fs.existsSync(paths[type]))
|
||||||
adapter: __dirname + '/adapters/' + connLib
|
{
|
||||||
};
|
throw new Error(
|
||||||
|
`Selected ${type} (` +
|
||||||
/*Object.keys(paths).forEach((type) => {
|
helpers.upperCaseFirst(driverType) +
|
||||||
if ( ! fs.existsSync(paths[type]))
|
`) does not exist!`
|
||||||
{
|
);
|
||||||
console.log(paths[type]);
|
|
||||||
throw new Error(
|
|
||||||
`Selected ${type} (` +
|
|
||||||
helpers.upperCaseFirst(driverType) +
|
|
||||||
`) does not exist!`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});*/
|
|
||||||
|
|
||||||
var driver = require(paths.driver);
|
|
||||||
var $adapter = require(paths.adapter);
|
|
||||||
var adapter = new $adapter(connObject);
|
|
||||||
|
|
||||||
this.instance = new _QueryBuilder2.default(driver, adapter);
|
|
||||||
|
|
||||||
return this.instance;
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
key: 'getQuery',
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return an existing query builder instance
|
|
||||||
*
|
|
||||||
* @memberOf NodeQuery
|
|
||||||
* @return {QueryBuilder}
|
|
||||||
*/
|
|
||||||
value: function getQuery() {
|
|
||||||
if (!this.instance) {
|
|
||||||
throw new Error("No Query Builder instance to return");
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return this.instance;
|
let driver = require(paths.driver);
|
||||||
|
let $adapter = require(paths.adapter);
|
||||||
|
let adapter = new $adapter(connObject);
|
||||||
|
|
||||||
|
this.instance = new QueryBuilder(driver, adapter);
|
||||||
|
|
||||||
|
return this.instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return an existing query builder instance
|
||||||
|
*
|
||||||
|
* @return {QueryBuilder} - The Query Builder object
|
||||||
|
*/
|
||||||
|
getQuery() {
|
||||||
|
if ( ! this.instance) {
|
||||||
|
throw new Error("No Query Builder instance to return");
|
||||||
}
|
}
|
||||||
}]);
|
|
||||||
|
|
||||||
return NodeQuery;
|
return this.instance;
|
||||||
})();
|
}
|
||||||
|
|
||||||
;
|
}
|
||||||
|
|
||||||
module.exports = new NodeQuery();
|
module.exports = new NodeQuery();
|
||||||
//# sourceMappingURL=NodeQuery.js.map
|
|
||||||
|
@ -1 +0,0 @@
|
|||||||
{"version":3,"sources":["NodeQuery.js"],"names":[],"mappings":"AAAA,YAAY,CAAC;;;;;;;;;;;;;;;;;;;;AAEb,IAAI,QAAQ,GAAG,IAAI,CAAC;;;;;;IAQd,SAAS;;;;;;AAKd,UALK,SAAS,GAKA;wBALT,SAAS;;AAMb,MAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;EACrB;;;;;;;;;;;AAAA;cAPI,SAAS;;uBAkBT,UAAU,EAAE,UAAU,EAAE,OAAO,EAAE;AACrC,UAAO,GAAG,OAAO,IAAI,UAAU,CAAC;;AAEhC,OAAI,KAAK,GAAG;AACX,UAAM,EAAE,AAAG,SAAS,iBAAc,kBAAQ,cAAc,CAAC,UAAU,CAAC;AACpE,WAAO,EAAK,SAAS,kBAAa,OAAO,AAAE;IAC3C;;;;;;;;;;;;;;AAAC,AAcF,OAAI,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;AACnC,OAAI,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;AACtC,OAAI,OAAO,GAAG,IAAI,QAAQ,CAAC,UAAU,CAAC,CAAC;;AAEvC,OAAI,CAAC,QAAQ,GAAG,2BAAiB,MAAM,EAAE,OAAO,CAAC,CAAC;;AAElD,UAAO,IAAI,CAAC,QAAQ,CAAC;GACrB;;;;;;;;;;6BAQU;AACV,OAAK,CAAE,IAAI,CAAC,QAAQ,EAAE;AACrB,UAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;IACvD;;AAED,UAAO,IAAI,CAAC,QAAQ,CAAC;GACrB;;;QA3DI,SAAS;;;AA6Dd,CAAC;;AAEF,MAAM,CAAC,OAAO,GAAG,IAAI,SAAS,EAAE,CAAC","file":"NodeQuery.js","sourcesContent":["\"use strict\";\n\nlet instance = null;\nimport fs from 'fs';\nimport helpers from './helpers';\nimport QueryBuilder from './QueryBuilder';\n\n/**\n * @module NodeQuery\n */\nclass NodeQuery {\n\n\t/**\n\t * Constructor\n\t */\n\tconstructor() {\n\t\tthis.instance = null;\n\t}\n\n\t/**\n\t * Create a query builder object\n\t *\n\t * @memberOf NodeQuery\n\t * @param {String} drivername - The name of the database type, eg. mysql or pg\n\t * @param {Object} connObject - A connection object from the database library you are connecting with\n\t * @param {String} [connLib] - The name of the db connection library you are using, eg. mysql or mysql2. Optional if the same as drivername\n\t * @return {QueryBuilder}\n\t */\n\tinit(driverType, connObject, connLib) {\n\t\tconnLib = connLib || driverType;\n\n\t\tlet paths = {\n\t\t\tdriver: `${__dirname}/drivers/` + helpers.upperCaseFirst(driverType),\n\t\t\tadapter: `${__dirname}/adapters/${connLib}`\n\t\t};\n\n\t\t/*Object.keys(paths).forEach((type) => {\n\t\t\tif ( ! fs.existsSync(paths[type]))\n\t\t\t{\n\t\t\t\tconsole.log(paths[type]);\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Selected ${type} (` +\n\t\t\t\t\thelpers.upperCaseFirst(driverType) +\n\t\t\t\t\t`) does not exist!`\n\t\t\t\t);\n\t\t\t}\n\t\t});*/\n\n\t\tlet driver = require(paths.driver);\n\t\tlet $adapter = require(paths.adapter);\n\t\tlet adapter = new $adapter(connObject);\n\n\t\tthis.instance = new QueryBuilder(driver, adapter);\n\n\t\treturn this.instance;\n\t};\n\n\t/**\n\t * Return an existing query builder instance\n\t *\n\t * @memberOf NodeQuery\n\t * @return {QueryBuilder}\n\t */\n\tgetQuery() {\n\t\tif ( ! this.instance) {\n\t\t\tthrow new Error(\"No Query Builder instance to return\");\n\t\t}\n\n\t\treturn this.instance;\n\t};\n\n};\n\nmodule.exports = new NodeQuery();"],"sourceRoot":"/source/"}
|
|
1821
lib/QueryBuilder.js
1821
lib/QueryBuilder.js
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@ -1,35 +1,20 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
let helpers = require('./helpers');
|
||||||
|
|
||||||
var _helpers = require('./helpers');
|
|
||||||
|
|
||||||
var _helpers2 = _interopRequireDefault(_helpers);
|
|
||||||
|
|
||||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
||||||
|
|
||||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
module.exports = class QueryParser {
|
||||||
* @constructor
|
|
||||||
* @param {Driver} - The driver object for the database in use
|
|
||||||
* @module query-parser
|
|
||||||
*/
|
|
||||||
module.exports = (function () {
|
|
||||||
/**
|
/**
|
||||||
* @constructor
|
* @constructor
|
||||||
* @param {Driver} - The driver object for the database in use
|
*
|
||||||
* @return {void}
|
* @param {Driver} driver - The driver object for the database in use
|
||||||
*/
|
* @return {void}
|
||||||
|
*/
|
||||||
function QueryParser(driver) {
|
constructor(driver) {
|
||||||
_classCallCheck(this, QueryParser);
|
|
||||||
|
|
||||||
this.driver = driver;
|
this.driver = driver;
|
||||||
|
|
||||||
var matchPatterns = {
|
let matchPatterns = {
|
||||||
'function': /([a-z0-9_]+\((.*)\))/i,
|
'function': /([a-z0-9_]+\((.*)\))/i,
|
||||||
operator: /\!=?|\=|\+|&&?|~|\|\|?|\^|\/|<>|>=?|<=?|\-|%|OR|AND|NOT|XOR/ig,
|
operator: /\!=?|\=|\+|&&?|~|\|\|?|\^|\/|<>|>=?|<=?|\-|%|OR|AND|NOT|XOR/ig,
|
||||||
literal: /([0-9]+)|'(.*?)'|true|false/ig
|
literal: /([0-9]+)|'(.*?)'|true|false/ig
|
||||||
@ -37,242 +22,248 @@ module.exports = (function () {
|
|||||||
|
|
||||||
// Full pattern for identifiers
|
// Full pattern for identifiers
|
||||||
// Making sure that literals and functions aren't matched
|
// Making sure that literals and functions aren't matched
|
||||||
matchPatterns.identifier = new RegExp('(' + '(?!' + matchPatterns['function'].source + '|' + matchPatterns.literal.source + ')' + '([a-z_\-]+[0-9]*\\.?)' + ')+', 'ig');
|
matchPatterns.identifier = new RegExp(
|
||||||
|
'('
|
||||||
|
+ '(?!'
|
||||||
|
+ matchPatterns['function'].source + '|'
|
||||||
|
+ matchPatterns.literal.source
|
||||||
|
+ ')'
|
||||||
|
+ '([a-z_\-]+[0-9]*\\.?)'
|
||||||
|
+ ')+'
|
||||||
|
, 'ig');
|
||||||
|
|
||||||
// Full pattern for determining ordering of the pieces
|
// Full pattern for determining ordering of the pieces
|
||||||
matchPatterns.joinCombined = new RegExp(matchPatterns['function'].source + "+|" + matchPatterns.literal.source + '+|' + matchPatterns.identifier.source + '|(' + matchPatterns.operator.source + ')+', 'ig');
|
matchPatterns.joinCombined = new RegExp(
|
||||||
|
matchPatterns['function'].source + "+|"
|
||||||
|
+ matchPatterns.literal.source + '+|'
|
||||||
|
+ matchPatterns.identifier.source
|
||||||
|
+ '|(' + matchPatterns.operator.source + ')+'
|
||||||
|
, 'ig');
|
||||||
|
|
||||||
this.matchPatterns = matchPatterns;
|
this.matchPatterns = matchPatterns;
|
||||||
this.identifierBlacklist = ['true', 'false', 'null'];
|
this.identifierBlacklist = ['true','false','null'];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filter matched patterns
|
* Filter matched patterns
|
||||||
*
|
*
|
||||||
* @param {Array} array
|
* @param {Array} array - Set of possible matches
|
||||||
* @return {Array|null}
|
* @return {Array|null} - Filtered set of possible matches
|
||||||
*/
|
*/
|
||||||
|
filterMatches(array) {
|
||||||
|
let output = [];
|
||||||
|
|
||||||
_createClass(QueryParser, [{
|
// Return non-array matches
|
||||||
key: 'filterMatches',
|
if (helpers.isNull(array)) return null;
|
||||||
value: function filterMatches(array) {
|
if (helpers.isScalar(array) || helpers.isUndefined(array)) return output;
|
||||||
var output = [];
|
|
||||||
|
|
||||||
// Return non-array matches
|
array.forEach(item => {
|
||||||
if (_helpers2.default.isNull(array)) return null;
|
output.push(item);
|
||||||
if (_helpers2.default.isScalar(array) || _helpers2.default.isUndefined(array)) return output;
|
});
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
array.forEach(function (item) {
|
/**
|
||||||
output.push(item);
|
* Check if the string contains an operator, and if so, return the operator(s).
|
||||||
});
|
* If there are no matches, return null
|
||||||
return output;
|
*
|
||||||
}
|
* @param {String} string - the string to check
|
||||||
|
* @return {Array|null} - List of operators
|
||||||
|
*/
|
||||||
|
hasOperator(string) {
|
||||||
|
return this.filterMatches(string.match(this.matchPatterns.operator));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the string contains an operator, and if so, return the operator(s).
|
* Tokenize the sql into parts for additional processing
|
||||||
* If there are no matches, return null
|
*
|
||||||
*
|
* @param {String} sql - Join sql to parse
|
||||||
* @param {String} string - the string to check
|
* @return {Object} - Join condition components
|
||||||
* @return {Array|null}
|
*/
|
||||||
*/
|
parseJoin(sql) {
|
||||||
|
let matches = {};
|
||||||
|
let output = {
|
||||||
|
functions: [],
|
||||||
|
identifiers: [],
|
||||||
|
operators: [],
|
||||||
|
literals: []
|
||||||
|
};
|
||||||
|
|
||||||
}, {
|
// Get clause components
|
||||||
key: 'hasOperator',
|
matches.functions = sql.match(new RegExp(this.matchPatterns['function'].source, 'ig'));
|
||||||
value: function hasOperator(string) {
|
matches.identifiers = sql.match(this.matchPatterns.identifier);
|
||||||
return this.filterMatches(string.match(this.matchPatterns.operator));
|
matches.operators = sql.match(this.matchPatterns.operator);
|
||||||
}
|
matches.literals = sql.match(this.matchPatterns.literal);
|
||||||
|
|
||||||
/**
|
// Get everything at once for ordering
|
||||||
* Tokenize the sql into parts for additional processing
|
matches.combined = sql.match(this.matchPatterns.joinCombined);
|
||||||
*
|
|
||||||
* @param {String} sql
|
|
||||||
* @return {Object}
|
|
||||||
*/
|
|
||||||
|
|
||||||
}, {
|
// Flatten the matches to increase relevance
|
||||||
key: 'parseJoin',
|
Object.keys(matches).forEach(key => {
|
||||||
value: function parseJoin(sql) {
|
output[key] = this.filterMatches(matches[key]);
|
||||||
var _this = this;
|
});
|
||||||
|
|
||||||
var matches = {};
|
return output;
|
||||||
var output = {
|
}
|
||||||
functions: [],
|
|
||||||
identifiers: [],
|
|
||||||
operators: [],
|
|
||||||
literals: []
|
|
||||||
};
|
|
||||||
|
|
||||||
// Get clause components
|
/**
|
||||||
matches.functions = sql.match(new RegExp(this.matchPatterns['function'].source, 'ig'));
|
* Return the output of the parsing of the join condition
|
||||||
matches.identifiers = sql.match(this.matchPatterns.identifier);
|
*
|
||||||
matches.operators = sql.match(this.matchPatterns.operator);
|
* @param {String} condition - The join condition to evalate
|
||||||
matches.literals = sql.match(this.matchPatterns.literal);
|
* @return {String} - The parsed/escaped join condition
|
||||||
|
*/
|
||||||
|
compileJoin(condition) {
|
||||||
|
let parts = this.parseJoin(condition);
|
||||||
|
let count = parts.identifiers.length;
|
||||||
|
let i;
|
||||||
|
|
||||||
// Get everything at once for ordering
|
// Quote the identifiers
|
||||||
matches.combined = sql.match(this.matchPatterns.joinCombined);
|
parts.combined.forEach((part, i) => {
|
||||||
|
if (parts.identifiers.indexOf(part) !== -1 && ! helpers.isNumber(part))
|
||||||
|
{
|
||||||
|
parts.combined[i] = this.driver.quoteIdentifiers(part);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Flatten the matches to increase relevance
|
return parts.combined.join(' ');
|
||||||
Object.keys(matches).forEach(function (key) {
|
}
|
||||||
output[key] = _this.filterMatches(matches[key]);
|
|
||||||
});
|
|
||||||
|
|
||||||
return output;
|
/**
|
||||||
}
|
* Parse a where clause to separate functions from values
|
||||||
|
*
|
||||||
|
* @param {Driver} driver - The current db driver
|
||||||
|
* @param {State} state - Query Builder state object
|
||||||
|
* @return {String} - The parsed/escaped where condition
|
||||||
|
*/
|
||||||
|
parseWhere(driver, state) {
|
||||||
|
let whereMap = state.whereMap;
|
||||||
|
let whereValues = state.rawWhereValues;
|
||||||
|
|
||||||
/**
|
let outputMap = [];
|
||||||
* Return the output of the parsing of the join condition
|
let outputValues = [];
|
||||||
*
|
|
||||||
* @param {String} condition - The join condition to evalate
|
|
||||||
* @return {String} - The parsed/escaped join condition
|
|
||||||
*/
|
|
||||||
|
|
||||||
}, {
|
Object.keys(whereMap).forEach(key => {
|
||||||
key: 'compileJoin',
|
// Combine fields, operators, functions and values into a full clause
|
||||||
value: function compileJoin(condition) {
|
// to have a common starting flow
|
||||||
var _this2 = this;
|
let fullClause = '';
|
||||||
|
|
||||||
var parts = this.parseJoin(condition);
|
// Add an explicit = sign where one is inferred
|
||||||
var count = parts.identifiers.length;
|
if ( ! this.hasOperator(key))
|
||||||
var i = undefined;
|
{
|
||||||
|
fullClause = key + ' = ' + whereMap[key];
|
||||||
|
}
|
||||||
|
else if (whereMap[key] === key)
|
||||||
|
{
|
||||||
|
fullClause = key;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fullClause = key + ' ' + whereMap[key];
|
||||||
|
}
|
||||||
|
|
||||||
// Quote the identifiers
|
// Separate the clause into separate pieces
|
||||||
parts.combined.forEach(function (part, i) {
|
let parts = this.parseJoin(fullClause);
|
||||||
if (parts.identifiers.indexOf(part) !== -1 && !_helpers2.default.isNumber(part)) {
|
|
||||||
parts.combined[i] = _this2.driver.quoteIdentifiers(part);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return parts.combined.join(' ');
|
// Filter explicit literals from lists of matches
|
||||||
}
|
if (whereValues.indexOf(whereMap[key]) !== -1)
|
||||||
|
{
|
||||||
|
let value = whereMap[key];
|
||||||
|
let identIndex = (helpers.isArray(parts.identifiers)) ? parts.identifiers.indexOf(value) : -1;
|
||||||
|
let litIndex = (helpers.isArray(parts.literals)) ? parts.literals.indexOf(value) : -1;
|
||||||
|
let combIndex = (helpers.isArray(parts.combined)) ? parts.combined.indexOf(value) : -1;
|
||||||
|
let funcIndex = (helpers.isArray(parts.functions)) ? parts.functions.indexOf(value) : -1;
|
||||||
|
let inOutputArray = outputValues.indexOf(value) !== -1;
|
||||||
|
|
||||||
/**
|
// Remove the identifier in question,
|
||||||
* Parse a where clause to separate functions from values
|
// and add to the output values array
|
||||||
*
|
if (identIndex !== -1)
|
||||||
* @param {Driver} driver
|
{
|
||||||
* @param {State} state
|
parts.identifiers.splice(identIndex, 1);
|
||||||
* @return {String} - The parsed/escaped where condition
|
|
||||||
*/
|
|
||||||
|
|
||||||
}, {
|
if ( ! inOutputArray)
|
||||||
key: 'parseWhere',
|
{
|
||||||
value: function parseWhere(driver, state) {
|
outputValues.push(value);
|
||||||
var _this3 = this;
|
inOutputArray = true;
|
||||||
|
}
|
||||||
var whereMap = state.whereMap;
|
|
||||||
var whereValues = state.rawWhereValues;
|
|
||||||
|
|
||||||
var outputMap = [];
|
|
||||||
var outputValues = [];
|
|
||||||
|
|
||||||
Object.keys(whereMap).forEach(function (key) {
|
|
||||||
// Combine fields, operators, functions and values into a full clause
|
|
||||||
// to have a common starting flow
|
|
||||||
var fullClause = '';
|
|
||||||
|
|
||||||
// Add an explicit = sign where one is inferred
|
|
||||||
if (!_this3.hasOperator(key)) {
|
|
||||||
fullClause = key + ' = ' + whereMap[key];
|
|
||||||
} else if (whereMap[key] === key) {
|
|
||||||
fullClause = key;
|
|
||||||
} else {
|
|
||||||
fullClause = key + ' ' + whereMap[key];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Separate the clause into separate pieces
|
// Remove the value from the literals list
|
||||||
var parts = _this3.parseJoin(fullClause);
|
// so it is not added twice
|
||||||
|
if (litIndex !== -1)
|
||||||
|
{
|
||||||
|
parts.literals.splice(litIndex, 1);
|
||||||
|
|
||||||
// Filter explicit literals from lists of matches
|
if ( ! inOutputArray)
|
||||||
if (whereValues.indexOf(whereMap[key]) !== -1) {
|
{
|
||||||
var value = whereMap[key];
|
outputValues.push(value);
|
||||||
var identIndex = _helpers2.default.isArray(parts.identifiers) ? parts.identifiers.indexOf(value) : -1;
|
inOutputArray = true;
|
||||||
var litIndex = _helpers2.default.isArray(parts.literals) ? parts.literals.indexOf(value) : -1;
|
}
|
||||||
var combIndex = _helpers2.default.isArray(parts.combined) ? parts.combined.indexOf(value) : -1;
|
}
|
||||||
var funcIndex = _helpers2.default.isArray(parts.functions) ? parts.functions.indexOf(value) : -1;
|
|
||||||
var inOutputArray = outputValues.indexOf(value) !== -1;
|
|
||||||
|
|
||||||
// Remove the identifier in question,
|
// Remove the value from the combined list
|
||||||
// and add to the output values array
|
// and replace it with a placeholder
|
||||||
if (identIndex !== -1) {
|
if (combIndex !== -1)
|
||||||
parts.identifiers.splice(identIndex, 1);
|
{
|
||||||
|
// Make sure to skip functions when replacing values
|
||||||
|
if (funcIndex === -1)
|
||||||
|
{
|
||||||
|
parts.combined[combIndex] = '?';
|
||||||
|
|
||||||
if (!inOutputArray) {
|
if ( ! inOutputArray)
|
||||||
|
{
|
||||||
outputValues.push(value);
|
outputValues.push(value);
|
||||||
inOutputArray = true;
|
inOutputArray = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Remove the value from the literals list
|
// Filter false positive identifiers
|
||||||
// so it is not added twice
|
parts.identifiers = parts.identifiers || [];
|
||||||
if (litIndex !== -1) {
|
parts.identifiers = parts.identifiers.filter(item => {
|
||||||
parts.literals.splice(litIndex, 1);
|
let isInCombinedMatches = parts.combined.indexOf(item) !== -1;
|
||||||
|
let isNotInBlackList = this.identifierBlacklist.indexOf(item.toLowerCase()) === -1;
|
||||||
|
|
||||||
if (!inOutputArray) {
|
return isInCombinedMatches && isNotInBlackList;
|
||||||
outputValues.push(value);
|
}, this);
|
||||||
inOutputArray = true;
|
|
||||||
}
|
// Quote identifiers
|
||||||
|
if (helpers.isArray(parts.identifiers))
|
||||||
|
{
|
||||||
|
parts.identifiers.forEach(ident => {
|
||||||
|
let index = parts.combined.indexOf(ident);
|
||||||
|
if (index !== -1)
|
||||||
|
{
|
||||||
|
parts.combined[index] = driver.quoteIdentifiers(ident);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Remove the value from the combined list
|
// Replace each literal with a placeholder in the map
|
||||||
// and replace it with a placeholder
|
// and add the literal to the values,
|
||||||
if (combIndex !== -1) {
|
// This should only apply to literal values that are not
|
||||||
// Make sure to skip functions when replacing values
|
// explicitly mapped to values, but have to be parsed from
|
||||||
if (funcIndex === -1) {
|
// a where condition,
|
||||||
parts.combined[combIndex] = '?';
|
if (helpers.isArray(parts.literals))
|
||||||
|
{
|
||||||
|
parts.literals.forEach(lit => {
|
||||||
|
let litIndex = parts.combined.indexOf(lit);
|
||||||
|
|
||||||
if (!inOutputArray) {
|
if (litIndex !== -1)
|
||||||
outputValues.push(value);
|
{
|
||||||
inOutputArray = true;
|
parts.combined[litIndex] = (helpers.isArray(parts.operators)) ? '?' : '= ?';
|
||||||
}
|
outputValues.push(lit);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Filter false positive identifiers
|
outputMap.push(parts.combined.join(' '));
|
||||||
parts.identifiers = parts.identifiers || [];
|
});
|
||||||
parts.identifiers = parts.identifiers.filter(function (item) {
|
|
||||||
var isInCombinedMatches = parts.combined.indexOf(item) !== -1;
|
|
||||||
var isNotInBlackList = _this3.identifierBlacklist.indexOf(item.toLowerCase()) === -1;
|
|
||||||
|
|
||||||
return isInCombinedMatches && isNotInBlackList;
|
state.rawWhereValues = [];
|
||||||
}, _this3);
|
state.whereValues = state.whereValues.concat(outputValues);
|
||||||
|
state.whereMap = outputMap;
|
||||||
|
|
||||||
// Quote identifiers
|
return state;
|
||||||
if (_helpers2.default.isArray(parts.identifiers)) {
|
}
|
||||||
parts.identifiers.forEach(function (ident) {
|
}
|
||||||
var index = parts.combined.indexOf(ident);
|
|
||||||
if (index !== -1) {
|
|
||||||
parts.combined[index] = driver.quoteIdentifiers(ident);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Replace each literal with a placeholder in the map
|
|
||||||
// and add the literal to the values,
|
|
||||||
// This should only apply to literal values that are not
|
|
||||||
// explicitly mapped to values, but have to be parsed from
|
|
||||||
// a where condition,
|
|
||||||
if (_helpers2.default.isArray(parts.literals)) {
|
|
||||||
parts.literals.forEach(function (lit) {
|
|
||||||
var litIndex = parts.combined.indexOf(lit);
|
|
||||||
|
|
||||||
if (litIndex !== -1) {
|
|
||||||
parts.combined[litIndex] = _helpers2.default.isArray(parts.operators) ? '?' : '= ?';
|
|
||||||
outputValues.push(lit);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
outputMap.push(parts.combined.join(' '));
|
|
||||||
});
|
|
||||||
|
|
||||||
state.rawWhereValues = [];
|
|
||||||
state.whereValues = state.whereValues.concat(outputValues);
|
|
||||||
state.whereMap = outputMap;
|
|
||||||
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
}]);
|
|
||||||
|
|
||||||
return QueryParser;
|
|
||||||
})();
|
|
||||||
//# sourceMappingURL=QueryParser.js.map
|
|
File diff suppressed because one or more lines are too long
53
lib/State.js
53
lib/State.js
@ -1,34 +1,29 @@
|
|||||||
'use strict'
|
'use strict';
|
||||||
|
|
||||||
/** @module State */
|
/** @module State */
|
||||||
;
|
module.exports = class State {
|
||||||
|
constructor() {
|
||||||
|
// Arrays/maps
|
||||||
|
this.queryMap = [];
|
||||||
|
this.values = [];
|
||||||
|
this.whereValues = [];
|
||||||
|
this.setArrayKeys = [];
|
||||||
|
this.orderArray = [];
|
||||||
|
this.groupArray = [];
|
||||||
|
this.havingMap = [];
|
||||||
|
this.whereMap = [];
|
||||||
|
this.rawWhereValues = [];
|
||||||
|
|
||||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
// Partials
|
||||||
|
this.selectString = '';
|
||||||
|
this.fromString = '';
|
||||||
|
this.setString = '';
|
||||||
|
this.orderString = '';
|
||||||
|
this.groupString = '';
|
||||||
|
|
||||||
module.exports = function State() {
|
// Other various values
|
||||||
_classCallCheck(this, State);
|
this.limit = null;
|
||||||
|
this.offset = null;
|
||||||
// Arrays/maps
|
}
|
||||||
this.queryMap = [];
|
}
|
||||||
this.values = [];
|
|
||||||
this.whereValues = [];
|
|
||||||
this.setArrayKeys = [];
|
|
||||||
this.orderArray = [];
|
|
||||||
this.groupArray = [];
|
|
||||||
this.havingMap = [];
|
|
||||||
this.whereMap = [];
|
|
||||||
this.rawWhereValues = [];
|
|
||||||
|
|
||||||
// Partials
|
|
||||||
this.selectString = '';
|
|
||||||
this.fromString = '';
|
|
||||||
this.setString = '';
|
|
||||||
this.orderString = '';
|
|
||||||
this.groupString = '';
|
|
||||||
|
|
||||||
// Other various values
|
|
||||||
this.limit = null;
|
|
||||||
this.offset = null;
|
|
||||||
};
|
|
||||||
// End of module State
|
// End of module State
|
||||||
//# sourceMappingURL=State.js.map
|
|
||||||
|
@ -1 +0,0 @@
|
|||||||
{"version":3,"sources":["State.js"],"names":[],"mappings":"AAAA;;;AAAY,CAAC;;;;AAGb,MAAM,CAAC,OAAO,GACb,SADsB,KAAK,GACb;uBADQ,KAAK;;;AAG1B,KAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;AACnB,KAAI,CAAC,MAAM,GAAG,EAAE,CAAC;AACjB,KAAI,CAAC,WAAW,GAAG,EAAE,CAAC;AACtB,KAAI,CAAC,YAAY,GAAG,EAAE,CAAC;AACvB,KAAI,CAAC,UAAU,GAAG,EAAE,CAAC;AACrB,KAAI,CAAC,UAAU,GAAG,EAAE,CAAC;AACrB,KAAI,CAAC,SAAS,GAAG,EAAE,CAAC;AACpB,KAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;AACnB,KAAI,CAAC,cAAc,GAAG,EAAE;;;AAAC,AAGzB,KAAI,CAAC,YAAY,GAAG,EAAE,CAAC;AACvB,KAAI,CAAC,UAAU,GAAG,EAAE,CAAC;AACrB,KAAI,CAAC,SAAS,GAAG,EAAE,CAAC;AACpB,KAAI,CAAC,WAAW,GAAG,EAAE,CAAC;AACtB,KAAI,CAAC,WAAW,GAAG,EAAE;;;AAAC,AAGtB,KAAI,CAAC,KAAK,GAAG,IAAI,CAAC;AAClB,KAAI,CAAC,MAAM,GAAG,IAAI,CAAC;CACnB,AACD;;AAAA","file":"State.js","sourcesContent":["'use strict';\n\n/** @module State */\nmodule.exports = class State {\n\tconstructor() {\n\t\t// Arrays/maps\n\t\tthis.queryMap = [];\n\t\tthis.values = [];\n\t\tthis.whereValues = [];\n\t\tthis.setArrayKeys = [];\n\t\tthis.orderArray = [];\n\t\tthis.groupArray = [];\n\t\tthis.havingMap = [];\n\t\tthis.whereMap = [];\n\t\tthis.rawWhereValues = [];\n\n\t\t// Partials\n\t\tthis.selectString = '';\n\t\tthis.fromString = '';\n\t\tthis.setString = '';\n\t\tthis.orderString = '';\n\t\tthis.groupString = '';\n\n\t\t// Other various values\n\t\tthis.limit = null;\n\t\tthis.offset = null;\n\t}\n}\n// End of module State"],"sourceRoot":"/source/"}
|
|
@ -1,50 +1,19 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
let Adapter = require('../Adapter'),
|
||||||
|
getArgs = require('getargs');
|
||||||
|
|
||||||
var _Adapter2 = require('../Adapter');
|
module.exports = class dblite extends Adapter {
|
||||||
|
/**
|
||||||
var _Adapter3 = _interopRequireDefault(_Adapter2);
|
* Run the sql query as a prepared statement
|
||||||
|
*
|
||||||
var _getargs = require('getargs');
|
* @param {String} sql - The sql with placeholders
|
||||||
|
* @param {Array} params - The values to insert into the query
|
||||||
var _getargs2 = _interopRequireDefault(_getargs);
|
* @param {Function} callback - Callback to run when a response is recieved
|
||||||
|
* @return {void}
|
||||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
*/
|
||||||
|
execute(/*sql, params, callback*/) {
|
||||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
let args = getArgs('sql:string, [params]:array, callback:function', arguments);
|
||||||
|
this.instance.query(args.sql, args.params, args.callback);
|
||||||
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
||||||
|
|
||||||
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
||||||
|
|
||||||
/** @module adapters/dblite */
|
|
||||||
module.exports = (function (_Adapter) {
|
|
||||||
_inherits(dblite, _Adapter);
|
|
||||||
|
|
||||||
function dblite() {
|
|
||||||
_classCallCheck(this, dblite);
|
|
||||||
|
|
||||||
return _possibleConstructorReturn(this, Object.getPrototypeOf(dblite).apply(this, arguments));
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
_createClass(dblite, [{
|
|
||||||
key: 'execute',
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Run the sql query as a prepared statement
|
|
||||||
*
|
|
||||||
* @param {String} sql - The sql with placeholders
|
|
||||||
* @param {Array} params - The values to insert into the query
|
|
||||||
* @param {Function} callback - Callback to run when a response is recieved
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
value: function execute() /*sql, params, callback*/{
|
|
||||||
var args = (0, _getargs2.default)('sql:string, [params]:array, callback:function', arguments);
|
|
||||||
this.instance.query(args.sql, args.params, args.callback);
|
|
||||||
}
|
|
||||||
}]);
|
|
||||||
|
|
||||||
return dblite;
|
|
||||||
})(_Adapter3.default);
|
|
||||||
//# sourceMappingURL=dblite.js.map
|
|
@ -1 +0,0 @@
|
|||||||
{"version":3,"sources":["dblite.js"],"names":[],"mappings":"AAAA,YAAY,CAAC;;;;;;;;;;;;;;;;;;;;;AAMb,MAAM,CAAC,OAAO;WAAS,MAAM;;UAAN,MAAM;wBAAN,MAAM;;gEAAN,MAAM;;;cAAN,MAAM;;;;;;;;;;;qDASO;AAClC,OAAI,IAAI,GAAG,uBAAQ,+CAA+C,EAAE,SAAS,CAAC,CAAC;AAC/E,OAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;GAC1D;;;QAZqB,MAAM;qBAa5B,CAAA","file":"adapters/dblite.js","sourcesContent":["'use strict';\n\nimport Adapter from '../Adapter';\nimport getArgs from 'getargs';\n\n/** @module adapters/dblite */\nmodule.exports = class dblite extends Adapter {\n\t/**\n\t * Run the sql query as a prepared statement\n\t *\n\t * @param {String} sql - The sql with placeholders\n\t * @param {Array} params - The values to insert into the query\n\t * @param {Function} callback - Callback to run when a response is recieved\n\t * @return void\n\t */\n\texecute(/*sql, params, callback*/) {\n\t\tlet args = getArgs('sql:string, [params]:array, callback:function', arguments);\n\t\tthis.instance.query(args.sql, args.params, args.callback);\n\t};\n}"],"sourceRoot":"/source/"}
|
|
@ -1,45 +1,20 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
let Adapter = require('../Adapter'),
|
||||||
|
getArgs = require('getargs');
|
||||||
|
|
||||||
var _Adapter2 = require('../Adapter');
|
module.exports = class mysql extends Adapter {
|
||||||
|
/**
|
||||||
var _Adapter3 = _interopRequireDefault(_Adapter2);
|
* Run the sql query as a prepared statement
|
||||||
|
*
|
||||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
* @param {String} sql - The sql with placeholders
|
||||||
|
* @param {Array} params - The values to insert into the query
|
||||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
* @param {Function} callback - Callback to run when a response is recieved
|
||||||
|
* @return {void}
|
||||||
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
*/
|
||||||
|
execute(sql, params, callback) {
|
||||||
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
let args = getArgs('sql:string, [params], callback:function', arguments);
|
||||||
|
return this.instance.query(args.sql, args.params, args.callback);
|
||||||
/** @module adapters/mysql */
|
//this.instance.query.apply(this.instance, Array(args));
|
||||||
module.exports = (function (_Adapter) {
|
|
||||||
_inherits(mysql, _Adapter);
|
|
||||||
|
|
||||||
function mysql() {
|
|
||||||
_classCallCheck(this, mysql);
|
|
||||||
|
|
||||||
return _possibleConstructorReturn(this, Object.getPrototypeOf(mysql).apply(this, arguments));
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
_createClass(mysql, [{
|
|
||||||
key: 'execute',
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Run the sql query as a prepared statement
|
|
||||||
*
|
|
||||||
* @param {String} sql - The sql with placeholders
|
|
||||||
* @param {Array} params - The values to insert into the query
|
|
||||||
* @param {Function} callback - Callback to run when a response is recieved
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
value: function execute(sql, params, callback) {
|
|
||||||
this.instance.query.apply(instance, arguments);
|
|
||||||
}
|
|
||||||
}]);
|
|
||||||
|
|
||||||
return mysql;
|
|
||||||
})(_Adapter3.default);
|
|
||||||
//# sourceMappingURL=mysql.js.map
|
|
@ -1 +0,0 @@
|
|||||||
{"version":3,"sources":["mysql.js"],"names":[],"mappings":"AAAA,YAAY,CAAC;;;;;;;;;;;;;;;;;AAKb,MAAM,CAAC,OAAO;WAAS,KAAK;;UAAL,KAAK;wBAAL,KAAK;;gEAAL,KAAK;;;cAAL,KAAK;;;;;;;;;;;0BASnB,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE;AAC9B,OAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;GAC/C;;;QAXqB,KAAK;qBAY3B,CAAA","file":"adapters/mysql.js","sourcesContent":["'use strict';\n\nimport Adapter from '../Adapter';\n\n/** @module adapters/mysql */\nmodule.exports = class mysql extends Adapter {\n\t/**\n\t * Run the sql query as a prepared statement\n\t *\n\t * @param {String} sql - The sql with placeholders\n\t * @param {Array} params - The values to insert into the query\n\t * @param {Function} callback - Callback to run when a response is recieved\n\t * @return void\n\t */\n\texecute(sql, params, callback) {\n\t\tthis.instance.query.apply(instance, arguments);\n\t}\n}"],"sourceRoot":"/source/"}
|
|
@ -1,45 +1,20 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
let Adapter = require('../Adapter'),
|
||||||
|
getArgs = require('getargs');
|
||||||
|
|
||||||
var _Adapter2 = require('../Adapter');
|
module.exports = class mysql2 extends Adapter {
|
||||||
|
/**
|
||||||
var _Adapter3 = _interopRequireDefault(_Adapter2);
|
* Run the sql query as a prepared statement
|
||||||
|
*
|
||||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
* @param {String} sql - The sql with placeholders
|
||||||
|
* @param {Array} params - The values to insert into the query
|
||||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
* @param {Function} callback - Callback to run when a response is recieved
|
||||||
|
* @return {void}
|
||||||
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
*/
|
||||||
|
execute(/*sql, params, callback*/) {
|
||||||
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
let args = getArgs('sql:string, [params], callback:function', arguments);
|
||||||
|
return this.instance.execute(args.sql, args.params, args.callback);
|
||||||
/** @module adapters/mysql2 */
|
//this.instance.execute.apply(this.instance, args);
|
||||||
module.exports = (function (_Adapter) {
|
|
||||||
_inherits(mysql2, _Adapter);
|
|
||||||
|
|
||||||
function mysql2() {
|
|
||||||
_classCallCheck(this, mysql2);
|
|
||||||
|
|
||||||
return _possibleConstructorReturn(this, Object.getPrototypeOf(mysql2).apply(this, arguments));
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
_createClass(mysql2, [{
|
|
||||||
key: 'execute',
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Run the sql query as a prepared statement
|
|
||||||
*
|
|
||||||
* @param {String} sql - The sql with placeholders
|
|
||||||
* @param {Array} params - The values to insert into the query
|
|
||||||
* @param {Function} callback - Callback to run when a response is recieved
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
value: function execute(sql, params, callback) {
|
|
||||||
this.instance.execute.apply(this.instance, arguments);
|
|
||||||
}
|
|
||||||
}]);
|
|
||||||
|
|
||||||
return mysql2;
|
|
||||||
})(_Adapter3.default);
|
|
||||||
//# sourceMappingURL=mysql2.js.map
|
|
@ -1 +0,0 @@
|
|||||||
{"version":3,"sources":["mysql2.js"],"names":[],"mappings":"AAAA,YAAY,CAAC;;;;;;;;;;;;;;;;;AAKb,MAAM,CAAC,OAAO;WAAS,MAAM;;UAAN,MAAM;wBAAN,MAAM;;gEAAN,MAAM;;;cAAN,MAAM;;;;;;;;;;;0BASpB,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE;AAC9B,OAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;GACtD;;;QAXqB,MAAM;qBAY5B,CAAA","file":"adapters/mysql2.js","sourcesContent":["'use strict';\n\nimport Adapter from '../Adapter';\n\n/** @module adapters/mysql2 */\nmodule.exports = class mysql2 extends Adapter {\n\t/**\n\t * Run the sql query as a prepared statement\n\t *\n\t * @param {String} sql - The sql with placeholders\n\t * @param {Array} params - The values to insert into the query\n\t * @param {Function} callback - Callback to run when a response is recieved\n\t * @return void\n\t */\n\texecute(sql, params, callback) {\n\t\tthis.instance.execute.apply(this.instance, arguments);\n\t};\n}"],"sourceRoot":"/source/"}
|
|
@ -1,50 +1,19 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
let Adapter = require('../Adapter'),
|
||||||
|
getArgs = require('getargs');
|
||||||
|
|
||||||
var _Adapter2 = require('../Adapter');
|
module.exports = class nodefirebird extends Adapter {
|
||||||
|
/**
|
||||||
var _Adapter3 = _interopRequireDefault(_Adapter2);
|
* Run the sql query as a prepared statement
|
||||||
|
*
|
||||||
var _getargs = require('getargs');
|
* @param {String} sql - The sql with placeholders
|
||||||
|
* @param {Array} params - The values to insert into the query
|
||||||
var _getargs2 = _interopRequireDefault(_getargs);
|
* @param {Function} callback - Callback to run when a response is recieved
|
||||||
|
* @return {void}
|
||||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
*/
|
||||||
|
execute(/*sql, params, callback*/) {
|
||||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
let args = getArgs('sql:string, [params], callback:function', arguments);
|
||||||
|
return this.instance.execute(args.sql, args.params, args.callback);
|
||||||
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
||||||
|
|
||||||
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
||||||
|
|
||||||
/** @module adapters/node-firebird */
|
|
||||||
module.exports = (function (_Adapter) {
|
|
||||||
_inherits(nodefirebird, _Adapter);
|
|
||||||
|
|
||||||
function nodefirebird() {
|
|
||||||
_classCallCheck(this, nodefirebird);
|
|
||||||
|
|
||||||
return _possibleConstructorReturn(this, Object.getPrototypeOf(nodefirebird).apply(this, arguments));
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
_createClass(nodefirebird, [{
|
|
||||||
key: 'execute',
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Run the sql query as a prepared statement
|
|
||||||
*
|
|
||||||
* @param {String} sql - The sql with placeholders
|
|
||||||
* @param {Array} params - The values to insert into the query
|
|
||||||
* @param {Function} callback - Callback to run when a response is recieved
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
value: function execute() /*sql, params, callback*/{
|
|
||||||
var args = (0, _getargs2.default)('sql:string, [params], callback:function', arguments);
|
|
||||||
this.instance.execute(args.sql, args.params, args.callback);
|
|
||||||
}
|
|
||||||
}]);
|
|
||||||
|
|
||||||
return nodefirebird;
|
|
||||||
})(_Adapter3.default);
|
|
||||||
//# sourceMappingURL=node-firebird.js.map
|
|
@ -1 +0,0 @@
|
|||||||
{"version":3,"sources":["node-firebird.js"],"names":[],"mappings":"AAAA,YAAY,CAAC;;;;;;;;;;;;;;;;;;;;;AAMb,MAAM,CAAC,OAAO;WAAS,YAAY;;UAAZ,YAAY;wBAAZ,YAAY;;gEAAZ,YAAY;;;cAAZ,YAAY;;;;;;;;;;;qDASC;AAClC,OAAI,IAAI,GAAG,uBAAQ,yCAAyC,EAAE,SAAS,CAAC,CAAC;AACzE,OAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;GAC5D;;;QAZqB,YAAY;qBAalC,CAAA","file":"adapters/node-firebird.js","sourcesContent":["'use strict';\n\nimport Adapter from '../Adapter';\nimport getArgs from 'getargs';\n\n/** @module adapters/node-firebird */\nmodule.exports = class nodefirebird extends Adapter {\n\t/**\n\t * Run the sql query as a prepared statement\n\t *\n\t * @param {String} sql - The sql with placeholders\n\t * @param {Array} params - The values to insert into the query\n\t * @param {Function} callback - Callback to run when a response is recieved\n\t * @return void\n\t */\n\texecute(/*sql, params, callback*/) {\n\t\tlet args = getArgs('sql:string, [params], callback:function', arguments);\n\t\tthis.instance.execute(args.sql, args.params, args.callback);\n\t}\n}"],"sourceRoot":"/source/"}
|
|
@ -1,58 +1,27 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
let Adapter = require('../Adapter'),
|
||||||
|
getArgs = require('getargs');
|
||||||
|
|
||||||
var _Adapter2 = require('../Adapter');
|
module.exports = class pg extends Adapter {
|
||||||
|
/**
|
||||||
|
* Run the sql query as a prepared statement
|
||||||
|
*
|
||||||
|
* @param {String} sql - The sql with placeholders
|
||||||
|
* @param {Array} params - The values to insert into the query
|
||||||
|
* @param {Function} callback - Callback to run when a response is recieved
|
||||||
|
* @return {void}
|
||||||
|
*/
|
||||||
|
execute(/*sql, params, callback*/) {
|
||||||
|
let args = getArgs('sql:string, [params]:array, callback:function', arguments);
|
||||||
|
|
||||||
var _Adapter3 = _interopRequireDefault(_Adapter2);
|
// Replace question marks with numbered placeholders, because this adapter is different...
|
||||||
|
let count = 0;
|
||||||
|
args.sql = args.sql.replace(/\?/g, () => {
|
||||||
|
count++;
|
||||||
|
return '$' + count;
|
||||||
|
});
|
||||||
|
|
||||||
var _getargs = require('getargs');
|
this.instance.query(args.sql, args.params, args.callback);
|
||||||
|
|
||||||
var _getargs2 = _interopRequireDefault(_getargs);
|
|
||||||
|
|
||||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
||||||
|
|
||||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
||||||
|
|
||||||
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
||||||
|
|
||||||
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
||||||
|
|
||||||
/** @module adapters/pg */
|
|
||||||
module.exports = (function (_Adapter) {
|
|
||||||
_inherits(pg, _Adapter);
|
|
||||||
|
|
||||||
function pg() {
|
|
||||||
_classCallCheck(this, pg);
|
|
||||||
|
|
||||||
return _possibleConstructorReturn(this, Object.getPrototypeOf(pg).apply(this, arguments));
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
_createClass(pg, [{
|
|
||||||
key: 'execute',
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Run the sql query as a prepared statement
|
|
||||||
*
|
|
||||||
* @param {String} sql - The sql with placeholders
|
|
||||||
* @param {Array} params - The values to insert into the query
|
|
||||||
* @param {Function} callback - Callback to run when a response is recieved
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
value: function execute() /*sql, params, callback*/{
|
|
||||||
var args = (0, _getargs2.default)('sql:string, [params]:array, callback:function', arguments);
|
|
||||||
|
|
||||||
// Replace question marks with numbered placeholders, because this adapter is different...
|
|
||||||
var count = 0;
|
|
||||||
args.sql = args.sql.replace(/\?/g, function () {
|
|
||||||
count++;
|
|
||||||
return '$' + count;
|
|
||||||
});
|
|
||||||
|
|
||||||
this.instance.query(args.sql, args.params, args.callback);
|
|
||||||
}
|
|
||||||
}]);
|
|
||||||
|
|
||||||
return pg;
|
|
||||||
})(_Adapter3.default);
|
|
||||||
//# sourceMappingURL=pg.js.map
|
|
@ -1 +0,0 @@
|
|||||||
{"version":3,"sources":["pg.js"],"names":[],"mappings":"AAAA,YAAY,CAAC;;;;;;;;;;;;;;;;;;;;;AAMb,MAAM,CAAC,OAAO;WAAS,EAAE;;UAAF,EAAE;wBAAF,EAAE;;gEAAF,EAAE;;;cAAF,EAAE;;;;;;;;;;;qDASW;AAClC,OAAI,IAAI,GAAG,uBAAQ,+CAA+C,EAAE,SAAS,CAAC;;;AAAC,AAG/E,OAAI,KAAK,GAAG,CAAC,CAAC;AACd,OAAI,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,YAAM;AACxC,SAAK,EAAE,CAAC;AACR,WAAO,GAAG,GAAG,KAAK,CAAC;IACnB,CAAC,CAAC;;AAEH,OAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;GAC1D;;;QApBqB,EAAE;qBAqBxB,CAAA","file":"adapters/pg.js","sourcesContent":["'use strict';\n\nimport Adapter from '../Adapter';\nimport getArgs from 'getargs';\n\n/** @module adapters/pg */\nmodule.exports = class pg extends Adapter {\n\t/**\n\t * Run the sql query as a prepared statement\n\t *\n\t * @param {String} sql - The sql with placeholders\n\t * @param {Array} params - The values to insert into the query\n\t * @param {Function} callback - Callback to run when a response is recieved\n\t * @return void\n\t */\n\texecute(/*sql, params, callback*/) {\n\t\tlet args = getArgs('sql:string, [params]:array, callback:function', arguments);\n\n\t\t// Replace question marks with numbered placeholders, because this adapter is different...\n\t\tlet count = 0;\n\t\targs.sql = args.sql.replace(/\\?/g, () => {\n\t\t\tcount++;\n\t\t\treturn '$' + count;\n\t\t});\n\n\t\tthis.instance.query(args.sql, args.params, args.callback);\n\t}\n}"],"sourceRoot":"/source/"}
|
|
@ -1,78 +1,44 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
let helpers = require('../helpers'),
|
||||||
|
Driver = require('../DriverClass');
|
||||||
|
|
||||||
var _helpers = require('../helpers');
|
class Firebird extends Driver {
|
||||||
|
constructor() {
|
||||||
var _helpers2 = _interopRequireDefault(_helpers);
|
super({
|
||||||
|
|
||||||
var _DriverClass = require('../DriverClass');
|
|
||||||
|
|
||||||
var _DriverClass2 = _interopRequireDefault(_DriverClass);
|
|
||||||
|
|
||||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
||||||
|
|
||||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
||||||
|
|
||||||
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
||||||
|
|
||||||
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Driver for Firebird databases
|
|
||||||
*
|
|
||||||
* @module drivers/firebird
|
|
||||||
*/
|
|
||||||
|
|
||||||
var Firebird = (function (_Driver) {
|
|
||||||
_inherits(Firebird, _Driver);
|
|
||||||
|
|
||||||
function Firebird() {
|
|
||||||
_classCallCheck(this, Firebird);
|
|
||||||
|
|
||||||
return _possibleConstructorReturn(this, Object.getPrototypeOf(Firebird).call(this, {
|
|
||||||
hasTruncate: false
|
hasTruncate: false
|
||||||
}));
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate a limit clause for firebird, which uses the syntax closest to the SQL standard
|
* Set the limit clause
|
||||||
*
|
*
|
||||||
* @param {String} sql
|
* @param {String} origSql - SQL statement to modify
|
||||||
* @param {Number} limit
|
* @param {Number} limit - Maximum number of rows to fetch
|
||||||
* @param {Number} offset
|
* @param {Number|null} offset - Number of rows to skip
|
||||||
* @return {String}
|
* @return {String} - Modified SQL statement
|
||||||
*/
|
*/
|
||||||
|
limit(origSql, limit, offset) {
|
||||||
|
let sql = `FIRST ${limit}`;
|
||||||
|
|
||||||
_createClass(Firebird, [{
|
if (helpers.isNumber(offset))
|
||||||
key: 'limit',
|
{
|
||||||
value: function limit(origSql, _limit, offset) {
|
sql += ` SKIP ${offset}`;
|
||||||
var sql = 'FIRST ' + _limit;
|
|
||||||
|
|
||||||
if (_helpers2.default.isNumber(offset)) {
|
|
||||||
sql += ' SKIP ' + offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
return origSql.replace(/SELECT/i, "SELECT " + sql);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
return origSql.replace(/SELECT/i, "SELECT " + sql);
|
||||||
* SQL to insert a group of rows
|
}
|
||||||
*
|
|
||||||
* @param {String} table - The table to insert to
|
|
||||||
* @param {Array} [data] - The array of object containing data to insert
|
|
||||||
* @return {String}
|
|
||||||
*/
|
|
||||||
|
|
||||||
}, {
|
/**
|
||||||
key: 'insertBatch',
|
* SQL to insert a group of rows
|
||||||
value: function insertBatch() {
|
*
|
||||||
throw new Error("Not Implemented");
|
* @param {String} table - The table to insert to
|
||||||
}
|
* @param {Array} [data] - The array of object containing data to insert
|
||||||
}]);
|
* @return {String} - Query and data to insert
|
||||||
|
*/
|
||||||
return Firebird;
|
insertBatch() {
|
||||||
})(_DriverClass2.default);
|
throw new Error("Not Implemented");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = new Firebird();
|
module.exports = new Firebird();
|
||||||
//# sourceMappingURL=Firebird.js.map
|
|
||||||
|
@ -1 +0,0 @@
|
|||||||
{"version":3,"sources":["Firebird.js"],"names":[],"mappings":"AAAA,YAAY,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;IAUP,QAAQ;WAAR,QAAQ;;AACb,UADK,QAAQ,GACC;wBADT,QAAQ;;gEAAR,QAAQ,aAEN;AACL,cAAW,EAAE,KAAK;GAClB;EACD;;;;;;;;;;AAAA;cALI,QAAQ;;wBAeP,OAAO,EAAE,MAAK,EAAE,MAAM,EAAE;AAC7B,OAAI,GAAG,eAAa,MAAK,AAAE,CAAC;;AAE5B,OAAI,kBAAQ,QAAQ,CAAC,MAAM,CAAC,EAC5B;AACC,OAAG,gBAAc,MAAM,AAAE,CAAC;IAC1B;;AAED,UAAO,OAAO,CAAC,OAAO,CAAC,SAAS,EAAE,SAAS,GAAG,GAAG,CAAC,CAAC;GACnD;;;;;;;;;;;;gCASa;AACb,SAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;GACnC;;;QAnCI,QAAQ;;;AAsCd,MAAM,CAAC,OAAO,GAAG,IAAI,QAAQ,EAAE,CAAC","file":"drivers/Firebird.js","sourcesContent":["\"use strict\";\n\nimport helpers from '../helpers';\nimport Driver from '../DriverClass';\n\n/**\n * Driver for Firebird databases\n *\n * @module drivers/firebird\n */\nclass Firebird extends Driver {\n\tconstructor() {\n\t\tsuper({\n\t\t\thasTruncate: false\n\t\t});\n\t}\n\n\t/**\n\t * Generate a limit clause for firebird, which uses the syntax closest to the SQL standard\n\t *\n\t * @param {String} sql\n\t * @param {Number} limit\n\t * @param {Number} offset\n\t * @return {String}\n\t */\n\tlimit(origSql, limit, offset) {\n\t\tlet sql = `FIRST ${limit}`;\n\n\t\tif (helpers.isNumber(offset))\n\t\t{\n\t\t\tsql += ` SKIP ${offset}`;\n\t\t}\n\n\t\treturn origSql.replace(/SELECT/i, \"SELECT \" + sql);\n\t}\n\n\t/**\n\t * SQL to insert a group of rows\n\t *\n\t * @param {String} table - The table to insert to\n\t * @param {Array} [data] - The array of object containing data to insert\n\t * @return {String}\n\t */\n\tinsertBatch() {\n\t\tthrow new Error(\"Not Implemented\");\n\t}\n}\n\nmodule.exports = new Firebird();"],"sourceRoot":"/source/"}
|
|
@ -1,54 +1,32 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
let helpers = require('../helpers'),
|
||||||
|
Driver = require('../DriverClass');
|
||||||
|
|
||||||
var _helpers = require('../helpers');
|
class Mysql extends Driver {
|
||||||
|
constructor() {
|
||||||
var _helpers2 = _interopRequireDefault(_helpers);
|
super({
|
||||||
|
|
||||||
var _DriverClass = require('../DriverClass');
|
|
||||||
|
|
||||||
var _DriverClass2 = _interopRequireDefault(_DriverClass);
|
|
||||||
|
|
||||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
||||||
|
|
||||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
||||||
|
|
||||||
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
||||||
|
|
||||||
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Driver for MySQL databases
|
|
||||||
*
|
|
||||||
* @module drivers/mysql
|
|
||||||
*/
|
|
||||||
|
|
||||||
var Mysql = (function (_Driver) {
|
|
||||||
_inherits(Mysql, _Driver);
|
|
||||||
|
|
||||||
function Mysql() {
|
|
||||||
_classCallCheck(this, Mysql);
|
|
||||||
|
|
||||||
return _possibleConstructorReturn(this, Object.getPrototypeOf(Mysql).call(this, {
|
|
||||||
identifierStartChar: '`',
|
identifierStartChar: '`',
|
||||||
identifierEndChar: '`'
|
identifierEndChar: '`'
|
||||||
}));
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
_createClass(Mysql, [{
|
/**
|
||||||
key: 'limit',
|
* Set the limit clause
|
||||||
value: function limit(sql, _limit, offset) {
|
*
|
||||||
if (!_helpers2.default.isNumber(offset)) {
|
* @param {String} sql - SQL statement to modify
|
||||||
return sql += ' LIMIT ' + _limit;
|
* @param {Number} limit - Maximum number of rows to fetch
|
||||||
}
|
* @param {Number|null} offset - Number of rows to skip
|
||||||
|
* @return {String} - Modified SQL statement
|
||||||
return sql += ' LIMIT ' + offset + ', ' + _limit;
|
*/
|
||||||
|
limit(sql, limit, offset) {
|
||||||
|
if ( ! helpers.isNumber(offset))
|
||||||
|
{
|
||||||
|
return sql += ` LIMIT ${limit}`;
|
||||||
}
|
}
|
||||||
}]);
|
|
||||||
|
|
||||||
return Mysql;
|
return sql += ` LIMIT ${offset}, ${limit}`;
|
||||||
})(_DriverClass2.default);
|
}
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = new Mysql();
|
module.exports = new Mysql();
|
||||||
//# sourceMappingURL=Mysql.js.map
|
|
||||||
|
@ -1 +0,0 @@
|
|||||||
{"version":3,"sources":["Mysql.js"],"names":[],"mappings":"AAAA,YAAY,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;IAUP,KAAK;WAAL,KAAK;;AACV,UADK,KAAK,GACI;wBADT,KAAK;;gEAAL,KAAK,aAEH;AACL,sBAAmB,EAAE,GAAG;AACxB,oBAAiB,EAAE,GAAG;GACtB;EACD;;cANI,KAAK;;wBAQJ,GAAG,EAAE,MAAK,EAAE,MAAM,EAAE;AACzB,OAAK,CAAE,kBAAQ,QAAQ,CAAC,MAAM,CAAC,EAC/B;AACC,WAAO,GAAG,gBAAc,MAAK,AAAE,CAAC;IAChC;;AAED,UAAO,GAAG,gBAAc,MAAM,UAAK,MAAK,AAAE,CAAC;GAC3C;;;QAfI,KAAK;;;AAkBX,MAAM,CAAC,OAAO,GAAG,IAAI,KAAK,EAAE,CAAC","file":"drivers/Mysql.js","sourcesContent":["\"use strict\";\n\nimport helpers from '../helpers';\nimport Driver from '../DriverClass';\n\n/**\n * Driver for MySQL databases\n *\n * @module drivers/mysql\n */\nclass Mysql extends Driver {\n\tconstructor() {\n\t\tsuper({\n\t\t\tidentifierStartChar: '`',\n\t\t\tidentifierEndChar: '`'\n\t\t});\n\t}\n\n\tlimit(sql, limit, offset) {\n\t\tif ( ! helpers.isNumber(offset))\n\t\t{\n\t\t\treturn sql += ` LIMIT ${limit}`;\n\t\t}\n\n\t\treturn sql += ` LIMIT ${offset}, ${limit}`;\n\t}\n}\n\nmodule.exports = new Mysql();"],"sourceRoot":"/source/"}
|
|
@ -1,15 +1,10 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var _DriverClass = require("../DriverClass");
|
let Driver = require('../DriverClass');
|
||||||
|
|
||||||
var _DriverClass2 = _interopRequireDefault(_DriverClass);
|
|
||||||
|
|
||||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Driver for PostgreSQL databases
|
* Driver for PostgreSQL databases
|
||||||
*
|
*
|
||||||
* @module drivers/pg
|
* @module drivers/pg
|
||||||
*/
|
*/
|
||||||
module.exports = new _DriverClass2.default();
|
module.exports = new Driver();
|
||||||
//# sourceMappingURL=Pg.js.map
|
|
@ -1 +0,0 @@
|
|||||||
{"version":3,"sources":["Pg.js"],"names":[],"mappings":"AAAA,YAAY,CAAC;;;;;;;;;;;;;AASb,MAAM,CAAC,OAAO,GAAG,2BAAY,CAAC","file":"drivers/Pg.js","sourcesContent":["\"use strict\";\n\nimport Driver from '../DriverClass';\n\n/**\n * Driver for PostgreSQL databases\n *\n * @module drivers/pg\n */\nmodule.exports = new Driver();"],"sourceRoot":"/source/"}
|
|
@ -1,94 +1,66 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
let helpers = require('../helpers'),
|
||||||
|
Driver = require('../DriverClass');
|
||||||
|
|
||||||
var _helpers = require('../helpers');
|
class Sqlite extends Driver {
|
||||||
|
constructor() {
|
||||||
var _helpers2 = _interopRequireDefault(_helpers);
|
super({
|
||||||
|
hasTruncate: false
|
||||||
var _DriverClass = require('../DriverClass');
|
});
|
||||||
|
|
||||||
var _DriverClass2 = _interopRequireDefault(_DriverClass);
|
|
||||||
|
|
||||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
||||||
|
|
||||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
||||||
|
|
||||||
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
||||||
|
|
||||||
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Driver for Sqlite databases
|
|
||||||
*
|
|
||||||
* @module drivers/sqlite
|
|
||||||
*/
|
|
||||||
|
|
||||||
var Sqlite = (function (_Driver) {
|
|
||||||
_inherits(Sqlite, _Driver);
|
|
||||||
|
|
||||||
function Sqlite() {
|
|
||||||
_classCallCheck(this, Sqlite);
|
|
||||||
|
|
||||||
var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(Sqlite).call(this));
|
|
||||||
|
|
||||||
_this.hasTruncate = false;
|
|
||||||
return _this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_createClass(Sqlite, [{
|
/**
|
||||||
key: 'insertBatch',
|
* SQL to insert a group of rows
|
||||||
value: function insertBatch(table, data) {
|
*
|
||||||
var _this2 = this;
|
* @param {String} table - The table to insert to
|
||||||
|
* @param {Array} [data] - The array of object containing data to insert
|
||||||
|
* @return {String} - Query and data to insert
|
||||||
|
*/
|
||||||
|
insertBatch(table, data) {
|
||||||
|
// Get the data values to insert, so they can
|
||||||
|
// be parameterized
|
||||||
|
let sql = "",
|
||||||
|
vals = [],
|
||||||
|
cols = [],
|
||||||
|
fields = [],
|
||||||
|
first = data.shift(),
|
||||||
|
params = [],
|
||||||
|
paramString = "",
|
||||||
|
paramList = [];
|
||||||
|
|
||||||
// Get the data values to insert, so they can
|
|
||||||
// be parameterized
|
|
||||||
var sql = "",
|
|
||||||
vals = [],
|
|
||||||
cols = [],
|
|
||||||
fields = [],
|
|
||||||
first = data.shift(),
|
|
||||||
params = [],
|
|
||||||
paramString = "",
|
|
||||||
paramList = [];
|
|
||||||
|
|
||||||
data.forEach(function (obj) {
|
data.forEach(obj => {
|
||||||
var row = [];
|
let row = [];
|
||||||
Object.keys(obj).forEach(function (key) {
|
Object.keys(obj).forEach(key => {
|
||||||
row.push(obj[key]);
|
row.push(obj[key]);
|
||||||
});
|
|
||||||
vals.push(row);
|
|
||||||
});
|
});
|
||||||
|
vals.push(row);
|
||||||
|
});
|
||||||
|
|
||||||
sql += "INSERT INTO " + this.quoteTable(table) + "\n";
|
sql += "INSERT INTO " + this.quoteTable(table) + "\n";
|
||||||
|
|
||||||
// Get the field names from the keys of the first
|
// Get the field names from the keys of the first
|
||||||
// object to be inserted
|
// object to be inserted
|
||||||
fields = Object.keys(first);
|
fields = Object.keys(first);
|
||||||
Object.keys(first).forEach(function (key) {
|
Object.keys(first).forEach(key => {
|
||||||
cols.push("'" + _this2._quote(first[key]) + "' AS " + _this2.quoteIdentifiers(key));
|
cols.push("'" + this._quote(first[key]) + "' AS " + this.quoteIdentifiers(key));
|
||||||
|
});
|
||||||
|
|
||||||
|
sql += "SELECT " + cols.join(', ') + "\n";
|
||||||
|
|
||||||
|
vals.forEach(row_values => {
|
||||||
|
let quoted = row_values.map(value => {
|
||||||
|
return String(value).replace("'", "'\'");
|
||||||
});
|
});
|
||||||
|
sql += "UNION ALL SELECT '" + quoted.join("', '") + "'\n";
|
||||||
|
});
|
||||||
|
|
||||||
sql += "SELECT " + cols.join(', ') + "\n";
|
return {
|
||||||
|
sql: sql,
|
||||||
vals.forEach(function (row_values) {
|
values: null
|
||||||
var quoted = row_values.map(function (value) {
|
};
|
||||||
return String(value).replace("'", "'\'");
|
}
|
||||||
});
|
}
|
||||||
sql += "UNION ALL SELECT '" + quoted.join("', '") + "'\n";
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
|
||||||
sql: sql,
|
|
||||||
values: null
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}]);
|
|
||||||
|
|
||||||
return Sqlite;
|
|
||||||
})(_DriverClass2.default);
|
|
||||||
|
|
||||||
;
|
|
||||||
|
|
||||||
module.exports = new Sqlite();
|
module.exports = new Sqlite();
|
||||||
//# sourceMappingURL=Sqlite.js.map
|
|
||||||
|
@ -1 +0,0 @@
|
|||||||
{"version":3,"sources":["Sqlite.js"],"names":[],"mappings":"AAAA,YAAY,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;IAUP,MAAM;WAAN,MAAM;;AACX,UADK,MAAM,GACG;wBADT,MAAM;;qEAAN,MAAM;;AAGV,QAAK,WAAW,GAAG,KAAK,CAAC;;EACzB;;cAJI,MAAM;;8BAMC,KAAK,EAAE,IAAI,EAAE;;;;;AAIxB,OAAI,GAAG,GAAG,EAAE;OACX,IAAI,GAAG,EAAE;OACT,IAAI,GAAG,EAAE;OACT,MAAM,GAAG,EAAE;OACX,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE;OACpB,MAAM,GAAG,EAAE;OACX,WAAW,GAAG,EAAE;OAChB,SAAS,GAAG,EAAE,CAAC;;AAGhB,OAAI,CAAC,OAAO,CAAC,UAAC,GAAG,EAAK;AACrB,QAAI,GAAG,GAAG,EAAE,CAAC;AACb,UAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,UAAC,GAAG,EAAK;AACjC,QAAG,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;KACnB,CAAC,CAAC;AACH,QAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACf,CAAC,CAAC;;AAEH,MAAG,IAAI,cAAc,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,IAAI;;;;AAAC,AAItD,SAAM,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC5B,SAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,UAAC,GAAG,EAAK;AACnC,QAAI,CAAC,IAAI,CAAC,GAAG,GAAG,OAAK,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,OAAO,GAAG,OAAK,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC;IAChF,CAAC,CAAC;;AAEH,MAAG,IAAI,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;;AAE1C,OAAI,CAAC,OAAO,CAAC,UAAC,UAAU,EAAK;AAC5B,QAAI,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,UAAC,KAAK,EAAK;AACtC,YAAO,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;KACzC,CAAC,CAAC;AACH,OAAG,IAAI,oBAAoB,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,KAAK,CAAC;IAC1D,CAAC,CAAC;;AAEH,UAAO;AACN,OAAG,EAAE,GAAG;AACR,UAAM,EAAE,IAAI;IACZ,CAAC;GACF;;;QAlDI,MAAM;;;AAmDX,CAAC;;AAEF,MAAM,CAAC,OAAO,GAAG,IAAI,MAAM,EAAE,CAAC","file":"drivers/Sqlite.js","sourcesContent":["\"use strict\";\n\nimport helpers from '../helpers';\nimport Driver from '../DriverClass';\n\n/**\n * Driver for Sqlite databases\n *\n * @module drivers/sqlite\n */\nclass Sqlite extends Driver {\n\tconstructor() {\n\t\tsuper();\n\t\tthis.hasTruncate = false;\n\t}\n\n\tinsertBatch(table, data) {\n\n\t\t// Get the data values to insert, so they can\n\t\t// be parameterized\n\t\tlet sql = \"\",\n\t\t\tvals = [],\n\t\t\tcols = [],\n\t\t\tfields = [],\n\t\t\tfirst = data.shift(),\n\t\t\tparams = [],\n\t\t\tparamString = \"\",\n\t\t\tparamList = [];\n\n\n\t\tdata.forEach((obj) => {\n\t\t\tlet row = [];\n\t\t\tObject.keys(obj).forEach((key) => {\n\t\t\t\trow.push(obj[key]);\n\t\t\t});\n\t\t\tvals.push(row);\n\t\t});\n\n\t\tsql += \"INSERT INTO \" + this.quoteTable(table) + \"\\n\";\n\n\t\t// Get the field names from the keys of the first\n\t\t// object to be inserted\n\t\tfields = Object.keys(first);\n\t\tObject.keys(first).forEach((key) => {\n\t\t\tcols.push(\"'\" + this._quote(first[key]) + \"' AS \" + this.quoteIdentifiers(key));\n\t\t});\n\n\t\tsql += \"SELECT \" + cols.join(', ') + \"\\n\";\n\n\t\tvals.forEach((row_values) => {\n\t\t\tlet quoted = row_values.map((value) => {\n\t\t\t\treturn String(value).replace(\"'\", \"'\\'\");\n\t\t\t});\n\t\t\tsql += \"UNION ALL SELECT '\" + quoted.join(\"', '\") + \"'\\n\";\n\t\t});\n\n\t\treturn {\n\t\t\tsql: sql,\n\t\t\tvalues: null\n\t\t};\n\t}\n};\n\nmodule.exports = new Sqlite();"],"sourceRoot":"/source/"}
|
|
174
lib/helpers.js
174
lib/helpers.js
@ -1,66 +1,62 @@
|
|||||||
"use strict"
|
"use strict";
|
||||||
|
|
||||||
//require('es6-shim');
|
let helpers = {
|
||||||
|
|
||||||
;
|
|
||||||
var helpers = {
|
|
||||||
/**
|
/**
|
||||||
* Wrap String.prototype.trim in a way that is easily mappable
|
* Wrap String.prototype.trim in a way that is easily mappable
|
||||||
*
|
*
|
||||||
* @param {String} str - The string to trim
|
* @param {String} str - The string to trim
|
||||||
* @return {String} - The trimmed string
|
* @return {String} - The trimmed string
|
||||||
*/
|
*/
|
||||||
stringTrim: function stringTrim(str) {
|
stringTrim: str => str.trim(),
|
||||||
return str.trim();
|
/**
|
||||||
|
* Get the type of the variable passed
|
||||||
|
*
|
||||||
|
* @see https://techblog.badoo.com/blog/2013/11/01/type-checking-in-javascript/
|
||||||
|
* @see http://toddmotto.com/understanding-javascript-types-and-reliable-type-checking/
|
||||||
|
* @param {mixed} o - Object to type check
|
||||||
|
* @return {String} - Type of the object
|
||||||
|
*/
|
||||||
|
type: o => {
|
||||||
|
let type = Object.prototype.toString.call(o).slice(8, -1).toLowerCase();
|
||||||
|
|
||||||
|
// handle NaN and Infinity
|
||||||
|
if (type === 'number') {
|
||||||
|
if (isNaN(o)) {
|
||||||
|
return 'nan';
|
||||||
|
}
|
||||||
|
if (!isFinite(o)) {
|
||||||
|
return 'infinity';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return type;
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* Get the type of the variable passed
|
* Determine whether an object is scalar
|
||||||
*
|
*
|
||||||
* @see https://techblog.badoo.com/blog/2013/11/01/type-checking-in-javascript/
|
* @param {mixed} obj - Object to test
|
||||||
* @see http://toddmotto.com/understanding-javascript-types-and-reliable-type-checking/
|
* @return {bool} - Is object scalar
|
||||||
* @param {mixed} o
|
*/
|
||||||
* @return {String}
|
isScalar: obj => {
|
||||||
*/
|
let scalar = ['string', 'number', 'boolean'];
|
||||||
type: function type(o) {
|
|
||||||
var type = Object.prototype.toString.call(o).slice(8, -1).toLowerCase();
|
|
||||||
|
|
||||||
// handle NaN and Infinity
|
|
||||||
if (type === 'number') {
|
|
||||||
if (isNaN(o)) {
|
|
||||||
return 'nan';
|
|
||||||
}
|
|
||||||
if (!isFinite(o)) {
|
|
||||||
return 'infinity';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return type;
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Determine whether an object is scalar
|
|
||||||
*
|
|
||||||
* @param {mixed} obj
|
|
||||||
* @return {bool}
|
|
||||||
*/
|
|
||||||
isScalar: function isScalar(obj) {
|
|
||||||
var scalar = ['string', 'number', 'boolean'];
|
|
||||||
return scalar.indexOf(helpers.type(obj)) !== -1;
|
return scalar.indexOf(helpers.type(obj)) !== -1;
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* Get a list of values with a common key from an array of objects
|
* Get a list of values with a common key from an array of objects
|
||||||
*
|
*
|
||||||
* @param {Array} arr - The array of objects to search
|
* @param {Array} arr - The array of objects to search
|
||||||
* @param {String} key - The key of the object to get
|
* @param {String} key - The key of the object to get
|
||||||
* @return {Array}
|
* @return {Array} - The new array of plucked values
|
||||||
*/
|
*/
|
||||||
arrayPluck: function arrayPluck(arr, key) {
|
arrayPluck: (arr, key) => {
|
||||||
var output = [];
|
let output = [];
|
||||||
|
|
||||||
// Empty case
|
// Empty case
|
||||||
if (arr.length === 0) return output;
|
if (arr.length === 0) return output;
|
||||||
|
|
||||||
arr.forEach(function (obj) {
|
arr.forEach(obj => {
|
||||||
if (!helpers.isUndefined(obj[key])) {
|
if ( ! helpers.isUndefined(obj[key]))
|
||||||
|
{
|
||||||
output.push(obj[key]);
|
output.push(obj[key]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -68,22 +64,22 @@ var helpers = {
|
|||||||
return output;
|
return output;
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* Determine if a value matching the passed regular expression is
|
* Determine if a value matching the passed regular expression is
|
||||||
* in the passed array
|
* in the passed array
|
||||||
*
|
*
|
||||||
* @param {Array} arr - The array to search
|
* @param {Array} arr - The array to search
|
||||||
* @param {RegExp} pattern - The pattern to match
|
* @param {RegExp} pattern - The pattern to match
|
||||||
* @return {Boolean} - If an array item matches the pattern
|
* @return {Boolean} - If an array item matches the pattern
|
||||||
*/
|
*/
|
||||||
regexInArray: function regexInArray(arr, pattern) {
|
regexInArray: (arr, pattern) => {
|
||||||
// Empty case(s)
|
// Empty case(s)
|
||||||
if (!helpers.isArray(arr)) return false;
|
if ( ! helpers.isArray(arr)) return false;
|
||||||
if (arr.length === 0) return false;
|
if (arr.length === 0) return false;
|
||||||
|
|
||||||
var i = undefined,
|
let i, l = arr.length;
|
||||||
l = arr.length;
|
|
||||||
|
|
||||||
for (i = 0; i < l; i++) {
|
for(i=0; i< l; i++)
|
||||||
|
{
|
||||||
// Short circuit if any items match
|
// Short circuit if any items match
|
||||||
if (pattern.test(arr[i])) return true;
|
if (pattern.test(arr[i])) return true;
|
||||||
}
|
}
|
||||||
@ -91,39 +87,39 @@ var helpers = {
|
|||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* Make the first letter of the string uppercase
|
* Make the first letter of the string uppercase
|
||||||
*
|
*
|
||||||
* @param {String} str
|
* @param {String} str - The string to modify
|
||||||
* @return {String}
|
* @return {String} - The modified string
|
||||||
*/
|
*/
|
||||||
upperCaseFirst: function upperCaseFirst(str) {
|
upperCaseFirst: str => {
|
||||||
str += '';
|
str += '';
|
||||||
var first = str.charAt(0).toUpperCase();
|
let first = str.charAt(0).toUpperCase();
|
||||||
return first + str.substr(1);
|
return first + str.substr(1);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Define an 'is' method for each type
|
// Define an 'is' method for each type
|
||||||
var types = ['Null', 'Undefined', 'Object', 'Array', 'String', 'Number', 'Boolean', 'Function', 'RegExp', 'NaN', 'Infinite'];
|
let types = ['Null','Undefined','Object','Array','String','Number','Boolean','Function','RegExp','NaN','Infinite'];
|
||||||
types.forEach(function (t) {
|
types.forEach(t => {
|
||||||
/**
|
/**
|
||||||
* Determine whether a variable is of the type specified in the
|
* Determine whether a variable is of the type specified in the
|
||||||
* function name, eg isNumber
|
* function name, eg isNumber
|
||||||
*
|
*
|
||||||
* Types available are Null, Undefined, Object, Array, String, Number, Boolean, Function, RegExp, NaN and Infinite
|
* Types available are Null, Undefined, Object, Array, String, Number, Boolean, Function, RegExp, NaN and Infinite
|
||||||
*
|
*
|
||||||
* @name is[type]
|
* @name is[type]
|
||||||
* @param {mixed} o
|
* @param {mixed} o
|
||||||
* @return {Boolean}
|
* @return {Boolean}
|
||||||
*/
|
*/
|
||||||
helpers['is' + t] = function (o) {
|
helpers['is' + t] = function (o) {
|
||||||
if (t.toLowerCase() === 'infinite') {
|
if (t.toLowerCase() === 'infinite')
|
||||||
t = 'infinity';
|
{
|
||||||
}
|
t = 'infinity';
|
||||||
|
}
|
||||||
|
|
||||||
return helpers.type(o) === t.toLowerCase();
|
return helpers.type(o) === t.toLowerCase();
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = helpers;
|
module.exports = helpers;
|
||||||
//# sourceMappingURL=helpers.js.map
|
|
||||||
|
File diff suppressed because one or more lines are too long
30
package.json
30
package.json
@ -4,7 +4,7 @@
|
|||||||
"description": "A query builder for node based on the one in CodeIgniter",
|
"description": "A query builder for node based on the one in CodeIgniter",
|
||||||
"author": "Timothy J Warren <tim@timshomepage.net>",
|
"author": "Timothy J Warren <tim@timshomepage.net>",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.10.0"
|
"node": ">=4.0.0"
|
||||||
},
|
},
|
||||||
"contributors": [
|
"contributors": [
|
||||||
{
|
{
|
||||||
@ -38,10 +38,7 @@
|
|||||||
"mysql2": "^0.15.8",
|
"mysql2": "^0.15.8",
|
||||||
"node-firebird": "^0.7.0",
|
"node-firebird": "^0.7.0",
|
||||||
"pg": "^4.4.3",
|
"pg": "^4.4.3",
|
||||||
"es6-shim": "",
|
"require-reload": "*"
|
||||||
"babel": "",
|
|
||||||
"babel-preset-es2015": "",
|
|
||||||
"babel-plugin-transform-es2015-modules-commonjs": ""
|
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"dblite": "*",
|
"dblite": "*",
|
||||||
@ -49,22 +46,21 @@
|
|||||||
"pg": "*"
|
"pg": "*"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"chai": "",
|
||||||
"documentation": "",
|
"documentation": "",
|
||||||
"nodeunit": "",
|
|
||||||
"gulp": "",
|
|
||||||
"gulp-babel": "",
|
|
||||||
"gulp-babel-istanbul": "",
|
|
||||||
"gulp-sourcemaps": "",
|
|
||||||
"gulp-concat": "",
|
|
||||||
"gulp-documentation": "",
|
|
||||||
"gulp-nodeunit-runner": "",
|
|
||||||
"gulp-sloc": "",
|
|
||||||
"gulp-eslint": "",
|
|
||||||
"eslint": "",
|
"eslint": "",
|
||||||
"istanbul": ""
|
"gulp": "",
|
||||||
|
"gulp-documentation": "^2.1.0",
|
||||||
|
"gulp-eslint": "",
|
||||||
|
"gulp-istanbul": "^0.10.3",
|
||||||
|
"gulp-mocha": "^2.2.0",
|
||||||
|
"gulp-pipe": "^1.0.4",
|
||||||
|
"gulp-sloc": "",
|
||||||
|
"istanbul": "",
|
||||||
|
"mocha": ""
|
||||||
},
|
},
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "gulp nodeunit"
|
"test": "gulp test"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
sonar.projectKey=node-query
|
sonar.projectKey=node-query
|
||||||
sonar.projectName=NodeJS Query Builder
|
sonar.projectName=NodeJS Query Builder
|
||||||
sonar.projectVersion=2.2.1
|
sonar.projectVersion=3.0.0
|
||||||
sonar.sources=lib
|
sonar.sources=lib
|
||||||
sonar.javascript.lcov.reportPath=coverage/lcov.info
|
sonar.javascript.lcov.reportPath=coverage/lcov.info
|
@ -1,26 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
/** @module Adapter */
|
|
||||||
module.exports = class Adapter {
|
|
||||||
/**
|
|
||||||
* Invoke an adapter
|
|
||||||
*
|
|
||||||
* @param {Object} instance - The connection objec
|
|
||||||
* @return {void}
|
|
||||||
*/
|
|
||||||
constructor(instance) {
|
|
||||||
this.instance = instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Run the sql query as a prepared statement
|
|
||||||
*
|
|
||||||
* @param {String} sql - The sql with placeholders
|
|
||||||
* @param {Array} params - The values to insert into the query
|
|
||||||
* @param {Function} callback - Callback to run when a response is recieved
|
|
||||||
* @return {void}
|
|
||||||
*/
|
|
||||||
execute(/*sql, params, callback*/) {
|
|
||||||
throw new Error("Correct adapter not defined for query execution");
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,164 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
import helpers from './helpers'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Base Database Driver
|
|
||||||
*
|
|
||||||
* @module driver
|
|
||||||
*/
|
|
||||||
var d = {
|
|
||||||
identifierStartChar: '"',
|
|
||||||
identifierEndChar: '"',
|
|
||||||
tablePrefix: null,
|
|
||||||
hasTruncate: true,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Low level function for naive quoting of strings
|
|
||||||
|
|
||||||
* @param {String} str
|
|
||||||
* @return {String}
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
_quote: function(str) {
|
|
||||||
return (helpers.isString(str) && ! (str.startsWith(d.identifierStartChar) || str.endsWith(d.identifierEndChar)))
|
|
||||||
? d.identifierStartChar + str + d.identifierEndChar
|
|
||||||
: str;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the limit clause
|
|
||||||
|
|
||||||
* @param {String} sql
|
|
||||||
* @param {Number} limit
|
|
||||||
* @param {Number|null} offset
|
|
||||||
* @return {String}
|
|
||||||
*/
|
|
||||||
limit: function(sql, limit, offset) {
|
|
||||||
sql += " LIMIT " + limit;
|
|
||||||
|
|
||||||
if (helpers.isNumber(offset))
|
|
||||||
{
|
|
||||||
sql += " OFFSET " + offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
return sql;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Quote database table name, and set prefix
|
|
||||||
*
|
|
||||||
* @param {String} table
|
|
||||||
* @return {String}
|
|
||||||
*/
|
|
||||||
quoteTable: function(table) {
|
|
||||||
// Quote after prefix
|
|
||||||
return d.quoteIdentifiers(table);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Use the driver's escape character to quote identifiers
|
|
||||||
*
|
|
||||||
* @param {String|Array}
|
|
||||||
* @return {String|Array}
|
|
||||||
*/
|
|
||||||
quoteIdentifiers: function(str) {
|
|
||||||
var hiers, raw;
|
|
||||||
var pattern = new RegExp(d.identifierStartChar + '(' + '([a-zA-Z0-9_]+)' + '(\((.*?)\))' + ')' + d.identifierEndChar, 'ig');
|
|
||||||
|
|
||||||
// Recurse for arrays of identifiiers
|
|
||||||
if (Array.isArray(str))
|
|
||||||
{
|
|
||||||
return str.map(d.quoteIdentifiers);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle commas
|
|
||||||
if (str.includes(','))
|
|
||||||
{
|
|
||||||
var parts = str.split(',').map(helpers.stringTrim);
|
|
||||||
str = parts.map(d.quoteIdentifiers).join(',');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Split identifiers by period
|
|
||||||
hiers = str.split('.').map(d._quote);
|
|
||||||
raw = hiers.join('.');
|
|
||||||
|
|
||||||
// Fix functions
|
|
||||||
if (raw.includes('(') && raw.includes(')'))
|
|
||||||
{
|
|
||||||
var funcs = pattern.exec(raw);
|
|
||||||
|
|
||||||
// Unquote the function
|
|
||||||
raw = raw.replace(funcs[0], funcs[1]);
|
|
||||||
|
|
||||||
// Quote the identifiers inside of the parens
|
|
||||||
var inParens = funcs[3].substring(1, funcs[3].length -1);
|
|
||||||
raw = raw.replace(inParens, d.quoteIdentifiers(inParens));
|
|
||||||
}
|
|
||||||
|
|
||||||
return raw;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SQL to truncate the passed table
|
|
||||||
*
|
|
||||||
* @param {String} table
|
|
||||||
* @return {String} - sql
|
|
||||||
*/
|
|
||||||
truncate: function(table) {
|
|
||||||
var sql = (d.hasTruncate)
|
|
||||||
? 'TRUNCATE '
|
|
||||||
: 'DELETE FROM ';
|
|
||||||
|
|
||||||
sql += d.quoteTable(table);
|
|
||||||
|
|
||||||
return sql;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SQL to insert a group of rows
|
|
||||||
*
|
|
||||||
* @param {String} table - The table to insert to
|
|
||||||
* @param {Array} [data] - The array of object containing data to insert
|
|
||||||
* @return {String}
|
|
||||||
*/
|
|
||||||
insertBatch: function(table, data) {
|
|
||||||
var vals = [],
|
|
||||||
fields = Object.keys(data[0]),
|
|
||||||
sql = "",
|
|
||||||
params = [],
|
|
||||||
paramString = "",
|
|
||||||
paramList = [];
|
|
||||||
|
|
||||||
// Get the data values to insert, so they can
|
|
||||||
// be parameterized
|
|
||||||
data.forEach(function(obj) {
|
|
||||||
Object.keys(obj).forEach(function(key) {
|
|
||||||
vals.push(obj[key]);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// Get the field names from the keys of the first
|
|
||||||
// object inserted
|
|
||||||
table = d.quoteTable(table);
|
|
||||||
|
|
||||||
sql += "INSERT INTO " + table + " ("
|
|
||||||
+ d.quoteIdentifiers(fields).join(",")
|
|
||||||
+ ") VALUES ";
|
|
||||||
|
|
||||||
// Create placeholder groups
|
|
||||||
params = Array(fields.length).fill('?');
|
|
||||||
paramString = "(" + params.join(',') + ")";
|
|
||||||
paramList = Array(data.length).fill(paramString);
|
|
||||||
|
|
||||||
sql += paramList.join(',');
|
|
||||||
|
|
||||||
return {
|
|
||||||
sql: sql,
|
|
||||||
values: vals
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = d;
|
|
@ -1,13 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
import driverBase from './DriverBase';
|
|
||||||
|
|
||||||
module.exports = class DriverClass {
|
|
||||||
constructor(properties = {}) {
|
|
||||||
Object.keys(driverBase).forEach((key) => {
|
|
||||||
this[key] = (Object.keys(properties).indexOf(key) !== -1)
|
|
||||||
? properties[key]
|
|
||||||
: driverBase[key];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,74 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
let instance = null;
|
|
||||||
import fs from 'fs';
|
|
||||||
import helpers from './helpers';
|
|
||||||
import QueryBuilder from './QueryBuilder';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @module NodeQuery
|
|
||||||
*/
|
|
||||||
class NodeQuery {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor
|
|
||||||
*/
|
|
||||||
constructor() {
|
|
||||||
this.instance = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a query builder object
|
|
||||||
*
|
|
||||||
* @memberOf NodeQuery
|
|
||||||
* @param {String} drivername - The name of the database type, eg. mysql or pg
|
|
||||||
* @param {Object} connObject - A connection object from the database library you are connecting with
|
|
||||||
* @param {String} [connLib] - The name of the db connection library you are using, eg. mysql or mysql2. Optional if the same as drivername
|
|
||||||
* @return {QueryBuilder}
|
|
||||||
*/
|
|
||||||
init(driverType, connObject, connLib) {
|
|
||||||
connLib = connLib || driverType;
|
|
||||||
|
|
||||||
let paths = {
|
|
||||||
driver: `${__dirname}/drivers/` + helpers.upperCaseFirst(driverType),
|
|
||||||
adapter: `${__dirname}/adapters/${connLib}`
|
|
||||||
};
|
|
||||||
|
|
||||||
/*Object.keys(paths).forEach((type) => {
|
|
||||||
if ( ! fs.existsSync(paths[type]))
|
|
||||||
{
|
|
||||||
console.log(paths[type]);
|
|
||||||
throw new Error(
|
|
||||||
`Selected ${type} (` +
|
|
||||||
helpers.upperCaseFirst(driverType) +
|
|
||||||
`) does not exist!`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});*/
|
|
||||||
|
|
||||||
let driver = require(paths.driver);
|
|
||||||
let $adapter = require(paths.adapter);
|
|
||||||
let adapter = new $adapter(connObject);
|
|
||||||
|
|
||||||
this.instance = new QueryBuilder(driver, adapter);
|
|
||||||
|
|
||||||
return this.instance;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return an existing query builder instance
|
|
||||||
*
|
|
||||||
* @memberOf NodeQuery
|
|
||||||
* @return {QueryBuilder}
|
|
||||||
*/
|
|
||||||
getQuery() {
|
|
||||||
if ( ! this.instance) {
|
|
||||||
throw new Error("No Query Builder instance to return");
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.instance;
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = new NodeQuery();
|
|
@ -1,924 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
/** @module QueryBuilder */
|
|
||||||
import getArgs from 'getargs';
|
|
||||||
import helpers from './helpers';
|
|
||||||
import State from './State';
|
|
||||||
import QueryParser from './QueryParser';
|
|
||||||
|
|
||||||
module.exports = class QueryBuilder {
|
|
||||||
/*
|
|
||||||
* SQL generation object
|
|
||||||
*
|
|
||||||
* @param {driver} - The syntax driver for the database
|
|
||||||
* @param {adapter} - The database module adapter for running queries
|
|
||||||
* @returns {QueryBuilder}
|
|
||||||
* @constructor
|
|
||||||
*/
|
|
||||||
constructor(driver, adapter) {
|
|
||||||
this.driver = driver;
|
|
||||||
this.adapter = adapter;
|
|
||||||
this.parser = new QueryParser(this.driver);
|
|
||||||
this.state = new State();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Complete the sql building based on the type provided
|
|
||||||
*
|
|
||||||
* @param {String} type
|
|
||||||
* @param {String} table
|
|
||||||
* @private
|
|
||||||
* @return {String}
|
|
||||||
*/
|
|
||||||
_compile(type, table) {
|
|
||||||
// Put together the basic query
|
|
||||||
let sql = this._compileType(type, table);
|
|
||||||
|
|
||||||
// Set each subClause
|
|
||||||
['queryMap', 'groupString', 'orderString', 'havingMap'].forEach((clause) => {
|
|
||||||
let param = this.state[clause];
|
|
||||||
|
|
||||||
if ( ! helpers.isScalar(param))
|
|
||||||
{
|
|
||||||
Object.keys(param).forEach((part) => {
|
|
||||||
sql += param[part].conjunction + param[part].string;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sql += param;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Append the limit, if it exists
|
|
||||||
if (helpers.isNumber(this.state.limit))
|
|
||||||
{
|
|
||||||
sql = this.driver.limit(sql, this.state.limit, this.state.offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
return sql;
|
|
||||||
}
|
|
||||||
|
|
||||||
_compileType(type, table) {
|
|
||||||
let sql = '';
|
|
||||||
|
|
||||||
switch(type) {
|
|
||||||
case "insert":
|
|
||||||
let params = Array(this.state.setArrayKeys.length).fill('?');
|
|
||||||
|
|
||||||
sql = `INSERT INTO ${table} (`;
|
|
||||||
sql += this.state.setArrayKeys.join(',');
|
|
||||||
sql += ") VALUES (";
|
|
||||||
sql += params.join(',') + ')';
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "update":
|
|
||||||
sql = `UPDATE ${table} SET ${this.state.setString}`;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "delete":
|
|
||||||
sql = `DELETE FROM ${table}`;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
sql = `SELECT * FROM ${this.state.fromString}`;
|
|
||||||
|
|
||||||
// Set the select string
|
|
||||||
if (this.state.selectString.length > 0)
|
|
||||||
{
|
|
||||||
// Replace the star with the selected fields
|
|
||||||
sql = sql.replace('*', this.state.selectString);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return sql;
|
|
||||||
}
|
|
||||||
|
|
||||||
_like(field, val, pos, like, conj) {
|
|
||||||
field = this.driver.quoteIdentifiers(field);
|
|
||||||
|
|
||||||
like = `${field} ${like} ?`;
|
|
||||||
|
|
||||||
if (pos == 'before')
|
|
||||||
{
|
|
||||||
val = `%${val}`;
|
|
||||||
}
|
|
||||||
else if (pos == 'after')
|
|
||||||
{
|
|
||||||
val = `${val}%`;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
val = `%${val}%`;
|
|
||||||
}
|
|
||||||
|
|
||||||
conj = (this.state.queryMap.length < 1) ? ' WHERE ' : ` ${conj} `;
|
|
||||||
this._appendMap(conj, like, 'like');
|
|
||||||
|
|
||||||
this.state.whereValues.push(val);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Append a clause to the query map
|
|
||||||
*
|
|
||||||
* @param {String} conjunction
|
|
||||||
* @param {String} string
|
|
||||||
* @param {String} type
|
|
||||||
* @return {void}
|
|
||||||
*/
|
|
||||||
_appendMap(conjunction, string, type) {
|
|
||||||
this.state.queryMap.push({
|
|
||||||
type: type,
|
|
||||||
conjunction: conjunction,
|
|
||||||
string: string
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle key/value pairs in an object the same way as individual arguments,
|
|
||||||
* when appending to state
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
_mixedSet(/* $letName, $valType, $key, [$val] */) {
|
|
||||||
let args = getArgs('$letName:string, $valType:string, $key:object|string|number, [$val]', arguments);
|
|
||||||
|
|
||||||
let obj = {};
|
|
||||||
|
|
||||||
|
|
||||||
if (helpers.isScalar(args.$key) && !helpers.isUndefined(args.$val))
|
|
||||||
{
|
|
||||||
// Convert key/val pair to a simple object
|
|
||||||
obj[args.$key] = args.$val;
|
|
||||||
}
|
|
||||||
else if (helpers.isScalar(args.$key) && helpers.isUndefined(args.$val))
|
|
||||||
{
|
|
||||||
// If just a string for the key, and no value, create a simple object with duplicate key/val
|
|
||||||
obj[args.$key] = args.$key;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
obj = args.$key;
|
|
||||||
}
|
|
||||||
|
|
||||||
Object.keys(obj).forEach((k) => {
|
|
||||||
// If a single value for the return
|
|
||||||
if (['key','value'].indexOf(args.$valType) !== -1)
|
|
||||||
{
|
|
||||||
let pushVal = (args.$valType === 'key') ? k : obj[k];
|
|
||||||
this.state[args.$letName].push(pushVal);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this.state[args.$letName][k] = obj[k];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
return this.state[args.$letName];
|
|
||||||
}
|
|
||||||
|
|
||||||
_whereMixedSet(/*key, val*/) {
|
|
||||||
let args = getArgs('key:string|object, [val]', arguments);
|
|
||||||
|
|
||||||
this.state.whereMap = [];
|
|
||||||
this.state.rawWhereValues = [];
|
|
||||||
|
|
||||||
this._mixedSet('whereMap', 'both', args.key, args.val);
|
|
||||||
this._mixedSet('rawWhereValues', 'value', args.key, args.val);
|
|
||||||
}
|
|
||||||
|
|
||||||
_fixConjunction(conj) {
|
|
||||||
let lastItem = this.state.queryMap[this.state.queryMap.length - 1];
|
|
||||||
let conjunctionList = helpers.arrayPluck(this.state.queryMap, 'conjunction');
|
|
||||||
|
|
||||||
if (this.state.queryMap.length === 0 || ( ! helpers.regexInArray(conjunctionList, /^ ?WHERE/i)))
|
|
||||||
{
|
|
||||||
conj = " WHERE ";
|
|
||||||
}
|
|
||||||
else if (lastItem.type === 'groupStart')
|
|
||||||
{
|
|
||||||
conj = '';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
conj = ' ' + conj + ' ';
|
|
||||||
}
|
|
||||||
|
|
||||||
return conj;
|
|
||||||
}
|
|
||||||
|
|
||||||
_where(key, val, defaultConj) {
|
|
||||||
// Normalize key and value and insert into this.state.whereMap
|
|
||||||
this._whereMixedSet(key, val);
|
|
||||||
|
|
||||||
// Parse the where condition to account for operators,
|
|
||||||
// functions, identifiers, and literal values
|
|
||||||
this.state = this.parser.parseWhere(this.driver, this.state);
|
|
||||||
|
|
||||||
this.state.whereMap.forEach((clause) => {
|
|
||||||
let conj = this._fixConjunction(defaultConj);
|
|
||||||
this._appendMap(conj, clause, 'where');
|
|
||||||
});
|
|
||||||
|
|
||||||
this.state.whereMap = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
_whereNull(field, stmt, conj) {
|
|
||||||
field = this.driver.quoteIdentifiers(field);
|
|
||||||
let item = field + ' ' + stmt;
|
|
||||||
|
|
||||||
this._appendMap(this._fixConjunction(conj), item, 'whereNull');
|
|
||||||
}
|
|
||||||
|
|
||||||
_having(/*key, val, conj*/) {
|
|
||||||
let args = getArgs('key:string|object, [val]:string|number, [conj]:string', arguments);
|
|
||||||
args.conj = args.conj || 'AND';
|
|
||||||
args.val = args.val || null;
|
|
||||||
|
|
||||||
// Normalize key/val and put in state.whereMap
|
|
||||||
this._whereMixedSet(args.key, args.val);
|
|
||||||
|
|
||||||
// Parse the having condition to account for operators,
|
|
||||||
// functions, identifiers, and literal values
|
|
||||||
this.state = this.parser.parseWhere(this.driver, this.state);
|
|
||||||
|
|
||||||
this.state.whereMap.forEach((clause) => {
|
|
||||||
// Put in the having map
|
|
||||||
this.state.havingMap.push({
|
|
||||||
conjunction: (this.state.havingMap.length > 0) ? ` ${args.conj} ` : ' HAVING ',
|
|
||||||
string: clause
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// Clear the where Map
|
|
||||||
this.state.whereMap = {};
|
|
||||||
}
|
|
||||||
_whereIn(/*key, val, inClause, conj*/) {
|
|
||||||
let args = getArgs('key:string, val:array, inClause:string, conj:string', arguments);
|
|
||||||
|
|
||||||
args.key = this.driver.quoteIdentifiers(args.key);
|
|
||||||
let params = new Array(args.val.length);
|
|
||||||
params.fill('?');
|
|
||||||
|
|
||||||
args.val.forEach((value) => {
|
|
||||||
this.state.whereValues.push(value);
|
|
||||||
});
|
|
||||||
|
|
||||||
args.conj = (this.state.queryMap.length > 0) ? " " + args.conj + " " : ' WHERE ';
|
|
||||||
let str = args.key + " " + args.inClause + " (" + params.join(',') + ") ";
|
|
||||||
|
|
||||||
this._appendMap(args.conj, str, 'whereIn');
|
|
||||||
}
|
|
||||||
|
|
||||||
_run(type, table, callback, sql, vals) {
|
|
||||||
|
|
||||||
if ( ! sql)
|
|
||||||
{
|
|
||||||
sql = this._compile(type, table);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ! vals)
|
|
||||||
{
|
|
||||||
vals = this.state.values.concat(this.state.whereValues);
|
|
||||||
}
|
|
||||||
|
|
||||||
//console.log(this.state);
|
|
||||||
//console.log(sql);
|
|
||||||
//console.log(vals);
|
|
||||||
//console.log(callback);
|
|
||||||
//console.log('------------------------');
|
|
||||||
|
|
||||||
// Reset the state so another query can be built
|
|
||||||
this._resetState();
|
|
||||||
|
|
||||||
// Pass the sql and values to the adapter to run on the database
|
|
||||||
this.adapter.execute(sql, vals, callback);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
_getCompile(type, table, reset) {
|
|
||||||
reset = reset || false;
|
|
||||||
|
|
||||||
let sql = this._compile(type, table);
|
|
||||||
|
|
||||||
if (reset) this._resetState();
|
|
||||||
|
|
||||||
return sql;
|
|
||||||
}
|
|
||||||
|
|
||||||
_resetState() {
|
|
||||||
this.state = new State();
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// ! Miscellaneous Methods
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reset the object state for a new query
|
|
||||||
*
|
|
||||||
* @memberOf QueryBuilder
|
|
||||||
* @return {void}
|
|
||||||
*/
|
|
||||||
resetQuery() {
|
|
||||||
this._resetState();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the current class state for testing or other purposes
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @return {Object}
|
|
||||||
*/
|
|
||||||
getState() {
|
|
||||||
return this.state;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Closes the database connection for the current adapter
|
|
||||||
*
|
|
||||||
* @return {void}
|
|
||||||
*/
|
|
||||||
end() {
|
|
||||||
this.adapter.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
|
||||||
// ! Query Builder Methods
|
|
||||||
// ------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Specify rows to select in the query
|
|
||||||
*
|
|
||||||
* @memberOf QueryBuilder
|
|
||||||
* @param {String|Array} fields - The fields to select from the current table
|
|
||||||
* @return {QueryBuilder}
|
|
||||||
*/
|
|
||||||
select(fields) {
|
|
||||||
|
|
||||||
// Split/trim fields by comma
|
|
||||||
fields = (Array.isArray(fields))
|
|
||||||
? fields
|
|
||||||
: fields.split(",").map(helpers.stringTrim);
|
|
||||||
|
|
||||||
// Split on 'As'
|
|
||||||
fields.forEach((field, index) => {
|
|
||||||
if (field.match(/as/i))
|
|
||||||
{
|
|
||||||
fields[index] = field.split(/ as /i).map(helpers.stringTrim);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let safeArray = this.driver.quoteIdentifiers(fields);
|
|
||||||
|
|
||||||
// Join the strings back together
|
|
||||||
safeArray.forEach((field, index) => {
|
|
||||||
if (Array.isArray(field))
|
|
||||||
{
|
|
||||||
safeArray[index] = safeArray[index].join(' AS ');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this.state.selectString += safeArray.join(', ');
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Specify the database table to select from
|
|
||||||
*
|
|
||||||
* @param {String} tableName - The table to use for the current query
|
|
||||||
* @return {QueryBuilder}
|
|
||||||
*/
|
|
||||||
from(tableName) {
|
|
||||||
// Split identifiers on spaces
|
|
||||||
let identArray = tableName.trim().split(' ').map(helpers.stringTrim);
|
|
||||||
|
|
||||||
// Quote/prefix identifiers
|
|
||||||
identArray[0] = this.driver.quoteTable(identArray[0]);
|
|
||||||
identArray = this.driver.quoteIdentifiers(identArray);
|
|
||||||
|
|
||||||
// Put it back together
|
|
||||||
this.state.fromString = identArray.join(' ');
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a 'like/ and like' clause to the query
|
|
||||||
*
|
|
||||||
* @param {String} field - The name of the field to compare to
|
|
||||||
* @param {String} val - The value to compare to
|
|
||||||
* @param {String} [pos=both] - The placement of the wildcard character(s): before, after, or both
|
|
||||||
* @return {QueryBuilder}
|
|
||||||
*/
|
|
||||||
like(field, val, pos) {
|
|
||||||
this._like(field, val, pos, ' LIKE ', 'AND');
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a 'not like/ and not like' clause to the query
|
|
||||||
*
|
|
||||||
* @param {String} field - The name of the field to compare to
|
|
||||||
* @param {String} val - The value to compare to
|
|
||||||
* @param {String} [pos=both] - The placement of the wildcard character(s): before, after, or both
|
|
||||||
* @return {QueryBuilder}
|
|
||||||
*/
|
|
||||||
notLike(field, val, pos) {
|
|
||||||
this._like(field, val, pos, ' NOT LIKE ', 'AND');
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add an 'or like' clause to the query
|
|
||||||
*
|
|
||||||
* @param {String} field - The name of the field to compare to
|
|
||||||
* @param {String} val - The value to compare to
|
|
||||||
* @param {String} [pos=both] - The placement of the wildcard character(s): before, after, or both
|
|
||||||
* @return {QueryBuilder}
|
|
||||||
*/
|
|
||||||
orLike(field, val, pos) {
|
|
||||||
this._like(field, val, pos, ' LIKE ', 'OR');
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add an 'or not like' clause to the query
|
|
||||||
*
|
|
||||||
* @param {String} field - The name of the field to compare to
|
|
||||||
* @param {String} val - The value to compare to
|
|
||||||
* @param {String} [pos=both] - The placement of the wildcard character(s): before, after, or both
|
|
||||||
* @return {QueryBuilder}
|
|
||||||
*/
|
|
||||||
orNotLike(field, val, pos) {
|
|
||||||
this._like(field, val, pos, ' NOT LIKE ', 'OR');
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a 'having' clause
|
|
||||||
*
|
|
||||||
* @param {String|Object} key - The name of the field and the comparision operator, or an object
|
|
||||||
* @param {String|Number} [val] - The value to compare if the value of key is a string
|
|
||||||
* @return {QueryBuilder}
|
|
||||||
*/
|
|
||||||
having(/*key, [val]*/) {
|
|
||||||
let args = getArgs('key:string|object, [val]:string|number', arguments);
|
|
||||||
|
|
||||||
this._having(args.key, args.val, 'AND');
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add an 'or having' clause
|
|
||||||
*
|
|
||||||
* @param {String|Object} key - The name of the field and the comparision operator, or an object
|
|
||||||
* @param {String|Number} [val] - The value to compare if the value of key is a string
|
|
||||||
* @return {QueryBuilder}
|
|
||||||
*/
|
|
||||||
orHaving(/*key, [val]*/) {
|
|
||||||
let args = getArgs('key:string|object, [val]:string|number', arguments);
|
|
||||||
|
|
||||||
this._having(args.key, args.val, 'OR');
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set a 'where' clause
|
|
||||||
*
|
|
||||||
* @param {String|Object} key - The name of the field and the comparision operator, or an object
|
|
||||||
* @param {String|Number} [val] - The value to compare if the value of key is a string
|
|
||||||
* @return {QueryBuilder}
|
|
||||||
*/
|
|
||||||
where(key, val) {
|
|
||||||
this._where(key, val, 'AND');
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set a 'or where' clause
|
|
||||||
*
|
|
||||||
* @param {String|Object} key - The name of the field and the comparision operator, or an object
|
|
||||||
* @param {String|Number} [val] - The value to compare if the value of key is a string
|
|
||||||
* @return {QueryBuilder}
|
|
||||||
*/
|
|
||||||
orWhere(key, val) {
|
|
||||||
this._where(key, val, 'OR');
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Select a field that is Null
|
|
||||||
*
|
|
||||||
* @param {String} field - The name of the field that has a NULL value
|
|
||||||
* @return {QueryBuilder}
|
|
||||||
*/
|
|
||||||
whereIsNull(field) {
|
|
||||||
this._whereNull(field, 'IS NULL', 'AND');
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Specify that a field IS NOT NULL
|
|
||||||
*
|
|
||||||
* @param {String} field
|
|
||||||
* @return {QueryBuilder}
|
|
||||||
*/
|
|
||||||
whereIsNotNull(field) {
|
|
||||||
this._whereNull(field, 'IS NOT NULL', 'AND');
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Field is null prefixed with 'OR'
|
|
||||||
*
|
|
||||||
* @param {String} field
|
|
||||||
* @return {QueryBuilder}
|
|
||||||
*/
|
|
||||||
orWhereIsNull(field) {
|
|
||||||
this._whereNull(field, 'IS NULL', 'OR');
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Field is not null prefixed with 'OR'
|
|
||||||
*
|
|
||||||
* @param {String} field
|
|
||||||
* @return {QueryBuilder}
|
|
||||||
*/
|
|
||||||
orWhereIsNotNull(field) {
|
|
||||||
this._whereNull(field, 'IS NOT NULL', 'OR');
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set a 'where in' clause
|
|
||||||
*
|
|
||||||
* @param {String} key - the field to search
|
|
||||||
* @param {Array} val - the array of items to search in
|
|
||||||
* @return {QueryBuilder}
|
|
||||||
*/
|
|
||||||
whereIn(key, val) {
|
|
||||||
this._whereIn(key, val, 'IN', 'AND');
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set a 'or where in' clause
|
|
||||||
*
|
|
||||||
* @param {String} key - the field to search
|
|
||||||
* @param {Array} val - the array of items to search in
|
|
||||||
* @return {QueryBuilder}
|
|
||||||
*/
|
|
||||||
orWhereIn(key, val) {
|
|
||||||
this._whereIn(key, val, 'IN', 'OR');
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set a 'where not in' clause
|
|
||||||
*
|
|
||||||
* @param {String} key - the field to search
|
|
||||||
* @param {Array} val - the array of items to search in
|
|
||||||
* @return {QueryBuilder}
|
|
||||||
*/
|
|
||||||
whereNotIn(key, val) {
|
|
||||||
this._whereIn(key, val, 'NOT IN', 'AND');
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set a 'or where not in' clause
|
|
||||||
*
|
|
||||||
* @param {String} key - the field to search
|
|
||||||
* @param {Array} val - the array of items to search in
|
|
||||||
* @return {QueryBuilder}
|
|
||||||
*/
|
|
||||||
orWhereNotIn(key, val) {
|
|
||||||
this._whereIn(key, val, 'NOT IN', 'OR');
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set values for insertion or updating
|
|
||||||
*
|
|
||||||
* @param {String|Object} key - The key or object to use
|
|
||||||
* @param {String} [val] - The value if using a scalar key
|
|
||||||
* @return {QueryBuilder}
|
|
||||||
*/
|
|
||||||
set(/* $key, [$val] */) {
|
|
||||||
let args = getArgs('$key, [$val]', arguments);
|
|
||||||
|
|
||||||
// Set the appropriate state variables
|
|
||||||
this._mixedSet('setArrayKeys', 'key', args.$key, args.$val);
|
|
||||||
this._mixedSet('values', 'value', args.$key, args.$val);
|
|
||||||
|
|
||||||
// Use the keys of the array to make the insert/update string
|
|
||||||
// and escape the field names
|
|
||||||
this.state.setArrayKeys = this.state.setArrayKeys.map(this.driver._quote);
|
|
||||||
|
|
||||||
// Generate the "set" string
|
|
||||||
this.state.setString = this.state.setArrayKeys.join('=?,');
|
|
||||||
this.state.setString += '=?';
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a join clause to the query
|
|
||||||
*
|
|
||||||
* @param {String} table - The table you are joining
|
|
||||||
* @param {String} cond - The join condition.
|
|
||||||
* @param {String} [type='inner'] - The type of join, which defaults to inner
|
|
||||||
* @return {QueryBuilder}
|
|
||||||
*/
|
|
||||||
join(table, cond, type) {
|
|
||||||
type = type || "inner";
|
|
||||||
|
|
||||||
// Prefix/quote table name
|
|
||||||
table = table.split(' ').map(helpers.stringTrim);
|
|
||||||
table[0] = this.driver.quoteTable(table[0]);
|
|
||||||
table = table.map(this.driver.quoteIdentifiers);
|
|
||||||
table = table.join(' ');
|
|
||||||
|
|
||||||
// Parse out the join condition
|
|
||||||
let parsedCondition = this.parser.compileJoin(cond);
|
|
||||||
let condition = table + ' ON ' + parsedCondition;
|
|
||||||
|
|
||||||
// Append the join condition to the query map
|
|
||||||
this._appendMap("\n" + type.toUpperCase() + ' JOIN ', condition, 'join');
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Group the results by the selected field(s)
|
|
||||||
*
|
|
||||||
* @param {String|Array} field
|
|
||||||
* @return {QueryBuilder}
|
|
||||||
*/
|
|
||||||
groupBy(field) {
|
|
||||||
if ( ! helpers.isScalar(field))
|
|
||||||
{
|
|
||||||
let newGroupArray = field.map(this.driver.quoteIdentifiers);
|
|
||||||
this.state.groupArray = this.state.groupArray.concat(newGroupArray);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this.state.groupArray.push(this.driver.quoteIdentifiers(field));
|
|
||||||
}
|
|
||||||
|
|
||||||
this.state.groupString = ' GROUP BY ' + this.state.groupArray.join(',');
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Order the results by the selected field(s)
|
|
||||||
*
|
|
||||||
* @param {String} field - The field(s) to order by
|
|
||||||
* @param {String} [type='ASC'] - The order direction, ASC or DESC
|
|
||||||
* @return {QueryBuilder}
|
|
||||||
*/
|
|
||||||
orderBy(field, type) {
|
|
||||||
type = type || 'ASC';
|
|
||||||
|
|
||||||
// Set the fields for later manipulation
|
|
||||||
field = this.driver.quoteIdentifiers(field);
|
|
||||||
|
|
||||||
this.state.orderArray[field] = type;
|
|
||||||
|
|
||||||
let orderClauses = [];
|
|
||||||
|
|
||||||
// Flatten key/val pairs into an array of space-separated pairs
|
|
||||||
Object.keys(this.state.orderArray).forEach((key) => {
|
|
||||||
orderClauses.push(key + ' ' + this.state.orderArray[key].toUpperCase());
|
|
||||||
});
|
|
||||||
|
|
||||||
// Set the final string
|
|
||||||
this.state.orderString = ' ORDER BY ' + orderClauses.join(', ');
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Put a limit on the query
|
|
||||||
*
|
|
||||||
* @param {Number} limit - The maximum number of rows to fetch
|
|
||||||
* @param {Number} [offset] - The row number to start from
|
|
||||||
* @return {QueryBuilder}
|
|
||||||
*/
|
|
||||||
limit(limit, offset) {
|
|
||||||
this.state.limit = limit;
|
|
||||||
this.state.offset = offset || null;
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds an open paren to the current query for logical grouping
|
|
||||||
*
|
|
||||||
* @return {QueryBuilder}
|
|
||||||
*/
|
|
||||||
groupStart() {
|
|
||||||
let conj = (this.state.queryMap.length < 1) ? ' WHERE ' : ' AND ';
|
|
||||||
this._appendMap(conj, '(', 'groupStart');
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds an open paren to the current query for logical grouping,
|
|
||||||
* prefixed with 'OR'
|
|
||||||
*
|
|
||||||
* @return {QueryBuilder}
|
|
||||||
*/
|
|
||||||
orGroupStart() {
|
|
||||||
this._appendMap('', ' OR (', 'groupStart');
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds an open paren to the current query for logical grouping,
|
|
||||||
* prefixed with 'OR NOT'
|
|
||||||
*
|
|
||||||
* @return {QueryBuilder}
|
|
||||||
*/
|
|
||||||
orNotGroupStart() {
|
|
||||||
this._appendMap('', ' OR NOT (', 'groupStart');
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ends a logical grouping started with one of the groupStart methods
|
|
||||||
*
|
|
||||||
* @return {QueryBuilder}
|
|
||||||
*/
|
|
||||||
groupEnd() {
|
|
||||||
this._appendMap('', ')', 'groupEnd');
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
|
||||||
// ! Result Methods
|
|
||||||
// ------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the results of the compiled query
|
|
||||||
*
|
|
||||||
* @param {String} [table] - The table to select from
|
|
||||||
* @param {Number} [limit] - A limit for the query
|
|
||||||
* @param {Number} [offset] - An offset for the query
|
|
||||||
* @param {Function} callback - A callback for receiving the result
|
|
||||||
* @return {void}
|
|
||||||
*/
|
|
||||||
get(/* [table], [limit], [offset], callback */) {
|
|
||||||
let args = getArgs('[table]:string, [limit]:number, [offset]:number, callback:function', arguments);
|
|
||||||
|
|
||||||
if (args.table) {
|
|
||||||
this.from(args.table);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args.limit) {
|
|
||||||
this.limit(args.limit, args.offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run the query
|
|
||||||
this._run('get', args.table, args.callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Run the generated insert query
|
|
||||||
*
|
|
||||||
* @param {String} table - The table to insert into
|
|
||||||
* @param {Object} [data] - Data to insert, if not already added with the 'set' method
|
|
||||||
* @param {Function} callback - Callback for handling response from the database
|
|
||||||
* @return {void}
|
|
||||||
*/
|
|
||||||
insert(/* table, data, callback */) {
|
|
||||||
let args = getArgs('table:string, [data]:object, callback:function', arguments);
|
|
||||||
|
|
||||||
if (args.data) {
|
|
||||||
this.set(args.data);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run the query
|
|
||||||
this._run('insert', this.driver.quoteTable(args.table), args.callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Insert multiple sets of rows at a time
|
|
||||||
*
|
|
||||||
* @param {String} table - The table to insert into
|
|
||||||
* @param {Array} data - The array of objects containing data rows to insert
|
|
||||||
* @param {Function} callback - Callback for handling database response
|
|
||||||
* @example query.insertBatch('foo',[{id:1,val:'bar'},{id:2,val:'baz'}], callbackFunction);
|
|
||||||
* @return {void}
|
|
||||||
*/
|
|
||||||
insertBatch(/* table, data, callback */) {
|
|
||||||
let args = getArgs('table:string, data:array, callback:function', arguments);
|
|
||||||
let batch = this.driver.insertBatch(args.table, args.data);
|
|
||||||
|
|
||||||
// Run the query
|
|
||||||
this._run('', '', args.callback, batch.sql, batch.values);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Run the generated update query
|
|
||||||
*
|
|
||||||
* @param {String} table - The table to insert into
|
|
||||||
* @param {Object} [data] - Data to insert, if not already added with the 'set' method
|
|
||||||
* @param {Function} callback - Callback for handling response from the database
|
|
||||||
* @return {void}
|
|
||||||
*/
|
|
||||||
update(/*table, data, callback*/) {
|
|
||||||
let args = getArgs('table:string, [data]:object, callback:function', arguments);
|
|
||||||
|
|
||||||
if (args.data) {
|
|
||||||
this.set(args.data);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run the query
|
|
||||||
this._run('update', this.driver.quoteTable(args.table), args.callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Run the generated delete query
|
|
||||||
*
|
|
||||||
* @param {String} table - The table to insert into
|
|
||||||
* @param {Object} [where] - Where clause for delete statement
|
|
||||||
* @param {Function} callback - Callback for handling response from the database
|
|
||||||
* @return {void}
|
|
||||||
*/
|
|
||||||
delete(/*table, [where], callback*/) {
|
|
||||||
let args = getArgs('table:string, [where]:object, callback:function', arguments);
|
|
||||||
|
|
||||||
if (args.where)
|
|
||||||
{
|
|
||||||
this.where(args.where);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run the query
|
|
||||||
this._run('delete', this.driver.quoteTable(args.table), args.callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
|
||||||
// ! Methods returning SQL
|
|
||||||
// ------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return generated select query SQL
|
|
||||||
*
|
|
||||||
* @param {String} [table] - the name of the table to retrieve from
|
|
||||||
* @param {Boolean} [reset=true] - Whether to reset the query builder so another query can be built
|
|
||||||
* @return {String}
|
|
||||||
*/
|
|
||||||
getCompiledSelect(/*table, reset*/) {
|
|
||||||
let args = getArgs('[table]:string, [reset]:boolean', arguments);
|
|
||||||
if (args.table)
|
|
||||||
{
|
|
||||||
this.from(args.table);
|
|
||||||
}
|
|
||||||
|
|
||||||
return this._getCompile('get', args.table, args.reset);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return generated insert query SQL
|
|
||||||
*
|
|
||||||
* @param {String} table - the name of the table to insert into
|
|
||||||
* @param {Boolean} [reset=true] - Whether to reset the query builder so another query can be built
|
|
||||||
* @return {String}
|
|
||||||
*/
|
|
||||||
getCompiledInsert(table, reset) {
|
|
||||||
return this._getCompile('insert', this.driver.quoteTable(table), reset);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return generated update query SQL
|
|
||||||
*
|
|
||||||
* @param {String} table - the name of the table to update
|
|
||||||
* @param {Boolean} [reset=true] - Whether to reset the query builder so another query can be built
|
|
||||||
* @return {String}
|
|
||||||
*/
|
|
||||||
getCompiledUpdate(table, reset) {
|
|
||||||
return this._getCompile('update', this.driver.quoteTable(table), reset);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return generated delete query SQL
|
|
||||||
*
|
|
||||||
* @param {String} table - the name of the table to delete from
|
|
||||||
* @param {Boolean} [reset=true] - Whether to reset the query builder so another query can be built
|
|
||||||
* @return {String}
|
|
||||||
*/
|
|
||||||
getCompiledDelete(table, reset) {
|
|
||||||
return this._getCompile('delete', this.driver.quoteTable(table), reset);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,274 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
import helpers from './helpers';
|
|
||||||
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @constructor
|
|
||||||
* @param {Driver} - The driver object for the database in use
|
|
||||||
* @module query-parser
|
|
||||||
*/
|
|
||||||
module.exports = class QueryParser {
|
|
||||||
/**
|
|
||||||
* @constructor
|
|
||||||
* @param {Driver} - The driver object for the database in use
|
|
||||||
* @return {void}
|
|
||||||
*/
|
|
||||||
constructor(driver) {
|
|
||||||
this.driver = driver;
|
|
||||||
|
|
||||||
let matchPatterns = {
|
|
||||||
'function': /([a-z0-9_]+\((.*)\))/i,
|
|
||||||
operator: /\!=?|\=|\+|&&?|~|\|\|?|\^|\/|<>|>=?|<=?|\-|%|OR|AND|NOT|XOR/ig,
|
|
||||||
literal: /([0-9]+)|'(.*?)'|true|false/ig
|
|
||||||
};
|
|
||||||
|
|
||||||
// Full pattern for identifiers
|
|
||||||
// Making sure that literals and functions aren't matched
|
|
||||||
matchPatterns.identifier = new RegExp(
|
|
||||||
'('
|
|
||||||
+ '(?!'
|
|
||||||
+ matchPatterns['function'].source + '|'
|
|
||||||
+ matchPatterns.literal.source
|
|
||||||
+ ')'
|
|
||||||
+ '([a-z_\-]+[0-9]*\\.?)'
|
|
||||||
+ ')+'
|
|
||||||
, 'ig');
|
|
||||||
|
|
||||||
// Full pattern for determining ordering of the pieces
|
|
||||||
matchPatterns.joinCombined = new RegExp(
|
|
||||||
matchPatterns['function'].source + "+|"
|
|
||||||
+ matchPatterns.literal.source + '+|'
|
|
||||||
+ matchPatterns.identifier.source
|
|
||||||
+ '|(' + matchPatterns.operator.source + ')+'
|
|
||||||
, 'ig');
|
|
||||||
|
|
||||||
this.matchPatterns = matchPatterns;
|
|
||||||
this.identifierBlacklist = ['true','false','null'];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Filter matched patterns
|
|
||||||
*
|
|
||||||
* @param {Array} array
|
|
||||||
* @return {Array|null}
|
|
||||||
*/
|
|
||||||
filterMatches(array) {
|
|
||||||
let output = [];
|
|
||||||
|
|
||||||
// Return non-array matches
|
|
||||||
if (helpers.isNull(array)) return null;
|
|
||||||
if (helpers.isScalar(array) || helpers.isUndefined(array)) return output;
|
|
||||||
|
|
||||||
array.forEach((item) => {
|
|
||||||
output.push(item);
|
|
||||||
});
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if the string contains an operator, and if so, return the operator(s).
|
|
||||||
* If there are no matches, return null
|
|
||||||
*
|
|
||||||
* @param {String} string - the string to check
|
|
||||||
* @return {Array|null}
|
|
||||||
*/
|
|
||||||
hasOperator(string) {
|
|
||||||
return this.filterMatches(string.match(this.matchPatterns.operator));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tokenize the sql into parts for additional processing
|
|
||||||
*
|
|
||||||
* @param {String} sql
|
|
||||||
* @return {Object}
|
|
||||||
*/
|
|
||||||
parseJoin(sql) {
|
|
||||||
let matches = {};
|
|
||||||
let output = {
|
|
||||||
functions: [],
|
|
||||||
identifiers: [],
|
|
||||||
operators: [],
|
|
||||||
literals: []
|
|
||||||
};
|
|
||||||
|
|
||||||
// Get clause components
|
|
||||||
matches.functions = sql.match(new RegExp(this.matchPatterns['function'].source, 'ig'));
|
|
||||||
matches.identifiers = sql.match(this.matchPatterns.identifier);
|
|
||||||
matches.operators = sql.match(this.matchPatterns.operator);
|
|
||||||
matches.literals = sql.match(this.matchPatterns.literal);
|
|
||||||
|
|
||||||
// Get everything at once for ordering
|
|
||||||
matches.combined = sql.match(this.matchPatterns.joinCombined);
|
|
||||||
|
|
||||||
// Flatten the matches to increase relevance
|
|
||||||
Object.keys(matches).forEach((key) => {
|
|
||||||
output[key] = this.filterMatches(matches[key]);
|
|
||||||
});
|
|
||||||
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the output of the parsing of the join condition
|
|
||||||
*
|
|
||||||
* @param {String} condition - The join condition to evalate
|
|
||||||
* @return {String} - The parsed/escaped join condition
|
|
||||||
*/
|
|
||||||
compileJoin(condition) {
|
|
||||||
let parts = this.parseJoin(condition);
|
|
||||||
let count = parts.identifiers.length;
|
|
||||||
let i;
|
|
||||||
|
|
||||||
// Quote the identifiers
|
|
||||||
parts.combined.forEach((part, i) => {
|
|
||||||
if (parts.identifiers.indexOf(part) !== -1 && ! helpers.isNumber(part))
|
|
||||||
{
|
|
||||||
parts.combined[i] = this.driver.quoteIdentifiers(part);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return parts.combined.join(' ');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse a where clause to separate functions from values
|
|
||||||
*
|
|
||||||
* @param {Driver} driver
|
|
||||||
* @param {State} state
|
|
||||||
* @return {String} - The parsed/escaped where condition
|
|
||||||
*/
|
|
||||||
parseWhere(driver, state) {
|
|
||||||
let whereMap = state.whereMap;
|
|
||||||
let whereValues = state.rawWhereValues;
|
|
||||||
|
|
||||||
let outputMap = [];
|
|
||||||
let outputValues = [];
|
|
||||||
|
|
||||||
Object.keys(whereMap).forEach((key) => {
|
|
||||||
// Combine fields, operators, functions and values into a full clause
|
|
||||||
// to have a common starting flow
|
|
||||||
let fullClause = '';
|
|
||||||
|
|
||||||
// Add an explicit = sign where one is inferred
|
|
||||||
if ( ! this.hasOperator(key))
|
|
||||||
{
|
|
||||||
fullClause = key + ' = ' + whereMap[key];
|
|
||||||
}
|
|
||||||
else if (whereMap[key] === key)
|
|
||||||
{
|
|
||||||
fullClause = key;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fullClause = key + ' ' + whereMap[key];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Separate the clause into separate pieces
|
|
||||||
let parts = this.parseJoin(fullClause);
|
|
||||||
|
|
||||||
// Filter explicit literals from lists of matches
|
|
||||||
if (whereValues.indexOf(whereMap[key]) !== -1)
|
|
||||||
{
|
|
||||||
let value = whereMap[key];
|
|
||||||
let identIndex = (helpers.isArray(parts.identifiers)) ? parts.identifiers.indexOf(value) : -1;
|
|
||||||
let litIndex = (helpers.isArray(parts.literals)) ? parts.literals.indexOf(value) : -1;
|
|
||||||
let combIndex = (helpers.isArray(parts.combined)) ? parts.combined.indexOf(value) : -1;
|
|
||||||
let funcIndex = (helpers.isArray(parts.functions)) ? parts.functions.indexOf(value) : -1;
|
|
||||||
let inOutputArray = outputValues.indexOf(value) !== -1;
|
|
||||||
|
|
||||||
// Remove the identifier in question,
|
|
||||||
// and add to the output values array
|
|
||||||
if (identIndex !== -1)
|
|
||||||
{
|
|
||||||
parts.identifiers.splice(identIndex, 1);
|
|
||||||
|
|
||||||
if ( ! inOutputArray)
|
|
||||||
{
|
|
||||||
outputValues.push(value);
|
|
||||||
inOutputArray = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove the value from the literals list
|
|
||||||
// so it is not added twice
|
|
||||||
if (litIndex !== -1)
|
|
||||||
{
|
|
||||||
parts.literals.splice(litIndex, 1);
|
|
||||||
|
|
||||||
if ( ! inOutputArray)
|
|
||||||
{
|
|
||||||
outputValues.push(value);
|
|
||||||
inOutputArray = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove the value from the combined list
|
|
||||||
// and replace it with a placeholder
|
|
||||||
if (combIndex !== -1)
|
|
||||||
{
|
|
||||||
// Make sure to skip functions when replacing values
|
|
||||||
if (funcIndex === -1)
|
|
||||||
{
|
|
||||||
parts.combined[combIndex] = '?';
|
|
||||||
|
|
||||||
if ( ! inOutputArray)
|
|
||||||
{
|
|
||||||
outputValues.push(value);
|
|
||||||
inOutputArray = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Filter false positive identifiers
|
|
||||||
parts.identifiers = parts.identifiers || [];
|
|
||||||
parts.identifiers = parts.identifiers.filter((item) => {
|
|
||||||
let isInCombinedMatches = parts.combined.indexOf(item) !== -1;
|
|
||||||
let isNotInBlackList = this.identifierBlacklist.indexOf(item.toLowerCase()) === -1;
|
|
||||||
|
|
||||||
return isInCombinedMatches && isNotInBlackList;
|
|
||||||
}, this);
|
|
||||||
|
|
||||||
// Quote identifiers
|
|
||||||
if (helpers.isArray(parts.identifiers))
|
|
||||||
{
|
|
||||||
parts.identifiers.forEach((ident) => {
|
|
||||||
let index = parts.combined.indexOf(ident);
|
|
||||||
if (index !== -1)
|
|
||||||
{
|
|
||||||
parts.combined[index] = driver.quoteIdentifiers(ident);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Replace each literal with a placeholder in the map
|
|
||||||
// and add the literal to the values,
|
|
||||||
// This should only apply to literal values that are not
|
|
||||||
// explicitly mapped to values, but have to be parsed from
|
|
||||||
// a where condition,
|
|
||||||
if (helpers.isArray(parts.literals))
|
|
||||||
{
|
|
||||||
parts.literals.forEach((lit) => {
|
|
||||||
let litIndex = parts.combined.indexOf(lit);
|
|
||||||
|
|
||||||
if (litIndex !== -1)
|
|
||||||
{
|
|
||||||
parts.combined[litIndex] = (helpers.isArray(parts.operators)) ? '?' : '= ?';
|
|
||||||
outputValues.push(lit);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
outputMap.push(parts.combined.join(' '));
|
|
||||||
});
|
|
||||||
|
|
||||||
state.rawWhereValues = [];
|
|
||||||
state.whereValues = state.whereValues.concat(outputValues);
|
|
||||||
state.whereMap = outputMap;
|
|
||||||
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
}
|
|
29
src/State.js
29
src/State.js
@ -1,29 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
/** @module State */
|
|
||||||
module.exports = class State {
|
|
||||||
constructor() {
|
|
||||||
// Arrays/maps
|
|
||||||
this.queryMap = [];
|
|
||||||
this.values = [];
|
|
||||||
this.whereValues = [];
|
|
||||||
this.setArrayKeys = [];
|
|
||||||
this.orderArray = [];
|
|
||||||
this.groupArray = [];
|
|
||||||
this.havingMap = [];
|
|
||||||
this.whereMap = [];
|
|
||||||
this.rawWhereValues = [];
|
|
||||||
|
|
||||||
// Partials
|
|
||||||
this.selectString = '';
|
|
||||||
this.fromString = '';
|
|
||||||
this.setString = '';
|
|
||||||
this.orderString = '';
|
|
||||||
this.groupString = '';
|
|
||||||
|
|
||||||
// Other various values
|
|
||||||
this.limit = null;
|
|
||||||
this.offset = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// End of module State
|
|
@ -1,20 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
import Adapter from '../Adapter';
|
|
||||||
import getArgs from 'getargs';
|
|
||||||
|
|
||||||
/** @module adapters/dblite */
|
|
||||||
module.exports = class dblite extends Adapter {
|
|
||||||
/**
|
|
||||||
* Run the sql query as a prepared statement
|
|
||||||
*
|
|
||||||
* @param {String} sql - The sql with placeholders
|
|
||||||
* @param {Array} params - The values to insert into the query
|
|
||||||
* @param {Function} callback - Callback to run when a response is recieved
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
execute(/*sql, params, callback*/) {
|
|
||||||
let args = getArgs('sql:string, [params]:array, callback:function', arguments);
|
|
||||||
this.instance.query(args.sql, args.params, args.callback);
|
|
||||||
};
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
import Adapter from '../Adapter';
|
|
||||||
|
|
||||||
/** @module adapters/mysql */
|
|
||||||
module.exports = class mysql extends Adapter {
|
|
||||||
/**
|
|
||||||
* Run the sql query as a prepared statement
|
|
||||||
*
|
|
||||||
* @param {String} sql - The sql with placeholders
|
|
||||||
* @param {Array} params - The values to insert into the query
|
|
||||||
* @param {Function} callback - Callback to run when a response is recieved
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
execute(sql, params, callback) {
|
|
||||||
this.instance.query.apply(instance, arguments);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
import Adapter from '../Adapter';
|
|
||||||
|
|
||||||
/** @module adapters/mysql2 */
|
|
||||||
module.exports = class mysql2 extends Adapter {
|
|
||||||
/**
|
|
||||||
* Run the sql query as a prepared statement
|
|
||||||
*
|
|
||||||
* @param {String} sql - The sql with placeholders
|
|
||||||
* @param {Array} params - The values to insert into the query
|
|
||||||
* @param {Function} callback - Callback to run when a response is recieved
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
execute(sql, params, callback) {
|
|
||||||
this.instance.execute.apply(this.instance, arguments);
|
|
||||||
};
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
import Adapter from '../Adapter';
|
|
||||||
import getArgs from 'getargs';
|
|
||||||
|
|
||||||
/** @module adapters/node-firebird */
|
|
||||||
module.exports = class nodefirebird extends Adapter {
|
|
||||||
/**
|
|
||||||
* Run the sql query as a prepared statement
|
|
||||||
*
|
|
||||||
* @param {String} sql - The sql with placeholders
|
|
||||||
* @param {Array} params - The values to insert into the query
|
|
||||||
* @param {Function} callback - Callback to run when a response is recieved
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
execute(/*sql, params, callback*/) {
|
|
||||||
let args = getArgs('sql:string, [params], callback:function', arguments);
|
|
||||||
this.instance.execute(args.sql, args.params, args.callback);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
import Adapter from '../Adapter';
|
|
||||||
import getArgs from 'getargs';
|
|
||||||
|
|
||||||
/** @module adapters/pg */
|
|
||||||
module.exports = class pg extends Adapter {
|
|
||||||
/**
|
|
||||||
* Run the sql query as a prepared statement
|
|
||||||
*
|
|
||||||
* @param {String} sql - The sql with placeholders
|
|
||||||
* @param {Array} params - The values to insert into the query
|
|
||||||
* @param {Function} callback - Callback to run when a response is recieved
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
execute(/*sql, params, callback*/) {
|
|
||||||
let args = getArgs('sql:string, [params]:array, callback:function', arguments);
|
|
||||||
|
|
||||||
// Replace question marks with numbered placeholders, because this adapter is different...
|
|
||||||
let count = 0;
|
|
||||||
args.sql = args.sql.replace(/\?/g, () => {
|
|
||||||
count++;
|
|
||||||
return '$' + count;
|
|
||||||
});
|
|
||||||
|
|
||||||
this.instance.query(args.sql, args.params, args.callback);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,49 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
import helpers from '../helpers';
|
|
||||||
import Driver from '../DriverClass';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Driver for Firebird databases
|
|
||||||
*
|
|
||||||
* @module drivers/firebird
|
|
||||||
*/
|
|
||||||
class Firebird extends Driver {
|
|
||||||
constructor() {
|
|
||||||
super({
|
|
||||||
hasTruncate: false
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generate a limit clause for firebird, which uses the syntax closest to the SQL standard
|
|
||||||
*
|
|
||||||
* @param {String} sql
|
|
||||||
* @param {Number} limit
|
|
||||||
* @param {Number} offset
|
|
||||||
* @return {String}
|
|
||||||
*/
|
|
||||||
limit(origSql, limit, offset) {
|
|
||||||
let sql = `FIRST ${limit}`;
|
|
||||||
|
|
||||||
if (helpers.isNumber(offset))
|
|
||||||
{
|
|
||||||
sql += ` SKIP ${offset}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return origSql.replace(/SELECT/i, "SELECT " + sql);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SQL to insert a group of rows
|
|
||||||
*
|
|
||||||
* @param {String} table - The table to insert to
|
|
||||||
* @param {Array} [data] - The array of object containing data to insert
|
|
||||||
* @return {String}
|
|
||||||
*/
|
|
||||||
insertBatch() {
|
|
||||||
throw new Error("Not Implemented");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = new Firebird();
|
|
@ -1,29 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
import helpers from '../helpers';
|
|
||||||
import Driver from '../DriverClass';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Driver for MySQL databases
|
|
||||||
*
|
|
||||||
* @module drivers/mysql
|
|
||||||
*/
|
|
||||||
class Mysql extends Driver {
|
|
||||||
constructor() {
|
|
||||||
super({
|
|
||||||
identifierStartChar: '`',
|
|
||||||
identifierEndChar: '`'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
limit(sql, limit, offset) {
|
|
||||||
if ( ! helpers.isNumber(offset))
|
|
||||||
{
|
|
||||||
return sql += ` LIMIT ${limit}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return sql += ` LIMIT ${offset}, ${limit}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = new Mysql();
|
|
@ -1,10 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
import Driver from '../DriverClass';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Driver for PostgreSQL databases
|
|
||||||
*
|
|
||||||
* @module drivers/pg
|
|
||||||
*/
|
|
||||||
module.exports = new Driver();
|
|
@ -1,64 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
import helpers from '../helpers';
|
|
||||||
import Driver from '../DriverClass';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Driver for Sqlite databases
|
|
||||||
*
|
|
||||||
* @module drivers/sqlite
|
|
||||||
*/
|
|
||||||
class Sqlite extends Driver {
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
this.hasTruncate = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
insertBatch(table, data) {
|
|
||||||
|
|
||||||
// Get the data values to insert, so they can
|
|
||||||
// be parameterized
|
|
||||||
let sql = "",
|
|
||||||
vals = [],
|
|
||||||
cols = [],
|
|
||||||
fields = [],
|
|
||||||
first = data.shift(),
|
|
||||||
params = [],
|
|
||||||
paramString = "",
|
|
||||||
paramList = [];
|
|
||||||
|
|
||||||
|
|
||||||
data.forEach((obj) => {
|
|
||||||
let row = [];
|
|
||||||
Object.keys(obj).forEach((key) => {
|
|
||||||
row.push(obj[key]);
|
|
||||||
});
|
|
||||||
vals.push(row);
|
|
||||||
});
|
|
||||||
|
|
||||||
sql += "INSERT INTO " + this.quoteTable(table) + "\n";
|
|
||||||
|
|
||||||
// Get the field names from the keys of the first
|
|
||||||
// object to be inserted
|
|
||||||
fields = Object.keys(first);
|
|
||||||
Object.keys(first).forEach((key) => {
|
|
||||||
cols.push("'" + this._quote(first[key]) + "' AS " + this.quoteIdentifiers(key));
|
|
||||||
});
|
|
||||||
|
|
||||||
sql += "SELECT " + cols.join(', ') + "\n";
|
|
||||||
|
|
||||||
vals.forEach((row_values) => {
|
|
||||||
let quoted = row_values.map((value) => {
|
|
||||||
return String(value).replace("'", "'\'");
|
|
||||||
});
|
|
||||||
sql += "UNION ALL SELECT '" + quoted.join("', '") + "'\n";
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
|
||||||
sql: sql,
|
|
||||||
values: null
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = new Sqlite();
|
|
127
src/helpers.js
127
src/helpers.js
@ -1,127 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
//require('es6-shim');
|
|
||||||
|
|
||||||
let helpers = {
|
|
||||||
/**
|
|
||||||
* Wrap String.prototype.trim in a way that is easily mappable
|
|
||||||
*
|
|
||||||
* @param {String} str - The string to trim
|
|
||||||
* @return {String} - The trimmed string
|
|
||||||
*/
|
|
||||||
stringTrim: (str) => str.trim(),
|
|
||||||
/**
|
|
||||||
* Get the type of the variable passed
|
|
||||||
*
|
|
||||||
* @see https://techblog.badoo.com/blog/2013/11/01/type-checking-in-javascript/
|
|
||||||
* @see http://toddmotto.com/understanding-javascript-types-and-reliable-type-checking/
|
|
||||||
* @param {mixed} o
|
|
||||||
* @return {String}
|
|
||||||
*/
|
|
||||||
type: (o) => {
|
|
||||||
let type = Object.prototype.toString.call(o).slice(8, -1).toLowerCase();
|
|
||||||
|
|
||||||
// handle NaN and Infinity
|
|
||||||
if (type === 'number') {
|
|
||||||
if (isNaN(o)) {
|
|
||||||
return 'nan';
|
|
||||||
}
|
|
||||||
if (!isFinite(o)) {
|
|
||||||
return 'infinity';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return type;
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Determine whether an object is scalar
|
|
||||||
*
|
|
||||||
* @param {mixed} obj
|
|
||||||
* @return {bool}
|
|
||||||
*/
|
|
||||||
isScalar: (obj) => {
|
|
||||||
let scalar = ['string', 'number', 'boolean'];
|
|
||||||
return scalar.indexOf(helpers.type(obj)) !== -1;
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Get a list of values with a common key from an array of objects
|
|
||||||
*
|
|
||||||
* @param {Array} arr - The array of objects to search
|
|
||||||
* @param {String} key - The key of the object to get
|
|
||||||
* @return {Array}
|
|
||||||
*/
|
|
||||||
arrayPluck: (arr, key) => {
|
|
||||||
let output = [];
|
|
||||||
|
|
||||||
// Empty case
|
|
||||||
if (arr.length === 0) return output;
|
|
||||||
|
|
||||||
arr.forEach((obj) => {
|
|
||||||
if ( ! helpers.isUndefined(obj[key]))
|
|
||||||
{
|
|
||||||
output.push(obj[key]);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return output;
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Determine if a value matching the passed regular expression is
|
|
||||||
* in the passed array
|
|
||||||
*
|
|
||||||
* @param {Array} arr - The array to search
|
|
||||||
* @param {RegExp} pattern - The pattern to match
|
|
||||||
* @return {Boolean} - If an array item matches the pattern
|
|
||||||
*/
|
|
||||||
regexInArray: (arr, pattern) => {
|
|
||||||
// Empty case(s)
|
|
||||||
if ( ! helpers.isArray(arr)) return false;
|
|
||||||
if (arr.length === 0) return false;
|
|
||||||
|
|
||||||
let i, l = arr.length;
|
|
||||||
|
|
||||||
for(i=0; i< l; i++)
|
|
||||||
{
|
|
||||||
// Short circuit if any items match
|
|
||||||
if (pattern.test(arr[i])) return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Make the first letter of the string uppercase
|
|
||||||
*
|
|
||||||
* @param {String} str
|
|
||||||
* @return {String}
|
|
||||||
*/
|
|
||||||
upperCaseFirst: (str) => {
|
|
||||||
str += '';
|
|
||||||
let first = str.charAt(0).toUpperCase();
|
|
||||||
return first + str.substr(1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Define an 'is' method for each type
|
|
||||||
let types = ['Null','Undefined','Object','Array','String','Number','Boolean','Function','RegExp','NaN','Infinite'];
|
|
||||||
types.forEach((t) => {
|
|
||||||
/**
|
|
||||||
* Determine whether a variable is of the type specified in the
|
|
||||||
* function name, eg isNumber
|
|
||||||
*
|
|
||||||
* Types available are Null, Undefined, Object, Array, String, Number, Boolean, Function, RegExp, NaN and Infinite
|
|
||||||
*
|
|
||||||
* @name is[type]
|
|
||||||
* @param {mixed} o
|
|
||||||
* @return {Boolean}
|
|
||||||
*/
|
|
||||||
helpers['is' + t] = function (o) {
|
|
||||||
if (t.toLowerCase() === 'infinite')
|
|
||||||
{
|
|
||||||
t = 'infinity';
|
|
||||||
}
|
|
||||||
|
|
||||||
return helpers.type(o) === t.toLowerCase();
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
module.exports = helpers;
|
|
Binary file not shown.
39
test/base_test.js
Normal file
39
test/base_test.js
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
let assert = require('chai').assert;
|
||||||
|
let nodeQuery = require('../lib/NodeQuery');
|
||||||
|
|
||||||
|
suite('Base tests', () => {
|
||||||
|
test('Sanity check', () => {
|
||||||
|
let modules = {
|
||||||
|
helpers: require('../lib/helpers'),
|
||||||
|
driver: require('../lib/DriverBase'),
|
||||||
|
qb: require('../lib/QueryBuilder'),
|
||||||
|
'node-query': require('../lib/NodeQuery'),
|
||||||
|
'state': require('../lib/State'),
|
||||||
|
'drivers/pg': require('../lib/drivers/Pg'),
|
||||||
|
'drivers/mysql': require('../lib/drivers/Mysql'),
|
||||||
|
'drivers/sqlite': require('../lib/drivers/Sqlite'),
|
||||||
|
'adapters/mysql': require('../lib/adapters/mysql'),
|
||||||
|
'adapters/mysql2': require('../lib/adapters/mysql2'),
|
||||||
|
'adapters/pg': require('../lib/adapters/pg'),
|
||||||
|
'adapters/dblite': require('../lib/adapters/dblite')
|
||||||
|
};
|
||||||
|
|
||||||
|
Object.keys(modules).forEach(mod => {
|
||||||
|
assert.ok(modules[mod], mod + " module is sane");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('NodeQuery.getQuery with no instance', () => {
|
||||||
|
assert.throws(() => {
|
||||||
|
nodeQuery.getQuery();
|
||||||
|
}, Error, "No Query Builder instance to return");
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Invalid driver type', () => {
|
||||||
|
assert.throws(() => {
|
||||||
|
nodeQuery.init('foo', {}, 'bar');
|
||||||
|
}, Error, "Selected driver (Foo) does not exist!");
|
||||||
|
});
|
||||||
|
});
|
136
test/helpers_test.js
Normal file
136
test/helpers_test.js
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
let chai = require('chai'),
|
||||||
|
assert = chai.assert,
|
||||||
|
expect = chai.expect,
|
||||||
|
should = chai.should();
|
||||||
|
|
||||||
|
let helpers = require('../lib/helpers');
|
||||||
|
|
||||||
|
suite('Helper Module Tests', () => {
|
||||||
|
suite('Type-checking methods', () => {
|
||||||
|
suite('Object wrappers are listed as their native type', () => {
|
||||||
|
test("Boolean Wrapper returns 'boolean' not 'object'", () => {
|
||||||
|
let item = Boolean(true);
|
||||||
|
expect(helpers.type(item)).to.deep.equal('boolean');
|
||||||
|
});
|
||||||
|
test("Number Wrapper returns 'number' not 'object", () => {
|
||||||
|
let item = Number(4867);
|
||||||
|
expect(helpers.type(item)).to.deep.equal('number');
|
||||||
|
});
|
||||||
|
test("String Wrapper returns 'string' not 'object'", () => {
|
||||||
|
let item = String("Foo");
|
||||||
|
expect(helpers.type(item)).to.deep.equal('string');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
suite('is..Method methods exist', () => {
|
||||||
|
let types = ['Null','Undefined','Object','Array','String','Number','Boolean','Function','RegExp','NaN','Infinite'];
|
||||||
|
|
||||||
|
types.forEach(type => {
|
||||||
|
test(`is${type} method exists`, () => {
|
||||||
|
assert.ok(helpers[`is${type}`]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
suite('isScalar', () => {
|
||||||
|
let trueCases = {
|
||||||
|
'Strings are scalar': 'foo',
|
||||||
|
'Booleans are scalar': true,
|
||||||
|
'Numbers are scalar': 545
|
||||||
|
};
|
||||||
|
Object.keys(trueCases).forEach(desc => {
|
||||||
|
test(desc, () => {
|
||||||
|
expect(helpers.isScalar(trueCases[desc])).to.be.true;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
let falseCases = {
|
||||||
|
'Arrays are not scalar': [],
|
||||||
|
'Objects are not scalar': [],
|
||||||
|
};
|
||||||
|
Object.keys(falseCases).forEach(desc => {
|
||||||
|
test(desc, () => {
|
||||||
|
expect(helpers.isScalar(falseCases[desc])).to.be.false;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
suite('isInfinity', () => {
|
||||||
|
test('The type of 1/0 is infinity', () => {
|
||||||
|
expect(helpers.type(1/0)).to.equal('infinity');
|
||||||
|
});
|
||||||
|
test('isInfinity is the same as isInfinite', () => {
|
||||||
|
expect(helpers.isInfinite(1/0)).to.be.true;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
suite('isNaN', () => {
|
||||||
|
test('The type of 0 / 0 is NaN', () => {
|
||||||
|
expect(helpers.type(0 / 0)).to.equal('nan');
|
||||||
|
});
|
||||||
|
test('isNaN method agrees with type', () => {
|
||||||
|
expect(helpers.isNaN(0 / 0)).to.be.true;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
suite('Other helper methods', () => {
|
||||||
|
suite('stringTrim', () => {
|
||||||
|
test('stringTrim method works as expected', () => {
|
||||||
|
let orig = [' x y ', 'z ', ' q'];
|
||||||
|
let ret = ['x y', 'z', 'q'];
|
||||||
|
|
||||||
|
expect(orig.map(helpers.stringTrim)).to.be.deep.equal(ret);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
suite('arrayPluck', () => {
|
||||||
|
let orig = [{
|
||||||
|
foo: 1
|
||||||
|
},{
|
||||||
|
foo: 2,
|
||||||
|
bar: 10
|
||||||
|
},{
|
||||||
|
foo: 3,
|
||||||
|
bar: 15
|
||||||
|
}];
|
||||||
|
|
||||||
|
test('Finding members in all objects', () => {
|
||||||
|
expect(helpers.arrayPluck(orig, 'foo')).to.be.deep.equal([1,2,3]);
|
||||||
|
});
|
||||||
|
test('Some members are missing in some objects', () => {
|
||||||
|
expect(helpers.arrayPluck(orig, 'bar')).to.be.deep.equal([10, 15]);
|
||||||
|
});
|
||||||
|
test('Empty case', () => {
|
||||||
|
expect(helpers.arrayPluck([], 'apple')).to.be.deep.equal([]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
suite('regexInArray', () => {
|
||||||
|
let orig = ['apple', ' string ', 6, 4, 7];
|
||||||
|
|
||||||
|
let cases = [{
|
||||||
|
'Dollar sign is not in any of the array items': /\$/,
|
||||||
|
'None of the numbers in the array match /5/': /5/
|
||||||
|
},{
|
||||||
|
"' string ' matches /^ ?string/": /^ ?string/,
|
||||||
|
"'apple' matches /APPLE/i": /APPLE/i
|
||||||
|
}];
|
||||||
|
|
||||||
|
[0, 1].forEach(i => {
|
||||||
|
let boolCase = cases[i];
|
||||||
|
Object.keys(boolCase).forEach(desc => {
|
||||||
|
test(desc, () => {
|
||||||
|
if (i) {
|
||||||
|
expect(helpers.regexInArray(orig, boolCase[desc])).to.be.true;
|
||||||
|
} else {
|
||||||
|
expect(helpers.regexInArray(orig, boolCase[desc])).to.be.false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('First argument is not an array', () => {
|
||||||
|
expect(helpers.regexInArray(5, /5/)).to.be.false;
|
||||||
|
});
|
||||||
|
test('Array is empty', () => {
|
||||||
|
expect(helpers.regexInArray([], /.*/)).to.be.false;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
178
test/query-parser_test.js
Normal file
178
test/query-parser_test.js
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
let expect = require('chai').expect;
|
||||||
|
|
||||||
|
// Use the base driver as a mock for testing
|
||||||
|
let getArgs = require('getargs');
|
||||||
|
let helpers = require('../lib/helpers');
|
||||||
|
let driver = require('../lib/DriverBase');
|
||||||
|
|
||||||
|
let p = require('../lib/QueryParser');
|
||||||
|
let parser = new p(driver);
|
||||||
|
|
||||||
|
let State = require('../lib/State');
|
||||||
|
|
||||||
|
// Simulate query builder state
|
||||||
|
let state = new State();
|
||||||
|
|
||||||
|
let mixedSet = function mixedSet(/* $letName, $valType, $key, [$val] */) {
|
||||||
|
let args = getArgs('$letName:string, $valType:string, $key:object|string|number, [$val]', arguments);
|
||||||
|
|
||||||
|
let obj = {};
|
||||||
|
|
||||||
|
if (helpers.isScalar(args.$key) && !helpers.isUndefined(args.$val))
|
||||||
|
{
|
||||||
|
// Convert key/val pair to a simple object
|
||||||
|
obj[args.$key] = args.$val;
|
||||||
|
}
|
||||||
|
else if (helpers.isScalar(args.$key) && helpers.isUndefined(args.$val))
|
||||||
|
{
|
||||||
|
// If just a string for the key, and no value, create a simple object with duplicate key/val
|
||||||
|
obj[args.$key] = args.$key;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
obj = args.$key;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.keys(obj).forEach(k => {
|
||||||
|
// If a single value for the return
|
||||||
|
if (['key','value'].indexOf(args.$valType) !== -1)
|
||||||
|
{
|
||||||
|
let pushVal = (args.$valType === 'key') ? k : obj[k];
|
||||||
|
state[args.$letName].push(pushVal);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
state[args.$letName][k] = obj[k];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
return state[args.$letName];
|
||||||
|
}
|
||||||
|
|
||||||
|
let whereMock = function() {
|
||||||
|
let args = getArgs('key:string|object, [val]', arguments);
|
||||||
|
|
||||||
|
state.whereMap = [];
|
||||||
|
state.whereValues = [];
|
||||||
|
|
||||||
|
mixedSet('rawWhereValues', 'value', args.key, args.val);
|
||||||
|
mixedSet('whereMap', 'both', args.key, args.val);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// ! Start Tests
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
suite('Query Parser Tests', () => {
|
||||||
|
suite('Has operator tests', () => {
|
||||||
|
test('Has operator', () => {
|
||||||
|
let matches = parser.hasOperator('foo <> 2');
|
||||||
|
expect(matches).to.be.deep.equal(['<>']);
|
||||||
|
});
|
||||||
|
test('Has no operator', () => {
|
||||||
|
let matches = parser.hasOperator('foo');
|
||||||
|
expect(matches).to.be.null;
|
||||||
|
})
|
||||||
|
});
|
||||||
|
suite('Where parser tests', () => {
|
||||||
|
setup(() => {
|
||||||
|
state = new State();
|
||||||
|
});
|
||||||
|
test('Has function full string', () => {
|
||||||
|
whereMock('time < SUM(FOO(BAR()))');
|
||||||
|
parser.parseWhere(driver, state);
|
||||||
|
expect(state.whereMap)
|
||||||
|
.to.be.deep.equal(['"time" < SUM(FOO(BAR()))']);
|
||||||
|
});
|
||||||
|
test('Has function key/val', () => {
|
||||||
|
whereMock('time <', 'SUM(FOO(BAR()))');
|
||||||
|
parser.parseWhere(driver, state);
|
||||||
|
expect(state.whereMap)
|
||||||
|
.to.be.deep.equal(['"time" < SUM(FOO(BAR()))']);
|
||||||
|
});
|
||||||
|
test('Has function key/val object', () => {
|
||||||
|
whereMock({
|
||||||
|
'time <': "SUM(FOO(BAR('x')))"
|
||||||
|
});
|
||||||
|
parser.parseWhere(driver, state);
|
||||||
|
expect(state.whereMap)
|
||||||
|
.to.be.deep.equal(['"time" < SUM(FOO(BAR(\'x\')))']);
|
||||||
|
});
|
||||||
|
test('Has literal value', () => {
|
||||||
|
whereMock({
|
||||||
|
'foo': 3
|
||||||
|
});
|
||||||
|
parser.parseWhere(driver, state);
|
||||||
|
expect(state.whereMap)
|
||||||
|
.to.be.deep.equal(['"foo" = ?']);
|
||||||
|
expect(state.whereValues)
|
||||||
|
.to.be.deep.equal(['3']);
|
||||||
|
});
|
||||||
|
test('Has multiple literal values', () => {
|
||||||
|
whereMock({
|
||||||
|
foo: 3,
|
||||||
|
bar: 5
|
||||||
|
});
|
||||||
|
parser.parseWhere(driver, state);
|
||||||
|
expect(state.whereMap)
|
||||||
|
.to.be.deep.equal(['"foo" = ?', '"bar" = ?']);
|
||||||
|
expect(state.whereValues)
|
||||||
|
.to.be.deep.equal(['3','5']);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
suite('Parse join tests', () => {
|
||||||
|
let data = [{
|
||||||
|
desc: 'Simple equals condition',
|
||||||
|
join: 'table1.field1=table2.field2',
|
||||||
|
expected: ['table1.field1','=','table2.field2']
|
||||||
|
},{
|
||||||
|
desc: 'Db.table.field condition',
|
||||||
|
join: 'db1.table1.field1!=db2.table2.field2',
|
||||||
|
expected: ['db1.table1.field1','!=', 'db2.table2.field2']
|
||||||
|
},{
|
||||||
|
desc: 'Underscore in identifier',
|
||||||
|
join: 'table_1.field1 = tab_le2.field_2',
|
||||||
|
expected: ['table_1.field1', '=', 'tab_le2.field_2']
|
||||||
|
},{
|
||||||
|
desc: 'Function in condition',
|
||||||
|
join: 'table1.field1 > SUM(3+6)',
|
||||||
|
expected: ['table1.field1', '>', 'SUM(3+6)']
|
||||||
|
}];
|
||||||
|
|
||||||
|
data.forEach(datum => {
|
||||||
|
test(datum.desc, () => {
|
||||||
|
let matches = parser.parseJoin(datum.join);
|
||||||
|
expect(matches.combined).to.be.deep.equal(datum.expected);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
});
|
||||||
|
suite('Compile join tests', () => {
|
||||||
|
let data = [{
|
||||||
|
desc: 'Simple equals condition',
|
||||||
|
clause: 'table1.field1=table2.field2',
|
||||||
|
expected: '"table1"."field1" = "table2"."field2"'
|
||||||
|
},{
|
||||||
|
desc: 'Db.table.field condition',
|
||||||
|
clause: 'db1.table1.field1!=db2.table2.field2',
|
||||||
|
expected: '"db1"."table1"."field1" != "db2"."table2"."field2"'
|
||||||
|
},{
|
||||||
|
desc: 'Underscore in identifier',
|
||||||
|
clause: 'table_1.field1 = tab_le2.field_2',
|
||||||
|
expected: '"table_1"."field1" = "tab_le2"."field_2"'
|
||||||
|
},{
|
||||||
|
desc: 'Function in condition',
|
||||||
|
clause: 'table1.field1 > SUM(3+6)',
|
||||||
|
expected: '"table1"."field1" > SUM(3+6)'
|
||||||
|
}];
|
||||||
|
|
||||||
|
data.forEach(datum => {
|
||||||
|
test(datum.desc, () => {
|
||||||
|
let join = parser.compileJoin(datum.clause);
|
||||||
|
expect(join).to.be.deep.equal(datum.expected);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
@ -1,91 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
// Load the test base
|
|
||||||
delete require.cache[require.resolve('../query-builder-base')];
|
|
||||||
var testBase = require('../query-builder-base');
|
|
||||||
var tests = testBase.tests;
|
|
||||||
|
|
||||||
// Load the test config file
|
|
||||||
var adapterName = 'dblite';
|
|
||||||
var sqlite = null;
|
|
||||||
var connection = null;
|
|
||||||
|
|
||||||
// Set up the connection
|
|
||||||
try {
|
|
||||||
sqlite = require(adapterName).withSQLite('3.7.11');
|
|
||||||
connection = sqlite(':memory:');
|
|
||||||
} catch (e) {
|
|
||||||
// Export an empty testsuite if module not loaded
|
|
||||||
console.log(e);
|
|
||||||
console.log("Database adapter dblite not found");
|
|
||||||
//return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (connection)
|
|
||||||
{
|
|
||||||
// Set up the query builder object
|
|
||||||
var nodeQuery = require('../../lib/NodeQuery');
|
|
||||||
var qb = nodeQuery.init('sqlite', connection, adapterName);
|
|
||||||
|
|
||||||
// Set up the sqlite database
|
|
||||||
var sql = 'CREATE TABLE IF NOT EXISTS "create_test" ("id" INTEGER PRIMARY KEY, "key" TEXT, "val" TEXT);' +
|
|
||||||
'CREATE TABLE IF NOT EXISTS "create_join" ("id" INTEGER PRIMARY KEY, "key" TEXT, "val" TEXT);';
|
|
||||||
connection.query(sql);
|
|
||||||
|
|
||||||
// Set up the test base
|
|
||||||
testBase._setUp(qb, function(test, err, rows) {
|
|
||||||
if (err != null) {
|
|
||||||
test.done();
|
|
||||||
throw new Error(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Insert/Update/Delete queries return undefined
|
|
||||||
if (rows === undefined) {
|
|
||||||
rows = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
test.ok(rows, 'dblite: Invalid result for generated query');
|
|
||||||
test.done();
|
|
||||||
});
|
|
||||||
|
|
||||||
tests['nodeQuery.getQuery = nodeQuery.init'] = function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
test.deepEqual(qb, nodeQuery.getQuery(), "getQuery returns same object");
|
|
||||||
test.done();
|
|
||||||
};
|
|
||||||
|
|
||||||
tests['Select tests']['Select with function and argument in WHERE clause'] = function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
qb.select('id')
|
|
||||||
.from('create_test')
|
|
||||||
.where('id', 'ABS(-88)')
|
|
||||||
.get(function(err, rows) {
|
|
||||||
if (err != null) {
|
|
||||||
test.done();
|
|
||||||
throw new Error(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
test.ok(rows, 'dblite: Valid result for generated query');
|
|
||||||
test.done();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
tests["dblite adapter with query builder"] = function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
test.ok(testBase.qb);
|
|
||||||
|
|
||||||
// Close the db connection
|
|
||||||
connection.close();
|
|
||||||
test.done();
|
|
||||||
};
|
|
||||||
|
|
||||||
// Export the final test object
|
|
||||||
module.exports = tests;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
module.exports = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,51 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
var configFile = (process.env.CI) ? '../config-travis.json' : '../config.json';
|
|
||||||
|
|
||||||
// Load a fresh version of the test base
|
|
||||||
delete require.cache[require.resolve('../query-builder-base')];
|
|
||||||
var testBase = require('../query-builder-base');
|
|
||||||
var tests = testBase.tests;
|
|
||||||
|
|
||||||
// Load the test config file
|
|
||||||
var adapterName = 'mysql2';
|
|
||||||
var config = require(configFile)[adapterName];
|
|
||||||
|
|
||||||
// Set up the connection
|
|
||||||
var mysql2 = require(adapterName);
|
|
||||||
var connection = mysql2.createConnection(config.conn);
|
|
||||||
|
|
||||||
// Set up the query builder object
|
|
||||||
var nodeQuery = require('../../lib/NodeQuery');
|
|
||||||
var qb = nodeQuery.init('mysql', connection, adapterName);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
tests['nodeQuery.getQuery = nodeQuery.init'] = function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
test.deepEqual(qb, nodeQuery.getQuery(), "getQuery returns same object");
|
|
||||||
test.done();
|
|
||||||
};
|
|
||||||
|
|
||||||
// Export the final test object
|
|
||||||
tests["mysql2 adapter with query builder"] = function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
test.ok(testBase.qb);
|
|
||||||
|
|
||||||
// Close the db connection
|
|
||||||
connection.end();
|
|
||||||
test.done();
|
|
||||||
};
|
|
||||||
|
|
||||||
// Set up the test base
|
|
||||||
testBase._setUp(qb, function(test, err, rows) {
|
|
||||||
if (err != null) {
|
|
||||||
test.done();
|
|
||||||
throw new Error(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
test.ok(rows, 'mysql2: Invalid result for generated query');
|
|
||||||
test.done();
|
|
||||||
});
|
|
||||||
|
|
||||||
module.exports = tests;
|
|
@ -1,51 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
var configFile = (process.env.CI) ? '../config-travis.json' : '../config.json';
|
|
||||||
|
|
||||||
// Load the test base
|
|
||||||
delete require.cache[require.resolve('../query-builder-base')];
|
|
||||||
var testBase = require('../query-builder-base');
|
|
||||||
var tests = testBase.tests;
|
|
||||||
|
|
||||||
// Load the test config file
|
|
||||||
var adapterName = 'mysql';
|
|
||||||
var config = require(configFile)[adapterName];
|
|
||||||
|
|
||||||
// Set up the connection
|
|
||||||
var mysql = require(adapterName);
|
|
||||||
var connection = mysql.createConnection(config.conn);
|
|
||||||
|
|
||||||
// Set up the query builder object
|
|
||||||
var nodeQuery = require('../../lib/NodeQuery');
|
|
||||||
var qb = nodeQuery.init('mysql', connection);
|
|
||||||
|
|
||||||
// Set up the test base
|
|
||||||
testBase._setUp(qb, function(test, err, rows) {
|
|
||||||
if (err != null) {
|
|
||||||
test.done();
|
|
||||||
throw new Error(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
test.ok(rows, 'mysql: Valid result for generated query');
|
|
||||||
test.done();
|
|
||||||
});
|
|
||||||
|
|
||||||
tests['nodeQuery.getQuery = nodeQuery.init'] = function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
test.deepEqual(qb, nodeQuery.getQuery(), "getQuery returns same object");
|
|
||||||
test.done();
|
|
||||||
};
|
|
||||||
|
|
||||||
tests["mysql adapter with query builder"] = function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
test.ok(testBase.qb);
|
|
||||||
|
|
||||||
// Close the db connection
|
|
||||||
qb = null;
|
|
||||||
connection.destroy();
|
|
||||||
|
|
||||||
test.done();
|
|
||||||
};
|
|
||||||
|
|
||||||
// Export the final test object
|
|
||||||
module.exports = tests;
|
|
@ -1,96 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
// Load the test base
|
|
||||||
var testBase = require('../query-builder-base');
|
|
||||||
|
|
||||||
// Load the test config file
|
|
||||||
var adapterName = 'node-firebird';
|
|
||||||
var config = require('../config.json')[adapterName];
|
|
||||||
config.conn.database = __dirname + config.conn.database;
|
|
||||||
var nodeQuery = require('../../lib/NodeQuery');
|
|
||||||
|
|
||||||
// Skip on TravisCi
|
|
||||||
if (process.env.CI || process.env.JENKINS_HOME)
|
|
||||||
{
|
|
||||||
module.exports = {};
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set up the connection
|
|
||||||
try {
|
|
||||||
var Firebird = require(adapterName);
|
|
||||||
var conn = null;
|
|
||||||
var qb = null;
|
|
||||||
|
|
||||||
// Setup testbase from the inside out
|
|
||||||
// Because the connection is async, utilize
|
|
||||||
// the setUp function from nodeunit to get the connection
|
|
||||||
testBase.tests.setUp = function(cb) {
|
|
||||||
if ( ! conn)
|
|
||||||
{
|
|
||||||
// Connect to the database
|
|
||||||
Firebird.attach(config.conn, function(err, db) {
|
|
||||||
if (err) {
|
|
||||||
console.error(err);
|
|
||||||
}
|
|
||||||
conn = db;
|
|
||||||
|
|
||||||
// Set up the query builder object
|
|
||||||
qb = nodeQuery.init('firebird', db, adapterName);
|
|
||||||
|
|
||||||
testBase._setUp(qb, function(test, err, result) {
|
|
||||||
if (err) {
|
|
||||||
test.done();
|
|
||||||
throw new Error(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
result = result || [];
|
|
||||||
|
|
||||||
test.ok(result, 'firebird: Valid result for generated query');
|
|
||||||
test.done();
|
|
||||||
});
|
|
||||||
|
|
||||||
cb();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cb();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//delete testBase.tests['DB update tests'];
|
|
||||||
testBase.tests['DB update tests']['Test Insert Batch'] = function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
|
|
||||||
test.throws(function() {
|
|
||||||
qb.insertBatch({}, (function() {}));
|
|
||||||
}, Error, "Insert Batch not implemented for firebird");
|
|
||||||
|
|
||||||
test.done();
|
|
||||||
};
|
|
||||||
|
|
||||||
testBase.tests['nodeQuery.getQuery = nodeQuery.init'] = function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
test.deepEqual(qb, nodeQuery.getQuery(), "getQuery returns same object");
|
|
||||||
test.done();
|
|
||||||
};
|
|
||||||
|
|
||||||
testBase.tests["firebird adapter with query builder"] = function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
test.ok(testBase.qb);
|
|
||||||
|
|
||||||
// Disconnect from the db
|
|
||||||
conn.detach();
|
|
||||||
|
|
||||||
test.done();
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = testBase.tests;
|
|
||||||
|
|
||||||
} catch (e) {
|
|
||||||
// Export an empty testBase.testsuite if module not loaded
|
|
||||||
console.log(e);
|
|
||||||
console.log("Database adapter firebird not found");
|
|
||||||
module.exports = {};
|
|
||||||
}
|
|
@ -1,54 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
var configFile = (process.env.CI) ? '../config-travis.json' : '../config.json';
|
|
||||||
|
|
||||||
// Load the test base
|
|
||||||
delete require.cache[require.resolve('../query-builder-base')];
|
|
||||||
var testBase = require('../query-builder-base');
|
|
||||||
var tests = testBase.tests;
|
|
||||||
|
|
||||||
// Load the test config file
|
|
||||||
var adapterName = 'pg';
|
|
||||||
var config = require(configFile)[adapterName];
|
|
||||||
|
|
||||||
// Set up the connection
|
|
||||||
var pg = require(adapterName);
|
|
||||||
var connection = new pg.Client(config.conn);
|
|
||||||
connection.connect(function(err) {
|
|
||||||
if (err) {
|
|
||||||
throw new Error(err);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Set up the query builder object
|
|
||||||
var nodeQuery = require('../../lib/NodeQuery');
|
|
||||||
var qb = nodeQuery.init('pg', connection);
|
|
||||||
|
|
||||||
|
|
||||||
// Set up the test base
|
|
||||||
testBase._setUp(qb, function(test, err, result) {
|
|
||||||
if (err) {
|
|
||||||
console.error('SQL syntax error', err);
|
|
||||||
}
|
|
||||||
|
|
||||||
test.ok(result, 'pg: Valid result for generated query');
|
|
||||||
test.done();
|
|
||||||
});
|
|
||||||
|
|
||||||
tests['nodeQuery.getQuery = nodeQuery.init'] = function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
test.deepEqual(qb, nodeQuery.getQuery(), "getQuery returns same object");
|
|
||||||
test.done();
|
|
||||||
};
|
|
||||||
|
|
||||||
tests["pg adapter with query builder"] = function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
test.ok(testBase.qb);
|
|
||||||
|
|
||||||
// Close the db connection
|
|
||||||
connection.end();
|
|
||||||
test.done();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = tests;
|
|
@ -1,42 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
var modules = {
|
|
||||||
helpers: require('../lib/helpers'),
|
|
||||||
driver: require('../lib/DriverBase'),
|
|
||||||
qb: require('../lib/QueryBuilder'),
|
|
||||||
'node-query': require('../lib/NodeQuery'),
|
|
||||||
'state': require('../lib/State'),
|
|
||||||
'drivers/pg': require('../lib/drivers/Pg'),
|
|
||||||
'drivers/mysql': require('../lib/drivers/Mysql'),
|
|
||||||
'drivers/sqlite': require('../lib/drivers/Sqlite'),
|
|
||||||
'adapters/mysql': require('../lib/adapters/mysql'),
|
|
||||||
'adapters/mysql2': require('../lib/adapters/mysql2'),
|
|
||||||
'adapters/pg': require('../lib/adapters/pg'),
|
|
||||||
'adapters/dblite': require('../lib/adapters/dblite')
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
'Sanity check': function (test) {
|
|
||||||
test.expect(modules.length);
|
|
||||||
|
|
||||||
Object.keys(modules).forEach(function(mod) {
|
|
||||||
test.ok(modules[mod], mod + " module is sane");
|
|
||||||
});
|
|
||||||
|
|
||||||
test.done();
|
|
||||||
},
|
|
||||||
'NodeQuery.getQuery with no instance': function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
test.throws(function() {
|
|
||||||
nodeQuery.getQuery();
|
|
||||||
}, Error, "No query builder instance if none created");
|
|
||||||
test.done();
|
|
||||||
},
|
|
||||||
'Invalid driver type': function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
test.throws(function() {
|
|
||||||
nodeQuery.init('foo', {}, 'bar');
|
|
||||||
}, Error, "Bad driver throws exception");
|
|
||||||
test.done();
|
|
||||||
}
|
|
||||||
};
|
|
@ -1,87 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
var helpers = require('../lib/helpers');
|
|
||||||
|
|
||||||
var helperTests = {
|
|
||||||
'Type checking method tests' : {
|
|
||||||
"Object wrappers are listed as their native type": function(test) {
|
|
||||||
test.deepEqual('boolean', helpers.type(new Boolean(true)), "Boolean Wrapper returns 'boolean' not 'object'");
|
|
||||||
test.deepEqual('number', helpers.type(new Number(4867)), "Number Wrapper returns 'number' not 'object");
|
|
||||||
test.deepEqual('string', helpers.type(new String("Foo")), "String Wrapper returns 'string' not 'object'");
|
|
||||||
test.done();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'is..Method tests exist' : function(test) {
|
|
||||||
test.expect(11);
|
|
||||||
|
|
||||||
var types = ['Null','Undefined','Object','Array','String','Number','Boolean','Function','RegExp','NaN','Infinite'];
|
|
||||||
|
|
||||||
types.forEach(function(type) {
|
|
||||||
test.ok(helpers['is' + type], 'is' + type + ' method exists');
|
|
||||||
});
|
|
||||||
|
|
||||||
test.done();
|
|
||||||
},
|
|
||||||
'isNaN': function(test) {
|
|
||||||
test.expect(2);
|
|
||||||
test.equal(helpers.type(0 / 0), 'nan');
|
|
||||||
test.deepEqual(helpers.isNaN(0 / 0), true);
|
|
||||||
|
|
||||||
test.done();
|
|
||||||
},
|
|
||||||
'isInfinity': function(test) {
|
|
||||||
test.expect(2);
|
|
||||||
|
|
||||||
test.equal(helpers.type(1/0), 'infinity');
|
|
||||||
test.deepEqual(helpers.isInfinite(1/0), true);
|
|
||||||
test.done();
|
|
||||||
},
|
|
||||||
'stringTrim': function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
|
|
||||||
var orig = [' x y ', 'z ', ' q'];
|
|
||||||
var ret = ['x y', 'z', 'q'];
|
|
||||||
|
|
||||||
test.deepEqual(ret, orig.map(helpers.stringTrim));
|
|
||||||
|
|
||||||
test.done();
|
|
||||||
},
|
|
||||||
'arrayPluck': function(test) {
|
|
||||||
test.expect(3);
|
|
||||||
|
|
||||||
var orig = [{
|
|
||||||
foo: 1
|
|
||||||
},{
|
|
||||||
foo: 2,
|
|
||||||
bar: 10
|
|
||||||
},{
|
|
||||||
foo: 3,
|
|
||||||
bar: 15
|
|
||||||
}];
|
|
||||||
|
|
||||||
test.deepEqual([1,2,3], helpers.arrayPluck(orig, 'foo'), 'Finding members in all objects');
|
|
||||||
test.deepEqual([10,15], helpers.arrayPluck(orig, 'bar'), 'Some members are missing in some objects');
|
|
||||||
|
|
||||||
// Empty case
|
|
||||||
test.deepEqual([], helpers.arrayPluck([], 'apple'));
|
|
||||||
|
|
||||||
test.done();
|
|
||||||
},
|
|
||||||
'regexInArray': function(test) {
|
|
||||||
var orig = ['apple', ' string ', 6, 4, 7];
|
|
||||||
|
|
||||||
test.expect(6);
|
|
||||||
|
|
||||||
test.equal(false, helpers.regexInArray(orig, /\$/), 'Dollar sign is not in any of the array items');
|
|
||||||
test.equal(true, helpers.regexInArray(orig, /^ ?string/), "' string ' matches /^ ?string/");
|
|
||||||
test.equal(true, helpers.regexInArray(orig, /APPLE/i), "'apple' matches /APPLE/i");
|
|
||||||
test.equal(false, helpers.regexInArray(orig, /5/), 'None of the numbers in the array match /5/');
|
|
||||||
test.equal(false, helpers.regexInArray(5, /5/), 'First argument is not an array');
|
|
||||||
test.equal(false, helpers.regexInArray([], /.*/), 'Array is empty');
|
|
||||||
|
|
||||||
test.done();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = helperTests;
|
|
@ -1,526 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
var helpers = require('../lib/helpers');
|
|
||||||
var State = require('../lib/State');
|
|
||||||
|
|
||||||
module.exports = (function QueryBuilderTestBase() {
|
|
||||||
|
|
||||||
// That 'new' keyword is annoying
|
|
||||||
if ( ! (this instanceof QueryBuilderTestBase)) return new QueryBuilderTestBase();
|
|
||||||
|
|
||||||
var base = {};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Inject the appropriate driver and adapter for the test suite
|
|
||||||
*
|
|
||||||
* @param {Object} qb - The adapter-specific query builder object
|
|
||||||
* @param {Function} callback - The test callback
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
this._setUp = function(qb, callback) {
|
|
||||||
base.qb = qb;
|
|
||||||
base.testCallback = callback;
|
|
||||||
|
|
||||||
this.qb = base.qb;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generic query builder tests
|
|
||||||
*/
|
|
||||||
this.tests = {
|
|
||||||
// ! Get tests
|
|
||||||
'Get tests' : {
|
|
||||||
'Get with function': function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
base.qb.select('id, COUNT(id) as count')
|
|
||||||
.from('create_test')
|
|
||||||
.groupBy('id')
|
|
||||||
.get(base.testCallback.bind(this, test));
|
|
||||||
},
|
|
||||||
'Basic select all get': function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
base.qb.get('create_test', base.testCallback.bind(this, test));
|
|
||||||
},
|
|
||||||
'Basic select all with from': function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
base.qb.from('create_test')
|
|
||||||
.get(base.testCallback.bind(this, test));
|
|
||||||
},
|
|
||||||
'Get with limit': function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
base.qb.get('create_test', 2, base.testCallback.bind(this, test));
|
|
||||||
},
|
|
||||||
'Get with limit and offset': function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
base.qb.get('create_test', 2, 1, base.testCallback.bind(this, test));
|
|
||||||
},
|
|
||||||
'Test get with having': function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
base.qb.select('id')
|
|
||||||
.from('create_test')
|
|
||||||
.groupBy('id')
|
|
||||||
.having({'id >':1})
|
|
||||||
.having('id !=', 3)
|
|
||||||
.having('id', 900)
|
|
||||||
.get(base.testCallback.bind(this, test));
|
|
||||||
},
|
|
||||||
"Test get with 'orHaving'": function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
base.qb.select('id')
|
|
||||||
.from('create_test')
|
|
||||||
.groupBy('id')
|
|
||||||
.having({'id >':1})
|
|
||||||
.orHaving('id !=', 3)
|
|
||||||
.get(base.testCallback.bind(this, test));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// ! Select tests
|
|
||||||
'Select tests' : {
|
|
||||||
'Select where get': function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
base.qb.select(['id', 'key as k', 'val'])
|
|
||||||
.where('id >', 1)
|
|
||||||
.where('id <', 900)
|
|
||||||
.get('create_test', 2, 1, base.testCallback.bind(this, test));
|
|
||||||
},
|
|
||||||
'Select where get 2': function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
base.qb.select('id, key as k, val')
|
|
||||||
.where('id !=', 1)
|
|
||||||
.get('create_test', 2, 1, base.testCallback.bind(this, test));
|
|
||||||
},
|
|
||||||
'Multi Order By': function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
base.qb.from('create_test')
|
|
||||||
.orderBy('id, key')
|
|
||||||
.get(base.testCallback.bind(this, test));
|
|
||||||
},
|
|
||||||
'Select get': function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
base.qb.select('id, key as k, val')
|
|
||||||
.get('create_test', 2, 1, base.testCallback.bind(this, test));
|
|
||||||
},
|
|
||||||
'Select from get': function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
base.qb.select('id, key as k, val')
|
|
||||||
.from('create_test ct')
|
|
||||||
.where('id >', 1)
|
|
||||||
.get(base.testCallback.bind(this, test));
|
|
||||||
},
|
|
||||||
'Select from limit get': function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
base.qb.select('id, key as k, val')
|
|
||||||
.from('create_test ct')
|
|
||||||
.where('id >', 1)
|
|
||||||
.limit(3)
|
|
||||||
.get(base.testCallback.bind(this, test));
|
|
||||||
},
|
|
||||||
'Select where IS NOT NULL': function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
base.qb.select('id', 'key as k', 'val')
|
|
||||||
.from('create_test ct')
|
|
||||||
.whereIsNotNull('id')
|
|
||||||
.get(base.testCallback.bind(this, test));
|
|
||||||
},
|
|
||||||
'Select where IS NULL': function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
base.qb.select('id', 'key as k', 'val')
|
|
||||||
.from('create_test ct')
|
|
||||||
.whereIsNull('id')
|
|
||||||
.get(base.testCallback.bind(this, test));
|
|
||||||
},
|
|
||||||
'Select where OR IS NOT NULL': function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
base.qb.select('id', 'key as k', 'val')
|
|
||||||
.from('create_test ct')
|
|
||||||
.whereIsNull('id')
|
|
||||||
.orWhereIsNotNull('id')
|
|
||||||
.get(base.testCallback.bind(this, test));
|
|
||||||
},
|
|
||||||
'Select where OR IS NULL': function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
base.qb.select('id', 'key as k', 'val')
|
|
||||||
.from('create_test ct')
|
|
||||||
.where('id', 3)
|
|
||||||
.orWhereIsNull('id')
|
|
||||||
.get(base.testCallback.bind(this, test));
|
|
||||||
},
|
|
||||||
'Select with string where value': function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
base.qb.select('id','key as k', 'val')
|
|
||||||
.from('create_test ct')
|
|
||||||
.where('id > 3')
|
|
||||||
.get(base.testCallback.bind(this, test));
|
|
||||||
},
|
|
||||||
'Select with function and argument in WHERE clause': function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
base.qb.select('id')
|
|
||||||
.from('create_test')
|
|
||||||
.where('id', 'CEILING(SQRT(88))')
|
|
||||||
.get(base.testCallback.bind(this, test));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// ! Grouping tests
|
|
||||||
'Grouping tests' : {
|
|
||||||
'Using grouping method': function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
base.qb.select('id, key as k, val')
|
|
||||||
.from('create_test')
|
|
||||||
.groupStart()
|
|
||||||
.where('id >', 1)
|
|
||||||
.where('id <', 900)
|
|
||||||
.groupEnd()
|
|
||||||
.limit(2, 1)
|
|
||||||
.get(base.testCallback.bind(this, test));
|
|
||||||
},
|
|
||||||
'Using where first grouping': function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
base.qb.select('id, key as k, val')
|
|
||||||
.from('create_test')
|
|
||||||
.where('id !=', 5)
|
|
||||||
.groupStart()
|
|
||||||
.where('id >', 1)
|
|
||||||
.where('id <', 900)
|
|
||||||
.groupEnd()
|
|
||||||
.limit(2, 1)
|
|
||||||
.get(base.testCallback.bind(this, test));
|
|
||||||
},
|
|
||||||
'Using or grouping method': function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
base.qb.select('id, key as k, val')
|
|
||||||
.from('create_test')
|
|
||||||
.groupStart()
|
|
||||||
.where('id >', 1)
|
|
||||||
.where('id <', 900)
|
|
||||||
.groupEnd()
|
|
||||||
.orGroupStart()
|
|
||||||
.where('id', 0)
|
|
||||||
.groupEnd()
|
|
||||||
.limit(2, 1)
|
|
||||||
.get(base.testCallback.bind(this, test));
|
|
||||||
},
|
|
||||||
'Using or not grouping method': function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
base.qb.select('id, key as k, val')
|
|
||||||
.from('create_test')
|
|
||||||
.groupStart()
|
|
||||||
.where('id >', 1)
|
|
||||||
.where('id <', 900)
|
|
||||||
.groupEnd()
|
|
||||||
.orNotGroupStart()
|
|
||||||
.where('id', 0)
|
|
||||||
.groupEnd()
|
|
||||||
.limit(2, 1)
|
|
||||||
.get(base.testCallback.bind(this, test));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// ! Where in tests
|
|
||||||
'Where in tests' : {
|
|
||||||
'Where in': function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
base.qb.from('create_test')
|
|
||||||
.whereIn('id', [0, 6, 56, 563, 341])
|
|
||||||
.get(base.testCallback.bind(this, test));
|
|
||||||
},
|
|
||||||
'Or Where in': function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
base.qb.from('create_test')
|
|
||||||
.where('key', 'false')
|
|
||||||
.orWhereIn('id', [0, 6, 56, 563, 341])
|
|
||||||
.get(base.testCallback.bind(this, test));
|
|
||||||
},
|
|
||||||
'Where Not in': function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
base.qb.from('create_test')
|
|
||||||
.where('key', 'false')
|
|
||||||
.whereNotIn('id', [0, 6, 56, 563, 341])
|
|
||||||
.get(base.testCallback.bind(this, test));
|
|
||||||
},
|
|
||||||
'Or Where Not in': function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
base.qb.from('create_test')
|
|
||||||
.where('key', 'false')
|
|
||||||
.orWhereNotIn('id', [0, 6, 56, 563, 341])
|
|
||||||
.get(base.testCallback.bind(this, test));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// ! Query modifier tests
|
|
||||||
'Query modifier tests': {
|
|
||||||
'Order By': function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
base.qb.select('id, key as k, val')
|
|
||||||
.from('create_test')
|
|
||||||
.where('id >', 0)
|
|
||||||
.where('id <', 9000)
|
|
||||||
.orderBy('id', 'DESC')
|
|
||||||
.orderBy('k', "ASC")
|
|
||||||
.limit(5, 2)
|
|
||||||
.get(base.testCallback.bind(this, test));
|
|
||||||
},
|
|
||||||
'Group by': function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
base.qb.select('id, key as k, val')
|
|
||||||
.from('create_test')
|
|
||||||
.where('id >', 0)
|
|
||||||
.where('id <', 9000)
|
|
||||||
.groupBy('k')
|
|
||||||
.groupBy(['id', 'val'])
|
|
||||||
.orderBy('id', 'DESC')
|
|
||||||
.orderBy('k', "ASC")
|
|
||||||
.limit(5, 2)
|
|
||||||
.get(base.testCallback.bind(this, test));
|
|
||||||
},
|
|
||||||
'Or Where': function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
base.qb.select('id, key as k, val')
|
|
||||||
.from('create_test')
|
|
||||||
.where(' id ', 1)
|
|
||||||
.orWhere('key >', 0)
|
|
||||||
.limit(2, 1)
|
|
||||||
.get(base.testCallback.bind(this, test));
|
|
||||||
},
|
|
||||||
'Like' : function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
base.qb.from('create_test')
|
|
||||||
.like('key', 'og')
|
|
||||||
.get(base.testCallback.bind(this, test));
|
|
||||||
},
|
|
||||||
'Or Like': function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
base.qb.from('create_test')
|
|
||||||
.like('key', 'og')
|
|
||||||
.orLike('key', 'val')
|
|
||||||
.get(base.testCallback.bind(this, test));
|
|
||||||
},
|
|
||||||
'Not Like': function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
base.qb.from('create_test')
|
|
||||||
.like('key', 'og', 'before')
|
|
||||||
.notLike('key', 'val')
|
|
||||||
.get(base.testCallback.bind(this, test));
|
|
||||||
},
|
|
||||||
'Or Not Like': function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
base.qb.from('create_test')
|
|
||||||
.like('key', 'og', 'before')
|
|
||||||
.orNotLike('key', 'val')
|
|
||||||
.get(base.testCallback.bind(this, test));
|
|
||||||
},
|
|
||||||
'Like Before': function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
base.qb.from('create_test')
|
|
||||||
.like('key', 'og', 'before')
|
|
||||||
.get(base.testCallback.bind(this, test));
|
|
||||||
},
|
|
||||||
'Like After': function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
base.qb.from('create_test')
|
|
||||||
.like('key', 'og', 'after')
|
|
||||||
.get(base.testCallback.bind(this, test));
|
|
||||||
},
|
|
||||||
'Basic Join': function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
base.qb.from('create_test ct')
|
|
||||||
.join('create_join cj', 'cj.id=ct.id')
|
|
||||||
.get(base.testCallback.bind(this, test));
|
|
||||||
},
|
|
||||||
'Left Join': function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
base.qb.from('create_test ct')
|
|
||||||
.join('create_join cj', 'cj.id=ct.id', 'left')
|
|
||||||
.get(base.testCallback.bind(this, test));
|
|
||||||
},
|
|
||||||
'InnerJoin': function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
base.qb.from('create_test ct')
|
|
||||||
.join('create_join cj', 'cj.id=ct.id', 'inner')
|
|
||||||
.get(base.testCallback.bind(this, test));
|
|
||||||
},
|
|
||||||
'Join with multiple where values': function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
base.qb.from('create_test ct')
|
|
||||||
.join('create_join cj', 'cj.id=ct.id', 'inner')
|
|
||||||
.where({
|
|
||||||
'ct.id <': 3,
|
|
||||||
'ct.key': 'foo'
|
|
||||||
})
|
|
||||||
.get(base.testCallback.bind(this, test));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// ! DB Update test
|
|
||||||
'DB update tests' : {
|
|
||||||
setUp: function(callback) {
|
|
||||||
var sql = base.qb.driver.truncate('create_test');
|
|
||||||
base.qb.adapter.execute(sql, function(err, result) {
|
|
||||||
callback();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
tearDown: function(callback) {
|
|
||||||
callback();
|
|
||||||
},
|
|
||||||
'Test Insert': function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
base.qb.set('id', 98)
|
|
||||||
.set('key', "84")
|
|
||||||
.set('val', new Buffer("120"))
|
|
||||||
.insert('create_test', base.testCallback.bind(this, test));
|
|
||||||
},
|
|
||||||
'Test Insert Object': function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
base.qb.insert('create_test', {
|
|
||||||
id: 587,
|
|
||||||
key: 1,
|
|
||||||
val: new Buffer('2')
|
|
||||||
}, base.testCallback.bind(this, test));
|
|
||||||
},
|
|
||||||
'Test Insert Batch': function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
var data = [{
|
|
||||||
id: 544,
|
|
||||||
key: 3,
|
|
||||||
val: new Buffer('7')
|
|
||||||
}, {
|
|
||||||
id: 89,
|
|
||||||
key: 34,
|
|
||||||
val: new Buffer("10 o'clock")
|
|
||||||
}, {
|
|
||||||
id: 48,
|
|
||||||
key: 403,
|
|
||||||
val: new Buffer('97')
|
|
||||||
}];
|
|
||||||
|
|
||||||
base.qb.insertBatch('create_test', data, base.testCallback.bind(this, test));
|
|
||||||
},
|
|
||||||
'Test Update': function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
base.qb.where('id', 7)
|
|
||||||
.update('create_test', {
|
|
||||||
id: 7,
|
|
||||||
key: 'gogle',
|
|
||||||
val: new Buffer('non-word')
|
|
||||||
}, base.testCallback.bind(this, test));
|
|
||||||
},
|
|
||||||
'Test set Array Update': function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
var object = {
|
|
||||||
id: 22,
|
|
||||||
key: 'gogle',
|
|
||||||
val: new Buffer('non-word')
|
|
||||||
};
|
|
||||||
|
|
||||||
base.qb.set(object)
|
|
||||||
.where('id', 22)
|
|
||||||
.update('create_test', base.testCallback.bind(this, test));
|
|
||||||
},
|
|
||||||
'Test where set update': function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
base.qb.where('id', 36)
|
|
||||||
.set('id', 36)
|
|
||||||
.set('key', 'gogle')
|
|
||||||
.set('val', new Buffer('non-word'))
|
|
||||||
.update('create_test', base.testCallback.bind(this, test));
|
|
||||||
},
|
|
||||||
'Test delete': function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
base.qb.delete('create_test', {id: 5}, base.testCallback.bind(this, test));
|
|
||||||
},
|
|
||||||
'delete with where': function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
base.qb.where('id', 5)
|
|
||||||
.delete('create_test', base.testCallback.bind(this, test));
|
|
||||||
},
|
|
||||||
'Delete multiple where values': function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
base.qb.delete('create_test', {
|
|
||||||
id: 5,
|
|
||||||
key: 'gogle'
|
|
||||||
}, base.testCallback.bind(this, test));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// ! Get compiled tests
|
|
||||||
'Get compiled tests' : {
|
|
||||||
'select': function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
var string = base.qb.select('id')
|
|
||||||
.from('create_test')
|
|
||||||
.getCompiledSelect(true);
|
|
||||||
|
|
||||||
test.equal(true, helpers.isString(string));
|
|
||||||
|
|
||||||
test.done();
|
|
||||||
},
|
|
||||||
'select from': function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
var string = base.qb.select('id')
|
|
||||||
.getCompiledSelect('create_test', true);
|
|
||||||
|
|
||||||
test.equal(true, helpers.isString(string));
|
|
||||||
|
|
||||||
test.done();
|
|
||||||
},
|
|
||||||
'insert': function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
|
|
||||||
var string = base.qb.set('id', 3)
|
|
||||||
.getCompiledInsert('create_test');
|
|
||||||
|
|
||||||
test.equal(true, helpers.isString(string));
|
|
||||||
|
|
||||||
test.done();
|
|
||||||
},
|
|
||||||
'update': function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
|
|
||||||
var string = base.qb.set('id', 3)
|
|
||||||
.where('id', 5)
|
|
||||||
.getCompiledUpdate('create_test');
|
|
||||||
|
|
||||||
test.equal(true, helpers.isString(string));
|
|
||||||
|
|
||||||
test.done();
|
|
||||||
},
|
|
||||||
'delete': function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
|
|
||||||
var string = base.qb.where('id', 5)
|
|
||||||
.getCompiledDelete('create_test');
|
|
||||||
|
|
||||||
test.equal(true, helpers.isString(string));
|
|
||||||
|
|
||||||
test.done();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// ! Misc tests
|
|
||||||
'Misc tests' : {
|
|
||||||
'Get State': function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
|
|
||||||
base.qb.select('foo')
|
|
||||||
.from('bar')
|
|
||||||
.where('baz', 'foobar');
|
|
||||||
|
|
||||||
var state = new State();
|
|
||||||
|
|
||||||
test.notDeepEqual(JSON.stringify(state), JSON.stringify(base.qb.getState()));
|
|
||||||
test.done();
|
|
||||||
},
|
|
||||||
'Reset State': function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
|
|
||||||
base.qb.select('foo')
|
|
||||||
.from('bar')
|
|
||||||
.where('baz', 'foobar');
|
|
||||||
|
|
||||||
base.qb.resetQuery();
|
|
||||||
|
|
||||||
var state = new State();
|
|
||||||
|
|
||||||
test.deepEqual(state, base.qb.getState());
|
|
||||||
|
|
||||||
test.done();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}());
|
|
@ -1,178 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
// Use the base driver as a mock for testing
|
|
||||||
var getArgs = require('getargs');
|
|
||||||
var helpers = require('../lib/helpers');
|
|
||||||
var driver = require('../lib/DriverBase');
|
|
||||||
|
|
||||||
var p = require('../lib/QueryParser');
|
|
||||||
var parser = new p(driver);
|
|
||||||
|
|
||||||
var State = require('../lib/State');
|
|
||||||
|
|
||||||
// Simulate query builder state
|
|
||||||
var state = new State();
|
|
||||||
|
|
||||||
var mixedSet = function(/* $varName, $valType, $key, [$val] */) {
|
|
||||||
var args = getArgs('$varName:string, $valType:string, $key:object|string|number, [$val]', arguments);
|
|
||||||
|
|
||||||
var obj = {};
|
|
||||||
|
|
||||||
|
|
||||||
if (helpers.isScalar(args.$key) && !helpers.isUndefined(args.$val))
|
|
||||||
{
|
|
||||||
// Convert key/val pair to a simple object
|
|
||||||
obj[args.$key] = args.$val;
|
|
||||||
}
|
|
||||||
else if (helpers.isScalar(args.$key) && helpers.isUndefined(args.$val))
|
|
||||||
{
|
|
||||||
// If just a string for the key, and no value, create a simple object with duplicate key/val
|
|
||||||
obj[args.$key] = args.$key;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
obj = args.$key;
|
|
||||||
}
|
|
||||||
|
|
||||||
Object.keys(obj).forEach(function(k) {
|
|
||||||
// If a single value for the return
|
|
||||||
if (['key','value'].indexOf(args.$valType) !== -1)
|
|
||||||
{
|
|
||||||
var pushVal = (args.$valType === 'key') ? k : obj[k];
|
|
||||||
state[args.$varName].push(pushVal);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
state[args.$varName][k] = obj[k];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
return state[args.$varName];
|
|
||||||
}
|
|
||||||
|
|
||||||
var whereMock = function() {
|
|
||||||
var args = getArgs('key:string|object, [val]', arguments);
|
|
||||||
|
|
||||||
state.whereMap = [];
|
|
||||||
state.whereValues = [];
|
|
||||||
|
|
||||||
mixedSet('rawWhereValues', 'value', args.key, args.val);
|
|
||||||
mixedSet('whereMap', 'both', args.key, args.val);
|
|
||||||
}
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
// ! Start Tests
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
var tests = {
|
|
||||||
'Has operator tests': {
|
|
||||||
'Has operator': function(test) {
|
|
||||||
var matches = parser.hasOperator('foo <> 2');
|
|
||||||
test.deepEqual(['<>'], matches);
|
|
||||||
test.done();
|
|
||||||
},
|
|
||||||
'Has no operator': function(test) {
|
|
||||||
var matches = parser.hasOperator('foo');
|
|
||||||
test.equal(null, matches);
|
|
||||||
test.done();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'Where parser tests': {
|
|
||||||
'Has function full string': function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
whereMock('time < SUM(FOO(BAR()))');
|
|
||||||
var result = parser.parseWhere(driver, state);
|
|
||||||
test.deepEqual(['"time" < SUM(FOO(BAR()))'], state.whereMap);
|
|
||||||
|
|
||||||
test.done();
|
|
||||||
},
|
|
||||||
'Has function key/val': function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
var map = whereMock('time <', 'SUM(FOO(BAR()))');
|
|
||||||
state = parser.parseWhere(driver, state);
|
|
||||||
test.deepEqual(['"time" < SUM(FOO(BAR()))'], state.whereMap);
|
|
||||||
|
|
||||||
test.done();
|
|
||||||
},
|
|
||||||
'Has function key/val object': function(test) {
|
|
||||||
test.expect(1);
|
|
||||||
var map = whereMock({
|
|
||||||
'time <': "SUM(FOO(BAR('x')))"
|
|
||||||
});
|
|
||||||
state = parser.parseWhere(driver, state);
|
|
||||||
test.deepEqual(['"time" < SUM(FOO(BAR(\'x\')))'], state.whereMap);
|
|
||||||
|
|
||||||
test.done();
|
|
||||||
},
|
|
||||||
'Has literal value': function(test) {
|
|
||||||
test.expect(2);
|
|
||||||
var map = whereMock({
|
|
||||||
'foo': 3
|
|
||||||
});
|
|
||||||
state = parser.parseWhere(driver, state);
|
|
||||||
test.deepEqual(['"foo" = ?'], state.whereMap);
|
|
||||||
test.deepEqual(['3'], state.whereValues);
|
|
||||||
|
|
||||||
test.done();
|
|
||||||
},
|
|
||||||
'Has multiple literal values': function(test) {
|
|
||||||
test.expect(2);
|
|
||||||
var map = whereMock({
|
|
||||||
foo: 3,
|
|
||||||
bar: 5
|
|
||||||
});
|
|
||||||
state = parser.parseWhere(driver, state);
|
|
||||||
test.deepEqual(['"foo" = ?', '"bar" = ?'], state.whereMap);
|
|
||||||
test.deepEqual(['3','5'], state.whereValues);
|
|
||||||
|
|
||||||
test.done();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'Parse join tests' : {
|
|
||||||
'Simple equals condition': function(test) {
|
|
||||||
var matches = parser.parseJoin('table1.field1=table2.field2');
|
|
||||||
test.deepEqual(['table1.field1','=','table2.field2'], matches.combined);
|
|
||||||
test.done();
|
|
||||||
},
|
|
||||||
'Db.table.field condition': function(test) {
|
|
||||||
var matches = parser.parseJoin('db1.table1.field1!=db2.table2.field2');
|
|
||||||
test.deepEqual(['db1.table1.field1','!=', 'db2.table2.field2'], matches.combined);
|
|
||||||
test.done();
|
|
||||||
},
|
|
||||||
'Underscore in identifier': function(test) {
|
|
||||||
var matches = parser.parseJoin('table_1.field1 = tab_le2.field_2');
|
|
||||||
test.deepEqual(['table_1.field1', '=', 'tab_le2.field_2'], matches.combined);
|
|
||||||
test.done();
|
|
||||||
},
|
|
||||||
'Function in condition': function(test) {
|
|
||||||
var matches = parser.parseJoin('table1.field1 > SUM(3+6)');
|
|
||||||
test.deepEqual(['table1.field1', '>', 'SUM(3+6)'], matches.combined);
|
|
||||||
test.done();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'Compile join tests': {
|
|
||||||
'Simple equals condition': function(test) {
|
|
||||||
var join = parser.compileJoin('table1.field1=table2.field2');
|
|
||||||
test.deepEqual('"table1"."field1" = "table2"."field2"', join);
|
|
||||||
test.done();
|
|
||||||
},
|
|
||||||
'Db.table.field condition': function(test) {
|
|
||||||
var join = parser.compileJoin('db1.table1.field1!=db2.table2.field2');
|
|
||||||
test.deepEqual('"db1"."table1"."field1" != "db2"."table2"."field2"', join);
|
|
||||||
test.done();
|
|
||||||
},
|
|
||||||
'Underscore in identifier': function(test) {
|
|
||||||
var join = parser.compileJoin('table_1.field1 = tab_le2.field_2');
|
|
||||||
test.deepEqual('"table_1"."field1" = "tab_le2"."field_2"', join);
|
|
||||||
test.done();
|
|
||||||
},
|
|
||||||
'Function in condition': function(test) {
|
|
||||||
var join = parser.compileJoin('table1.field1 > SUM(3+6)');
|
|
||||||
test.deepEqual('"table1"."field1" > SUM(3+6)', join);
|
|
||||||
test.done();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = tests;
|
|
Loading…
Reference in New Issue
Block a user