Version 5.0.0

* Remove callback interface
* Add updateBatch command
This commit is contained in:
Timothy Warren 2018-02-12 15:37:33 -05:00
commit 9fa2ddefa1
122 changed files with 26819 additions and 1952 deletions

View File

@ -1,38 +1,43 @@
{
"env": {
"node": true,
"es6": true
"commonjs": true,
"es6": true,
"jest": true,
"node": true
},
"extends": ["eslint:recommended", "happiness"],
"rules": {
"arrow-parens": [2, "as-needed"],
"no-console": [1],
"no-constant-condition": [1],
"no-extra-semi": [1],
"no-func-assign": [1],
"no-obj-calls": [2],
"no-unexpected-multiline" : [2],
"no-unneeded-ternary": [2],
"radix": [2],
"no-with": [2],
"no-eval": [2],
"no-unreachable": [1],
"no-irregular-whitespace": [1],
"no-new-wrappers": [2],
"no-new-func": [2],
"curly" : [2, "multi-line"],
"no-implied-eval": [2],
"no-invalid-this": [2],
"constructor-super": [2],
"no-dupe-args": [2],
"no-dupe-keys": [2],
"no-dupe-class-members": [2],
"no-this-before-super": [2],
"prefer-arrow-callback": [1],
"no-var": [2],
"valid-jsdoc": [1],
"strict": [2, "global"],
"callback-return": [1],
"object-shorthand": [1, "methods"],
"prefer-template": [1]
}
"arrow-parens": ["error", "as-needed"],
"callback-return": ["warn"],
"constructor-super": ["error"],
"curly" : ["error", "multi-line"],
"no-case-declarations": "off",
"no-console": ["warn"],
"no-constant-condition": ["warn"],
"no-dupe-args": ["error"],
"no-dupe-class-members": ["error"],
"no-dupe-keys": ["error"],
"no-eval": ["error"],
"no-extra-semi": ["warn"],
"no-func-assign": ["warn"],
"no-implied-eval": ["error"],
"no-invalid-this": ["error"],
"no-irregular-whitespace": ["warn"],
"no-new-func": ["error"],
"no-new-wrappers": ["error"],
"no-obj-calls": ["error"],
"no-this-before-super": ["error"],
"no-unexpected-multiline" : ["error"],
"no-unneeded-ternary": ["error"],
"no-unreachable": ["warn"],
"no-var": ["error"],
"no-with": ["error"],
"object-shorthand": ["warn", "methods"],
"prefer-arrow-callback": ["warn"],
"prefer-template": ["warn"],
"radix": ["error"],
"strict": ["error", "global"],
"valid-jsdoc": ["warn"]
},
"parser": "babel-eslint"
}

View File

@ -1,11 +1,11 @@
before_script:
# Install dependencies
- bash test/docker_install.sh > /dev/null
- npm install
- sh test/docker_install.sh > /dev/null
- yarn
services:
- mysql:latest
- postgres:latest
- mariadb:latest
- postgres:alpine
variables:
MYSQL_ROOT_PASSWORD: foo-bar-baz
@ -22,10 +22,14 @@ cache:
paths:
- node_modules/
test:6:
image: node:6
script: npm run test
test:8:
image: node:8-alpine
script: yarn run test
test:9:
image: node:9-alpine
script: yarn run test
test:latest:
image: node:latest
script: npm run test
image: node:alpine
script: yarn run test

View File

@ -1,9 +0,0 @@
reporting:
print: summary
reports:
- lcov
- lcovonly
- clover
- html
- text
dir: ./coverage

359
API.md
View File

