Merge branch 'develop'
This commit is contained in:
commit
cc6a3bb80b
29
.editorconfig
Normal file
29
.editorconfig
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
# EditorConfig is awesome: http://EditorConfig.org
|
||||||
|
|
||||||
|
# top-most EditorConfig file
|
||||||
|
root = true
|
||||||
|
|
||||||
|
# Unix-style newlines with a newline ending every file
|
||||||
|
[*]
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
||||||
|
|
||||||
|
# Matches multiple files with brace expansion notation
|
||||||
|
# Set default charset
|
||||||
|
[*]
|
||||||
|
charset = utf-8
|
||||||
|
|
||||||
|
# Tab indentation (no size specified)
|
||||||
|
[*]
|
||||||
|
indent_style = tab
|
||||||
|
indent_size = 4
|
||||||
|
|
||||||
|
# Indentation override for all JS under lib directory
|
||||||
|
[*.js]
|
||||||
|
indent_size = 2
|
||||||
|
|
||||||
|
# Matches the exact files either package.json or .travis.yml
|
||||||
|
[*.yml]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -4,3 +4,6 @@ npm-debug.log
|
|||||||
node_modules/*
|
node_modules/*
|
||||||
.sonar/*
|
.sonar/*
|
||||||
test/config.json
|
test/config.json
|
||||||
|
.DS_store
|
||||||
|
/.idea/
|
||||||
|
yarn.lock
|
31
.gitlab-ci.yml
Normal file
31
.gitlab-ci.yml
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
before_script:
|
||||||
|
# Install dependencies
|
||||||
|
- bash test/docker_install.sh > /dev/null
|
||||||
|
- npm install
|
||||||
|
|
||||||
|
services:
|
||||||
|
- mysql:latest
|
||||||
|
- postgres:latest
|
||||||
|
|
||||||
|
variables:
|
||||||
|
MYSQL_ROOT_PASSWORD: foo-bar-baz
|
||||||
|
MYSQL_DATABASE: test
|
||||||
|
MYSQL_USER: test
|
||||||
|
MYSQL_PASSWORD: test
|
||||||
|
POSTGRES_DB: test
|
||||||
|
POSTGRES_USER: test
|
||||||
|
POSTGRES_PASSWORD: test
|
||||||
|
|
||||||
|
# This folder is cached between builds
|
||||||
|
# http://docs.gitlab.com/ce/ci/yaml/README.html#cache
|
||||||
|
cache:
|
||||||
|
paths:
|
||||||
|
- node_modules/
|
||||||
|
|
||||||
|
test:6:
|
||||||
|
image: node:6
|
||||||
|
script: npm run test
|
||||||
|
|
||||||
|
test:latest:
|
||||||
|
image: node:latest
|
||||||
|
script: npm run test
|
9
.istanbul.yml
Normal file
9
.istanbul.yml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
reporting:
|
||||||
|
print: summary
|
||||||
|
reports:
|
||||||
|
- lcov
|
||||||
|
- lcovonly
|
||||||
|
- clover
|
||||||
|
- html
|
||||||
|
- text
|
||||||
|
dir: ./coverage
|
7
.jscsrc
7
.jscsrc
@ -1,7 +0,0 @@
|
|||||||
{
|
|
||||||
"preset": "airbnb",
|
|
||||||
"validateIndentation": null,
|
|
||||||
"requireLineFeedAtFileEnd": null,
|
|
||||||
"disallowSpaceAfterPrefixUnaryOperators": null,
|
|
||||||
"disallowMultipleVarDecl": null
|
|
||||||
}
|
|
773
API.md
773
API.md
@ -1,10 +1,12 @@
|
|||||||
|
<!-- Generated by documentation.js. Update this documentation by updating the source code. -->
|
||||||
|
|
||||||
# NodeQuery
|
# NodeQuery
|
||||||
|
|
||||||
Class for connection management
|
Class for connection management
|
||||||
|
|
||||||
**Parameters**
|
**Parameters**
|
||||||
|
|
||||||
- `config` **object** connection parameters
|
- `config` **[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** connection parameters
|
||||||
|
|
||||||
## constructor
|
## constructor
|
||||||
|
|
||||||
@ -12,7 +14,7 @@ Constructor
|
|||||||
|
|
||||||
**Parameters**
|
**Parameters**
|
||||||
|
|
||||||
- `config` **object** connection parameters
|
- `config` **[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** connection parameters
|
||||||
|
|
||||||
**Examples**
|
**Examples**
|
||||||
|
|
||||||
@ -39,10 +41,12 @@ let nodeQuery = require('ci-node-query')({
|
|||||||
|
|
||||||
Return an existing query builder instance
|
Return an existing query builder instance
|
||||||
|
|
||||||
Returns **QueryBuilder** The Query Builder object
|
Returns **[QueryBuilder](#querybuilder)** The Query Builder object
|
||||||
|
|
||||||
# QueryBuilder
|
# QueryBuilder
|
||||||
|
|
||||||
|
**Extends QueryBuilderBase**
|
||||||
|
|
||||||
Main object that builds SQL queries.
|
Main object that builds SQL queries.
|
||||||
|
|
||||||
**Parameters**
|
**Parameters**
|
||||||
@ -50,354 +54,16 @@ Main object that builds SQL queries.
|
|||||||
- `Driver` **Driver** The syntax driver for the database
|
- `Driver` **Driver** The syntax driver for the database
|
||||||
- `Adapter` **Adapter** The database module adapter for running queries
|
- `Adapter` **Adapter** The database module adapter for running queries
|
||||||
|
|
||||||
## delete
|
|
||||||
|
|
||||||
Run the generated delete query
|
|
||||||
|
|
||||||
**Parameters**
|
|
||||||
|
|
||||||
- `table` **String** The table to insert into
|
|
||||||
- `where` **[Object]** Where clause for delete statement
|
|
||||||
- `callback` **[Function]** Callback for handling response from the database
|
|
||||||
|
|
||||||
Returns **void or Promise** If no callback is passed, a promise is returned
|
|
||||||
|
|
||||||
## end
|
|
||||||
|
|
||||||
Closes the database connection for the current adapter
|
|
||||||
|
|
||||||
Returns **void**
|
|
||||||
|
|
||||||
## from
|
|
||||||
|
|
||||||
Specify the database table to select from
|
|
||||||
|
|
||||||
**Parameters**
|
|
||||||
|
|
||||||
- `tableName` **String** The table to use for the current query
|
|
||||||
|
|
||||||
**Examples**
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
query.from('tableName');
|
|
||||||
```
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
query.from('tableName t'); // Select the table with an alias
|
|
||||||
```
|
|
||||||
|
|
||||||
Returns **QueryBuilder** The Query Builder object, for chaining
|
|
||||||
|
|
||||||
## get
|
|
||||||
|
|
||||||
Get the results of the compiled query
|
|
||||||
|
|
||||||
**Parameters**
|
|
||||||
|
|
||||||
- `table` **[String]** The table to select from
|
|
||||||
- `limit` **[Number]** A limit for the query
|
|
||||||
- `offset` **[Number]** An offset for the query
|
|
||||||
- `callback` **[Function]** A callback for receiving the result
|
|
||||||
|
|
||||||
**Examples**
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
query.get('table_name').then(promiseCallback); // Get all the rows in the table
|
|
||||||
```
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
query.get('table_name', 5, callback); // Get 5 rows from the table
|
|
||||||
```
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
query.get(callback); // Get the results of a query generated with other methods
|
|
||||||
```
|
|
||||||
|
|
||||||
Returns **void or Promise** If no callback is passed, a promise is returned
|
|
||||||
|
|
||||||
## getCompiledDelete
|
|
||||||
|
|
||||||
Return generated delete query SQL
|
|
||||||
|
|
||||||
**Parameters**
|
|
||||||
|
|
||||||
- `table` **String** the name of the table to delete from
|
|
||||||
- `reset` **[Boolean]** Whether to reset the query builder so another query can be built (optional, default `true`)
|
|
||||||
|
|
||||||
Returns **String** The compiled sql statement
|
|
||||||
|
|
||||||
## getCompiledInsert
|
|
||||||
|
|
||||||
Return generated insert query SQL
|
|
||||||
|
|
||||||
**Parameters**
|
|
||||||
|
|
||||||
- `table` **String** the name of the table to insert into
|
|
||||||
- `reset` **[Boolean]** Whether to reset the query builder so another query can be built (optional, default `true`)
|
|
||||||
|
|
||||||
Returns **String** The compiled sql statement
|
|
||||||
|
|
||||||
## getCompiledSelect
|
|
||||||
|
|
||||||
Return generated select query SQL
|
|
||||||
|
|
||||||
**Parameters**
|
|
||||||
|
|
||||||
- `table` **[String]** the name of the table to retrieve from
|
|
||||||
- `reset` **[Boolean]** Whether to reset the query builder so another query can be built (optional, default `true`)
|
|
||||||
|
|
||||||
Returns **String** The compiled sql statement
|
|
||||||
|
|
||||||
## getCompiledUpdate
|
|
||||||
|
|
||||||
Return generated update query SQL
|
|
||||||
|
|
||||||
**Parameters**
|
|
||||||
|
|
||||||
- `table` **String** the name of the table to update
|
|
||||||
- `reset` **[Boolean]** Whether to reset the query builder so another query can be built (optional, default `true`)
|
|
||||||
|
|
||||||
Returns **String** The compiled sql statement
|
|
||||||
|
|
||||||
## groupBy
|
|
||||||
|
|
||||||
Group the results by the selected field(s)
|
|
||||||
|
|
||||||
**Parameters**
|
|
||||||
|
|
||||||
- `field` **String or Array** The name of the field to group by
|
|
||||||
|
|
||||||
Returns **QueryBuilder** The Query Builder object, for chaining
|
|
||||||
|
|
||||||
## groupEnd
|
|
||||||
|
|
||||||
Ends a logical grouping started with one of the groupStart methods
|
|
||||||
|
|
||||||
Returns **QueryBuilder** The Query Builder object, for chaining
|
|
||||||
|
|
||||||
## groupStart
|
|
||||||
|
|
||||||
Adds an open paren to the current query for logical grouping
|
|
||||||
|
|
||||||
Returns **QueryBuilder** The Query Builder object, for chaining
|
|
||||||
|
|
||||||
## having
|
|
||||||
|
|
||||||
Add a 'having' clause
|
|
||||||
|
|
||||||
**Parameters**
|
|
||||||
|
|
||||||
- `key` **String or Object** The name of the field and the comparision operator, or an object
|
|
||||||
- `val` **[String or Number]** The value to compare if the value of key is a string
|
|
||||||
|
|
||||||
Returns **QueryBuilder** The Query Builder object, for chaining
|
|
||||||
|
|
||||||
## insert
|
|
||||||
|
|
||||||
Run the generated insert query
|
|
||||||
|
|
||||||
**Parameters**
|
|
||||||
|
|
||||||
- `table` **String** The table to insert into
|
|
||||||
- `data` **[Object]** Data to insert, if not already added with the 'set' method
|
|
||||||
- `callback` **[Function]** Callback for handling response from the database
|
|
||||||
|
|
||||||
Returns **void or Promise** If no callback is passed, a promise is returned
|
|
||||||
|
|
||||||
## insertBatch
|
|
||||||
|
|
||||||
Insert multiple sets of rows at a time
|
|
||||||
|
|
||||||
**Parameters**
|
|
||||||
|
|
||||||
- `table` **String** The table to insert into
|
|
||||||
- `data` **Array** The array of objects containing data rows to insert
|
|
||||||
- `callback` **[Function]** Callback for handling database response
|
|
||||||
|
|
||||||
**Examples**
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
query.insertBatch('foo',[{id:1,val:'bar'},{id:2,val:'baz'}], callbackFunction);
|
|
||||||
```
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
query.insertBatch('foo',[{id:1,val:'bar'},{id:2,val:'baz'}])
|
|
||||||
.then(promiseCallback);
|
|
||||||
```
|
|
||||||
|
|
||||||
Returns **void or Promise** If no callback is passed, a promise is returned
|
|
||||||
|
|
||||||
## join
|
|
||||||
|
|
||||||
Add a join clause to the query
|
|
||||||
|
|
||||||
**Parameters**
|
|
||||||
|
|
||||||
- `table` **String** The table you are joining
|
|
||||||
- `cond` **String** The join condition.
|
|
||||||
- `type` **[String]** The type of join, which defaults to inner (optional, default `'inner'`)
|
|
||||||
|
|
||||||
Returns **QueryBuilder** The Query Builder object, for chaining
|
|
||||||
|
|
||||||
## like
|
|
||||||
|
|
||||||
Add a 'like/ and like' clause to the query
|
|
||||||
|
|
||||||
**Parameters**
|
|
||||||
|
|
||||||
- `field` **String** The name of the field to compare to
|
|
||||||
- `val` **String** The value to compare to
|
|
||||||
- `pos` **[String]** The placement of the wildcard character(s): before, after, or both (optional, default `both`)
|
|
||||||
|
|
||||||
Returns **QueryBuilder** The Query Builder object, for chaining
|
|
||||||
|
|
||||||
## limit
|
|
||||||
|
|
||||||
Put a limit on the query
|
|
||||||
|
|
||||||
**Parameters**
|
|
||||||
|
|
||||||
- `limit` **Number** The maximum number of rows to fetch
|
|
||||||
- `offset` **[Number]** The row number to start from
|
|
||||||
|
|
||||||
Returns **QueryBuilder** The Query Builder object, for chaining
|
|
||||||
|
|
||||||
## notLike
|
|
||||||
|
|
||||||
Add a 'not like/ and not like' clause to the query
|
|
||||||
|
|
||||||
**Parameters**
|
|
||||||
|
|
||||||
- `field` **String** The name of the field to compare to
|
|
||||||
- `val` **String** The value to compare to
|
|
||||||
- `pos` **[String]** The placement of the wildcard character(s): before, after, or both (optional, default `both`)
|
|
||||||
|
|
||||||
Returns **QueryBuilder** The Query Builder object, for chaining
|
|
||||||
|
|
||||||
## orGroupStart
|
|
||||||
|
|
||||||
Adds an open paren to the current query for logical grouping,
|
|
||||||
prefixed with 'OR'
|
|
||||||
|
|
||||||
Returns **QueryBuilder** The Query Builder object, for chaining
|
|
||||||
|
|
||||||
## orHaving
|
|
||||||
|
|
||||||
Add an 'or having' clause
|
|
||||||
|
|
||||||
**Parameters**
|
|
||||||
|
|
||||||
- `key` **String or Object** The name of the field and the comparision operator, or an object
|
|
||||||
- `val` **[String or Number]** The value to compare if the value of key is a string
|
|
||||||
|
|
||||||
Returns **QueryBuilder** The Query Builder object, for chaining
|
|
||||||
|
|
||||||
## orLike
|
|
||||||
|
|
||||||
Add an 'or like' clause to the query
|
|
||||||
|
|
||||||
**Parameters**
|
|
||||||
|
|
||||||
- `field` **String** The name of the field to compare to
|
|
||||||
- `val` **String** The value to compare to
|
|
||||||
- `pos` **[String]** The placement of the wildcard character(s): before, after, or both (optional, default `both`)
|
|
||||||
|
|
||||||
Returns **QueryBuilder** The Query Builder object, for chaining
|
|
||||||
|
|
||||||
## orNotGroupStart
|
|
||||||
|
|
||||||
Adds an open paren to the current query for logical grouping,
|
|
||||||
prefixed with 'OR NOT'
|
|
||||||
|
|
||||||
Returns **QueryBuilder** The Query Builder object, for chaining
|
|
||||||
|
|
||||||
## orNotLike
|
|
||||||
|
|
||||||
Add an 'or not like' clause to the query
|
|
||||||
|
|
||||||
**Parameters**
|
|
||||||
|
|
||||||
- `field` **String** The name of the field to compare to
|
|
||||||
- `val` **String** The value to compare to
|
|
||||||
- `pos` **[String]** The placement of the wildcard character(s): before, after, or both (optional, default `both`)
|
|
||||||
|
|
||||||
Returns **QueryBuilder** The Query Builder object, for chaining
|
|
||||||
|
|
||||||
## orWhere
|
|
||||||
|
|
||||||
Set a 'or where' clause
|
|
||||||
|
|
||||||
**Parameters**
|
|
||||||
|
|
||||||
- `key` **String or Object** The name of the field and the comparision operator, or an object
|
|
||||||
- `val` **[String or Number]** The value to compare if the value of key is a string
|
|
||||||
|
|
||||||
Returns **QueryBuilder** The Query Builder object, for chaining
|
|
||||||
|
|
||||||
## orWhereIn
|
|
||||||
|
|
||||||
Set a 'or where in' clause
|
|
||||||
|
|
||||||
**Parameters**
|
|
||||||
|
|
||||||
- `key` **String** the field to search
|
|
||||||
- `values` **Array** the array of items to search in
|
|
||||||
|
|
||||||
Returns **QueryBuilder** The Query Builder object, for chaining
|
|
||||||
|
|
||||||
## orWhereIsNotNull
|
|
||||||
|
|
||||||
Field is not null prefixed with 'OR'
|
|
||||||
|
|
||||||
**Parameters**
|
|
||||||
|
|
||||||
- `field` **String** The name of the field
|
|
||||||
|
|
||||||
Returns **QueryBuilder** The Query Builder object, for chaining
|
|
||||||
|
|
||||||
## orWhereIsNull
|
|
||||||
|
|
||||||
Field is null prefixed with 'OR'
|
|
||||||
|
|
||||||
**Parameters**
|
|
||||||
|
|
||||||
- `field` **String** The name of the field
|
|
||||||
|
|
||||||
Returns **QueryBuilder** The Query Builder object, for chaining
|
|
||||||
|
|
||||||
## orWhereNotIn
|
|
||||||
|
|
||||||
Set a 'or where not in' clause
|
|
||||||
|
|
||||||
**Parameters**
|
|
||||||
|
|
||||||
- `key` **String** the field to search
|
|
||||||
- `values` **Array** the array of items to search in
|
|
||||||
|
|
||||||
Returns **QueryBuilder** The Query Builder object, for chaining
|
|
||||||
|
|
||||||
## orderBy
|
|
||||||
|
|
||||||
Order the results by the selected field(s)
|
|
||||||
|
|
||||||
**Parameters**
|
|
||||||
|
|
||||||
- `field` **String** The field(s) to order by
|
|
||||||
- `type` **[String]** The order direction, ASC or DESC (optional, default `'ASC'`)
|
|
||||||
|
|
||||||
Returns **QueryBuilder** The Query Builder object, for chaining
|
|
||||||
|
|
||||||
## query
|
## query
|
||||||
|
|
||||||
Run an arbitrary sql query. Run as a prepared statement.
|
Run an arbitrary sql query. Run as a prepared statement.
|
||||||
|
|
||||||
**Parameters**
|
**Parameters**
|
||||||
|
|
||||||
- `sql` **string** The sql to execute
|
- `sql` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** The sql to execute
|
||||||
- `params` **[array]** The query parameters
|
- `params` **\[[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)]** The query parameters
|
||||||
- `callback` **[function]** Optional callback
|
|
||||||
|
|
||||||
Returns **void or Promise** Returns a promise if no callback is supplied
|
Returns **[Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)** Promise with result of query
|
||||||
|
|
||||||
## resetQuery
|
## resetQuery
|
||||||
|
|
||||||
@ -405,13 +71,29 @@ Reset the object state for a new query
|
|||||||
|
|
||||||
Returns **void**
|
Returns **void**
|
||||||
|
|
||||||
|
## truncate
|
||||||
|
|
||||||
|
Empties the selected database table
|
||||||
|
|
||||||
|
**Parameters**
|
||||||
|
|
||||||
|
- `table` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** the name of the table to truncate
|
||||||
|
|
||||||
|
Returns **(void | [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise))** Returns a promise if no callback is supplied
|
||||||
|
|
||||||
|
## end
|
||||||
|
|
||||||
|
Closes the database connection for the current adapter
|
||||||
|
|
||||||
|
Returns **void**
|
||||||
|
|
||||||
## select
|
## select
|
||||||
|
|
||||||
Specify rows to select in the query
|
Specify rows to select in the query
|
||||||
|
|
||||||
**Parameters**
|
**Parameters**
|
||||||
|
|
||||||
- `fields` **String or Array** The fields to select from the current table
|
- `fields` **([String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) \| [Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array))** The fields to select from the current table
|
||||||
|
|
||||||
**Examples**
|
**Examples**
|
||||||
|
|
||||||
@ -423,7 +105,203 @@ query.select('foo, bar'); // Select multiple fields with a string
|
|||||||
query.select(['foo', 'bar']); // Select multiple fileds with an array
|
query.select(['foo', 'bar']); // Select multiple fileds with an array
|
||||||
```
|
```
|
||||||
|
|
||||||
Returns **QueryBuilder** The Query Builder object, for chaining
|
Returns **[QueryBuilder](#querybuilder)** The Query Builder object, for chaining
|
||||||
|
|
||||||
|
## from
|
||||||
|
|
||||||
|
Specify the database table to select from
|
||||||
|
|
||||||
|
**Parameters**
|
||||||
|
|
||||||
|
- `tableName` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** The table to use for the current query
|
||||||
|
|
||||||
|
**Examples**
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
query.from('tableName');
|
||||||
|
```
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
query.from('tableName t'); // Select the table with an alias
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns **[QueryBuilder](#querybuilder)** The Query Builder object, for chaining
|
||||||
|
|
||||||
|
## like
|
||||||
|
|
||||||
|
Add a 'like/ and like' clause to the query
|
||||||
|
|
||||||
|
**Parameters**
|
||||||
|
|
||||||
|
- `field` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** The name of the field to compare to
|
||||||
|
- `val` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** The value to compare to
|
||||||
|
- `pos` **\[[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)]** The placement of the wildcard character(s): before, after, or both (optional, default `both`)
|
||||||
|
|
||||||
|
Returns **[QueryBuilder](#querybuilder)** The Query Builder object, for chaining
|
||||||
|
|
||||||
|
## notLike
|
||||||
|
|
||||||
|
Add a 'not like/ and not like' clause to the query
|
||||||
|
|
||||||
|
**Parameters**
|
||||||
|
|
||||||
|
- `field` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** The name of the field to compare to
|
||||||
|
- `val` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** The value to compare to
|
||||||
|
- `pos` **\[[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)]** The placement of the wildcard character(s): before, after, or both (optional, default `both`)
|
||||||
|
|
||||||
|
Returns **[QueryBuilder](#querybuilder)** The Query Builder object, for chaining
|
||||||
|
|
||||||
|
## orLike
|
||||||
|
|
||||||
|
Add an 'or like' clause to the query
|
||||||
|
|
||||||
|
**Parameters**
|
||||||
|
|
||||||
|
- `field` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** The name of the field to compare to
|
||||||
|
- `val` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** The value to compare to
|
||||||
|
- `pos` **\[[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)]** The placement of the wildcard character(s): before, after, or both (optional, default `both`)
|
||||||
|
|
||||||
|
Returns **[QueryBuilder](#querybuilder)** The Query Builder object, for chaining
|
||||||
|
|
||||||
|
## orNotLike
|
||||||
|
|
||||||
|
Add an 'or not like' clause to the query
|
||||||
|
|
||||||
|
**Parameters**
|
||||||
|
|
||||||
|
- `field` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** The name of the field to compare to
|
||||||
|
- `val` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** The value to compare to
|
||||||
|
- `pos` **\[[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)]** The placement of the wildcard character(s): before, after, or both (optional, default `both`)
|
||||||
|
|
||||||
|
Returns **[QueryBuilder](#querybuilder)** The Query Builder object, for chaining
|
||||||
|
|
||||||
|
## having
|
||||||
|
|
||||||
|
Add a 'having' clause
|
||||||
|
|
||||||
|
**Parameters**
|
||||||
|
|
||||||
|
- `key` **([String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) \| [Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object))** The name of the field and the comparision operator, or an object
|
||||||
|
- `val` **\[([String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) \| [Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number))]** The value to compare if the value of key is a string
|
||||||
|
|
||||||
|
Returns **[QueryBuilder](#querybuilder)** The Query Builder object, for chaining
|
||||||
|
|
||||||
|
## orHaving
|
||||||
|
|
||||||
|
Add an 'or having' clause
|
||||||
|
|
||||||
|
**Parameters**
|
||||||
|
|
||||||
|
- `key` **([String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) \| [Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object))** The name of the field and the comparision operator, or an object
|
||||||
|
- `val` **\[([String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) \| [Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number))]** The value to compare if the value of key is a string
|
||||||
|
|
||||||
|
Returns **[QueryBuilder](#querybuilder)** The Query Builder object, for chaining
|
||||||
|
|
||||||
|
## where
|
||||||
|
|
||||||
|
Set a 'where' clause
|
||||||
|
|
||||||
|
**Parameters**
|
||||||
|
|
||||||
|
- `key` **([String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) \| [Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object))** The name of the field and the comparision operator, or an object
|
||||||
|
- `val` **\[([String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) \| [Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number))]** The value to compare if the value of key is a string
|
||||||
|
|
||||||
|
Returns **[QueryBuilder](#querybuilder)** The Query Builder object, for chaining
|
||||||
|
|
||||||
|
## orWhere
|
||||||
|
|
||||||
|
Set a 'or where' clause
|
||||||
|
|
||||||
|
**Parameters**
|
||||||
|
|
||||||
|
- `key` **([String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) \| [Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object))** The name of the field and the comparision operator, or an object
|
||||||
|
- `val` **\[([String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) \| [Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number))]** The value to compare if the value of key is a string
|
||||||
|
|
||||||
|
Returns **[QueryBuilder](#querybuilder)** The Query Builder object, for chaining
|
||||||
|
|
||||||
|
## whereIsNull
|
||||||
|
|
||||||
|
Select a field that is Null
|
||||||
|
|
||||||
|
**Parameters**
|
||||||
|
|
||||||
|
- `field` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** The name of the field that has a NULL value
|
||||||
|
|
||||||
|
Returns **[QueryBuilder](#querybuilder)** The Query Builder object, for chaining
|
||||||
|
|
||||||
|
## whereIsNotNull
|
||||||
|
|
||||||
|
Specify that a field IS NOT NULL
|
||||||
|
|
||||||
|
**Parameters**
|
||||||
|
|
||||||
|
- `field` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** The name so the field that is not to be null
|
||||||
|
|
||||||
|
Returns **[QueryBuilder](#querybuilder)** The Query Builder object, for chaining
|
||||||
|
|
||||||
|
## orWhereIsNull
|
||||||
|
|
||||||
|
Field is null prefixed with 'OR'
|
||||||
|
|
||||||
|
**Parameters**
|
||||||
|
|
||||||
|
- `field` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** The name of the field
|
||||||
|
|
||||||
|
Returns **[QueryBuilder](#querybuilder)** The Query Builder object, for chaining
|
||||||
|
|
||||||
|
## orWhereIsNotNull
|
||||||
|
|
||||||
|
Field is not null prefixed with 'OR'
|
||||||
|
|
||||||
|
**Parameters**
|
||||||
|
|
||||||
|
- `field` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** The name of the field
|
||||||
|
|
||||||
|
Returns **[QueryBuilder](#querybuilder)** The Query Builder object, for chaining
|
||||||
|
|
||||||
|
## whereIn
|
||||||
|
|
||||||
|
Set a 'where in' clause
|
||||||
|
|
||||||
|
**Parameters**
|
||||||
|
|
||||||
|
- `key` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** the field to search
|
||||||
|
- `values` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)** the array of items to search in
|
||||||
|
|
||||||
|
Returns **[QueryBuilder](#querybuilder)** The Query Builder object, for chaining
|
||||||
|
|
||||||
|
## orWhereIn
|
||||||
|
|
||||||
|
Set a 'or where in' clause
|
||||||
|
|
||||||
|
**Parameters**
|
||||||
|
|
||||||
|
- `key` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** the field to search
|
||||||
|
- `values` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)** the array of items to search in
|
||||||
|
|
||||||
|
Returns **[QueryBuilder](#querybuilder)** The Query Builder object, for chaining
|
||||||
|
|
||||||
|
## whereNotIn
|
||||||
|
|
||||||
|
Set a 'where not in' clause
|
||||||
|
|
||||||
|
**Parameters**
|
||||||
|
|
||||||
|
- `key` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** the field to search
|
||||||
|
- `values` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)** the array of items to search in
|
||||||
|
|
||||||
|
Returns **[QueryBuilder](#querybuilder)** The Query Builder object, for chaining
|
||||||
|
|
||||||
|
## orWhereNotIn
|
||||||
|
|
||||||
|
Set a 'or where not in' clause
|
||||||
|
|
||||||
|
**Parameters**
|
||||||
|
|
||||||
|
- `key` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** the field to search
|
||||||
|
- `values` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)** the array of items to search in
|
||||||
|
|
||||||
|
Returns **[QueryBuilder](#querybuilder)** The Query Builder object, for chaining
|
||||||
|
|
||||||
## set
|
## set
|
||||||
|
|
||||||
@ -431,8 +309,8 @@ Set values for insertion or updating
|
|||||||
|
|
||||||
**Parameters**
|
**Parameters**
|
||||||
|
|
||||||
- `key` **String or Object** The key or object to use
|
- `key` **([String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) \| [Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object))** The key or object to use
|
||||||
- `val` **[String]** The value if using a scalar key
|
- `val` **\[[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)]** The value if using a scalar key
|
||||||
|
|
||||||
**Examples**
|
**Examples**
|
||||||
|
|
||||||
@ -444,18 +322,132 @@ query.set('foo', 'bar'); // Set a key, value pair
|
|||||||
query.set({foo:'bar'}); // Set with an object
|
query.set({foo:'bar'}); // Set with an object
|
||||||
```
|
```
|
||||||
|
|
||||||
Returns **QueryBuilder** The Query Builder object, for chaining
|
Returns **[QueryBuilder](#querybuilder)** The Query Builder object, for chaining
|
||||||
|
|
||||||
## truncate
|
## join
|
||||||
|
|
||||||
Empties the selected database table
|
Add a join clause to the query
|
||||||
|
|
||||||
**Parameters**
|
**Parameters**
|
||||||
|
|
||||||
- `table` **string** the name of the table to truncate
|
- `table` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** The table you are joining
|
||||||
- `callback` **[function]** Optional callback
|
- `cond` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** The join condition.
|
||||||
|
- `type` **\[[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)]** The type of join, which defaults to inner (optional, default `'inner'`)
|
||||||
|
|
||||||
Returns **void or Promise** Returns a promise if no callback is supplied
|
Returns **[QueryBuilder](#querybuilder)** The Query Builder object, for chaining
|
||||||
|
|
||||||
|
## groupBy
|
||||||
|
|
||||||
|
Group the results by the selected field(s)
|
||||||
|
|
||||||
|
**Parameters**
|
||||||
|
|
||||||
|
- `field` **([String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) \| [Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array))** The name of the field to group by
|
||||||
|
|
||||||
|
Returns **[QueryBuilder](#querybuilder)** The Query Builder object, for chaining
|
||||||
|
|
||||||
|
## orderBy
|
||||||
|
|
||||||
|
Order the results by the selected field(s)
|
||||||
|
|
||||||
|
**Parameters**
|
||||||
|
|
||||||
|
- `field` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** The field(s) to order by
|
||||||
|
- `type` **\[[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)]** The order direction, ASC or DESC (optional, default `'ASC'`)
|
||||||
|
|
||||||
|
Returns **[QueryBuilder](#querybuilder)** The Query Builder object, for chaining
|
||||||
|
|
||||||
|
## limit
|
||||||
|
|
||||||
|
Put a limit on the query
|
||||||
|
|
||||||
|
**Parameters**
|
||||||
|
|
||||||
|
- `limit` **[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** The maximum number of rows to fetch
|
||||||
|
- `offset` **\[[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)]** The row number to start from
|
||||||
|
|
||||||
|
Returns **[QueryBuilder](#querybuilder)** The Query Builder object, for chaining
|
||||||
|
|
||||||
|
## groupStart
|
||||||
|
|
||||||
|
Adds an open paren to the current query for logical grouping
|
||||||
|
|
||||||
|
Returns **[QueryBuilder](#querybuilder)** The Query Builder object, for chaining
|
||||||
|
|
||||||
|
## orGroupStart
|
||||||
|
|
||||||
|
Adds an open paren to the current query for logical grouping,
|
||||||
|
prefixed with 'OR'
|
||||||
|
|
||||||
|
Returns **[QueryBuilder](#querybuilder)** The Query Builder object, for chaining
|
||||||
|
|
||||||
|
## orNotGroupStart
|
||||||
|
|
||||||
|
Adds an open paren to the current query for logical grouping,
|
||||||
|
prefixed with 'OR NOT'
|
||||||
|
|
||||||
|
Returns **[QueryBuilder](#querybuilder)** The Query Builder object, for chaining
|
||||||
|
|
||||||
|
## groupEnd
|
||||||
|
|
||||||
|
Ends a logical grouping started with one of the groupStart methods
|
||||||
|
|
||||||
|
Returns **[QueryBuilder](#querybuilder)** The Query Builder object, for chaining
|
||||||
|
|
||||||
|
## get
|
||||||
|
|
||||||
|
Get the results of the compiled query
|
||||||
|
|
||||||
|
**Parameters**
|
||||||
|
|
||||||
|
- `table` **\[[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)]** The table to select from
|
||||||
|
- `limit` **\[[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)]** A limit for the query
|
||||||
|
- `offset` **\[[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)]** An offset for the query
|
||||||
|
|
||||||
|
**Examples**
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
query.get('table_name').then(promiseCallback); // Get all the rows in the table
|
||||||
|
```
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
query.get('table_name', 5); // Get 5 rows from the table
|
||||||
|
```
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
query.get(); // Get the results of a query generated with other methods
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns **[Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[Result](#result)>** Promise containing the result of the query
|
||||||
|
|
||||||
|
## insert
|
||||||
|
|
||||||
|
Run the generated insert query
|
||||||
|
|
||||||
|
**Parameters**
|
||||||
|
|
||||||
|
- `table` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** The table to insert into
|
||||||
|
- `data` **\[[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)]** Data to insert, if not already added with the 'set' method
|
||||||
|
|
||||||
|
Returns **[Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[Result](#result)>** Promise containing the result of the query
|
||||||
|
|
||||||
|
## insertBatch
|
||||||
|
|
||||||
|
Insert multiple sets of rows at a time
|
||||||
|
|
||||||
|
**Parameters**
|
||||||
|
|
||||||
|
- `table` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** The table to insert into
|
||||||
|
- `data` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)** The array of objects containing data rows to insert
|
||||||
|
|
||||||
|
**Examples**
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
query.insertBatch('foo',[{id:1,val:'bar'},{id:2,val:'baz'}])
|
||||||
|
.then(promiseCallback);
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns **[Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[Result](#result)>** Promise containing the result of the query
|
||||||
|
|
||||||
## update
|
## update
|
||||||
|
|
||||||
@ -463,64 +455,65 @@ Run the generated update query
|
|||||||
|
|
||||||
**Parameters**
|
**Parameters**
|
||||||
|
|
||||||
- `table` **String** The table to insert into
|
- `table` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** The table to insert into
|
||||||
- `data` **[Object]** Data to insert, if not already added with the 'set' method
|
- `data` **\[[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)]** Data to insert, if not already added with the 'set' method
|
||||||
- `callback` **[Function]** Callback for handling response from the database
|
|
||||||
|
|
||||||
Returns **void or Promise** If no callback is passed, a promise is returned
|
Returns **[Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[Result](#result)>** Promise containing the result of the query
|
||||||
|
|
||||||
## where
|
## delete
|
||||||
|
|
||||||
Set a 'where' clause
|
Run the generated delete query
|
||||||
|
|
||||||
**Parameters**
|
**Parameters**
|
||||||
|
|
||||||
- `key` **String or Object** The name of the field and the comparision operator, or an object
|
- `table` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** The table to insert into
|
||||||
- `val` **[String or Number]** The value to compare if the value of key is a string
|
- `where` **\[[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)]** Where clause for delete statement
|
||||||
|
|
||||||
Returns **QueryBuilder** The Query Builder object, for chaining
|
Returns **[Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[Result](#result)>** Promise containing the result of the query
|
||||||
|
|
||||||
## whereIn
|
## getCompiledSelect
|
||||||
|
|
||||||
Set a 'where in' clause
|
Return generated select query SQL
|
||||||
|
|
||||||
**Parameters**
|
**Parameters**
|
||||||
|
|
||||||
- `key` **String** the field to search
|
- `table` **\[[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)]** the name of the table to retrieve from
|
||||||
- `values` **Array** the array of items to search in
|
- `reset` **\[[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)]** Whether to reset the query builder so another query can be built (optional, default `true`)
|
||||||
|
|
||||||
Returns **QueryBuilder** The Query Builder object, for chaining
|
Returns **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** The compiled sql statement
|
||||||
|
|
||||||
## whereIsNotNull
|
## getCompiledInsert
|
||||||
|
|
||||||
Specify that a field IS NOT NULL
|
Return generated insert query SQL
|
||||||
|
|
||||||
**Parameters**
|
**Parameters**
|
||||||
|
|
||||||
- `field` **String** The name so the field that is not to be null
|
- `table` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** the name of the table to insert into
|
||||||
|
- `reset` **\[[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)]** Whether to reset the query builder so another query can be built (optional, default `true`)
|
||||||
|
|
||||||
Returns **QueryBuilder** The Query Builder object, for chaining
|
Returns **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** The compiled sql statement
|
||||||
|
|
||||||
## whereIsNull
|
## getCompiledUpdate
|
||||||
|
|
||||||
Select a field that is Null
|
Return generated update query SQL
|
||||||
|
|
||||||
**Parameters**
|
**Parameters**
|
||||||
|
|
||||||
- `field` **String** The name of the field that has a NULL value
|
- `table` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** the name of the table to update
|
||||||
|
- `reset` **\[[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)]** Whether to reset the query builder so another query can be built (optional, default `true`)
|
||||||
|
|
||||||
Returns **QueryBuilder** The Query Builder object, for chaining
|
Returns **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** The compiled sql statement
|
||||||
|
|
||||||
## whereNotIn
|
## getCompiledDelete
|
||||||
|
|
||||||
Set a 'where not in' clause
|
Return generated delete query SQL
|
||||||
|
|
||||||
**Parameters**
|
**Parameters**
|
||||||
|
|
||||||
- `key` **String** the field to search
|
- `table` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** the name of the table to delete from
|
||||||
- `values` **Array** the array of items to search in
|
- `reset` **\[[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)]** Whether to reset the query builder so another query can be built (optional, default `true`)
|
||||||
|
|
||||||
Returns **QueryBuilder** The Query Builder object, for chaining
|
Returns **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** The compiled sql statement
|
||||||
|
|
||||||
# Result
|
# Result
|
||||||
|
|
||||||
@ -528,17 +521,17 @@ Query result object
|
|||||||
|
|
||||||
**Parameters**
|
**Parameters**
|
||||||
|
|
||||||
- `rows` **Array** the data rows of the result
|
- `rows` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)** the data rows of the result
|
||||||
- `columns` **Array** the column names in the result
|
- `columns` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)** the column names in the result
|
||||||
|
|
||||||
## columnCount
|
|
||||||
|
|
||||||
Get the number of columns returned by the query
|
|
||||||
|
|
||||||
Returns **Number** the number of columns in the result
|
|
||||||
|
|
||||||
## rowCount
|
## rowCount
|
||||||
|
|
||||||
Get the number of rows returned by the query
|
Get the number of rows returned by the query
|
||||||
|
|
||||||
Returns **Number** the number of rows in the result
|
Returns **[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** the number of rows in the result
|
||||||
|
|
||||||
|
## columnCount
|
||||||
|
|
||||||
|
Get the number of columns returned by the query
|
||||||
|
|
||||||
|
Returns **[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** the number of columns in the result
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
# 5.0.0
|
||||||
|
* Re-added firebird as a database
|
||||||
|
* Replaced all callback interfaces with promises
|
||||||
|
|
||||||
## 4.0.0
|
## 4.0.0
|
||||||
* Changed connection setup to just use a config object - the appropriate adapter object is created by the library.
|
* Changed connection setup to just use a config object - the appropriate adapter object is created by the library.
|
||||||
* Removed mysql adapter, as mysql2 is very similar and does proper prepared statements
|
* Removed mysql adapter, as mysql2 is very similar and does proper prepared statements
|
||||||
|
19
README.md
19
README.md
@ -9,6 +9,7 @@ A node query builder for various SQL databases, based on [CodeIgniter](http://ww
|
|||||||
|
|
||||||
### Supported databases
|
### Supported databases
|
||||||
|
|
||||||
|
* Firebird (via `node-firebird`)
|
||||||
* Mysql (via `mysql2`)
|
* Mysql (via `mysql2`)
|
||||||
* PostgreSQL (via `pg`)
|
* PostgreSQL (via `pg`)
|
||||||
* Sqlite (via `dblite`)
|
* Sqlite (via `dblite`)
|
||||||
@ -38,19 +39,9 @@ const nodeQuery = require('ci-node-query')({
|
|||||||
// Get the query builder
|
// Get the query builder
|
||||||
const query = nodeQuery.getQuery();
|
const query = nodeQuery.getQuery();
|
||||||
|
|
||||||
query.select('foo')
|
|
||||||
.from('bar')
|
|
||||||
.where('x', 3)
|
|
||||||
.orWhere({y: 2})
|
|
||||||
.join('baz', 'baz.boo = bar.foo', 'left')
|
|
||||||
.orderBy('x', 'DESC')
|
|
||||||
.limit(2, 3)
|
|
||||||
.get(function(err, result) {
|
|
||||||
// Handle Results Here
|
|
||||||
});
|
|
||||||
|
|
||||||
// As of version 3.1.0, you can also get promises
|
// As of version 3.1.0, you can also get promises
|
||||||
var queryPromise = query.select('foo')
|
// Version 5.0.0 removes all callback interfaces
|
||||||
|
const queryPromise = query.select('foo')
|
||||||
.from('bar')
|
.from('bar')
|
||||||
.where('x', 3)
|
.where('x', 3)
|
||||||
.orWhere({y: 2})
|
.orWhere({y: 2})
|
||||||
@ -93,5 +84,7 @@ As of version 2, `where` and `having` type methods parse the values passed to lo
|
|||||||
* Generated documentation is in the docs/ folder
|
* Generated documentation is in the docs/ folder
|
||||||
* The API is documented in [API.md](./API.md)
|
* The API is documented in [API.md](./API.md)
|
||||||
* The `tests/adapters` folder contains examples of how to set up a connection for the appropriate database library
|
* The `tests/adapters` folder contains examples of how to set up a connection for the appropriate database library
|
||||||
* The documentation generated for the latest dev build is also [Available](https://github.timshomepage.net/node-query/docs/)
|
* The documentation generated for the latest dev build is also [Available](https://github.timshomepage.net/node-query/docs/index.html)
|
||||||
|
|
||||||
|
[![js-happiness-style](https://cdn.rawgit.com/JedWatson/happiness/master/badge.svg)](https://github.com/JedWatson/happiness)
|
||||||
|
|
||||||
|
12
docs/assets/bass-addons.css
Normal file
12
docs/assets/bass-addons.css
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
.input {
|
||||||
|
font-family: inherit;
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: 2rem;
|
||||||
|
padding: .5rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
font-size: .875rem;
|
||||||
|
border-radius: 3px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
1037
docs/assets/bass.css
Executable file → Normal file
1037
docs/assets/bass.css
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
BIN
docs/assets/fonts/EOT/SourceCodePro-Bold.eot
Executable file
BIN
docs/assets/fonts/EOT/SourceCodePro-Bold.eot
Executable file
Binary file not shown.
BIN
docs/assets/fonts/EOT/SourceCodePro-Regular.eot
Executable file
BIN
docs/assets/fonts/EOT/SourceCodePro-Regular.eot
Executable file
Binary file not shown.
93
docs/assets/fonts/LICENSE.txt
Executable file
93
docs/assets/fonts/LICENSE.txt
Executable file
@ -0,0 +1,93 @@
|
|||||||
|
Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries.
|
||||||
|
|
||||||
|
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||||
|
|
||||||
|
This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
|
||||||
|
|
||||||
|
|
||||||
|
-----------------------------------------------------------
|
||||||
|
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||||
|
-----------------------------------------------------------
|
||||||
|
|
||||||
|
PREAMBLE
|
||||||
|
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||||
|
development of collaborative font projects, to support the font creation
|
||||||
|
efforts of academic and linguistic communities, and to provide a free and
|
||||||
|
open framework in which fonts may be shared and improved in partnership
|
||||||
|
with others.
|
||||||
|
|
||||||
|
The OFL allows the licensed fonts to be used, studied, modified and
|
||||||
|
redistributed freely as long as they are not sold by themselves. The
|
||||||
|
fonts, including any derivative works, can be bundled, embedded,
|
||||||
|
redistributed and/or sold with any software provided that any reserved
|
||||||
|
names are not used by derivative works. The fonts and derivatives,
|
||||||
|
however, cannot be released under any other type of license. The
|
||||||
|
requirement for fonts to remain under this license does not apply
|
||||||
|
to any document created using the fonts or their derivatives.
|
||||||
|
|
||||||
|
DEFINITIONS
|
||||||
|
"Font Software" refers to the set of files released by the Copyright
|
||||||
|
Holder(s) under this license and clearly marked as such. This may
|
||||||
|
include source files, build scripts and documentation.
|
||||||
|
|
||||||
|
"Reserved Font Name" refers to any names specified as such after the
|
||||||
|
copyright statement(s).
|
||||||
|
|
||||||
|
"Original Version" refers to the collection of Font Software components as
|
||||||
|
distributed by the Copyright Holder(s).
|
||||||
|
|
||||||
|
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||||
|
or substituting -- in part or in whole -- any of the components of the
|
||||||
|
Original Version, by changing formats or by porting the Font Software to a
|
||||||
|
new environment.
|
||||||
|
|
||||||
|
"Author" refers to any designer, engineer, programmer, technical
|
||||||
|
writer or other person who contributed to the Font Software.
|
||||||
|
|
||||||
|
PERMISSION & CONDITIONS
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||||
|
redistribute, and sell modified and unmodified copies of the Font
|
||||||
|
Software, subject to the following conditions:
|
||||||
|
|
||||||
|
1) Neither the Font Software nor any of its individual components,
|
||||||
|
in Original or Modified Versions, may be sold by itself.
|
||||||
|
|
||||||
|
2) Original or Modified Versions of the Font Software may be bundled,
|
||||||
|
redistributed and/or sold with any software, provided that each copy
|
||||||
|
contains the above copyright notice and this license. These can be
|
||||||
|
included either as stand-alone text files, human-readable headers or
|
||||||
|
in the appropriate machine-readable metadata fields within text or
|
||||||
|
binary files as long as those fields can be easily viewed by the user.
|
||||||
|
|
||||||
|
3) No Modified Version of the Font Software may use the Reserved Font
|
||||||
|
Name(s) unless explicit written permission is granted by the corresponding
|
||||||
|
Copyright Holder. This restriction only applies to the primary font name as
|
||||||
|
presented to the users.
|
||||||
|
|
||||||
|
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||||
|
Software shall not be used to promote, endorse or advertise any
|
||||||
|
Modified Version, except to acknowledge the contribution(s) of the
|
||||||
|
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||||
|
permission.
|
||||||
|
|
||||||
|
5) The Font Software, modified or unmodified, in part or in whole,
|
||||||
|
must be distributed entirely under this license, and must not be
|
||||||
|
distributed under any other license. The requirement for fonts to
|
||||||
|
remain under this license does not apply to any document created
|
||||||
|
using the Font Software.
|
||||||
|
|
||||||
|
TERMINATION
|
||||||
|
This license becomes null and void if any of the above conditions are
|
||||||
|
not met.
|
||||||
|
|
||||||
|
DISCLAIMER
|
||||||
|
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||||
|
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||||
|
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||||
|
OTHER DEALINGS IN THE FONT SOFTWARE.
|
BIN
docs/assets/fonts/OTF/SourceCodePro-Bold.otf
Executable file
BIN
docs/assets/fonts/OTF/SourceCodePro-Bold.otf
Executable file
Binary file not shown.
BIN
docs/assets/fonts/OTF/SourceCodePro-Regular.otf
Executable file
BIN
docs/assets/fonts/OTF/SourceCodePro-Regular.otf
Executable file
Binary file not shown.
BIN
docs/assets/fonts/TTF/SourceCodePro-Bold.ttf
Executable file
BIN
docs/assets/fonts/TTF/SourceCodePro-Bold.ttf
Executable file
Binary file not shown.
BIN
docs/assets/fonts/TTF/SourceCodePro-Regular.ttf
Executable file
BIN
docs/assets/fonts/TTF/SourceCodePro-Regular.ttf
Executable file
Binary file not shown.
BIN
docs/assets/fonts/WOFF/OTF/SourceCodePro-Bold.otf.woff
Executable file
BIN
docs/assets/fonts/WOFF/OTF/SourceCodePro-Bold.otf.woff
Executable file
Binary file not shown.
BIN
docs/assets/fonts/WOFF/OTF/SourceCodePro-Regular.otf.woff
Executable file
BIN
docs/assets/fonts/WOFF/OTF/SourceCodePro-Regular.otf.woff
Executable file
Binary file not shown.
BIN
docs/assets/fonts/WOFF/TTF/SourceCodePro-Bold.ttf.woff
Executable file
BIN
docs/assets/fonts/WOFF/TTF/SourceCodePro-Bold.ttf.woff
Executable file
Binary file not shown.
BIN
docs/assets/fonts/WOFF/TTF/SourceCodePro-Regular.ttf.woff
Executable file
BIN
docs/assets/fonts/WOFF/TTF/SourceCodePro-Regular.ttf.woff
Executable file
Binary file not shown.
BIN
docs/assets/fonts/WOFF2/OTF/SourceCodePro-Bold.otf.woff2
Executable file
BIN
docs/assets/fonts/WOFF2/OTF/SourceCodePro-Bold.otf.woff2
Executable file
Binary file not shown.
BIN
docs/assets/fonts/WOFF2/OTF/SourceCodePro-Regular.otf.woff2
Executable file
BIN
docs/assets/fonts/WOFF2/OTF/SourceCodePro-Regular.otf.woff2
Executable file
Binary file not shown.
BIN
docs/assets/fonts/WOFF2/TTF/SourceCodePro-Bold.ttf.woff2
Executable file
BIN
docs/assets/fonts/WOFF2/TTF/SourceCodePro-Bold.ttf.woff2
Executable file
Binary file not shown.
BIN
docs/assets/fonts/WOFF2/TTF/SourceCodePro-Regular.ttf.woff2
Executable file
BIN
docs/assets/fonts/WOFF2/TTF/SourceCodePro-Regular.ttf.woff2
Executable file
Binary file not shown.
23
docs/assets/fonts/source-code-pro.css
Executable file
23
docs/assets/fonts/source-code-pro.css
Executable file
@ -0,0 +1,23 @@
|
|||||||
|
@font-face{
|
||||||
|
font-family: 'Source Code Pro';
|
||||||
|
font-weight: 400;
|
||||||
|
font-style: normal;
|
||||||
|
font-stretch: normal;
|
||||||
|
src: url('EOT/SourceCodePro-Regular.eot') format('embedded-opentype'),
|
||||||
|
url('WOFF2/TTF/SourceCodePro-Regular.ttf.woff2') format('woff2'),
|
||||||
|
url('WOFF/OTF/SourceCodePro-Regular.otf.woff') format('woff'),
|
||||||
|
url('OTF/SourceCodePro-Regular.otf') format('opentype'),
|
||||||
|
url('TTF/SourceCodePro-Regular.ttf') format('truetype');
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face{
|
||||||
|
font-family: 'Source Code Pro';
|
||||||
|
font-weight: 700;
|
||||||
|
font-style: normal;
|
||||||
|
font-stretch: normal;
|
||||||
|
src: url('EOT/SourceCodePro-Bold.eot') format('embedded-opentype'),
|
||||||
|
url('WOFF2/TTF/SourceCodePro-Bold.ttf.woff2') format('woff2'),
|
||||||
|
url('WOFF/OTF/SourceCodePro-Bold.otf.woff') format('woff'),
|
||||||
|
url('OTF/SourceCodePro-Bold.otf') format('opentype'),
|
||||||
|
url('TTF/SourceCodePro-Bold.ttf') format('truetype');
|
||||||
|
}
|
@ -2,39 +2,107 @@
|
|||||||
|
|
||||||
// add anchor links to headers
|
// add anchor links to headers
|
||||||
anchors.options.placement = 'left';
|
anchors.options.placement = 'left';
|
||||||
anchors.add().remove('.no-anchor');
|
anchors.add('h3');
|
||||||
|
|
||||||
// Filter UI
|
// Filter UI
|
||||||
var tocElements = document.getElementById('toc').getElementsByTagName('a');
|
var tocElements = document.getElementById('toc')
|
||||||
document.getElementById('filter-input').addEventListener('keyup', function(e) {
|
.getElementsByTagName('li');
|
||||||
|
|
||||||
var i, element;
|
document.getElementById('filter-input')
|
||||||
|
.addEventListener('keyup', function (e) {
|
||||||
|
|
||||||
|
var i, element, children;
|
||||||
|
|
||||||
// enter key
|
// enter key
|
||||||
if (e.keyCode === 13) {
|
if (e.keyCode === 13) {
|
||||||
// go to the first displayed item in the toc
|
// go to the first displayed item in the toc
|
||||||
for (i = 0; i < tocElements.length; i++) {
|
for (i = 0; i < tocElements.length; i++) {
|
||||||
element = tocElements[i];
|
element = tocElements[i];
|
||||||
if (!element.classList.contains('hide')) {
|
if (!element.classList.contains('display-none')) {
|
||||||
location.replace(element.href);
|
location.replace(element.firstChild.href);
|
||||||
return e.preventDefault();
|
return e.preventDefault();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var match = function() { return true; },
|
var match = function () {
|
||||||
value = this.value.toLowerCase();
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
var value = this.value.toLowerCase();
|
||||||
|
|
||||||
if (!value.match(/^\s*$/)) {
|
if (!value.match(/^\s*$/)) {
|
||||||
match = function(text) { return text.toLowerCase().indexOf(value) !== -1; };
|
match = function (element) {
|
||||||
|
return element.firstChild.innerHTML.toLowerCase().indexOf(value) !== -1;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < tocElements.length; i++) {
|
for (i = 0; i < tocElements.length; i++) {
|
||||||
element = tocElements[i];
|
element = tocElements[i];
|
||||||
if (match(element.innerHTML)) {
|
children = Array.from(element.getElementsByTagName('li'));
|
||||||
element.classList.remove('hide');
|
if (match(element) || children.some(match)) {
|
||||||
|
element.classList.remove('display-none');
|
||||||
} else {
|
} else {
|
||||||
element.classList.add('hide');
|
element.classList.add('display-none');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var toggles = document.getElementsByClassName('toggle-step-sibling');
|
||||||
|
for (var i = 0; i < toggles.length; i++) {
|
||||||
|
toggles[i].addEventListener('click', toggleStepSibling);
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleStepSibling() {
|
||||||
|
var stepSibling = this.parentNode.parentNode.parentNode.getElementsByClassName('toggle-target')[0];
|
||||||
|
var klass = 'display-none';
|
||||||
|
if (stepSibling.classList.contains(klass)) {
|
||||||
|
stepSibling.classList.remove(klass);
|
||||||
|
stepSibling.innerHTML = '▾';
|
||||||
|
} else {
|
||||||
|
stepSibling.classList.add(klass);
|
||||||
|
stepSibling.innerHTML = '▸';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var items = document.getElementsByClassName('toggle-sibling');
|
||||||
|
for (var j = 0; j < items.length; j++) {
|
||||||
|
items[j].addEventListener('click', toggleSibling);
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleSibling() {
|
||||||
|
var stepSibling = this.parentNode.getElementsByClassName('toggle-target')[0];
|
||||||
|
var icon = this.getElementsByClassName('icon')[0];
|
||||||
|
var klass = 'display-none';
|
||||||
|
if (stepSibling.classList.contains(klass)) {
|
||||||
|
stepSibling.classList.remove(klass);
|
||||||
|
icon.innerHTML = '▾';
|
||||||
|
} else {
|
||||||
|
stepSibling.classList.add(klass);
|
||||||
|
icon.innerHTML = '▸';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function showHashTarget(targetId) {
|
||||||
|
var hashTarget = document.getElementById(targetId);
|
||||||
|
// new target is hidden
|
||||||
|
if (hashTarget && hashTarget.offsetHeight === 0 &&
|
||||||
|
hashTarget.parentNode.parentNode.classList.contains('display-none')) {
|
||||||
|
hashTarget.parentNode.parentNode.classList.remove('display-none');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener('hashchange', function() {
|
||||||
|
showHashTarget(location.hash.substring(1));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
showHashTarget(location.hash.substring(1));
|
||||||
|
|
||||||
|
var toclinks = document.getElementsByClassName('pre-open');
|
||||||
|
for (var k = 0; k < toclinks.length; k++) {
|
||||||
|
toclinks[k].addEventListener('mousedown', preOpen, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
function preOpen() {
|
||||||
|
showHashTarget(this.hash.substring(1));
|
||||||
|
}
|
||||||
|
@ -1,68 +1,55 @@
|
|||||||
.documentation a {
|
.documentation {
|
||||||
|
font-family: Helvetica, sans-serif;
|
||||||
|
color: #666;
|
||||||
|
line-height: 1.5;
|
||||||
|
background: #f5f5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.black {
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-white {
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
margin: 20px 0 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.documentation h3 {
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.border-bottom {
|
||||||
|
border-color: #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
color: #1184CE;
|
color: #1184CE;
|
||||||
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.documentation .suppress-p-margin p {
|
.documentation a[href]:hover {
|
||||||
margin:0;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
.force-inline, .force-inline p {
|
a:hover {
|
||||||
display: inline;
|
cursor: pointer;
|
||||||
color: #222;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.container-small {
|
.py1-ul li {
|
||||||
max-width: 58rem;
|
padding: 5px 0;
|
||||||
margin-left: auto;
|
|
||||||
margin-right: auto;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.max-height-100 {
|
.max-height-100 {
|
||||||
max-height: 100%;
|
max-height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fade {
|
|
||||||
opacity:0.50;
|
|
||||||
}
|
|
||||||
|
|
||||||
.button-indent {
|
|
||||||
padding: .25rem 1.5rem;
|
|
||||||
font-size: 90%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.section-indent {
|
|
||||||
border-left: 2px solid #eee;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bg-cloudy {
|
|
||||||
background: #fafafa;
|
|
||||||
}
|
|
||||||
|
|
||||||
.force-inline * {
|
|
||||||
display:inline;
|
|
||||||
}
|
|
||||||
|
|
||||||
section:target h3 {
|
section:target h3 {
|
||||||
font-weight:700;
|
font-weight:700;
|
||||||
}
|
}
|
||||||
|
|
||||||
.documentation,
|
|
||||||
.documentation h1,
|
|
||||||
.documentation h2,
|
|
||||||
.documentation h3,
|
|
||||||
.documentation h4,
|
|
||||||
.documentation h5,
|
|
||||||
.documentation h6 {
|
|
||||||
font-family: 'Source Sans Pro', Helvetica, sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
.documentation pre,
|
|
||||||
.documentation code,
|
|
||||||
.documentation samp {
|
|
||||||
font-family: 'Source Code Pro', monospace;
|
|
||||||
font-size: 90%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.documentation td,
|
.documentation td,
|
||||||
.documentation th {
|
.documentation th {
|
||||||
padding: .25rem .25rem;
|
padding: .25rem .25rem;
|
||||||
@ -75,12 +62,9 @@ h4:hover .anchorjs-link {
|
|||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.collapsible .collapser {
|
.fix-3 {
|
||||||
display:none;
|
width: 25%;
|
||||||
}
|
max-width: 244px;
|
||||||
|
|
||||||
.collapsible:target .collapser {
|
|
||||||
display: block;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.fix-3 {
|
.fix-3 {
|
||||||
@ -93,3 +77,60 @@ h4:hover .anchorjs-link {
|
|||||||
margin-left: 25%;
|
margin-left: 25%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.pre, pre, code, .code {
|
||||||
|
font-family: Source Code Pro,Menlo,Consolas,Liberation Mono,monospace;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fill-light {
|
||||||
|
background: #F9F9F9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.width2 {
|
||||||
|
width: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input {
|
||||||
|
font-family: inherit;
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: 2rem;
|
||||||
|
padding: .5rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
font-size: .875rem;
|
||||||
|
border-radius: 3px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
|
||||||
|
.prose table th,
|
||||||
|
.prose table td {
|
||||||
|
text-align: left;
|
||||||
|
padding:8px;
|
||||||
|
border:1px solid #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.prose table th:nth-child(1) { border-right: none; }
|
||||||
|
.prose table th:nth-child(2) { border-left: none; }
|
||||||
|
|
||||||
|
.prose table {
|
||||||
|
border:1px solid #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.prose-big {
|
||||||
|
font-size: 18px;
|
||||||
|
line-height: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quiet {
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.minishadow {
|
||||||
|
box-shadow: 2px 2px 10px #f3f3f3;
|
||||||
|
}
|
||||||
|
5572
docs/index.html
5572
docs/index.html
File diff suppressed because it is too large
Load Diff
87
gulpfile.js
87
gulpfile.js
@ -1,87 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
const documentation = require('gulp-documentation'),
|
|
||||||
eslint = require('gulp-eslint'),
|
|
||||||
gulp = require('gulp'),
|
|
||||||
istanbul = require('gulp-istanbul'),
|
|
||||||
jscs = require('gulp-jscs'),
|
|
||||||
mocha = require('gulp-mocha'),
|
|
||||||
pipe = require('gulp-pipe'),
|
|
||||||
sloc = require('gulp-sloc');
|
|
||||||
|
|
||||||
const SRC_FILES = ['lib/**/*.js'];
|
|
||||||
const TEST_FILES = [
|
|
||||||
'test/*_test.js',
|
|
||||||
'test/adapters/*_test.js'
|
|
||||||
];
|
|
||||||
|
|
||||||
const MOCHA_OPTIONS = {
|
|
||||||
ui: 'tdd',
|
|
||||||
bail: true,
|
|
||||||
reporter: 'dot',
|
|
||||||
timeout: 10000,
|
|
||||||
};
|
|
||||||
|
|
||||||
gulp.task('lint', () => {
|
|
||||||
pipe(gulp.src(SRC_FILES), [
|
|
||||||
eslint(),
|
|
||||||
eslint.format(),
|
|
||||||
eslint.failAfterError()
|
|
||||||
]);
|
|
||||||
pipe(gulp.src(SRC_FILES), [
|
|
||||||
jscs(),
|
|
||||||
jscs.reporter()
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
|
|
||||||
gulp.task('lint-tests', ['lint'], () => {
|
|
||||||
pipe(gulp.src(['test/**/*.js']), [
|
|
||||||
eslint(),
|
|
||||||
eslint.format(),
|
|
||||||
eslint.failAfterError()
|
|
||||||
]);
|
|
||||||
pipe(gulp.src(['test/**/*.js']), [
|
|
||||||
jscs(),
|
|
||||||
jscs.reporter()
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
|
|
||||||
gulp.task('sloc', () => gulp.src(SRC_FILES).pipe(sloc()));
|
|
||||||
gulp.task('test-sloc', () => gulp.src(TEST_FILES).pipe(sloc()));
|
|
||||||
|
|
||||||
gulp.task('docs', () => {
|
|
||||||
gulp.src(['lib/*.js'])
|
|
||||||
.pipe(documentation({format: 'html'}))
|
|
||||||
.pipe(gulp.dest('docs'));
|
|
||||||
gulp.src(['lib/*.js'])
|
|
||||||
.pipe(documentation({format: 'md'}))
|
|
||||||
.pipe(gulp.dest('.'));
|
|
||||||
});
|
|
||||||
|
|
||||||
gulp.task('mocha', ['lint-tests', 'sloc'], () => {
|
|
||||||
return gulp.src(TEST_FILES)
|
|
||||||
.pipe(mocha(MOCHA_OPTIONS))
|
|
||||||
.once('error', () => {
|
|
||||||
process.exit(1);
|
|
||||||
})
|
|
||||||
.once('end', () => {
|
|
||||||
process.exit();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
gulp.task('test', ['test-sloc', 'lint-tests'], function(cb) {
|
|
||||||
return pipe(gulp.src(SRC_FILES), [
|
|
||||||
istanbul(),
|
|
||||||
istanbul.hookRequire()
|
|
||||||
]).on('finish', () => {
|
|
||||||
pipe(gulp.src(TEST_FILES), [
|
|
||||||
mocha(MOCHA_OPTIONS),
|
|
||||||
istanbul.writeReports({
|
|
||||||
dir: './coverage',
|
|
||||||
reporters: ['clover', 'lcov', 'lcovonly', 'html', 'text'],
|
|
||||||
}),
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
gulp.task('default', ['lint', 'sloc', 'docs', 'test']);
|
|
@ -1,20 +1,19 @@
|
|||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class that wraps database connection libraries
|
* Class that wraps database connection libraries
|
||||||
*
|
*
|
||||||
* @private
|
* @private
|
||||||
* @param {Object} instance - The connection object
|
* @param {Promise} instance - The connection object
|
||||||
*/
|
*/
|
||||||
class Adapter {
|
class Adapter {
|
||||||
/**
|
/**
|
||||||
* Invoke an adapter
|
* Invoke an adapter
|
||||||
*
|
*
|
||||||
* @constructor
|
* @constructor
|
||||||
* @param {Object} instance - The connection object
|
* @param {Promise} instance - Promise holding connection object
|
||||||
*/
|
*/
|
||||||
constructor(instance) {
|
constructor (instance) {
|
||||||
this.instance = instance;
|
this.instance = instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23,10 +22,9 @@ class Adapter {
|
|||||||
*
|
*
|
||||||
* @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
|
* @return {Promise} - returns a promise if no callback is passed
|
||||||
* @return {void|Promise} - returns a promise if no callback is passed
|
|
||||||
*/
|
*/
|
||||||
execute(/*sql, params, callback*/) {
|
execute (sql, params) {
|
||||||
throw new Error('Correct adapter not defined for query execution');
|
throw new Error('Correct adapter not defined for query execution');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,7 +34,7 @@ class Adapter {
|
|||||||
* @param {*} originalResult - the original result object from the driver
|
* @param {*} originalResult - the original result object from the driver
|
||||||
* @return {Result} - the new result object
|
* @return {Result} - the new result object
|
||||||
*/
|
*/
|
||||||
transformResult(originalResult) {
|
transformResult (originalResult) {
|
||||||
throw new Error('Result transformer method not defined for current adapter');
|
throw new Error('Result transformer method not defined for current adapter');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,8 +42,8 @@ class Adapter {
|
|||||||
* Close the current database connection
|
* Close the current database connection
|
||||||
* @return {void}
|
* @return {void}
|
||||||
*/
|
*/
|
||||||
close() {
|
close () {
|
||||||
this.instance.end();
|
this.instance.then(conn => conn.end());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ const helpers = require('./helpers');
|
|||||||
*
|
*
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
let Driver = {
|
const Driver = {
|
||||||
identifierStartChar: '"',
|
identifierStartChar: '"',
|
||||||
identifierEndChar: '"',
|
identifierEndChar: '"',
|
||||||
tablePrefix: null,
|
tablePrefix: null,
|
||||||
@ -20,9 +20,9 @@ let Driver = {
|
|||||||
* @return {String} - The quoted sql fragment
|
* @return {String} - The quoted sql fragment
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
_quote(str) {
|
_quote (str) {
|
||||||
return (helpers.isString(str)
|
return (helpers.isString(str) &&
|
||||||
&& ! (str.startsWith(Driver.identifierStartChar) || str.endsWith(Driver.identifierEndChar))
|
!(str.startsWith(Driver.identifierStartChar) || str.endsWith(Driver.identifierEndChar))
|
||||||
)
|
)
|
||||||
? `${Driver.identifierStartChar}${str}${Driver.identifierEndChar}`
|
? `${Driver.identifierStartChar}${str}${Driver.identifierEndChar}`
|
||||||
: str;
|
: str;
|
||||||
@ -30,17 +30,16 @@ let Driver = {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the limit clause
|
* Set the limit clause
|
||||||
|
* @private
|
||||||
* @param {String} sql - SQL statement to modify
|
* @param {String} sql - SQL statement to modify
|
||||||
* @param {Number} limit - Maximum number of rows to fetch
|
* @param {Number} limit - Maximum number of rows to fetch
|
||||||
* @param {Number} [offset] - Number of rows to skip
|
* @param {Number} [offset] - Number of rows to skip
|
||||||
* @return {String} - Modified SQL statement
|
* @return {String} - Modified SQL statement
|
||||||
*/
|
*/
|
||||||
limit(sql, limit, offset) {
|
limit (sql, limit, offset) {
|
||||||
sql += ` LIMIT ${limit}`;
|
sql += ` LIMIT ${limit}`;
|
||||||
|
|
||||||
if (helpers.isNumber(offset))
|
if (helpers.isNumber(offset)) {
|
||||||
{
|
|
||||||
sql += ` OFFSET ${offset}`;
|
sql += ` OFFSET ${offset}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,10 +49,11 @@ let Driver = {
|
|||||||
/**
|
/**
|
||||||
* Quote database table name, and set prefix
|
* Quote database table name, and set prefix
|
||||||
*
|
*
|
||||||
|
* @private
|
||||||
* @param {String} table - Table name to quote
|
* @param {String} table - Table name to quote
|
||||||
* @return {String} - Quoted table name
|
* @return {String} - Quoted table name
|
||||||
*/
|
*/
|
||||||
quoteTable(table) {
|
quoteTable (table) {
|
||||||
// Quote after prefix
|
// Quote after prefix
|
||||||
return Driver.quoteIdentifiers(table);
|
return Driver.quoteIdentifiers(table);
|
||||||
},
|
},
|
||||||
@ -61,25 +61,24 @@ let Driver = {
|
|||||||
/**
|
/**
|
||||||
* Use the driver's escape character to quote identifiers
|
* Use the driver's escape character to quote identifiers
|
||||||
*
|
*
|
||||||
|
* @private
|
||||||
* @param {String|Array} str - String or array of strings to quote identifiers
|
* @param {String|Array} str - String or array of strings to quote identifiers
|
||||||
* @return {String|Array} - Quoted identifier(s)
|
* @return {String|Array} - Quoted identifier(s)
|
||||||
*/
|
*/
|
||||||
quoteIdentifiers(str) {
|
quoteIdentifiers (str) {
|
||||||
let hiers, raw;
|
let hiers, raw;
|
||||||
let pattern = new RegExp(
|
let pattern = new RegExp(
|
||||||
`${Driver.identifierStartChar}(`
|
`${Driver.identifierStartChar}(` +
|
||||||
+ '([a-zA-Z0-9_]+)' + '(\((.*?)\))'
|
'([a-zA-Z0-9_]+)' + '(((.*?)))' +
|
||||||
+ `)${Driver.identifierEndChar}`, 'ig');
|
`)${Driver.identifierEndChar}`, 'ig');
|
||||||
|
|
||||||
// Recurse for arrays of identifiiers
|
// Recurse for arrays of identifiiers
|
||||||
if (Array.isArray(str))
|
if (Array.isArray(str)) {
|
||||||
{
|
|
||||||
return str.map(Driver.quoteIdentifiers);
|
return str.map(Driver.quoteIdentifiers);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle commas
|
// Handle commas
|
||||||
if (str.includes(','))
|
if (str.includes(',')) {
|
||||||
{
|
|
||||||
let parts = str.split(',').map(helpers.stringTrim);
|
let parts = str.split(',').map(helpers.stringTrim);
|
||||||
str = parts.map(Driver.quoteIdentifiers).join(',');
|
str = parts.map(Driver.quoteIdentifiers).join(',');
|
||||||
}
|
}
|
||||||
@ -89,8 +88,7 @@ let Driver = {
|
|||||||
raw = hiers.join('.');
|
raw = hiers.join('.');
|
||||||
|
|
||||||
// Fix functions
|
// Fix functions
|
||||||
if (raw.includes('(') && raw.includes(')'))
|
if (raw.includes('(') && raw.includes(')')) {
|
||||||
{
|
|
||||||
let funcs = pattern.exec(raw);
|
let funcs = pattern.exec(raw);
|
||||||
|
|
||||||
// Unquote the function
|
// Unquote the function
|
||||||
@ -107,10 +105,11 @@ let Driver = {
|
|||||||
/**
|
/**
|
||||||
* Generate SQL to truncate the passed table
|
* Generate SQL to truncate the passed table
|
||||||
*
|
*
|
||||||
|
* @private
|
||||||
* @param {String} table - Table to truncate
|
* @param {String} table - Table to truncate
|
||||||
* @return {String} - Truncation SQL
|
* @return {String} - Truncation SQL
|
||||||
*/
|
*/
|
||||||
truncate(table) {
|
truncate (table) {
|
||||||
let sql = (Driver.hasTruncate)
|
let sql = (Driver.hasTruncate)
|
||||||
? 'TRUNCATE '
|
? 'TRUNCATE '
|
||||||
: 'DELETE FROM ';
|
: 'DELETE FROM ';
|
||||||
@ -123,17 +122,15 @@ let Driver = {
|
|||||||
/**
|
/**
|
||||||
* Generate SQL to insert a group of rows
|
* Generate SQL to insert a group of rows
|
||||||
*
|
*
|
||||||
|
* @private
|
||||||
* @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} - Query and data to insert
|
* @return {String} - Query and data to insert
|
||||||
*/
|
*/
|
||||||
insertBatch(table, data) {
|
insertBatch (table, data) {
|
||||||
let vals = [],
|
const vals = [];
|
||||||
fields = Object.keys(data[0]),
|
const fields = Object.keys(data[0]);
|
||||||
sql = '',
|
let sql = '';
|
||||||
params = [],
|
|
||||||
paramString = '',
|
|
||||||
paramList = [];
|
|
||||||
|
|
||||||
// Get the data values to insert, so they can
|
// Get the data values to insert, so they can
|
||||||
// be parameterized
|
// be parameterized
|
||||||
@ -150,17 +147,17 @@ let Driver = {
|
|||||||
sql += `INSERT INTO ${table} (${Driver.quoteIdentifiers(fields).join(',')}) VALUES `;
|
sql += `INSERT INTO ${table} (${Driver.quoteIdentifiers(fields).join(',')}) VALUES `;
|
||||||
|
|
||||||
// Create placeholder groups
|
// Create placeholder groups
|
||||||
params = Array(fields.length).fill('?');
|
let params = Array(fields.length).fill('?');
|
||||||
paramString = `(${params.join(',')})`;
|
let paramString = `(${params.join(',')})`;
|
||||||
paramList = Array(data.length).fill(paramString);
|
let paramList = Array(data.length).fill(paramString);
|
||||||
|
|
||||||
sql += paramList.join(',');
|
sql += paramList.join(',');
|
||||||
|
|
||||||
return {
|
return {
|
||||||
sql: sql,
|
sql: sql,
|
||||||
values: vals,
|
values: vals
|
||||||
};
|
};
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = Driver;
|
module.exports = Driver;
|
@ -1,6 +1,5 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const helpers = require('./helpers');
|
|
||||||
const QueryBuilder = require('./QueryBuilder');
|
const QueryBuilder = require('./QueryBuilder');
|
||||||
|
|
||||||
// Map config driver name to code class name
|
// Map config driver name to code class name
|
||||||
@ -15,6 +14,8 @@ const dbDriverMap = new Map([
|
|||||||
['pg', 'Pg'],
|
['pg', 'Pg'],
|
||||||
['sqlite3', 'Sqlite'],
|
['sqlite3', 'Sqlite'],
|
||||||
['sqlite', 'Sqlite'],
|
['sqlite', 'Sqlite'],
|
||||||
|
['sqlserver', 'MSSQLServer'],
|
||||||
|
['mssql', 'MSSQLServer']
|
||||||
]);
|
]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -23,7 +24,6 @@ const dbDriverMap = new Map([
|
|||||||
* @param {object} config - connection parameters
|
* @param {object} config - connection parameters
|
||||||
*/
|
*/
|
||||||
class NodeQuery {
|
class NodeQuery {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
@ -42,20 +42,20 @@ class NodeQuery {
|
|||||||
* connection: ':memory:'
|
* connection: ':memory:'
|
||||||
* });
|
* });
|
||||||
*/
|
*/
|
||||||
constructor(config) {
|
constructor (config) {
|
||||||
this.instance = null;
|
this.instance = null;
|
||||||
|
|
||||||
if (config != null) {
|
if (config !== undefined) {
|
||||||
let drivername = dbDriverMap.get(config.driver);
|
let drivername = dbDriverMap.get(config.driver);
|
||||||
|
|
||||||
if (! drivername) {
|
if (!drivername) {
|
||||||
throw new Error(`Selected driver (${config.driver}) does not exist!`);
|
throw new Error(`Selected driver (${config.driver}) does not exist!`);
|
||||||
}
|
}
|
||||||
|
|
||||||
let driver = require(`./drivers/${drivername}`);
|
const driver = require(`./drivers/${drivername}`);
|
||||||
let $adapter = require(`./adapters/${drivername}`);
|
const Adapter = require(`./adapters/${drivername}`);
|
||||||
|
|
||||||
let adapter = new $adapter(config.connection);
|
let adapter = Adapter(config);
|
||||||
this.instance = new QueryBuilder(driver, adapter);
|
this.instance = new QueryBuilder(driver, adapter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -65,7 +65,7 @@ class NodeQuery {
|
|||||||
*
|
*
|
||||||
* @return {QueryBuilder} - The Query Builder object
|
* @return {QueryBuilder} - The Query Builder object
|
||||||
*/
|
*/
|
||||||
getQuery() {
|
getQuery () {
|
||||||
if (this.instance == null) {
|
if (this.instance == null) {
|
||||||
throw new Error('No Query Builder instance to return');
|
throw new Error('No Query Builder instance to return');
|
||||||
}
|
}
|
||||||
@ -74,4 +74,4 @@ class NodeQuery {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = (config => new NodeQuery(config));
|
module.exports = config => new NodeQuery(config);
|
||||||
|
@ -1,309 +1,16 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const getArgs = require('getargs');
|
|
||||||
const helpers = require('./helpers');
|
const helpers = require('./helpers');
|
||||||
const State = require('./State');
|
const QueryBuilderBase = require('./QueryBuilderBase');
|
||||||
const QueryParser = require('./QueryParser');
|
|
||||||
|
|
||||||
class QueryBuilderBase {
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @constructor
|
|
||||||
* @param {Driver} Driver - The syntax driver for the database
|
|
||||||
* @param {Adapter} Adapter - The database module adapter for running queries
|
|
||||||
*/
|
|
||||||
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
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @param {String} type - Type of SQL query
|
|
||||||
* @param {String} table - The table to run the query on
|
|
||||||
* @return {String} - The compiled sql
|
|
||||||
*/
|
|
||||||
_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 (${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
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @param {String} conjunction - linking keyword for the clause
|
|
||||||
* @param {String} string - pre-compiled sql fragment
|
|
||||||
* @param {String} type - type of sql clause
|
|
||||||
* @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
|
|
||||||
* @return {Array} - modified state array
|
|
||||||
*/
|
|
||||||
_mixedSet(/* $letName, $valType, $key, [$val] */) {
|
|
||||||
const argPattern = '$letName:string, $valType:string, $key:object|string|number, [$val]';
|
|
||||||
let args = getArgs(argPattern, 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 = 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset the state so another query can be built
|
|
||||||
this._resetState();
|
|
||||||
|
|
||||||
// Pass the sql and values to the adapter to run on the database
|
|
||||||
if (callback) {
|
|
||||||
return this.query(sql, vals, callback);
|
|
||||||
} else {
|
|
||||||
return this.query(sql, vals);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_getCompile(type, table, reset) {
|
|
||||||
reset = reset || false;
|
|
||||||
|
|
||||||
let sql = this._compile(type, table);
|
|
||||||
|
|
||||||
if (reset) {
|
|
||||||
this._resetState();
|
|
||||||
}
|
|
||||||
|
|
||||||
return sql;
|
|
||||||
}
|
|
||||||
|
|
||||||
_resetState() {
|
|
||||||
this.state = new State();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main object that builds SQL queries.
|
* Main object that builds SQL queries.
|
||||||
*
|
*
|
||||||
* @param {Driver} Driver - The syntax driver for the database
|
* @param {Driver} Driver - The syntax driver for the database
|
||||||
* @param {Adapter} Adapter - The database module adapter for running queries
|
* @param {Adapter} Adapter - The database module adapter for running queries
|
||||||
|
* @extends QueryBuilderBase
|
||||||
*/
|
*/
|
||||||
class QueryBuilder extends QueryBuilderBase {
|
class QueryBuilder extends QueryBuilderBase {
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @constructor
|
|
||||||
* @param {Driver} Driver - The syntax driver for the database
|
|
||||||
* @param {Adapter} Adapter - The database module adapter for running queries
|
|
||||||
*/
|
|
||||||
constructor(Driver, Adapter) {
|
|
||||||
super(Driver, Adapter);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// ! Miscellaneous Methods
|
// ! Miscellaneous Methods
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@ -312,12 +19,11 @@ class QueryBuilder extends QueryBuilderBase {
|
|||||||
* Run an arbitrary sql query. Run as a prepared statement.
|
* Run an arbitrary sql query. Run as a prepared statement.
|
||||||
*
|
*
|
||||||
* @param {string} sql - The sql to execute
|
* @param {string} sql - The sql to execute
|
||||||
* @param {array} [params] - The query parameters
|
* @param {Array} [params] - The query parameters
|
||||||
* @param {function} [callback] - Optional callback
|
* @return {Promise} - Promise with result of query
|
||||||
* @return {void|Promise} - Returns a promise if no callback is supplied
|
|
||||||
*/
|
*/
|
||||||
query(/*sql:string, [params]:array, [callback]:function*/) {
|
query (sql, params) {
|
||||||
return this.adapter.execute.apply(this.adapter, arguments);
|
return this.adapter.execute(sql, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -325,7 +31,7 @@ class QueryBuilder extends QueryBuilderBase {
|
|||||||
*
|
*
|
||||||
* @return {void}
|
* @return {void}
|
||||||
*/
|
*/
|
||||||
resetQuery() {
|
resetQuery () {
|
||||||
this._resetState();
|
this._resetState();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -335,7 +41,7 @@ class QueryBuilder extends QueryBuilderBase {
|
|||||||
* @private
|
* @private
|
||||||
* @return {Object} - The State object
|
* @return {Object} - The State object
|
||||||
*/
|
*/
|
||||||
getState() {
|
getState () {
|
||||||
return this.state;
|
return this.state;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -343,15 +49,10 @@ class QueryBuilder extends QueryBuilderBase {
|
|||||||
* Empties the selected database table
|
* Empties the selected database table
|
||||||
*
|
*
|
||||||
* @param {string} table - the name of the table to truncate
|
* @param {string} table - the name of the table to truncate
|
||||||
* @param {function} [callback] - Optional callback
|
|
||||||
* @return {void|Promise} - Returns a promise if no callback is supplied
|
* @return {void|Promise} - Returns a promise if no callback is supplied
|
||||||
*/
|
*/
|
||||||
truncate(/*table:string, [callback]:function*/) {
|
truncate (table) {
|
||||||
getArgs('table:string, [callback]:function', arguments);
|
return this.query(this.driver.truncate(table));
|
||||||
let args = [].slice.apply(arguments);
|
|
||||||
let sql = this.driver.truncate(args.shift());
|
|
||||||
args.unshift(sql);
|
|
||||||
return this.query.apply(this, args);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -359,7 +60,7 @@ class QueryBuilder extends QueryBuilderBase {
|
|||||||
*
|
*
|
||||||
* @return {void}
|
* @return {void}
|
||||||
*/
|
*/
|
||||||
end() {
|
end () {
|
||||||
this.adapter.close();
|
this.adapter.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -375,8 +76,7 @@ class QueryBuilder extends QueryBuilderBase {
|
|||||||
* @example query.select(['foo', 'bar']); // Select multiple fileds with an array
|
* @example query.select(['foo', 'bar']); // Select multiple fileds with an array
|
||||||
* @return {QueryBuilder} - The Query Builder object, for chaining
|
* @return {QueryBuilder} - The Query Builder object, for chaining
|
||||||
*/
|
*/
|
||||||
select(fields) {
|
select (fields) {
|
||||||
|
|
||||||
// Split/trim fields by comma
|
// Split/trim fields by comma
|
||||||
fields = (Array.isArray(fields))
|
fields = (Array.isArray(fields))
|
||||||
? fields
|
? fields
|
||||||
@ -384,7 +84,7 @@ class QueryBuilder extends QueryBuilderBase {
|
|||||||
|
|
||||||
// Split on 'As'
|
// Split on 'As'
|
||||||
fields.forEach((field, index) => {
|
fields.forEach((field, index) => {
|
||||||
if (field.match(/as/i)) {
|
if (/as/i.test(field)) {
|
||||||
fields[index] = field.split(/ as /i).map(helpers.stringTrim);
|
fields[index] = field.split(/ as /i).map(helpers.stringTrim);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -411,7 +111,7 @@ class QueryBuilder extends QueryBuilderBase {
|
|||||||
* @example query.from('tableName t'); // Select the table with an alias
|
* @example query.from('tableName t'); // Select the table with an alias
|
||||||
* @return {QueryBuilder} - The Query Builder object, for chaining
|
* @return {QueryBuilder} - The Query Builder object, for chaining
|
||||||
*/
|
*/
|
||||||
from(tableName) {
|
from (tableName) {
|
||||||
// Split identifiers on spaces
|
// Split identifiers on spaces
|
||||||
let identArray = tableName.trim().split(' ').map(helpers.stringTrim);
|
let identArray = tableName.trim().split(' ').map(helpers.stringTrim);
|
||||||
|
|
||||||
@ -433,7 +133,7 @@ class QueryBuilder extends QueryBuilderBase {
|
|||||||
* @param {String} [pos=both] - The placement of the wildcard character(s): before, after, or both
|
* @param {String} [pos=both] - The placement of the wildcard character(s): before, after, or both
|
||||||
* @return {QueryBuilder} - The Query Builder object, for chaining
|
* @return {QueryBuilder} - The Query Builder object, for chaining
|
||||||
*/
|
*/
|
||||||
like(field, val, pos) {
|
like (field, val, pos) {
|
||||||
this._like(field, val, pos, ' LIKE ', 'AND');
|
this._like(field, val, pos, ' LIKE ', 'AND');
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -446,7 +146,7 @@ class QueryBuilder extends QueryBuilderBase {
|
|||||||
* @param {String} [pos=both] - The placement of the wildcard character(s): before, after, or both
|
* @param {String} [pos=both] - The placement of the wildcard character(s): before, after, or both
|
||||||
* @return {QueryBuilder} - The Query Builder object, for chaining
|
* @return {QueryBuilder} - The Query Builder object, for chaining
|
||||||
*/
|
*/
|
||||||
notLike(field, val, pos) {
|
notLike (field, val, pos) {
|
||||||
this._like(field, val, pos, ' NOT LIKE ', 'AND');
|
this._like(field, val, pos, ' NOT LIKE ', 'AND');
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -459,7 +159,7 @@ class QueryBuilder extends QueryBuilderBase {
|
|||||||
* @param {String} [pos=both] - The placement of the wildcard character(s): before, after, or both
|
* @param {String} [pos=both] - The placement of the wildcard character(s): before, after, or both
|
||||||
* @return {QueryBuilder} - The Query Builder object, for chaining
|
* @return {QueryBuilder} - The Query Builder object, for chaining
|
||||||
*/
|
*/
|
||||||
orLike(field, val, pos) {
|
orLike (field, val, pos) {
|
||||||
this._like(field, val, pos, ' LIKE ', 'OR');
|
this._like(field, val, pos, ' LIKE ', 'OR');
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -472,7 +172,7 @@ class QueryBuilder extends QueryBuilderBase {
|
|||||||
* @param {String} [pos=both] - The placement of the wildcard character(s): before, after, or both
|
* @param {String} [pos=both] - The placement of the wildcard character(s): before, after, or both
|
||||||
* @return {QueryBuilder} - The Query Builder object, for chaining
|
* @return {QueryBuilder} - The Query Builder object, for chaining
|
||||||
*/
|
*/
|
||||||
orNotLike(field, val, pos) {
|
orNotLike (field, val, pos) {
|
||||||
this._like(field, val, pos, ' NOT LIKE ', 'OR');
|
this._like(field, val, pos, ' NOT LIKE ', 'OR');
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -484,10 +184,8 @@ class QueryBuilder extends QueryBuilderBase {
|
|||||||
* @param {String|Number} [val] - The value to compare if the value of key is a string
|
* @param {String|Number} [val] - The value to compare if the value of key is a string
|
||||||
* @return {QueryBuilder} - The Query Builder object, for chaining
|
* @return {QueryBuilder} - The Query Builder object, for chaining
|
||||||
*/
|
*/
|
||||||
having(/*key, [val]*/) {
|
having (key, val = null) {
|
||||||
let args = getArgs('key:string|object, [val]:string|number', arguments);
|
this._having(key, val, 'AND');
|
||||||
|
|
||||||
this._having(args.key, args.val, 'AND');
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -498,10 +196,8 @@ class QueryBuilder extends QueryBuilderBase {
|
|||||||
* @param {String|Number} [val] - The value to compare if the value of key is a string
|
* @param {String|Number} [val] - The value to compare if the value of key is a string
|
||||||
* @return {QueryBuilder} - The Query Builder object, for chaining
|
* @return {QueryBuilder} - The Query Builder object, for chaining
|
||||||
*/
|
*/
|
||||||
orHaving(/*key, [val]*/) {
|
orHaving (key, val = null) {
|
||||||
let args = getArgs('key:string|object, [val]:string|number', arguments);
|
this._having(key, val, 'OR');
|
||||||
|
|
||||||
this._having(args.key, args.val, 'OR');
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -512,7 +208,7 @@ class QueryBuilder extends QueryBuilderBase {
|
|||||||
* @param {String|Number} [val] - The value to compare if the value of key is a string
|
* @param {String|Number} [val] - The value to compare if the value of key is a string
|
||||||
* @return {QueryBuilder} - The Query Builder object, for chaining
|
* @return {QueryBuilder} - The Query Builder object, for chaining
|
||||||
*/
|
*/
|
||||||
where(key, val) {
|
where (key, val) {
|
||||||
this._where(key, val, 'AND');
|
this._where(key, val, 'AND');
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -524,7 +220,7 @@ class QueryBuilder extends QueryBuilderBase {
|
|||||||
* @param {String|Number} [val] - The value to compare if the value of key is a string
|
* @param {String|Number} [val] - The value to compare if the value of key is a string
|
||||||
* @return {QueryBuilder} - The Query Builder object, for chaining
|
* @return {QueryBuilder} - The Query Builder object, for chaining
|
||||||
*/
|
*/
|
||||||
orWhere(key, val) {
|
orWhere (key, val) {
|
||||||
this._where(key, val, 'OR');
|
this._where(key, val, 'OR');
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -535,7 +231,7 @@ class QueryBuilder extends QueryBuilderBase {
|
|||||||
* @param {String} field - The name of the field that has a NULL value
|
* @param {String} field - The name of the field that has a NULL value
|
||||||
* @return {QueryBuilder} - The Query Builder object, for chaining
|
* @return {QueryBuilder} - The Query Builder object, for chaining
|
||||||
*/
|
*/
|
||||||
whereIsNull(field) {
|
whereIsNull (field) {
|
||||||
this._whereNull(field, 'IS NULL', 'AND');
|
this._whereNull(field, 'IS NULL', 'AND');
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -546,7 +242,7 @@ class QueryBuilder extends QueryBuilderBase {
|
|||||||
* @param {String} field - The name so the field that is not to be null
|
* @param {String} field - The name so the field that is not to be null
|
||||||
* @return {QueryBuilder} - The Query Builder object, for chaining
|
* @return {QueryBuilder} - The Query Builder object, for chaining
|
||||||
*/
|
*/
|
||||||
whereIsNotNull(field) {
|
whereIsNotNull (field) {
|
||||||
this._whereNull(field, 'IS NOT NULL', 'AND');
|
this._whereNull(field, 'IS NOT NULL', 'AND');
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -557,7 +253,7 @@ class QueryBuilder extends QueryBuilderBase {
|
|||||||
* @param {String} field - The name of the field
|
* @param {String} field - The name of the field
|
||||||
* @return {QueryBuilder} - The Query Builder object, for chaining
|
* @return {QueryBuilder} - The Query Builder object, for chaining
|
||||||
*/
|
*/
|
||||||
orWhereIsNull(field) {
|
orWhereIsNull (field) {
|
||||||
this._whereNull(field, 'IS NULL', 'OR');
|
this._whereNull(field, 'IS NULL', 'OR');
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -568,7 +264,7 @@ class QueryBuilder extends QueryBuilderBase {
|
|||||||
* @param {String} field - The name of the field
|
* @param {String} field - The name of the field
|
||||||
* @return {QueryBuilder} - The Query Builder object, for chaining
|
* @return {QueryBuilder} - The Query Builder object, for chaining
|
||||||
*/
|
*/
|
||||||
orWhereIsNotNull(field) {
|
orWhereIsNotNull (field) {
|
||||||
this._whereNull(field, 'IS NOT NULL', 'OR');
|
this._whereNull(field, 'IS NOT NULL', 'OR');
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -580,7 +276,7 @@ class QueryBuilder extends QueryBuilderBase {
|
|||||||
* @param {Array} values - the array of items to search in
|
* @param {Array} values - the array of items to search in
|
||||||
* @return {QueryBuilder} - The Query Builder object, for chaining
|
* @return {QueryBuilder} - The Query Builder object, for chaining
|
||||||
*/
|
*/
|
||||||
whereIn(key, values) {
|
whereIn (key, values) {
|
||||||
this._whereIn(key, values, 'IN', 'AND');
|
this._whereIn(key, values, 'IN', 'AND');
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -592,7 +288,7 @@ class QueryBuilder extends QueryBuilderBase {
|
|||||||
* @param {Array} values - the array of items to search in
|
* @param {Array} values - the array of items to search in
|
||||||
* @return {QueryBuilder} - The Query Builder object, for chaining
|
* @return {QueryBuilder} - The Query Builder object, for chaining
|
||||||
*/
|
*/
|
||||||
orWhereIn(key, values) {
|
orWhereIn (key, values) {
|
||||||
this._whereIn(key, values, 'IN', 'OR');
|
this._whereIn(key, values, 'IN', 'OR');
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -604,7 +300,7 @@ class QueryBuilder extends QueryBuilderBase {
|
|||||||
* @param {Array} values - the array of items to search in
|
* @param {Array} values - the array of items to search in
|
||||||
* @return {QueryBuilder} - The Query Builder object, for chaining
|
* @return {QueryBuilder} - The Query Builder object, for chaining
|
||||||
*/
|
*/
|
||||||
whereNotIn(key, values) {
|
whereNotIn (key, values) {
|
||||||
this._whereIn(key, values, 'NOT IN', 'AND');
|
this._whereIn(key, values, 'NOT IN', 'AND');
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -616,7 +312,7 @@ class QueryBuilder extends QueryBuilderBase {
|
|||||||
* @param {Array} values - the array of items to search in
|
* @param {Array} values - the array of items to search in
|
||||||
* @return {QueryBuilder} - The Query Builder object, for chaining
|
* @return {QueryBuilder} - The Query Builder object, for chaining
|
||||||
*/
|
*/
|
||||||
orWhereNotIn(key, values) {
|
orWhereNotIn (key, values) {
|
||||||
this._whereIn(key, values, 'NOT IN', 'OR');
|
this._whereIn(key, values, 'NOT IN', 'OR');
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -630,12 +326,10 @@ class QueryBuilder extends QueryBuilderBase {
|
|||||||
* @example query.set({foo:'bar'}); // Set with an object
|
* @example query.set({foo:'bar'}); // Set with an object
|
||||||
* @return {QueryBuilder} - The Query Builder object, for chaining
|
* @return {QueryBuilder} - The Query Builder object, for chaining
|
||||||
*/
|
*/
|
||||||
set(/* $key, [$val] */) {
|
set (key, val) {
|
||||||
let args = getArgs('$key, [$val]', arguments);
|
|
||||||
|
|
||||||
// Set the appropriate state variables
|
// Set the appropriate state variables
|
||||||
this._mixedSet('setArrayKeys', 'key', args.$key, args.$val);
|
this._mixedSet('setArrayKeys', 'key', key, val);
|
||||||
this._mixedSet('values', 'value', args.$key, args.$val);
|
this._mixedSet('values', 'value', key, val);
|
||||||
|
|
||||||
// Use the keys of the array to make the insert/update string
|
// Use the keys of the array to make the insert/update string
|
||||||
// and escape the field names
|
// and escape the field names
|
||||||
@ -656,7 +350,7 @@ class QueryBuilder extends QueryBuilderBase {
|
|||||||
* @param {String} [type='inner'] - The type of join, which defaults to inner
|
* @param {String} [type='inner'] - The type of join, which defaults to inner
|
||||||
* @return {QueryBuilder} - The Query Builder object, for chaining
|
* @return {QueryBuilder} - The Query Builder object, for chaining
|
||||||
*/
|
*/
|
||||||
join(table, cond, type) {
|
join (table, cond, type) {
|
||||||
type = type || 'inner';
|
type = type || 'inner';
|
||||||
|
|
||||||
// Prefix/quote table name
|
// Prefix/quote table name
|
||||||
@ -681,8 +375,8 @@ class QueryBuilder extends QueryBuilderBase {
|
|||||||
* @param {String|Array} field - The name of the field to group by
|
* @param {String|Array} field - The name of the field to group by
|
||||||
* @return {QueryBuilder} - The Query Builder object, for chaining
|
* @return {QueryBuilder} - The Query Builder object, for chaining
|
||||||
*/
|
*/
|
||||||
groupBy(field) {
|
groupBy (field) {
|
||||||
if (! helpers.isScalar(field)) {
|
if (!helpers.isScalar(field)) {
|
||||||
let newGroupArray = field.map(this.driver.quoteIdentifiers);
|
let newGroupArray = field.map(this.driver.quoteIdentifiers);
|
||||||
this.state.groupArray = this.state.groupArray.concat(newGroupArray);
|
this.state.groupArray = this.state.groupArray.concat(newGroupArray);
|
||||||
} else {
|
} else {
|
||||||
@ -701,7 +395,7 @@ class QueryBuilder extends QueryBuilderBase {
|
|||||||
* @param {String} [type='ASC'] - The order direction, ASC or DESC
|
* @param {String} [type='ASC'] - The order direction, ASC or DESC
|
||||||
* @return {QueryBuilder} - The Query Builder object, for chaining
|
* @return {QueryBuilder} - The Query Builder object, for chaining
|
||||||
*/
|
*/
|
||||||
orderBy(field, type) {
|
orderBy (field, type) {
|
||||||
type = type || 'ASC';
|
type = type || 'ASC';
|
||||||
|
|
||||||
// Set the fields for later manipulation
|
// Set the fields for later manipulation
|
||||||
@ -729,7 +423,7 @@ class QueryBuilder extends QueryBuilderBase {
|
|||||||
* @param {Number} [offset] - The row number to start from
|
* @param {Number} [offset] - The row number to start from
|
||||||
* @return {QueryBuilder} - The Query Builder object, for chaining
|
* @return {QueryBuilder} - The Query Builder object, for chaining
|
||||||
*/
|
*/
|
||||||
limit(limit, offset) {
|
limit (limit, offset) {
|
||||||
this.state.limit = limit;
|
this.state.limit = limit;
|
||||||
this.state.offset = offset || null;
|
this.state.offset = offset || null;
|
||||||
|
|
||||||
@ -741,7 +435,7 @@ class QueryBuilder extends QueryBuilderBase {
|
|||||||
*
|
*
|
||||||
* @return {QueryBuilder} - The Query Builder object, for chaining
|
* @return {QueryBuilder} - The Query Builder object, for chaining
|
||||||
*/
|
*/
|
||||||
groupStart() {
|
groupStart () {
|
||||||
let conj = (this.state.queryMap.length < 1) ? ' WHERE ' : ' AND ';
|
let conj = (this.state.queryMap.length < 1) ? ' WHERE ' : ' AND ';
|
||||||
this._appendMap(conj, '(', 'groupStart');
|
this._appendMap(conj, '(', 'groupStart');
|
||||||
|
|
||||||
@ -754,7 +448,7 @@ class QueryBuilder extends QueryBuilderBase {
|
|||||||
*
|
*
|
||||||
* @return {QueryBuilder} - The Query Builder object, for chaining
|
* @return {QueryBuilder} - The Query Builder object, for chaining
|
||||||
*/
|
*/
|
||||||
orGroupStart() {
|
orGroupStart () {
|
||||||
this._appendMap('', ' OR (', 'groupStart');
|
this._appendMap('', ' OR (', 'groupStart');
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
@ -766,7 +460,7 @@ class QueryBuilder extends QueryBuilderBase {
|
|||||||
*
|
*
|
||||||
* @return {QueryBuilder} - The Query Builder object, for chaining
|
* @return {QueryBuilder} - The Query Builder object, for chaining
|
||||||
*/
|
*/
|
||||||
orNotGroupStart() {
|
orNotGroupStart () {
|
||||||
this._appendMap('', ' OR NOT (', 'groupStart');
|
this._appendMap('', ' OR NOT (', 'groupStart');
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
@ -777,7 +471,7 @@ class QueryBuilder extends QueryBuilderBase {
|
|||||||
*
|
*
|
||||||
* @return {QueryBuilder} - The Query Builder object, for chaining
|
* @return {QueryBuilder} - The Query Builder object, for chaining
|
||||||
*/
|
*/
|
||||||
groupEnd() {
|
groupEnd () {
|
||||||
this._appendMap('', ')', 'groupEnd');
|
this._appendMap('', ')', 'groupEnd');
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
@ -793,26 +487,22 @@ class QueryBuilder extends QueryBuilderBase {
|
|||||||
* @param {String} [table] - The table to select from
|
* @param {String} [table] - The table to select from
|
||||||
* @param {Number} [limit] - A limit for the query
|
* @param {Number} [limit] - A limit for the query
|
||||||
* @param {Number} [offset] - An offset for the query
|
* @param {Number} [offset] - An offset for the query
|
||||||
* @param {Function} [callback] - A callback for receiving the result
|
|
||||||
* @example query.get('table_name').then(promiseCallback); // Get all the rows in the table
|
* @example query.get('table_name').then(promiseCallback); // Get all the rows in the table
|
||||||
* @example query.get('table_name', 5, callback); // Get 5 rows from the table
|
* @example query.get('table_name', 5); // Get 5 rows from the table
|
||||||
* @example query.get(callback); // Get the results of a query generated with other methods
|
* @example query.get(); // Get the results of a query generated with other methods
|
||||||
* @return {void|Promise} - If no callback is passed, a promise is returned
|
* @return {void|Promise} - If no callback is passed, a promise is returned
|
||||||
*/
|
*/
|
||||||
get(/* [table], [limit], [offset], [callback] */) {
|
get (table, limit, offset) {
|
||||||
const argPattern = '[table]:string, [limit]:number, [offset]:number, [callback]:function';
|
if (table) {
|
||||||
let args = getArgs(argPattern, arguments);
|
this.from(table);
|
||||||
|
|
||||||
if (args.table) {
|
|
||||||
this.from(args.table);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args.limit) {
|
if (limit) {
|
||||||
this.limit(args.limit, args.offset);
|
this.limit(limit, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run the query
|
// Run the query
|
||||||
return this._run('get', args.table, args.callback);
|
return this._run('get', table);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -820,18 +510,15 @@ class QueryBuilder extends QueryBuilderBase {
|
|||||||
*
|
*
|
||||||
* @param {String} table - The table to insert into
|
* @param {String} table - The table to insert into
|
||||||
* @param {Object} [data] - Data to insert, if not already added with the 'set' method
|
* @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 {Promise} - If no callback is passed, a promise is returned
|
||||||
* @return {void|Promise} - If no callback is passed, a promise is returned
|
|
||||||
*/
|
*/
|
||||||
insert(/* table, data, callback */) {
|
insert (table, data) {
|
||||||
let args = getArgs('table:string, [data]:object, [callback]:function', arguments);
|
if (data) {
|
||||||
|
this.set(data);
|
||||||
if (args.data) {
|
|
||||||
this.set(args.data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run the query
|
// Run the query
|
||||||
return this._run('insert', this.driver.quoteTable(args.table), args.callback);
|
return this._run('insert', this.driver.quoteTable(table));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -839,18 +526,15 @@ class QueryBuilder extends QueryBuilderBase {
|
|||||||
*
|
*
|
||||||
* @param {String} table - The table to insert into
|
* @param {String} table - The table to insert into
|
||||||
* @param {Array} data - The array of objects containing data rows to insert
|
* @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);
|
|
||||||
* @example query.insertBatch('foo',[{id:1,val:'bar'},{id:2,val:'baz'}])
|
* @example query.insertBatch('foo',[{id:1,val:'bar'},{id:2,val:'baz'}])
|
||||||
*.then(promiseCallback);
|
*.then(promiseCallback);
|
||||||
* @return {void|Promise} - If no callback is passed, a promise is returned
|
* @return {Promise} - If no callback is passed, a promise is returned
|
||||||
*/
|
*/
|
||||||
insertBatch(/* table, data, callback */) {
|
insertBatch (table, data) {
|
||||||
let args = getArgs('table:string, data:array, [callback]:function', arguments);
|
let batch = this.driver.insertBatch(table, data);
|
||||||
let batch = this.driver.insertBatch(args.table, args.data);
|
|
||||||
|
|
||||||
// Run the query
|
// Run the query
|
||||||
return this._run('', '', args.callback, batch.sql, batch.values);
|
return this.query(batch.sql, batch.values);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -858,18 +542,15 @@ class QueryBuilder extends QueryBuilderBase {
|
|||||||
*
|
*
|
||||||
* @param {String} table - The table to insert into
|
* @param {String} table - The table to insert into
|
||||||
* @param {Object} [data] - Data to insert, if not already added with the 'set' method
|
* @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 {Promise} - If no callback is passed, a promise is returned
|
||||||
* @return {void|Promise} - If no callback is passed, a promise is returned
|
|
||||||
*/
|
*/
|
||||||
update(/*table, data, callback*/) {
|
update (table, data) {
|
||||||
let args = getArgs('table:string, [data]:object, [callback]:function', arguments);
|
if (data) {
|
||||||
|
this.set(data);
|
||||||
if (args.data) {
|
|
||||||
this.set(args.data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run the query
|
// Run the query
|
||||||
return this._run('update', this.driver.quoteTable(args.table), args.callback);
|
return this._run('update', this.driver.quoteTable(table));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -877,18 +558,15 @@ class QueryBuilder extends QueryBuilderBase {
|
|||||||
*
|
*
|
||||||
* @param {String} table - The table to insert into
|
* @param {String} table - The table to insert into
|
||||||
* @param {Object} [where] - Where clause for delete statement
|
* @param {Object} [where] - Where clause for delete statement
|
||||||
* @param {Function} [callback] - Callback for handling response from the database
|
* @return {Promise} - If no callback is passed, a promise is returned
|
||||||
* @return {void|Promise} - If no callback is passed, a promise is returned
|
|
||||||
*/
|
*/
|
||||||
delete(/*table, [where], [callback]*/) {
|
delete (table, where) {
|
||||||
let args = getArgs('table:string, [where]:object, [callback]:function', arguments);
|
if (where) {
|
||||||
|
this.where(where);
|
||||||
if (args.where) {
|
|
||||||
this.where(args.where);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run the query
|
// Run the query
|
||||||
return this._run('delete', this.driver.quoteTable(args.table), args.callback);
|
return this._run('delete', this.driver.quoteTable(table));
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
@ -902,13 +580,12 @@ class QueryBuilder extends QueryBuilderBase {
|
|||||||
* @param {Boolean} [reset=true] - Whether to reset the query builder so another query can be built
|
* @param {Boolean} [reset=true] - Whether to reset the query builder so another query can be built
|
||||||
* @return {String} - The compiled sql statement
|
* @return {String} - The compiled sql statement
|
||||||
*/
|
*/
|
||||||
getCompiledSelect(/*table, reset*/) {
|
getCompiledSelect (table, reset = true) {
|
||||||
let args = getArgs('[table]:string, [reset]:boolean', arguments);
|
if (table) {
|
||||||
if (args.table) {
|
this.from(table);
|
||||||
this.from(args.table);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return this._getCompile('get', args.table, args.reset);
|
return this._getCompile('get', table, reset);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -918,7 +595,7 @@ class QueryBuilder extends QueryBuilderBase {
|
|||||||
* @param {Boolean} [reset=true] - Whether to reset the query builder so another query can be built
|
* @param {Boolean} [reset=true] - Whether to reset the query builder so another query can be built
|
||||||
* @return {String} - The compiled sql statement
|
* @return {String} - The compiled sql statement
|
||||||
*/
|
*/
|
||||||
getCompiledInsert(table, reset) {
|
getCompiledInsert (table, reset) {
|
||||||
return this._getCompile('insert', this.driver.quoteTable(table), reset);
|
return this._getCompile('insert', this.driver.quoteTable(table), reset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -929,7 +606,7 @@ class QueryBuilder extends QueryBuilderBase {
|
|||||||
* @param {Boolean} [reset=true] - Whether to reset the query builder so another query can be built
|
* @param {Boolean} [reset=true] - Whether to reset the query builder so another query can be built
|
||||||
* @return {String} - The compiled sql statement
|
* @return {String} - The compiled sql statement
|
||||||
*/
|
*/
|
||||||
getCompiledUpdate(table, reset) {
|
getCompiledUpdate (table, reset) {
|
||||||
return this._getCompile('update', this.driver.quoteTable(table), reset);
|
return this._getCompile('update', this.driver.quoteTable(table), reset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -940,7 +617,7 @@ class QueryBuilder extends QueryBuilderBase {
|
|||||||
* @param {Boolean} [reset=true] - Whether to reset the query builder so another query can be built
|
* @param {Boolean} [reset=true] - Whether to reset the query builder so another query can be built
|
||||||
* @return {String} - The compiled sql statement
|
* @return {String} - The compiled sql statement
|
||||||
*/
|
*/
|
||||||
getCompiledDelete(table, reset) {
|
getCompiledDelete (table, reset) {
|
||||||
return this._getCompile('delete', this.driver.quoteTable(table), reset);
|
return this._getCompile('delete', this.driver.quoteTable(table), reset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
272
lib/QueryBuilderBase.js
Normal file
272
lib/QueryBuilderBase.js
Normal file
@ -0,0 +1,272 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const helpers = require('./helpers');
|
||||||
|
const QueryParser = require('./QueryParser');
|
||||||
|
const State = require('./State');
|
||||||
|
|
||||||
|
class QueryBuilderBase {
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @constructor
|
||||||
|
* @param {Driver} Driver - The syntax driver for the database
|
||||||
|
* @param {Adapter} Adapter - The database module adapter for running queries
|
||||||
|
*/
|
||||||
|
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
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {String} type - Type of SQL query
|
||||||
|
* @param {String} table - The table to run the query on
|
||||||
|
* @return {String} - The compiled sql
|
||||||
|
*/
|
||||||
|
_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 (${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
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {String} conjunction - linking keyword for the clause
|
||||||
|
* @param {String} string - pre-compiled sql fragment
|
||||||
|
* @param {String} type - type of sql clause
|
||||||
|
* @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
|
||||||
|
* @return {Array} - modified state array
|
||||||
|
*/
|
||||||
|
_mixedSet (letName, valType, key, val) {
|
||||||
|
let obj = {};
|
||||||
|
|
||||||
|
if (helpers.isScalar(key) && !helpers.isUndefined(val)) {
|
||||||
|
// Convert key/val pair to a simple object
|
||||||
|
obj[key] = val;
|
||||||
|
} else if (helpers.isScalar(key) && helpers.isUndefined(val)) {
|
||||||
|
// If just a string for the key, and no value, create a simple object with duplicate key/val
|
||||||
|
obj[key] = key;
|
||||||
|
} else {
|
||||||
|
obj = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.keys(obj).forEach(k => {
|
||||||
|
// If a single value for the return
|
||||||
|
if (['key', 'value'].indexOf(valType) !== -1) {
|
||||||
|
let pushVal = (valType === 'key') ? k : obj[k];
|
||||||
|
this.state[letName].push(pushVal);
|
||||||
|
} else {
|
||||||
|
this.state[letName][k] = obj[k];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return this.state[letName];
|
||||||
|
}
|
||||||
|
|
||||||
|
_whereMixedSet (key, val) {
|
||||||
|
this.state.whereMap = [];
|
||||||
|
this.state.rawWhereValues = [];
|
||||||
|
|
||||||
|
this._mixedSet('whereMap', 'both', key, val);
|
||||||
|
this._mixedSet('rawWhereValues', 'value', key, 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 = null, conj = 'AND') {
|
||||||
|
// Normalize key/val and put in state.whereMap
|
||||||
|
this._whereMixedSet(key, 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) ? ` ${conj} ` : ' HAVING ',
|
||||||
|
string: clause
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Clear the where Map
|
||||||
|
this.state.whereMap = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
_whereIn (key, val, inClause, conj) {
|
||||||
|
key = this.driver.quoteIdentifiers(key);
|
||||||
|
let params = Array(val.length);
|
||||||
|
params.fill('?');
|
||||||
|
|
||||||
|
val.forEach(value => {
|
||||||
|
this.state.whereValues.push(value);
|
||||||
|
});
|
||||||
|
|
||||||
|
conj = (this.state.queryMap.length > 0) ? ` ${conj} ` : ' WHERE ';
|
||||||
|
let str = `${key} ${inClause} (${params.join(',')}) `;
|
||||||
|
|
||||||
|
this._appendMap(conj, str, 'whereIn');
|
||||||
|
}
|
||||||
|
|
||||||
|
_run (type, table, sql, vals) {
|
||||||
|
if (!sql) {
|
||||||
|
sql = this._compile(type, table);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!vals) {
|
||||||
|
vals = this.state.values.concat(this.state.whereValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset the state so another query can be built
|
||||||
|
this._resetState();
|
||||||
|
|
||||||
|
// Pass the sql and values to the adapter to run on the database
|
||||||
|
return this.query(sql, vals);
|
||||||
|
}
|
||||||
|
|
||||||
|
_getCompile (type, table, reset) {
|
||||||
|
reset = reset || false;
|
||||||
|
|
||||||
|
let sql = this._compile(type, table);
|
||||||
|
|
||||||
|
if (reset) {
|
||||||
|
this._resetState();
|
||||||
|
}
|
||||||
|
|
||||||
|
return sql;
|
||||||
|
}
|
||||||
|
|
||||||
|
_resetState () {
|
||||||
|
this.state = new State();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = QueryBuilderBase;
|
@ -18,13 +18,13 @@ class QueryParser {
|
|||||||
* @param {Driver} driver - The driver object for the database in use
|
* @param {Driver} driver - The driver object for the database in use
|
||||||
* @return {void}
|
* @return {void}
|
||||||
*/
|
*/
|
||||||
constructor(driver) {
|
constructor (driver) {
|
||||||
this.driver = driver;
|
this.driver = driver;
|
||||||
|
|
||||||
const matchPatterns = {
|
const 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
|
||||||
};
|
};
|
||||||
|
|
||||||
// Full pattern for identifiers
|
// Full pattern for identifiers
|
||||||
@ -55,7 +55,7 @@ class QueryParser {
|
|||||||
* @param {Array} array - Set of possible matches
|
* @param {Array} array - Set of possible matches
|
||||||
* @return {Array|null} - Filtered set of possible matches
|
* @return {Array|null} - Filtered set of possible matches
|
||||||
*/
|
*/
|
||||||
filterMatches(array) {
|
filterMatches (array) {
|
||||||
let output = [];
|
let output = [];
|
||||||
|
|
||||||
// Return non-array matches
|
// Return non-array matches
|
||||||
@ -76,7 +76,7 @@ class QueryParser {
|
|||||||
* @param {String} string - the string to check
|
* @param {String} string - the string to check
|
||||||
* @return {Array|null} - List of operators
|
* @return {Array|null} - List of operators
|
||||||
*/
|
*/
|
||||||
hasOperator(string) {
|
hasOperator (string) {
|
||||||
return this.filterMatches(string.match(this.matchPatterns.operator));
|
return this.filterMatches(string.match(this.matchPatterns.operator));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,13 +86,13 @@ class QueryParser {
|
|||||||
* @param {String} sql - Join sql to parse
|
* @param {String} sql - Join sql to parse
|
||||||
* @return {Object} - Join condition components
|
* @return {Object} - Join condition components
|
||||||
*/
|
*/
|
||||||
parseJoin(sql) {
|
parseJoin (sql) {
|
||||||
let matches = {};
|
let matches = {};
|
||||||
let output = {
|
let output = {
|
||||||
functions: [],
|
functions: [],
|
||||||
identifiers: [],
|
identifiers: [],
|
||||||
operators: [],
|
operators: [],
|
||||||
literals: [],
|
literals: []
|
||||||
};
|
};
|
||||||
|
|
||||||
// Get clause components
|
// Get clause components
|
||||||
@ -118,12 +118,12 @@ class QueryParser {
|
|||||||
* @param {String} condition - The join condition to evalate
|
* @param {String} condition - The join condition to evalate
|
||||||
* @return {String} - The parsed/escaped join condition
|
* @return {String} - The parsed/escaped join condition
|
||||||
*/
|
*/
|
||||||
compileJoin(condition) {
|
compileJoin (condition) {
|
||||||
let parts = this.parseJoin(condition);
|
let parts = this.parseJoin(condition);
|
||||||
|
|
||||||
// Quote the identifiers
|
// Quote the identifiers
|
||||||
parts.combined.forEach((part, i) => {
|
parts.combined.forEach((part, i) => {
|
||||||
if (parts.identifiers.indexOf(part) !== -1 && ! helpers.isNumber(part)) {
|
if (parts.identifiers.indexOf(part) !== -1 && !helpers.isNumber(part)) {
|
||||||
parts.combined[i] = this.driver.quoteIdentifiers(part);
|
parts.combined[i] = this.driver.quoteIdentifiers(part);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -138,7 +138,7 @@ class QueryParser {
|
|||||||
* @param {State} state - Query Builder state object
|
* @param {State} state - Query Builder state object
|
||||||
* @return {String} - The parsed/escaped where condition
|
* @return {String} - The parsed/escaped where condition
|
||||||
*/
|
*/
|
||||||
parseWhere(driver, state) {
|
parseWhere (driver, state) {
|
||||||
let whereMap = state.whereMap;
|
let whereMap = state.whereMap;
|
||||||
let whereValues = state.rawWhereValues;
|
let whereValues = state.rawWhereValues;
|
||||||
|
|
||||||
@ -151,7 +151,7 @@ class QueryParser {
|
|||||||
let fullClause = '';
|
let fullClause = '';
|
||||||
|
|
||||||
// Add an explicit = sign where one is inferred
|
// Add an explicit = sign where one is inferred
|
||||||
if (! this.hasOperator(key)) {
|
if (!this.hasOperator(key)) {
|
||||||
fullClause = `${key} = ${whereMap[key]}`;
|
fullClause = `${key} = ${whereMap[key]}`;
|
||||||
} else if (whereMap[key] === key) {
|
} else if (whereMap[key] === key) {
|
||||||
fullClause = key;
|
fullClause = key;
|
||||||
@ -176,7 +176,7 @@ class QueryParser {
|
|||||||
if (identIndex !== -1) {
|
if (identIndex !== -1) {
|
||||||
parts.identifiers.splice(identIndex, 1);
|
parts.identifiers.splice(identIndex, 1);
|
||||||
|
|
||||||
if (! inOutputArray) {
|
if (!inOutputArray) {
|
||||||
outputValues.push(value);
|
outputValues.push(value);
|
||||||
inOutputArray = true;
|
inOutputArray = true;
|
||||||
}
|
}
|
||||||
@ -187,7 +187,7 @@ class QueryParser {
|
|||||||
if (litIndex !== -1) {
|
if (litIndex !== -1) {
|
||||||
parts.literals.splice(litIndex, 1);
|
parts.literals.splice(litIndex, 1);
|
||||||
|
|
||||||
if (! inOutputArray) {
|
if (!inOutputArray) {
|
||||||
outputValues.push(value);
|
outputValues.push(value);
|
||||||
inOutputArray = true;
|
inOutputArray = true;
|
||||||
}
|
}
|
||||||
|
@ -16,9 +16,9 @@ class Result {
|
|||||||
* @param {Array} [rows] - the data rows of the result
|
* @param {Array} [rows] - the data rows of the result
|
||||||
* @param {Array} [columns] - the column names in the result
|
* @param {Array} [columns] - the column names in the result
|
||||||
*/
|
*/
|
||||||
constructor(rows, columns) {
|
constructor (rows=[], columns=[]) {
|
||||||
this._rows = (rows == null) ? [] : rows;
|
this._rows = rows;
|
||||||
this._columns = (columns == null) ? [] : columns;
|
this._columns = columns;
|
||||||
|
|
||||||
// If columns aren't explicitly given,
|
// If columns aren't explicitly given,
|
||||||
// get the list from the first row's keys
|
// get the list from the first row's keys
|
||||||
@ -37,7 +37,7 @@ class Result {
|
|||||||
* @private
|
* @private
|
||||||
* @return {Array} - the data rows of the result
|
* @return {Array} - the data rows of the result
|
||||||
*/
|
*/
|
||||||
get rows() {
|
get rows () {
|
||||||
return this._rows;
|
return this._rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,7 +48,7 @@ class Result {
|
|||||||
* @param {Array} rows - the data rows of the result
|
* @param {Array} rows - the data rows of the result
|
||||||
* @return {void}
|
* @return {void}
|
||||||
*/
|
*/
|
||||||
set rows(rows) {
|
set rows (rows) {
|
||||||
this._rows = rows;
|
this._rows = rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,7 +58,7 @@ class Result {
|
|||||||
* @private
|
* @private
|
||||||
* @return {Array} - the column names in the result
|
* @return {Array} - the column names in the result
|
||||||
*/
|
*/
|
||||||
get columns() {
|
get columns () {
|
||||||
return this._columns;
|
return this._columns;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,7 +69,7 @@ class Result {
|
|||||||
* @param {Array} cols - the array of columns for the current result
|
* @param {Array} cols - the array of columns for the current result
|
||||||
* @return {void}
|
* @return {void}
|
||||||
*/
|
*/
|
||||||
set columns(cols) {
|
set columns (cols) {
|
||||||
this._columns = cols;
|
this._columns = cols;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,7 +78,7 @@ class Result {
|
|||||||
*
|
*
|
||||||
* @return {Number} - the number of rows in the result
|
* @return {Number} - the number of rows in the result
|
||||||
*/
|
*/
|
||||||
rowCount() {
|
rowCount () {
|
||||||
return this._rows.length;
|
return this._rows.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,7 +87,7 @@ class Result {
|
|||||||
*
|
*
|
||||||
* @return {Number} - the number of columns in the result
|
* @return {Number} - the number of columns in the result
|
||||||
*/
|
*/
|
||||||
columnCount() {
|
columnCount () {
|
||||||
return this._columns.length;
|
return this._columns.length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
class State {
|
class State {
|
||||||
constructor() {
|
constructor () {
|
||||||
// Arrays/maps
|
// Arrays/maps
|
||||||
this.queryMap = [];
|
this.queryMap = [];
|
||||||
this.values = [];
|
this.values = [];
|
||||||
@ -31,5 +31,3 @@ class State {
|
|||||||
}
|
}
|
||||||
|
|
||||||
module.exports = State;
|
module.exports = State;
|
||||||
|
|
||||||
// End of module State
|
|
8
lib/adapters/Firebird/index.js
Normal file
8
lib/adapters/Firebird/index.js
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const NodeFirebird = require('./node-firebird');
|
||||||
|
|
||||||
|
module.exports = config => {
|
||||||
|
return new NodeFirebird(config.connection);
|
||||||
|
};
|
||||||
|
|
61
lib/adapters/Firebird/node-firebird.js
Normal file
61
lib/adapters/Firebird/node-firebird.js
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const Adapter = require('../../Adapter');
|
||||||
|
const Result = require('../../Result');
|
||||||
|
const fb = require('node-firebird');
|
||||||
|
|
||||||
|
class Firebird extends Adapter {
|
||||||
|
constructor (config) {
|
||||||
|
super({});
|
||||||
|
this.instance = new Promise((resolve, reject) => {
|
||||||
|
fb.attach(config, (err, instance) => {
|
||||||
|
if (err) {
|
||||||
|
return reject(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
return resolve(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
|
||||||
|
* @return {Promise} - Returns a promise if no callback is provided
|
||||||
|
*/
|
||||||
|
execute (sql, params) {
|
||||||
|
return this.instance.then(conn => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
conn.query(sql, params, (err, result) => {
|
||||||
|
if (err) {
|
||||||
|
return reject(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
return resolve(this.transformResult(result));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform the adapter's result into a standard format
|
||||||
|
*
|
||||||
|
* @param {*} originalResult - the original result object from the driver
|
||||||
|
* @return {Result} - the new result object
|
||||||
|
*/
|
||||||
|
transformResult (originalResult) {
|
||||||
|
return new Result(originalResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close the current database connection
|
||||||
|
* @return {void}
|
||||||
|
*/
|
||||||
|
close () {
|
||||||
|
this.instance.then(conn => conn.detach());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = Firebird;
|
0
lib/adapters/MSSQLServer/index.js
Normal file
0
lib/adapters/MSSQLServer/index.js
Normal file
3
lib/adapters/MariaDB/index.js
Normal file
3
lib/adapters/MariaDB/index.js
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
module.exports = require('../Mysql');
|
@ -1,71 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
const Adapter = require('../Adapter');
|
|
||||||
const Result = require('../Result');
|
|
||||||
const helpers = require('../helpers');
|
|
||||||
const getArgs = require('getargs');
|
|
||||||
const mysql2 = require('mysql2');
|
|
||||||
|
|
||||||
class Mysql extends Adapter {
|
|
||||||
|
|
||||||
constructor(config) {
|
|
||||||
let instance = mysql2.createConnection(config);
|
|
||||||
instance.connect(err => {
|
|
||||||
if (err) {
|
|
||||||
throw new Error(err);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
super(instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Transform the adapter's result into a standard format
|
|
||||||
*
|
|
||||||
* @param {*} result - original driver result object
|
|
||||||
* @return {Result} - standard result object
|
|
||||||
*/
|
|
||||||
transformResult(result) {
|
|
||||||
// For insert and update queries, the result object
|
|
||||||
// works differently. Just apply the properties of
|
|
||||||
// this special result to the standard result object.
|
|
||||||
if (helpers.type(result) === 'object') {
|
|
||||||
let r = new Result();
|
|
||||||
|
|
||||||
Object.keys(result).forEach(key => {
|
|
||||||
r[key] = result[key];
|
|
||||||
});
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Result(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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|Promise} - Returns a promise if no callback is provided
|
|
||||||
*/
|
|
||||||
execute(/*sql, params, callback*/) {
|
|
||||||
let args = getArgs('sql:string, [params]:array, [callback]:function', arguments);
|
|
||||||
|
|
||||||
if (! args.callback) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
this.instance.execute(args.sql, args.params, (err, result) =>
|
|
||||||
(err)
|
|
||||||
? reject(err)
|
|
||||||
: resolve(this.transformResult(result))
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.instance.execute(args.sql, args.params, (err, rows) =>
|
|
||||||
args.callback(err, this.transformResult(rows))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = Mysql;
|
|
7
lib/adapters/Mysql/index.js
Normal file
7
lib/adapters/Mysql/index.js
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const Mysql2 = require('./mysql2');
|
||||||
|
|
||||||
|
module.exports = config => {
|
||||||
|
return new Mysql2(config.connection);
|
||||||
|
};
|
52
lib/adapters/Mysql/mysql2.js
Normal file
52
lib/adapters/Mysql/mysql2.js
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const Adapter = require('../../Adapter');
|
||||||
|
const Result = require('../../Result');
|
||||||
|
const helpers = require('../../helpers');
|
||||||
|
const mysql2 = require('mysql2/promise');
|
||||||
|
|
||||||
|
class Mysql extends Adapter {
|
||||||
|
|
||||||
|
constructor (config) {
|
||||||
|
const instance = mysql2.createConnection(config);
|
||||||
|
super(instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform the adapter's result into a standard format
|
||||||
|
*
|
||||||
|
* @param {*} result - original driver result object
|
||||||
|
* @return {Result} - standard result object
|
||||||
|
*/
|
||||||
|
transformResult (result) {
|
||||||
|
// For insert and update queries, the result object
|
||||||
|
// works differently. Just apply the properties of
|
||||||
|
// this special result to the standard result object.
|
||||||
|
if (helpers.type(result) === 'object') {
|
||||||
|
let r = new Result();
|
||||||
|
|
||||||
|
Object.keys(result).forEach(key => {
|
||||||
|
r[key] = result[key];
|
||||||
|
});
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Result(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run the sql query as a prepared statement
|
||||||
|
*
|
||||||
|
* @param {String} sql - The sql with placeholders
|
||||||
|
* @param {Array|undefined} params - The values to insert into the query
|
||||||
|
* @return {Promise} Result of query
|
||||||
|
*/
|
||||||
|
execute (sql, params) {
|
||||||
|
return this.instance
|
||||||
|
.then(conn => conn.execute(sql, params))
|
||||||
|
.then(result => this.transformResult(result));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = Mysql;
|
@ -1,15 +1,13 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const Adapter = require('../Adapter');
|
const Adapter = require('../../Adapter');
|
||||||
const Result = require('../Result');
|
const Result = require('../../Result');
|
||||||
const getArgs = require('getargs');
|
const helpers = require('../../helpers');
|
||||||
const helpers = require('../helpers');
|
|
||||||
const pg = require('pg');
|
const pg = require('pg');
|
||||||
const url = require('url');
|
const url = require('url');
|
||||||
|
|
||||||
class Pg extends Adapter {
|
class Pg extends Adapter {
|
||||||
|
constructor (config) {
|
||||||
constructor(config) {
|
|
||||||
let instance = null;
|
let instance = null;
|
||||||
let connectionString = '';
|
let connectionString = '';
|
||||||
if (helpers.isObject(config)) {
|
if (helpers.isObject(config)) {
|
||||||
@ -23,7 +21,7 @@ class Pg extends Adapter {
|
|||||||
slashes: true,
|
slashes: true,
|
||||||
host: `${host}:${port}`,
|
host: `${host}:${port}`,
|
||||||
auth: `${user}${password}`,
|
auth: `${user}${password}`,
|
||||||
pathname: config.database,
|
pathname: config.database
|
||||||
};
|
};
|
||||||
|
|
||||||
connectionString = url.format(conn);
|
connectionString = url.format(conn);
|
||||||
@ -32,16 +30,14 @@ class Pg extends Adapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (connectionString !== '') {
|
if (connectionString !== '') {
|
||||||
let connected = false;
|
let conn = new pg.Client(connectionString);
|
||||||
instance = new pg.Client(connectionString);
|
conn.connect(err => {
|
||||||
|
|
||||||
instance.connect(err => {
|
|
||||||
connected = true;
|
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
throw new Error(err);
|
throw new Error(err);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
instance = Promise.resolve(conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
super(instance);
|
super(instance);
|
||||||
@ -53,13 +49,15 @@ class Pg extends Adapter {
|
|||||||
* @param {*} result - original driver result object
|
* @param {*} result - original driver result object
|
||||||
* @return {Result} - standard result object
|
* @return {Result} - standard result object
|
||||||
*/
|
*/
|
||||||
transformResult(result) {
|
transformResult (result) {
|
||||||
if (result == null) {
|
if (result == null) {
|
||||||
return new Result();
|
return new Result();
|
||||||
}
|
}
|
||||||
|
|
||||||
let cols = [];
|
let cols = [];
|
||||||
result.fields.forEach(field => cols = field.name);
|
result.fields.forEach(field => {
|
||||||
|
cols = field.name;
|
||||||
|
});
|
||||||
|
|
||||||
return new Result(result.rows, cols);
|
return new Result(result.rows, cols);
|
||||||
}
|
}
|
||||||
@ -69,32 +67,24 @@ class Pg extends Adapter {
|
|||||||
*
|
*
|
||||||
* @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
|
|
||||||
* @return {void|Promise} - Returns a promise if no callback is provided
|
* @return {void|Promise} - Returns a promise if no callback is provided
|
||||||
*/
|
*/
|
||||||
execute(/*sql, params, callback*/) {
|
execute (sql, params) {
|
||||||
let args = getArgs('sql:string, [params]:array, [callback]:function', arguments);
|
|
||||||
|
|
||||||
// Replace question marks with numbered placeholders, because this adapter is different...
|
// Replace question marks with numbered placeholders, because this adapter is different...
|
||||||
let count = 0;
|
let count = 0;
|
||||||
args.sql = args.sql.replace(/\?/g, () => {
|
sql = sql.replace(/\?/g, () => {
|
||||||
count++;
|
count++;
|
||||||
return `$${count}`;
|
return `$${count}`;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (! args.callback) {
|
return this.instance.then(conn => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.instance.query(args.sql, args.params, (err, result) =>
|
conn.query(sql, params, (err, result) =>
|
||||||
(err)
|
(err)
|
||||||
? reject(err)
|
? reject(err)
|
||||||
: resolve(this.transformResult(result))
|
: resolve(this.transformResult(result))
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
return this.instance.query(args.sql, args.params, (err, origResult) => {
|
|
||||||
let result = this.transformResult(origResult);
|
|
||||||
return args.callback(err, result);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
7
lib/adapters/Pg/index.js
Normal file
7
lib/adapters/Pg/index.js
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const Pg = require('./Pg');
|
||||||
|
|
||||||
|
module.exports = config => {
|
||||||
|
return new Pg(config.connection);
|
||||||
|
};
|
@ -1,64 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
const Adapter = require('../Adapter');
|
|
||||||
const Result = require('../Result');
|
|
||||||
const getArgs = require('getargs');
|
|
||||||
const helpers = require('../helpers');
|
|
||||||
const dbliteAdapter = require('dblite');
|
|
||||||
|
|
||||||
class Sqlite extends Adapter {
|
|
||||||
constructor(config) {
|
|
||||||
let file = (helpers.isString(config)) ? config : config.file;
|
|
||||||
super(dbliteAdapter(file));
|
|
||||||
|
|
||||||
// Stop the stupid 'bye bye' message being output
|
|
||||||
this.instance.on('close', () => {});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Transform the adapter's result into a standard format
|
|
||||||
*
|
|
||||||
* @param {*} result - original driver result object
|
|
||||||
* @return {Result} - standard result object
|
|
||||||
*/
|
|
||||||
transformResult(result) {
|
|
||||||
return new Result(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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|Promise} - Returns a promise if no callback is provided
|
|
||||||
*/
|
|
||||||
execute(/*sql, params, callback*/) {
|
|
||||||
let args = getArgs('sql:string, [params]:array, [callback]:function', arguments);
|
|
||||||
|
|
||||||
if (! args.callback) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
this.instance.query(args.sql, args.params, (err, result) =>
|
|
||||||
(err)
|
|
||||||
? reject(err)
|
|
||||||
: resolve(this.transformResult(result))
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.instance.query(args.sql, args.params, (err, res) => {
|
|
||||||
args.callback(err, this.transformResult(res));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Close the current database connection
|
|
||||||
|
|
||||||
* @return {void}
|
|
||||||
*/
|
|
||||||
close() {
|
|
||||||
this.instance.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = Sqlite;
|
|
67
lib/adapters/Sqlite/dblite.js
Normal file
67
lib/adapters/Sqlite/dblite.js
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const Adapter = require('../../Adapter');
|
||||||
|
const Result = require('../../Result');
|
||||||
|
const helpers = require('../../helpers');
|
||||||
|
const dbliteAdapter = require('dblite');
|
||||||
|
|
||||||
|
class SqliteDblite extends Adapter {
|
||||||
|
constructor (config) {
|
||||||
|
let file = (helpers.isString(config)) ? config : config.file;
|
||||||
|
|
||||||
|
const instance = new Promise((resolve, reject) => {
|
||||||
|
let conn = dbliteAdapter(file);
|
||||||
|
|
||||||
|
// Stop the stupid 'bye bye' message being output
|
||||||
|
conn.on('close', () => {});
|
||||||
|
|
||||||
|
conn.on('error', err => {
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Make sure to actually pass on the connection!
|
||||||
|
return resolve(conn);
|
||||||
|
});
|
||||||
|
|
||||||
|
super(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
|
||||||
|
* @return {Promise} - Returns a promise if no callback is provided
|
||||||
|
*/
|
||||||
|
execute (sql, params) {
|
||||||
|
return this.instance.then(conn => new Promise((resolve, reject) => {
|
||||||
|
return conn.query(sql, params, (err, rows) => {
|
||||||
|
if (err) {
|
||||||
|
return reject(err);
|
||||||
|
}
|
||||||
|
return resolve(this.transformResult(rows));
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform the adapter's result into a standard format
|
||||||
|
*
|
||||||
|
* @param {*} originalResult - the original result object from the driver
|
||||||
|
* @return {Result} - the new result object
|
||||||
|
*/
|
||||||
|
transformResult (originalResult) {
|
||||||
|
return new Result(originalResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close the current database connection
|
||||||
|
*
|
||||||
|
* @return {void}
|
||||||
|
*/
|
||||||
|
close () {
|
||||||
|
this.instance.then(conn => conn.close());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = SqliteDblite;
|
10
lib/adapters/Sqlite/index.js
Normal file
10
lib/adapters/Sqlite/index.js
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
module.exports = config => {
|
||||||
|
const Implementation = (config.adapter && config.adapter === 'dblite')
|
||||||
|
? require('./dblite')
|
||||||
|
: require('./sqlite3');
|
||||||
|
|
||||||
|
return new Implementation(config.connection);
|
||||||
|
};
|
||||||
|
|
63
lib/adapters/Sqlite/sqlite3.js
Normal file
63
lib/adapters/Sqlite/sqlite3.js
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const Adapter = require('../../Adapter');
|
||||||
|
const Result = require('../../Result');
|
||||||
|
const helpers = require('../../helpers');
|
||||||
|
const sqlite3 = require('sqlite3').verbose();
|
||||||
|
|
||||||
|
class SqliteSqlite3 extends Adapter {
|
||||||
|
constructor (config) {
|
||||||
|
let file = (helpers.isString(config)) ? config : config.file;
|
||||||
|
|
||||||
|
const instance = new Promise((resolve, reject) => {
|
||||||
|
let conn = new sqlite3.Database(file, sqlite3.OPEN_READWRITE | sqlite3.OPEN_CREATE, err => {
|
||||||
|
if (err) {
|
||||||
|
reject(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
conn.on('open', resolve(conn));
|
||||||
|
});
|
||||||
|
|
||||||
|
super(instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform the adapter's result into a standard format
|
||||||
|
*
|
||||||
|
* @param {*} result - original driver result object
|
||||||
|
* @return {Result} - standard result object
|
||||||
|
*/
|
||||||
|
transformResult (result) {
|
||||||
|
return new Result(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
* @return {Promise} - Returns a promise if no callback is provided
|
||||||
|
*/
|
||||||
|
execute (sql, params) {
|
||||||
|
return this.instance.then(conn => new Promise((resolve, reject) => {
|
||||||
|
conn.all(sql, params, (err, rows) => {
|
||||||
|
if (err) {
|
||||||
|
return reject(err);
|
||||||
|
}
|
||||||
|
return resolve(this.transformResult(rows));
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close the current database connection
|
||||||
|
|
||||||
|
* @return {void}
|
||||||
|
*/
|
||||||
|
close () {
|
||||||
|
this.instance.then(conn => conn.close());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = SqliteSqlite3;
|
45
lib/drivers/Firebird.js
Normal file
45
lib/drivers/Firebird.js
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
let helpers = require('../helpers');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Driver for Firebird databases
|
||||||
|
*
|
||||||
|
* @module drivers/firebird
|
||||||
|
*/
|
||||||
|
module.exports = (() => {
|
||||||
|
delete require.cache[require.resolve('../Driver')];
|
||||||
|
let driver = require('../Driver');
|
||||||
|
|
||||||
|
driver.hasTruncate = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the limit clause
|
||||||
|
|
||||||
|
* @param {String} origSql - SQL statement to modify
|
||||||
|
* @param {Number} limit - Maximum number of rows to fetch
|
||||||
|
* @param {Number|null} offset - Number of rows to skip
|
||||||
|
* @return {String} - Modified SQL statement
|
||||||
|
*/
|
||||||
|
driver.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
|
||||||
|
*
|
||||||
|
* @return {void}
|
||||||
|
* @throws {Error}
|
||||||
|
*/
|
||||||
|
driver.insertBatch = () => {
|
||||||
|
throw new Error('Not Implemented');
|
||||||
|
};
|
||||||
|
|
||||||
|
return driver;
|
||||||
|
})();
|
8
lib/drivers/MariaDB.js
Normal file
8
lib/drivers/MariaDB.js
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Driver for MariaDB databases
|
||||||
|
*
|
||||||
|
* @module drivers/MariaDB
|
||||||
|
*/
|
||||||
|
module.exports = require('./Mysql');
|
@ -3,32 +3,31 @@
|
|||||||
/**
|
/**
|
||||||
* Driver for MySQL databases
|
* Driver for MySQL databases
|
||||||
*
|
*
|
||||||
* @module drivers/mysql
|
* @module drivers/Mysql
|
||||||
*/
|
*/
|
||||||
module.exports = (() => {
|
module.exports = (() => {
|
||||||
delete require.cache[require.resolve('../Driver')];
|
delete require.cache[require.resolve('../Driver')];
|
||||||
let driver = require('../Driver'),
|
const driver = require('../Driver');
|
||||||
helpers = require('../helpers');
|
const helpers = require('../helpers');
|
||||||
|
|
||||||
driver.identifierStartChar = '`';
|
driver.identifierStartChar = '`';
|
||||||
driver.identifierEndChar = '`';
|
driver.identifierEndChar = '`';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the limit clause
|
* Set the limit clause
|
||||||
|
*
|
||||||
* @param {String} sql - SQL statement to modify
|
* @param {String} sql - SQL statement to modify
|
||||||
* @param {Number} limit - Maximum number of rows to fetch
|
* @param {Number} limit - Maximum number of rows to fetch
|
||||||
* @param {Number|null} offset - Number of rows to skip
|
* @param {Number|null} offset - Number of rows to skip
|
||||||
* @return {String} - Modified SQL statement
|
* @return {String} - Modified SQL statement
|
||||||
*/
|
*/
|
||||||
driver.limit = (sql, limit, offset) => {
|
driver.limit = (sql, limit, offset) => {
|
||||||
if (! helpers.isNumber(offset)) {
|
sql += (helpers.isNumber(offset))
|
||||||
return sql += ` LIMIT ${limit}`;
|
? ` LIMIT ${offset},${limit}`
|
||||||
}
|
: ` LIMIT ${limit}`;
|
||||||
|
|
||||||
return sql += ` LIMIT ${offset},${limit}`;
|
return sql;
|
||||||
};
|
};
|
||||||
|
|
||||||
return driver;
|
return driver;
|
||||||
|
|
||||||
})();
|
})();
|
@ -3,7 +3,7 @@
|
|||||||
/**
|
/**
|
||||||
* Driver for PostgreSQL databases
|
* Driver for PostgreSQL databases
|
||||||
*
|
*
|
||||||
* @module drivers/pg
|
* @module drivers/Pg
|
||||||
*/
|
*/
|
||||||
module.exports = (() => {
|
module.exports = (() => {
|
||||||
delete require.cache[require.resolve('../Driver')];
|
delete require.cache[require.resolve('../Driver')];
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Driver for Sqlite databases
|
* Driver for SQLite databases
|
||||||
*
|
*
|
||||||
* @module drivers/sqlite
|
* @module drivers/Sqlite
|
||||||
*/
|
*/
|
||||||
module.exports = (() => {
|
module.exports = (() => {
|
||||||
delete require.cache[require.resolve('../Driver')];
|
delete require.cache[require.resolve('../Driver')];
|
||||||
@ -21,15 +21,12 @@ module.exports = (() => {
|
|||||||
* @return {String} - The generated sql statement
|
* @return {String} - The generated sql statement
|
||||||
*/
|
*/
|
||||||
driver.insertBatch = (table, data) => {
|
driver.insertBatch = (table, data) => {
|
||||||
|
|
||||||
// Get the data values to insert, so they can
|
// Get the data values to insert, so they can
|
||||||
// be parameterized
|
// be parameterized
|
||||||
let sql = '',
|
let sql = '';
|
||||||
vals = [],
|
let first = data.shift();
|
||||||
cols = [],
|
|
||||||
fields = [],
|
|
||||||
first = data.shift();
|
|
||||||
|
|
||||||
|
let vals = [];
|
||||||
data.forEach(obj => {
|
data.forEach(obj => {
|
||||||
let row = [];
|
let row = [];
|
||||||
Object.keys(obj).forEach(key => {
|
Object.keys(obj).forEach(key => {
|
||||||
@ -42,7 +39,8 @@ module.exports = (() => {
|
|||||||
|
|
||||||
// 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);
|
let fields = Object.keys(first);
|
||||||
|
let cols = [];
|
||||||
fields.forEach(key => {
|
fields.forEach(key => {
|
||||||
cols.push(`'${driver._quote(first[key])}' AS ${driver.quoteIdentifiers(key)}`);
|
cols.push(`'${driver._quote(first[key])}' AS ${driver.quoteIdentifiers(key)}`);
|
||||||
});
|
});
|
||||||
@ -56,7 +54,7 @@ module.exports = (() => {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
sql: sql,
|
sql: sql,
|
||||||
values: null,
|
values: undefined
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ let helpers = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
arr.forEach(obj => {
|
arr.forEach(obj => {
|
||||||
if (! helpers.isUndefined(obj[key])) {
|
if (!helpers.isUndefined(obj[key])) {
|
||||||
output.push(obj[key]);
|
output.push(obj[key]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -80,13 +80,12 @@ let helpers = {
|
|||||||
*/
|
*/
|
||||||
regexInArray: (arr, pattern) => {
|
regexInArray: (arr, pattern) => {
|
||||||
// Empty case(s)
|
// Empty case(s)
|
||||||
if (! helpers.isArray(arr) || arr.length === 0) {
|
if (!helpers.isArray(arr) || arr.length === 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let i, l = arr.length;
|
const l = arr.length;
|
||||||
|
for (let 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])) {
|
if (pattern.test(arr[i])) {
|
||||||
return true;
|
return true;
|
||||||
@ -105,7 +104,7 @@ let helpers = {
|
|||||||
str += '';
|
str += '';
|
||||||
let 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
|
||||||
@ -120,7 +119,7 @@ let types = [
|
|||||||
'Function',
|
'Function',
|
||||||
'RegExp',
|
'RegExp',
|
||||||
'NaN',
|
'NaN',
|
||||||
'Infinite',
|
'Infinite'
|
||||||
];
|
];
|
||||||
types.forEach(t => {
|
types.forEach(t => {
|
||||||
/**
|
/**
|
||||||
|
54
package.json
54
package.json
@ -1,10 +1,10 @@
|
|||||||
{
|
{
|
||||||
"name": "ci-node-query",
|
"name": "ci-node-query",
|
||||||
"version": "4.0.0",
|
"version": "5.0.0",
|
||||||
"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": ">=4.0.0"
|
"node": ">=6.0.0"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"lib/"
|
"lib/"
|
||||||
@ -21,13 +21,14 @@
|
|||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"codeigniter",
|
"codeigniter",
|
||||||
"mysql2",
|
"mariadb",
|
||||||
|
"mysql",
|
||||||
"query builder",
|
"query builder",
|
||||||
"pg",
|
|
||||||
"postgres",
|
"postgres",
|
||||||
"sqlite3",
|
"postgresql",
|
||||||
|
"sql",
|
||||||
"sqlite",
|
"sqlite",
|
||||||
"dblite"
|
"sqlite3"
|
||||||
],
|
],
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://git.timshomepage.net/timw4mail/node-query/issues"
|
"url": "https://git.timshomepage.net/timw4mail/node-query/issues"
|
||||||
@ -38,31 +39,38 @@
|
|||||||
"getargs": "~0.0.8",
|
"getargs": "~0.0.8",
|
||||||
"glob": "^7.0.3",
|
"glob": "^7.0.3",
|
||||||
"mysql2": "^1.0.0-rc.1",
|
"mysql2": "^1.0.0-rc.1",
|
||||||
"pg": "^4.5.1",
|
"node-firebird": "^0.7.5",
|
||||||
|
"pg": "^6.0.0",
|
||||||
"require-reload": "~0.2.2",
|
"require-reload": "~0.2.2",
|
||||||
|
"sqlite3": "^3.1.8",
|
||||||
"xregexp": "^3.0.0"
|
"xregexp": "^3.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"chai": "^3.5.0",
|
"chai": "^3.5.0",
|
||||||
"chai-as-promised": "^5.2.0",
|
"chai-as-promised": "^6.0.0",
|
||||||
"documentation": "",
|
"documentation": "latest",
|
||||||
"eslint": "^2.4.0",
|
"eslint": "^3.5.0",
|
||||||
"glob": "~6.0.4",
|
"globstar": "^1.0.0",
|
||||||
"gulp": "~3.9.0",
|
"happiness": "^7.1.2",
|
||||||
"gulp-documentation": "^2.2.0",
|
|
||||||
"gulp-eslint": "^2.0.0",
|
|
||||||
"gulp-istanbul": "^0.10.3",
|
|
||||||
"gulp-jscs": "^3.0.2",
|
|
||||||
"gulp-mocha": "^2.2.0",
|
|
||||||
"gulp-pipe": "^1.0.4",
|
|
||||||
"gulp-sloc": "~1.0.4",
|
|
||||||
"istanbul": "~0.4.2",
|
"istanbul": "~0.4.2",
|
||||||
"mocha": "^2.4.5"
|
"mocha": "^3.0.0",
|
||||||
|
"npm-run-all": "^3.0.0",
|
||||||
|
"nsp": "^2.2.1"
|
||||||
},
|
},
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"predocs": "documentation build -f md -o API.md lib/*.js",
|
"audit": "nsp check",
|
||||||
"docs": "documentation build -f html -o docs lib/*.js",
|
"build": "npm-run-all --parallel lint:src lint:tests docs coverage",
|
||||||
"test": "gulp test"
|
"coverage": "istanbul cover ./node_modules/mocha/bin/_mocha",
|
||||||
|
"default": "npm-run-all --parallel audit lint:src lint:tests && npm run test",
|
||||||
|
"predocs": "globstar -- documentation build -f md -o API.md \"lib/*.js\"",
|
||||||
|
"docs": "globstar -- documentation build -f html -o docs \"lib/*.js\"",
|
||||||
|
"happy": "happiness \"lib/**/*.js\" \"test/**/*.js\"",
|
||||||
|
"happy:src": "happiness \"lib/**/*.js\"",
|
||||||
|
"happy:tests": "happiness \"test/**/*.js\"",
|
||||||
|
"lint": "npm-run-all lint:tests lint:src && happy",
|
||||||
|
"lint:src": "eslint ./lib",
|
||||||
|
"lint:tests": "eslint ./test",
|
||||||
|
"test": "mocha -R spec"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
sonar.projectKey=node-query
|
|
||||||
sonar.projectName=NodeJS Query Builder
|
|
||||||
sonar.projectVersion=3.1.0
|
|
||||||
sonar.sources=lib
|
|
||||||
sonar.javascript.lcov.reportPath=coverage/lcov.info
|
|
BIN
test/FB_TEST_DB.FDB
Executable file
BIN
test/FB_TEST_DB.FDB
Executable file
Binary file not shown.
38
test/adapters/00node-firebird_test.js
Normal file
38
test/adapters/00node-firebird_test.js
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
/* eslint-env node, mocha */
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
// Load the test base
|
||||||
|
const path = require('path');
|
||||||
|
const reload = require('require-reload')(require);
|
||||||
|
const testBase = reload('../base');
|
||||||
|
const expect = testBase.expect;
|
||||||
|
const testRunner = testBase.promiseTestRunner;
|
||||||
|
|
||||||
|
// Skip on CI
|
||||||
|
if (!(process.env.CI || process.env.TRAVIS)) {
|
||||||
|
// Load the test config file
|
||||||
|
let adapterName = 'node-firebird';
|
||||||
|
const config = reload('../config.json')[adapterName];
|
||||||
|
config.connection.database = path.join(__dirname, config.connection.database);
|
||||||
|
let nodeQuery = reload('../../lib/NodeQuery')(config);
|
||||||
|
|
||||||
|
let qb = nodeQuery.getQuery();
|
||||||
|
|
||||||
|
suite('Firebird adapter tests -', () => {
|
||||||
|
test('nodeQuery.getQuery = nodeQuery.init', () => {
|
||||||
|
expect(nodeQuery.getQuery())
|
||||||
|
.to.be.deep.equal(qb);
|
||||||
|
});
|
||||||
|
test('insertBatch throws error', () => {
|
||||||
|
expect(() => {
|
||||||
|
qb.driver.insertBatch('create_test', []);
|
||||||
|
}).to.throw(Error, 'Not Implemented');
|
||||||
|
});
|
||||||
|
|
||||||
|
testRunner(qb);
|
||||||
|
|
||||||
|
suiteTeardown(() => {
|
||||||
|
qb.end();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
@ -1,14 +1,12 @@
|
|||||||
|
/* eslint-env node, mocha */
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
// Load the test base
|
// Load the test base
|
||||||
const reload = require('require-reload')(require);
|
const reload = require('require-reload')(require);
|
||||||
reload.emptyCache();
|
reload.emptyCache();
|
||||||
const fs = require('fs');
|
|
||||||
const testBase = reload('../base');
|
const testBase = reload('../base');
|
||||||
const expect = testBase.expect;
|
const expect = testBase.expect;
|
||||||
const promiseTestRunner = testBase.promiseTestRunner;
|
const testRunner = testBase.promiseTestRunner;
|
||||||
const testRunner = testBase.testRunner;
|
|
||||||
let tests = reload('../base/tests');
|
|
||||||
|
|
||||||
// Load the test config file
|
// Load the test config file
|
||||||
const config = testBase.config;
|
const config = testBase.config;
|
||||||
@ -20,63 +18,17 @@ let qb = nodeQuery.getQuery();
|
|||||||
suite('Dblite adapter tests -', () => {
|
suite('Dblite adapter tests -', () => {
|
||||||
suiteSetup(done => {
|
suiteSetup(done => {
|
||||||
// Set up the sqlite database
|
// Set up the sqlite database
|
||||||
fs.readFile(`${__dirname}/../sql/sqlite.sql`, 'utf8', (err, data) => {
|
const createTest = 'CREATE TABLE IF NOT EXISTS "create_test" ("id" INTEGER PRIMARY KEY, "key" TEXT, "val" TEXT);';
|
||||||
if (err) {
|
const createJoin = 'CREATE TABLE IF NOT EXISTS "create_join" ("id" INTEGER PRIMARY KEY, "key" TEXT, "val" TEXT);';
|
||||||
return done(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
qb.query(data, () => done());
|
qb.query(createTest)
|
||||||
});
|
.then(() => qb.query(createJoin))
|
||||||
});
|
.then(() => {
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
|
||||||
Callback Tests
|
|
||||||
---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
testRunner(qb, (err, result, done) => {
|
|
||||||
expect(err).is.not.ok;
|
|
||||||
expect(result.rows).is.an('array');
|
|
||||||
expect(result.columns).is.an('array');
|
|
||||||
expect(result.rowCount()).to.not.be.undefined;
|
|
||||||
expect(result.columnCount()).to.not.be.undefined;
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
test('Callback - Select with function and argument in WHERE clause', done => {
|
|
||||||
qb.select('id')
|
|
||||||
.from('create_test')
|
|
||||||
.where('id', 'ABS(-88)')
|
|
||||||
.get((err, rows) => {
|
|
||||||
expect(err).is.not.ok;
|
|
||||||
return done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
test('Callback - Test Insert Batch', done => {
|
|
||||||
let 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'),
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
qb.insertBatch('create_test', data, err => {
|
|
||||||
expect(err).is.not.ok;
|
|
||||||
return done();
|
return done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
testRunner(qb);
|
||||||
Promise Tests
|
|
||||||
---------------------------------------------------------------------------*/
|
|
||||||
promiseTestRunner(qb);
|
|
||||||
test('Promise - Select with function and argument in WHERE clause', () => {
|
test('Promise - Select with function and argument in WHERE clause', () => {
|
||||||
let promise = qb.select('id')
|
let promise = qb.select('id')
|
||||||
.from('create_test')
|
.from('create_test')
|
||||||
@ -90,21 +42,19 @@ suite('Dblite adapter tests -', () => {
|
|||||||
{
|
{
|
||||||
id: 544,
|
id: 544,
|
||||||
key: 3,
|
key: 3,
|
||||||
val: new Buffer('7'),
|
val: Buffer.from('7')
|
||||||
}, {
|
}, {
|
||||||
id: 89,
|
id: 89,
|
||||||
key: 34,
|
key: 34,
|
||||||
val: new Buffer('10 o\'clock'),
|
val: Buffer.from('10 o\'clock')
|
||||||
}, {
|
}, {
|
||||||
id: 48,
|
id: 48,
|
||||||
key: 403,
|
key: 403,
|
||||||
val: new Buffer('97'),
|
val: Buffer.from('97')
|
||||||
},
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
let promise = qb.query(qb.driver.truncate('create_test')).then(
|
let promise = qb.insertBatch('create_test', data);
|
||||||
() => qb.insertBatch('create_test', data)
|
|
||||||
);
|
|
||||||
expect(promise).to.be.fulfilled;
|
expect(promise).to.be.fulfilled;
|
||||||
});
|
});
|
||||||
suiteTeardown(() => {
|
suiteTeardown(() => {
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-env node, mocha */
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
// Load the test base
|
// Load the test base
|
||||||
@ -5,8 +6,7 @@ const reload = require('require-reload')(require);
|
|||||||
reload.emptyCache();
|
reload.emptyCache();
|
||||||
const testBase = reload('../base');
|
const testBase = reload('../base');
|
||||||
const expect = testBase.expect;
|
const expect = testBase.expect;
|
||||||
const promiseTestRunner = testBase.promiseTestRunner;
|
const testRunner = testBase.promiseTestRunner;
|
||||||
const testRunner = testBase.testRunner;
|
|
||||||
|
|
||||||
// Load the test config file
|
// Load the test config file
|
||||||
let adapterName = 'mysql2';
|
let adapterName = 'mysql2';
|
||||||
@ -17,61 +17,12 @@ let nodeQuery = reload('../../lib/NodeQuery')(config);
|
|||||||
let qb = nodeQuery.getQuery();
|
let qb = nodeQuery.getQuery();
|
||||||
|
|
||||||
suite('Mysql2 adapter tests -', () => {
|
suite('Mysql2 adapter tests -', () => {
|
||||||
|
|
||||||
suiteSetup(done => qb.truncate('create_test').then(() => done()));
|
|
||||||
|
|
||||||
test('nodeQuery.getQuery = nodeQuery.init', () => {
|
test('nodeQuery.getQuery = nodeQuery.init', () => {
|
||||||
expect(nodeQuery.getQuery())
|
expect(nodeQuery.getQuery())
|
||||||
.to.be.deep.equal(qb);
|
.to.be.deep.equal(qb);
|
||||||
});
|
});
|
||||||
|
|
||||||
//--------------------------------------------------------------------------
|
testRunner(qb);
|
||||||
// Callback Tests
|
|
||||||
//--------------------------------------------------------------------------
|
|
||||||
testRunner(qb, (err, result, done) => {
|
|
||||||
expect(err).is.not.ok;
|
|
||||||
expect(result.rows).is.an('array');
|
|
||||||
expect(result.columns).is.an('array');
|
|
||||||
expect(result.rowCount()).to.not.be.undefined;
|
|
||||||
expect(result.columnCount()).to.not.be.undefined;
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
test('Callback - Select with function and argument in WHERE clause', done => {
|
|
||||||
qb.select('id')
|
|
||||||
.from('create_test')
|
|
||||||
.where('id', 'CEILING(SQRT(88))')
|
|
||||||
.get((err, rows) => {
|
|
||||||
expect(err).is.not.ok;
|
|
||||||
return done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
test('Callback - Test Insert Batch', done => {
|
|
||||||
let data = [
|
|
||||||
{
|
|
||||||
id: 5441,
|
|
||||||
key: 3,
|
|
||||||
val: new Buffer('7'),
|
|
||||||
}, {
|
|
||||||
id: 891,
|
|
||||||
key: 34,
|
|
||||||
val: new Buffer('10 o\'clock'),
|
|
||||||
}, {
|
|
||||||
id: 481,
|
|
||||||
key: 403,
|
|
||||||
val: new Buffer('97'),
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
qb.insertBatch('create_test', data, (err, res) => {
|
|
||||||
expect(err).is.not.ok;
|
|
||||||
return done(err);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
// Promise Tests
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
promiseTestRunner(qb);
|
|
||||||
test('Promise - Select with function and argument in WHERE clause', () => {
|
test('Promise - Select with function and argument in WHERE clause', () => {
|
||||||
let promise = qb.select('id')
|
let promise = qb.select('id')
|
||||||
.from('create_test')
|
.from('create_test')
|
||||||
@ -80,28 +31,31 @@ suite('Mysql2 adapter tests -', () => {
|
|||||||
|
|
||||||
return expect(promise).to.be.fulfilled;
|
return expect(promise).to.be.fulfilled;
|
||||||
});
|
});
|
||||||
|
test('Test Truncate', () => {
|
||||||
|
let promise = qb.truncate('create_test');
|
||||||
|
return expect(promise).to.be.fullfilled;
|
||||||
|
});
|
||||||
test('Test Insert Batch', () => {
|
test('Test Insert Batch', () => {
|
||||||
let data = [
|
let data = [
|
||||||
{
|
{
|
||||||
id: 5442,
|
id: 5442,
|
||||||
key: 4,
|
key: 4,
|
||||||
val: new Buffer('7'),
|
val: Buffer.from('7')
|
||||||
}, {
|
}, {
|
||||||
id: 892,
|
id: 892,
|
||||||
key: 35,
|
key: 35,
|
||||||
val: new Buffer('10 o\'clock'),
|
val: Buffer.from('10 o\'clock')
|
||||||
}, {
|
}, {
|
||||||
id: 482,
|
id: 482,
|
||||||
key: 404,
|
key: 404,
|
||||||
val: 97,
|
val: 97
|
||||||
},
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
return expect(qb.insertBatch('create_test', data)).to.be.fulfilled;
|
return expect(qb.insertBatch('create_test', data)).to.be.fulfilled;
|
||||||
});
|
});
|
||||||
|
|
||||||
suiteTeardown(() => {
|
/* suiteTeardown(() => {
|
||||||
qb.end();
|
qb.end();
|
||||||
});
|
}); */
|
||||||
});
|
});
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-env node, mocha */
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
// Load the test base
|
// Load the test base
|
||||||
@ -5,8 +6,7 @@ const reload = require('require-reload')(require);
|
|||||||
reload.emptyCache();
|
reload.emptyCache();
|
||||||
const testBase = reload('../base');
|
const testBase = reload('../base');
|
||||||
const expect = testBase.expect;
|
const expect = testBase.expect;
|
||||||
const promiseTestRunner = testBase.promiseTestRunner;
|
const testRunner = testBase.promiseTestRunner;
|
||||||
const testRunner = testBase.testRunner;
|
|
||||||
|
|
||||||
// Load the test config file
|
// Load the test config file
|
||||||
let adapterName = 'pg';
|
let adapterName = 'pg';
|
||||||
@ -32,53 +32,18 @@ suite('Pg adapter tests -', () => {
|
|||||||
return expect(qb2).to.be.ok;
|
return expect(qb2).to.be.ok;
|
||||||
});
|
});
|
||||||
|
|
||||||
//--------------------------------------------------------------------------
|
test('Test Connection Error', done => {
|
||||||
// Callback Tests
|
try {
|
||||||
//--------------------------------------------------------------------------
|
reload('../../lib/NodeQuery')({});
|
||||||
testRunner(qb, (err, result, done) => {
|
done(true);
|
||||||
expect(err).is.not.ok;
|
} catch (e) {
|
||||||
expect(result.rows).is.an('array');
|
expect(e).to.be.ok;
|
||||||
expect(result.rowCount()).to.not.be.undefined;
|
expect(e).is.an('Error');
|
||||||
expect(result.columnCount()).to.not.be.undefined;
|
|
||||||
done();
|
done();
|
||||||
});
|
}
|
||||||
test('Callback - Select with function and argument in WHERE clause', done => {
|
|
||||||
qb.select('id')
|
|
||||||
.from('create_test')
|
|
||||||
.where('id', 'CEILING(SQRT(88))')
|
|
||||||
.get((err, rows) => {
|
|
||||||
expect(rows).is.ok;
|
|
||||||
expect(err).is.not.ok;
|
|
||||||
return done(err);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
test('Callback - Test Insert Batch', done => {
|
|
||||||
let data = [
|
|
||||||
{
|
|
||||||
id: 5441,
|
|
||||||
key: 3,
|
|
||||||
val: new Buffer('7'),
|
|
||||||
}, {
|
|
||||||
id: 891,
|
|
||||||
key: 34,
|
|
||||||
val: new Buffer('10 o\'clock'),
|
|
||||||
}, {
|
|
||||||
id: 481,
|
|
||||||
key: 403,
|
|
||||||
val: new Buffer('97'),
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
qb.insertBatch('create_test', data, (err, res) => {
|
|
||||||
expect(err).is.not.ok;
|
|
||||||
return done(err);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
//--------------------------------------------------------------------------
|
testRunner(qb);
|
||||||
// Promise Tests
|
|
||||||
//--------------------------------------------------------------------------
|
|
||||||
promiseTestRunner(qb);
|
|
||||||
test('Promise - Select with function and argument in WHERE clause', () => {
|
test('Promise - Select with function and argument in WHERE clause', () => {
|
||||||
let promise = qb.select('id')
|
let promise = qb.select('id')
|
||||||
.from('create_test')
|
.from('create_test')
|
||||||
@ -87,21 +52,25 @@ suite('Pg adapter tests -', () => {
|
|||||||
|
|
||||||
return expect(promise).to.be.fulfilled;
|
return expect(promise).to.be.fulfilled;
|
||||||
});
|
});
|
||||||
|
test('Promise - Test Truncate', () => {
|
||||||
|
let promise = qb.truncate('create_test');
|
||||||
|
return expect(promise).to.be.fulfilled;
|
||||||
|
});
|
||||||
test('Promise - Test Insert Batch', () => {
|
test('Promise - Test Insert Batch', () => {
|
||||||
let data = [
|
let data = [
|
||||||
{
|
{
|
||||||
id: 544,
|
id: 544,
|
||||||
key: 3,
|
key: 3,
|
||||||
val: new Buffer('7'),
|
val: Buffer.from('7')
|
||||||
}, {
|
}, {
|
||||||
id: 89,
|
id: 89,
|
||||||
key: 34,
|
key: 34,
|
||||||
val: new Buffer('10 o\'clock'),
|
val: Buffer.from('10 o\'clock')
|
||||||
}, {
|
}, {
|
||||||
id: 48,
|
id: 48,
|
||||||
key: 403,
|
key: 403,
|
||||||
val: new Buffer('97'),
|
val: Buffer.from('97')
|
||||||
},
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
let promise = qb.insertBatch('create_test', data);
|
let promise = qb.insertBatch('create_test', data);
|
||||||
|
63
test/adapters/sqlite3_test.js
Normal file
63
test/adapters/sqlite3_test.js
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
/* eslint-env node, mocha */
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
// Load the test base
|
||||||
|
const reload = require('require-reload')(require);
|
||||||
|
reload.emptyCache();
|
||||||
|
const testBase = reload('../base');
|
||||||
|
const expect = testBase.expect;
|
||||||
|
const testRunner = testBase.promiseTestRunner;
|
||||||
|
|
||||||
|
// Load the test config file
|
||||||
|
const config = testBase.config;
|
||||||
|
|
||||||
|
// Set up the query builder object
|
||||||
|
let nodeQuery = require('../../lib/NodeQuery')(config.sqlite3);
|
||||||
|
let qb = nodeQuery.getQuery();
|
||||||
|
|
||||||
|
suite('Sqlite3 adapter tests -', () => {
|
||||||
|
suiteSetup(done => {
|
||||||
|
// Set up the sqlite database
|
||||||
|
const createTest = 'CREATE TABLE IF NOT EXISTS "create_test" ("id" INTEGER PRIMARY KEY, "key" TEXT, "val" TEXT);';
|
||||||
|
const createJoin = 'CREATE TABLE IF NOT EXISTS "create_join" ("id" INTEGER PRIMARY KEY, "key" TEXT, "val" TEXT);';
|
||||||
|
|
||||||
|
qb.query(createTest)
|
||||||
|
.then(() => qb.query(createJoin))
|
||||||
|
.then(() => {
|
||||||
|
return done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
testRunner(qb);
|
||||||
|
test('Promise - Select with function and argument in WHERE clause', () => {
|
||||||
|
let promise = qb.select('id')
|
||||||
|
.from('create_test')
|
||||||
|
.where('id', 'ABS(-88)')
|
||||||
|
.get();
|
||||||
|
|
||||||
|
expect(promise).to.be.fulfilled;
|
||||||
|
});
|
||||||
|
test('Promise - Test Insert Batch', () => {
|
||||||
|
let data = [
|
||||||
|
{
|
||||||
|
id: 544,
|
||||||
|
key: 3,
|
||||||
|
val: Buffer.from('7')
|
||||||
|
}, {
|
||||||
|
id: 89,
|
||||||
|
key: 34,
|
||||||
|
val: Buffer.from('10 o\'clock')
|
||||||
|
}, {
|
||||||
|
id: 48,
|
||||||
|
key: 403,
|
||||||
|
val: Buffer.from('97')
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
let promise = qb.insertBatch('create_test', data);
|
||||||
|
expect(promise).to.be.fulfilled;
|
||||||
|
});
|
||||||
|
suiteTeardown(() => {
|
||||||
|
qb.end();
|
||||||
|
});
|
||||||
|
});
|
@ -11,6 +11,5 @@ module.exports = {
|
|||||||
config: require(configFile),
|
config: require(configFile),
|
||||||
expect: chai.expect,
|
expect: chai.expect,
|
||||||
tests: require('./base/tests'),
|
tests: require('./base/tests'),
|
||||||
testRunner: require('./base/adapterCallbackTestRunner'),
|
promiseTestRunner: require('./base/adapterPromiseTestRunner')
|
||||||
promiseTestRunner: require('./base/adapterPromiseTestRunner'),
|
|
||||||
};
|
};
|
@ -1,230 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
// jscs:disable
|
|
||||||
// Load the test base
|
|
||||||
const chai = require('chai');
|
|
||||||
const chaiAsPromised = require('chai-as-promised');
|
|
||||||
chai.use(chaiAsPromised);
|
|
||||||
const expect = chai.expect;
|
|
||||||
|
|
||||||
const reload = require('require-reload')(require);
|
|
||||||
let tests = reload('../base/tests');
|
|
||||||
|
|
||||||
let helpers = reload('../../lib/helpers'),
|
|
||||||
State = reload('../../lib/State');
|
|
||||||
|
|
||||||
module.exports = function testRunner(qb, callback) {
|
|
||||||
Object.keys(tests).forEach(suiteName => {
|
|
||||||
suite(suiteName, () => {
|
|
||||||
let currentSuite = tests[suiteName];
|
|
||||||
Object.keys(currentSuite).forEach(testDesc => {
|
|
||||||
test(`Callback - ${testDesc}`, done => {
|
|
||||||
let methodObj = currentSuite[testDesc];
|
|
||||||
let methodNames = Object.keys(methodObj);
|
|
||||||
let lastMethodIndex = methodNames[methodNames.length - 1];
|
|
||||||
|
|
||||||
methodObj[lastMethodIndex].push((err, rows) => callback(err, rows, done));
|
|
||||||
|
|
||||||
methodNames.forEach(name => {
|
|
||||||
let args = methodObj[name],
|
|
||||||
method = qb[name];
|
|
||||||
|
|
||||||
if (args[0] === 'multiple') {
|
|
||||||
args.shift();
|
|
||||||
args.forEach(argSet => {
|
|
||||||
method.apply(qb, argSet);
|
|
||||||
});
|
|
||||||
|
|
||||||
} else {
|
|
||||||
method.apply(qb, args);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
suite('DB update tests -', () => {
|
|
||||||
suiteSetup(() => qb.truncate('create_test'));
|
|
||||||
test('Callback - Test Insert', done => {
|
|
||||||
qb.set('id', 98)
|
|
||||||
.set('key', '84')
|
|
||||||
.set('val', new Buffer('120'))
|
|
||||||
.insert('create_test', (err, rows) => {
|
|
||||||
return callback(err, rows, done);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
test('Callback - Test Insert Object', done => {
|
|
||||||
qb.insert('create_test', {
|
|
||||||
id: 587,
|
|
||||||
key: 1,
|
|
||||||
val: new Buffer('2'),
|
|
||||||
}, (err, rows) => {
|
|
||||||
return callback(err, rows, done);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
test('Callback - Test Update', done => {
|
|
||||||
qb.where('id', 7)
|
|
||||||
.update('create_test', {
|
|
||||||
id: 7,
|
|
||||||
key: 'gogle',
|
|
||||||
val: new Buffer('non-word'),
|
|
||||||
}, (err, rows) => {
|
|
||||||
return callback(err, rows, done);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
test('Callback - Test set Array Update', done => {
|
|
||||||
let object = {
|
|
||||||
id: 22,
|
|
||||||
key: 'gogle',
|
|
||||||
val: new Buffer('non-word'),
|
|
||||||
};
|
|
||||||
|
|
||||||
qb.set(object)
|
|
||||||
.where('id', 22)
|
|
||||||
.update('create_test', (err, rows) => {
|
|
||||||
return callback(err, rows, done);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
test('Callback - Test where set update', done => {
|
|
||||||
qb.where('id', 36)
|
|
||||||
.set('id', 36)
|
|
||||||
.set('key', 'gogle')
|
|
||||||
.set('val', new Buffer('non-word'))
|
|
||||||
.update('create_test', (err, rows) => {
|
|
||||||
return callback(err, rows, done);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
test('Callback - Test delete', done => {
|
|
||||||
qb.delete('create_test', {id: 5}, (err, rows) => {
|
|
||||||
return callback(err, rows, done);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
test('Callback - Delete with where', done => {
|
|
||||||
qb.where('id', 5)
|
|
||||||
.delete('create_test', (err, rows) => {
|
|
||||||
return callback(err, rows, done);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
test('Callback - Delete multiple where values', done => {
|
|
||||||
qb.delete('create_test', {
|
|
||||||
id: 5,
|
|
||||||
key: 'gogle',
|
|
||||||
}, (err, rows) => {
|
|
||||||
return callback(err, rows, done);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
suite('Grouping tests -', () => {
|
|
||||||
test('Callback - Using grouping method', done => {
|
|
||||||
qb.select('id, key as k, val')
|
|
||||||
.from('create_test')
|
|
||||||
.groupStart()
|
|
||||||
.where('id >', 1)
|
|
||||||
.where('id <', 900)
|
|
||||||
.groupEnd()
|
|
||||||
.limit(2, 1)
|
|
||||||
.get((err, rows) => {
|
|
||||||
return callback(err, rows, done);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
test('Callback - Using where first grouping', done => {
|
|
||||||
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((err, rows) => {
|
|
||||||
return callback(err, rows, done);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
test('Callback - Using or grouping method', done => {
|
|
||||||
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((err, rows) => {
|
|
||||||
return callback(err, rows, done);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
test('Callback - Using or not grouping method', done => {
|
|
||||||
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((err, rows) => {
|
|
||||||
return callback(err, rows, done);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
suite('Get compiled tests -', () => {
|
|
||||||
test('select', () => {
|
|
||||||
let sql = qb.select('id')
|
|
||||||
.from('create_test')
|
|
||||||
.getCompiledSelect(true);
|
|
||||||
|
|
||||||
return expect(helpers.isString(sql)).to.be.true;
|
|
||||||
});
|
|
||||||
test('select from', () => {
|
|
||||||
let sql = qb.select('id')
|
|
||||||
.getCompiledSelect('create_test', true);
|
|
||||||
|
|
||||||
return expect(helpers.isString(sql)).to.be.true;
|
|
||||||
});
|
|
||||||
test('insert', () => {
|
|
||||||
let sql = qb.set('id', 3)
|
|
||||||
.getCompiledInsert('create_test');
|
|
||||||
|
|
||||||
return expect(helpers.isString(sql)).to.be.true;
|
|
||||||
});
|
|
||||||
test('update', () => {
|
|
||||||
let sql = qb.set('id', 3)
|
|
||||||
.where('id', 5)
|
|
||||||
.getCompiledUpdate('create_test');
|
|
||||||
|
|
||||||
return expect(helpers.isString(sql)).to.be.true;
|
|
||||||
});
|
|
||||||
test('delete', () => {
|
|
||||||
let sql = qb.where('id', 5)
|
|
||||||
.getCompiledDelete('create_test');
|
|
||||||
|
|
||||||
return expect(helpers.isString(sql)).to.be.true;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
suite('Misc tests -', () => {
|
|
||||||
test('Get State', () => {
|
|
||||||
qb.select('foo')
|
|
||||||
.from('bar')
|
|
||||||
.where('baz', 'foobar');
|
|
||||||
|
|
||||||
let state = new State();
|
|
||||||
|
|
||||||
expect(JSON.stringify(state)).to.not.be.deep.equal(qb.getState());
|
|
||||||
});
|
|
||||||
test('Reset State', () => {
|
|
||||||
qb.select('foo')
|
|
||||||
.from('bar')
|
|
||||||
.where('baz', 'foobar');
|
|
||||||
|
|
||||||
qb.resetQuery();
|
|
||||||
|
|
||||||
let state = new State();
|
|
||||||
|
|
||||||
expect(qb.getState()).to.be.deep.equal(state);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
@ -1,6 +1,6 @@
|
|||||||
|
/* eslint-env node, mocha */
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
// jscs:disable
|
|
||||||
// Load the test base
|
// Load the test base
|
||||||
const chai = require('chai');
|
const chai = require('chai');
|
||||||
const chaiAsPromised = require('chai-as-promised');
|
const chaiAsPromised = require('chai-as-promised');
|
||||||
@ -8,39 +8,39 @@ chai.use(chaiAsPromised);
|
|||||||
const expect = chai.expect;
|
const expect = chai.expect;
|
||||||
|
|
||||||
const reload = require('require-reload')(require);
|
const reload = require('require-reload')(require);
|
||||||
let tests = reload('../base/tests');
|
const tests = reload('../base/tests');
|
||||||
|
|
||||||
let helpers = reload('../../lib/helpers'),
|
module.exports = function promiseTestRunner (qb) {
|
||||||
State = reload('../../lib/State');
|
|
||||||
|
|
||||||
module.exports = function promiseTestRunner(qb) {
|
|
||||||
Object.keys(tests).forEach(suiteName => {
|
Object.keys(tests).forEach(suiteName => {
|
||||||
suite(suiteName, () => {
|
suite(suiteName, () => {
|
||||||
let currentSuite = tests[suiteName];
|
let currentSuite = tests[suiteName];
|
||||||
Object.keys(currentSuite).forEach(testDesc => {
|
Object.keys(currentSuite).forEach(testDesc => {
|
||||||
test(`Promise - ${testDesc}`, () => {
|
test(testDesc, done => {
|
||||||
let methodObj = currentSuite[testDesc];
|
const methodObj = currentSuite[testDesc];
|
||||||
let methodNames = Object.keys(methodObj);
|
const methodNames = Object.keys(methodObj);
|
||||||
let lastMethodIndex = methodNames[methodNames.length - 1];
|
|
||||||
let results = [];
|
let results = [];
|
||||||
|
|
||||||
methodNames.forEach(name => {
|
methodNames.forEach(name => {
|
||||||
let args = methodObj[name],
|
const args = methodObj[name];
|
||||||
method = qb[name];
|
const method = qb[name];
|
||||||
|
|
||||||
if (args[0] === 'multiple') {
|
if (args[0] === 'multiple') {
|
||||||
args.shift();
|
args.shift();
|
||||||
args.forEach(argSet => {
|
args.forEach(argSet => {
|
||||||
results.push(method.apply(qb, argSet));
|
results.push(method.apply(qb, argSet));
|
||||||
});
|
});
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
results.push(method.apply(qb, args));
|
results.push(method.apply(qb, args));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let promise = results.pop();
|
let promise = results.pop();
|
||||||
return expect(promise).to.be.fulfilled;
|
promise.then(result => {
|
||||||
|
expect(result.rows).is.an('array');
|
||||||
|
expect(result.rowCount()).to.not.be.undefined;
|
||||||
|
expect(result.columnCount()).to.not.be.undefined;
|
||||||
|
return done();
|
||||||
|
}).catch(e => done(e));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -54,7 +54,7 @@ module.exports = function promiseTestRunner(qb) {
|
|||||||
test('Promise - Test Insert', () => {
|
test('Promise - Test Insert', () => {
|
||||||
let promise = qb.set('id', 98)
|
let promise = qb.set('id', 98)
|
||||||
.set('key', '84')
|
.set('key', '84')
|
||||||
.set('val', new Buffer('120'))
|
.set('val', Buffer.from('120'))
|
||||||
.insert('create_test');
|
.insert('create_test');
|
||||||
|
|
||||||
return expect(promise).to.be.fulfilled;
|
return expect(promise).to.be.fulfilled;
|
||||||
@ -63,7 +63,7 @@ module.exports = function promiseTestRunner(qb) {
|
|||||||
let promise = qb.insert('create_test', {
|
let promise = qb.insert('create_test', {
|
||||||
id: 587,
|
id: 587,
|
||||||
key: 1,
|
key: 1,
|
||||||
val: new Buffer('2'),
|
val: Buffer.from('2')
|
||||||
});
|
});
|
||||||
|
|
||||||
return expect(promise).to.be.fulfilled;
|
return expect(promise).to.be.fulfilled;
|
||||||
@ -73,7 +73,7 @@ module.exports = function promiseTestRunner(qb) {
|
|||||||
.update('create_test', {
|
.update('create_test', {
|
||||||
id: 7,
|
id: 7,
|
||||||
key: 'gogle',
|
key: 'gogle',
|
||||||
val: new Buffer('non-word'),
|
val: Buffer.from('non-word')
|
||||||
});
|
});
|
||||||
|
|
||||||
return expect(promise).to.be.fulfilled;
|
return expect(promise).to.be.fulfilled;
|
||||||
@ -82,7 +82,7 @@ module.exports = function promiseTestRunner(qb) {
|
|||||||
let object = {
|
let object = {
|
||||||
id: 22,
|
id: 22,
|
||||||
key: 'gogle',
|
key: 'gogle',
|
||||||
val: new Buffer('non-word'),
|
val: Buffer.from('non-word')
|
||||||
};
|
};
|
||||||
|
|
||||||
let promise = qb.set(object)
|
let promise = qb.set(object)
|
||||||
@ -95,7 +95,7 @@ module.exports = function promiseTestRunner(qb) {
|
|||||||
let promise = qb.where('id', 36)
|
let promise = qb.where('id', 36)
|
||||||
.set('id', 36)
|
.set('id', 36)
|
||||||
.set('key', 'gogle')
|
.set('key', 'gogle')
|
||||||
.set('val', new Buffer('non-word'))
|
.set('val', Buffer.from('non-word'))
|
||||||
.update('create_test');
|
.update('create_test');
|
||||||
|
|
||||||
return expect(promise).to.be.fulfilled;
|
return expect(promise).to.be.fulfilled;
|
||||||
@ -113,7 +113,7 @@ module.exports = function promiseTestRunner(qb) {
|
|||||||
test('Promise - Delete multiple where values', () => {
|
test('Promise - Delete multiple where values', () => {
|
||||||
let promise = qb.delete('create_test', {
|
let promise = qb.delete('create_test', {
|
||||||
id: 5,
|
id: 5,
|
||||||
key: 'gogle',
|
key: 'gogle'
|
||||||
});
|
});
|
||||||
|
|
||||||
return expect(promise).to.be.fulfilled;
|
return expect(promise).to.be.fulfilled;
|
||||||
|
@ -1,26 +1,25 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
// jscs:disable
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
'Get tests -': {
|
'Get tests -': {
|
||||||
'Get with function': {
|
'Get with function': {
|
||||||
select: ['id, COUNT(id) as count'],
|
select: ['id, COUNT(id) as count'],
|
||||||
from: ['create_test'],
|
from: ['create_test'],
|
||||||
groupBy: ['id'],
|
groupBy: ['id'],
|
||||||
get: [],
|
get: []
|
||||||
},
|
},
|
||||||
'Basic select all get': {
|
'Basic select all get': {
|
||||||
get: ['create_test'],
|
get: ['create_test']
|
||||||
},
|
},
|
||||||
'Basic select all with from': {
|
'Basic select all with from': {
|
||||||
from: ['create_test'],
|
from: ['create_test'],
|
||||||
get: [],
|
get: []
|
||||||
},
|
},
|
||||||
'Get with limit': {
|
'Get with limit': {
|
||||||
get: ['create_test', 2],
|
get: ['create_test', 2]
|
||||||
},
|
},
|
||||||
'Get with limit and offset': {
|
'Get with limit and offset': {
|
||||||
get: ['create_test', 2, 1],
|
get: ['create_test', 2, 1]
|
||||||
},
|
},
|
||||||
'Get with having': {
|
'Get with having': {
|
||||||
select: ['id'],
|
select: ['id'],
|
||||||
@ -30,9 +29,9 @@ module.exports = {
|
|||||||
'multiple',
|
'multiple',
|
||||||
[{'id >': 1}],
|
[{'id >': 1}],
|
||||||
['id !=', 3],
|
['id !=', 3],
|
||||||
['id', 900],
|
['id', 900]
|
||||||
],
|
],
|
||||||
get: [],
|
get: []
|
||||||
},
|
},
|
||||||
'Get with orHaving': {
|
'Get with orHaving': {
|
||||||
select: ['id'],
|
select: ['id'],
|
||||||
@ -40,8 +39,8 @@ module.exports = {
|
|||||||
groupBy: ['id'],
|
groupBy: ['id'],
|
||||||
having: [{'id >': 1}],
|
having: [{'id >': 1}],
|
||||||
orHaving: ['id !=', 3],
|
orHaving: ['id !=', 3],
|
||||||
get: [],
|
get: []
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
'Select tests -': {
|
'Select tests -': {
|
||||||
'Select where get': {
|
'Select where get': {
|
||||||
@ -49,94 +48,94 @@ module.exports = {
|
|||||||
where: [
|
where: [
|
||||||
'multiple',
|
'multiple',
|
||||||
['id >', 1],
|
['id >', 1],
|
||||||
['id <', 900],
|
['id <', 900]
|
||||||
],
|
],
|
||||||
get: ['create_test', 2, 1],
|
get: ['create_test', 2, 1]
|
||||||
},
|
},
|
||||||
'Select where get 2': {
|
'Select where get 2': {
|
||||||
select: ['id, key as k, val'],
|
select: ['id, key as k, val'],
|
||||||
where: ['id !=', 1],
|
where: ['id !=', 1],
|
||||||
get: ['create_test', 2, 1],
|
get: ['create_test', 2, 1]
|
||||||
},
|
},
|
||||||
'Multi Order By': {
|
'Multi Order By': {
|
||||||
from: ['create_test'],
|
from: ['create_test'],
|
||||||
orderBy: ['id, key'],
|
orderBy: ['id, key'],
|
||||||
get: [],
|
get: []
|
||||||
},
|
},
|
||||||
'Select get': {
|
'Select get': {
|
||||||
select: ['id, key as k, val'],
|
select: ['id, key as k, val'],
|
||||||
get: ['create_test', 2, 1],
|
get: ['create_test', 2, 1]
|
||||||
},
|
},
|
||||||
'Select from get': {
|
'Select from get': {
|
||||||
select: ['id, key as k, val'],
|
select: ['id, key as k, val'],
|
||||||
from: ['create_test ct'],
|
from: ['create_test ct'],
|
||||||
where: ['id >', 1],
|
where: ['id >', 1],
|
||||||
get: [],
|
get: []
|
||||||
},
|
},
|
||||||
'Select from limit get': {
|
'Select from limit get': {
|
||||||
select: ['id, key as k, val'],
|
select: ['id, key as k, val'],
|
||||||
from: ['create_test ct'],
|
from: ['create_test ct'],
|
||||||
where: ['id >', 1],
|
where: ['id >', 1],
|
||||||
limit: [3],
|
limit: [3],
|
||||||
get: [],
|
get: []
|
||||||
},
|
},
|
||||||
'Select where IS NOT NULL': {
|
'Select where IS NOT NULL': {
|
||||||
select: ['id', 'key as k', 'val'],
|
select: ['id', 'key as k', 'val'],
|
||||||
from: ['create_test ct'],
|
from: ['create_test ct'],
|
||||||
whereIsNotNull: ['id'],
|
whereIsNotNull: ['id'],
|
||||||
get: [],
|
get: []
|
||||||
},
|
},
|
||||||
'Select where IS NULL': {
|
'Select where IS NULL': {
|
||||||
select: ['id', 'key as k', 'val'],
|
select: ['id', 'key as k', 'val'],
|
||||||
from: ['create_test ct'],
|
from: ['create_test ct'],
|
||||||
whereIsNull: ['id'],
|
whereIsNull: ['id'],
|
||||||
get: [],
|
get: []
|
||||||
},
|
},
|
||||||
'Select where OR IS NOT NULL': {
|
'Select where OR IS NOT NULL': {
|
||||||
select: ['id', 'key as k', 'val'],
|
select: ['id', 'key as k', 'val'],
|
||||||
from: ['create_test ct'],
|
from: ['create_test ct'],
|
||||||
whereIsNull: ['id'],
|
whereIsNull: ['id'],
|
||||||
orWhereIsNotNull: ['id'],
|
orWhereIsNotNull: ['id'],
|
||||||
get: [],
|
get: []
|
||||||
},
|
},
|
||||||
'Select where OR IS NULL': {
|
'Select where OR IS NULL': {
|
||||||
select: ['id', 'key as k', 'val'],
|
select: ['id', 'key as k', 'val'],
|
||||||
from: ['create_test ct'],
|
from: ['create_test ct'],
|
||||||
where: ['id', 3],
|
where: ['id', 3],
|
||||||
orWhereIsNull: ['id'],
|
orWhereIsNull: ['id'],
|
||||||
get: [],
|
get: []
|
||||||
},
|
},
|
||||||
'Select with string where value': {
|
'Select with string where value': {
|
||||||
select: ['id', 'key as k', 'val'],
|
select: ['id', 'key as k', 'val'],
|
||||||
from: ['create_test ct'],
|
from: ['create_test ct'],
|
||||||
where: ['id > 3'],
|
where: ['id > 3'],
|
||||||
get: [],
|
get: []
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
'Where in tests -': {
|
'Where in tests -': {
|
||||||
'Where in': {
|
'Where in': {
|
||||||
from: ['create_test'],
|
from: ['create_test'],
|
||||||
whereIn: ['id', [0, 6, 56, 563, 341]],
|
whereIn: ['id', [0, 6, 56, 563, 341]],
|
||||||
get: [],
|
get: []
|
||||||
},
|
},
|
||||||
'Or Where in': {
|
'Or Where in': {
|
||||||
from: ['create_test'],
|
from: ['create_test'],
|
||||||
where: ['key', 'false'],
|
where: ['key', 'false'],
|
||||||
orWhereIn: ['id', [0, 6, 56, 563, 341]],
|
orWhereIn: ['id', [0, 6, 56, 563, 341]],
|
||||||
get: [],
|
get: []
|
||||||
},
|
},
|
||||||
'Where Not in': {
|
'Where Not in': {
|
||||||
from: ['create_test'],
|
from: ['create_test'],
|
||||||
where: ['key', 'false'],
|
where: ['key', 'false'],
|
||||||
whereNotIn: ['id', [0, 6, 56, 563, 341]],
|
whereNotIn: ['id', [0, 6, 56, 563, 341]],
|
||||||
get: [],
|
get: []
|
||||||
},
|
},
|
||||||
'Or Where Not in': {
|
'Or Where Not in': {
|
||||||
from: ['create_test'],
|
from: ['create_test'],
|
||||||
where: ['key', 'false'],
|
where: ['key', 'false'],
|
||||||
orWhereNotIn: ['id', [0, 6, 56, 563, 341]],
|
orWhereNotIn: ['id', [0, 6, 56, 563, 341]],
|
||||||
get: [],
|
get: []
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
'Query modifier tests -': {
|
'Query modifier tests -': {
|
||||||
'Order By': {
|
'Order By': {
|
||||||
@ -145,15 +144,15 @@ module.exports = {
|
|||||||
where: [
|
where: [
|
||||||
'multiple',
|
'multiple',
|
||||||
['id >', 0],
|
['id >', 0],
|
||||||
['id <', 9000],
|
['id <', 9000]
|
||||||
],
|
],
|
||||||
orderBy: [
|
orderBy: [
|
||||||
'multiple',
|
'multiple',
|
||||||
['id', 'DESC'],
|
['id', 'DESC'],
|
||||||
['k', 'ASC'],
|
['k', 'ASC']
|
||||||
],
|
],
|
||||||
limit: [5, 2],
|
limit: [5, 2],
|
||||||
get: [],
|
get: []
|
||||||
},
|
},
|
||||||
'Group By': {
|
'Group By': {
|
||||||
select: ['id, key as k, val'],
|
select: ['id, key as k, val'],
|
||||||
@ -161,20 +160,20 @@ module.exports = {
|
|||||||
where: [
|
where: [
|
||||||
'multiple',
|
'multiple',
|
||||||
['id >', 0],
|
['id >', 0],
|
||||||
['id <', 9000],
|
['id <', 9000]
|
||||||
],
|
],
|
||||||
groupBy: [
|
groupBy: [
|
||||||
'multiple',
|
'multiple',
|
||||||
['k'],
|
['k'],
|
||||||
[['id', 'val']],
|
[['id', 'val']]
|
||||||
],
|
],
|
||||||
orderBy: [
|
orderBy: [
|
||||||
'multiple',
|
'multiple',
|
||||||
['id', 'DESC'],
|
['id', 'DESC'],
|
||||||
['k', 'ASC'],
|
['k', 'ASC']
|
||||||
],
|
],
|
||||||
limit: [5, 2],
|
limit: [5, 2],
|
||||||
get: [],
|
get: []
|
||||||
},
|
},
|
||||||
'Or Where': {
|
'Or Where': {
|
||||||
select: ['id, key as k, val'],
|
select: ['id, key as k, val'],
|
||||||
@ -182,55 +181,55 @@ module.exports = {
|
|||||||
where: [' id ', 1],
|
where: [' id ', 1],
|
||||||
orWhere: ['key > ', 0],
|
orWhere: ['key > ', 0],
|
||||||
limit: [2, 1],
|
limit: [2, 1],
|
||||||
get: [],
|
get: []
|
||||||
},
|
},
|
||||||
Like: {
|
Like: {
|
||||||
from: ['create_test'],
|
from: ['create_test'],
|
||||||
like: ['key', 'og'],
|
like: ['key', 'og'],
|
||||||
get: [],
|
get: []
|
||||||
},
|
},
|
||||||
'Or Like': {
|
'Or Like': {
|
||||||
from: ['create_test'],
|
from: ['create_test'],
|
||||||
like: ['key', 'og'],
|
like: ['key', 'og'],
|
||||||
orLike: ['key', 'val'],
|
orLike: ['key', 'val'],
|
||||||
get: [],
|
get: []
|
||||||
},
|
},
|
||||||
'Not Like': {
|
'Not Like': {
|
||||||
from: ['create_test'],
|
from: ['create_test'],
|
||||||
like: ['key', 'og', 'before'],
|
like: ['key', 'og', 'before'],
|
||||||
notLike: ['key', 'val'],
|
notLike: ['key', 'val'],
|
||||||
get: [],
|
get: []
|
||||||
},
|
},
|
||||||
'Or Not Like': {
|
'Or Not Like': {
|
||||||
from: ['create_test'],
|
from: ['create_test'],
|
||||||
like: ['key', 'og', 'before'],
|
like: ['key', 'og', 'before'],
|
||||||
orNotLike: ['key', 'val'],
|
orNotLike: ['key', 'val'],
|
||||||
get: [],
|
get: []
|
||||||
},
|
},
|
||||||
'Like Before': {
|
'Like Before': {
|
||||||
from: ['create_test'],
|
from: ['create_test'],
|
||||||
like: ['key', 'og', 'before'],
|
like: ['key', 'og', 'before'],
|
||||||
get: [],
|
get: []
|
||||||
},
|
},
|
||||||
'Like After': {
|
'Like After': {
|
||||||
from: ['create_test'],
|
from: ['create_test'],
|
||||||
like: ['key', 'og', 'after'],
|
like: ['key', 'og', 'after'],
|
||||||
get: [],
|
get: []
|
||||||
},
|
},
|
||||||
'Basic Join': {
|
'Basic Join': {
|
||||||
from: ['create_test ct'],
|
from: ['create_test ct'],
|
||||||
join: ['create_join cj', 'cj.id=ct.id'],
|
join: ['create_join cj', 'cj.id=ct.id'],
|
||||||
get: [],
|
get: []
|
||||||
},
|
},
|
||||||
'Left Join': {
|
'Left Join': {
|
||||||
from: ['create_test ct'],
|
from: ['create_test ct'],
|
||||||
join: ['create_join cj', 'cj.id=ct.id', 'left'],
|
join: ['create_join cj', 'cj.id=ct.id', 'left'],
|
||||||
get: [],
|
get: []
|
||||||
},
|
},
|
||||||
'Inner Join': {
|
'Inner Join': {
|
||||||
from: ['create_test ct'],
|
from: ['create_test ct'],
|
||||||
join: ['create_join cj', 'cj.id=ct.id', 'inner'],
|
join: ['create_join cj', 'cj.id=ct.id', 'inner'],
|
||||||
get: [],
|
get: []
|
||||||
},
|
},
|
||||||
'Join with multiple where values': {
|
'Join with multiple where values': {
|
||||||
from: ['create_test ct'],
|
from: ['create_test ct'],
|
||||||
@ -238,10 +237,10 @@ module.exports = {
|
|||||||
where: [
|
where: [
|
||||||
{
|
{
|
||||||
'ct.id < ': 3,
|
'ct.id < ': 3,
|
||||||
'ct.key ': 'foo',
|
'ct.key ': 'foo'
|
||||||
},
|
}
|
||||||
],
|
],
|
||||||
get: [],
|
get: []
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
};
|
};
|
@ -1,10 +1,11 @@
|
|||||||
|
/* eslint-env node, mocha */
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
let expect = require('chai').expect,
|
const expect = require('chai').expect;
|
||||||
reload = require('require-reload')(require),
|
const reload = require('require-reload')(require);
|
||||||
glob = require('glob'),
|
const glob = require('glob');
|
||||||
nodeQuery = reload('../lib/NodeQuery')(),
|
const nodeQuery = reload('../lib/NodeQuery')();
|
||||||
Adapter = reload('../lib/Adapter');
|
const Adapter = reload('../lib/Adapter');
|
||||||
|
|
||||||
suite('Base tests -', () => {
|
suite('Base tests -', () => {
|
||||||
suite('Sanity check', () => {
|
suite('Sanity check', () => {
|
||||||
@ -31,7 +32,7 @@ suite('Base tests -', () => {
|
|||||||
test('Invalid driver type', () => {
|
test('Invalid driver type', () => {
|
||||||
expect(() => {
|
expect(() => {
|
||||||
reload('../lib/NodeQuery')({
|
reload('../lib/NodeQuery')({
|
||||||
driver: 'Foo',
|
driver: 'Foo'
|
||||||
});
|
});
|
||||||
}).to.throw(Error, 'Selected driver (Foo) does not exist!');
|
}).to.throw(Error, 'Selected driver (Foo) does not exist!');
|
||||||
});
|
});
|
||||||
|
39
test/config-ci.json
Normal file
39
test/config-ci.json
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
{
|
||||||
|
"mysql2": {
|
||||||
|
"driver": "mysql",
|
||||||
|
"connection": {
|
||||||
|
"host": "mysql2",
|
||||||
|
"user": "test",
|
||||||
|
"password": "test",
|
||||||
|
"database": "test"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pg": {
|
||||||
|
"driver": "pg",
|
||||||
|
"connection": "postgres://test:test@posgres/test"
|
||||||
|
},
|
||||||
|
"pg-object": {
|
||||||
|
"driver": "pg",
|
||||||
|
"connection": {
|
||||||
|
"database": "test"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"dblite": {
|
||||||
|
"adapter": "dblite",
|
||||||
|
"driver": "sqlite",
|
||||||
|
"connection": ":memory:"
|
||||||
|
},
|
||||||
|
"sqlite3": {
|
||||||
|
"driver": "sqlite",
|
||||||
|
"connection": ":memory:"
|
||||||
|
},
|
||||||
|
"node-firebird": {
|
||||||
|
"driver": "firebird",
|
||||||
|
"connection": {
|
||||||
|
"host": "127.0.0.1",
|
||||||
|
"database": "/../FB_TEST_DB.FDB",
|
||||||
|
"user": "SYSDBA",
|
||||||
|
"password": "masterkey"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
16
test/docker_install.sh
Normal file
16
test/docker_install.sh
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# We need to install dependencies only for Docker
|
||||||
|
[[ ! -e /.dockerenv ]] && [[ ! -e /.dockerinit ]] && exit 0
|
||||||
|
|
||||||
|
# Where am I?
|
||||||
|
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||||
|
|
||||||
|
set -xe
|
||||||
|
|
||||||
|
# Install sqlite3
|
||||||
|
apt-get update -yqq
|
||||||
|
apt-get install sqlite3 libsqlite3-dev -yqq
|
||||||
|
|
||||||
|
# Replace test config with docker config file
|
||||||
|
mv "$DIR/config-ci.json" "$DIR/config.json"
|
@ -1,9 +1,9 @@
|
|||||||
|
/* eslint-env node, mocha */
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
let chai = require('chai'),
|
const chai = require('chai');
|
||||||
assert = chai.assert,
|
const assert = chai.assert;
|
||||||
expect = chai.expect,
|
const expect = chai.expect;
|
||||||
should = chai.should();
|
|
||||||
|
|
||||||
let helpers = require('../lib/helpers');
|
let helpers = require('../lib/helpers');
|
||||||
|
|
||||||
@ -35,7 +35,7 @@ suite('Helper Module Tests -', () => {
|
|||||||
'Function',
|
'Function',
|
||||||
'RegExp',
|
'RegExp',
|
||||||
'NaN',
|
'NaN',
|
||||||
'Infinite',
|
'Infinite'
|
||||||
];
|
];
|
||||||
|
|
||||||
types.forEach(type => {
|
types.forEach(type => {
|
||||||
@ -48,7 +48,7 @@ suite('Helper Module Tests -', () => {
|
|||||||
let trueCases = {
|
let trueCases = {
|
||||||
'Strings are scalar': 'foo',
|
'Strings are scalar': 'foo',
|
||||||
'Booleans are scalar': true,
|
'Booleans are scalar': true,
|
||||||
'Numbers are scalar': 545,
|
'Numbers are scalar': 545
|
||||||
};
|
};
|
||||||
Object.keys(trueCases).forEach(desc => {
|
Object.keys(trueCases).forEach(desc => {
|
||||||
test(desc, () => {
|
test(desc, () => {
|
||||||
@ -58,7 +58,7 @@ suite('Helper Module Tests -', () => {
|
|||||||
|
|
||||||
let falseCases = {
|
let falseCases = {
|
||||||
'Arrays are not scalar': [],
|
'Arrays are not scalar': [],
|
||||||
'Objects are not scalar': [],
|
'Objects are not scalar': []
|
||||||
};
|
};
|
||||||
Object.keys(falseCases).forEach(desc => {
|
Object.keys(falseCases).forEach(desc => {
|
||||||
test(desc, () => {
|
test(desc, () => {
|
||||||
@ -95,14 +95,14 @@ suite('Helper Module Tests -', () => {
|
|||||||
suite('arrayPluck -', () => {
|
suite('arrayPluck -', () => {
|
||||||
let orig = [
|
let orig = [
|
||||||
{
|
{
|
||||||
foo: 1,
|
foo: 1
|
||||||
}, {
|
}, {
|
||||||
foo: 2,
|
foo: 2,
|
||||||
bar: 10,
|
bar: 10
|
||||||
}, {
|
}, {
|
||||||
foo: 3,
|
foo: 3,
|
||||||
bar: 15,
|
bar: 15
|
||||||
},
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
test('Finding members in all objects', () => {
|
test('Finding members in all objects', () => {
|
||||||
@ -121,11 +121,11 @@ suite('Helper Module Tests -', () => {
|
|||||||
let cases = [
|
let cases = [
|
||||||
{
|
{
|
||||||
'Dollar sign is not in any of the array items': /\$/,
|
'Dollar sign is not in any of the array items': /\$/,
|
||||||
'None of the numbers in the array match /5/': /5/,
|
'None of the numbers in the array match /5/': /5/
|
||||||
}, {
|
}, {
|
||||||
'\' string \' matches /^ ?string/': /^ ?string/,
|
'\' string \' matches /^ ?string/': /^ ?string/,
|
||||||
'\'apple\' matches /APPLE/i': /APPLE/i,
|
'\'apple\' matches /APPLE/i': /APPLE/i
|
||||||
},
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
[0, 1].forEach(i => {
|
[0, 1].forEach(i => {
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
--recursive
|
--recursive
|
||||||
--reporter nyan
|
--reporter nyan
|
||||||
--slow 200
|
--slow 200
|
||||||
--timeout 10000
|
--timeout 25000
|
||||||
--check-leaks
|
--check-leaks
|
||||||
--growl
|
--growl
|
||||||
test/**/*_test.js
|
test/**/*_test.js
|
@ -1,56 +1,51 @@
|
|||||||
|
/* eslint-env node, mocha */
|
||||||
'use strict';
|
'use strict';
|
||||||
let expect = require('chai').expect;
|
const expect = require('chai').expect;
|
||||||
|
|
||||||
// Use the base driver as a mock for testing
|
// Use the base driver as a mock for testing
|
||||||
let getArgs = require('getargs');
|
const helpers = require('../lib/helpers');
|
||||||
let helpers = require('../lib/helpers');
|
const driver = require('../lib/Driver');
|
||||||
let driver = require('../lib/Driver');
|
|
||||||
|
|
||||||
let P = require('../lib/QueryParser');
|
const P = require('../lib/QueryParser');
|
||||||
let parser = new P(driver);
|
let parser = new P(driver);
|
||||||
|
|
||||||
let State = require('../lib/State');
|
const State = require('../lib/State');
|
||||||
|
|
||||||
// Simulate query builder state
|
// Simulate query builder state
|
||||||
let state = new State();
|
let state = new State();
|
||||||
|
|
||||||
let mixedSet = function mixedSet(/* $letName, $valType, $key, [$val] */) {
|
let mixedSet = function mixedSet (letName, valType, key, val) {
|
||||||
const argPattern = '$letName:string, $valType:string, $key:object|string|number, [$val]';
|
|
||||||
let args = getArgs(argPattern, arguments);
|
|
||||||
|
|
||||||
let obj = {};
|
let obj = {};
|
||||||
|
|
||||||
if (helpers.isScalar(args.$key) && !helpers.isUndefined(args.$val)) {
|
if (helpers.isScalar(key) && !helpers.isUndefined(val)) {
|
||||||
// Convert key/val pair to a simple object
|
// Convert key/val pair to a simple object
|
||||||
obj[args.$key] = args.$val;
|
obj[key] = val;
|
||||||
} else if (helpers.isScalar(args.$key) && helpers.isUndefined(args.$val)) {
|
} else if (helpers.isScalar(key) && helpers.isUndefined(val)) {
|
||||||
// If just a string for the key, and no value, create a simple object with duplicate key/val
|
// If just a string for the key, and no value, create a simple object with duplicate key/val
|
||||||
obj[args.$key] = args.$key;
|
obj[key] = key;
|
||||||
} else {
|
} else {
|
||||||
obj = args.$key;
|
obj = key;
|
||||||
}
|
}
|
||||||
|
|
||||||
Object.keys(obj).forEach(k => {
|
Object.keys(obj).forEach(k => {
|
||||||
// If a single value for the return
|
// If a single value for the return
|
||||||
if (['key', 'value'].indexOf(args.$valType) !== -1) {
|
if (['key', 'value'].indexOf(valType) !== -1) {
|
||||||
let pushVal = (args.$valType === 'key') ? k : obj[k];
|
let pushVal = (valType === 'key') ? k : obj[k];
|
||||||
state[args.$letName].push(pushVal);
|
state[letName].push(pushVal);
|
||||||
} else {
|
} else {
|
||||||
state[args.$letName][k] = obj[k];
|
state[letName][k] = obj[k];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return state[args.$letName];
|
return state[letName];
|
||||||
};
|
};
|
||||||
|
|
||||||
let whereMock = function () {
|
let whereMock = function (key, val) {
|
||||||
let args = getArgs('key:string|object, [val]', arguments);
|
|
||||||
|
|
||||||
state.whereMap = [];
|
state.whereMap = [];
|
||||||
state.whereValues = [];
|
state.whereValues = [];
|
||||||
|
|
||||||
mixedSet('rawWhereValues', 'value', args.key, args.val);
|
mixedSet('rawWhereValues', 'value', key, val);
|
||||||
mixedSet('whereMap', 'both', args.key, args.val);
|
mixedSet('whereMap', 'both', key, val);
|
||||||
};
|
};
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
@ -86,7 +81,7 @@ suite('Query Parser Tests', () => {
|
|||||||
});
|
});
|
||||||
test('Has function key/val object', () => {
|
test('Has function key/val object', () => {
|
||||||
whereMock({
|
whereMock({
|
||||||
'time <': 'SUM(FOO(BAR(\'x\')))',
|
'time <': 'SUM(FOO(BAR(\'x\')))'
|
||||||
});
|
});
|
||||||
parser.parseWhere(driver, state);
|
parser.parseWhere(driver, state);
|
||||||
expect(state.whereMap)
|
expect(state.whereMap)
|
||||||
@ -94,7 +89,7 @@ suite('Query Parser Tests', () => {
|
|||||||
});
|
});
|
||||||
test('Has literal value', () => {
|
test('Has literal value', () => {
|
||||||
whereMock({
|
whereMock({
|
||||||
foo: 3,
|
foo: 3
|
||||||
});
|
});
|
||||||
parser.parseWhere(driver, state);
|
parser.parseWhere(driver, state);
|
||||||
expect(state.whereMap)
|
expect(state.whereMap)
|
||||||
@ -105,7 +100,7 @@ suite('Query Parser Tests', () => {
|
|||||||
test('Has multiple literal values', () => {
|
test('Has multiple literal values', () => {
|
||||||
whereMock({
|
whereMock({
|
||||||
foo: 3,
|
foo: 3,
|
||||||
bar: 5,
|
bar: 5
|
||||||
});
|
});
|
||||||
parser.parseWhere(driver, state);
|
parser.parseWhere(driver, state);
|
||||||
expect(state.whereMap)
|
expect(state.whereMap)
|
||||||
@ -119,20 +114,20 @@ suite('Query Parser Tests', () => {
|
|||||||
{
|
{
|
||||||
desc: 'Simple equals condition',
|
desc: 'Simple equals condition',
|
||||||
join: 'table1.field1=table2.field2',
|
join: 'table1.field1=table2.field2',
|
||||||
expected: ['table1.field1', '=', 'table2.field2'],
|
expected: ['table1.field1', '=', 'table2.field2']
|
||||||
}, {
|
}, {
|
||||||
desc: 'Db.table.field condition',
|
desc: 'Db.table.field condition',
|
||||||
join: 'db1.table1.field1!=db2.table2.field2',
|
join: 'db1.table1.field1!=db2.table2.field2',
|
||||||
expected: ['db1.table1.field1', '!=', 'db2.table2.field2'],
|
expected: ['db1.table1.field1', '!=', 'db2.table2.field2']
|
||||||
}, {
|
}, {
|
||||||
desc: 'Underscore in identifier',
|
desc: 'Underscore in identifier',
|
||||||
join: 'table_1.field1 = tab_le2.field_2',
|
join: 'table_1.field1 = tab_le2.field_2',
|
||||||
expected: ['table_1.field1', '=', 'tab_le2.field_2'],
|
expected: ['table_1.field1', '=', 'tab_le2.field_2']
|
||||||
}, {
|
}, {
|
||||||
desc: 'Function in condition',
|
desc: 'Function in condition',
|
||||||
join: 'table1.field1 > SUM(3+6)',
|
join: 'table1.field1 > SUM(3+6)',
|
||||||
expected: ['table1.field1', '>', 'SUM(3+6)'],
|
expected: ['table1.field1', '>', 'SUM(3+6)']
|
||||||
},
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
data.forEach(datum => {
|
data.forEach(datum => {
|
||||||
@ -147,20 +142,20 @@ suite('Query Parser Tests', () => {
|
|||||||
{
|
{
|
||||||
desc: 'Simple equals condition',
|
desc: 'Simple equals condition',
|
||||||
clause: 'table1.field1=table2.field2',
|
clause: 'table1.field1=table2.field2',
|
||||||
expected: '"table1"."field1" = "table2"."field2"',
|
expected: '"table1"."field1" = "table2"."field2"'
|
||||||
}, {
|
}, {
|
||||||
desc: 'Db.table.field condition',
|
desc: 'Db.table.field condition',
|
||||||
clause: 'db1.table1.field1!=db2.table2.field2',
|
clause: 'db1.table1.field1!=db2.table2.field2',
|
||||||
expected: '"db1"."table1"."field1" != "db2"."table2"."field2"',
|
expected: '"db1"."table1"."field1" != "db2"."table2"."field2"'
|
||||||
}, {
|
}, {
|
||||||
desc: 'Underscore in identifier',
|
desc: 'Underscore in identifier',
|
||||||
clause: 'table_1.field1 = tab_le2.field_2',
|
clause: 'table_1.field1 = tab_le2.field_2',
|
||||||
expected: '"table_1"."field1" = "tab_le2"."field_2"',
|
expected: '"table_1"."field1" = "tab_le2"."field_2"'
|
||||||
}, {
|
}, {
|
||||||
desc: 'Function in condition',
|
desc: 'Function in condition',
|
||||||
clause: 'table1.field1 > SUM(3+6)',
|
clause: 'table1.field1 > SUM(3+6)',
|
||||||
expected: '"table1"."field1" > SUM(3+6)',
|
expected: '"table1"."field1" > SUM(3+6)'
|
||||||
},
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
data.forEach(datum => {
|
data.forEach(datum => {
|
||||||
|
15
test/sql/mssql.sql
Normal file
15
test/sql/mssql.sql
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
DROP TABLE IF EXISTS [create_join];
|
||||||
|
DROP TABLE IF EXISTS [create_test];
|
||||||
|
|
||||||
|
-- Table create_join
|
||||||
|
CREATE TABLE [create_join] (
|
||||||
|
[id] INTEGER,
|
||||||
|
[key] VARCHAR(255),
|
||||||
|
[val] NVARCHAR(2048)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE [create_test] (
|
||||||
|
[id] INTEGER,
|
||||||
|
[key] VARCHAR(255),
|
||||||
|
[val] NVARCHAR(2048)
|
||||||
|
);
|
@ -1,11 +1,10 @@
|
|||||||
-- sample data to test MySQL
|
-- sample data to test MySQL
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Table structure for table `create_join`
|
-- Table structure for table `create_join`
|
||||||
--
|
--
|
||||||
|
|
||||||
DROP TABLE IF EXISTS `create_join`;
|
DROP TABLE IF EXISTS `create_join` CASCADE;
|
||||||
CREATE TABLE `create_join` (
|
CREATE TABLE `create_join` (
|
||||||
`id` int(10) NOT NULL,
|
`id` int(10) NOT NULL,
|
||||||
`key` text,
|
`key` text,
|
||||||
@ -18,7 +17,7 @@ ALTER TABLE `create_join`
|
|||||||
-- Table structure for table `create_test`
|
-- Table structure for table `create_test`
|
||||||
--
|
--
|
||||||
|
|
||||||
DROP TABLE IF EXISTS `create_test`;
|
DROP TABLE IF EXISTS `create_test` CASCADE;
|
||||||
CREATE TABLE `create_test` (
|
CREATE TABLE `create_test` (
|
||||||
`id` int(10) NOT NULL,
|
`id` int(10) NOT NULL,
|
||||||
`key` text,
|
`key` text,
|
||||||
|
@ -1,13 +1,15 @@
|
|||||||
-- sample data to test PostgreSQL INFORMATION_SCHEMA
|
-- sample data to test PostgreSQL INFORMATION_SCHEMA
|
||||||
|
DROP TABLE IF EXISTS "create_join" CASCADE;
|
||||||
|
DROP TABLE IF EXISTS "create_test" CASCADE;
|
||||||
|
|
||||||
-- Table create_join
|
-- Table create_join
|
||||||
CREATE TABLE create_join (
|
CREATE TABLE "create_join" (
|
||||||
id integer NOT NULL,
|
id integer NOT NULL,
|
||||||
key text,
|
key text,
|
||||||
val text
|
val text
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE create_test (
|
CREATE TABLE "create_test" (
|
||||||
id integer NOT NULL,
|
id integer NOT NULL,
|
||||||
key text,
|
key text,
|
||||||
val text
|
val text
|
||||||
|
Loading…
Reference in New Issue
Block a user