@ -1,49 +1,71 @@
<!-- Generated by documentation.js. Update this documentation by updating the source code. -->
# NodeQuery
### Table of Contents
- [NodeQuery](#nodequery)
- [getQuery](#getquery)
- [QueryBuilder](#querybuilder)
- [queryFile](#queryfile)
- [query](#query)
- [resetQuery](#resetquery)
- [truncate](#truncate)
- [end](#end)
- [select](#select)
- [from](#from)
- [like](#like)
- [notLike](#notlike)
- [orLike](#orlike)
- [orNotLike](#ornotlike)
- [having](#having)
- [orHaving](#orhaving)
- [where](#where)
- [orWhere](#orwhere)
- [whereIsNull](#whereisnull)
- [whereIsNotNull](#whereisnotnull)
- [orWhereIsNull](#orwhereisnull)
- [orWhereIsNotNull](#orwhereisnotnull)
- [whereIn](#wherein)
- [orWhereIn](#orwherein)
- [whereNotIn](#wherenotin)
- [orWhereNotIn](#orwherenotin)
- [set](#set)
- [join](#join)
- [groupBy](#groupby)
- [orderBy](#orderby)
- [limit](#limit)
- [groupStart](#groupstart)
- [orGroupStart](#orgroupstart)
- [orNotGroupStart](#ornotgroupstart)
- [groupEnd](#groupend)
- [get](#get)
- [insert](#insert)
- [insertBatch](#insertbatch)
- [update](#update)
- [updateBatch](#updatebatch)
- [delete](#delete)
- [getCompiledSelect](#getcompiledselect)
- [getCompiledInsert](#getcompiledinsert)
- [getCompiledUpdate](#getcompiledupdate)
- [getCompiledDelete](#getcompileddelete)
- [Result](#result)
- [rowCount](#rowcount)
- [columnCount](#columncount)
## NodeQuery
Class for connection management
**Parameters**
- `config` **[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** connection parameters
- `config` **[object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** connection parameters
## constructor
Constructor
**Parameters**
- `config` **[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** connection parameters
**Examples**
```javascript
let nodeQuery = require('ci-node-query')({
driver: 'mysql',
connection: {
host: 'localhost',
user: 'root',
password: '',
database: 'mysql'
}
});
```
```javascript
let nodeQuery = require('ci-node-query')({
driver: 'sqlite',
connection: ':memory:'
});
```
## getQuery
### getQuery
Return an existing query builder instance
Returns **[QueryBuilder](#querybuilder)** The Query Builder object
# QueryBuilder
## QueryBuilder
**Extends QueryBuilderBase**
@ -54,46 +76,57 @@ Main object that builds SQL queries.
- `Driver` **Driver** The syntax driver for the database
- `Adapter` **Adapter** The database module adapter for running queries
## query
### queryFile
Run a set of queries from a file
**Parameters**
- `file` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** The path to the sql file
- `separator` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** The character separating each query (optional, default `';'`)
Returns **[Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)** The result of all the queries
### query
Run an arbitrary sql query. Run as a prepared statement.
**Parameters**
- `sql` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** The sql to execute
- `params` **\[[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)]** The query parameters
- `sql` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** The sql to execute
- `params` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)?** The query parameters
Returns **[Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)** Promise with result of query
Returns **[Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)** Promise with result of query
## resetQuery
### resetQuery
Reset the object state for a new query
Returns **void**
## truncate
### 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
- `table` **[string](https://developer.mozilla.org/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
Returns **(void | [Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise))** Returns a promise if no callback is supplied
## end
### end
Closes the database connection for the current adapter
Returns **void**
## select
### select
Specify rows to select in the query
**Parameters**
- `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
- `fields` **([String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) \| [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array))** The fields to select from the current table
**Examples**
@ -107,13 +140,13 @@ query.select(['foo', 'bar']); // Select multiple fileds with an array
Returns **[QueryBuilder](#querybuilder)** The Query Builder object, for chaining
## from
### 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
- `tableName` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** The table to use for the current query
**Examples**
@ -127,190 +160,190 @@ query.from('tableName t'); // Select the table with an alias
Returns **[QueryBuilder](#querybuilder)** The Query Builder object, for chaining
## like
### 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`)
- `field` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** The name of the field to compare to
- `val` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** The value to compare to
- `pos` **[String](https://developer.mozilla.org/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
### 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`)
- `field` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** The name of the field to compare to
- `val` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** The value to compare to
- `pos` **[String](https://developer.mozilla.org/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
### 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`)
- `field` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** The name of the field to compare to
- `val` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** The value to compare to
- `pos` **[String](https://developer.mozilla.org/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
### 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`)
- `field` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** The name of the field to compare to
- `val` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** The value to compare to
- `pos` **[String](https://developer.mozilla.org/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
### 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
- `key` **([String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) \| [Object](https://developer.mozilla.org/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/docs/Web/JavaScript/Reference/Global_Objects/String) \| [Number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number))?** The value to compare if the value of key is a string (optional, default `null`)
Returns **[QueryBuilder](#querybuilder)** The Query Builder object, for chaining
## orHaving
### 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
- `key` **([String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) \| [Object](https://developer.mozilla.org/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/docs/Web/JavaScript/Reference/Global_Objects/String) \| [Number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number))?** The value to compare if the value of key is a string (optional, default `null`)
Returns **[QueryBuilder](#querybuilder)** The Query Builder object, for chaining
## where
### 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
- `key` **([String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) \| [Object](https://developer.mozilla.org/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/docs/Web/JavaScript/Reference/Global_Objects/String) \| [Number](https://developer.mozilla.org/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
### 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
- `key` **([String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) \| [Object](https://developer.mozilla.org/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/docs/Web/JavaScript/Reference/Global_Objects/String) \| [Number](https://developer.mozilla.org/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
### 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
- `field` **[String](https://developer.mozilla.org/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
### 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
- `field` **[String](https://developer.mozilla.org/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
### 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
- `field` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** The name of the field
Returns **[QueryBuilder](#querybuilder)** The Query Builder object, for chaining
## orWhereIsNotNull
### 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
- `field` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** The name of the field
Returns **[QueryBuilder](#querybuilder)** The Query Builder object, for chaining
## whereIn
### 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
- `key` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** the field to search
- `values` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)** the array of items to search in
Returns **[QueryBuilder](#querybuilder)** The Query Builder object, for chaining
## orWhereIn
### 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
- `key` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** the field to search
- `values` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)** the array of items to search in
Returns **[QueryBuilder](#querybuilder)** The Query Builder object, for chaining
## whereNotIn
### 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
- `key` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** the field to search
- `values` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)** the array of items to search in
Returns **[QueryBuilder](#querybuilder)** The Query Builder object, for chaining
## orWhereNotIn
### 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
- `key` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** the field to search
- `values` **[Array](https://developer.mozilla.org/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
Set values for insertion or updating
**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 key or object to use
- `val` **\[[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)]** The value if using a scalar key
- `key` **([String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) \| [Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object))** The key or object to use
- `val` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** The value if using a scalar key
**Examples**
@ -324,85 +357,85 @@ query.set({foo:'bar'}); // Set with an object
Returns **[QueryBuilder](#querybuilder)** The Query Builder object, for chaining
## join
### join
Add a join clause to the query
**Parameters**
- `table` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** The table you are joining
- `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'`)
- `table` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** The table you are joining
- `cond` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** The join condition.
- `type` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** The type of join, which defaults to inner (optional, default `'inner'`)
Returns **[QueryBuilder](#querybuilder)** The Query Builder object, for chaining
## groupBy
### 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
- `field` **([String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) \| [Array](https://developer.mozilla.org/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
### 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'`)
- `field` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** The field(s) to order by
- `type` **[String](https://developer.mozilla.org/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
### 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
- `limit` **[Number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** The maximum number of rows to fetch
- `offset` **[Number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)?** The row number to start from
Returns **[QueryBuilder](#querybuilder)** The Query Builder object, for chaining
## groupStart
### groupStart
Adds an open paren to the current query for logical grouping
Returns **[QueryBuilder](#querybuilder)** The Query Builder object, for chaining
## orGroupStart
### 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
### 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
### groupEnd
Ends a logical grouping started with one of the groupStart methods
Returns **[QueryBuilder](#querybuilder)** The Query Builder object, for chaining
## get
### 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
- `table` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** The table to select from
- `limit` **[Number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)?** A limit for the query
- `offset` **[Number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)?** An offset for the query
**Examples**
@ -418,27 +451,27 @@ query.get('table_name', 5); // Get 5 rows from the table
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)&lt;[Result](#result)>** Promise containing the result of the query
Returns **[Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)&lt;[Result](#result)>** Promise containing the result of the query
## insert
### 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
- `table` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** The table to insert into
- `data` **[Object](https://developer.mozilla.org/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)&lt;[Result](#result)>** Promise containing the result of the query
Returns **[Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)&lt;[Result](#result)>** Promise containing the result of the query
## insertBatch
### 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
- `table` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** The table to insert into
- `data` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)** The array of objects containing data rows to insert
**Examples**
@ -447,91 +480,103 @@ 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)&lt;[Result](#result)>** Promise containing the result of the query
Returns **[Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)&lt;[Result](#result)>** Promise containing the result of the query
## update
### update
Run the generated update 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
- `table` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** The table to insert into
- `data` **[Object](https://developer.mozilla.org/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)&lt;[Result](#result)>** Promise containing the result of the query
Returns **[Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)&lt;[Result](#result)>** Promise containing the result of the query
## delete
### updateBatch
Creates a batch update sql statement
**Parameters**
- `table` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** The table to update
- `data` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** Batch insert data
- `updateKey` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** The field in the table to compare against for updating
Returns **[Number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** Number of rows updated
### delete
Run the generated delete query
**Parameters**
- `table` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** The table to insert into
- `where` **\[[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)]** Where clause for delete statement
- `table` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** The table to insert into
- `where` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)?** Where clause for delete statement
Returns **[Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)&lt;[Result](#result)>** Promise containing the result of the query
Returns **[Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)&lt;[Result](#result)>** Promise containing the result of the query
## getCompiledSelect
### getCompiledSelect
Return generated select query SQL
**Parameters**
- `table` **\[[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)]** the name of the table to retrieve from
- `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`)
- `table` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** the name of the table to retrieve from
- `reset` **[Boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Whether to reset the query builder so another query can be built (optional, default `true`)
Returns **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** The compiled sql statement
Returns **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** The compiled sql statement
## getCompiledInsert
### getCompiledInsert
Return generated insert query SQL
**Parameters**
- `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`)
- `table` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** the name of the table to insert into
- `reset` **[Boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Whether to reset the query builder so another query can be built (optional, default `true`)
Returns **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** The compiled sql statement
Returns **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** The compiled sql statement
## getCompiledUpdate
### getCompiledUpdate
Return generated update query SQL
**Parameters**
- `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`)
- `table` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** the name of the table to update
- `reset` **[Boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Whether to reset the query builder so another query can be built (optional, default `true`)
Returns **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** The compiled sql statement
Returns **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** The compiled sql statement
## getCompiledDelete
### getCompiledDelete
Return generated delete query SQL
**Parameters**
- `table` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** the name of the table to delete from
- `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`)
- `table` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** the name of the table to delete from
- `reset` **[Boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Whether to reset the query builder so another query can be built (optional, default `true`)
Returns **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** The compiled sql statement
Returns **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** The compiled sql statement
# Result
## Result
Query result object
**Parameters**
- `rows` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)** the data rows of the result
- `columns` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)** the column names in the result
- `rows` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)** the data rows of the result (optional, default `[]`)
- `columns` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)** the column names in the result (optional, default `[]`)
## rowCount
### rowCount
Get the number of rows returned by the query
Returns **[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** the number of rows in the result
Returns **[Number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** the number of rows in the result
## columnCount
### 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
Returns **[Number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** the number of columns in the result

View File

@ -9,7 +9,6 @@ A node query builder for various SQL databases, based on [CodeIgniter](http://ww
### Supported databases
* Firebird (via `node-firebird`)
* Mysql (via `mysql2`)
* PostgreSQL (via `pg`)
* Sqlite (via `dblite`)

33
docker-compose.yml Normal file
View File

@ -0,0 +1,33 @@
mariadb:
image: mariadb:latest
environment:
- MYSQL_USER=test
- MYSQL_PASSWORD=test
- MYSQL_DATABASE=test
- MYSQL_RANDOM_ROOT_PASSWORD=yes
ports:
- 3306:3306
postgresql:
image: postgres:latest
environment:
- POSTGRES_USER=test
- POSTGRES_PASSWORD=test
- POSTGRES_DB=test
ports:
- 5432:5432
sqlserver:
image: microsoft/mssql-server-linux
environment:
- ACCEPT_EULA=Y
- SA_PASSWORD=t3571ng0n1y
ports:
- 1433:1433
firebird:
image: itherz/firebird3:latest
ports:
- 5040:5040
volumes:
- ./test:/databases

View File

@ -1,52 +1,107 @@
/*!
* AnchorJS - v1.2.1 - 2015-07-02
* AnchorJS - v4.0.0 - 2017-06-02
* https://github.com/bryanbraun/anchorjs
* Copyright (c) 2015 Bryan Braun; Licensed MIT
* Copyright (c) 2017 Bryan Braun; Licensed MIT
*/
/* eslint-env amd, node */
function AnchorJS(options) {
// https://github.com/umdjs/umd/blob/master/templates/returnExports.js
(function(root, factory) {
'use strict';
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define([], factory);
} else if (typeof module === 'object' && module.exports) {
// Node. Does not work with strict CommonJS, but
// only CommonJS-like environments that support module.exports,
// like Node.
module.exports = factory();
} else {
// Browser globals (root is window)
root.AnchorJS = factory();
root.anchors = new root.AnchorJS();
}
})(this, function() {
'use strict';
function AnchorJS(options) {
this.options = options || {};
this.elements = [];
this._applyRemainingDefaultOptions = function(opts) {
this.options.icon = this.options.hasOwnProperty('icon') ? opts.icon : '\ue9cb'; // Accepts characters (and also URLs?), like '#', '¶', '❡', or '§'.
this.options.visible = this.options.hasOwnProperty('visible') ? opts.visible : 'hover'; // Also accepts 'always'
this.options.placement = this.options.hasOwnProperty('placement') ? opts.placement : 'right'; // Also accepts 'left'
this.options.class = this.options.hasOwnProperty('class') ? opts.class : ''; // Accepts any class name.
/**
* Assigns options to the internal options object, and provides defaults.
* @param {Object} opts - Options object
*/
function _applyRemainingDefaultOptions(opts) {
opts.icon = opts.hasOwnProperty('icon') ? opts.icon : '\ue9cb'; // Accepts characters (and also URLs?), like '#', '¶', '❡', or '§'.
opts.visible = opts.hasOwnProperty('visible') ? opts.visible : 'hover'; // Also accepts 'always' & 'touch'
opts.placement = opts.hasOwnProperty('placement')
? opts.placement
: 'right'; // Also accepts 'left'
opts.class = opts.hasOwnProperty('class') ? opts.class : ''; // Accepts any class name.
// Using Math.floor here will ensure the value is Number-cast and an integer.
opts.truncate = opts.hasOwnProperty('truncate')
? Math.floor(opts.truncate)
: 64; // Accepts any value that can be typecast to a number.
}
_applyRemainingDefaultOptions(this.options);
/**
* Checks to see if this device supports touch. Uses criteria pulled from Modernizr:
* https://github.com/Modernizr/Modernizr/blob/da22eb27631fc4957f67607fe6042e85c0a84656/feature-detects/touchevents.js#L40
* @returns {Boolean} - true if the current device supports touch.
*/
this.isTouchDevice = function() {
return !!(
'ontouchstart' in window ||
(window.DocumentTouch && document instanceof DocumentTouch)
);
};
this._applyRemainingDefaultOptions(options);
/**
* Add anchor links to page elements.
* @param {String|Array|Nodelist} selector - A CSS selector for targeting the elements you wish to add anchor links
* to. Also accepts an array or nodeList containing the relavant elements.
* @returns {this} - The AnchorJS object
*/
this.add = function(selector) {
var elements,
elsWithIds,
idList,
elementID,
i,
roughText,
tidyText,
index,
count,
tidyText,
newTidyText,
readableID,
anchor;
anchor,
visibleOptionToUse,
indexesToDrop = [];
this._applyRemainingDefaultOptions(this.options);
// We reapply options here because somebody may have overwritten the default options object when setting options.
// For example, this overwrites all options but visible:
//
// anchors.options = { visible: 'always'; }
_applyRemainingDefaultOptions(this.options);
visibleOptionToUse = this.options.visible;
if (visibleOptionToUse === 'touch') {
visibleOptionToUse = this.isTouchDevice() ? 'always' : 'hover';
}
// Provide a sensible default selector, if none is given.
if (!selector) {
selector = 'h1, h2, h3, h4, h5, h6';
} else if (typeof selector !== 'string') {
throw new Error('The selector provided to AnchorJS was invalid.');
selector = 'h2, h3, h4, h5, h6';
}
elements = document.querySelectorAll(selector);
elements = _getElements(selector);
if (elements.length === 0) {
return false;
return this;
}
this._addBaselineStyles();
_addBaselineStyles();
// We produce a list of existing IDs so we don't generate a duplicate.
elsWithIds = document.querySelectorAll('[id]');
@ -55,22 +110,17 @@ function AnchorJS(options) {
});
for (i = 0; i < elements.length; i++) {
if (this.hasAnchorJSLink(elements[i])) {
indexesToDrop.push(i);
continue;
}
if (elements[i].hasAttribute('id')) {
elementID = elements[i].getAttribute('id');
} else if (elements[i].hasAttribute('data-anchor-id')) {
elementID = elements[i].getAttribute('data-anchor-id');
} else {
roughText = elements[i].textContent;
// Refine it so it makes a good ID. Strip out non-safe characters, replace
// spaces with hyphens, truncate to 32 characters, and make toLowerCase.
//
// Example string: // '⚡⚡⚡ Unicode icons are cool--but they definitely don't belong in a URL fragment.'
tidyText = roughText.replace(/[^\w\s-]/gi, '') // ' Unicode icons are cool--but they definitely dont belong in a URL fragment'
.replace(/\s+/g, '-') // '-Unicode-icons-are-cool--but-they-definitely-dont-belong-in-a-URL-fragment'
.replace(/-{2,}/g, '-') // '-Unicode-icons-are-cool-but-they-definitely-dont-belong-in-a-URL-fragment'
.substring(0, 64) // '-Unicode-icons-are-cool-but-they-definitely-dont-belong-in-a-URL'
.replace(/^-+|-+$/gm, '') // 'Unicode-icons-are-cool-but-they-definitely-dont-belong-in-a-URL'
.toLowerCase(); // 'unicode-icons-are-cool-but-they-definitely-dont-belong-in-a-url'
tidyText = this.urlify(elements[i].textContent);
// Compare our generated ID to existing IDs (and increment it if needed)
// before we add it to the page.
@ -80,17 +130,14 @@ function AnchorJS(options) {
if (index !== undefined) {
newTidyText = tidyText + '-' + count;
}
// .indexOf is supported in IE9+.
index = idList.indexOf(newTidyText);
count += 1;
} while (index !== -1);
index = undefined;
idList.push(newTidyText);
// Assign it to our element.
// Currently the setAttribute element is only supported in IE9 and above.
elements[i].setAttribute('id', newTidyText);
elementID = newTidyText;
}
@ -104,16 +151,20 @@ function AnchorJS(options) {
anchor.setAttribute('aria-label', 'Anchor link for: ' + readableID);
anchor.setAttribute('data-anchorjs-icon', this.options.icon);
if (this.options.visible === 'always') {
if (visibleOptionToUse === 'always') {
anchor.style.opacity = '1';
}
if (this.options.icon === '\ue9cb') {
anchor.style.fontFamily = 'anchorjs-icons';
anchor.style.fontStyle = 'normal';
anchor.style.fontVariant = 'normal';
anchor.style.fontWeight = 'normal';
anchor.style.lineHeight = 1;
anchor.style.font = '1em/1 anchorjs-icons';
// We set lineHeight = 1 here because the `anchorjs-icons` font family could otherwise affect the
// height of the heading. This isn't the case for icons with `placement: left`, so we restore
// line-height: inherit in that case, ensuring they remain positioned correctly. For more info,
// see https://github.com/bryanbraun/anchorjs/issues/39.
if (this.options.placement === 'left') {
anchor.style.lineHeight = 'inherit';
}
}
if (this.options.placement === 'left') {
@ -121,28 +172,131 @@ function AnchorJS(options) {
anchor.style.marginLeft = '-1em';
anchor.style.paddingRight = '0.5em';
elements[i].insertBefore(anchor, elements[i].firstChild);
} else { // if the option provided is `right` (or anything else).
} else {
// if the option provided is `right` (or anything else).
anchor.style.paddingLeft = '0.375em';
elements[i].appendChild(anchor);
}
}
for (i = 0; i < indexesToDrop.length; i++) {
elements.splice(indexesToDrop[i] - i, 1);
}
this.elements = this.elements.concat(elements);
return this;
};
/**
* Removes all anchorjs-links from elements targed by the selector.
* @param {String|Array|Nodelist} selector - A CSS selector string targeting elements with anchor links,
* OR a nodeList / array containing the DOM elements.
* @returns {this} - The AnchorJS object
*/
this.remove = function(selector) {
var domAnchor,
elements = document.querySelectorAll(selector);
var index,
domAnchor,
elements = _getElements(selector);
for (var i = 0; i < elements.length; i++) {
domAnchor = elements[i].querySelector('.anchorjs-link');
if (domAnchor) {
// Drop the element from our main list, if it's in there.
index = this.elements.indexOf(elements[i]);
if (index !== -1) {
this.elements.splice(index, 1);
}
// Remove the anchor from the DOM.
elements[i].removeChild(domAnchor);
}
}
return this;
};
this._addBaselineStyles = function() {
/**
* Removes all anchorjs links. Mostly used for tests.
*/
this.removeAll = function() {
this.remove(this.elements);
};
/**
* Urlify - Refine text so it makes a good ID.
*
* To do this, we remove apostrophes, replace nonsafe characters with hyphens,
* remove extra hyphens, truncate, trim hyphens, and make lowercase.
*
* @param {String} text - Any text. Usually pulled from the webpage element we are linking to.
* @returns {String} - hyphen-delimited text for use in IDs and URLs.
*/
this.urlify = function(text) {
// Regex for finding the nonsafe URL characters (many need escaping): & +$,:;=?@"#{}|^~[`%!'<>]./()*\
var nonsafeChars = /[& +$,:;=?@"#{}|^~[`%!'<>\]\.\/\(\)\*\\]/g,
urlText;
// The reason we include this _applyRemainingDefaultOptions is so urlify can be called independently,
// even after setting options. This can be useful for tests or other applications.
if (!this.options.truncate) {
_applyRemainingDefaultOptions(this.options);
}
// Note: we trim hyphens after truncating because truncating can cause dangling hyphens.
// Example string: // " ⚡⚡ Don't forget: URL fragments should be i18n-friendly, hyphenated, short, and clean."
urlText = text
.trim() // "⚡⚡ Don't forget: URL fragments should be i18n-friendly, hyphenated, short, and clean."
.replace(/\'/gi, '') // "⚡⚡ Dont forget: URL fragments should be i18n-friendly, hyphenated, short, and clean."
.replace(nonsafeChars, '-') // "⚡⚡-Dont-forget--URL-fragments-should-be-i18n-friendly--hyphenated--short--and-clean-"
.replace(/-{2,}/g, '-') // "⚡⚡-Dont-forget-URL-fragments-should-be-i18n-friendly-hyphenated-short-and-clean-"
.substring(0, this.options.truncate) // "⚡⚡-Dont-forget-URL-fragments-should-be-i18n-friendly-hyphenated-"
.replace(/^-+|-+$/gm, '') // "⚡⚡-Dont-forget-URL-fragments-should-be-i18n-friendly-hyphenated"
.toLowerCase(); // "⚡⚡-dont-forget-url-fragments-should-be-i18n-friendly-hyphenated"
return urlText;
};
/**
* Determines if this element already has an AnchorJS link on it.
* Uses this technique: http://stackoverflow.com/a/5898748/1154642
* @param {HTMLElemnt} el - a DOM node
* @returns {Boolean} true/false
*/
this.hasAnchorJSLink = function(el) {
var hasLeftAnchor =
el.firstChild &&
(' ' + el.firstChild.className + ' ').indexOf(' anchorjs-link ') > -1,
hasRightAnchor =
el.lastChild &&
(' ' + el.lastChild.className + ' ').indexOf(' anchorjs-link ') > -1;
return hasLeftAnchor || hasRightAnchor || false;
};
/**
* Turns a selector, nodeList, or array of elements into an array of elements (so we can use array methods).
* It also throws errors on any other inputs. Used to handle inputs to .add and .remove.
* @param {String|Array|Nodelist} input - A CSS selector string targeting elements with anchor links,
* OR a nodeList / array containing the DOM elements.
* @returns {Array} - An array containing the elements we want.
*/
function _getElements(input) {
var elements;
if (typeof input === 'string' || input instanceof String) {
// See https://davidwalsh.name/nodelist-array for the technique transforming nodeList -> Array.
elements = [].slice.call(document.querySelectorAll(input));
// I checked the 'input instanceof NodeList' test in IE9 and modern browsers and it worked for me.
} else if (Array.isArray(input) || input instanceof NodeList) {
elements = [].slice.call(input);
} else {
throw new Error('The selector provided to AnchorJS was invalid.');
}
return elements;
}
/**
* _addBaselineStyles
* Adds baseline styles to the page, used by all AnchorJS links irregardless of configuration.
*/
function _addBaselineStyles() {
// We don't want to add global baseline styles if they've been added before.
if (document.head.querySelector('style.anchorjs') !== null) {
return;
@ -163,10 +317,8 @@ function AnchorJS(options) {
' }',
anchorjsLinkFontFace =
' @font-face {' +
' font-family: "anchorjs-icons";' +
' font-style: normal;' +
' font-weight: normal;' + // Icon from icomoon; 10px wide & 10px tall; 2 empty below & 4 above
' src: url(data:application/x-font-ttf;charset=utf-8;base64,AAEAAAALAIAAAwAwT1MvMg8SBTUAAAC8AAAAYGNtYXAWi9QdAAABHAAAAFRnYXNwAAAAEAAAAXAAAAAIZ2x5Zgq29TcAAAF4AAABNGhlYWQEZM3pAAACrAAAADZoaGVhBhUDxgAAAuQAAAAkaG10eASAADEAAAMIAAAAFGxvY2EAKACuAAADHAAAAAxtYXhwAAgAVwAAAygAAAAgbmFtZQ5yJ3cAAANIAAAB2nBvc3QAAwAAAAAFJAAAACAAAwJAAZAABQAAApkCzAAAAI8CmQLMAAAB6wAzAQkAAAAAAAAAAAAAAAAAAAABEAAAAAAAAAAAAAAAAAAAAABAAADpywPA/8AAQAPAAEAAAAABAAAAAAAAAAAAAAAgAAAAAAADAAAAAwAAABwAAQADAAAAHAADAAEAAAAcAAQAOAAAAAoACAACAAIAAQAg6cv//f//AAAAAAAg6cv//f//AAH/4xY5AAMAAQAAAAAAAAAAAAAAAQAB//8ADwABAAAAAAAAAAAAAgAANzkBAAAAAAEAAAAAAAAAAAACAAA3OQEAAAAAAQAAAAAAAAAAAAIAADc5AQAAAAACADEARAJTAsAAKwBUAAABIiYnJjQ/AT4BMzIWFxYUDwEGIicmND8BNjQnLgEjIgYPAQYUFxYUBw4BIwciJicmND8BNjIXFhQPAQYUFx4BMzI2PwE2NCcmNDc2MhcWFA8BDgEjARQGDAUtLXoWOR8fORYtLTgKGwoKCjgaGg0gEhIgDXoaGgkJBQwHdR85Fi0tOAobCgoKOBoaDSASEiANehoaCQkKGwotLXoWOR8BMwUFLYEuehYXFxYugC44CQkKGwo4GkoaDQ0NDXoaShoKGwoFBe8XFi6ALjgJCQobCjgaShoNDQ0NehpKGgobCgoKLYEuehYXAAEAAAABAACiToc1Xw889QALBAAAAAAA0XnFFgAAAADRecUWAAAAAAJTAsAAAAAIAAIAAAAAAAAAAQAAA8D/wAAABAAAAAAAAlMAAQAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAACAAAAAoAAMQAAAAAACgAUAB4AmgABAAAABQBVAAIAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAADgCuAAEAAAAAAAEADgAAAAEAAAAAAAIABwCfAAEAAAAAAAMADgBLAAEAAAAAAAQADgC0AAEAAAAAAAUACwAqAAEAAAAAAAYADgB1AAEAAAAAAAoAGgDeAAMAAQQJAAEAHAAOAAMAAQQJAAIADgCmAAMAAQQJAAMAHABZAAMAAQQJAAQAHADCAAMAAQQJAAUAFgA1AAMAAQQJAAYAHACDAAMAAQQJAAoANAD4YW5jaG9yanMtaWNvbnMAYQBuAGMAaABvAHIAagBzAC0AaQBjAG8AbgBzVmVyc2lvbiAxLjAAVgBlAHIAcwBpAG8AbgAgADEALgAwYW5jaG9yanMtaWNvbnMAYQBuAGMAaABvAHIAagBzAC0AaQBjAG8AbgBzYW5jaG9yanMtaWNvbnMAYQBuAGMAaABvAHIAagBzAC0AaQBjAG8AbgBzUmVndWxhcgBSAGUAZwB1AGwAYQByYW5jaG9yanMtaWNvbnMAYQBuAGMAaABvAHIAagBzAC0AaQBjAG8AbgBzRm9udCBnZW5lcmF0ZWQgYnkgSWNvTW9vbi4ARgBvAG4AdAAgAGcAZQBuAGUAcgBhAHQAZQBkACAAYgB5ACAASQBjAG8ATQBvAG8AbgAuAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==) format("truetype");' +
' font-family: "anchorjs-icons";' + // Icon from icomoon; 10px wide & 10px tall; 2 empty below & 4 above
' src: url(data:n/a;base64,AAEAAAALAIAAAwAwT1MvMg8yG2cAAAE4AAAAYGNtYXDp3gC3AAABpAAAAExnYXNwAAAAEAAAA9wAAAAIZ2x5ZlQCcfwAAAH4AAABCGhlYWQHFvHyAAAAvAAAADZoaGVhBnACFwAAAPQAAAAkaG10eASAADEAAAGYAAAADGxvY2EACACEAAAB8AAAAAhtYXhwAAYAVwAAARgAAAAgbmFtZQGOH9cAAAMAAAAAunBvc3QAAwAAAAADvAAAACAAAQAAAAEAAHzE2p9fDzz1AAkEAAAAAADRecUWAAAAANQA6R8AAAAAAoACwAAAAAgAAgAAAAAAAAABAAADwP/AAAACgAAA/9MCrQABAAAAAAAAAAAAAAAAAAAAAwABAAAAAwBVAAIAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAMCQAGQAAUAAAKZAswAAACPApkCzAAAAesAMwEJAAAAAAAAAAAAAAAAAAAAARAAAAAAAAAAAAAAAAAAAAAAQAAg//0DwP/AAEADwABAAAAAAQAAAAAAAAAAAAAAIAAAAAAAAAIAAAACgAAxAAAAAwAAAAMAAAAcAAEAAwAAABwAAwABAAAAHAAEADAAAAAIAAgAAgAAACDpy//9//8AAAAg6cv//f///+EWNwADAAEAAAAAAAAAAAAAAAAACACEAAEAAAAAAAAAAAAAAAAxAAACAAQARAKAAsAAKwBUAAABIiYnJjQ3NzY2MzIWFxYUBwcGIicmNDc3NjQnJiYjIgYHBwYUFxYUBwYGIwciJicmNDc3NjIXFhQHBwYUFxYWMzI2Nzc2NCcmNDc2MhcWFAcHBgYjARQGDAUtLXoWOR8fORYtLTgKGwoKCjgaGg0gEhIgDXoaGgkJBQwHdR85Fi0tOAobCgoKOBoaDSASEiANehoaCQkKGwotLXoWOR8BMwUFLYEuehYXFxYugC44CQkKGwo4GkoaDQ0NDXoaShoKGwoFBe8XFi6ALjgJCQobCjgaShoNDQ0NehpKGgobCgoKLYEuehYXAAAADACWAAEAAAAAAAEACAAAAAEAAAAAAAIAAwAIAAEAAAAAAAMACAAAAAEAAAAAAAQACAAAAAEAAAAAAAUAAQALAAEAAAAAAAYACAAAAAMAAQQJAAEAEAAMAAMAAQQJAAIABgAcAAMAAQQJAAMAEAAMAAMAAQQJAAQAEAAMAAMAAQQJAAUAAgAiAAMAAQQJAAYAEAAMYW5jaG9yanM0MDBAAGEAbgBjAGgAbwByAGoAcwA0ADAAMABAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAH//wAP) format("truetype");' +
' }',
pseudoElContent =
' [data-anchorjs-icon]::after {' +
@ -191,7 +343,8 @@ function AnchorJS(options) {
style.sheet.insertRule(hoverRule, style.sheet.cssRules.length);
style.sheet.insertRule(pseudoElContent, style.sheet.cssRules.length);
style.sheet.insertRule(anchorjsLinkFontFace, style.sheet.cssRules.length);
};
}
}
}
var anchors = new AnchorJS();
return AnchorJS;
});

View File

@ -457,6 +457,7 @@
min-height:0;
}
.flex-none{ -webkit-box-flex:0; -webkit-flex:none; -ms-flex:none; flex:none }
.fs0{ flex-shrink: 0 }
.order-0{ -webkit-box-ordinal-group:1; -webkit-order:0; -ms-flex-order:0; order:0 }
.order-1{ -webkit-box-ordinal-group:2; -webkit-order:1; -ms-flex-order:1; order:1 }

View File

@ -1,93 +0,0 @@
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.

View File

@ -1,20 +0,0 @@
# Source Code Pro
Source Code Pro is a set of OpenType fonts that have been designed to work well
in user interface (UI) environments. In addition to a functional OpenType font, this open
source project provides all of the source files that were used to build this OpenType font
by using the AFDKO makeotf tool.
## Font installation instructions
* [Mac OS X](http://support.apple.com/kb/HT2509)
* [Windows](http://windows.microsoft.com/en-us/windows-vista/install-or-uninstall-fonts)
* [Linux/Unix-based systems](https://github.com/adobe-fonts/source-code-pro/issues/17#issuecomment-8967116)
## Getting Involved
Send suggestions for changes to the Source Code OpenType font project maintainer, [Paul D. Hunt](mailto:opensourcefonts@adobe.com?subject=[GitHub] Source Code Pro), for consideration.
## Further information
For information about the design and background of Source Code, please refer to the [official font readme file](http://www.adobe.com/products/type/font-information/source-code-pro-readme.html).

View File

@ -1,15 +0,0 @@
@font-face{
font-family: 'Source Code Pro';
font-weight: 400;
font-style: normal;
font-stretch: normal;
src: url('WOFF/OTF/SourceCodePro-Regular.otf.woff') format('woff');
}
@font-face{
font-family: 'Source Code Pro';
font-weight: 500;
font-style: normal;
font-stretch: normal;
src: url('WOFF/OTF/SourceCodePro-Medium.otf.woff') format('woff');
}

View File

@ -1,93 +0,0 @@
Copyright 2010, 2012, 2014 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.

View File

@ -1,20 +0,0 @@
# Source Sans Pro
Source Sans Pro is a set of OpenType fonts that have been designed to work well
in user interface (UI) environments. In addition to a functional OpenType font, this open
source project provides all of the source files that were used to build this OpenType font
by using the AFDKO makeotf tool.
## Font installation instructions
* [Mac OS X](http://support.apple.com/kb/HT2509)
* [Windows](http://windows.microsoft.com/en-us/windows-vista/install-or-uninstall-fonts)
* [Linux/Unix-based systems](https://github.com/adobe-fonts/source-code-pro/issues/17#issuecomment-8967116)
## Getting Involved
Send suggestions for changes to the Source Sans OpenType font project maintainer, [Paul D. Hunt](mailto:opensourcefonts@adobe.com?subject=[GitHub] Source Sans Pro), for consideration.
## Further information
For information about the design and background of Source Sans, please refer to the [official font readme file](http://www.adobe.com/products/type/font-information/source-sans-pro-readme.html).

View File

@ -1,17 +0,0 @@
{
"name": "source-sans-pro",
"version": "2.020R-ro/1.075R-it",
"main": "source-sans-pro.css",
"homepage": "https://github.com/adobe-fonts/source-sans-pro",
"repository": {
"type": "git",
"url": "https://github.com/adobe-fonts/source-sans-pro.git"
},
"authors": [
{ "name": "Paul D. Hunt" }
],
"description": "Source Sans Pro font family by Adobe",
"license": "SIL OFL 1.1",
"keywords": ["font", "sourcesans", "sourcesanspro", "source sans", "source sans pro"],
"ignore": ["**/.*"]
}

View File

@ -1,31 +0,0 @@
@font-face{
font-family: 'Source Sans Pro';
font-weight: 300;
font-style: normal;
font-stretch: normal;
src: url('WOFF/OTF/SourceSansPro-Light.otf.woff') format('woff');
}
@font-face{
font-family: 'Source Sans Pro';
font-weight: 400;
font-style: normal;
font-stretch: normal;
src: url('WOFF/OTF/SourceSansPro-Regular.otf.woff') format('woff');
}
@font-face{
font-family: 'Source Sans Pro';
font-weight: 600;
font-style: normal;
font-stretch: normal;
src: url('WOFF/OTF/SourceSansPro-Semibold.otf.woff') format('woff');
}
@font-face{
font-family: 'Source Sans Pro';
font-weight: 700;
font-style: normal;
font-stretch: normal;
src: url('WOFF/OTF/SourceSansPro-Bold.otf.woff') format('woff');
}

View File

@ -5,12 +5,9 @@ anchors.options.placement = 'left';
anchors.add('h3');
// Filter UI
var tocElements = document.getElementById('toc')
.getElementsByTagName('li');
document.getElementById('filter-input')
.addEventListener('keyup', function (e) {
var tocElements = document.getElementById('toc').getElementsByTagName('li');
document.getElementById('filter-input').addEventListener('keyup', function(e) {
var i, element, children;
// enter key
@ -25,15 +22,16 @@ document.getElementById('filter-input')
}
}
var match = function () {
var match = function() {
return true;
};
var value = this.value.toLowerCase();
if (!value.match(/^\s*$/)) {
match = function (element) {
return element.firstChild.innerHTML.toLowerCase().indexOf(value) !== -1;
match = function(element) {
var html = element.firstChild.innerHTML;
return html && html.toLowerCase().indexOf(value) !== -1;
};
}
@ -46,24 +44,7 @@ document.getElementById('filter-input')
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++) {
@ -84,19 +65,36 @@ function toggleSibling() {
}
function showHashTarget(targetId) {
if (targetId) {
var hashTarget = document.getElementById(targetId);
// new target is hidden
if (hashTarget && hashTarget.offsetHeight === 0 &&
hashTarget.parentNode.parentNode.classList.contains('display-none')) {
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));
});
function scrollIntoView(targetId) {
// Only scroll to element if we don't have a stored scroll position.
if (targetId && !history.state) {
var hashTarget = document.getElementById(targetId);
if (hashTarget) {
hashTarget.scrollIntoView();
}
}
}
showHashTarget(location.hash.substring(1));
function gotoCurrentTarget() {
showHashTarget(location.hash.substring(1));
scrollIntoView(location.hash.substring(1));
}
window.addEventListener('hashchange', gotoCurrentTarget);
gotoCurrentTarget();
var toclinks = document.getElementsByClassName('pre-open');
for (var k = 0; k < toclinks.length; k++) {
@ -106,3 +104,65 @@ for (var k = 0; k < toclinks.length; k++) {
function preOpen() {
showHashTarget(this.hash.substring(1));
}
var split_left = document.querySelector('#split-left');
var split_right = document.querySelector('#split-right');
var split_parent = split_left.parentNode;
var cw_with_sb = split_left.clientWidth;
split_left.style.overflow = 'hidden';
var cw_without_sb = split_left.clientWidth;
split_left.style.overflow = '';
Split(['#split-left', '#split-right'], {
elementStyle: function(dimension, size, gutterSize) {
return {
'flex-basis': 'calc(' + size + '% - ' + gutterSize + 'px)'
};
},
gutterStyle: function(dimension, gutterSize) {
return {
'flex-basis': gutterSize + 'px'
};
},
gutterSize: 20,
sizes: [33, 67]
});
// Chrome doesn't remember scroll position properly so do it ourselves.
// Also works on Firefox and Edge.
function updateState() {
history.replaceState(
{
left_top: split_left.scrollTop,
right_top: split_right.scrollTop
},
document.title
);
}
function loadState(ev) {
if (ev) {
// Edge doesn't replace change history.state on popstate.
history.replaceState(ev.state, document.title);
}
if (history.state) {
split_left.scrollTop = history.state.left_top;
split_right.scrollTop = history.state.right_top;
}
}
window.addEventListener('load', function() {
// Restore after Firefox scrolls to hash.
setTimeout(function() {
loadState();
// Update with initial scroll position.
updateState();
// Update scroll positions only after we've loaded because Firefox
// emits an initial scroll event with 0.
split_left.addEventListener('scroll', updateState);
split_right.addEventListener('scroll', updateState);
}, 1);
});
window.addEventListener('popstate', loadState);

15
docs/assets/split.css Normal file
View File

@ -0,0 +1,15 @@
.gutter {
background-color: #f5f5f5;
background-repeat: no-repeat;
background-position: 50%;
}
.gutter.gutter-vertical {
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAFAQMAAABo7865AAAABlBMVEVHcEzMzMzyAv2sAAAAAXRSTlMAQObYZgAAABBJREFUeF5jOAMEEAIEEFwAn3kMwcB6I2AAAAAASUVORK5CYII=');
cursor: ns-resize;
}
.gutter.gutter-horizontal {
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAeCAYAAADkftS9AAAAIklEQVQoU2M4c+bMfxAGAgYYmwGrIIiDjrELjpo5aiZeMwF+yNnOs5KSvgAAAABJRU5ErkJggg==');
cursor: ew-resize;
}

586
docs/assets/split.js Normal file
View File

@ -0,0 +1,586 @@
/*! Split.js - v1.3.5 */
// https://github.com/nathancahill/Split.js
// Copyright (c) 2017 Nathan Cahill; Licensed MIT
(function(global, factory) {
typeof exports === 'object' && typeof module !== 'undefined'
? (module.exports = factory())
: typeof define === 'function' && define.amd
? define(factory)
: (global.Split = factory());
})(this, function() {
'use strict';
// The programming goals of Split.js are to deliver readable, understandable and
// maintainable code, while at the same time manually optimizing for tiny minified file size,
// browser compatibility without additional requirements, graceful fallback (IE8 is supported)
// and very few assumptions about the user's page layout.
var global = window;
var document = global.document;
// Save a couple long function names that are used frequently.
// This optimization saves around 400 bytes.
var addEventListener = 'addEventListener';
var removeEventListener = 'removeEventListener';
var getBoundingClientRect = 'getBoundingClientRect';
var NOOP = function() {
return false;
};
// Figure out if we're in IE8 or not. IE8 will still render correctly,
// but will be static instead of draggable.
var isIE8 = global.attachEvent && !global[addEventListener];
// This library only needs two helper functions:
//
// The first determines which prefixes of CSS calc we need.
// We only need to do this once on startup, when this anonymous function is called.
//
// Tests -webkit, -moz and -o prefixes. Modified from StackOverflow:
// http://stackoverflow.com/questions/16625140/js-feature-detection-to-detect-the-usage-of-webkit-calc-over-calc/16625167#16625167
var calc =
['', '-webkit-', '-moz-', '-o-']
.filter(function(prefix) {
var el = document.createElement('div');
el.style.cssText = 'width:' + prefix + 'calc(9px)';
return !!el.style.length;
})
.shift() + 'calc';
// The second helper function allows elements and string selectors to be used
// interchangeably. In either case an element is returned. This allows us to
// do `Split([elem1, elem2])` as well as `Split(['#id1', '#id2'])`.
var elementOrSelector = function(el) {
if (typeof el === 'string' || el instanceof String) {
return document.querySelector(el);
}
return el;
};
// The main function to initialize a split. Split.js thinks about each pair
// of elements as an independant pair. Dragging the gutter between two elements
// only changes the dimensions of elements in that pair. This is key to understanding
// how the following functions operate, since each function is bound to a pair.
//
// A pair object is shaped like this:
//
// {
// a: DOM element,
// b: DOM element,
// aMin: Number,
// bMin: Number,
// dragging: Boolean,
// parent: DOM element,
// isFirst: Boolean,
// isLast: Boolean,
// direction: 'horizontal' | 'vertical'
// }
//
// The basic sequence:
//
// 1. Set defaults to something sane. `options` doesn't have to be passed at all.
// 2. Initialize a bunch of strings based on the direction we're splitting.
// A lot of the behavior in the rest of the library is paramatized down to
// rely on CSS strings and classes.
// 3. Define the dragging helper functions, and a few helpers to go with them.
// 4. Loop through the elements while pairing them off. Every pair gets an
// `pair` object, a gutter, and special isFirst/isLast properties.
// 5. Actually size the pair elements, insert gutters and attach event listeners.
var Split = function(ids, options) {
if (options === void 0) options = {};
var dimension;
var clientDimension;
var clientAxis;
var position;
var paddingA;
var paddingB;
var elements;
// All DOM elements in the split should have a common parent. We can grab
// the first elements parent and hope users read the docs because the
// behavior will be whacky otherwise.
var parent = elementOrSelector(ids[0]).parentNode;
var parentFlexDirection = global.getComputedStyle(parent).flexDirection;
// Set default options.sizes to equal percentages of the parent element.
var sizes =
options.sizes ||
ids.map(function() {
return 100 / ids.length;
});
// Standardize minSize to an array if it isn't already. This allows minSize
// to be passed as a number.
var minSize = options.minSize !== undefined ? options.minSize : 100;
var minSizes = Array.isArray(minSize)
? minSize
: ids.map(function() {
return minSize;
});
var gutterSize = options.gutterSize !== undefined ? options.gutterSize : 10;
var snapOffset = options.snapOffset !== undefined ? options.snapOffset : 30;
var direction = options.direction || 'horizontal';
var cursor =
options.cursor ||
(direction === 'horizontal' ? 'ew-resize' : 'ns-resize');
var gutter =
options.gutter ||
function(i, gutterDirection) {
var gut = document.createElement('div');
gut.className = 'gutter gutter-' + gutterDirection;
return gut;
};
var elementStyle =
options.elementStyle ||
function(dim, size, gutSize) {
var style = {};
if (typeof size !== 'string' && !(size instanceof String)) {
if (!isIE8) {
style[dim] = calc + '(' + size + '% - ' + gutSize + 'px)';
} else {
style[dim] = size + '%';
}
} else {
style[dim] = size;
}
return style;
};
var gutterStyle =
options.gutterStyle ||
function(dim, gutSize) {
return (obj = {}), (obj[dim] = gutSize + 'px'), obj;
var obj;
};
// 2. Initialize a bunch of strings based on the direction we're splitting.
// A lot of the behavior in the rest of the library is paramatized down to
// rely on CSS strings and classes.
if (direction === 'horizontal') {
dimension = 'width';
clientDimension = 'clientWidth';
clientAxis = 'clientX';
position = 'left';
paddingA = 'paddingLeft';
paddingB = 'paddingRight';
} else if (direction === 'vertical') {
dimension = 'height';
clientDimension = 'clientHeight';
clientAxis = 'clientY';
position = 'top';
paddingA = 'paddingTop';
paddingB = 'paddingBottom';
}
// 3. Define the dragging helper functions, and a few helpers to go with them.
// Each helper is bound to a pair object that contains it's metadata. This
// also makes it easy to store references to listeners that that will be
// added and removed.
//
// Even though there are no other functions contained in them, aliasing
// this to self saves 50 bytes or so since it's used so frequently.
//
// The pair object saves metadata like dragging state, position and
// event listener references.
function setElementSize(el, size, gutSize) {
// Split.js allows setting sizes via numbers (ideally), or if you must,
// by string, like '300px'. This is less than ideal, because it breaks
// the fluid layout that `calc(% - px)` provides. You're on your own if you do that,
// make sure you calculate the gutter size by hand.
var style = elementStyle(dimension, size, gutSize);
// eslint-disable-next-line no-param-reassign
Object.keys(style).forEach(function(prop) {
return (el.style[prop] = style[prop]);
});
}
function setGutterSize(gutterElement, gutSize) {
var style = gutterStyle(dimension, gutSize);
// eslint-disable-next-line no-param-reassign
Object.keys(style).forEach(function(prop) {
return (gutterElement.style[prop] = style[prop]);
});
}
// Actually adjust the size of elements `a` and `b` to `offset` while dragging.
// calc is used to allow calc(percentage + gutterpx) on the whole split instance,
// which allows the viewport to be resized without additional logic.
// Element a's size is the same as offset. b's size is total size - a size.
// Both sizes are calculated from the initial parent percentage,
// then the gutter size is subtracted.
function adjust(offset) {
var a = elements[this.a];
var b = elements[this.b];
var percentage = a.size + b.size;
a.size = offset / this.size * percentage;
b.size = percentage - offset / this.size * percentage;
setElementSize(a.element, a.size, this.aGutterSize);
setElementSize(b.element, b.size, this.bGutterSize);
}
// drag, where all the magic happens. The logic is really quite simple:
//
// 1. Ignore if the pair is not dragging.
// 2. Get the offset of the event.
// 3. Snap offset to min if within snappable range (within min + snapOffset).
// 4. Actually adjust each element in the pair to offset.
//
// ---------------------------------------------------------------------
// | | <- a.minSize || b.minSize -> | |
// | | | <- this.snapOffset || this.snapOffset -> | | |
// | | | || | | |
// | | | || | | |
// ---------------------------------------------------------------------
// | <- this.start this.size -> |
function drag(e) {
var offset;
if (!this.dragging) {
return;
}
// Get the offset of the event from the first side of the
// pair `this.start`. Supports touch events, but not multitouch, so only the first
// finger `touches[0]` is counted.
if ('touches' in e) {
offset = e.touches[0][clientAxis] - this.start;
} else {
offset = e[clientAxis] - this.start;
}
// If within snapOffset of min or max, set offset to min or max.
// snapOffset buffers a.minSize and b.minSize, so logic is opposite for both.
// Include the appropriate gutter sizes to prevent overflows.
if (offset <= elements[this.a].minSize + snapOffset + this.aGutterSize) {
offset = elements[this.a].minSize + this.aGutterSize;
} else if (
offset >=
this.size - (elements[this.b].minSize + snapOffset + this.bGutterSize)
) {
offset = this.size - (elements[this.b].minSize + this.bGutterSize);
}
// Actually adjust the size.
adjust.call(this, offset);
// Call the drag callback continously. Don't do anything too intensive
// in this callback.
if (options.onDrag) {
options.onDrag();
}
}
// Cache some important sizes when drag starts, so we don't have to do that
// continously:
//
// `size`: The total size of the pair. First + second + first gutter + second gutter.
// `start`: The leading side of the first element.
//
// ------------------------------------------------
// | aGutterSize -> ||| |
// | ||| |
// | ||| |
// | ||| <- bGutterSize |
// ------------------------------------------------
// | <- start size -> |
function calculateSizes() {
// Figure out the parent size minus padding.
var a = elements[this.a].element;
var b = elements[this.b].element;
this.size =
a[getBoundingClientRect]()[dimension] +
b[getBoundingClientRect]()[dimension] +
this.aGutterSize +
this.bGutterSize;
this.start = a[getBoundingClientRect]()[position];
}
// stopDragging is very similar to startDragging in reverse.
function stopDragging() {
var self = this;
var a = elements[self.a].element;
var b = elements[self.b].element;
if (self.dragging && options.onDragEnd) {
options.onDragEnd();
}
self.dragging = false;
// Remove the stored event listeners. This is why we store them.
global[removeEventListener]('mouseup', self.stop);
global[removeEventListener]('touchend', self.stop);
global[removeEventListener]('touchcancel', self.stop);
self.parent[removeEventListener]('mousemove', self.move);
self.parent[removeEventListener]('touchmove', self.move);
// Delete them once they are removed. I think this makes a difference
// in memory usage with a lot of splits on one page. But I don't know for sure.
delete self.stop;
delete self.move;
a[removeEventListener]('selectstart', NOOP);
a[removeEventListener]('dragstart', NOOP);
b[removeEventListener]('selectstart', NOOP);
b[removeEventListener]('dragstart', NOOP);
a.style.userSelect = '';
a.style.webkitUserSelect = '';
a.style.MozUserSelect = '';
a.style.pointerEvents = '';
b.style.userSelect = '';
b.style.webkitUserSelect = '';
b.style.MozUserSelect = '';
b.style.pointerEvents = '';
self.gutter.style.cursor = '';
self.parent.style.cursor = '';
}
// startDragging calls `calculateSizes` to store the inital size in the pair object.
// It also adds event listeners for mouse/touch events,
// and prevents selection while dragging so avoid the selecting text.
function startDragging(e) {
// Alias frequently used variables to save space. 200 bytes.
var self = this;
var a = elements[self.a].element;
var b = elements[self.b].element;
// Call the onDragStart callback.
if (!self.dragging && options.onDragStart) {
options.onDragStart();
}
// Don't actually drag the element. We emulate that in the drag function.
e.preventDefault();
// Set the dragging property of the pair object.
self.dragging = true;
// Create two event listeners bound to the same pair object and store
// them in the pair object.
self.move = drag.bind(self);
self.stop = stopDragging.bind(self);
// All the binding. `window` gets the stop events in case we drag out of the elements.
global[addEventListener]('mouseup', self.stop);
global[addEventListener]('touchend', self.stop);
global[addEventListener]('touchcancel', self.stop);
self.parent[addEventListener]('mousemove', self.move);
self.parent[addEventListener]('touchmove', self.move);
// Disable selection. Disable!
a[addEventListener]('selectstart', NOOP);
a[addEventListener]('dragstart', NOOP);
b[addEventListener]('selectstart', NOOP);
b[addEventListener]('dragstart', NOOP);
a.style.userSelect = 'none';
a.style.webkitUserSelect = 'none';
a.style.MozUserSelect = 'none';
a.style.pointerEvents = 'none';
b.style.userSelect = 'none';
b.style.webkitUserSelect = 'none';
b.style.MozUserSelect = 'none';
b.style.pointerEvents = 'none';
// Set the cursor, both on the gutter and the parent element.
// Doing only a, b and gutter causes flickering.
self.gutter.style.cursor = cursor;
self.parent.style.cursor = cursor;
// Cache the initial sizes of the pair.
calculateSizes.call(self);
}
// 5. Create pair and element objects. Each pair has an index reference to
// elements `a` and `b` of the pair (first and second elements).
// Loop through the elements while pairing them off. Every pair gets a
// `pair` object, a gutter, and isFirst/isLast properties.
//
// Basic logic:
//
// - Starting with the second element `i > 0`, create `pair` objects with
// `a = i - 1` and `b = i`
// - Set gutter sizes based on the _pair_ being first/last. The first and last
// pair have gutterSize / 2, since they only have one half gutter, and not two.
// - Create gutter elements and add event listeners.
// - Set the size of the elements, minus the gutter sizes.
//
// -----------------------------------------------------------------------
// | i=0 | i=1 | i=2 | i=3 |
// | | isFirst | | isLast |
// | pair 0 pair 1 pair 2 |
// | | | | |
// -----------------------------------------------------------------------
var pairs = [];
elements = ids.map(function(id, i) {
// Create the element object.
var element = {
element: elementOrSelector(id),
size: sizes[i],
minSize: minSizes[i]
};
var pair;
if (i > 0) {
// Create the pair object with it's metadata.
pair = {
a: i - 1,
b: i,
dragging: false,
isFirst: i === 1,
isLast: i === ids.length - 1,
direction: direction,
parent: parent
};
// For first and last pairs, first and last gutter width is half.
pair.aGutterSize = gutterSize;
pair.bGutterSize = gutterSize;
if (pair.isFirst) {
pair.aGutterSize = gutterSize / 2;
}
if (pair.isLast) {
pair.bGutterSize = gutterSize / 2;
}
// if the parent has a reverse flex-direction, switch the pair elements.
if (
parentFlexDirection === 'row-reverse' ||
parentFlexDirection === 'column-reverse'
) {
var temp = pair.a;
pair.a = pair.b;
pair.b = temp;
}
}
// Determine the size of the current element. IE8 is supported by
// staticly assigning sizes without draggable gutters. Assigns a string
// to `size`.
//
// IE9 and above
if (!isIE8) {
// Create gutter elements for each pair.
if (i > 0) {
var gutterElement = gutter(i, direction);
setGutterSize(gutterElement, gutterSize);
gutterElement[addEventListener](
'mousedown',
startDragging.bind(pair)
);
gutterElement[addEventListener](
'touchstart',
startDragging.bind(pair)
);
parent.insertBefore(gutterElement, element.element);
pair.gutter = gutterElement;
}
}
// Set the element size to our determined size.
// Half-size gutters for first and last elements.
if (i === 0 || i === ids.length - 1) {
setElementSize(element.element, element.size, gutterSize / 2);
} else {
setElementSize(element.element, element.size, gutterSize);
}
var computedSize = element.element[getBoundingClientRect]()[dimension];
if (computedSize < element.minSize) {
element.minSize = computedSize;
}
// After the first iteration, and we have a pair object, append it to the
// list of pairs.
if (i > 0) {
pairs.push(pair);
}
return element;
});
function setSizes(newSizes) {
newSizes.forEach(function(newSize, i) {
if (i > 0) {
var pair = pairs[i - 1];
var a = elements[pair.a];
var b = elements[pair.b];
a.size = newSizes[i - 1];
b.size = newSize;
setElementSize(a.element, a.size, pair.aGutterSize);
setElementSize(b.element, b.size, pair.bGutterSize);
}
});
}
function destroy() {
pairs.forEach(function(pair) {
pair.parent.removeChild(pair.gutter);
elements[pair.a].element.style[dimension] = '';
elements[pair.b].element.style[dimension] = '';
});
}
if (isIE8) {
return {
setSizes: setSizes,
destroy: destroy
};
}
return {
setSizes: setSizes,
getSizes: function getSizes() {
return elements.map(function(element) {
return element.size;
});
},
collapse: function collapse(i) {
if (i === pairs.length) {
var pair = pairs[i - 1];
calculateSizes.call(pair);
if (!isIE8) {
adjust.call(pair, pair.size - pair.bGutterSize);
}
} else {
var pair$1 = pairs[i];
calculateSizes.call(pair$1);
if (!isIE8) {
adjust.call(pair$1, pair$1.aGutterSize);
}
}
},
destroy: destroy
};
};
return Split;
});

View File

@ -46,6 +46,10 @@ a:hover {
max-height: 100%;
}
.height-viewport-100 {
height: 100vh;
}
section:target h3 {
font-weight:700;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,99 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>JSDoc: Source: Adapter.js</title>
<script src="scripts/prettify/prettify.js"> </script>
<script src="scripts/prettify/lang-css.js"> </script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>
<body>
<div id="main">
<h1 class="page-title">Source: Adapter.js</h1>
<section>
<article>
<pre class="prettyprint source linenums"><code>/**
* Class that wraps database connection libraries
*
* @private
* @param {Promise} instance - The connection object
*/
class Adapter {
/**
* Invoke an adapter
*
* @constructor
* @param {Promise} instance - Promise holding connection object
*/
constructor (instance) {
this.instance = instance;
}
/**
* Run the sql query as a prepared statement
*
* @param {String} sql - The sql with placeholders
* @param {Array} params - The values to insert into the query
* @return {Promise} - returns a promise resolving to the result of the database query
*/
execute (sql, params) {
throw new Error('Correct adapter not defined for query execution');
}
/**
* 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) {
throw new Error('Result transformer method not defined for current adapter');
}
/**
* Close the current database connection
* @return {void}
*/
close () {
this.instance.then(conn => conn.end());
}
}
module.exports = Adapter;
</code></pre>
</article>
</section>
</div>
<nav>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-drivers_MariaDB.html">drivers/MariaDB</a></li><li><a href="module-drivers_MSSQLDriver.html">drivers/MSSQLDriver</a></li><li><a href="module-drivers_Mysql.html">drivers/Mysql</a></li><li><a href="module-drivers_Pg.html">drivers/Pg</a></li><li><a href="module-drivers_Sqlite.html">drivers/Sqlite</a></li></ul><h3>Classes</h3><ul><li><a href="NodeQuery.html">NodeQuery</a></li><li><a href="QueryBuilder.html">QueryBuilder</a></li><li><a href="Result.html">Result</a></li></ul>
</nav>
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Mon Feb 12 2018 14:58:25 GMT-0500 (EST)
</footer>
<script> prettyPrint(); </script>
<script src="scripts/linenumber.js"> </script>
</body>
</html>

View File

@ -0,0 +1,220 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>JSDoc: Source: Helpers.js</title>
<script src="scripts/prettify/prettify.js"> </script>
<script src="scripts/prettify/lang-css.js"> </script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>
<body>
<div id="main">
<h1 class="page-title">Source: Helpers.js</h1>
<section>
<article>
<pre class="prettyprint source linenums"><code>const fs = require('fs');
/**
* Various internal helper functions
*
* @private
*/
class Helpers {
/**
* Get the contents of a file
*
* @param {string} file - The path to the file
* @return {Promise&lt;string>} - Promise resolving to the contents of the file
*/
static readFile (file) {
return new Promise((resolve, reject) => {
fs.readFile(file, (err, data) => {
if (err) {
return reject(err);
}
return resolve(Buffer.from(data).toString());
});
});
}
/**
* Wrap String.prototype.trim in a way that is easily mappable
*
* @param {String} str - The string to trim
* @return {String} - The trimmed string
*/
static stringTrim (str) {
return str.trim();
}
/**
* Get the type of the variable passed
*
* @see https://techblog.badoo.com/blog/2013/11/01/type-checking-in-javascript/
* @see http://toddmotto.com/understanding-javascript-types-and-reliable-type-checking/
* @param {mixed} o - Object to type check
* @return {String} - Type of the object
*/
static type (o) {
const type = Object.prototype.toString.call(o).slice(8, -1).toLowerCase();
// handle NaN and Infinity
if (type === 'number') {
if (isNaN(o)) {
return 'nan';
}
if (!isFinite(o)) {
return 'infinity';
}
}
return type;
}
/**
* Determine whether an object is scalar
*
* @param {mixed} obj - Object to test
* @return {boolean} - Is object scalar
*/
static isScalar (obj) {
return ['string', 'number', 'boolean'].includes(Helpers.type(obj));
}
/**
* Get a list of values with a common key from an array of objects
*
* @param {Array} arr - The array of objects to search
* @param {String} key - The key of the object to get
* @return {Array} - The new array of plucked values
*/
static arrayPluck (arr, key) {
const output = [];
// Empty case
if (arr.length === 0) {
return output;
}
arr.forEach(obj => {
if (!Helpers.isUndefined(obj[key])) {
output.push(obj[key]);
}
});
return output;
}
/**
* Determine if a value matching the passed regular expression is
* in the passed array
*
* @param {Array} arr - The array to search
* @param {RegExp} pattern - The pattern to match
* @return {Boolean} - If an array item matches the pattern
*/
static regexInArray (arr, pattern) {
// Empty case(s)
if (!Helpers.isArray(arr) || arr.length === 0) {
return false;
}
const l = arr.length;
for (let i = 0; i &lt; l; i++) {
// Short circuit if any items match
if (pattern.test(arr[i])) {
return true;
}
}
return false;
}
/**
* Make the first constter of the string uppercase
*
* @param {String} str - The string to modify
* @return {String} - The modified string
*/
static upperCaseFirst (str) {
str += '';
const first = str.charAt(0).toUpperCase();
return first + str.substr(1);
}
}
// Define an 'is' method for each type
const types = [
'Null',
'Undefined',
'Object',
'Array',
'String',
'Number',
'Boolean',
'Function',
'RegExp',
'NaN',
'Infinite',
'Promise'
];
types.forEach(t => {
/**
* Determine whether a variable is of the type specified in the
* function name, eg isNumber
*
* Types available are Null, Undefined, Object, Array, String, Number,
* Boolean, Function, RegExp, NaN, Infinite, Promise
*
* @private
* @param {mixed} o - The object to check its type
* @return {Boolean} - If the type matches
*/
Helpers[`is${t}`] = function (o) {
if (t.toLowerCase() === 'infinite') {
t = 'infinity';
}
return Helpers.type(o) === t.toLowerCase();
};
});
module.exports = Helpers;
</code></pre>
</article>
</section>
</div>
<nav>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-drivers_MariaDB.html">drivers/MariaDB</a></li><li><a href="module-drivers_MSSQLDriver.html">drivers/MSSQLDriver</a></li><li><a href="module-drivers_Mysql.html">drivers/Mysql</a></li><li><a href="module-drivers_Pg.html">drivers/Pg</a></li><li><a href="module-drivers_Sqlite.html">drivers/Sqlite</a></li></ul><h3>Classes</h3><ul><li><a href="NodeQuery.html">NodeQuery</a></li><li><a href="QueryBuilder.html">QueryBuilder</a></li><li><a href="Result.html">Result</a></li></ul>
</nav>
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Mon Feb 12 2018 14:58:25 GMT-0500 (EST)
</footer>
<script> prettyPrint(); </script>
<script src="scripts/linenumber.js"> </script>
</body>
</html>

View File

@ -0,0 +1,333 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>JSDoc: Class: NodeQuery</title>
<script src="scripts/prettify/prettify.js"> </script>
<script src="scripts/prettify/lang-css.js"> </script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>
<body>
<div id="main">
<h1 class="page-title">Class: NodeQuery</h1>
<section>
<header>
<h2><span class="attribs"><span class="type-signature"></span></span>NodeQuery<span class="signature">(config)</span><span class="type-signature"></span></h2>
<div class="class-description">Class for connection management</div>
</header>
<article>
<div class="container-overview">
<h2>Constructor</h2>
<h4 class="name" id="NodeQuery"><span class="type-signature"></span>new NodeQuery<span class="signature">(config)</span><span class="type-signature"></span></h4>
<div class="description">
Constructor
</div>
<h5>Parameters:</h5>
<table class="params">
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th class="last">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="name"><code>config</code></td>
<td class="type">
<span class="param-type">object</span>
</td>
<td class="description last">connection parameters</td>
</tr>
</tbody>
</table>
<dl class="details">
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="NodeQuery.js.html">NodeQuery.js</a>, <a href="NodeQuery.js.html#line24">line 24</a>
</li></ul></dd>
</dl>
</div>
<h3 class="subsection-title">Methods</h3>
<h4 class="name" id="getQuery"><span class="type-signature"></span>getQuery<span class="signature">()</span><span class="type-signature"> &rarr; {<a href="QueryBuilder.html">QueryBuilder</a>}</span></h4>
<div class="description">
Return an existing query builder instance
</div>
<dl class="details">
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="NodeQuery.js.html">NodeQuery.js</a>, <a href="NodeQuery.js.html#line71">line 71</a>
</li></ul></dd>
</dl>
<h5>Returns:</h5>
<div class="param-desc">
- The Query Builder object
</div>
<dl>
<dt>
Type
</dt>
<dd>
<span class="param-type"><a href="QueryBuilder.html">QueryBuilder</a></span>
</dd>
</dl>
</article>
</section>
</div>
<nav>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-drivers_MariaDB.html">drivers/MariaDB</a></li><li><a href="module-drivers_MSSQLDriver.html">drivers/MSSQLDriver</a></li><li><a href="module-drivers_Mysql.html">drivers/Mysql</a></li><li><a href="module-drivers_Pg.html">drivers/Pg</a></li><li><a href="module-drivers_Sqlite.html">drivers/Sqlite</a></li></ul><h3>Classes</h3><ul><li><a href="NodeQuery.html">NodeQuery</a></li><li><a href="QueryBuilder.html">QueryBuilder</a></li><li><a href="Result.html">Result</a></li></ul>
</nav>
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Mon Feb 12 2018 14:58:25 GMT-0500 (EST)
</footer>
<script> prettyPrint(); </script>
<script src="scripts/linenumber.js"> </script>
</body>
</html>

View File

@ -0,0 +1,131 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>JSDoc: Source: NodeQuery.js</title>
<script src="scripts/prettify/prettify.js"> </script>
<script src="scripts/prettify/lang-css.js"> </script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>
<body>
<div id="main">
<h1 class="page-title">Source: NodeQuery.js</h1>
<section>
<article>
<pre class="prettyprint source linenums"><code>const QueryBuilder = require('./QueryBuilder');
// Map config driver name to code class name
const dbDriverMap = new Map([
['my', 'Mysql'],
['mysql', 'Mysql'],
['maria', 'Mysql'],
['mariadb', 'Mysql'],
['firebird', 'Firebird'],
['postgresql', 'Pg'],
['postgres', 'Pg'],
['pg', 'Pg'],
['sqlite3', 'Sqlite'],
['sqlite', 'Sqlite'],
['sqlserver', 'MSSQLServer'],
['mssql', 'MSSQLServer']
]);
/**
* Class for connection management
*
* @param {object} config - connection parameters
*/
class NodeQuery {
/**
* Constructor
*
* @param {object} config - connection parameters
* @param {string} config.driver - the database driver to use, such as mysql, sqlite, mssql, or pgsql
* @param {object|string} config.connection - the connection options for the database
* @param {string} config.connection.host - the ip or hostname of the database server
* @param {string} config.connection.user - the user to log in as
* @param {string} config.connection.password - the password to log in with
* @param {string} config.connection.database - the name of the database to connect to
* @example let nodeQuery = require('ci-node-query')({
* driver: 'mysql',
* connection: {
* host: 'localhost',
* user: 'root',
* password: '',
* database: 'mysql'
* }
* });
* @example let nodeQuery = require('ci-node-query')({
* driver: 'sqlite',
* connection: ':memory:'
* });
*/
constructor (config) {
this.instance = null;
if (config !== undefined) {
const driverName = dbDriverMap.get(config.driver);
if (!driverName) {
throw new Error(`Selected driver (${config.driver}) does not exist!`);
}
const driver = require(`./drivers/${driverName}`);
const Adapter = require(`./adapters/${driverName}`);
this.instance = new QueryBuilder(driver, Adapter(config));
}
}
/**
* Return an existing query builder instance
*
* @return {QueryBuilder} - The Query Builder object
*/
getQuery () {
if (this.instance == null) {
throw new Error('No Query Builder instance to return');
}
return this.instance;
}
}
module.exports = config => new NodeQuery(config);
</code></pre>
</article>
</section>
</div>
<nav>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-drivers_MariaDB.html">drivers/MariaDB</a></li><li><a href="module-drivers_MSSQLDriver.html">drivers/MSSQLDriver</a></li><li><a href="module-drivers_Mysql.html">drivers/Mysql</a></li><li><a href="module-drivers_Pg.html">drivers/Pg</a></li><li><a href="module-drivers_Sqlite.html">drivers/Sqlite</a></li></ul><h3>Classes</h3><ul><li><a href="NodeQuery.html">NodeQuery</a></li><li><a href="QueryBuilder.html">QueryBuilder</a></li><li><a href="Result.html">Result</a></li></ul>
</nav>
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Mon Feb 12 2018 14:58:25 GMT-0500 (EST)
</footer>
<script> prettyPrint(); </script>
<script src="scripts/linenumber.js"> </script>
</body>
</html>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,708 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>JSDoc: Source: QueryBuilder.js</title>
<script src="scripts/prettify/prettify.js"> </script>
<script src="scripts/prettify/lang-css.js"> </script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>
<body>
<div id="main">
<h1 class="page-title">Source: QueryBuilder.js</h1>
<section>
<article>
<pre class="prettyprint source linenums"><code>const Helpers = require('./Helpers');
const QueryBuilderBase = require('./QueryBuilderBase');
/**
* Main object that builds SQL queries.
*
* @param {Driver} Driver - The syntax driver for the database
* @param {Adapter} Adapter - The database module adapter for running queries
* @extends QueryBuilderBase
*/
class QueryBuilder extends QueryBuilderBase {
// ----------------------------------------------------------------------------
// ! Miscellaneous Methods
// ----------------------------------------------------------------------------
/**
* Run a set of queries from a file
*
* @param {string} file - The path to the sql file
* @param {string} [separator=';'] - The character separating each query
* @return {Promise} - The result of all the queries
*/
queryFile (file, separator = ';') {
return Helpers.readFile(file).then(sqlFile => {
const queries = sqlFile.split(separator);
const results = [];
queries.forEach(sql => {
results.push(this.query(sql));
});
return Promise.all(results);
});
}
/**
* Run an arbitrary sql query. Run as a prepared statement.
*
* @param {string} sql - The sql to execute
* @param {Array} [params] - The query parameters
* @return {Promise} - Promise with result of query
*/
query (sql, params) {
return this.adapter.execute(sql, params);
}
/**
* Reset the object state for a new query
*
* @return {void}
*/
resetQuery () {
this._resetState();
}
/**
* Returns the current class state for testing or other purposes
*
* @private
* @return {Object} - The State object
*/
getState () {
return this.state;
}
/**
* Empties the selected database table
*
* @param {string} table - the name of the table to truncate
* @return {void|Promise} - Returns a promise if no callback is supplied
*/
truncate (table) {
return this.query(this.driver.truncate(table));
}
/**
* Closes the database connection for the current adapter
*
* @return {void}
*/
end () {
this.adapter.close();
}
// ------------------------------------------------------------------------
// ! Query Builder Methods
// ------------------------------------------------------------------------
/**
* Specify rows to select in the query
*
* @param {String|Array} fields - The fields to select from the current table
* @example query.select('foo, bar'); // Select multiple fields with a string
* @example query.select(['foo', 'bar']); // Select multiple fileds with an array
* @return {QueryBuilder} - The Query Builder object, for chaining
*/
select (fields) {
// Split/trim fields by comma
fields = (Array.isArray(fields))
? fields
: fields.split(',').map(Helpers.stringTrim);
// Split on 'As'
fields.forEach((field, index) => {
if (/as/i.test(field)) {
fields[index] = field.split(/ as /i).map(Helpers.stringTrim);
}
});
const safeArray = this.driver.quoteIdentifiers(fields);
// Join the strings back together
safeArray.forEach((field, index) => {
if (Array.isArray(field)) {
safeArray[index] = safeArray[index].join(' AS ');
}
});
this.state.selectString += safeArray.join(', ');
return this;
}
/**
* Specify the database table to select from
*
* @param {String} tableName - The table to use for the current query
* @example query.from('tableName');
* @example query.from('tableName t'); // Select the table with an alias
* @return {QueryBuilder} - The Query Builder object, for chaining
*/
from (tableName) {
// Split identifiers on spaces
let identArray = tableName.trim().split(' ').map(Helpers.stringTrim);
// Quote/prefix identifiers
identArray[0] = this.driver.quoteTable(identArray[0]);
identArray = this.driver.quoteIdentifiers(identArray);
// Put it back together
this.state.fromString = identArray.join(' ');
return this;
}
/**
* Add a 'like/ and like' clause to the query
*
* @param {String} field - The name of the field to compare to
* @param {String} val - The value to compare to
* @param {String} [pos=both] - The placement of the wildcard character(s): before, after, or both
* @return {QueryBuilder} - The Query Builder object, for chaining
*/
like (field, val, pos) {
this._like(field, val, pos, ' LIKE ', 'AND');
return this;
}
/**
* Add a 'not like/ and not like' clause to the query
*
* @param {String} field - The name of the field to compare to
* @param {String} val - The value to compare to
* @param {String} [pos=both] - The placement of the wildcard character(s): before, after, or both
* @return {QueryBuilder} - The Query Builder object, for chaining
*/
notLike (field, val, pos) {
this._like(field, val, pos, ' NOT LIKE ', 'AND');
return this;
}
/**
* Add an 'or like' clause to the query
*
* @param {String} field - The name of the field to compare to
* @param {String} val - The value to compare to
* @param {String} [pos=both] - The placement of the wildcard character(s): before, after, or both
* @return {QueryBuilder} - The Query Builder object, for chaining
*/
orLike (field, val, pos) {
this._like(field, val, pos, ' LIKE ', 'OR');
return this;
}
/**
* Add an 'or not like' clause to the query
*
* @param {String} field - The name of the field to compare to
* @param {String} val - The value to compare to
* @param {String} [pos=both] - The placement of the wildcard character(s): before, after, or both
* @return {QueryBuilder} - The Query Builder object, for chaining
*/
orNotLike (field, val, pos) {
this._like(field, val, pos, ' NOT LIKE ', 'OR');
return this;
}
/**
* Add a 'having' clause
*
* @param {String|Object} key - The name of the field and the comparision operator, or an object
* @param {String|Number} [val] - The value to compare if the value of key is a string
* @return {QueryBuilder} - The Query Builder object, for chaining
*/
having (key, val = null) {
this._having(key, val, 'AND');
return this;
}
/**
* Add an 'or having' clause
*
* @param {String|Object} key - The name of the field and the comparision operator, or an object
* @param {String|Number} [val] - The value to compare if the value of key is a string
* @return {QueryBuilder} - The Query Builder object, for chaining
*/
orHaving (key, val = null) {
this._having(key, val, 'OR');
return this;
}
/**
* Set a 'where' clause
*
* @param {String|Object} key - The name of the field and the comparision operator, or an object
* @param {String|Number} [val] - The value to compare if the value of key is a string
* @return {QueryBuilder} - The Query Builder object, for chaining
*/
where (key, val) {
this._where(key, val, 'AND');
return this;
}
/**
* Set a 'or where' clause
*
* @param {String|Object} key - The name of the field and the comparision operator, or an object
* @param {String|Number} [val] - The value to compare if the value of key is a string
* @return {QueryBuilder} - The Query Builder object, for chaining
*/
orWhere (key, val) {
this._where(key, val, 'OR');
return this;
}
/**
* Select a field that is Null
*
* @param {String} field - The name of the field that has a NULL value
* @return {QueryBuilder} - The Query Builder object, for chaining
*/
whereIsNull (field) {
this._whereNull(field, 'IS NULL', 'AND');
return this;
}
/**
* Specify that a field IS NOT NULL
*
* @param {String} field - The name so the field that is not to be null
* @return {QueryBuilder} - The Query Builder object, for chaining
*/
whereIsNotNull (field) {
this._whereNull(field, 'IS NOT NULL', 'AND');
return this;
}
/**
* Field is null prefixed with 'OR'
*
* @param {String} field - The name of the field
* @return {QueryBuilder} - The Query Builder object, for chaining
*/
orWhereIsNull (field) {
this._whereNull(field, 'IS NULL', 'OR');
return this;
}
/**
* Field is not null prefixed with 'OR'
*
* @param {String} field - The name of the field
* @return {QueryBuilder} - The Query Builder object, for chaining
*/
orWhereIsNotNull (field) {
this._whereNull(field, 'IS NOT NULL', 'OR');
return this;
}
/**
* Set a 'where in' clause
*
* @param {String} key - the field to search
* @param {Array} values - the array of items to search in
* @return {QueryBuilder} - The Query Builder object, for chaining
*/
whereIn (key, values) {
this._whereIn(key, values, 'IN', 'AND');
return this;
}
/**
* Set a 'or where in' clause
*
* @param {String} key - the field to search
* @param {Array} values - the array of items to search in
* @return {QueryBuilder} - The Query Builder object, for chaining
*/
orWhereIn (key, values) {
this._whereIn(key, values, 'IN', 'OR');
return this;
}
/**
* Set a 'where not in' clause
*
* @param {String} key - the field to search
* @param {Array} values - the array of items to search in
* @return {QueryBuilder} - The Query Builder object, for chaining
*/
whereNotIn (key, values) {
this._whereIn(key, values, 'NOT IN', 'AND');
return this;
}
/**
* Set a 'or where not in' clause
*
* @param {String} key - the field to search
* @param {Array} values - the array of items to search in
* @return {QueryBuilder} - The Query Builder object, for chaining
*/
orWhereNotIn (key, values) {
this._whereIn(key, values, 'NOT IN', 'OR');
return this;
}
/**
* Set values for insertion or updating
*
* @param {String|Object} key - The key or object to use
* @param {String} [val] - The value if using a scalar key
* @example query.set('foo', 'bar'); // Set a key, value pair
* @example query.set({foo:'bar'}); // Set with an object
* @return {QueryBuilder} - The Query Builder object, for chaining
*/
set (key, val) {
// Set the appropriate state variables
this._mixedSet('setArrayKeys', 'key', key, val);
this._mixedSet('values', 'value', key, val);
// Use the keys of the array to make the insert/update string
// and escape the field names
this.state.setArrayKeys = this.state.setArrayKeys.map(this.driver._quote);
// Generate the "set" string
this.state.setString = this.state.setArrayKeys.join('=?,');
this.state.setString += '=?';
return this;
}
/**
* Add a join clause to the query
*
* @param {String} table - The table you are joining
* @param {String} cond - The join condition.
* @param {String} [type='inner'] - The type of join, which defaults to inner
* @return {QueryBuilder} - The Query Builder object, for chaining
*/
join (table, cond, type) {
type = type || 'inner';
// Prefix/quote table name
table = table.split(' ').map(Helpers.stringTrim);
table[0] = this.driver.quoteTable(table[0]);
table = table.map(this.driver.quoteIdentifiers);
table = table.join(' ');
// Parse out the join condition
const parsedCondition = this.parser.compileJoin(cond);
const condition = `${table} ON ${parsedCondition}`;
// Append the join condition to the query map
this._appendMap(`\n${type.toUpperCase()} JOIN `, condition, 'join');
return this;
}
/**
* Group the results by the selected field(s)
*
* @param {String|Array} field - The name of the field to group by
* @return {QueryBuilder} - The Query Builder object, for chaining
*/
groupBy (field) {
if (!Helpers.isScalar(field)) {
const newGroupArray = field.map(this.driver.quoteIdentifiers);
this.state.groupArray = this.state.groupArray.concat(newGroupArray);
} else {
this.state.groupArray.push(this.driver.quoteIdentifiers(field));
}
this.state.groupString = ` GROUP BY ${this.state.groupArray.join(',')}`;
return this;
}
/**
* Order the results by the selected field(s)
*
* @param {String} field - The field(s) to order by
* @param {String} [type='ASC'] - The order direction, ASC or DESC
* @return {QueryBuilder} - The Query Builder object, for chaining
*/
orderBy (field, type) {
type = type || 'ASC';
// Set the fields for later manipulation
field = this.driver.quoteIdentifiers(field);
this.state.orderArray[field] = type;
const orderClauses = [];
// Flatten key/val pairs into an array of space-separated pairs
Object.keys(this.state.orderArray).forEach(key => {
orderClauses.push(`${key} ${this.state.orderArray[key].toUpperCase()}`);
});
// Set the final string
this.state.orderString = ` ORDER BY ${orderClauses.join(', ')}`;
return this;
}
/**
* Put a limit on the query
*
* @param {Number} limit - The maximum number of rows to fetch
* @param {Number} [offset] - The row number to start from
* @return {QueryBuilder} - The Query Builder object, for chaining
*/
limit (limit, offset) {
this.state.limit = limit;
this.state.offset = offset || null;
return this;
}
/**
* Adds an open paren to the current query for logical grouping
*
* @return {QueryBuilder} - The Query Builder object, for chaining
*/
groupStart () {
const conj = (this.state.queryMap.length &lt; 1) ? ' WHERE ' : ' AND ';
this._appendMap(conj, '(', 'groupStart');
return this;
}
/**
* Adds an open paren to the current query for logical grouping,
* prefixed with 'OR'
*
* @return {QueryBuilder} - The Query Builder object, for chaining
*/
orGroupStart () {
this._appendMap('', ' OR (', 'groupStart');
return this;
}
/**
* Adds an open paren to the current query for logical grouping,
* prefixed with 'OR NOT'
*
* @return {QueryBuilder} - The Query Builder object, for chaining
*/
orNotGroupStart () {
this._appendMap('', ' OR NOT (', 'groupStart');
return this;
}
/**
* Ends a logical grouping started with one of the groupStart methods
*
* @return {QueryBuilder} - The Query Builder object, for chaining
*/
groupEnd () {
this._appendMap('', ')', 'groupEnd');
return this;
}
// ------------------------------------------------------------------------
// ! Result Methods
// ------------------------------------------------------------------------
/**
* Get the results of the compiled query
*
* @param {String} [table] - The table to select from
* @param {Number} [limit] - A limit for the query
* @param {Number} [offset] - An offset for the query
* @example query.get('table_name').then(promiseCallback); // Get all the rows in the table
* @example query.get('table_name', 5); // Get 5 rows from the table
* @example query.get(); // Get the results of a query generated with other methods
* @return {Promise&lt;Result>} - Promise containing the result of the query
*/
get (table, limit, offset) {
if (table) {
this.from(table);
}
if (limit) {
this.limit(limit, offset);
}
// Run the query
return this._run('get', table);
}
/**
* Run the generated insert query
*
* @param {String} table - The table to insert into
* @param {Object} [data] - Data to insert, if not already added with the 'set' method
* @return {Promise&lt;Result>} - Promise containing the result of the query
*/
insert (table, data) {
if (data) {
this.set(data);
}
// Run the query
return this._run('insert', this.driver.quoteTable(table));
}
/**
* Insert multiple sets of rows at a time
*
* @param {String} table - The table to insert into
* @param {Array} data - The array of objects containing data rows to insert
* @example query.insertBatch('foo',[{id:1,val:'bar'},{id:2,val:'baz'}])
*.then(promiseCallback);
* @return {Promise&lt;Result>} - Promise containing the result of the query
*/
insertBatch (table, data) {
const batch = this.driver.insertBatch(table, data);
// Run the query
return this.query(batch.sql, batch.values);
}
/**
* Run the generated update query
*
* @param {String} table - The table to insert into
* @param {Object} [data] - Data to insert, if not already added with the 'set' method
* @return {Promise&lt;Result>} - Promise containing the result of the query
*/
update (table, data) {
if (data) {
this.set(data);
}
// Run the query
return this._run('update', this.driver.quoteTable(table));
}
/**
* Creates a batch update sql statement
*
* @param {String} table - The table to update
* @param {Object} data - Batch insert data
* @param {String} updateKey - The field in the table to compare against for updating
* @return {Number} Number of rows updated
*/
updateBatch (table, data, updateKey) {
const [sql, insertData, affectedRows] = this.driver.updateBatch(table, data, updateKey);
this._run('', table, sql, insertData);
return affectedRows;
}
/**
* Run the generated delete query
*
* @param {String} table - The table to insert into
* @param {Object} [where] - Where clause for delete statement
* @return {Promise&lt;Result>} - Promise containing the result of the query
*/
delete (table, where) {
if (where) {
this.where(where);
}
// Run the query
return this._run('delete', this.driver.quoteTable(table));
}
// ------------------------------------------------------------------------
// ! Methods returning SQL
// ------------------------------------------------------------------------
/**
* Return generated select query SQL
*
* @param {String} [table] - the name of the table to retrieve from
* @param {Boolean} [reset=true] - Whether to reset the query builder so another query can be built
* @return {String} - The compiled sql statement
*/
getCompiledSelect (table, reset = true) {
if (table) {
this.from(table);
}
return this._getCompile('get', table, reset);
}
/**
* Return generated insert query SQL
*
* @param {String} table - the name of the table to insert into
* @param {Boolean} [reset=true] - Whether to reset the query builder so another query can be built
* @return {String} - The compiled sql statement
*/
getCompiledInsert (table, reset = true) {
return this._getCompile('insert', this.driver.quoteTable(table), reset);
}
/**
* Return generated update query SQL
*
* @param {String} table - the name of the table to update
* @param {Boolean} [reset=true] - Whether to reset the query builder so another query can be built
* @return {String} - The compiled sql statement
*/
getCompiledUpdate (table, reset = true) {
return this._getCompile('update', this.driver.quoteTable(table), reset);
}
/**
* Return generated delete query SQL
*
* @param {String} table - the name of the table to delete from
* @param {Boolean} [reset=true] - Whether to reset the query builder so another query can be built
* @return {String} - The compiled sql statement
*/
getCompiledDelete (table, reset = true) {
return this._getCompile('delete', this.driver.quoteTable(table), reset);
}
}
module.exports = QueryBuilder;
</code></pre>
</article>
</section>
</div>
<nav>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-drivers_MariaDB.html">drivers/MariaDB</a></li><li><a href="module-drivers_MSSQLDriver.html">drivers/MSSQLDriver</a></li><li><a href="module-drivers_Mysql.html">drivers/Mysql</a></li><li><a href="module-drivers_Pg.html">drivers/Pg</a></li><li><a href="module-drivers_Sqlite.html">drivers/Sqlite</a></li></ul><h3>Classes</h3><ul><li><a href="NodeQuery.html">NodeQuery</a></li><li><a href="QueryBuilder.html">QueryBuilder</a></li><li><a href="Result.html">Result</a></li></ul>
</nav>
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Mon Feb 12 2018 14:58:25 GMT-0500 (EST)
</footer>
<script> prettyPrint(); </script>
<script src="scripts/linenumber.js"> </script>
</body>
</html>

View File

@ -0,0 +1,298 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>JSDoc: Source: QueryParser.js</title>
<script src="scripts/prettify/prettify.js"> </script>
<script src="scripts/prettify/lang-css.js"> </script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>
<body>
<div id="main">
<h1 class="page-title">Source: QueryParser.js</h1>
<section>
<article>
<pre class="prettyprint source linenums"><code>const XRegExp = require('xregexp');
const Helpers = require('./Helpers');
// --------------------------------------------------------------------------
/**
* Internal object for parsing query fragments
*
* @private
* @param {Driver} driver - The driver object for the database in use
*/
class QueryParser {
/**
* @constructor
*
* @param {Driver} driver - The driver object for the database in use
* @return {void}
*/
constructor (driver) {
this.driver = driver;
const matchPatterns = {
function: /([a-z0-9_]+\((.*)\))/i,
operator: /!=?|=|\+|&amp;&amp;?|~|\|\|?|\^|\/|&lt;>|>=?|&lt;=?|-|%|OR|AND|NOT|XOR/ig,
literal: /([0-9]+)|'(.*?)'|true|false/ig
};
// Full pattern for identifiers
// Making sure that literals and functions aren't matched
matchPatterns.identifier = XRegExp(
`(
(?!
${matchPatterns['function'].source}|
${matchPatterns.literal.source}
)
([a-z_-]+[0-9]*\\.?)
)+`, 'igx');
// Full pattern for determining ordering of the pieces
matchPatterns.joinCombined = XRegExp(
`${matchPatterns['function'].source}+| # functions
${matchPatterns.literal.source}+| # literal values
${matchPatterns.identifier.source} # identifiers
|(${matchPatterns.operator.source})+`, 'igx');
this.matchPatterns = matchPatterns;
this.identifierBlacklist = ['true', 'false', 'null'];
}
/**
* Filter matched patterns
*
* @param {Array} array - Set of possible matches
* @return {Array|null} - Filtered set of possible matches
*/
filterMatches (array) {
const output = [];
// Return non-array matches
if (Helpers.isNull(array)) {
return null;
}
array.forEach(item => {
output.push(item);
});
return output;
}
/**
* Check if the string contains an operator, and if so, return the operator(s).
* If there are no matches, return null
*
* @param {String} string - the string to check
* @return {Array|null} - List of operators
*/
hasOperator (string) {
return this.filterMatches(string.match(this.matchPatterns.operator));
}
/**
* Tokenize the sql into parts for additional processing
*
* @param {String} sql - Join sql to parse
* @return {Object} - Join condition components
*/
parseJoin (sql) {
const matches = {};
const output = {
functions: [],
identifiers: [],
operators: [],
literals: []
};
// Get clause components
matches.functions = sql.match(new RegExp(this.matchPatterns['function'].source, 'ig'));
matches.identifiers = sql.match(this.matchPatterns.identifier);
matches.operators = sql.match(this.matchPatterns.operator);
matches.literals = sql.match(this.matchPatterns.literal);
// Get everything at once for ordering
matches.combined = sql.match(this.matchPatterns.joinCombined);
// Flatten the matches to increase relevance
Object.keys(matches).forEach(key => {
output[key] = this.filterMatches(matches[key]);
});
return output;
}
/**
* Return the output of the parsing of the join condition
*
* @param {String} condition - The join condition to evaluate
* @return {String} - The parsed/escaped join condition
*/
compileJoin (condition) {
const parts = this.parseJoin(condition);
// Quote the identifiers
parts.combined.forEach((part, i) => {
if (parts.identifiers.indexOf(part) !== -1 &amp;&amp; !Helpers.isNumber(part)) {
parts.combined[i] = this.driver.quoteIdentifiers(part);
}
});
return parts.combined.join(' ');
}
/**
* Parse a where clause to separate functions from values
*
* @param {Driver} driver - The current db driver
* @param {State} state - Query Builder state object
* @return {String} - The parsed/escaped where condition
*/
parseWhere (driver, state) {
const whereMap = state.whereMap;
let whereValues = state.rawWhereValues;
const outputMap = [];
const outputValues = [];
Object.keys(whereMap).forEach(key => {
// Combine fields, operators, functions and values into a full clause
// to have a common starting flow
let fullClause = '';
// Add an explicit = sign where one is inferred
if (!this.hasOperator(key)) {
fullClause = `${key} = ${whereMap[key]}`;
} else if (whereMap[key] === key) {
fullClause = key;
} else {
fullClause = `${key} ${whereMap[key]}`;
}
// Separate the clause into separate pieces
const parts = this.parseJoin(fullClause);
// Filter explicit literals from lists of matches
if (whereValues.indexOf(whereMap[key]) !== -1) {
const value = whereMap[key];
const identIndex = parts.identifiers.indexOf(value);
const litIndex = (Helpers.isArray(parts.literals)) ? parts.literals.indexOf(value) : -1;
const combIndex = parts.combined.indexOf(value);
const funcIndex = (Helpers.isArray(parts.functions)) ? parts.functions.indexOf(value) : -1;
let inOutputArray = outputValues.includes(value);
// Remove the identifier in question,
// and add to the output values array
if (identIndex !== -1) {
parts.identifiers.splice(identIndex, 1);
if (!inOutputArray) {
outputValues.push(value);
inOutputArray = true;
}
}
// Remove the value from the literals list
// so it is not added twice
if (litIndex !== -1) {
parts.literals.splice(litIndex, 1);
if (!inOutputArray) {
outputValues.push(value);
inOutputArray = true;
}
}
// Remove the value from the combined list
// and replace it with a placeholder
if (combIndex !== -1 &amp;&amp; funcIndex === -1) {
// Make sure to skip functions when replacing values
parts.combined[combIndex] = '?';
}
}
// Filter false positive identifiers
parts.identifiers = parts.identifiers.filter(item => {
const isInCombinedMatches = parts.combined.indexOf(item) !== -1;
const isNotInBlackList = this.identifierBlacklist.indexOf(item.toLowerCase()) === -1;
return isInCombinedMatches &amp;&amp; isNotInBlackList;
}, this);
// Quote identifiers
if (Helpers.isArray(parts.identifiers)) {
parts.identifiers.forEach(ident => {
const index = parts.combined.indexOf(ident);
if (index !== -1) {
parts.combined[index] = driver.quoteIdentifiers(ident);
}
});
}
// Replace each literal with a placeholder in the map
// and add the literal to the values,
// This should only apply to literal values that are not
// explicitly mapped to values, but have to be parsed from
// a where condition,
if (Helpers.isArray(parts.literals)) {
parts.literals.forEach(lit => {
const litIndex = parts.combined.indexOf(lit);
if (litIndex !== -1) {
parts.combined[litIndex] = '?';
outputValues.push(lit);
}
});
}
outputMap.push(parts.combined.join(' '));
});
state.rawWhereValues = [];
state.whereValues = state.whereValues.concat(outputValues);
state.whereMap = outputMap;
return state;
}
}
module.exports = QueryParser;
</code></pre>
</article>
</section>
</div>
<nav>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-drivers_MariaDB.html">drivers/MariaDB</a></li><li><a href="module-drivers_MSSQLDriver.html">drivers/MSSQLDriver</a></li><li><a href="module-drivers_Mysql.html">drivers/Mysql</a></li><li><a href="module-drivers_Pg.html">drivers/Pg</a></li><li><a href="module-drivers_Sqlite.html">drivers/Sqlite</a></li></ul><h3>Classes</h3><ul><li><a href="NodeQuery.html">NodeQuery</a></li><li><a href="QueryBuilder.html">QueryBuilder</a></li><li><a href="Result.html">Result</a></li></ul>
</nav>
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Mon Feb 12 2018 14:58:25 GMT-0500 (EST)
</footer>
<script> prettyPrint(); </script>
<script src="scripts/linenumber.js"> </script>
</body>
</html>

464
documentation/Result.html Normal file
View File

@ -0,0 +1,464 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>JSDoc: Class: Result</title>
<script src="scripts/prettify/prettify.js"> </script>
<script src="scripts/prettify/lang-css.js"> </script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>
<body>
<div id="main">
<h1 class="page-title">Class: Result</h1>
<section>
<header>
<h2><span class="attribs"><span class="type-signature"></span></span>Result<span class="signature">(rows, columns)</span><span class="type-signature"></span></h2>
<div class="class-description">Query result object</div>
</header>
<article>
<div class="container-overview">
<h2>Constructor</h2>
<h4 class="name" id="Result"><span class="type-signature"></span>new Result<span class="signature">(rows, columns)</span><span class="type-signature"></span></h4>
<div class="description">
Create a result object
</div>
<h5>Parameters:</h5>
<table class="params">
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th class="last">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="name"><code>rows</code></td>
<td class="type">
<span class="param-type">Array</span>
</td>
<td class="description last">the data rows of the result</td>
</tr>
<tr>
<td class="name"><code>columns</code></td>
<td class="type">
<span class="param-type">Array</span>
</td>
<td class="description last">the column names in the result</td>
</tr>
</tbody>
</table>
<dl class="details">
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="Result.js.html">Result.js</a>, <a href="Result.js.html#line9">line 9</a>
</li></ul></dd>
</dl>
</div>
<h3 class="subsection-title">Methods</h3>
<h4 class="name" id="columnCount"><span class="type-signature"></span>columnCount<span class="signature">()</span><span class="type-signature"> &rarr; {Number}</span></h4>
<div class="description">
Get the number of columns returned by the query
</div>
<dl class="details">
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="Result.js.html">Result.js</a>, <a href="Result.js.html#line88">line 88</a>
</li></ul></dd>
</dl>
<h5>Returns:</h5>
<div class="param-desc">
- the number of columns in the result
</div>
<dl>
<dt>
Type
</dt>
<dd>
<span class="param-type">Number</span>
</dd>
</dl>
<h4 class="name" id="rowCount"><span class="type-signature"></span>rowCount<span class="signature">()</span><span class="type-signature"> &rarr; {Number}</span></h4>
<div class="description">
Get the number of rows returned by the query
</div>
<dl class="details">
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="Result.js.html">Result.js</a>, <a href="Result.js.html#line79">line 79</a>
</li></ul></dd>
</dl>
<h5>Returns:</h5>
<div class="param-desc">
- the number of rows in the result
</div>
<dl>
<dt>
Type
</dt>
<dd>
<span class="param-type">Number</span>
</dd>
</dl>
</article>
</section>
</div>
<nav>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-drivers_MariaDB.html">drivers/MariaDB</a></li><li><a href="module-drivers_MSSQLDriver.html">drivers/MSSQLDriver</a></li><li><a href="module-drivers_Mysql.html">drivers/Mysql</a></li><li><a href="module-drivers_Pg.html">drivers/Pg</a></li><li><a href="module-drivers_Sqlite.html">drivers/Sqlite</a></li></ul><h3>Classes</h3><ul><li><a href="NodeQuery.html">NodeQuery</a></li><li><a href="QueryBuilder.html">QueryBuilder</a></li><li><a href="Result.html">Result</a></li></ul>
</nav>
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Mon Feb 12 2018 14:58:25 GMT-0500 (EST)
</footer>
<script> prettyPrint(); </script>
<script src="scripts/linenumber.js"> </script>
</body>
</html>

View File

@ -0,0 +1,144 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>JSDoc: Source: Result.js</title>
<script src="scripts/prettify/prettify.js"> </script>
<script src="scripts/prettify/lang-css.js"> </script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>
<body>
<div id="main">
<h1 class="page-title">Source: Result.js</h1>
<section>
<article>
<pre class="prettyprint source linenums"><code>const Helpers = require('./Helpers');
/**
* Query result object
*
* @param {Array} rows - the data rows of the result
* @param {Array} columns - the column names in the result
*/
class Result {
/**
* Create a result object
*
* @private
* @param {Array} [rows] - the data rows of the result
* @param {Array} [columns] - the column names in the result
*/
constructor (rows = [], columns = []) {
this._rows = rows;
this._columns = columns;
// If columns aren't explicitly given,
// get the list from the first row's keys
if (
this._columns.length === 0 &amp;&amp;
this._rows.length > 0 &amp;&amp;
Helpers.isObject(rows[0])
) {
this.columns = Object.keys(rows[0]);
}
}
/**
* Return the result rows
*
* @private
* @return {Array} - the data rows of the result
*/
get rows () {
return this._rows;
}
/**
* Set the result rows for the result object
*
* @private
* @param {Array} rows - the data rows of the result
* @return {void}
*/
set rows (rows) {
this._rows = rows;
}
/**
* Return the result columns
*
* @private
* @return {Array} - the column names in the result
*/
get columns () {
return this._columns;
}
/**
* Set the result columns for the result object
*
* @private
* @param {Array} cols - the array of columns for the current result
* @return {void}
*/
set columns (cols) {
this._columns = cols;
}
/**
* Get the number of rows returned by the query
*
* @return {Number} - the number of rows in the result
*/
rowCount () {
return this._rows.length;
}
/**
* Get the number of columns returned by the query
*
* @return {Number} - the number of columns in the result
*/
columnCount () {
return this._columns.length;
}
}
module.exports = Result;
</code></pre>
</article>
</section>
</div>
<nav>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-drivers_MariaDB.html">drivers/MariaDB</a></li><li><a href="module-drivers_MSSQLDriver.html">drivers/MSSQLDriver</a></li><li><a href="module-drivers_Mysql.html">drivers/Mysql</a></li><li><a href="module-drivers_Pg.html">drivers/Pg</a></li><li><a href="module-drivers_Sqlite.html">drivers/Sqlite</a></li></ul><h3>Classes</h3><ul><li><a href="NodeQuery.html">NodeQuery</a></li><li><a href="QueryBuilder.html">QueryBuilder</a></li><li><a href="Result.html">Result</a></li></ul>
</nav>
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Mon Feb 12 2018 14:58:25 GMT-0500 (EST)
</footer>
<script> prettyPrint(); </script>
<script src="scripts/linenumber.js"> </script>
</body>
</html>

View File

@ -0,0 +1,100 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>JSDoc: Source: adapters/Mysql/mysql2.js</title>
<script src="scripts/prettify/prettify.js"> </script>
<script src="scripts/prettify/lang-css.js"> </script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>
<body>
<div id="main">
<h1 class="page-title">Source: adapters/Mysql/mysql2.js</h1>
<section>
<article>
<pre class="prettyprint source linenums"><code>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} 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;
</code></pre>
</article>
</section>
</div>
<nav>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-drivers_MariaDB.html">drivers/MariaDB</a></li><li><a href="module-drivers_MSSQLDriver.html">drivers/MSSQLDriver</a></li><li><a href="module-drivers_Mysql.html">drivers/Mysql</a></li><li><a href="module-drivers_Pg.html">drivers/Pg</a></li><li><a href="module-drivers_Sqlite.html">drivers/Sqlite</a></li></ul><h3>Classes</h3><ul><li><a href="NodeQuery.html">NodeQuery</a></li><li><a href="QueryBuilder.html">QueryBuilder</a></li><li><a href="Result.html">Result</a></li></ul>
</nav>
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Mon Feb 12 2018 14:58:25 GMT-0500 (EST)
</footer>
<script> prettyPrint(); </script>
<script src="scripts/linenumber.js"> </script>
</body>
</html>

View File

@ -0,0 +1,154 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>JSDoc: Source: adapters/Pg/Pg.js</title>
<script src="scripts/prettify/prettify.js"> </script>
<script src="scripts/prettify/lang-css.js"> </script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>
<body>
<div id="main">
<h1 class="page-title">Source: adapters/Pg/Pg.js</h1>
<section>
<article>
<pre class="prettyprint source linenums"><code>const Adapter = require('../../Adapter');
const Result = require('../../Result');
const Helpers = require('../../Helpers');
const pg = require('pg');
const url = require('url');
class Pg extends Adapter {
constructor (config) {
let instance = null;
let connectionString = Pg.formatConnectionString(config);
if (connectionString !== '') {
const conn = new pg.Client(connectionString);
conn.connect(err => {
if (err) {
throw new Error(err);
}
});
instance = Promise.resolve(conn);
}
super(instance);
}
/**
* Convert the connection object to a connection string
*
* @param {Object} config - the configuration object
* @return {String} - the connection string
*/
static formatConnectionString (config) {
let connectionString = '';
if (Helpers.isObject(config)) {
const host = config.host || 'localhost';
const user = config.user || 'postgres';
const password = `:${config.password}` || '';
const port = config.port || 5432;
const conn = {
protocol: 'postgres',
slashes: true,
host: `${host}:${port}`,
auth: `${user}${password}`,
pathname: config.database
};
connectionString = url.format(conn);
} else if (Helpers.isString(config)) {
connectionString = config;
}
return connectionString;
}
/**
* Transform the adapter's result into a standard format
*
* @param {*} result - original driver result object
* @return {Result} - standard result object
*/
transformResult (result) {
if (result == null) {
return new Result();
}
const cols = [];
result.fields.forEach(field => {
cols.push(field.name);
});
return new Result(result.rows, cols);
}
/**
* 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 {void|Promise} - Returns a promise if no callback is provided
*/
execute (sql, params) {
// Replace question marks with numbered placeholders, because this adapter is different...
let count = 0;
sql = sql.replace(/\?/g, () => {
count++;
return `$${count}`;
});
return this.instance.then(conn => {
return new Promise((resolve, reject) => {
conn.query(sql, params, (err, result) =>
(err)
? reject(err)
: resolve(this.transformResult(result))
);
});
});
}
}
module.exports = Pg;
</code></pre>
</article>
</section>
</div>
<nav>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-drivers_MariaDB.html">drivers/MariaDB</a></li><li><a href="module-drivers_MSSQLDriver.html">drivers/MSSQLDriver</a></li><li><a href="module-drivers_Mysql.html">drivers/Mysql</a></li><li><a href="module-drivers_Pg.html">drivers/Pg</a></li><li><a href="module-drivers_Sqlite.html">drivers/Sqlite</a></li></ul><h3>Classes</h3><ul><li><a href="NodeQuery.html">NodeQuery</a></li><li><a href="QueryBuilder.html">QueryBuilder</a></li><li><a href="Result.html">Result</a></li></ul>
</nav>
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Mon Feb 12 2018 14:58:25 GMT-0500 (EST)
</footer>
<script> prettyPrint(); </script>
<script src="scripts/linenumber.js"> </script>
</body>
</html>

View File

@ -0,0 +1,116 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>JSDoc: Source: adapters/Sqlite/dblite.js</title>
<script src="scripts/prettify/prettify.js"> </script>
<script src="scripts/prettify/lang-css.js"> </script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>
<body>
<div id="main">
<h1 class="page-title">Source: adapters/Sqlite/dblite.js</h1>
<section>
<article>
<pre class="prettyprint source linenums"><code>const Adapter = require('../../Adapter');
const Result = require('../../Result');
const Helpers = require('../../Helpers');
const dbliteAdapter = require('dblite');
class SqliteDblite extends Adapter {
constructor (config) {
const file = (Helpers.isString(config)) ? config : config.file;
const instance = new Promise((resolve, reject) => {
const 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;
</code></pre>
</article>
</section>
</div>
<nav>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-drivers_MariaDB.html">drivers/MariaDB</a></li><li><a href="module-drivers_MSSQLDriver.html">drivers/MSSQLDriver</a></li><li><a href="module-drivers_Mysql.html">drivers/Mysql</a></li><li><a href="module-drivers_Pg.html">drivers/Pg</a></li><li><a href="module-drivers_Sqlite.html">drivers/Sqlite</a></li></ul><h3>Classes</h3><ul><li><a href="NodeQuery.html">NodeQuery</a></li><li><a href="QueryBuilder.html">QueryBuilder</a></li><li><a href="Result.html">Result</a></li></ul>
</nav>
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Mon Feb 12 2018 14:58:25 GMT-0500 (EST)
</footer>
<script> prettyPrint(); </script>
<script src="scripts/linenumber.js"> </script>
</body>
</html>

View File

@ -0,0 +1,112 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>JSDoc: Source: adapters/Sqlite/sqlite3.js</title>
<script src="scripts/prettify/prettify.js"> </script>
<script src="scripts/prettify/lang-css.js"> </script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>
<body>
<div id="main">
<h1 class="page-title">Source: adapters/Sqlite/sqlite3.js</h1>
<section>
<article>
<pre class="prettyprint source linenums"><code>const Adapter = require('../../Adapter');
const Result = require('../../Result');
const Helpers = require('../../Helpers');
const sqlite3 = require('sqlite3').verbose();
class SqliteSqlite3 extends Adapter {
constructor (config) {
const file = (Helpers.isString(config)) ? config : config.file;
const instance = new Promise((resolve, reject) => {
const 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;
</code></pre>
</article>
</section>
</div>
<nav>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-drivers_MariaDB.html">drivers/MariaDB</a></li><li><a href="module-drivers_MSSQLDriver.html">drivers/MSSQLDriver</a></li><li><a href="module-drivers_Mysql.html">drivers/Mysql</a></li><li><a href="module-drivers_Pg.html">drivers/Pg</a></li><li><a href="module-drivers_Sqlite.html">drivers/Sqlite</a></li></ul><h3>Classes</h3><ul><li><a href="NodeQuery.html">NodeQuery</a></li><li><a href="QueryBuilder.html">QueryBuilder</a></li><li><a href="Result.html">Result</a></li></ul>
</nav>
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Mon Feb 12 2018 14:58:25 GMT-0500 (EST)
</footer>
<script> prettyPrint(); </script>
<script src="scripts/linenumber.js"> </script>
</body>
</html>

View File

@ -0,0 +1,65 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>JSDoc: Source: drivers/MSSQLDriver.js</title>
<script src="scripts/prettify/prettify.js"> </script>
<script src="scripts/prettify/lang-css.js"> </script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>
<body>
<div id="main">
<h1 class="page-title">Source: drivers/MSSQLDriver.js</h1>
<section>
<article>
<pre class="prettyprint source linenums"><code>/**
* Driver for Microsoft SQL Server databases
*
* @module drivers/MSSQLDriver
*/
module.exports = (() => {
delete require.cache[require.resolve('../Driver')];
const driver = require('../Driver');
driver.identifierStartChar = '[';
driver.identifierEndChar = ']';
return driver;
})();
</code></pre>
</article>
</section>
</div>
<nav>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-drivers_MariaDB.html">drivers/MariaDB</a></li><li><a href="module-drivers_MSSQLDriver.html">drivers/MSSQLDriver</a></li><li><a href="module-drivers_Mysql.html">drivers/Mysql</a></li><li><a href="module-drivers_Pg.html">drivers/Pg</a></li><li><a href="module-drivers_Sqlite.html">drivers/Sqlite</a></li></ul><h3>Classes</h3><ul><li><a href="NodeQuery.html">NodeQuery</a></li><li><a href="QueryBuilder.html">QueryBuilder</a></li><li><a href="Result.html">Result</a></li></ul>
</nav>
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Mon Feb 12 2018 14:58:25 GMT-0500 (EST)
</footer>
<script> prettyPrint(); </script>
<script src="scripts/linenumber.js"> </script>
</body>
</html>

View File

@ -0,0 +1,57 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>JSDoc: Source: drivers/MariaDB.js</title>
<script src="scripts/prettify/prettify.js"> </script>
<script src="scripts/prettify/lang-css.js"> </script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>
<body>
<div id="main">
<h1 class="page-title">Source: drivers/MariaDB.js</h1>
<section>
<article>
<pre class="prettyprint source linenums"><code>/**
* Driver for MariaDB databases
*
* @module drivers/MariaDB
*/
module.exports = require('./Mysql');
</code></pre>
</article>
</section>
</div>
<nav>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-drivers_MariaDB.html">drivers/MariaDB</a></li><li><a href="module-drivers_MSSQLDriver.html">drivers/MSSQLDriver</a></li><li><a href="module-drivers_Mysql.html">drivers/Mysql</a></li><li><a href="module-drivers_Pg.html">drivers/Pg</a></li><li><a href="module-drivers_Sqlite.html">drivers/Sqlite</a></li></ul><h3>Classes</h3><ul><li><a href="NodeQuery.html">NodeQuery</a></li><li><a href="QueryBuilder.html">QueryBuilder</a></li><li><a href="Result.html">Result</a></li></ul>
</nav>
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Mon Feb 12 2018 14:58:25 GMT-0500 (EST)
</footer>
<script> prettyPrint(); </script>
<script src="scripts/linenumber.js"> </script>
</body>
</html>

View File

@ -0,0 +1,82 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>JSDoc: Source: drivers/Mysql.js</title>
<script src="scripts/prettify/prettify.js"> </script>
<script src="scripts/prettify/lang-css.js"> </script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>
<body>
<div id="main">
<h1 class="page-title">Source: drivers/Mysql.js</h1>
<section>
<article>
<pre class="prettyprint source linenums"><code>/**
* Driver for MySQL databases
*
* @module drivers/Mysql
*/
module.exports = (() => {
delete require.cache[require.resolve('../Driver')];
const driver = require('../Driver');
const Helpers = require('../Helpers');
driver.identifierStartChar = '`';
driver.identifierEndChar = '`';
/**
* Set the limit clause
*
* @param {String} sql - 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 = (sql, limit, offset) => {
sql += (Helpers.isNumber(offset))
? ` LIMIT ${offset},${limit}`
: ` LIMIT ${limit}`;
return sql;
};
return driver;
})();
</code></pre>
</article>
</section>
</div>
<nav>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-drivers_MariaDB.html">drivers/MariaDB</a></li><li><a href="module-drivers_MSSQLDriver.html">drivers/MSSQLDriver</a></li><li><a href="module-drivers_Mysql.html">drivers/Mysql</a></li><li><a href="module-drivers_Pg.html">drivers/Pg</a></li><li><a href="module-drivers_Sqlite.html">drivers/Sqlite</a></li></ul><h3>Classes</h3><ul><li><a href="NodeQuery.html">NodeQuery</a></li><li><a href="QueryBuilder.html">QueryBuilder</a></li><li><a href="Result.html">Result</a></li></ul>
</nav>
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Mon Feb 12 2018 14:58:25 GMT-0500 (EST)
</footer>
<script> prettyPrint(); </script>
<script src="scripts/linenumber.js"> </script>
</body>
</html>

View File

@ -0,0 +1,60 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>JSDoc: Source: drivers/Pg.js</title>
<script src="scripts/prettify/prettify.js"> </script>
<script src="scripts/prettify/lang-css.js"> </script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>
<body>
<div id="main">
<h1 class="page-title">Source: drivers/Pg.js</h1>
<section>
<article>
<pre class="prettyprint source linenums"><code>/**
* Driver for PostgreSQL databases
*
* @module drivers/Pg
*/
module.exports = (() => {
delete require.cache[require.resolve('../Driver')];
return require('../Driver');
})();
</code></pre>
</article>
</section>
</div>
<nav>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-drivers_MariaDB.html">drivers/MariaDB</a></li><li><a href="module-drivers_MSSQLDriver.html">drivers/MSSQLDriver</a></li><li><a href="module-drivers_Mysql.html">drivers/Mysql</a></li><li><a href="module-drivers_Pg.html">drivers/Pg</a></li><li><a href="module-drivers_Sqlite.html">drivers/Sqlite</a></li></ul><h3>Classes</h3><ul><li><a href="NodeQuery.html">NodeQuery</a></li><li><a href="QueryBuilder.html">QueryBuilder</a></li><li><a href="Result.html">Result</a></li></ul>
</nav>
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Mon Feb 12 2018 14:58:25 GMT-0500 (EST)
</footer>
<script> prettyPrint(); </script>
<script src="scripts/linenumber.js"> </script>
</body>
</html>

View File

@ -0,0 +1,111 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>JSDoc: Source: drivers/Sqlite.js</title>
<script src="scripts/prettify/prettify.js"> </script>
<script src="scripts/prettify/lang-css.js"> </script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>
<body>
<div id="main">
<h1 class="page-title">Source: drivers/Sqlite.js</h1>
<section>
<article>
<pre class="prettyprint source linenums"><code>/**
* Driver for SQLite databases
*
* @module drivers/Sqlite
*/
module.exports = (() => {
delete require.cache[require.resolve('../Driver')];
const driver = require('../Driver');
// Sqlite doesn't have a truncate command
driver.hasTruncate = false;
/**
* SQL to insert a group of rows
* Override default to have better compatibility
*
* @param {String} table - The table to insert to
* @param {Array} [data] - The array of object containing data to insert
* @return {String} - The generated sql statement
*/
driver.insertBatch = (table, data) => {
// Get the data values to insert, so they can
// be parameterized
let sql = '';
const first = data.shift();
const vals = [];
data.forEach(obj => {
const row = [];
Object.keys(obj).forEach(key => {
row.push(obj[key]);
});
vals.push(row);
});
sql += `INSERT INTO ${driver.quoteTable(table)}\n`;
// Get the field names from the keys of the first
// object to be inserted
const fields = Object.keys(first);
const cols = [];
fields.forEach(key => {
cols.push(`'${driver._quote(first[key])}' AS ${driver.quoteIdentifiers(key)}`);
});
sql += `SELECT ${cols.join(', ')}\n`;
vals.forEach(rowValues => {
const quoted = rowValues.map(value => String(value).replace('\'', '\'\''));
sql += `UNION ALL SELECT '${quoted.join('\', \'')}'\n`;
});
return {
sql: sql,
values: undefined
};
};
return driver;
})();
</code></pre>
</article>
</section>
</div>
<nav>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-drivers_MariaDB.html">drivers/MariaDB</a></li><li><a href="module-drivers_MSSQLDriver.html">drivers/MSSQLDriver</a></li><li><a href="module-drivers_Mysql.html">drivers/Mysql</a></li><li><a href="module-drivers_Pg.html">drivers/Pg</a></li><li><a href="module-drivers_Sqlite.html">drivers/Sqlite</a></li></ul><h3>Classes</h3><ul><li><a href="NodeQuery.html">NodeQuery</a></li><li><a href="QueryBuilder.html">QueryBuilder</a></li><li><a href="Result.html">Result</a></li></ul>
</nav>
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Mon Feb 12 2018 14:58:25 GMT-0500 (EST)
</footer>
<script> prettyPrint(); </script>
<script src="scripts/linenumber.js"> </script>
</body>
</html>

Binary file not shown.

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

65
documentation/index.html Normal file
View File

@ -0,0 +1,65 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>JSDoc: Home</title>
<script src="scripts/prettify/prettify.js"> </script>
<script src="scripts/prettify/lang-css.js"> </script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>
<body>
<div id="main">
<h1 class="page-title">Home</h1>
<h3> </h3>
</div>
<nav>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-drivers_MariaDB.html">drivers/MariaDB</a></li><li><a href="module-drivers_MSSQLDriver.html">drivers/MSSQLDriver</a></li><li><a href="module-drivers_Mysql.html">drivers/Mysql</a></li><li><a href="module-drivers_Pg.html">drivers/Pg</a></li><li><a href="module-drivers_Sqlite.html">drivers/Sqlite</a></li></ul><h3>Classes</h3><ul><li><a href="NodeQuery.html">NodeQuery</a></li><li><a href="QueryBuilder.html">QueryBuilder</a></li><li><a href="Result.html">Result</a></li></ul>
</nav>
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Mon Feb 12 2018 14:58:25 GMT-0500 (EST)
</footer>
<script> prettyPrint(); </script>
<script src="scripts/linenumber.js"> </script>
</body>
</html>

View File

@ -0,0 +1,163 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>JSDoc: Module: drivers/MSSQLDriver</title>
<script src="scripts/prettify/prettify.js"> </script>
<script src="scripts/prettify/lang-css.js"> </script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>
<body>
<div id="main">
<h1 class="page-title">Module: drivers/MSSQLDriver</h1>
<section>
<header>
</header>
<article>
<div class="container-overview">
<div class="description">Driver for Microsoft SQL Server databases</div>
<dl class="details">
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="drivers_MSSQLDriver.js.html">drivers/MSSQLDriver.js</a>, <a href="drivers_MSSQLDriver.js.html#line1">line 1</a>
</li></ul></dd>
</dl>
</div>
</article>
</section>
</div>
<nav>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-drivers_MariaDB.html">drivers/MariaDB</a></li><li><a href="module-drivers_MSSQLDriver.html">drivers/MSSQLDriver</a></li><li><a href="module-drivers_Mysql.html">drivers/Mysql</a></li><li><a href="module-drivers_Pg.html">drivers/Pg</a></li><li><a href="module-drivers_Sqlite.html">drivers/Sqlite</a></li></ul><h3>Classes</h3><ul><li><a href="NodeQuery.html">NodeQuery</a></li><li><a href="QueryBuilder.html">QueryBuilder</a></li><li><a href="Result.html">Result</a></li></ul>
</nav>
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Mon Feb 12 2018 14:58:25 GMT-0500 (EST)
</footer>
<script> prettyPrint(); </script>
<script src="scripts/linenumber.js"> </script>
</body>
</html>

View File

@ -0,0 +1,163 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>JSDoc: Module: drivers/MariaDB</title>
<script src="scripts/prettify/prettify.js"> </script>
<script src="scripts/prettify/lang-css.js"> </script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>
<body>
<div id="main">
<h1 class="page-title">Module: drivers/MariaDB</h1>
<section>
<header>
</header>
<article>
<div class="container-overview">
<div class="description">Driver for MariaDB databases</div>
<dl class="details">
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="drivers_MariaDB.js.html">drivers/MariaDB.js</a>, <a href="drivers_MariaDB.js.html#line1">line 1</a>
</li></ul></dd>
</dl>
</div>
</article>
</section>
</div>
<nav>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-drivers_MariaDB.html">drivers/MariaDB</a></li><li><a href="module-drivers_MSSQLDriver.html">drivers/MSSQLDriver</a></li><li><a href="module-drivers_Mysql.html">drivers/Mysql</a></li><li><a href="module-drivers_Pg.html">drivers/Pg</a></li><li><a href="module-drivers_Sqlite.html">drivers/Sqlite</a></li></ul><h3>Classes</h3><ul><li><a href="NodeQuery.html">NodeQuery</a></li><li><a href="QueryBuilder.html">QueryBuilder</a></li><li><a href="Result.html">Result</a></li></ul>
</nav>
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Mon Feb 12 2018 14:58:25 GMT-0500 (EST)
</footer>
<script> prettyPrint(); </script>
<script src="scripts/linenumber.js"> </script>
</body>
</html>

View File

@ -0,0 +1,163 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>JSDoc: Module: drivers/Mysql</title>
<script src="scripts/prettify/prettify.js"> </script>
<script src="scripts/prettify/lang-css.js"> </script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>
<body>
<div id="main">
<h1 class="page-title">Module: drivers/Mysql</h1>
<section>
<header>
</header>
<article>
<div class="container-overview">
<div class="description">Driver for MySQL databases</div>
<dl class="details">
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="drivers_Mysql.js.html">drivers/Mysql.js</a>, <a href="drivers_Mysql.js.html#line1">line 1</a>
</li></ul></dd>
</dl>
</div>
</article>
</section>
</div>
<nav>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-drivers_MariaDB.html">drivers/MariaDB</a></li><li><a href="module-drivers_MSSQLDriver.html">drivers/MSSQLDriver</a></li><li><a href="module-drivers_Mysql.html">drivers/Mysql</a></li><li><a href="module-drivers_Pg.html">drivers/Pg</a></li><li><a href="module-drivers_Sqlite.html">drivers/Sqlite</a></li></ul><h3>Classes</h3><ul><li><a href="NodeQuery.html">NodeQuery</a></li><li><a href="QueryBuilder.html">QueryBuilder</a></li><li><a href="Result.html">Result</a></li></ul>
</nav>
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Mon Feb 12 2018 14:58:25 GMT-0500 (EST)
</footer>
<script> prettyPrint(); </script>
<script src="scripts/linenumber.js"> </script>
</body>
</html>

View File

@ -0,0 +1,163 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>JSDoc: Module: drivers/Pg</title>
<script src="scripts/prettify/prettify.js"> </script>
<script src="scripts/prettify/lang-css.js"> </script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>
<body>
<div id="main">
<h1 class="page-title">Module: drivers/Pg</h1>
<section>
<header>
</header>
<article>
<div class="container-overview">
<div class="description">Driver for PostgreSQL databases</div>
<dl class="details">
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="drivers_Pg.js.html">drivers/Pg.js</a>, <a href="drivers_Pg.js.html#line1">line 1</a>
</li></ul></dd>
</dl>
</div>
</article>
</section>
</div>
<nav>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-drivers_MariaDB.html">drivers/MariaDB</a></li><li><a href="module-drivers_MSSQLDriver.html">drivers/MSSQLDriver</a></li><li><a href="module-drivers_Mysql.html">drivers/Mysql</a></li><li><a href="module-drivers_Pg.html">drivers/Pg</a></li><li><a href="module-drivers_Sqlite.html">drivers/Sqlite</a></li></ul><h3>Classes</h3><ul><li><a href="NodeQuery.html">NodeQuery</a></li><li><a href="QueryBuilder.html">QueryBuilder</a></li><li><a href="Result.html">Result</a></li></ul>
</nav>
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Mon Feb 12 2018 14:58:25 GMT-0500 (EST)
</footer>
<script> prettyPrint(); </script>
<script src="scripts/linenumber.js"> </script>
</body>
</html>

View File

@ -0,0 +1,163 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>JSDoc: Module: drivers/Sqlite</title>
<script src="scripts/prettify/prettify.js"> </script>
<script src="scripts/prettify/lang-css.js"> </script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>
<body>
<div id="main">
<h1 class="page-title">Module: drivers/Sqlite</h1>
<section>
<header>
</header>
<article>
<div class="container-overview">
<div class="description">Driver for SQLite databases</div>
<dl class="details">
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="drivers_Sqlite.js.html">drivers/Sqlite.js</a>, <a href="drivers_Sqlite.js.html#line1">line 1</a>
</li></ul></dd>
</dl>
</div>
</article>
</section>
</div>
<nav>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-drivers_MariaDB.html">drivers/MariaDB</a></li><li><a href="module-drivers_MSSQLDriver.html">drivers/MSSQLDriver</a></li><li><a href="module-drivers_Mysql.html">drivers/Mysql</a></li><li><a href="module-drivers_Pg.html">drivers/Pg</a></li><li><a href="module-drivers_Sqlite.html">drivers/Sqlite</a></li></ul><h3>Classes</h3><ul><li><a href="NodeQuery.html">NodeQuery</a></li><li><a href="QueryBuilder.html">QueryBuilder</a></li><li><a href="Result.html">Result</a></li></ul>
</nav>
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Mon Feb 12 2018 14:58:25 GMT-0500 (EST)
</footer>
<script> prettyPrint(); </script>
<script src="scripts/linenumber.js"> </script>
</body>
</html>

View File

@ -0,0 +1,25 @@
/*global document */
(function() {
var source = document.getElementsByClassName('prettyprint source linenums');
var i = 0;
var lineNumber = 0;
var lineId;
var lines;
var totalLines;
var anchorHash;
if (source && source[0]) {
anchorHash = document.location.hash.substring(1);
lines = source[0].getElementsByTagName('li');
totalLines = lines.length;
for (; i < totalLines; i++) {
lineNumber++;
lineId = 'line' + lineNumber;
lines[i].id = lineId;
if (lineId === anchorHash) {
lines[i].className += ' selected';
}
}
}
})();

View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -0,0 +1,2 @@
PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\f\r ]+/,null," \t\r\n "]],[["str",/^"(?:[^\n\f\r"\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*"/,null],["str",/^'(?:[^\n\f\r'\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*'/,null],["lang-css-str",/^url\(([^"')]*)\)/i],["kwd",/^(?:url|rgb|!important|@import|@page|@media|@charset|inherit)(?=[^\w-]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*)\s*:/i],["com",/^\/\*[^*]*\*+(?:[^*/][^*]*\*+)*\//],["com",
/^(?:<\!--|--\>)/],["lit",/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],["lit",/^#[\da-f]{3,6}/i],["pln",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i],["pun",/^[^\s\w"']+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[["kwd",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[["str",/^[^"')]+/]]),["css-str"]);

View File

@ -0,0 +1,28 @@
var q=null;window.PR_SHOULD_USE_CONTINUATION=!0;
(function(){function L(a){function m(a){var f=a.charCodeAt(0);if(f!==92)return f;var b=a.charAt(1);return(f=r[b])?f:"0"<=b&&b<="7"?parseInt(a.substring(1),8):b==="u"||b==="x"?parseInt(a.substring(2),16):a.charCodeAt(1)}function e(a){if(a<32)return(a<16?"\\x0":"\\x")+a.toString(16);a=String.fromCharCode(a);if(a==="\\"||a==="-"||a==="["||a==="]")a="\\"+a;return a}function h(a){for(var f=a.substring(1,a.length-1).match(/\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\[0-3][0-7]{0,2}|\\[0-7]{1,2}|\\[\S\s]|[^\\]/g),a=
[],b=[],o=f[0]==="^",c=o?1:0,i=f.length;c<i;++c){var j=f[c];if(/\\[bdsw]/i.test(j))a.push(j);else{var j=m(j),d;c+2<i&&"-"===f[c+1]?(d=m(f[c+2]),c+=2):d=j;b.push([j,d]);d<65||j>122||(d<65||j>90||b.push([Math.max(65,j)|32,Math.min(d,90)|32]),d<97||j>122||b.push([Math.max(97,j)&-33,Math.min(d,122)&-33]))}}b.sort(function(a,f){return a[0]-f[0]||f[1]-a[1]});f=[];j=[NaN,NaN];for(c=0;c<b.length;++c)i=b[c],i[0]<=j[1]+1?j[1]=Math.max(j[1],i[1]):f.push(j=i);b=["["];o&&b.push("^");b.push.apply(b,a);for(c=0;c<
f.length;++c)i=f[c],b.push(e(i[0])),i[1]>i[0]&&(i[1]+1>i[0]&&b.push("-"),b.push(e(i[1])));b.push("]");return b.join("")}function y(a){for(var f=a.source.match(/\[(?:[^\\\]]|\\[\S\s])*]|\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\\d+|\\[^\dux]|\(\?[!:=]|[()^]|[^()[\\^]+/g),b=f.length,d=[],c=0,i=0;c<b;++c){var j=f[c];j==="("?++i:"\\"===j.charAt(0)&&(j=+j.substring(1))&&j<=i&&(d[j]=-1)}for(c=1;c<d.length;++c)-1===d[c]&&(d[c]=++t);for(i=c=0;c<b;++c)j=f[c],j==="("?(++i,d[i]===void 0&&(f[c]="(?:")):"\\"===j.charAt(0)&&
(j=+j.substring(1))&&j<=i&&(f[c]="\\"+d[i]);for(i=c=0;c<b;++c)"^"===f[c]&&"^"!==f[c+1]&&(f[c]="");if(a.ignoreCase&&s)for(c=0;c<b;++c)j=f[c],a=j.charAt(0),j.length>=2&&a==="["?f[c]=h(j):a!=="\\"&&(f[c]=j.replace(/[A-Za-z]/g,function(a){a=a.charCodeAt(0);return"["+String.fromCharCode(a&-33,a|32)+"]"}));return f.join("")}for(var t=0,s=!1,l=!1,p=0,d=a.length;p<d;++p){var g=a[p];if(g.ignoreCase)l=!0;else if(/[a-z]/i.test(g.source.replace(/\\u[\da-f]{4}|\\x[\da-f]{2}|\\[^UXux]/gi,""))){s=!0;l=!1;break}}for(var r=
{b:8,t:9,n:10,v:11,f:12,r:13},n=[],p=0,d=a.length;p<d;++p){g=a[p];if(g.global||g.multiline)throw Error(""+g);n.push("(?:"+y(g)+")")}return RegExp(n.join("|"),l?"gi":"g")}function M(a){function m(a){switch(a.nodeType){case 1:if(e.test(a.className))break;for(var g=a.firstChild;g;g=g.nextSibling)m(g);g=a.nodeName;if("BR"===g||"LI"===g)h[s]="\n",t[s<<1]=y++,t[s++<<1|1]=a;break;case 3:case 4:g=a.nodeValue,g.length&&(g=p?g.replace(/\r\n?/g,"\n"):g.replace(/[\t\n\r ]+/g," "),h[s]=g,t[s<<1]=y,y+=g.length,
t[s++<<1|1]=a)}}var e=/(?:^|\s)nocode(?:\s|$)/,h=[],y=0,t=[],s=0,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=document.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);m(a);return{a:h.join("").replace(/\n$/,""),c:t}}function B(a,m,e,h){m&&(a={a:m,d:a},e(a),h.push.apply(h,a.e))}function x(a,m){function e(a){for(var l=a.d,p=[l,"pln"],d=0,g=a.a.match(y)||[],r={},n=0,z=g.length;n<z;++n){var f=g[n],b=r[f],o=void 0,c;if(typeof b===
"string")c=!1;else{var i=h[f.charAt(0)];if(i)o=f.match(i[1]),b=i[0];else{for(c=0;c<t;++c)if(i=m[c],o=f.match(i[1])){b=i[0];break}o||(b="pln")}if((c=b.length>=5&&"lang-"===b.substring(0,5))&&!(o&&typeof o[1]==="string"))c=!1,b="src";c||(r[f]=b)}i=d;d+=f.length;if(c){c=o[1];var j=f.indexOf(c),k=j+c.length;o[2]&&(k=f.length-o[2].length,j=k-c.length);b=b.substring(5);B(l+i,f.substring(0,j),e,p);B(l+i+j,c,C(b,c),p);B(l+i+k,f.substring(k),e,p)}else p.push(l+i,b)}a.e=p}var h={},y;(function(){for(var e=a.concat(m),
l=[],p={},d=0,g=e.length;d<g;++d){var r=e[d],n=r[3];if(n)for(var k=n.length;--k>=0;)h[n.charAt(k)]=r;r=r[1];n=""+r;p.hasOwnProperty(n)||(l.push(r),p[n]=q)}l.push(/[\S\s]/);y=L(l)})();var t=m.length;return e}function u(a){var m=[],e=[];a.tripleQuotedStrings?m.push(["str",/^(?:'''(?:[^'\\]|\\[\S\s]|''?(?=[^']))*(?:'''|$)|"""(?:[^"\\]|\\[\S\s]|""?(?=[^"]))*(?:"""|$)|'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$))/,q,"'\""]):a.multiLineStrings?m.push(["str",/^(?:'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$)|`(?:[^\\`]|\\[\S\s])*(?:`|$))/,
q,"'\"`"]):m.push(["str",/^(?:'(?:[^\n\r'\\]|\\.)*(?:'|$)|"(?:[^\n\r"\\]|\\.)*(?:"|$))/,q,"\"'"]);a.verbatimStrings&&e.push(["str",/^@"(?:[^"]|"")*(?:"|$)/,q]);var h=a.hashComments;h&&(a.cStyleComments?(h>1?m.push(["com",/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,q,"#"]):m.push(["com",/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\n\r]*)/,q,"#"]),e.push(["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,q])):m.push(["com",/^#[^\n\r]*/,
q,"#"]));a.cStyleComments&&(e.push(["com",/^\/\/[^\n\r]*/,q]),e.push(["com",/^\/\*[\S\s]*?(?:\*\/|$)/,q]));a.regexLiterals&&e.push(["lang-regex",/^(?:^^\.?|[!+-]|!=|!==|#|%|%=|&|&&|&&=|&=|\(|\*|\*=|\+=|,|-=|->|\/|\/=|:|::|;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|[?@[^]|\^=|\^\^|\^\^=|{|\||\|=|\|\||\|\|=|~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\s*(\/(?=[^*/])(?:[^/[\\]|\\[\S\s]|\[(?:[^\\\]]|\\[\S\s])*(?:]|$))+\/)/]);(h=a.types)&&e.push(["typ",h]);a=(""+a.keywords).replace(/^ | $/g,
"");a.length&&e.push(["kwd",RegExp("^(?:"+a.replace(/[\s,]+/g,"|")+")\\b"),q]);m.push(["pln",/^\s+/,q," \r\n\t\xa0"]);e.push(["lit",/^@[$_a-z][\w$@]*/i,q],["typ",/^(?:[@_]?[A-Z]+[a-z][\w$@]*|\w+_t\b)/,q],["pln",/^[$_a-z][\w$@]*/i,q],["lit",/^(?:0x[\da-f]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+-]?\d+)?)[a-z]*/i,q,"0123456789"],["pln",/^\\[\S\s]?/,q],["pun",/^.[^\s\w"-$'./@\\`]*/,q]);return x(m,e)}function D(a,m){function e(a){switch(a.nodeType){case 1:if(k.test(a.className))break;if("BR"===a.nodeName)h(a),
a.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)e(a);break;case 3:case 4:if(p){var b=a.nodeValue,d=b.match(t);if(d){var c=b.substring(0,d.index);a.nodeValue=c;(b=b.substring(d.index+d[0].length))&&a.parentNode.insertBefore(s.createTextNode(b),a.nextSibling);h(a);c||a.parentNode.removeChild(a)}}}}function h(a){function b(a,d){var e=d?a.cloneNode(!1):a,f=a.parentNode;if(f){var f=b(f,1),g=a.nextSibling;f.appendChild(e);for(var h=g;h;h=g)g=h.nextSibling,f.appendChild(h)}return e}
for(;!a.nextSibling;)if(a=a.parentNode,!a)return;for(var a=b(a.nextSibling,0),e;(e=a.parentNode)&&e.nodeType===1;)a=e;d.push(a)}var k=/(?:^|\s)nocode(?:\s|$)/,t=/\r\n?|\n/,s=a.ownerDocument,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=s.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);for(l=s.createElement("LI");a.firstChild;)l.appendChild(a.firstChild);for(var d=[l],g=0;g<d.length;++g)e(d[g]);m===(m|0)&&d[0].setAttribute("value",
m);var r=s.createElement("OL");r.className="linenums";for(var n=Math.max(0,m-1|0)||0,g=0,z=d.length;g<z;++g)l=d[g],l.className="L"+(g+n)%10,l.firstChild||l.appendChild(s.createTextNode("\xa0")),r.appendChild(l);a.appendChild(r)}function k(a,m){for(var e=m.length;--e>=0;){var h=m[e];A.hasOwnProperty(h)?window.console&&console.warn("cannot override language handler %s",h):A[h]=a}}function C(a,m){if(!a||!A.hasOwnProperty(a))a=/^\s*</.test(m)?"default-markup":"default-code";return A[a]}function E(a){var m=
a.g;try{var e=M(a.h),h=e.a;a.a=h;a.c=e.c;a.d=0;C(m,h)(a);var k=/\bMSIE\b/.test(navigator.userAgent),m=/\n/g,t=a.a,s=t.length,e=0,l=a.c,p=l.length,h=0,d=a.e,g=d.length,a=0;d[g]=s;var r,n;for(n=r=0;n<g;)d[n]!==d[n+2]?(d[r++]=d[n++],d[r++]=d[n++]):n+=2;g=r;for(n=r=0;n<g;){for(var z=d[n],f=d[n+1],b=n+2;b+2<=g&&d[b+1]===f;)b+=2;d[r++]=z;d[r++]=f;n=b}for(d.length=r;h<p;){var o=l[h+2]||s,c=d[a+2]||s,b=Math.min(o,c),i=l[h+1],j;if(i.nodeType!==1&&(j=t.substring(e,b))){k&&(j=j.replace(m,"\r"));i.nodeValue=
j;var u=i.ownerDocument,v=u.createElement("SPAN");v.className=d[a+1];var x=i.parentNode;x.replaceChild(v,i);v.appendChild(i);e<o&&(l[h+1]=i=u.createTextNode(t.substring(b,o)),x.insertBefore(i,v.nextSibling))}e=b;e>=o&&(h+=2);e>=c&&(a+=2)}}catch(w){"console"in window&&console.log(w&&w.stack?w.stack:w)}}var v=["break,continue,do,else,for,if,return,while"],w=[[v,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"],
"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],F=[w,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"],G=[w,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"],
H=[G,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"],w=[w,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"],I=[v,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"],
J=[v,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"],v=[v,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],K=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/,N=/\S/,O=u({keywords:[F,H,w,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END"+
I,J,v],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),A={};k(O,["default-code"]);k(x([],[["pln",/^[^<?]+/],["dec",/^<!\w[^>]*(?:>|$)/],["com",/^<\!--[\S\s]*?(?:--\>|$)/],["lang-",/^<\?([\S\s]+?)(?:\?>|$)/],["lang-",/^<%([\S\s]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-",/^<xmp\b[^>]*>([\S\s]+?)<\/xmp\b[^>]*>/i],["lang-js",/^<script\b[^>]*>([\S\s]*?)(<\/script\b[^>]*>)/i],["lang-css",/^<style\b[^>]*>([\S\s]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),
["default-markup","htm","html","mxml","xhtml","xml","xsl"]);k(x([["pln",/^\s+/,q," \t\r\n"],["atv",/^(?:"[^"]*"?|'[^']*'?)/,q,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w-.:]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^\s"'>]*(?:[^\s"'/>]|\/(?=\s)))/],["pun",/^[/<->]+/],["lang-js",/^on\w+\s*=\s*"([^"]+)"/i],["lang-js",/^on\w+\s*=\s*'([^']+)'/i],["lang-js",/^on\w+\s*=\s*([^\s"'>]+)/i],["lang-css",/^style\s*=\s*"([^"]+)"/i],["lang-css",/^style\s*=\s*'([^']+)'/i],["lang-css",
/^style\s*=\s*([^\s"'>]+)/i]]),["in.tag"]);k(x([],[["atv",/^[\S\s]+/]]),["uq.val"]);k(u({keywords:F,hashComments:!0,cStyleComments:!0,types:K}),["c","cc","cpp","cxx","cyc","m"]);k(u({keywords:"null,true,false"}),["json"]);k(u({keywords:H,hashComments:!0,cStyleComments:!0,verbatimStrings:!0,types:K}),["cs"]);k(u({keywords:G,cStyleComments:!0}),["java"]);k(u({keywords:v,hashComments:!0,multiLineStrings:!0}),["bsh","csh","sh"]);k(u({keywords:I,hashComments:!0,multiLineStrings:!0,tripleQuotedStrings:!0}),
["cv","py"]);k(u({keywords:"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["perl","pl","pm"]);k(u({keywords:J,hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["rb"]);k(u({keywords:w,cStyleComments:!0,regexLiterals:!0}),["js"]);k(u({keywords:"all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes",
hashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0,regexLiterals:!0}),["coffee"]);k(x([],[["str",/^[\S\s]+/]]),["regex"]);window.prettyPrintOne=function(a,m,e){var h=document.createElement("PRE");h.innerHTML=a;e&&D(h,e);E({g:m,i:e,h:h});return h.innerHTML};window.prettyPrint=function(a){function m(){for(var e=window.PR_SHOULD_USE_CONTINUATION?l.now()+250:Infinity;p<h.length&&l.now()<e;p++){var n=h[p],k=n.className;if(k.indexOf("prettyprint")>=0){var k=k.match(g),f,b;if(b=
!k){b=n;for(var o=void 0,c=b.firstChild;c;c=c.nextSibling)var i=c.nodeType,o=i===1?o?b:c:i===3?N.test(c.nodeValue)?b:o:o;b=(f=o===b?void 0:o)&&"CODE"===f.tagName}b&&(k=f.className.match(g));k&&(k=k[1]);b=!1;for(o=n.parentNode;o;o=o.parentNode)if((o.tagName==="pre"||o.tagName==="code"||o.tagName==="xmp")&&o.className&&o.className.indexOf("prettyprint")>=0){b=!0;break}b||((b=(b=n.className.match(/\blinenums\b(?::(\d+))?/))?b[1]&&b[1].length?+b[1]:!0:!1)&&D(n,b),d={g:k,h:n,i:b},E(d))}}p<h.length?setTimeout(m,
250):a&&a()}for(var e=[document.getElementsByTagName("pre"),document.getElementsByTagName("code"),document.getElementsByTagName("xmp")],h=[],k=0;k<e.length;++k)for(var t=0,s=e[k].length;t<s;++t)h.push(e[k][t]);var e=q,l=Date;l.now||(l={now:function(){return+new Date}});var p=0,d,g=/\blang(?:uage)?-([\w.]+)(?!\S)/;m()};window.PR={createSimpleLexer:x,registerLangHandler:k,sourceDecorator:u,PR_ATTRIB_NAME:"atn",PR_ATTRIB_VALUE:"atv",PR_COMMENT:"com",PR_DECLARATION:"dec",PR_KEYWORD:"kwd",PR_LITERAL:"lit",
PR_NOCODE:"nocode",PR_PLAIN:"pln",PR_PUNCTUATION:"pun",PR_SOURCE:"src",PR_STRING:"str",PR_TAG:"tag",PR_TYPE:"typ"}})();

View File

@ -0,0 +1,358 @@
@font-face {
font-family: 'Open Sans';
font-weight: normal;
font-style: normal;
src: url('../fonts/OpenSans-Regular-webfont.eot');
src:
local('Open Sans'),
local('OpenSans'),
url('../fonts/OpenSans-Regular-webfont.eot?#iefix') format('embedded-opentype'),
url('../fonts/OpenSans-Regular-webfont.woff') format('woff'),
url('../fonts/OpenSans-Regular-webfont.svg#open_sansregular') format('svg');
}
@font-face {
font-family: 'Open Sans Light';
font-weight: normal;
font-style: normal;
src: url('../fonts/OpenSans-Light-webfont.eot');
src:
local('Open Sans Light'),
local('OpenSans Light'),
url('../fonts/OpenSans-Light-webfont.eot?#iefix') format('embedded-opentype'),
url('../fonts/OpenSans-Light-webfont.woff') format('woff'),
url('../fonts/OpenSans-Light-webfont.svg#open_sanslight') format('svg');
}
html
{
overflow: auto;
background-color: #fff;
font-size: 14px;
}
body
{
font-family: 'Open Sans', sans-serif;
line-height: 1.5;
color: #4d4e53;
background-color: white;
}
a, a:visited, a:active {
color: #0095dd;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
header
{
display: block;
padding: 0px 4px;
}
tt, code, kbd, samp {
font-family: Consolas, Monaco, 'Andale Mono', monospace;
}
.class-description {
font-size: 130%;
line-height: 140%;
margin-bottom: 1em;
margin-top: 1em;
}
.class-description:empty {
margin: 0;
}
#main {
float: left;
width: 70%;
}
article dl {
margin-bottom: 40px;
}
article img {
max-width: 100%;
}
section
{
display: block;
background-color: #fff;
padding: 12px 24px;
border-bottom: 1px solid #ccc;
margin-right: 30px;
}
.variation {
display: none;
}
.signature-attributes {
font-size: 60%;
color: #aaa;
font-style: italic;
font-weight: lighter;
}
nav
{
display: block;
float: right;
margin-top: 28px;
width: 30%;
box-sizing: border-box;
border-left: 1px solid #ccc;
padding-left: 16px;
}
nav ul {
font-family: 'Lucida Grande', 'Lucida Sans Unicode', arial, sans-serif;
font-size: 100%;
line-height: 17px;
padding: 0;
margin: 0;
list-style-type: none;
}
nav ul a, nav ul a:visited, nav ul a:active {
font-family: Consolas, Monaco, 'Andale Mono', monospace;
line-height: 18px;
color: #4D4E53;
}
nav h3 {
margin-top: 12px;
}
nav li {
margin-top: 6px;
}
footer {
display: block;
padding: 6px;
margin-top: 12px;
font-style: italic;
font-size: 90%;
}
h1, h2, h3, h4 {
font-weight: 200;
margin: 0;
}
h1
{
font-family: 'Open Sans Light', sans-serif;
font-size: 48px;
letter-spacing: -2px;
margin: 12px 24px 20px;
}
h2, h3.subsection-title
{
font-size: 30px;
font-weight: 700;
letter-spacing: -1px;
margin-bottom: 12px;
}
h3
{
font-size: 24px;
letter-spacing: -0.5px;
margin-bottom: 12px;
}
h4
{
font-size: 18px;
letter-spacing: -0.33px;
margin-bottom: 12px;
color: #4d4e53;
}
h5, .container-overview .subsection-title
{
font-size: 120%;
font-weight: bold;
letter-spacing: -0.01em;
margin: 8px 0 3px 0;
}
h6
{
font-size: 100%;
letter-spacing: -0.01em;
margin: 6px 0 3px 0;
font-style: italic;
}
table
{
border-spacing: 0;
border: 0;
border-collapse: collapse;
}
td, th
{
border: 1px solid #ddd;
margin: 0px;
text-align: left;
vertical-align: top;
padding: 4px 6px;
display: table-cell;
}
thead tr
{
background-color: #ddd;
font-weight: bold;
}
th { border-right: 1px solid #aaa; }
tr > th:last-child { border-right: 1px solid #ddd; }
.ancestors, .attribs { color: #999; }
.ancestors a, .attribs a
{
color: #999 !important;
text-decoration: none;
}
.clear
{
clear: both;
}
.important
{
font-weight: bold;
color: #950B02;
}
.yes-def {
text-indent: -1000px;
}
.type-signature {
color: #aaa;
}
.name, .signature {
font-family: Consolas, Monaco, 'Andale Mono', monospace;
}
.details { margin-top: 14px; border-left: 2px solid #DDD; }
.details dt { width: 120px; float: left; padding-left: 10px; padding-top: 6px; }
.details dd { margin-left: 70px; }
.details ul { margin: 0; }
.details ul { list-style-type: none; }
.details li { margin-left: 30px; padding-top: 6px; }
.details pre.prettyprint { margin: 0 }
.details .object-value { padding-top: 0; }
.description {
margin-bottom: 1em;
margin-top: 1em;
}
.code-caption
{
font-style: italic;
font-size: 107%;
margin: 0;
}
.prettyprint
{
border: 1px solid #ddd;
width: 80%;
overflow: auto;
}
.prettyprint.source {
width: inherit;
}
.prettyprint code
{
font-size: 100%;
line-height: 18px;
display: block;
padding: 4px 12px;
margin: 0;
background-color: #fff;
color: #4D4E53;
}
.prettyprint code span.line
{
display: inline-block;
}
.prettyprint.linenums
{
padding-left: 70px;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.prettyprint.linenums ol
{
padding-left: 0;
}
.prettyprint.linenums li
{
border-left: 3px #ddd solid;
}
.prettyprint.linenums li.selected,
.prettyprint.linenums li.selected *
{
background-color: lightyellow;
}
.prettyprint.linenums li *
{
-webkit-user-select: text;
-moz-user-select: text;
-ms-user-select: text;
user-select: text;
}
.params .name, .props .name, .name code {
color: #4D4E53;
font-family: Consolas, Monaco, 'Andale Mono', monospace;
font-size: 100%;
}
.params td.description > p:first-child,
.props td.description > p:first-child
{
margin-top: 0;
padding-top: 0;
}
.params td.description > p:last-child,
.props td.description > p:last-child
{
margin-bottom: 0;
padding-bottom: 0;
}
.disabled {
color: #454545;
}

View File

@ -0,0 +1,111 @@
/* JSDoc prettify.js theme */
/* plain text */
.pln {
color: #000000;
font-weight: normal;
font-style: normal;
}
/* string content */
.str {
color: #006400;
font-weight: normal;
font-style: normal;
}
/* a keyword */
.kwd {
color: #000000;
font-weight: bold;
font-style: normal;
}
/* a comment */
.com {
font-weight: normal;
font-style: italic;
}
/* a type name */
.typ {
color: #000000;
font-weight: normal;
font-style: normal;
}
/* a literal value */
.lit {
color: #006400;
font-weight: normal;
font-style: normal;
}
/* punctuation */
.pun {
color: #000000;
font-weight: bold;
font-style: normal;
}
/* lisp open bracket */
.opn {
color: #000000;
font-weight: bold;
font-style: normal;
}
/* lisp close bracket */
.clo {
color: #000000;
font-weight: bold;
font-style: normal;
}
/* a markup tag name */
.tag {
color: #006400;
font-weight: normal;
font-style: normal;
}
/* a markup attribute name */
.atn {
color: #006400;
font-weight: normal;
font-style: normal;
}
/* a markup attribute value */
.atv {
color: #006400;
font-weight: normal;
font-style: normal;
}
/* a declaration */
.dec {
color: #000000;
font-weight: bold;
font-style: normal;
}
/* a variable name */
.var {
color: #000000;
font-weight: normal;
font-style: normal;
}
/* a function name */
.fun {
color: #000000;
font-weight: bold;
font-style: normal;
}
/* Specify class=linenums on a pre to get line numbering */
ol.linenums {
margin-top: 0;
margin-bottom: 0;
}

View File

@ -0,0 +1,132 @@
/* Tomorrow Theme */
/* Original theme - https://github.com/chriskempson/tomorrow-theme */
/* Pretty printing styles. Used with prettify.js. */
/* SPAN elements with the classes below are added by prettyprint. */
/* plain text */
.pln {
color: #4d4d4c; }
@media screen {
/* string content */
.str {
color: #718c00; }
/* a keyword */
.kwd {
color: #8959a8; }
/* a comment */
.com {
color: #8e908c; }
/* a type name */
.typ {
color: #4271ae; }
/* a literal value */
.lit {
color: #f5871f; }
/* punctuation */
.pun {
color: #4d4d4c; }
/* lisp open bracket */
.opn {
color: #4d4d4c; }
/* lisp close bracket */
.clo {
color: #4d4d4c; }
/* a markup tag name */
.tag {
color: #c82829; }
/* a markup attribute name */
.atn {
color: #f5871f; }
/* a markup attribute value */
.atv {
color: #3e999f; }
/* a declaration */
.dec {
color: #f5871f; }
/* a variable name */
.var {
color: #c82829; }
/* a function name */
.fun {
color: #4271ae; } }
/* Use higher contrast and text-weight for printable form. */
@media print, projection {
.str {
color: #060; }
.kwd {
color: #006;
font-weight: bold; }
.com {
color: #600;
font-style: italic; }
.typ {
color: #404;
font-weight: bold; }
.lit {
color: #044; }
.pun, .opn, .clo {
color: #440; }
.tag {
color: #006;
font-weight: bold; }
.atn {
color: #404; }
.atv {
color: #060; } }
/* Style */
/*
pre.prettyprint {
background: white;
font-family: Consolas, Monaco, 'Andale Mono', monospace;
font-size: 12px;
line-height: 1.5;
border: 1px solid #ccc;
padding: 10px; }
*/
/* Specify class=linenums on a pre to get line numbering */
ol.linenums {
margin-top: 0;
margin-bottom: 0; }
/* IE indents via margin-left */
li.L0,
li.L1,
li.L2,
li.L3,
li.L4,
li.L5,
li.L6,
li.L7,
li.L8,
li.L9 {
/* */ }
/* Alternate shading for lines */
li.L1,
li.L3,
li.L5,
li.L7,
li.L9 {
/* */ }

View File

@ -1,5 +1,3 @@
'use strict';
/**
* Class that wraps database connection libraries
*
@ -22,7 +20,7 @@ class Adapter {
*
* @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 passed
* @return {Promise} - returns a promise resolving to the result of the database query
*/
execute (sql, params) {
throw new Error('Correct adapter not defined for query execution');

View File

@ -1,6 +1,4 @@
'use strict';
const helpers = require('./helpers');
const Helpers = require('./Helpers');
/**
* Base Database Driver
@ -21,7 +19,7 @@ const Driver = {
* @private
*/
_quote (str) {
return (helpers.isString(str) &&
return (Helpers.isString(str) &&
!(str.startsWith(Driver.identifierStartChar) || str.endsWith(Driver.identifierEndChar))
)
? `${Driver.identifierStartChar}${str}${Driver.identifierEndChar}`
@ -39,7 +37,7 @@ const Driver = {
limit (sql, limit, offset) {
sql += ` LIMIT ${limit}`;
if (helpers.isNumber(offset)) {
if (Helpers.isNumber(offset)) {
sql += ` OFFSET ${offset}`;
}
@ -66,36 +64,38 @@ const Driver = {
* @return {String|Array} - Quoted identifier(s)
*/
quoteIdentifiers (str) {
let hiers, raw;
let pattern = new RegExp(
const pattern = new RegExp(
`${Driver.identifierStartChar}(` +
'([a-zA-Z0-9_]+)' + '(((.*?)))' +
`)${Driver.identifierEndChar}`, 'ig');
// Recurse for arrays of identifiiers
// Recurse for arrays of identifiers
if (Array.isArray(str)) {
return str.map(Driver.quoteIdentifiers);
}
// cast to string so that you don't have undefined method errors with junk data
str = String(str);
// Handle commas
if (str.includes(',')) {
let parts = str.split(',').map(helpers.stringTrim);
const parts = str.split(',').map(Helpers.stringTrim);
str = parts.map(Driver.quoteIdentifiers).join(',');
}
// Split identifiers by period
hiers = str.split('.').map(Driver._quote);
raw = hiers.join('.');
const hierarchies = str.split('.').map(Driver._quote);
let raw = hierarchies.join('.');
// Fix functions
if (raw.includes('(') && raw.includes(')')) {
let funcs = pattern.exec(raw);
const functionCalls = pattern.exec(raw);
// Unquote the function
raw = raw.replace(funcs[0], funcs[1]);
raw = raw.replace(functionCalls[0], functionCalls[1]);
// Quote the identifiers inside of the parens
let inParens = funcs[3].substring(1, funcs[3].length - 1);
const inParens = functionCalls[3].substring(1, functionCalls[3].length - 1);
raw = raw.replace(inParens, Driver.quoteIdentifiers(inParens));
}
@ -128,7 +128,7 @@ const Driver = {
* @return {String} - Query and data to insert
*/
insertBatch (table, data) {
const vals = [];
const values = [];
const fields = Object.keys(data[0]);
let sql = '';
@ -136,7 +136,7 @@ const Driver = {
// be parameterized
data.forEach(obj => {
Object.keys(obj).forEach(key => {
vals.push(obj[key]);
values.push(obj[key]);
});
});
@ -147,16 +147,79 @@ const Driver = {
sql += `INSERT INTO ${table} (${Driver.quoteIdentifiers(fields).join(',')}) VALUES `;
// Create placeholder groups
let params = Array(fields.length).fill('?');
let paramString = `(${params.join(',')})`;
let paramList = Array(data.length).fill(paramString);
const params = Array(fields.length).fill('?');
const paramString = `(${params.join(',')})`;
const paramList = Array(data.length).fill(paramString);
sql += paramList.join(',');
return {
sql: sql,
values: vals
values: values
};
},
/**
* Creates a batch update sql statement
*
* @private
* @param {String} table - The name of the table to update
* @param {Array<Object>} data - Array of objects containing the update data
* @param {String} updateKey - the field name to update based on
* @return {Array<String,Object,Number>} - array of parameters passed to run the query
*/
updateBatch (table, data, updateKey) {
let affectedRows = 0;
let insertData = [];
const fieldLines = [];
let sql = `UPDATE ${Driver.quoteTable(table)} SET `;
// get the keys of the current set of data, except the one used to
// set the update condition
const fields = data.reduce((previous, current) => {
affectedRows++;
const keys = Object.keys(current).filter(key => {
return key !== updateKey && !previous.includes(key);
});
return previous.concat(keys);
}, []);
// Create the CASE blocks for each data set
fields.forEach(field => {
let line = `${Driver.quoteIdentifiers(field)} = CASE\n`;
const cases = [];
data.forEach(currentCase => {
insertData.push(currentCase[updateKey]);
insertData.push(currentCase[field]);
const newCase = `WHEN ${Driver.quoteIdentifiers(updateKey)} =? THEN ? `;
cases.push(newCase);
});
line += `${cases.join('\n')}\n`;
line += `ELSE ${Driver.quoteIdentifiers(field)} END`;
fieldLines.push(line);
});
sql += `${fieldLines.join(',\n')}\n`;
const whereValues = [];
data.forEach(entry => {
const insertValue = entry[updateKey];
whereValues.push(insertValue);
insertData.push(insertValue);
});
// Create the placeholders for the WHERE IN clause
const placeholders = Array(whereValues.length);
placeholders.fill('?');
sql += `WHERE ${Driver.quoteIdentifiers(updateKey)} IN `;
sql += `( ${placeholders.join(',')} )`;
return [sql, insertData, affectedRows];
}
};

View File

@ -1,18 +1,38 @@
'use strict';
const fs = require('fs');
/**
* Various internal helper functions
*
* @private
*/
let helpers = {
class Helpers {
/**
* Get the contents of a file
*
* @param {string} file - The path to the file
* @return {Promise<string>} - Promise resolving to the contents of the file
*/
static readFile (file) {
return new Promise((resolve, reject) => {
fs.readFile(file, (err, data) => {
if (err) {
return reject(err);
}
return resolve(Buffer.from(data).toString());
});
});
}
/**
* Wrap String.prototype.trim in a way that is easily mappable
*
* @param {String} str - The string to trim
* @return {String} - The trimmed string
*/
stringTrim: str => str.trim(),
static stringTrim (str) {
return str.trim();
}
/**
* Get the type of the variable passed
*
@ -21,8 +41,8 @@ let helpers = {
* @param {mixed} o - Object to type check
* @return {String} - Type of the object
*/
type: o => {
let type = Object.prototype.toString.call(o).slice(8, -1).toLowerCase();
static type (o) {
const type = Object.prototype.toString.call(o).slice(8, -1).toLowerCase();
// handle NaN and Infinity
if (type === 'number') {
@ -36,17 +56,18 @@ let helpers = {
}
return type;
},
}
/**
* Determine whether an object is scalar
*
* @param {mixed} obj - Object to test
* @return {bool} - Is object scalar
* @return {boolean} - Is object scalar
*/
isScalar: obj => {
let scalar = ['string', 'number', 'boolean'];
return scalar.indexOf(helpers.type(obj)) !== -1;
},
static isScalar (obj) {
return ['string', 'number', 'boolean'].includes(Helpers.type(obj));
}
/**
* Get a list of values with a common key from an array of objects
*
@ -54,8 +75,8 @@ let helpers = {
* @param {String} key - The key of the object to get
* @return {Array} - The new array of plucked values
*/
arrayPluck: (arr, key) => {
let output = [];
static arrayPluck (arr, key) {
const output = [];
// Empty case
if (arr.length === 0) {
@ -63,13 +84,14 @@ let helpers = {
}
arr.forEach(obj => {
if (!helpers.isUndefined(obj[key])) {
if (!Helpers.isUndefined(obj[key])) {
output.push(obj[key]);
}
});
return output;
},
}
/**
* Determine if a value matching the passed regular expression is
* in the passed array
@ -78,9 +100,9 @@ let helpers = {
* @param {RegExp} pattern - The pattern to match
* @return {Boolean} - If an array item matches the pattern
*/
regexInArray: (arr, pattern) => {
static regexInArray (arr, pattern) {
// Empty case(s)
if (!helpers.isArray(arr) || arr.length === 0) {
if (!Helpers.isArray(arr) || arr.length === 0) {
return false;
}
@ -93,22 +115,23 @@ let helpers = {
}
return false;
},
}
/**
* Make the first letter of the string uppercase
* Make the first constter of the string uppercase
*
* @param {String} str - The string to modify
* @return {String} - The modified string
*/
upperCaseFirst: str => {
static upperCaseFirst (str) {
str += '';
let first = str.charAt(0).toUpperCase();
const first = str.charAt(0).toUpperCase();
return first + str.substr(1);
}
};
}
// Define an 'is' method for each type
let types = [
const types = [
'Null',
'Undefined',
'Object',
@ -119,7 +142,8 @@ let types = [
'Function',
'RegExp',
'NaN',
'Infinite'
'Infinite',
'Promise'
];
types.forEach(t => {
/**
@ -127,19 +151,19 @@ types.forEach(t => {
* function name, eg isNumber
*
* Types available are Null, Undefined, Object, Array, String, Number,
* Boolean, Function, RegExp, NaN and Infinite
* Boolean, Function, RegExp, NaN, Infinite, Promise
*
* @private
* @param {mixed} o - The object to check its type
* @return {Boolean} - If the type matches
*/
helpers[`is${t}`] = function (o) {
Helpers[`is${t}`] = function (o) {
if (t.toLowerCase() === 'infinite') {
t = 'infinity';
}
return helpers.type(o) === t.toLowerCase();
return Helpers.type(o) === t.toLowerCase();
};
});
module.exports = helpers;
module.exports = Helpers;

View File

@ -1,5 +1,3 @@
'use strict';
const QueryBuilder = require('./QueryBuilder');
// Map config driver name to code class name
@ -28,6 +26,12 @@ class NodeQuery {
* Constructor
*
* @param {object} config - connection parameters
* @param {string} config.driver - the database driver to use, such as mysql, sqlite, mssql, or pgsql
* @param {object|string} config.connection - the connection options for the database
* @param {string} config.connection.host - the ip or hostname of the database server
* @param {string} config.connection.user - the user to log in as
* @param {string} config.connection.password - the password to log in with
* @param {string} config.connection.database - the name of the database to connect to
* @example let nodeQuery = require('ci-node-query')({
* driver: 'mysql',
* connection: {
@ -46,17 +50,16 @@ class NodeQuery {
this.instance = null;
if (config !== undefined) {
let drivername = dbDriverMap.get(config.driver);
const driverName = dbDriverMap.get(config.driver);
if (!drivername) {
if (!driverName) {
throw new Error(`Selected driver (${config.driver}) does not exist!`);
}
const driver = require(`./drivers/${drivername}`);
const Adapter = require(`./adapters/${drivername}`);
const driver = require(`./drivers/${driverName}`);
const Adapter = require(`./adapters/${driverName}`);
let adapter = Adapter(config);
this.instance = new QueryBuilder(driver, adapter);
this.instance = new QueryBuilder(driver, Adapter(config));
}
}

View File

@ -1,6 +1,4 @@
'use strict';
const helpers = require('./helpers');
const Helpers = require('./Helpers');
const QueryBuilderBase = require('./QueryBuilderBase');
/**
@ -15,6 +13,26 @@ class QueryBuilder extends QueryBuilderBase {
// ! Miscellaneous Methods
// ----------------------------------------------------------------------------
/**
* Run a set of queries from a file
*
* @param {string} file - The path to the sql file
* @param {string} [separator=';'] - The character separating each query
* @return {Promise} - The result of all the queries
*/
queryFile (file, separator = ';') {
return Helpers.readFile(file).then(sqlFile => {
const queries = sqlFile.split(separator);
const results = [];
queries.forEach(sql => {
results.push(this.query(sql));
});
return Promise.all(results);
});
}
/**
* Run an arbitrary sql query. Run as a prepared statement.
*
@ -80,16 +98,16 @@ class QueryBuilder extends QueryBuilderBase {
// Split/trim fields by comma
fields = (Array.isArray(fields))
? fields
: fields.split(',').map(helpers.stringTrim);
: fields.split(',').map(Helpers.stringTrim);
// Split on 'As'
fields.forEach((field, index) => {
if (/as/i.test(field)) {
fields[index] = field.split(/ as /i).map(helpers.stringTrim);
fields[index] = field.split(/ as /i).map(Helpers.stringTrim);
}
});
let safeArray = this.driver.quoteIdentifiers(fields);
const safeArray = this.driver.quoteIdentifiers(fields);
// Join the strings back together
safeArray.forEach((field, index) => {
@ -113,7 +131,7 @@ class QueryBuilder extends QueryBuilderBase {
*/
from (tableName) {
// Split identifiers on spaces
let identArray = tableName.trim().split(' ').map(helpers.stringTrim);
let identArray = tableName.trim().split(' ').map(Helpers.stringTrim);
// Quote/prefix identifiers
identArray[0] = this.driver.quoteTable(identArray[0]);
@ -354,14 +372,14 @@ class QueryBuilder extends QueryBuilderBase {
type = type || 'inner';
// Prefix/quote table name
table = table.split(' ').map(helpers.stringTrim);
table = table.split(' ').map(Helpers.stringTrim);
table[0] = this.driver.quoteTable(table[0]);
table = table.map(this.driver.quoteIdentifiers);
table = table.join(' ');
// Parse out the join condition
let parsedCondition = this.parser.compileJoin(cond);
let condition = `${table} ON ${parsedCondition}`;
const parsedCondition = this.parser.compileJoin(cond);
const condition = `${table} ON ${parsedCondition}`;
// Append the join condition to the query map
this._appendMap(`\n${type.toUpperCase()} JOIN `, condition, 'join');
@ -376,8 +394,8 @@ class QueryBuilder extends QueryBuilderBase {
* @return {QueryBuilder} - The Query Builder object, for chaining
*/
groupBy (field) {
if (!helpers.isScalar(field)) {
let newGroupArray = field.map(this.driver.quoteIdentifiers);
if (!Helpers.isScalar(field)) {
const newGroupArray = field.map(this.driver.quoteIdentifiers);
this.state.groupArray = this.state.groupArray.concat(newGroupArray);
} else {
this.state.groupArray.push(this.driver.quoteIdentifiers(field));
@ -403,7 +421,7 @@ class QueryBuilder extends QueryBuilderBase {
this.state.orderArray[field] = type;
let orderClauses = [];
const orderClauses = [];
// Flatten key/val pairs into an array of space-separated pairs
Object.keys(this.state.orderArray).forEach(key => {
@ -436,7 +454,7 @@ class QueryBuilder extends QueryBuilderBase {
* @return {QueryBuilder} - The Query Builder object, for chaining
*/
groupStart () {
let conj = (this.state.queryMap.length < 1) ? ' WHERE ' : ' AND ';
const conj = (this.state.queryMap.length < 1) ? ' WHERE ' : ' AND ';
this._appendMap(conj, '(', 'groupStart');
return this;
@ -490,7 +508,7 @@ class QueryBuilder extends QueryBuilderBase {
* @example query.get('table_name').then(promiseCallback); // Get all the rows in the table
* @example query.get('table_name', 5); // Get 5 rows from the table
* @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 {Promise<Result>} - Promise containing the result of the query
*/
get (table, limit, offset) {
if (table) {
@ -510,7 +528,7 @@ class QueryBuilder extends QueryBuilderBase {
*
* @param {String} table - The table to insert into
* @param {Object} [data] - Data to insert, if not already added with the 'set' method
* @return {Promise} - If no callback is passed, a promise is returned
* @return {Promise<Result>} - Promise containing the result of the query
*/
insert (table, data) {
if (data) {
@ -528,10 +546,10 @@ class QueryBuilder extends QueryBuilderBase {
* @param {Array} data - The array of objects containing data rows to insert
* @example query.insertBatch('foo',[{id:1,val:'bar'},{id:2,val:'baz'}])
*.then(promiseCallback);
* @return {Promise} - If no callback is passed, a promise is returned
* @return {Promise<Result>} - Promise containing the result of the query
*/
insertBatch (table, data) {
let batch = this.driver.insertBatch(table, data);
const batch = this.driver.insertBatch(table, data);
// Run the query
return this.query(batch.sql, batch.values);
@ -542,7 +560,7 @@ class QueryBuilder extends QueryBuilderBase {
*
* @param {String} table - The table to insert into
* @param {Object} [data] - Data to insert, if not already added with the 'set' method
* @return {Promise} - If no callback is passed, a promise is returned
* @return {Promise<Result>} - Promise containing the result of the query
*/
update (table, data) {
if (data) {
@ -553,12 +571,26 @@ class QueryBuilder extends QueryBuilderBase {
return this._run('update', this.driver.quoteTable(table));
}
/**
* Creates a batch update sql statement
*
* @param {String} table - The table to update
* @param {Object} data - Batch insert data
* @param {String} updateKey - The field in the table to compare against for updating
* @return {Number} Number of rows updated
*/
updateBatch (table, data, updateKey) {
const [sql, insertData, affectedRows] = this.driver.updateBatch(table, data, updateKey);
this._run('', table, sql, insertData);
return affectedRows;
}
/**
* Run the generated delete query
*
* @param {String} table - The table to insert into
* @param {Object} [where] - Where clause for delete statement
* @return {Promise} - If no callback is passed, a promise is returned
* @return {Promise<Result>} - Promise containing the result of the query
*/
delete (table, where) {
if (where) {
@ -595,7 +627,7 @@ class QueryBuilder extends QueryBuilderBase {
* @param {Boolean} [reset=true] - Whether to reset the query builder so another query can be built
* @return {String} - The compiled sql statement
*/
getCompiledInsert (table, reset) {
getCompiledInsert (table, reset = true) {
return this._getCompile('insert', this.driver.quoteTable(table), reset);
}
@ -606,7 +638,7 @@ class QueryBuilder extends QueryBuilderBase {
* @param {Boolean} [reset=true] - Whether to reset the query builder so another query can be built
* @return {String} - The compiled sql statement
*/
getCompiledUpdate (table, reset) {
getCompiledUpdate (table, reset = true) {
return this._getCompile('update', this.driver.quoteTable(table), reset);
}
@ -617,7 +649,7 @@ class QueryBuilder extends QueryBuilderBase {
* @param {Boolean} [reset=true] - Whether to reset the query builder so another query can be built
* @return {String} - The compiled sql statement
*/
getCompiledDelete (table, reset) {
getCompiledDelete (table, reset = true) {
return this._getCompile('delete', this.driver.quoteTable(table), reset);
}
}

View File

@ -1,6 +1,4 @@
'use strict';
const helpers = require('./helpers');
const Helpers = require('./Helpers');
const QueryParser = require('./QueryParser');
const State = require('./State');
@ -18,74 +16,6 @@ class QueryBuilderBase {
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);
@ -127,15 +57,19 @@ class QueryBuilderBase {
* when appending to state
*
* @private
* @param {mixed} letName Lorem Ipsum
* @param {mixed} valType Lorem Ipsum
* @param {mixed} key Lorem Ipsum
* @param {mixed} val Lorem Ipsum
* @return {Array} - modified state array
*/
_mixedSet (letName, valType, key, val) {
let obj = {};
if (helpers.isScalar(key) && !helpers.isUndefined(val)) {
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)) {
} 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 {
@ -145,7 +79,7 @@ class QueryBuilderBase {
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];
const pushVal = (valType === 'key') ? k : obj[k];
this.state[letName].push(pushVal);
} else {
this.state[letName][k] = obj[k];
@ -164,10 +98,10 @@ class QueryBuilderBase {
}
_fixConjunction (conj) {
let lastItem = this.state.queryMap[this.state.queryMap.length - 1];
let conjunctionList = helpers.arrayPluck(this.state.queryMap, 'conjunction');
const lastItem = this.state.queryMap[this.state.queryMap.length - 1];
const conjunctionList = Helpers.arrayPluck(this.state.queryMap, 'conjunction');
if (this.state.queryMap.length === 0 || (!helpers.regexInArray(conjunctionList, /^ ?WHERE/i))) {
if (this.state.queryMap.length === 0 || (!Helpers.regexInArray(conjunctionList, /^ ?WHERE/i))) {
conj = ' WHERE ';
} else if (lastItem.type === 'groupStart') {
conj = '';
@ -187,7 +121,7 @@ class QueryBuilderBase {
this.state = this.parser.parseWhere(this.driver, this.state);
this.state.whereMap.forEach(clause => {
let conj = this._fixConjunction(defaultConj);
const conj = this._fixConjunction(defaultConj);
this._appendMap(conj, clause, 'where');
});
@ -196,7 +130,7 @@ class QueryBuilderBase {
_whereNull (field, stmt, conj) {
field = this.driver.quoteIdentifiers(field);
let item = `${field} ${stmt}`;
const item = `${field} ${stmt}`;
this._appendMap(this._fixConjunction(conj), item, 'whereNull');
}
@ -223,7 +157,7 @@ class QueryBuilderBase {
_whereIn (key, val, inClause, conj) {
key = this.driver.quoteIdentifiers(key);
let params = Array(val.length);
const params = Array(val.length);
params.fill('?');
val.forEach(value => {
@ -231,7 +165,7 @@ class QueryBuilderBase {
});
conj = (this.state.queryMap.length > 0) ? ` ${conj} ` : ' WHERE ';
let str = `${key} ${inClause} (${params.join(',')}) `;
const str = `${key} ${inClause} (${params.join(',')}) `;
this._appendMap(conj, str, 'whereIn');
}
@ -255,7 +189,7 @@ class QueryBuilderBase {
_getCompile (type, table, reset) {
reset = reset || false;
let sql = this._compile(type, table);
const sql = this._compile(type, table);
if (reset) {
this._resetState();
@ -264,6 +198,74 @@ class QueryBuilderBase {
return sql;
}
/**
* 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 => {
const 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':
const 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;
}
_resetState () {
this.state = new State();
}

View File

@ -1,7 +1,5 @@
'use strict';
const XRegExp = require('xregexp');
const helpers = require('./helpers');
const Helpers = require('./Helpers');
// --------------------------------------------------------------------------
@ -35,7 +33,7 @@ class QueryParser {
${matchPatterns['function'].source}|
${matchPatterns.literal.source}
)
([a-z_\-]+[0-9]*\\.?)
([a-z_-]+[0-9]*\\.?)
)+`, 'igx');
// Full pattern for determining ordering of the pieces
@ -56,10 +54,10 @@ class QueryParser {
* @return {Array|null} - Filtered set of possible matches
*/
filterMatches (array) {
let output = [];
const output = [];
// Return non-array matches
if (helpers.isNull(array)) {
if (Helpers.isNull(array)) {
return null;
}
@ -87,8 +85,8 @@ class QueryParser {
* @return {Object} - Join condition components
*/
parseJoin (sql) {
let matches = {};
let output = {
const matches = {};
const output = {
functions: [],
identifiers: [],
operators: [],
@ -115,15 +113,15 @@ class QueryParser {
/**
* Return the output of the parsing of the join condition
*
* @param {String} condition - The join condition to evalate
* @param {String} condition - The join condition to evaluate
* @return {String} - The parsed/escaped join condition
*/
compileJoin (condition) {
let parts = this.parseJoin(condition);
const parts = this.parseJoin(condition);
// Quote the identifiers
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);
}
});
@ -139,11 +137,11 @@ class QueryParser {
* @return {String} - The parsed/escaped where condition
*/
parseWhere (driver, state) {
let whereMap = state.whereMap;
const whereMap = state.whereMap;
let whereValues = state.rawWhereValues;
let outputMap = [];
let outputValues = [];
const outputMap = [];
const outputValues = [];
Object.keys(whereMap).forEach(key => {
// Combine fields, operators, functions and values into a full clause
@ -160,16 +158,16 @@ class QueryParser {
}
// Separate the clause into separate pieces
let parts = this.parseJoin(fullClause);
const parts = this.parseJoin(fullClause);
// Filter explicit literals from lists of matches
if (whereValues.indexOf(whereMap[key]) !== -1) {
let value = whereMap[key];
let identIndex = parts.identifiers.indexOf(value);
let litIndex = (helpers.isArray(parts.literals)) ? parts.literals.indexOf(value) : -1;
let combIndex = parts.combined.indexOf(value);
let funcIndex = (helpers.isArray(parts.functions)) ? parts.functions.indexOf(value) : -1;
let inOutputArray = outputValues.indexOf(value) !== -1;
const value = whereMap[key];
const identIndex = parts.identifiers.indexOf(value);
const litIndex = (Helpers.isArray(parts.literals)) ? parts.literals.indexOf(value) : -1;
const combIndex = parts.combined.indexOf(value);
const funcIndex = (Helpers.isArray(parts.functions)) ? parts.functions.indexOf(value) : -1;
let inOutputArray = outputValues.includes(value);
// Remove the identifier in question,
// and add to the output values array
@ -203,16 +201,16 @@ class QueryParser {
// Filter false positive identifiers
parts.identifiers = parts.identifiers.filter(item => {
let isInCombinedMatches = parts.combined.indexOf(item) !== -1;
let isNotInBlackList = this.identifierBlacklist.indexOf(item.toLowerCase()) === -1;
const isInCombinedMatches = parts.combined.indexOf(item) !== -1;
const isNotInBlackList = this.identifierBlacklist.indexOf(item.toLowerCase()) === -1;
return isInCombinedMatches && isNotInBlackList;
}, this);
// Quote identifiers
if (helpers.isArray(parts.identifiers)) {
if (Helpers.isArray(parts.identifiers)) {
parts.identifiers.forEach(ident => {
let index = parts.combined.indexOf(ident);
const index = parts.combined.indexOf(ident);
if (index !== -1) {
parts.combined[index] = driver.quoteIdentifiers(ident);
}
@ -224,9 +222,9 @@ class QueryParser {
// This should only apply to literal values that are not
// explicitly mapped to values, but have to be parsed from
// a where condition,
if (helpers.isArray(parts.literals)) {
if (Helpers.isArray(parts.literals)) {
parts.literals.forEach(lit => {
let litIndex = parts.combined.indexOf(lit);
const litIndex = parts.combined.indexOf(lit);
if (litIndex !== -1) {
parts.combined[litIndex] = '?';

View File

@ -1,6 +1,4 @@
'use strict';
const helpers = require('./helpers');
const Helpers = require('./Helpers');
/**
* Query result object
@ -16,7 +14,7 @@ class Result {
* @param {Array} [rows] - the data rows of the result
* @param {Array} [columns] - the column names in the result
*/
constructor (rows=[], columns=[]) {
constructor (rows = [], columns = []) {
this._rows = rows;
this._columns = columns;
@ -25,7 +23,7 @@ class Result {
if (
this._columns.length === 0 &&
this._rows.length > 0 &&
helpers.isObject(rows[0])
Helpers.isObject(rows[0])
) {
this.columns = Object.keys(rows[0]);
}

View File

@ -1,5 +1,3 @@
'use strict';
/**
* Class for objects containing the query builder state
* @private

View File

@ -1,8 +0,0 @@
'use strict';
const NodeFirebird = require('./node-firebird');
module.exports = config => {
return new NodeFirebird(config.connection);
};

View File

@ -1,61 +0,0 @@
'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;

View File

@ -0,0 +1,3 @@
module.exports = config => {
};

View File

@ -1,3 +1 @@
'use strict';
module.exports = require('../Mysql');

View File

@ -1,5 +1,3 @@
'use strict';
const Mysql2 = require('./mysql2');
module.exports = config => {

View File

@ -1,12 +1,9 @@
'use strict';
const Adapter = require('../../Adapter');
const Result = require('../../Result');
const helpers = require('../../helpers');
const Helpers = require('../../Helpers');
const mysql2 = require('mysql2/promise');
class Mysql extends Adapter {
constructor (config) {
const instance = mysql2.createConnection(config);
super(instance);
@ -22,7 +19,7 @@ class Mysql extends Adapter {
// 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') {
if (Helpers.type(result) === 'object') {
let r = new Result();
Object.keys(result).forEach(key => {
@ -39,7 +36,7 @@ class Mysql extends Adapter {
* 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
* @param {Array} params - The values to insert into the query
* @return {Promise} Result of query
*/
execute (sql, params) {

View File

@ -1,36 +1,16 @@
'use strict';
const Adapter = require('../../Adapter');
const Result = require('../../Result');
const helpers = require('../../helpers');
const Helpers = require('../../Helpers');
const pg = require('pg');
const url = require('url');
class Pg extends Adapter {
constructor (config) {
let instance = null;
let connectionString = '';
if (helpers.isObject(config)) {
let host = config.host || 'localhost';
let user = config.user || 'postgres';
let password = `:${config.password}` || '';
let port = config.port || 5432;
let conn = {
protocol: 'postgres',
slashes: true,
host: `${host}:${port}`,
auth: `${user}${password}`,
pathname: config.database
};
connectionString = url.format(conn);
} else if (helpers.isString(config)) {
connectionString = config;
}
let connectionString = Pg.formatConnectionString(config);
if (connectionString !== '') {
let conn = new pg.Client(connectionString);
const conn = new pg.Client(connectionString);
conn.connect(err => {
if (err) {
throw new Error(err);
@ -43,6 +23,37 @@ class Pg extends Adapter {
super(instance);
}
/**
* Convert the connection object to a connection string
*
* @param {Object} config - the configuration object
* @return {String} - the connection string
*/
static formatConnectionString (config) {
let connectionString = '';
if (Helpers.isObject(config)) {
const host = config.host || 'localhost';
const user = config.user || 'postgres';
const password = `:${config.password}` || '';
const port = config.port || 5432;
const conn = {
protocol: 'postgres',
slashes: true,
host: `${host}:${port}`,
auth: `${user}${password}`,
pathname: config.database
};
connectionString = url.format(conn);
} else if (Helpers.isString(config)) {
connectionString = config;
}
return connectionString;
}
/**
* Transform the adapter's result into a standard format
*
@ -54,9 +65,9 @@ class Pg extends Adapter {
return new Result();
}
let cols = [];
const cols = [];
result.fields.forEach(field => {
cols = field.name;
cols.push(field.name);
});
return new Result(result.rows, cols);

View File

@ -1,7 +1,2 @@
'use strict';
const Pg = require('./Pg');
module.exports = config => {
return new Pg(config.connection);
};
module.exports = config => new Pg(config.connection);

View File

@ -1,16 +1,14 @@
'use strict';
const Adapter = require('../../Adapter');
const Result = require('../../Result');
const helpers = require('../../helpers');
const Helpers = require('../../Helpers');
const dbliteAdapter = require('dblite');
class SqliteDblite extends Adapter {
constructor (config) {
let file = (helpers.isString(config)) ? config : config.file;
const file = (Helpers.isString(config)) ? config : config.file;
const instance = new Promise((resolve, reject) => {
let conn = dbliteAdapter(file);
const conn = dbliteAdapter(file);
// Stop the stupid 'bye bye' message being output
conn.on('close', () => {});

View File

@ -1,10 +1,7 @@
'use strict';
module.exports = config => {
const Implementation = (config.adapter && config.adapter === 'dblite')
? require('./dblite')
: require('./sqlite3');
const Implementation = (config.native)
? require('./sqlite3')
: require('./dblite');
return new Implementation(config.connection);
};

View File

@ -1,16 +1,14 @@
'use strict';
const Adapter = require('../../Adapter');
const Result = require('../../Result');
const helpers = require('../../helpers');
const Helpers = require('../../Helpers');
const sqlite3 = require('sqlite3').verbose();
class SqliteSqlite3 extends Adapter {
constructor (config) {
let file = (helpers.isString(config)) ? config : config.file;
const 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 => {
const conn = new sqlite3.Database(file, sqlite3.OPEN_READWRITE | sqlite3.OPEN_CREATE, err => {
if (err) {
reject(err);
}

View File

@ -1,45 +0,0 @@
'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;
})();

View File

@ -0,0 +1,14 @@
/**
* Driver for Microsoft SQL Server databases
*
* @module drivers/MSSQLDriver
*/
module.exports = (() => {
delete require.cache[require.resolve('../Driver')];
const driver = require('../Driver');
driver.identifierStartChar = '[';
driver.identifierEndChar = ']';
return driver;
})();

View File

@ -1,5 +1,3 @@
'use strict';
/**
* Driver for MariaDB databases
*

View File

@ -1,5 +1,3 @@
'use strict';
/**
* Driver for MySQL databases
*
@ -8,7 +6,7 @@
module.exports = (() => {
delete require.cache[require.resolve('../Driver')];
const driver = require('../Driver');
const helpers = require('../helpers');
const Helpers = require('../Helpers');
driver.identifierStartChar = '`';
driver.identifierEndChar = '`';
@ -22,7 +20,7 @@ module.exports = (() => {
* @return {String} - Modified SQL statement
*/
driver.limit = (sql, limit, offset) => {
sql += (helpers.isNumber(offset))
sql += (Helpers.isNumber(offset))
? ` LIMIT ${offset},${limit}`
: ` LIMIT ${limit}`;

View File

@ -1,5 +1,3 @@
'use strict';
/**
* Driver for PostgreSQL databases
*
@ -7,7 +5,5 @@
*/
module.exports = (() => {
delete require.cache[require.resolve('../Driver')];
let driver = require('../Driver');
return driver;
return require('../Driver');
})();

View File

@ -1,5 +1,3 @@
'use strict';
/**
* Driver for SQLite databases
*
@ -7,7 +5,7 @@
*/
module.exports = (() => {
delete require.cache[require.resolve('../Driver')];
let driver = require('../Driver');
const driver = require('../Driver');
// Sqlite doesn't have a truncate command
driver.hasTruncate = false;
@ -24,11 +22,11 @@ module.exports = (() => {
// Get the data values to insert, so they can
// be parameterized
let sql = '';
let first = data.shift();
const first = data.shift();
let vals = [];
const vals = [];
data.forEach(obj => {
let row = [];
const row = [];
Object.keys(obj).forEach(key => {
row.push(obj[key]);
});
@ -39,8 +37,8 @@ module.exports = (() => {
// Get the field names from the keys of the first
// object to be inserted
let fields = Object.keys(first);
let cols = [];
const fields = Object.keys(first);
const cols = [];
fields.forEach(key => {
cols.push(`'${driver._quote(first[key])}' AS ${driver.quoteIdentifiers(key)}`);
});
@ -48,7 +46,7 @@ module.exports = (() => {
sql += `SELECT ${cols.join(', ')}\n`;
vals.forEach(rowValues => {
let quoted = rowValues.map(value => String(value).replace('\'', '\'\''));
const quoted = rowValues.map(value => String(value).replace('\'', '\'\''));
sql += `UNION ALL SELECT '${quoted.join('\', \'')}'\n`;
});

Some files were not shown because too many files have changed in this diff Show More