diff --git a/.travis.yml b/.travis.yml
index b22fa3e..0f60068 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -4,11 +4,10 @@ sudo: false
node_js:
- "iojs"
- "node"
+ - "5.1"
+ - "5.0"
- "4.1"
- "4.0"
- - "0.12"
- - "0.11"
- - "0.10"
before_script:
- npm install -g gulp
@@ -18,4 +17,8 @@ before_script:
- mysql -v -uroot test < ./tests/sql/mysql.sql
- psql test postgres -f ./tests/sql/pgsql.sql
-script: gulp
\ No newline at end of file
+script: gulp
+
+matrix:
+ allow_failures:
+ - node_js: iojs
\ No newline at end of file
diff --git a/docs/index.html b/docs/index.html
index 08c0a43..35f4112 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -31,16 +31,6 @@
class='block bold'>
State
-
- State
-
-
- _appendMap
-
@@ -313,62 +303,6 @@
-
-
- State(Driver, driver)
-
-
- Parameters
-
- - Driver
- :
-
-
The driver object for the database in use
-
-
-
- - driver
- :
-
-
-
-
-
-
-
-
- _appendMap(conjunction, string, type)
-
- Append a clause to the query map
-
- Parameters
-
- Returns
- void
-
-
-
-
-
helpers(o)
@@ -429,9 +363,10 @@ function name, eg isNumber
Returns
Array
-
+ :
-
+ The new array of plucked values
+
@@ -458,15 +393,17 @@ function name, eg isNumber
mixed
obj
:
-
+ Object to test
+
Returns
bool
-
+ :
-
+ Is object scalar
+
@@ -576,15 +513,17 @@ in the passed array
mixed
o
:
-
+ Object to type check
+
Returns
String
-
+ :
-
+ Type of the object
+
@@ -611,15 +550,17 @@ in the passed array
String
str
:
-
+ The string to modify
+
Returns
String
-
+ :
-
+ The modified string
+
@@ -651,22 +592,16 @@ in the passed array
- constructor(Driver, driver)
+ constructor(driver)
Parameters
- - Driver
+
Driver
driver
:
The driver object for the database in use
-
-
- - driver
- :
-
-
@@ -738,15 +673,17 @@ in the passed array
Array
array
:
-
+ Set of possible matches
+
Returns
Array
or
-
+ :
-
+ Filtered set of possible matches
+
@@ -767,9 +704,10 @@ in the passed array
Returns
QueryBuilder
-
+ :
-
+ The Query Builder object, for chaining
+
@@ -842,9 +780,10 @@ in the passed array
Returns
String
-
+ :
-
+ The compiled sql statement
+
@@ -873,9 +812,10 @@ in the passed array
Returns
String
-
+ :
-
+ The compiled sql statement
+
@@ -904,9 +844,10 @@ in the passed array
Returns
String
-
+ :
-
+ The compiled sql statement
+
@@ -935,9 +876,10 @@ in the passed array
Returns
String
-
+ :
-
+ The compiled sql statement
+
@@ -951,15 +893,17 @@ in the passed array
String
or Array
field
:
-
+ The name of the field to group by
+
Returns
QueryBuilder
-
+ :
-
+ The Query Builder object, for chaining
+
@@ -970,9 +914,10 @@ in the passed array
Returns
QueryBuilder
-
+ :
-
+ The Query Builder object, for chaining
+
@@ -983,9 +928,10 @@ in the passed array
Returns
QueryBuilder
-
+ :
-
+ The Query Builder object, for chaining
+
@@ -1007,9 +953,10 @@ If there are no matches, return null
Returns
Array
or
-
+ :
-
+ List of operators
+
@@ -1037,9 +984,10 @@ If there are no matches, return null
Returns
QueryBuilder
-
+ :
-
+ The Query Builder object, for chaining
+
@@ -1151,9 +1099,10 @@ If there are no matches, return null
Returns
QueryBuilder
-
+ :
-
+ The Query Builder object, for chaining
+
@@ -1189,9 +1138,10 @@ If there are no matches, return null
Returns
QueryBuilder
-
+ :
-
+ The Query Builder object, for chaining
+
@@ -1219,9 +1169,10 @@ If there are no matches, return null
Returns
QueryBuilder
-
+ :
-
+ The Query Builder object, for chaining
+
@@ -1257,9 +1208,10 @@ If there are no matches, return null
Returns
QueryBuilder
-
+ :
-
+ The Query Builder object, for chaining
+
@@ -1271,9 +1223,10 @@ prefixed with 'OR'
Returns
QueryBuilder
-
+ :
-
+ The Query Builder object, for chaining
+
@@ -1301,9 +1254,10 @@ prefixed with 'OR'
Returns
QueryBuilder
-
+ :
-
+ The Query Builder object, for chaining
+
@@ -1339,9 +1293,10 @@ prefixed with 'OR'
Returns
QueryBuilder
-
+ :
-
+ The Query Builder object, for chaining
+
@@ -1353,9 +1308,10 @@ prefixed with 'OR NOT'
Returns
QueryBuilder
-
+ :
-
+ The Query Builder object, for chaining
+
@@ -1391,9 +1347,10 @@ prefixed with 'OR NOT'
Returns
QueryBuilder
-
+ :
-
+ The Query Builder object, for chaining
+
@@ -1421,9 +1378,10 @@ prefixed with 'OR NOT'
Returns
QueryBuilder
-
+ :
-
+ The Query Builder object, for chaining
+
@@ -1451,9 +1409,10 @@ prefixed with 'OR NOT'
Returns
QueryBuilder
-
+ :
-
+ The Query Builder object, for chaining
+
@@ -1467,15 +1426,17 @@ prefixed with 'OR NOT'
String
field
:
-
+ The name of the field
+
Returns
QueryBuilder
-
+ :
-
+ The Query Builder object, for chaining
+
@@ -1489,15 +1450,17 @@ prefixed with 'OR NOT'
String
field
:
-
+ The name of the field
+
Returns
QueryBuilder
-
+ :
-
+ The Query Builder object, for chaining
+
@@ -1525,9 +1488,10 @@ prefixed with 'OR NOT'
Returns
QueryBuilder
-
+ :
-
+ The Query Builder object, for chaining
+
@@ -1556,9 +1520,10 @@ prefixed with 'OR NOT'
Returns
QueryBuilder
-
+ :
-
+ The Query Builder object, for chaining
+
@@ -1572,15 +1537,17 @@ prefixed with 'OR NOT'
String
sql
:
-
+ Join sql to parse
+
Returns
Object
-
+ :
-
+ Join condition components
+
@@ -1594,13 +1561,15 @@ prefixed with 'OR NOT'
Driver
driver
:
-
+ The current db driver
+
State
state
:
-
+ Query Builder state object
+
@@ -1643,9 +1612,10 @@ prefixed with 'OR NOT'
Returns
QueryBuilder
-
+ :
-
+ The Query Builder object, for chaining
+
@@ -1673,9 +1643,10 @@ prefixed with 'OR NOT'
Returns
QueryBuilder
-
+ :
-
+ The Query Builder object, for chaining
+
@@ -1740,9 +1711,10 @@ prefixed with 'OR NOT'
Returns
QueryBuilder
-
+ :
-
+ The Query Builder object, for chaining
+
@@ -1770,9 +1742,10 @@ prefixed with 'OR NOT'
Returns
QueryBuilder
-
+ :
-
+ The Query Builder object, for chaining
+
@@ -1786,15 +1759,17 @@ prefixed with 'OR NOT'
String
field
:
-
+ The name so the field that is not to be null
+
Returns
QueryBuilder
-
+ :
-
+ The Query Builder object, for chaining
+
@@ -1815,9 +1790,10 @@ prefixed with 'OR NOT'
Returns
QueryBuilder
-
+ :
-
+ The Query Builder object, for chaining
+
@@ -1845,9 +1821,10 @@ prefixed with 'OR NOT'
Returns
QueryBuilder
-
+ :
-
+ The Query Builder object, for chaining
+
diff --git a/gulpfile.js b/gulpfile.js
index 4011e1f..9aafd5d 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -1,94 +1,72 @@
-var babel = require('gulp-babel'),
- concat = require('gulp-concat'),
- documentation = require('gulp-documentation'),
+'use strict';
+
+const documentation = require('gulp-documentation'),
eslint = require('gulp-eslint'),
gulp = require('gulp'),
- istanbul = require('gulp-babel-istanbul'),
- nodeunit_runner = require('gulp-nodeunit-runner'),
- sloc = require('gulp-sloc'),
- sourcemaps = require('gulp-sourcemaps');
+ istanbul = require('gulp-istanbul'),
+ mocha = require('gulp-mocha'),
+ pipe = require('gulp-pipe'),
+ sloc = require('gulp-sloc');
-gulp.task('transpile', function() {
- return gulp.src('src/**/*.js')
- .pipe(sourcemaps.init())
- .pipe(babel({
- presets: ['es2015'],
- plugins: ['transform-es2015-modules-commonjs']
- }))
- .pipe(sourcemaps.write('.'))
- .pipe(gulp.dest('lib'));
+const SRC_FILES = ['lib/**/*.js'];
+const TEST_FILES = ['test/**/*_test.js'];
+
+const ESLINT_SETTINGS = {
+ "env": {
+ "node": true,
+ "es6": true
+ },
+ "rules": {
+ "arrow-parens": [2, "as-needed"],
+ "no-console": [1],
+ "no-constant-condition": [1],
+ "no-extra-semi": [1],
+ "no-func-assign": [1],
+ "no-unexpected-multiline" : [2],
+ "radix": [2],
+ "no-with": [2],
+ "no-eval": [2],
+ "no-unreachable": [1],
+ "no-irregular-whitespace": [1],
+ "no-new-wrappers": [2],
+ "no-new-func": [2],
+ "curly" : [2, "multi-line"],
+ "no-implied-eval": [2],
+ "no-invalid-this": [2],
+ "constructor-super": [2],
+ "no-dupe-args": [2],
+ "no-dupe-keys": [2],
+ "no-dupe-class-members": [2],
+ "no-this-before-super": [2],
+ "prefer-arrow-callback": [1],
+ "no-var": [2],
+ "valid-jsdoc": [1],
+ "strict": [2, "global"],
+ "callback-return": [1]
+ }
+};
+
+gulp.task('lint', () => {
+ return pipe(gulp.src(SRC_FILES), [
+ eslint(ESLINT_SETTINGS),
+ eslint.format(),
+ eslint.failAfterError()
+ ]);
});
-gulp.task('lint', function() {
- return gulp.src('src/**/*.js')
- .pipe(eslint({
- "env": {
- "node": true,
- "es6": true
- },
- "ecmaFeatures": {
- "arrowFunctions": true,
- "blockBindings": true,
- "classes": true,
- "defaultParams": true,
- "destructuring": true,
- "forOf": true,
- "modules": true
- },
- "rules": {
- "radix": [2],
- "no-with": [2],
- "no-eval": [2],
- "no-unreachable": [2],
- "no-irregular-whitespace": [1],
- "no-new-wrappers": [2],
- "curly" : [2, "multi-line"],
- "no-implied-eval": [2],
- "no-invalid-this": [2],
- "constructor-super": [2],
- "no-dupe-class-members": [2],
- "no-this-before-super": [2],
- "prefer-arrow-callback": [1],
- "no-var": [1],
- "valid-jsdoc": [1]
- }
- }))
- .pipe(eslint.format())
- .pipe(eslint.failAfterError());
+gulp.task('lint-tests', ['lint'], () => {
+ return pipe(gulp.src(TEST_FILES), [
+ eslint(ESLINT_SETTINGS),
+ eslint.format(),
+ eslint.failAfterError()
+ ]);
});
-gulp.task('lint-tests', ['lint'], function() {
- return gulp.src('tests/**/*.js')
- .pipe(eslint({
- "env": {
- "node": true
- },
- "rules": {
- "radix": [2],
- "no-with": [2],
- "no-eval": [2],
- "no-unreachable": [1],
- "no-irregular-whitespace": [1],
- "curly" : [2, "multi-line"],
- "no-implied-eval": [2],
- "no-invalid-this": [2],
- "no-dupe-class-members": [2],
- "block-scoped-var": [2]
- }
- }))
- .pipe(eslint.format())
- .pipe(eslint.failAfterError());
-});
+gulp.task('sloc', () => gulp.src(SRC_FILES).pipe(sloc()));
+gulp.task('test-sloc', () => gulp.src(TEST_FILES).pipe(sloc()));
-gulp.task('sloc', ['transpile'], function() {
- gulp.src(['src/**/*.js'])
- .pipe(sloc());
- gulp.src(['lib/**/*.js'])
- .pipe(sloc());
-})
-
-gulp.task('docs', ['transpile'], function() {
- gulp.src('./src/QueryBuilder.js')
+gulp.task('docs', () => {
+ gulp.src('./lib/QueryBuilder.js')
.pipe(documentation({format: 'html'}))
.pipe(gulp.dest('docs'));
/*gulp.src('./lib/QueryBuilder.js')
@@ -96,28 +74,32 @@ gulp.task('docs', ['transpile'], function() {
.pipe(gulp.dest('api-docs'));*/
});
-gulp.task('nodeunit', ['transpile', 'lint-tests'], function() {
- return gulp.src(['tests/**/*_test.js'])
- .pipe(nodeunit_runner());
+gulp.task('mocha', ['lint-tests', 'sloc'], () => {
+ return gulp.src(TEST_FILES)
+ .pipe(mocha({
+ ui: 'tdd',
+ bail: true,
+ //reporter: 'dot',
+ //reporter: 'landing',
+ }));
});
-gulp.task('fast-test', ['transpile', 'lint-tests'], function() {
- return gulp.src(['tests/**/*_test.js'])
- .pipe(nodeunit_runner());
-});
-
-gulp.task('test', ['transpile', 'lint-tests'], function(cb) {
- return gulp.src(['lib/**/*.js'])
- .pipe(istanbul())
- .pipe(istanbul.hookRequire())
- .on('finish', function () {
- gulp.src(['tests/**/*_test.js'])
- .pipe(nodeunit_runner())
- .pipe(istanbul.writeReports({
- dir: './coverage',
- reporters: ['lcov', 'lcovonly', 'html', 'text']
- }));
- });
+gulp.task('test', ['test-sloc', 'lint-tests'], function(cb) {
+ return pipe(gulp.src(SRC_FILES), [
+ istanbul(),
+ istanbul.hookRequire()
+ ]).on('finish', () => {
+ pipe(gulp.src(TEST_FILES), [
+ mocha({
+ ui: 'tdd',
+ bail: true
+ }),
+ istanbul.writeReports({
+ dir: './coverage',
+ reporters: ['lcov', 'lcovonly', 'html', 'text']
+ })
+ ]);
+ });
});
gulp.task('default', ['lint', 'sloc', 'docs', 'test']);
\ No newline at end of file
diff --git a/lib/Adapter.js b/lib/Adapter.js
index bd29e2a..bb1627d 100755
--- a/lib/Adapter.js
+++ b/lib/Adapter.js
@@ -1,42 +1,26 @@
-'use strict'
+'use strict';
/** @module Adapter */
-;
-
-var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-module.exports = (function () {
+module.exports = class Adapter {
/**
- * Invoke an adapter
- *
- * @param {Object} instance - The connection objec
- * @return {void}
- */
-
- function Adapter(instance) {
- _classCallCheck(this, Adapter);
-
+ * Invoke an adapter
+ *
+ * @param {Object} instance - The connection objec
+ * @return {void}
+ */
+ constructor(instance) {
this.instance = instance;
}
/**
- * Run the sql query as a prepared statement
- *
- * @param {String} sql - The sql with placeholders
- * @param {Array} params - The values to insert into the query
- * @param {Function} callback - Callback to run when a response is recieved
- * @return {void}
- */
-
- _createClass(Adapter, [{
- key: "execute",
- value: function execute() /*sql, params, callback*/{
- throw new Error("Correct adapter not defined for query execution");
- }
- }]);
-
- return Adapter;
-})();
-//# sourceMappingURL=Adapter.js.map
+ * Run the sql query as a prepared statement
+ *
+ * @param {String} sql - The sql with placeholders
+ * @param {Array} params - The values to insert into the query
+ * @param {Function} callback - Callback to run when a response is recieved
+ * @return {void}
+ */
+ execute(/*sql, params, callback*/) {
+ throw new Error("Correct adapter not defined for query execution");
+ }
+}
\ No newline at end of file
diff --git a/lib/Adapter.js.map b/lib/Adapter.js.map
deleted file mode 100644
index 06bc225..0000000
--- a/lib/Adapter.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"sources":["Adapter.js"],"names":[],"mappings":"AAAA;;;AAAY,CAAC;;;;;;AAGb,MAAM,CAAC,OAAO;;;;;;;;AAOb,UAPsB,OAAO,CAOjB,QAAQ,EAAE;wBAPA,OAAO;;AAQ5B,MAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;EACzB;;;;;;;;;;AAAA;cATqB,OAAO;;qDAmBM;AAClC,SAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;GACnE;;;QArBqB,OAAO;IAsB7B,CAAA","file":"Adapter.js","sourcesContent":["'use strict';\n\n/** @module Adapter */\nmodule.exports = class Adapter {\n\t/**\n\t * Invoke an adapter\n\t *\n\t * @param {Object} instance - The connection objec\n\t * @return {void}\n\t */\n\tconstructor(instance) {\n\t\tthis.instance = instance;\n\t}\n\n\t/**\n\t * Run the sql query as a prepared statement\n\t *\n\t * @param {String} sql - The sql with placeholders\n\t * @param {Array} params - The values to insert into the query\n\t * @param {Function} callback - Callback to run when a response is recieved\n\t * @return {void}\n\t */\n\texecute(/*sql, params, callback*/) {\n\t\tthrow new Error(\"Correct adapter not defined for query execution\");\n\t}\n}"],"sourceRoot":"/source/"}
\ No newline at end of file
diff --git a/lib/DriverBase.js b/lib/DriverBase.js
index 11ddacf..48884bd 100755
--- a/lib/DriverBase.js
+++ b/lib/DriverBase.js
@@ -1,78 +1,84 @@
'use strict';
-var _helpers = require('./helpers');
-
-var _helpers2 = _interopRequireDefault(_helpers);
-
-function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+let helpers = require('./helpers');
/**
* Base Database Driver
*
* @module driver
*/
-var d = {
+let d = {
identifierStartChar: '"',
identifierEndChar: '"',
tablePrefix: null,
hasTruncate: true,
/**
- * Low level function for naive quoting of strings
- * @param {String} str
- * @return {String}
- * @private
- */
- _quote: function _quote(str) {
- return _helpers2.default.isString(str) && !(str.startsWith(d.identifierStartChar) || str.endsWith(d.identifierEndChar)) ? d.identifierStartChar + str + d.identifierEndChar : str;
+ * Low level function for naive quoting of strings
+
+ * @param {String} str - The sql fragment to quote
+ * @return {String} - The quoted sql fragment
+ * @private
+ */
+ _quote: function(str) {
+ return (helpers.isString(str) && ! (str.startsWith(d.identifierStartChar) || str.endsWith(d.identifierEndChar)))
+ ? `${d.identifierStartChar}${str}${d.identifierEndChar}`
+ : str;
},
/**
- * Set the limit clause
- * @param {String} sql
- * @param {Number} limit
- * @param {Number|null} offset
- * @return {String}
- */
- limit: function limit(sql, _limit, offset) {
- sql += " LIMIT " + _limit;
+ * Set the limit clause
- if (_helpers2.default.isNumber(offset)) {
- sql += " OFFSET " + offset;
+ * @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
+ */
+ limit: function(sql, limit, offset) {
+ sql += ` LIMIT ${limit}`;
+
+ if (helpers.isNumber(offset))
+ {
+ sql += ` OFFSET ${offset}`;
}
return sql;
},
/**
- * Quote database table name, and set prefix
- *
- * @param {String} table
- * @return {String}
- */
- quoteTable: function quoteTable(table) {
+ * Quote database table name, and set prefix
+ *
+ * @param {String} table - Table name to quote
+ * @return {String} - Quoted table name
+ */
+ quoteTable: function(table) {
// Quote after prefix
return d.quoteIdentifiers(table);
},
/**
- * Use the driver's escape character to quote identifiers
- *
- * @param {String|Array}
- * @return {String|Array}
- */
- quoteIdentifiers: function quoteIdentifiers(str) {
- var hiers, raw;
- var pattern = new RegExp(d.identifierStartChar + '(' + '([a-zA-Z0-9_]+)' + '(\((.*?)\))' + ')' + d.identifierEndChar, 'ig');
+ * Use the driver's escape character to quote identifiers
+ *
+ * @param {String|String[]} - String or array of strings to quote identifiers
+ * @return {String|String[]} - Quoted identifier(s)
+ */
+ quoteIdentifiers: function(str) {
+ let hiers, raw;
+ let pattern = new RegExp(
+ `${d.identifierStartChar}(`
+ + '([a-zA-Z0-9_]+)' + '(\((.*?)\))'
+ + `)${d.identifierEndChar}`, 'ig');
// Recurse for arrays of identifiiers
- if (Array.isArray(str)) {
+ if (Array.isArray(str))
+ {
return str.map(d.quoteIdentifiers);
}
// Handle commas
- if (str.includes(',')) {
- var parts = str.split(',').map(_helpers2.default.stringTrim);
+ if (str.includes(','))
+ {
+ let parts = str.split(',').map(helpers.stringTrim);
str = parts.map(d.quoteIdentifiers).join(',');
}
@@ -81,14 +87,15 @@ var d = {
raw = hiers.join('.');
// Fix functions
- if (raw.includes('(') && raw.includes(')')) {
- var funcs = pattern.exec(raw);
+ if (raw.includes('(') && raw.includes(')'))
+ {
+ let funcs = pattern.exec(raw);
// Unquote the function
raw = raw.replace(funcs[0], funcs[1]);
// Quote the identifiers inside of the parens
- var inParens = funcs[3].substring(1, funcs[3].length - 1);
+ let inParens = funcs[3].substring(1, funcs[3].length -1);
raw = raw.replace(inParens, d.quoteIdentifiers(inParens));
}
@@ -96,13 +103,15 @@ var d = {
},
/**
- * SQL to truncate the passed table
- *
- * @param {String} table
- * @return {String} - sql
- */
- truncate: function truncate(table) {
- var sql = d.hasTruncate ? 'TRUNCATE ' : 'DELETE FROM ';
+ * SQL to truncate the passed table
+ *
+ * @param {String} table - Table to truncate
+ * @return {String} - Truncation SQL
+ */
+ truncate: function(table) {
+ let sql = (d.hasTruncate)
+ ? 'TRUNCATE '
+ : 'DELETE FROM ';
sql += d.quoteTable(table);
@@ -110,24 +119,24 @@ var d = {
},
/**
- * SQL to insert a group of rows
- *
- * @param {String} table - The table to insert to
- * @param {Array} [data] - The array of object containing data to insert
- * @return {String}
- */
- insertBatch: function insertBatch(table, data) {
- var vals = [],
- fields = Object.keys(data[0]),
- sql = "",
- params = [],
- paramString = "",
- paramList = [];
+ * SQL to insert a group of rows
+ *
+ * @param {String} table - The table to insert to
+ * @param {Array} [data] - The array of object containing data to insert
+ * @return {String} - Query and data to insert
+ */
+ insertBatch: function(table, data) {
+ let vals = [],
+ fields = Object.keys(data[0]),
+ sql = "",
+ params = [],
+ paramString = "",
+ paramList = [];
// Get the data values to insert, so they can
// be parameterized
- data.forEach(function (obj) {
- Object.keys(obj).forEach(function (key) {
+ data.forEach(obj => {
+ Object.keys(obj).forEach(key => {
vals.push(obj[key]);
});
});
@@ -136,7 +145,9 @@ var d = {
// object inserted
table = d.quoteTable(table);
- sql += "INSERT INTO " + table + " (" + d.quoteIdentifiers(fields).join(",") + ") VALUES ";
+ sql += `INSERT INTO ${table} (`
+ + d.quoteIdentifiers(fields).join(",")
+ + ") VALUES ";
// Create placeholder groups
params = Array(fields.length).fill('?');
@@ -153,5 +164,4 @@ var d = {
};
-module.exports = d;
-//# sourceMappingURL=DriverBase.js.map
+module.exports = d;
\ No newline at end of file
diff --git a/lib/DriverBase.js.map b/lib/DriverBase.js.map
deleted file mode 100644
index fdbcf48..0000000
--- a/lib/DriverBase.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"sources":["DriverBase.js"],"names":[],"mappings":"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","file":"DriverBase.js","sourcesContent":["'use strict';\n\nimport helpers from './helpers'\n\n/**\n * Base Database Driver\n *\n * @module driver\n */\nvar d = {\n\tidentifierStartChar: '\"',\n\tidentifierEndChar: '\"',\n\ttablePrefix: null,\n\thasTruncate: true,\n\n\t/**\n\t * Low level function for naive quoting of strings\n\n\t * @param {String} str\n\t * @return {String}\n\t * @private\n\t */\n\t_quote: function(str) {\n\t\treturn (helpers.isString(str) && ! (str.startsWith(d.identifierStartChar) || str.endsWith(d.identifierEndChar)))\n\t\t\t? d.identifierStartChar + str + d.identifierEndChar\n\t\t\t: str;\n\t},\n\n\t/**\n\t * Set the limit clause\n\n\t * @param {String} sql\n\t * @param {Number} limit\n\t * @param {Number|null} offset\n\t * @return {String}\n\t */\n\tlimit: function(sql, limit, offset) {\n\t\tsql += \" LIMIT \" + limit;\n\n\t\tif (helpers.isNumber(offset))\n\t\t{\n\t\t\tsql += \" OFFSET \" + offset;\n\t\t}\n\n\t\treturn sql;\n\t},\n\n\t/**\n\t * Quote database table name, and set prefix\n\t *\n\t * @param {String} table\n\t * @return {String}\n\t */\n\tquoteTable: function(table) {\n\t\t// Quote after prefix\n\t\treturn d.quoteIdentifiers(table);\n\t},\n\n\t/**\n\t * Use the driver's escape character to quote identifiers\n\t *\n\t * @param {String|Array}\n\t * @return {String|Array}\n\t */\n\tquoteIdentifiers: function(str) {\n\t\tvar hiers, raw;\n\t\tvar pattern = new RegExp(d.identifierStartChar + '(' + '([a-zA-Z0-9_]+)' + '(\\((.*?)\\))' + ')' + d.identifierEndChar, 'ig');\n\n\t\t// Recurse for arrays of identifiiers\n\t\tif (Array.isArray(str))\n\t\t{\n\t\t\treturn str.map(d.quoteIdentifiers);\n\t\t}\n\n\t\t// Handle commas\n\t\tif (str.includes(','))\n\t\t{\n\t\t\tvar parts = str.split(',').map(helpers.stringTrim);\n\t\t\tstr = parts.map(d.quoteIdentifiers).join(',');\n\t\t}\n\n\t\t// Split identifiers by period\n\t\thiers = str.split('.').map(d._quote);\n\t\traw = hiers.join('.');\n\n\t\t// Fix functions\n\t\tif (raw.includes('(') && raw.includes(')'))\n\t\t{\n\t\t\tvar funcs = pattern.exec(raw);\n\n\t\t\t// Unquote the function\n\t\t\traw = raw.replace(funcs[0], funcs[1]);\n\n\t\t\t// Quote the identifiers inside of the parens\n\t\t\tvar inParens = funcs[3].substring(1, funcs[3].length -1);\n\t\t\traw = raw.replace(inParens, d.quoteIdentifiers(inParens));\n\t\t}\n\n\t\treturn raw;\n\t},\n\n\t/**\n\t * SQL to truncate the passed table\n\t *\n\t * @param {String} table\n\t * @return {String} - sql\n\t */\n\ttruncate: function(table) {\n\t\tvar sql = (d.hasTruncate)\n\t\t\t? 'TRUNCATE '\n\t\t\t: 'DELETE FROM ';\n\n\t\tsql += d.quoteTable(table);\n\n\t\treturn sql;\n\t},\n\n\t/**\n\t * SQL to insert a group of rows\n\t *\n\t * @param {String} table - The table to insert to\n\t * @param {Array} [data] - The array of object containing data to insert\n\t * @return {String}\n\t */\n\tinsertBatch: function(table, data) {\n\t\tvar vals = [],\n\t\t\tfields = Object.keys(data[0]),\n\t\t\tsql = \"\",\n\t\t\tparams = [],\n\t\t\tparamString = \"\",\n\t\t\tparamList = [];\n\n\t\t// Get the data values to insert, so they can\n\t\t// be parameterized\n\t\tdata.forEach(function(obj) {\n\t\t\tObject.keys(obj).forEach(function(key) {\n\t\t\t\tvals.push(obj[key]);\n\t\t\t});\n\t\t});\n\n\t\t// Get the field names from the keys of the first\n\t\t// object inserted\n\t\ttable = d.quoteTable(table);\n\n\t\tsql += \"INSERT INTO \" + table + \" (\"\n\t\t\t+ d.quoteIdentifiers(fields).join(\",\")\n\t\t\t+ \") VALUES \";\n\n\t\t// Create placeholder groups\n\t\tparams = Array(fields.length).fill('?');\n\t\tparamString = \"(\" + params.join(',') + \")\";\n\t\tparamList = Array(data.length).fill(paramString);\n\n\t\tsql += paramList.join(',');\n\n\t\treturn {\n\t\t\tsql: sql,\n\t\t\tvalues: vals\n\t\t};\n\t}\n\n};\n\nmodule.exports = d;"],"sourceRoot":"/source/"}
\ No newline at end of file
diff --git a/lib/DriverClass.js b/lib/DriverClass.js
index 3029d7a..4401867 100644
--- a/lib/DriverClass.js
+++ b/lib/DriverClass.js
@@ -1,22 +1,18 @@
'use strict';
-var _DriverBase = require('./DriverBase');
+let driverBase = require('./DriverBase'),
+ getArgs = require('getargs');
-var _DriverBase2 = _interopRequireDefault(_DriverBase);
+module.exports = class DriverClass {
+ constructor(/* properties:object */) {
+ let args = getArgs('[properties]:object', arguments);
-function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+ args.properties = args.properties || {};
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-module.exports = function DriverClass() {
- var _this = this;
-
- var properties = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
-
- _classCallCheck(this, DriverClass);
-
- Object.keys(_DriverBase2.default).forEach(function (key) {
- _this[key] = Object.keys(properties).indexOf(key) !== -1 ? properties[key] : _DriverBase2.default[key];
- });
-};
-//# sourceMappingURL=DriverClass.js.map
+ Object.keys(driverBase).forEach(key => {
+ this[key] = (Object.keys(args.properties).indexOf(key) !== -1)
+ ? args.properties[key]
+ : driverBase[key];
+ });
+ }
+}
\ No newline at end of file
diff --git a/lib/DriverClass.js.map b/lib/DriverClass.js.map
deleted file mode 100644
index 278b095..0000000
--- a/lib/DriverClass.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"sources":["DriverClass.js"],"names":[],"mappings":"AAAA,YAAY,CAAC;;;;;;;;;;AAIb,MAAM,CAAC,OAAO,GACb,SADsB,WAAW,GACJ;;;KAAjB,UAAU,yDAAG,EAAE;;uBADL,WAAW;;AAEhC,OAAM,CAAC,IAAI,sBAAY,CAAC,OAAO,CAAC,UAAC,GAAG,EAAK;AACxC,QAAK,GAAG,CAAC,GAAG,AAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GACrD,UAAU,CAAC,GAAG,CAAC,GACf,qBAAW,GAAG,CAAC,CAAC;EACnB,CAAC,CAAC;CACH,AACD,CAAA","file":"DriverClass.js","sourcesContent":["'use strict';\n\nimport driverBase from './DriverBase';\n\nmodule.exports = class DriverClass {\n\tconstructor(properties = {}) {\n\t\tObject.keys(driverBase).forEach((key) => {\n\t\t\tthis[key] = (Object.keys(properties).indexOf(key) !== -1)\n\t\t\t\t? properties[key]\n\t\t\t\t: driverBase[key];\n\t\t});\n\t}\n}"],"sourceRoot":"/source/"}
\ No newline at end of file
diff --git a/lib/NodeQuery.js b/lib/NodeQuery.js
index 2531bd4..d49c8fc 100755
--- a/lib/NodeQuery.js
+++ b/lib/NodeQuery.js
@@ -1,103 +1,74 @@
"use strict";
-var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
-
-var _fs = require('fs');
-
-var _fs2 = _interopRequireDefault(_fs);
-
-var _helpers = require('./helpers');
-
-var _helpers2 = _interopRequireDefault(_helpers);
-
-var _QueryBuilder = require('./QueryBuilder');
-
-var _QueryBuilder2 = _interopRequireDefault(_QueryBuilder);
-
-function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-var instance = null;
+let instance = null;
+let fs = require('fs'),
+ helpers = require('./helpers'),
+ QueryBuilder = require('./QueryBuilder');
/**
* @module NodeQuery
*/
-
-var NodeQuery = (function () {
+class NodeQuery {
/**
- * Constructor
- */
-
- function NodeQuery() {
- _classCallCheck(this, NodeQuery);
-
+ * Constructor
+ *
+ * @return {void}
+ */
+ constructor() {
this.instance = null;
}
/**
- * Create a query builder object
- *
- * @memberOf NodeQuery
- * @param {String} drivername - The name of the database type, eg. mysql or pg
- * @param {Object} connObject - A connection object from the database library you are connecting with
- * @param {String} [connLib] - The name of the db connection library you are using, eg. mysql or mysql2. Optional if the same as drivername
- * @return {QueryBuilder}
- */
+ * Create a query builder object
+ *
+ * @memberOf NodeQuery
+ * @param {String} driverType - The name of the database type, eg. mysql or pg
+ * @param {Object} connObject - A connection object from the database library you are connecting with
+ * @param {String} [connLib] - The name of the db connection library you are using, eg. mysql or mysql2. Optional if the same as drivername
+ * @return {QueryBuilder} - The Query Builder object
+ */
+ init(driverType, connObject, connLib) {
+ connLib = connLib || driverType;
- _createClass(NodeQuery, [{
- key: 'init',
- value: function init(driverType, connObject, connLib) {
- connLib = connLib || driverType;
+ let paths = {
+ driver: `${__dirname}/drivers/` + helpers.upperCaseFirst(driverType),
+ adapter: `${__dirname}/adapters/${connLib}`
+ };
- var paths = {
- driver: __dirname + '/drivers/' + _helpers2.default.upperCaseFirst(driverType),
- adapter: __dirname + '/adapters/' + connLib
- };
-
- /*Object.keys(paths).forEach((type) => {
- if ( ! fs.existsSync(paths[type]))
- {
- console.log(paths[type]);
- throw new Error(
- `Selected ${type} (` +
- helpers.upperCaseFirst(driverType) +
- `) does not exist!`
- );
- }
- });*/
-
- var driver = require(paths.driver);
- var $adapter = require(paths.adapter);
- var adapter = new $adapter(connObject);
-
- this.instance = new _QueryBuilder2.default(driver, adapter);
-
- return this.instance;
- }
- }, {
- key: 'getQuery',
-
- /**
- * Return an existing query builder instance
- *
- * @memberOf NodeQuery
- * @return {QueryBuilder}
- */
- value: function getQuery() {
- if (!this.instance) {
- throw new Error("No Query Builder instance to return");
+ Object.keys(paths).forEach(type => {
+ if ( ! fs.existsSync(paths[type]))
+ {
+ throw new Error(
+ `Selected ${type} (` +
+ helpers.upperCaseFirst(driverType) +
+ `) does not exist!`
+ );
}
+ });
- return this.instance;
+ let driver = require(paths.driver);
+ let $adapter = require(paths.adapter);
+ let adapter = new $adapter(connObject);
+
+ this.instance = new QueryBuilder(driver, adapter);
+
+ return this.instance;
+ }
+
+ /**
+ * Return an existing query builder instance
+ *
+ * @return {QueryBuilder} - The Query Builder object
+ */
+ getQuery() {
+ if ( ! this.instance) {
+ throw new Error("No Query Builder instance to return");
}
- }]);
- return NodeQuery;
-})();
+ return this.instance;
+ }
-;
+}
-module.exports = new NodeQuery();
-//# sourceMappingURL=NodeQuery.js.map
+module.exports = new NodeQuery();
\ No newline at end of file
diff --git a/lib/NodeQuery.js.map b/lib/NodeQuery.js.map
deleted file mode 100644
index 00d5f09..0000000
--- a/lib/NodeQuery.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"sources":["NodeQuery.js"],"names":[],"mappings":"AAAA,YAAY,CAAC;;;;;;;;;;;;;;;;;;;;AAEb,IAAI,QAAQ,GAAG,IAAI,CAAC;;;;;;IAQd,SAAS;;;;;;AAKd,UALK,SAAS,GAKA;wBALT,SAAS;;AAMb,MAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;EACrB;;;;;;;;;;;AAAA;cAPI,SAAS;;uBAkBT,UAAU,EAAE,UAAU,EAAE,OAAO,EAAE;AACrC,UAAO,GAAG,OAAO,IAAI,UAAU,CAAC;;AAEhC,OAAI,KAAK,GAAG;AACX,UAAM,EAAE,AAAG,SAAS,iBAAc,kBAAQ,cAAc,CAAC,UAAU,CAAC;AACpE,WAAO,EAAK,SAAS,kBAAa,OAAO,AAAE;IAC3C;;;;;;;;;;;;;;AAAC,AAcF,OAAI,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;AACnC,OAAI,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;AACtC,OAAI,OAAO,GAAG,IAAI,QAAQ,CAAC,UAAU,CAAC,CAAC;;AAEvC,OAAI,CAAC,QAAQ,GAAG,2BAAiB,MAAM,EAAE,OAAO,CAAC,CAAC;;AAElD,UAAO,IAAI,CAAC,QAAQ,CAAC;GACrB;;;;;;;;;;6BAQU;AACV,OAAK,CAAE,IAAI,CAAC,QAAQ,EAAE;AACrB,UAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;IACvD;;AAED,UAAO,IAAI,CAAC,QAAQ,CAAC;GACrB;;;QA3DI,SAAS;;;AA6Dd,CAAC;;AAEF,MAAM,CAAC,OAAO,GAAG,IAAI,SAAS,EAAE,CAAC","file":"NodeQuery.js","sourcesContent":["\"use strict\";\n\nlet instance = null;\nimport fs from 'fs';\nimport helpers from './helpers';\nimport QueryBuilder from './QueryBuilder';\n\n/**\n * @module NodeQuery\n */\nclass NodeQuery {\n\n\t/**\n\t * Constructor\n\t */\n\tconstructor() {\n\t\tthis.instance = null;\n\t}\n\n\t/**\n\t * Create a query builder object\n\t *\n\t * @memberOf NodeQuery\n\t * @param {String} drivername - The name of the database type, eg. mysql or pg\n\t * @param {Object} connObject - A connection object from the database library you are connecting with\n\t * @param {String} [connLib] - The name of the db connection library you are using, eg. mysql or mysql2. Optional if the same as drivername\n\t * @return {QueryBuilder}\n\t */\n\tinit(driverType, connObject, connLib) {\n\t\tconnLib = connLib || driverType;\n\n\t\tlet paths = {\n\t\t\tdriver: `${__dirname}/drivers/` + helpers.upperCaseFirst(driverType),\n\t\t\tadapter: `${__dirname}/adapters/${connLib}`\n\t\t};\n\n\t\t/*Object.keys(paths).forEach((type) => {\n\t\t\tif ( ! fs.existsSync(paths[type]))\n\t\t\t{\n\t\t\t\tconsole.log(paths[type]);\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Selected ${type} (` +\n\t\t\t\t\thelpers.upperCaseFirst(driverType) +\n\t\t\t\t\t`) does not exist!`\n\t\t\t\t);\n\t\t\t}\n\t\t});*/\n\n\t\tlet driver = require(paths.driver);\n\t\tlet $adapter = require(paths.adapter);\n\t\tlet adapter = new $adapter(connObject);\n\n\t\tthis.instance = new QueryBuilder(driver, adapter);\n\n\t\treturn this.instance;\n\t};\n\n\t/**\n\t * Return an existing query builder instance\n\t *\n\t * @memberOf NodeQuery\n\t * @return {QueryBuilder}\n\t */\n\tgetQuery() {\n\t\tif ( ! this.instance) {\n\t\t\tthrow new Error(\"No Query Builder instance to return\");\n\t\t}\n\n\t\treturn this.instance;\n\t};\n\n};\n\nmodule.exports = new NodeQuery();"],"sourceRoot":"/source/"}
\ No newline at end of file
diff --git a/lib/QueryBuilder.js b/lib/QueryBuilder.js
index 3efc825..4c14a25 100755
--- a/lib/QueryBuilder.js
+++ b/lib/QueryBuilder.js
@@ -1,1063 +1,926 @@
-'use strict'
+'use strict';
/** @module QueryBuilder */
-;
+let getArgs = require('getargs'),
+ helpers = require('./helpers'),
+ State = require('./State'),
+ QueryParser = require('./QueryParser');
-var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
-
-var _getargs = require('getargs');
-
-var _getargs2 = _interopRequireDefault(_getargs);
-
-var _helpers = require('./helpers');
-
-var _helpers2 = _interopRequireDefault(_helpers);
-
-var _State = require('./State');
-
-var _State2 = _interopRequireDefault(_State);
-
-var _QueryParser = require('./QueryParser');
-
-var _QueryParser2 = _interopRequireDefault(_QueryParser);
-
-function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-module.exports = (function () {
+module.exports = class QueryBuilder {
/*
- * SQL generation object
- *
- * @param {driver} - The syntax driver for the database
- * @param {adapter} - The database module adapter for running queries
- * @returns {QueryBuilder}
- * @constructor
- */
-
- function QueryBuilder(driver, adapter) {
- _classCallCheck(this, QueryBuilder);
-
+ * SQL generation object
+ *
+ * @param {driver} - The syntax driver for the database
+ * @param {adapter} - The database module adapter for running queries
+ * @return {QueryBuilder} - The Query Builder object, for chaining
+ * @constructor
+ */
+ constructor(driver, adapter) {
this.driver = driver;
this.adapter = adapter;
- this.parser = new _QueryParser2.default(this.driver);
- this.state = new _State2.default();
+ this.parser = new QueryParser(this.driver);
+ this.state = new State();
}
/**
- * Complete the sql building based on the type provided
- *
- * @param {String} type
- * @param {String} table
- * @private
- * @return {String}
- */
+ * 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);
- _createClass(QueryBuilder, [{
- key: '_compile',
- value: function _compile(type, table) {
- var _this = this;
+ // Set each subClause
+ ['queryMap', 'groupString', 'orderString', 'havingMap'].forEach(clause => {
+ let param = this.state[clause];
- // Put together the basic query
- var sql = this._compileType(type, table);
-
- // Set each subClause
- ['queryMap', 'groupString', 'orderString', 'havingMap'].forEach(function (clause) {
- var param = _this.state[clause];
-
- if (!_helpers2.default.isScalar(param)) {
- Object.keys(param).forEach(function (part) {
- sql += param[part].conjunction + param[part].string;
- });
- } else {
- sql += param;
- }
- });
-
- // Append the limit, if it exists
- if (_helpers2.default.isNumber(this.state.limit)) {
- sql = this.driver.limit(sql, this.state.limit, this.state.offset);
- }
-
- return sql;
- }
- }, {
- key: '_compileType',
- value: function _compileType(type, table) {
- var sql = '';
-
- switch (type) {
- case "insert":
- var params = Array(this.state.setArrayKeys.length).fill('?');
-
- sql = 'INSERT INTO ' + table + ' (';
- sql += this.state.setArrayKeys.join(',');
- sql += ") VALUES (";
- sql += params.join(',') + ')';
- break;
-
- case "update":
- sql = 'UPDATE ' + table + ' SET ' + this.state.setString;
- break;
-
- case "delete":
- sql = 'DELETE FROM ' + table;
- break;
-
- default:
- sql = 'SELECT * FROM ' + this.state.fromString;
-
- // Set the select string
- if (this.state.selectString.length > 0) {
- // Replace the star with the selected fields
- sql = sql.replace('*', this.state.selectString);
- }
- break;
- }
-
- return sql;
- }
- }, {
- key: '_like',
- value: function _like(field, val, pos, like, conj) {
- field = this.driver.quoteIdentifiers(field);
-
- like = field + ' ' + like + ' ?';
-
- if (pos == 'before') {
- val = '%' + val;
- } else if (pos == 'after') {
- val = val + '%';
- } else {
- val = '%' + val + '%';
- }
-
- conj = this.state.queryMap.length < 1 ? ' WHERE ' : ' ' + conj + ' ';
- this._appendMap(conj, like, 'like');
-
- this.state.whereValues.push(val);
- }
-
- /**
- * Append a clause to the query map
- *
- * @param {String} conjunction
- * @param {String} string
- * @param {String} type
- * @return {void}
- */
-
- }, {
- key: '_appendMap',
- value: function _appendMap(conjunction, string, type) {
- this.state.queryMap.push({
- type: type,
- conjunction: conjunction,
- string: string
- });
- }
-
- /**
- * Handle key/value pairs in an object the same way as individual arguments,
- * when appending to state
- *
- * @private
- */
-
- }, {
- key: '_mixedSet',
- value: function _mixedSet() /* $letName, $valType, $key, [$val] */{
- var _this2 = this;
-
- var args = (0, _getargs2.default)('$letName:string, $valType:string, $key:object|string|number, [$val]', arguments);
-
- var obj = {};
-
- if (_helpers2.default.isScalar(args.$key) && !_helpers2.default.isUndefined(args.$val)) {
- // Convert key/val pair to a simple object
- obj[args.$key] = args.$val;
- } else if (_helpers2.default.isScalar(args.$key) && _helpers2.default.isUndefined(args.$val)) {
- // If just a string for the key, and no value, create a simple object with duplicate key/val
- obj[args.$key] = args.$key;
- } else {
- obj = args.$key;
- }
-
- Object.keys(obj).forEach(function (k) {
- // If a single value for the return
- if (['key', 'value'].indexOf(args.$valType) !== -1) {
- var pushVal = args.$valType === 'key' ? k : obj[k];
- _this2.state[args.$letName].push(pushVal);
- } else {
- _this2.state[args.$letName][k] = obj[k];
- }
- });
-
- return this.state[args.$letName];
- }
- }, {
- key: '_whereMixedSet',
- value: function _whereMixedSet() /*key, val*/{
- var args = (0, _getargs2.default)('key:string|object, [val]', arguments);
-
- this.state.whereMap = [];
- this.state.rawWhereValues = [];
-
- this._mixedSet('whereMap', 'both', args.key, args.val);
- this._mixedSet('rawWhereValues', 'value', args.key, args.val);
- }
- }, {
- key: '_fixConjunction',
- value: function _fixConjunction(conj) {
- var lastItem = this.state.queryMap[this.state.queryMap.length - 1];
- var conjunctionList = _helpers2.default.arrayPluck(this.state.queryMap, 'conjunction');
-
- if (this.state.queryMap.length === 0 || !_helpers2.default.regexInArray(conjunctionList, /^ ?WHERE/i)) {
- conj = " WHERE ";
- } else if (lastItem.type === 'groupStart') {
- conj = '';
- } else {
- conj = ' ' + conj + ' ';
- }
-
- return conj;
- }
- }, {
- key: '_where',
- value: function _where(key, val, defaultConj) {
- var _this3 = this;
-
- // Normalize key and value and insert into this.state.whereMap
- this._whereMixedSet(key, val);
-
- // Parse the where condition to account for operators,
- // functions, identifiers, and literal values
- this.state = this.parser.parseWhere(this.driver, this.state);
-
- this.state.whereMap.forEach(function (clause) {
- var conj = _this3._fixConjunction(defaultConj);
- _this3._appendMap(conj, clause, 'where');
- });
-
- this.state.whereMap = {};
- }
- }, {
- key: '_whereNull',
- value: function _whereNull(field, stmt, conj) {
- field = this.driver.quoteIdentifiers(field);
- var item = field + ' ' + stmt;
-
- this._appendMap(this._fixConjunction(conj), item, 'whereNull');
- }
- }, {
- key: '_having',
- value: function _having() /*key, val, conj*/{
- var _this4 = this;
-
- var args = (0, _getargs2.default)('key:string|object, [val]:string|number, [conj]:string', arguments);
- args.conj = args.conj || 'AND';
- args.val = args.val || null;
-
- // Normalize key/val and put in state.whereMap
- this._whereMixedSet(args.key, args.val);
-
- // Parse the having condition to account for operators,
- // functions, identifiers, and literal values
- this.state = this.parser.parseWhere(this.driver, this.state);
-
- this.state.whereMap.forEach(function (clause) {
- // Put in the having map
- _this4.state.havingMap.push({
- conjunction: _this4.state.havingMap.length > 0 ? ' ' + args.conj + ' ' : ' HAVING ',
- string: clause
+ if ( ! helpers.isScalar(param))
+ {
+ Object.keys(param).forEach(part => {
+ sql += param[part].conjunction + param[part].string;
});
- });
-
- // Clear the where Map
- this.state.whereMap = {};
- }
- }, {
- key: '_whereIn',
- value: function _whereIn() /*key, val, inClause, conj*/{
- var _this5 = this;
-
- var args = (0, _getargs2.default)('key:string, val:array, inClause:string, conj:string', arguments);
-
- args.key = this.driver.quoteIdentifiers(args.key);
- var params = new Array(args.val.length);
- params.fill('?');
-
- args.val.forEach(function (value) {
- _this5.state.whereValues.push(value);
- });
-
- args.conj = this.state.queryMap.length > 0 ? " " + args.conj + " " : ' WHERE ';
- var str = args.key + " " + args.inClause + " (" + params.join(',') + ") ";
-
- this._appendMap(args.conj, str, 'whereIn');
- }
- }, {
- key: '_run',
- value: function _run(type, table, callback, sql, vals) {
-
- if (!sql) {
- sql = this._compile(type, table);
}
-
- if (!vals) {
- vals = this.state.values.concat(this.state.whereValues);
+ else
+ {
+ sql += param;
}
+ });
- //console.log(this.state);
- //console.log(sql);
- //console.log(vals);
- //console.log(callback);
- //console.log('------------------------');
-
- // Reset the state so another query can be built
- this._resetState();
-
- // Pass the sql and values to the adapter to run on the database
- this.adapter.execute(sql, vals, callback);
- }
- }, {
- key: '_getCompile',
- value: function _getCompile(type, table, reset) {
- reset = reset || false;
-
- var sql = this._compile(type, table);
-
- if (reset) this._resetState();
-
- return sql;
- }
- }, {
- key: '_resetState',
- value: function _resetState() {
- this.state = new _State2.default();
+ // Append the limit, if it exists
+ if (helpers.isNumber(this.state.limit))
+ {
+ sql = this.driver.limit(sql, this.state.limit, this.state.offset);
}
- // ----------------------------------------------------------------------------
- // ! Miscellaneous Methods
- // ----------------------------------------------------------------------------
+ return sql;
+ }
- /**
- * Reset the object state for a new query
- *
- * @memberOf QueryBuilder
- * @return {void}
- */
+ _compileType(type, table) {
+ let sql = '';
- }, {
- key: 'resetQuery',
- value: function resetQuery() {
- this._resetState();
- }
+ switch(type) {
+ case "insert":
+ let params = Array(this.state.setArrayKeys.length).fill('?');
- /**
- * Returns the current class state for testing or other purposes
- *
- * @private
- * @return {Object}
- */
+ sql = `INSERT INTO ${table} (`;
+ sql += this.state.setArrayKeys.join(',');
+ sql += ") VALUES (";
+ sql += params.join(',') + ')';
+ break;
- }, {
- key: 'getState',
- value: function getState() {
- return this.state;
- }
+ case "update":
+ sql = `UPDATE ${table} SET ${this.state.setString}`;
+ break;
- /**
- * Closes the database connection for the current adapter
- *
- * @return {void}
- */
+ case "delete":
+ sql = `DELETE FROM ${table}`;
+ break;
- }, {
- key: 'end',
- value: function end() {
- this.adapter.close();
- }
+ default:
+ sql = `SELECT * FROM ${this.state.fromString}`;
- // ------------------------------------------------------------------------
- // ! Query Builder Methods
- // ------------------------------------------------------------------------
-
- /**
- * Specify rows to select in the query
- *
- * @memberOf QueryBuilder
- * @param {String|Array} fields - The fields to select from the current table
- * @return {QueryBuilder}
- */
-
- }, {
- key: 'select',
- value: function select(fields) {
-
- // Split/trim fields by comma
- fields = Array.isArray(fields) ? fields : fields.split(",").map(_helpers2.default.stringTrim);
-
- // Split on 'As'
- fields.forEach(function (field, index) {
- if (field.match(/as/i)) {
- fields[index] = field.split(/ as /i).map(_helpers2.default.stringTrim);
+ // Set the select string
+ if (this.state.selectString.length > 0)
+ {
+ // Replace the star with the selected fields
+ sql = sql.replace('*', this.state.selectString);
}
+ break;
+ }
+
+ return sql;
+ }
+
+ _like(field, val, pos, like, conj) {
+ field = this.driver.quoteIdentifiers(field);
+
+ like = `${field} ${like} ?`;
+
+ if (pos == 'before')
+ {
+ val = `%${val}`;
+ }
+ else if (pos == 'after')
+ {
+ val = `${val}%`;
+ }
+ else
+ {
+ val = `%${val}%`;
+ }
+
+ conj = (this.state.queryMap.length < 1) ? ' WHERE ' : ` ${conj} `;
+ this._appendMap(conj, like, 'like');
+
+ this.state.whereValues.push(val);
+ }
+
+ /**
+ * Append a clause to the query map
+ *
+ * @private
+ * @param {String} conjunction - linking keyword for the clause
+ * @param {String} string - pre-compiled sql fragment
+ * @param {String} type - type of sql clause
+ * @return {void}
+ */
+ _appendMap(conjunction, string, type) {
+ this.state.queryMap.push({
+ type: type,
+ conjunction: conjunction,
+ string: string
+ });
+ }
+
+ /**
+ * Handle key/value pairs in an object the same way as individual arguments,
+ * when appending to state
+ *
+ * @private
+ * @return {Array} - modified state array
+ */
+ _mixedSet(/* $letName, $valType, $key, [$val] */) {
+ let args = getArgs('$letName:string, $valType:string, $key:object|string|number, [$val]', arguments);
+
+ let obj = {};
+
+
+ if (helpers.isScalar(args.$key) && !helpers.isUndefined(args.$val))
+ {
+ // Convert key/val pair to a simple object
+ obj[args.$key] = args.$val;
+ }
+ else if (helpers.isScalar(args.$key) && helpers.isUndefined(args.$val))
+ {
+ // If just a string for the key, and no value, create a simple object with duplicate key/val
+ obj[args.$key] = args.$key;
+ }
+ else
+ {
+ obj = args.$key;
+ }
+
+ Object.keys(obj).forEach(k => {
+ // If a single value for the return
+ if (['key','value'].indexOf(args.$valType) !== -1)
+ {
+ let pushVal = (args.$valType === 'key') ? k : obj[k];
+ this.state[args.$letName].push(pushVal);
+ }
+ else
+ {
+ this.state[args.$letName][k] = obj[k];
+ }
+ });
+
+
+ return this.state[args.$letName];
+ }
+
+ _whereMixedSet(/*key, val*/) {
+ let args = getArgs('key:string|object, [val]', arguments);
+
+ this.state.whereMap = [];
+ this.state.rawWhereValues = [];
+
+ this._mixedSet('whereMap', 'both', args.key, args.val);
+ this._mixedSet('rawWhereValues', 'value', args.key, args.val);
+ }
+
+ _fixConjunction(conj) {
+ let lastItem = this.state.queryMap[this.state.queryMap.length - 1];
+ let conjunctionList = helpers.arrayPluck(this.state.queryMap, 'conjunction');
+
+ if (this.state.queryMap.length === 0 || ( ! helpers.regexInArray(conjunctionList, /^ ?WHERE/i)))
+ {
+ conj = " WHERE ";
+ }
+ else if (lastItem.type === 'groupStart')
+ {
+ conj = '';
+ }
+ else
+ {
+ conj = ' ' + conj + ' ';
+ }
+
+ return conj;
+ }
+
+ _where(key, val, defaultConj) {
+ // Normalize key and value and insert into this.state.whereMap
+ this._whereMixedSet(key, val);
+
+ // Parse the where condition to account for operators,
+ // functions, identifiers, and literal values
+ this.state = this.parser.parseWhere(this.driver, this.state);
+
+ this.state.whereMap.forEach(clause => {
+ let conj = this._fixConjunction(defaultConj);
+ this._appendMap(conj, clause, 'where');
+ });
+
+ this.state.whereMap = {};
+ }
+
+ _whereNull(field, stmt, conj) {
+ field = this.driver.quoteIdentifiers(field);
+ let item = field + ' ' + stmt;
+
+ this._appendMap(this._fixConjunction(conj), item, 'whereNull');
+ }
+
+ _having(/*key, val, conj*/) {
+ let args = getArgs('key:string|object, [val]:string|number, [conj]:string', arguments);
+ args.conj = args.conj || 'AND';
+ args.val = args.val || null;
+
+ // Normalize key/val and put in state.whereMap
+ this._whereMixedSet(args.key, args.val);
+
+ // Parse the having condition to account for operators,
+ // functions, identifiers, and literal values
+ this.state = this.parser.parseWhere(this.driver, this.state);
+
+ this.state.whereMap.forEach(clause => {
+ // Put in the having map
+ this.state.havingMap.push({
+ conjunction: (this.state.havingMap.length > 0) ? ` ${args.conj} ` : ' HAVING ',
+ string: clause
});
+ });
- var safeArray = this.driver.quoteIdentifiers(fields);
+ // Clear the where Map
+ this.state.whereMap = {};
+ }
+ _whereIn(/*key, val, inClause, conj*/) {
+ let args = getArgs('key:string, val:array, inClause:string, conj:string', arguments);
- // Join the strings back together
- safeArray.forEach(function (field, index) {
- if (Array.isArray(field)) {
- safeArray[index] = safeArray[index].join(' AS ');
- }
- });
+ args.key = this.driver.quoteIdentifiers(args.key);
+ let params = new Array(args.val.length);
+ params.fill('?');
- this.state.selectString += safeArray.join(', ');
+ args.val.forEach(value => {
+ this.state.whereValues.push(value);
+ });
- return this;
+ args.conj = (this.state.queryMap.length > 0) ? " " + args.conj + " " : ' WHERE ';
+ let str = args.key + " " + args.inClause + " (" + params.join(',') + ") ";
+
+ this._appendMap(args.conj, str, 'whereIn');
+ }
+
+ _run(type, table, callback, sql, vals) {
+
+ if ( ! sql)
+ {
+ sql = this._compile(type, table);
}
- /**
- * Specify the database table to select from
- *
- * @param {String} tableName - The table to use for the current query
- * @return {QueryBuilder}
- */
-
- }, {
- key: 'from',
- value: function from(tableName) {
- // Split identifiers on spaces
- var identArray = tableName.trim().split(' ').map(_helpers2.default.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;
+ if ( ! vals)
+ {
+ vals = this.state.values.concat(this.state.whereValues);
}
- /**
- * 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}
- */
+//console.log(this.state);
+//console.log(sql);
+//console.log(vals);
+//console.log(callback);
+//console.log('------------------------');
- }, {
- key: 'like',
- value: function like(field, val, pos) {
- this._like(field, val, pos, ' LIKE ', 'AND');
- return this;
- }
+ // Reset the state so another query can be built
+ this._resetState();
- /**
- * 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}
- */
+ // Pass the sql and values to the adapter to run on the database
+ this.adapter.execute(sql, vals, callback);
- }, {
- key: 'notLike',
- value: function 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}
- */
+ _getCompile(type, table, reset) {
+ reset = reset || false;
- }, {
- key: 'orLike',
- value: function orLike(field, val, pos) {
- this._like(field, val, pos, ' LIKE ', 'OR');
- return this;
- }
+ let sql = this._compile(type, table);
- /**
- * 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}
- */
+ if (reset) this._resetState();
- }, {
- key: 'orNotLike',
- value: function orNotLike(field, val, pos) {
- this._like(field, val, pos, ' NOT LIKE ', 'OR');
- return this;
- }
+ return sql;
+ }
- /**
- * 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}
- */
+ _resetState() {
+ this.state = new State();
+ }
- }, {
- key: 'having',
- value: function having() /*key, [val]*/{
- var args = (0, _getargs2.default)('key:string|object, [val]:string|number', arguments);
+ // ----------------------------------------------------------------------------
+ // ! Miscellaneous Methods
+ // ----------------------------------------------------------------------------
- this._having(args.key, args.val, 'AND');
- return this;
- }
+ /**
+ * Reset the object state for a new query
+ *
+ * @memberOf QueryBuilder
+ * @return {void}
+ */
+ resetQuery() {
+ this._resetState();
+ }
- /**
- * 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}
- */
+ /**
+ * Returns the current class state for testing or other purposes
+ *
+ * @private
+ * @return {Object} - The State object
+ */
+ getState() {
+ return this.state;
+ }
- }, {
- key: 'orHaving',
- value: function orHaving() /*key, [val]*/{
- var args = (0, _getargs2.default)('key:string|object, [val]:string|number', arguments);
+ /**
+ * Closes the database connection for the current adapter
+ *
+ * @return {void}
+ */
+ end() {
+ this.adapter.close();
+ }
- this._having(args.key, args.val, 'OR');
- return this;
- }
+ // ------------------------------------------------------------------------
+ // ! Query Builder Methods
+ // ------------------------------------------------------------------------
- /**
- * 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}
- */
+ /**
+ * Specify rows to select in the query
+ *
+ * @memberOf QueryBuilder
+ * @param {String|Array} fields - The fields to select from the current table
+ * @return {QueryBuilder} - The Query Builder object, for chaining
+ */
+ select(fields) {
- }, {
- key: 'where',
- value: function where(key, val) {
- this._where(key, val, 'AND');
- return this;
- }
+ // Split/trim fields by comma
+ fields = (Array.isArray(fields))
+ ? fields
+ : fields.split(",").map(helpers.stringTrim);
- /**
- * 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}
- */
-
- }, {
- key: 'orWhere',
- value: function 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}
- */
-
- }, {
- key: 'whereIsNull',
- value: function whereIsNull(field) {
- this._whereNull(field, 'IS NULL', 'AND');
- return this;
- }
-
- /**
- * Specify that a field IS NOT NULL
- *
- * @param {String} field
- * @return {QueryBuilder}
- */
-
- }, {
- key: 'whereIsNotNull',
- value: function whereIsNotNull(field) {
- this._whereNull(field, 'IS NOT NULL', 'AND');
- return this;
- }
-
- /**
- * Field is null prefixed with 'OR'
- *
- * @param {String} field
- * @return {QueryBuilder}
- */
-
- }, {
- key: 'orWhereIsNull',
- value: function orWhereIsNull(field) {
- this._whereNull(field, 'IS NULL', 'OR');
- return this;
- }
-
- /**
- * Field is not null prefixed with 'OR'
- *
- * @param {String} field
- * @return {QueryBuilder}
- */
-
- }, {
- key: 'orWhereIsNotNull',
- value: function orWhereIsNotNull(field) {
- this._whereNull(field, 'IS NOT NULL', 'OR');
- return this;
- }
-
- /**
- * Set a 'where in' clause
- *
- * @param {String} key - the field to search
- * @param {Array} val - the array of items to search in
- * @return {QueryBuilder}
- */
-
- }, {
- key: 'whereIn',
- value: function whereIn(key, val) {
- this._whereIn(key, val, 'IN', 'AND');
- return this;
- }
-
- /**
- * Set a 'or where in' clause
- *
- * @param {String} key - the field to search
- * @param {Array} val - the array of items to search in
- * @return {QueryBuilder}
- */
-
- }, {
- key: 'orWhereIn',
- value: function orWhereIn(key, val) {
- this._whereIn(key, val, 'IN', 'OR');
- return this;
- }
-
- /**
- * Set a 'where not in' clause
- *
- * @param {String} key - the field to search
- * @param {Array} val - the array of items to search in
- * @return {QueryBuilder}
- */
-
- }, {
- key: 'whereNotIn',
- value: function whereNotIn(key, val) {
- this._whereIn(key, val, 'NOT IN', 'AND');
- return this;
- }
-
- /**
- * Set a 'or where not in' clause
- *
- * @param {String} key - the field to search
- * @param {Array} val - the array of items to search in
- * @return {QueryBuilder}
- */
-
- }, {
- key: 'orWhereNotIn',
- value: function orWhereNotIn(key, val) {
- this._whereIn(key, val, 'NOT IN', 'OR');
- return this;
- }
-
- /**
- * Set values for insertion or updating
- *
- * @param {String|Object} key - The key or object to use
- * @param {String} [val] - The value if using a scalar key
- * @return {QueryBuilder}
- */
-
- }, {
- key: 'set',
- value: function set() /* $key, [$val] */{
- var args = (0, _getargs2.default)('$key, [$val]', arguments);
-
- // Set the appropriate state variables
- this._mixedSet('setArrayKeys', 'key', args.$key, args.$val);
- this._mixedSet('values', 'value', args.$key, args.$val);
-
- // Use the keys of the array to make the insert/update string
- // and escape the field names
- this.state.setArrayKeys = this.state.setArrayKeys.map(this.driver._quote);
-
- // Generate the "set" string
- this.state.setString = this.state.setArrayKeys.join('=?,');
- this.state.setString += '=?';
-
- return this;
- }
-
- /**
- * Add a join clause to the query
- *
- * @param {String} table - The table you are joining
- * @param {String} cond - The join condition.
- * @param {String} [type='inner'] - The type of join, which defaults to inner
- * @return {QueryBuilder}
- */
-
- }, {
- key: 'join',
- value: function join(table, cond, type) {
- type = type || "inner";
-
- // Prefix/quote table name
- table = table.split(' ').map(_helpers2.default.stringTrim);
- table[0] = this.driver.quoteTable(table[0]);
- table = table.map(this.driver.quoteIdentifiers);
- table = table.join(' ');
-
- // Parse out the join condition
- var parsedCondition = this.parser.compileJoin(cond);
- var condition = table + ' ON ' + parsedCondition;
-
- // Append the join condition to the query map
- this._appendMap("\n" + type.toUpperCase() + ' JOIN ', condition, 'join');
-
- return this;
- }
-
- /**
- * Group the results by the selected field(s)
- *
- * @param {String|Array} field
- * @return {QueryBuilder}
- */
-
- }, {
- key: 'groupBy',
- value: function groupBy(field) {
- if (!_helpers2.default.isScalar(field)) {
- var newGroupArray = field.map(this.driver.quoteIdentifiers);
- this.state.groupArray = this.state.groupArray.concat(newGroupArray);
- } else {
- this.state.groupArray.push(this.driver.quoteIdentifiers(field));
+ // Split on 'As'
+ fields.forEach((field, index) => {
+ if (field.match(/as/i))
+ {
+ fields[index] = field.split(/ as /i).map(helpers.stringTrim);
}
+ });
- this.state.groupString = ' GROUP BY ' + this.state.groupArray.join(',');
+ let safeArray = this.driver.quoteIdentifiers(fields);
- 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}
- */
-
- }, {
- key: 'orderBy',
- value: function orderBy(field, type) {
- var _this6 = this;
-
- type = type || 'ASC';
-
- // Set the fields for later manipulation
- field = this.driver.quoteIdentifiers(field);
-
- this.state.orderArray[field] = type;
-
- var orderClauses = [];
-
- // Flatten key/val pairs into an array of space-separated pairs
- Object.keys(this.state.orderArray).forEach(function (key) {
- orderClauses.push(key + ' ' + _this6.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}
- */
-
- }, {
- key: 'limit',
- value: function 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}
- */
-
- }, {
- key: 'groupStart',
- value: function groupStart() {
- var conj = this.state.queryMap.length < 1 ? ' WHERE ' : ' AND ';
- this._appendMap(conj, '(', 'groupStart');
-
- return this;
- }
-
- /**
- * Adds an open paren to the current query for logical grouping,
- * prefixed with 'OR'
- *
- * @return {QueryBuilder}
- */
-
- }, {
- key: 'orGroupStart',
- value: function orGroupStart() {
- this._appendMap('', ' OR (', 'groupStart');
-
- return this;
- }
-
- /**
- * Adds an open paren to the current query for logical grouping,
- * prefixed with 'OR NOT'
- *
- * @return {QueryBuilder}
- */
-
- }, {
- key: 'orNotGroupStart',
- value: function orNotGroupStart() {
- this._appendMap('', ' OR NOT (', 'groupStart');
-
- return this;
- }
-
- /**
- * Ends a logical grouping started with one of the groupStart methods
- *
- * @return {QueryBuilder}
- */
-
- }, {
- key: 'groupEnd',
- value: function groupEnd() {
- this._appendMap('', ')', 'groupEnd');
-
- return this;
- }
-
- // ------------------------------------------------------------------------
- // ! Result Methods
- // ------------------------------------------------------------------------
-
- /**
- * Get the results of the compiled query
- *
- * @param {String} [table] - The table to select from
- * @param {Number} [limit] - A limit for the query
- * @param {Number} [offset] - An offset for the query
- * @param {Function} callback - A callback for receiving the result
- * @return {void}
- */
-
- }, {
- key: 'get',
- value: function get() /* [table], [limit], [offset], callback */{
- var args = (0, _getargs2.default)('[table]:string, [limit]:number, [offset]:number, callback:function', arguments);
-
- if (args.table) {
- this.from(args.table);
+ // Join the strings back together
+ safeArray.forEach((field, index) => {
+ if (Array.isArray(field))
+ {
+ safeArray[index] = safeArray[index].join(' AS ');
}
+ });
- if (args.limit) {
- this.limit(args.limit, args.offset);
- }
+ this.state.selectString += safeArray.join(', ');
- // Run the query
- this._run('get', args.table, args.callback);
+ return this;
+ }
+
+ /**
+ * Specify the database table to select from
+ *
+ * @param {String} tableName - The table to use for the current query
+ * @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]*/) {
+ let args = getArgs('key:string|object, [val]:string|number', arguments);
+
+ this._having(args.key, args.val, 'AND');
+ return this;
+ }
+
+ /**
+ * Add an 'or having' clause
+ *
+ * @param {String|Object} key - The name of the field and the comparision operator, or an object
+ * @param {String|Number} [val] - The value to compare if the value of key is a string
+ * @return {QueryBuilder} - The Query Builder object, for chaining
+ */
+ orHaving(/*key, [val]*/) {
+ let args = getArgs('key:string|object, [val]:string|number', arguments);
+
+ this._having(args.key, args.val, 'OR');
+ return this;
+ }
+
+ /**
+ * Set a 'where' clause
+ *
+ * @param {String|Object} key - The name of the field and the comparision operator, or an object
+ * @param {String|Number} [val] - The value to compare if the value of key is a string
+ * @return {QueryBuilder} - 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} val - the array of items to search in
+ * @return {QueryBuilder} - The Query Builder object, for chaining
+ */
+ whereIn(key, val) {
+ this._whereIn(key, val, 'IN', 'AND');
+ return this;
+ }
+
+ /**
+ * Set a 'or where in' clause
+ *
+ * @param {String} key - the field to search
+ * @param {Array} val - the array of items to search in
+ * @return {QueryBuilder} - The Query Builder object, for chaining
+ */
+ orWhereIn(key, val) {
+ this._whereIn(key, val, 'IN', 'OR');
+ return this;
+ }
+
+ /**
+ * Set a 'where not in' clause
+ *
+ * @param {String} key - the field to search
+ * @param {Array} val - the array of items to search in
+ * @return {QueryBuilder} - The Query Builder object, for chaining
+ */
+ whereNotIn(key, val) {
+ this._whereIn(key, val, 'NOT IN', 'AND');
+ return this;
+ }
+
+ /**
+ * Set a 'or where not in' clause
+ *
+ * @param {String} key - the field to search
+ * @param {Array} val - the array of items to search in
+ * @return {QueryBuilder} - The Query Builder object, for chaining
+ */
+ orWhereNotIn(key, val) {
+ this._whereIn(key, val, 'NOT IN', 'OR');
+ return this;
+ }
+
+ /**
+ * Set values for insertion or updating
+ *
+ * @param {String|Object} key - The key or object to use
+ * @param {String} [val] - The value if using a scalar key
+ * @return {QueryBuilder} - The Query Builder object, for chaining
+ */
+ set(/* $key, [$val] */) {
+ let args = getArgs('$key, [$val]', arguments);
+
+ // Set the appropriate state variables
+ this._mixedSet('setArrayKeys', 'key', args.$key, args.$val);
+ this._mixedSet('values', 'value', args.$key, args.$val);
+
+ // Use the keys of the array to make the insert/update string
+ // and escape the field names
+ this.state.setArrayKeys = this.state.setArrayKeys.map(this.driver._quote);
+
+ // Generate the "set" string
+ this.state.setString = this.state.setArrayKeys.join('=?,');
+ this.state.setString += '=?';
+
+ return this;
+ }
+
+ /**
+ * Add a join clause to the query
+ *
+ * @param {String} table - The table you are joining
+ * @param {String} cond - The join condition.
+ * @param {String} [type='inner'] - The type of join, which defaults to inner
+ * @return {QueryBuilder} - 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
+ let parsedCondition = this.parser.compileJoin(cond);
+ let condition = table + ' ON ' + parsedCondition;
+
+ // Append the join condition to the query map
+ this._appendMap("\n" + type.toUpperCase() + ' JOIN ', condition, 'join');
+
+ return this;
+ }
+
+ /**
+ * Group the results by the selected field(s)
+ *
+ * @param {String|Array} field - The name of the field to group by
+ * @return {QueryBuilder} - The Query Builder object, for chaining
+ */
+ groupBy(field) {
+ if ( ! helpers.isScalar(field))
+ {
+ let newGroupArray = field.map(this.driver.quoteIdentifiers);
+ this.state.groupArray = this.state.groupArray.concat(newGroupArray);
+ }
+ else
+ {
+ this.state.groupArray.push(this.driver.quoteIdentifiers(field));
}
- /**
- * Run the generated insert query
- *
- * @param {String} table - The table to insert into
- * @param {Object} [data] - Data to insert, if not already added with the 'set' method
- * @param {Function} callback - Callback for handling response from the database
- * @return {void}
- */
+ this.state.groupString = ' GROUP BY ' + this.state.groupArray.join(',');
- }, {
- key: 'insert',
- value: function insert() /* table, data, callback */{
- var args = (0, _getargs2.default)('table:string, [data]:object, callback:function', arguments);
+ return this;
+ }
- if (args.data) {
- this.set(args.data);
- }
+ /**
+ * 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';
- // Run the query
- this._run('insert', this.driver.quoteTable(args.table), args.callback);
+ // Set the fields for later manipulation
+ field = this.driver.quoteIdentifiers(field);
+
+ this.state.orderArray[field] = type;
+
+ let orderClauses = [];
+
+ // Flatten key/val pairs into an array of space-separated pairs
+ Object.keys(this.state.orderArray).forEach(key => {
+ orderClauses.push(key + ' ' + this.state.orderArray[key].toUpperCase());
+ });
+
+ // Set the final string
+ this.state.orderString = ' ORDER BY ' + orderClauses.join(', ');
+
+ return this;
+ }
+
+ /**
+ * Put a limit on the query
+ *
+ * @param {Number} limit - The maximum number of rows to fetch
+ * @param {Number} [offset] - The row number to start from
+ * @return {QueryBuilder} - 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() {
+ let conj = (this.state.queryMap.length < 1) ? ' WHERE ' : ' AND ';
+ this._appendMap(conj, '(', 'groupStart');
+
+ return this;
+ }
+
+ /**
+ * Adds an open paren to the current query for logical grouping,
+ * prefixed with 'OR'
+ *
+ * @return {QueryBuilder} - 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
+ * @param {Function} callback - A callback for receiving the result
+ * @return {void}
+ */
+ get(/* [table], [limit], [offset], callback */) {
+ let args = getArgs('[table]:string, [limit]:number, [offset]:number, callback:function', arguments);
+
+ if (args.table) {
+ this.from(args.table);
}
- /**
- * Insert multiple sets of rows at a time
- *
- * @param {String} table - The table to insert into
- * @param {Array} data - The array of objects containing data rows to insert
- * @param {Function} callback - Callback for handling database response
- * @example query.insertBatch('foo',[{id:1,val:'bar'},{id:2,val:'baz'}], callbackFunction);
- * @return {void}
- */
-
- }, {
- key: 'insertBatch',
- value: function insertBatch() /* table, data, callback */{
- var args = (0, _getargs2.default)('table:string, data:array, callback:function', arguments);
- var batch = this.driver.insertBatch(args.table, args.data);
-
- // Run the query
- this._run('', '', args.callback, batch.sql, batch.values);
+ if (args.limit) {
+ this.limit(args.limit, args.offset);
}
- /**
- * Run the generated update query
- *
- * @param {String} table - The table to insert into
- * @param {Object} [data] - Data to insert, if not already added with the 'set' method
- * @param {Function} callback - Callback for handling response from the database
- * @return {void}
- */
+ // Run the query
+ this._run('get', args.table, args.callback);
+ }
- }, {
- key: 'update',
- value: function update() /*table, data, callback*/{
- var args = (0, _getargs2.default)('table:string, [data]:object, callback:function', arguments);
+ /**
+ * Run the generated insert query
+ *
+ * @param {String} table - The table to insert into
+ * @param {Object} [data] - Data to insert, if not already added with the 'set' method
+ * @param {Function} callback - Callback for handling response from the database
+ * @return {void}
+ */
+ insert(/* table, data, callback */) {
+ let args = getArgs('table:string, [data]:object, callback:function', arguments);
- if (args.data) {
- this.set(args.data);
- }
-
- // Run the query
- this._run('update', this.driver.quoteTable(args.table), args.callback);
+ if (args.data) {
+ this.set(args.data);
}
- /**
- * Run the generated delete query
- *
- * @param {String} table - The table to insert into
- * @param {Object} [where] - Where clause for delete statement
- * @param {Function} callback - Callback for handling response from the database
- * @return {void}
- */
+ // Run the query
+ this._run('insert', this.driver.quoteTable(args.table), args.callback);
+ }
- }, {
- key: 'delete',
- value: function _delete() /*table, [where], callback*/{
- var args = (0, _getargs2.default)('table:string, [where]:object, callback:function', arguments);
+ /**
+ * Insert multiple sets of rows at a time
+ *
+ * @param {String} table - The table to insert into
+ * @param {Array} data - The array of objects containing data rows to insert
+ * @param {Function} callback - Callback for handling database response
+ * @example query.insertBatch('foo',[{id:1,val:'bar'},{id:2,val:'baz'}], callbackFunction);
+ * @return {void}
+ */
+ insertBatch(/* table, data, callback */) {
+ let args = getArgs('table:string, data:array, callback:function', arguments);
+ let batch = this.driver.insertBatch(args.table, args.data);
- if (args.where) {
- this.where(args.where);
- }
+ // Run the query
+ this._run('', '', args.callback, batch.sql, batch.values);
+ }
- // Run the query
- this._run('delete', this.driver.quoteTable(args.table), args.callback);
+ /**
+ * Run the generated update query
+ *
+ * @param {String} table - The table to insert into
+ * @param {Object} [data] - Data to insert, if not already added with the 'set' method
+ * @param {Function} callback - Callback for handling response from the database
+ * @return {void}
+ */
+ update(/*table, data, callback*/) {
+ let args = getArgs('table:string, [data]:object, callback:function', arguments);
+
+ if (args.data) {
+ this.set(args.data);
}
- // ------------------------------------------------------------------------
- // ! Methods returning SQL
- // ------------------------------------------------------------------------
+ // Run the query
+ this._run('update', this.driver.quoteTable(args.table), args.callback);
+ }
- /**
- * 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}
- */
+ /**
+ * Run the generated delete query
+ *
+ * @param {String} table - The table to insert into
+ * @param {Object} [where] - Where clause for delete statement
+ * @param {Function} callback - Callback for handling response from the database
+ * @return {void}
+ */
+ delete(/*table, [where], callback*/) {
+ let args = getArgs('table:string, [where]:object, callback:function', arguments);
- }, {
- key: 'getCompiledSelect',
- value: function getCompiledSelect() /*table, reset*/{
- var args = (0, _getargs2.default)('[table]:string, [reset]:boolean', arguments);
- if (args.table) {
- this.from(args.table);
- }
-
- return this._getCompile('get', args.table, args.reset);
+ if (args.where)
+ {
+ this.where(args.where);
}
- /**
- * 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}
- */
+ // Run the query
+ this._run('delete', this.driver.quoteTable(args.table), args.callback);
+ }
- }, {
- key: 'getCompiledInsert',
- value: function getCompiledInsert(table, reset) {
- return this._getCompile('insert', this.driver.quoteTable(table), reset);
+ // ------------------------------------------------------------------------
+ // ! 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*/) {
+ let args = getArgs('[table]:string, [reset]:boolean', arguments);
+ if (args.table)
+ {
+ this.from(args.table);
}
- /**
- * 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}
- */
+ return this._getCompile('get', args.table, args.reset);
+ }
- }, {
- key: 'getCompiledUpdate',
- value: function getCompiledUpdate(table, reset) {
- return this._getCompile('update', this.driver.quoteTable(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) {
+ return this._getCompile('insert', 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}
- */
+ /**
+ * 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) {
+ return this._getCompile('update', this.driver.quoteTable(table), reset);
+ }
- }, {
- key: 'getCompiledDelete',
- value: function getCompiledDelete(table, reset) {
- return this._getCompile('delete', this.driver.quoteTable(table), reset);
- }
- }]);
-
- return QueryBuilder;
-})();
-//# sourceMappingURL=QueryBuilder.js.map
+ /**
+ * 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) {
+ return this._getCompile('delete', this.driver.quoteTable(table), reset);
+ }
+}
\ No newline at end of file
diff --git a/lib/QueryBuilder.js.map b/lib/QueryBuilder.js.map
deleted file mode 100644
index b9903ee..0000000
--- a/lib/QueryBuilder.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"sources":["QueryBuilder.js"],"names":[],"mappings":"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","file":"QueryBuilder.js","sourcesContent":["'use strict';\n\n/** @module QueryBuilder */\nimport getArgs from 'getargs';\nimport helpers from './helpers';\nimport State from './State';\nimport QueryParser from './QueryParser';\n\nmodule.exports = class QueryBuilder {\n\t/*\n\t * SQL generation object\n\t *\n\t * @param {driver} - The syntax driver for the database\n\t * @param {adapter} - The database module adapter for running queries\n\t * @returns {QueryBuilder}\n\t * @constructor\n\t */\n\tconstructor(driver, adapter) {\n\t\tthis.driver = driver;\n\t\tthis.adapter = adapter;\n\t\tthis.parser = new QueryParser(this.driver);\n\t\tthis.state = new State();\n\t}\n\n\t/**\n\t * Complete the sql building based on the type provided\n\t *\n\t * @param {String} type\n\t * @param {String} table\n\t * @private\n\t * @return {String}\n\t */\n\t_compile(type, table) {\n\t\t// Put together the basic query\n\t\tlet sql = this._compileType(type, table);\n\n\t\t// Set each subClause\n\t\t['queryMap', 'groupString', 'orderString', 'havingMap'].forEach((clause) => {\n\t\t\tlet param = this.state[clause];\n\n\t\t\tif ( ! helpers.isScalar(param))\n\t\t\t{\n\t\t\t\tObject.keys(param).forEach((part) => {\n\t\t\t\t\tsql += param[part].conjunction + param[part].string;\n\t\t\t\t});\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tsql += param;\n\t\t\t}\n\t\t});\n\n\t\t// Append the limit, if it exists\n\t\tif (helpers.isNumber(this.state.limit))\n\t\t{\n\t\t\tsql = this.driver.limit(sql, this.state.limit, this.state.offset);\n\t\t}\n\n\t\treturn sql;\n\t}\n\n\t_compileType(type, table) {\n\t\tlet sql = '';\n\n\t\tswitch(type) {\n\t\t\tcase \"insert\":\n\t\t\t\tlet params = Array(this.state.setArrayKeys.length).fill('?');\n\n\t\t\t\tsql = `INSERT INTO ${table} (`;\n\t\t\t\tsql += this.state.setArrayKeys.join(',');\n\t\t\t\tsql += \") VALUES (\";\n\t\t\t\tsql += params.join(',') + ')';\n\t\t\tbreak;\n\n\t\t\tcase \"update\":\n\t\t\t\tsql = `UPDATE ${table} SET ${this.state.setString}`;\n\t\t\tbreak;\n\n\t\t\tcase \"delete\":\n\t\t\t\tsql = `DELETE FROM ${table}`;\n\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tsql = `SELECT * FROM ${this.state.fromString}`;\n\n\t\t\t\t// Set the select string\n\t\t\t\tif (this.state.selectString.length > 0)\n\t\t\t\t{\n\t\t\t\t\t// Replace the star with the selected fields\n\t\t\t\t\tsql = sql.replace('*', this.state.selectString);\n\t\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\treturn sql;\n\t}\n\n\t_like(field, val, pos, like, conj) {\n\t\tfield = this.driver.quoteIdentifiers(field);\n\n\t\tlike = `${field} ${like} ?`;\n\n\t\tif (pos == 'before')\n\t\t{\n\t\t\tval = `%${val}`;\n\t\t}\n\t\telse if (pos == 'after')\n\t\t{\n\t\t\tval = `${val}%`;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tval = `%${val}%`;\n\t\t}\n\n\t\tconj = (this.state.queryMap.length < 1) ? ' WHERE ' : ` ${conj} `;\n\t\tthis._appendMap(conj, like, 'like');\n\n\t\tthis.state.whereValues.push(val);\n\t}\n\n\t/**\n\t * Append a clause to the query map\n\t *\n\t * @param {String} conjunction\n\t * @param {String} string\n\t * @param {String} type\n\t * @return {void}\n\t */\n\t_appendMap(conjunction, string, type) {\n\t\tthis.state.queryMap.push({\n\t\t\ttype: type,\n\t\t\tconjunction: conjunction,\n\t\t\tstring: string\n\t\t});\n\t}\n\n\t/**\n\t * Handle key/value pairs in an object the same way as individual arguments,\n\t * when appending to state\n\t *\n\t * @private\n\t */\n\t_mixedSet(/* $letName, $valType, $key, [$val] */) {\n\t\tlet args = getArgs('$letName:string, $valType:string, $key:object|string|number, [$val]', arguments);\n\n\t\tlet obj = {};\n\n\n\t\tif (helpers.isScalar(args.$key) && !helpers.isUndefined(args.$val))\n\t\t{\n\t\t\t// Convert key/val pair to a simple object\n\t\t\tobj[args.$key] = args.$val;\n\t\t}\n\t\telse if (helpers.isScalar(args.$key) && helpers.isUndefined(args.$val))\n\t\t{\n\t\t\t// If just a string for the key, and no value, create a simple object with duplicate key/val\n\t\t\tobj[args.$key] = args.$key;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tobj = args.$key;\n\t\t}\n\n\t\tObject.keys(obj).forEach((k) => {\n\t\t\t// If a single value for the return\n\t\t\tif (['key','value'].indexOf(args.$valType) !== -1)\n\t\t\t{\n\t\t\t\tlet pushVal = (args.$valType === 'key') ? k : obj[k];\n\t\t\t\tthis.state[args.$letName].push(pushVal);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tthis.state[args.$letName][k] = obj[k];\n\t\t\t}\n\t\t});\n\n\n\t\treturn this.state[args.$letName];\n\t}\n\n\t_whereMixedSet(/*key, val*/) {\n\t\tlet args = getArgs('key:string|object, [val]', arguments);\n\n\t\tthis.state.whereMap = [];\n\t\tthis.state.rawWhereValues = [];\n\n\t\tthis._mixedSet('whereMap', 'both', args.key, args.val);\n\t\tthis._mixedSet('rawWhereValues', 'value', args.key, args.val);\n\t}\n\n\t_fixConjunction(conj) {\n\t\tlet lastItem = this.state.queryMap[this.state.queryMap.length - 1];\n\t\tlet conjunctionList = helpers.arrayPluck(this.state.queryMap, 'conjunction');\n\n\t\tif (this.state.queryMap.length === 0 || ( ! helpers.regexInArray(conjunctionList, /^ ?WHERE/i)))\n\t\t{\n\t\t\tconj = \" WHERE \";\n\t\t}\n\t\telse if (lastItem.type === 'groupStart')\n\t\t{\n\t\t\tconj = '';\n\t\t}\n\t\telse\n\t\t{\n\t\t\tconj = ' ' + conj + ' ';\n\t\t}\n\n\t\treturn conj;\n\t}\n\n\t_where(key, val, defaultConj) {\n\t\t// Normalize key and value and insert into this.state.whereMap\n\t\tthis._whereMixedSet(key, val);\n\n\t\t// Parse the where condition to account for operators,\n\t\t// functions, identifiers, and literal values\n\t\tthis.state = this.parser.parseWhere(this.driver, this.state);\n\n\t\tthis.state.whereMap.forEach((clause) => {\n\t\t\tlet conj = this._fixConjunction(defaultConj);\n\t\t\tthis._appendMap(conj, clause, 'where');\n\t\t});\n\n\t\tthis.state.whereMap = {};\n\t}\n\n\t_whereNull(field, stmt, conj) {\n\t\tfield = this.driver.quoteIdentifiers(field);\n\t\tlet item = field + ' ' + stmt;\n\n\t\tthis._appendMap(this._fixConjunction(conj), item, 'whereNull');\n\t}\n\n\t_having(/*key, val, conj*/) {\n\t\tlet args = getArgs('key:string|object, [val]:string|number, [conj]:string', arguments);\n\t\targs.conj = args.conj || 'AND';\n\t\targs.val = args.val || null;\n\n\t\t// Normalize key/val and put in state.whereMap\n\t\tthis._whereMixedSet(args.key, args.val);\n\n\t\t// Parse the having condition to account for operators,\n\t\t// functions, identifiers, and literal values\n\t\tthis.state = this.parser.parseWhere(this.driver, this.state);\n\n\t\tthis.state.whereMap.forEach((clause) => {\n\t\t\t// Put in the having map\n\t\t\tthis.state.havingMap.push({\n\t\t\t\tconjunction: (this.state.havingMap.length > 0) ? ` ${args.conj} ` : ' HAVING ',\n\t\t\t\tstring: clause\n\t\t\t});\n\t\t});\n\n\t\t// Clear the where Map\n\t\tthis.state.whereMap = {};\n\t}\n\t_whereIn(/*key, val, inClause, conj*/) {\n\t\tlet args = getArgs('key:string, val:array, inClause:string, conj:string', arguments);\n\n\t\targs.key = this.driver.quoteIdentifiers(args.key);\n\t\tlet params = new Array(args.val.length);\n\t\tparams.fill('?');\n\n\t\targs.val.forEach((value) => {\n\t\t\tthis.state.whereValues.push(value);\n\t\t});\n\n\t\targs.conj = (this.state.queryMap.length > 0) ? \" \" + args.conj + \" \" : ' WHERE ';\n\t\tlet str = args.key + \" \" + args.inClause + \" (\" + params.join(',') + \") \";\n\n\t\tthis._appendMap(args.conj, str, 'whereIn');\n\t}\n\n\t_run(type, table, callback, sql, vals) {\n\n\t\tif ( ! sql)\n\t\t{\n\t\t\tsql = this._compile(type, table);\n\t\t}\n\n\t\tif ( ! vals)\n\t\t{\n\t\t\tvals = this.state.values.concat(this.state.whereValues);\n\t\t}\n\n//console.log(this.state);\n//console.log(sql);\n//console.log(vals);\n//console.log(callback);\n//console.log('------------------------');\n\n\t\t// Reset the state so another query can be built\n\t\tthis._resetState();\n\n\t\t// Pass the sql and values to the adapter to run on the database\n\t\tthis.adapter.execute(sql, vals, callback);\n\n\t}\n\n\t_getCompile(type, table, reset) {\n\t\treset = reset || false;\n\n\t\tlet sql = this._compile(type, table);\n\n\t\tif (reset) this._resetState();\n\n\t\treturn sql;\n\t}\n\n\t_resetState() {\n\t\tthis.state = new State();\n\t}\n\n\t// ----------------------------------------------------------------------------\n\t// ! Miscellaneous Methods\n\t// ----------------------------------------------------------------------------\n\n\t/**\n\t * Reset the object state for a new query\n\t *\n\t * @memberOf QueryBuilder\n\t * @return {void}\n\t */\n\tresetQuery() {\n\t\tthis._resetState();\n\t}\n\n\t/**\n\t * Returns the current class state for testing or other purposes\n\t *\n\t * @private\n\t * @return {Object}\n\t */\n\tgetState() {\n\t\treturn this.state;\n\t}\n\n\t/**\n\t * Closes the database connection for the current adapter\n\t *\n\t * @return {void}\n\t */\n\tend() {\n\t\tthis.adapter.close();\n\t}\n\n\t// ------------------------------------------------------------------------\n\t// ! Query Builder Methods\n\t// ------------------------------------------------------------------------\n\n\t/**\n\t * Specify rows to select in the query\n\t *\n\t * @memberOf QueryBuilder\n\t * @param {String|Array} fields - The fields to select from the current table\n\t * @return {QueryBuilder}\n\t */\n\tselect(fields) {\n\n\t\t// Split/trim fields by comma\n\t\tfields = (Array.isArray(fields))\n\t\t\t? fields\n\t\t\t: fields.split(\",\").map(helpers.stringTrim);\n\n\t\t// Split on 'As'\n\t\tfields.forEach((field, index) => {\n\t\t\tif (field.match(/as/i))\n\t\t\t{\n\t\t\t\tfields[index] = field.split(/ as /i).map(helpers.stringTrim);\n\t\t\t}\n\t\t});\n\n\t\tlet safeArray = this.driver.quoteIdentifiers(fields);\n\n\t\t// Join the strings back together\n\t\tsafeArray.forEach((field, index) => {\n\t\t\tif (Array.isArray(field))\n\t\t\t{\n\t\t\t\tsafeArray[index] = safeArray[index].join(' AS ');\n\t\t\t}\n\t\t});\n\n\t\tthis.state.selectString += safeArray.join(', ');\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Specify the database table to select from\n\t *\n\t * @param {String} tableName - The table to use for the current query\n\t * @return {QueryBuilder}\n\t */\n\tfrom(tableName) {\n\t\t// Split identifiers on spaces\n\t\tlet identArray = tableName.trim().split(' ').map(helpers.stringTrim);\n\n\t\t// Quote/prefix identifiers\n\t\tidentArray[0] = this.driver.quoteTable(identArray[0]);\n\t\tidentArray = this.driver.quoteIdentifiers(identArray);\n\n\t\t// Put it back together\n\t\tthis.state.fromString = identArray.join(' ');\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Add a 'like/ and like' clause to the query\n\t *\n\t * @param {String} field - The name of the field to compare to\n\t * @param {String} val - The value to compare to\n\t * @param {String} [pos=both] - The placement of the wildcard character(s): before, after, or both\n\t * @return {QueryBuilder}\n\t */\n\tlike(field, val, pos) {\n\t\tthis._like(field, val, pos, ' LIKE ', 'AND');\n\t\treturn this;\n\t}\n\n\t/**\n\t * Add a 'not like/ and not like' clause to the query\n\t *\n\t * @param {String} field - The name of the field to compare to\n\t * @param {String} val - The value to compare to\n\t * @param {String} [pos=both] - The placement of the wildcard character(s): before, after, or both\n\t * @return {QueryBuilder}\n\t */\n\tnotLike(field, val, pos) {\n\t\tthis._like(field, val, pos, ' NOT LIKE ', 'AND');\n\t\treturn this;\n\t}\n\n\t/**\n\t * Add an 'or like' clause to the query\n\t *\n\t * @param {String} field - The name of the field to compare to\n\t * @param {String} val - The value to compare to\n\t * @param {String} [pos=both] - The placement of the wildcard character(s): before, after, or both\n\t * @return {QueryBuilder}\n\t */\n\torLike(field, val, pos) {\n\t\tthis._like(field, val, pos, ' LIKE ', 'OR');\n\t\treturn this;\n\t}\n\n\t/**\n\t * Add an 'or not like' clause to the query\n\t *\n\t * @param {String} field - The name of the field to compare to\n\t * @param {String} val - The value to compare to\n\t * @param {String} [pos=both] - The placement of the wildcard character(s): before, after, or both\n\t * @return {QueryBuilder}\n\t */\n\torNotLike(field, val, pos) {\n\t\tthis._like(field, val, pos, ' NOT LIKE ', 'OR');\n\t\treturn this;\n\t}\n\n\t/**\n\t * Add a 'having' clause\n\t *\n\t * @param {String|Object} key - The name of the field and the comparision operator, or an object\n\t * @param {String|Number} [val] - The value to compare if the value of key is a string\n\t * @return {QueryBuilder}\n\t */\n\thaving(/*key, [val]*/) {\n\t\tlet args = getArgs('key:string|object, [val]:string|number', arguments);\n\n\t\tthis._having(args.key, args.val, 'AND');\n\t\treturn this;\n\t}\n\n\t/**\n\t * Add an 'or having' clause\n\t *\n\t * @param {String|Object} key - The name of the field and the comparision operator, or an object\n\t * @param {String|Number} [val] - The value to compare if the value of key is a string\n\t * @return {QueryBuilder}\n\t */\n\torHaving(/*key, [val]*/) {\n\t\tlet args = getArgs('key:string|object, [val]:string|number', arguments);\n\n\t\tthis._having(args.key, args.val, 'OR');\n\t\treturn this;\n\t}\n\n\t/**\n\t * Set a 'where' clause\n\t *\n\t * @param {String|Object} key - The name of the field and the comparision operator, or an object\n\t * @param {String|Number} [val] - The value to compare if the value of key is a string\n\t * @return {QueryBuilder}\n\t */\n\twhere(key, val) {\n\t\tthis._where(key, val, 'AND');\n\t\treturn this;\n\t}\n\n\t/**\n\t * Set a 'or where' clause\n\t *\n\t * @param {String|Object} key - The name of the field and the comparision operator, or an object\n\t * @param {String|Number} [val] - The value to compare if the value of key is a string\n\t * @return {QueryBuilder}\n\t */\n\torWhere(key, val) {\n\t\tthis._where(key, val, 'OR');\n\t\treturn this;\n\t}\n\n\t/**\n\t * Select a field that is Null\n\t *\n\t * @param {String} field - The name of the field that has a NULL value\n\t * @return {QueryBuilder}\n\t */\n\twhereIsNull(field) {\n\t\tthis._whereNull(field, 'IS NULL', 'AND');\n\t\treturn this;\n\t}\n\n\t/**\n\t * Specify that a field IS NOT NULL\n\t *\n\t * @param {String} field\n\t * @return {QueryBuilder}\n\t */\n\twhereIsNotNull(field) {\n\t\tthis._whereNull(field, 'IS NOT NULL', 'AND');\n\t\treturn this;\n\t}\n\n\t/**\n\t * Field is null prefixed with 'OR'\n\t *\n\t * @param {String} field\n\t * @return {QueryBuilder}\n\t */\n\torWhereIsNull(field) {\n\t\tthis._whereNull(field, 'IS NULL', 'OR');\n\t\treturn this;\n\t}\n\n\t/**\n\t * Field is not null prefixed with 'OR'\n\t *\n\t * @param {String} field\n\t * @return {QueryBuilder}\n\t */\n\torWhereIsNotNull(field) {\n\t\tthis._whereNull(field, 'IS NOT NULL', 'OR');\n\t\treturn this;\n\t}\n\n\t/**\n\t * Set a 'where in' clause\n\t *\n\t * @param {String} key - the field to search\n\t * @param {Array} val - the array of items to search in\n\t * @return {QueryBuilder}\n\t */\n\twhereIn(key, val) {\n\t\tthis._whereIn(key, val, 'IN', 'AND');\n\t\treturn this;\n\t}\n\n\t/**\n\t * Set a 'or where in' clause\n\t *\n\t * @param {String} key - the field to search\n\t * @param {Array} val - the array of items to search in\n\t * @return {QueryBuilder}\n\t */\n\torWhereIn(key, val) {\n\t\tthis._whereIn(key, val, 'IN', 'OR');\n\t\treturn this;\n\t}\n\n\t/**\n\t * Set a 'where not in' clause\n\t *\n\t * @param {String} key - the field to search\n\t * @param {Array} val - the array of items to search in\n\t * @return {QueryBuilder}\n\t */\n\twhereNotIn(key, val) {\n\t\tthis._whereIn(key, val, 'NOT IN', 'AND');\n\t\treturn this;\n\t}\n\n\t/**\n\t * Set a 'or where not in' clause\n\t *\n\t * @param {String} key - the field to search\n\t * @param {Array} val - the array of items to search in\n\t * @return {QueryBuilder}\n\t */\n\torWhereNotIn(key, val) {\n\t\tthis._whereIn(key, val, 'NOT IN', 'OR');\n\t\treturn this;\n\t}\n\n\t/**\n\t * Set values for insertion or updating\n\t *\n\t * @param {String|Object} key - The key or object to use\n\t * @param {String} [val] - The value if using a scalar key\n\t * @return {QueryBuilder}\n\t */\n\tset(/* $key, [$val] */) {\n\t\tlet args = getArgs('$key, [$val]', arguments);\n\n\t\t// Set the appropriate state variables\n\t\tthis._mixedSet('setArrayKeys', 'key', args.$key, args.$val);\n\t\tthis._mixedSet('values', 'value', args.$key, args.$val);\n\n\t\t// Use the keys of the array to make the insert/update string\n\t\t// and escape the field names\n\t\tthis.state.setArrayKeys = this.state.setArrayKeys.map(this.driver._quote);\n\n\t\t// Generate the \"set\" string\n\t\tthis.state.setString = this.state.setArrayKeys.join('=?,');\n\t\tthis.state.setString += '=?';\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Add a join clause to the query\n\t *\n\t * @param {String} table - The table you are joining\n\t * @param {String} cond - The join condition.\n\t * @param {String} [type='inner'] - The type of join, which defaults to inner\n\t * @return {QueryBuilder}\n\t */\n\tjoin(table, cond, type) {\n\t\ttype = type || \"inner\";\n\n\t\t// Prefix/quote table name\n\t\ttable = table.split(' ').map(helpers.stringTrim);\n\t\ttable[0] = this.driver.quoteTable(table[0]);\n\t\ttable = table.map(this.driver.quoteIdentifiers);\n\t\ttable = table.join(' ');\n\n\t\t// Parse out the join condition\n\t\tlet parsedCondition = this.parser.compileJoin(cond);\n\t\tlet condition = table + ' ON ' + parsedCondition;\n\n\t\t// Append the join condition to the query map\n\t\tthis._appendMap(\"\\n\" + type.toUpperCase() + ' JOIN ', condition, 'join');\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Group the results by the selected field(s)\n\t *\n\t * @param {String|Array} field\n\t * @return {QueryBuilder}\n\t */\n\tgroupBy(field) {\n\t\tif ( ! helpers.isScalar(field))\n\t\t{\n\t\t\tlet newGroupArray = field.map(this.driver.quoteIdentifiers);\n\t\t\tthis.state.groupArray = this.state.groupArray.concat(newGroupArray);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tthis.state.groupArray.push(this.driver.quoteIdentifiers(field));\n\t\t}\n\n\t\tthis.state.groupString = ' GROUP BY ' + this.state.groupArray.join(',');\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Order the results by the selected field(s)\n\t *\n\t * @param {String} field - The field(s) to order by\n\t * @param {String} [type='ASC'] - The order direction, ASC or DESC\n\t * @return {QueryBuilder}\n\t */\n\torderBy(field, type) {\n\t\ttype = type || 'ASC';\n\n\t\t// Set the fields for later manipulation\n\t\tfield = this.driver.quoteIdentifiers(field);\n\n\t\tthis.state.orderArray[field] = type;\n\n\t\tlet orderClauses = [];\n\n\t\t// Flatten key/val pairs into an array of space-separated pairs\n\t\tObject.keys(this.state.orderArray).forEach((key) => {\n\t\t\torderClauses.push(key + ' ' + this.state.orderArray[key].toUpperCase());\n\t\t});\n\n\t\t// Set the final string\n\t\tthis.state.orderString = ' ORDER BY ' + orderClauses.join(', ');\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Put a limit on the query\n\t *\n\t * @param {Number} limit - The maximum number of rows to fetch\n\t * @param {Number} [offset] - The row number to start from\n\t * @return {QueryBuilder}\n\t */\n\tlimit(limit, offset) {\n\t\tthis.state.limit = limit;\n\t\tthis.state.offset = offset || null;\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Adds an open paren to the current query for logical grouping\n\t *\n\t * @return {QueryBuilder}\n\t */\n\tgroupStart() {\n\t\tlet conj = (this.state.queryMap.length < 1) ? ' WHERE ' : ' AND ';\n\t\tthis._appendMap(conj, '(', 'groupStart');\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Adds an open paren to the current query for logical grouping,\n\t * prefixed with 'OR'\n\t *\n\t * @return {QueryBuilder}\n\t */\n\torGroupStart() {\n\t\tthis._appendMap('', ' OR (', 'groupStart');\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Adds an open paren to the current query for logical grouping,\n\t * prefixed with 'OR NOT'\n\t *\n\t * @return {QueryBuilder}\n\t */\n\torNotGroupStart() {\n\t\tthis._appendMap('', ' OR NOT (', 'groupStart');\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Ends a logical grouping started with one of the groupStart methods\n\t *\n\t * @return {QueryBuilder}\n\t */\n\tgroupEnd() {\n\t\tthis._appendMap('', ')', 'groupEnd');\n\n\t\treturn this;\n\t}\n\n\t// ------------------------------------------------------------------------\n\t// ! Result Methods\n\t// ------------------------------------------------------------------------\n\n\t/**\n\t * Get the results of the compiled query\n\t *\n\t * @param {String} [table] - The table to select from\n\t * @param {Number} [limit] - A limit for the query\n\t * @param {Number} [offset] - An offset for the query\n\t * @param {Function} callback - A callback for receiving the result\n\t * @return {void}\n\t */\n\tget(/* [table], [limit], [offset], callback */) {\n\t\tlet args = getArgs('[table]:string, [limit]:number, [offset]:number, callback:function', arguments);\n\n\t\tif (args.table) {\n\t\t\tthis.from(args.table);\n\t\t}\n\n\t\tif (args.limit) {\n\t\t\tthis.limit(args.limit, args.offset);\n\t\t}\n\n\t\t// Run the query\n\t\tthis._run('get', args.table, args.callback);\n\t}\n\n\t/**\n\t * Run the generated insert query\n\t *\n\t * @param {String} table - The table to insert into\n\t * @param {Object} [data] - Data to insert, if not already added with the 'set' method\n\t * @param {Function} callback - Callback for handling response from the database\n\t * @return {void}\n\t */\n\tinsert(/* table, data, callback */) {\n\t\tlet args = getArgs('table:string, [data]:object, callback:function', arguments);\n\n\t\tif (args.data) {\n\t\t\tthis.set(args.data);\n\t\t}\n\n\t\t// Run the query\n\t\tthis._run('insert', this.driver.quoteTable(args.table), args.callback);\n\t}\n\n\t/**\n\t * Insert multiple sets of rows at a time\n\t *\n\t * @param {String} table - The table to insert into\n\t * @param {Array} data - The array of objects containing data rows to insert\n\t * @param {Function} callback - Callback for handling database response\n\t * @example query.insertBatch('foo',[{id:1,val:'bar'},{id:2,val:'baz'}], callbackFunction);\n\t * @return {void}\n\t */\n\tinsertBatch(/* table, data, callback */) {\n\t\tlet args = getArgs('table:string, data:array, callback:function', arguments);\n\t\tlet batch = this.driver.insertBatch(args.table, args.data);\n\n\t\t// Run the query\n\t\tthis._run('', '', args.callback, batch.sql, batch.values);\n\t}\n\n\t/**\n\t * Run the generated update query\n\t *\n\t * @param {String} table - The table to insert into\n\t * @param {Object} [data] - Data to insert, if not already added with the 'set' method\n\t * @param {Function} callback - Callback for handling response from the database\n\t * @return {void}\n\t */\n\tupdate(/*table, data, callback*/) {\n\t\tlet args = getArgs('table:string, [data]:object, callback:function', arguments);\n\n\t\tif (args.data) {\n\t\t\tthis.set(args.data);\n\t\t}\n\n\t\t// Run the query\n\t\tthis._run('update', this.driver.quoteTable(args.table), args.callback);\n\t}\n\n\t/**\n\t * Run the generated delete query\n\t *\n\t * @param {String} table - The table to insert into\n\t * @param {Object} [where] - Where clause for delete statement\n\t * @param {Function} callback - Callback for handling response from the database\n\t * @return {void}\n\t */\n\tdelete(/*table, [where], callback*/) {\n\t\tlet args = getArgs('table:string, [where]:object, callback:function', arguments);\n\n\t\tif (args.where)\n\t\t{\n\t\t\tthis.where(args.where);\n\t\t}\n\n\t\t// Run the query\n\t\tthis._run('delete', this.driver.quoteTable(args.table), args.callback);\n\t}\n\n\t// ------------------------------------------------------------------------\n\t// ! Methods returning SQL\n\t// ------------------------------------------------------------------------\n\n\t/**\n\t * Return generated select query SQL\n\t *\n\t * @param {String} [table] - the name of the table to retrieve from\n\t * @param {Boolean} [reset=true] - Whether to reset the query builder so another query can be built\n\t * @return {String}\n\t */\n\tgetCompiledSelect(/*table, reset*/) {\n\t\tlet args = getArgs('[table]:string, [reset]:boolean', arguments);\n\t\tif (args.table)\n\t\t{\n\t\t\tthis.from(args.table);\n\t\t}\n\n\t\treturn this._getCompile('get', args.table, args.reset);\n\t}\n\n\t/**\n\t * Return generated insert query SQL\n\t *\n\t * @param {String} table - the name of the table to insert into\n\t * @param {Boolean} [reset=true] - Whether to reset the query builder so another query can be built\n\t * @return {String}\n\t */\n\tgetCompiledInsert(table, reset) {\n\t\treturn this._getCompile('insert', this.driver.quoteTable(table), reset);\n\t}\n\n\t/**\n\t * Return generated update query SQL\n\t *\n\t * @param {String} table - the name of the table to update\n\t * @param {Boolean} [reset=true] - Whether to reset the query builder so another query can be built\n\t * @return {String}\n\t */\n\tgetCompiledUpdate(table, reset) {\n\t\treturn this._getCompile('update', this.driver.quoteTable(table), reset);\n\t}\n\n\t/**\n\t * Return generated delete query SQL\n\t *\n\t * @param {String} table - the name of the table to delete from\n\t * @param {Boolean} [reset=true] - Whether to reset the query builder so another query can be built\n\t * @return {String}\n\t */\n\tgetCompiledDelete(table, reset) {\n\t\treturn this._getCompile('delete', this.driver.quoteTable(table), reset);\n\t}\n}"],"sourceRoot":"/source/"}
\ No newline at end of file
diff --git a/lib/QueryParser.js b/lib/QueryParser.js
index 13bd592..e3beee6 100644
--- a/lib/QueryParser.js
+++ b/lib/QueryParser.js
@@ -1,35 +1,20 @@
'use strict';
-var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
-
-var _helpers = require('./helpers');
-
-var _helpers2 = _interopRequireDefault(_helpers);
-
-function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+let helpers = require('./helpers');
// --------------------------------------------------------------------------
-/**
- * @constructor
- * @param {Driver} - The driver object for the database in use
- * @module query-parser
- */
-module.exports = (function () {
+module.exports = class QueryParser {
/**
- * @constructor
- * @param {Driver} - The driver object for the database in use
- * @return {void}
- */
-
- function QueryParser(driver) {
- _classCallCheck(this, QueryParser);
-
+ * @constructor
+ *
+ * @param {Driver} driver - The driver object for the database in use
+ * @return {void}
+ */
+ constructor(driver) {
this.driver = driver;
- var matchPatterns = {
+ let matchPatterns = {
'function': /([a-z0-9_]+\((.*)\))/i,
operator: /\!=?|\=|\+|&&?|~|\|\|?|\^|\/|<>|>=?|<=?|\-|%|OR|AND|NOT|XOR/ig,
literal: /([0-9]+)|'(.*?)'|true|false/ig
@@ -37,242 +22,248 @@ module.exports = (function () {
// Full pattern for identifiers
// Making sure that literals and functions aren't matched
- matchPatterns.identifier = new RegExp('(' + '(?!' + matchPatterns['function'].source + '|' + matchPatterns.literal.source + ')' + '([a-z_\-]+[0-9]*\\.?)' + ')+', 'ig');
+ matchPatterns.identifier = new RegExp(
+ '('
+ + '(?!'
+ + matchPatterns['function'].source + '|'
+ + matchPatterns.literal.source
+ + ')'
+ + '([a-z_\-]+[0-9]*\\.?)'
+ + ')+'
+ , 'ig');
// Full pattern for determining ordering of the pieces
- matchPatterns.joinCombined = new RegExp(matchPatterns['function'].source + "+|" + matchPatterns.literal.source + '+|' + matchPatterns.identifier.source + '|(' + matchPatterns.operator.source + ')+', 'ig');
+ matchPatterns.joinCombined = new RegExp(
+ matchPatterns['function'].source + "+|"
+ + matchPatterns.literal.source + '+|'
+ + matchPatterns.identifier.source
+ + '|(' + matchPatterns.operator.source + ')+'
+ , 'ig');
this.matchPatterns = matchPatterns;
- this.identifierBlacklist = ['true', 'false', 'null'];
+ this.identifierBlacklist = ['true','false','null'];
}
/**
- * Filter matched patterns
- *
- * @param {Array} array
- * @return {Array|null}
- */
+ * Filter matched patterns
+ *
+ * @param {Array} array - Set of possible matches
+ * @return {Array|null} - Filtered set of possible matches
+ */
+ filterMatches(array) {
+ let output = [];
- _createClass(QueryParser, [{
- key: 'filterMatches',
- value: function filterMatches(array) {
- var output = [];
+ // Return non-array matches
+ if (helpers.isNull(array)) return null;
+ if (helpers.isScalar(array) || helpers.isUndefined(array)) return output;
- // Return non-array matches
- if (_helpers2.default.isNull(array)) return null;
- if (_helpers2.default.isScalar(array) || _helpers2.default.isUndefined(array)) return output;
+ array.forEach(item => {
+ output.push(item);
+ });
+ return output;
+ }
- array.forEach(function (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));
+ }
- /**
- * 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}
- */
+ /**
+ * Tokenize the sql into parts for additional processing
+ *
+ * @param {String} sql - Join sql to parse
+ * @return {Object} - Join condition components
+ */
+ parseJoin(sql) {
+ let matches = {};
+ let output = {
+ functions: [],
+ identifiers: [],
+ operators: [],
+ literals: []
+ };
- }, {
- key: 'hasOperator',
- value: function hasOperator(string) {
- return this.filterMatches(string.match(this.matchPatterns.operator));
- }
+ // 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);
- /**
- * Tokenize the sql into parts for additional processing
- *
- * @param {String} sql
- * @return {Object}
- */
+ // Get everything at once for ordering
+ matches.combined = sql.match(this.matchPatterns.joinCombined);
- }, {
- key: 'parseJoin',
- value: function parseJoin(sql) {
- var _this = this;
+ // Flatten the matches to increase relevance
+ Object.keys(matches).forEach(key => {
+ output[key] = this.filterMatches(matches[key]);
+ });
- var matches = {};
- var output = {
- functions: [],
- identifiers: [],
- operators: [],
- literals: []
- };
+ return output;
+ }
- // 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);
+ /**
+ * Return the output of the parsing of the join condition
+ *
+ * @param {String} condition - The join condition to evalate
+ * @return {String} - The parsed/escaped join condition
+ */
+ compileJoin(condition) {
+ let parts = this.parseJoin(condition);
+ let count = parts.identifiers.length;
+ let i;
- // Get everything at once for ordering
- matches.combined = sql.match(this.matchPatterns.joinCombined);
+ // Quote the identifiers
+ parts.combined.forEach((part, i) => {
+ if (parts.identifiers.indexOf(part) !== -1 && ! helpers.isNumber(part))
+ {
+ parts.combined[i] = this.driver.quoteIdentifiers(part);
+ }
+ });
- // Flatten the matches to increase relevance
- Object.keys(matches).forEach(function (key) {
- output[key] = _this.filterMatches(matches[key]);
- });
+ return parts.combined.join(' ');
+ }
- return output;
- }
+ /**
+ * Parse a where clause to separate functions from values
+ *
+ * @param {Driver} driver - The current db driver
+ * @param {State} state - Query Builder state object
+ * @return {String} - The parsed/escaped where condition
+ */
+ parseWhere(driver, state) {
+ let whereMap = state.whereMap;
+ let whereValues = state.rawWhereValues;
- /**
- * Return the output of the parsing of the join condition
- *
- * @param {String} condition - The join condition to evalate
- * @return {String} - The parsed/escaped join condition
- */
+ let outputMap = [];
+ let outputValues = [];
- }, {
- key: 'compileJoin',
- value: function compileJoin(condition) {
- var _this2 = this;
+ Object.keys(whereMap).forEach(key => {
+ // Combine fields, operators, functions and values into a full clause
+ // to have a common starting flow
+ let fullClause = '';
- var parts = this.parseJoin(condition);
- var count = parts.identifiers.length;
- var i = undefined;
+ // 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];
+ }
- // Quote the identifiers
- parts.combined.forEach(function (part, i) {
- if (parts.identifiers.indexOf(part) !== -1 && !_helpers2.default.isNumber(part)) {
- parts.combined[i] = _this2.driver.quoteIdentifiers(part);
- }
- });
+ // Separate the clause into separate pieces
+ let parts = this.parseJoin(fullClause);
- return parts.combined.join(' ');
- }
+ // Filter explicit literals from lists of matches
+ if (whereValues.indexOf(whereMap[key]) !== -1)
+ {
+ let value = whereMap[key];
+ let identIndex = (helpers.isArray(parts.identifiers)) ? parts.identifiers.indexOf(value) : -1;
+ let litIndex = (helpers.isArray(parts.literals)) ? parts.literals.indexOf(value) : -1;
+ let combIndex = (helpers.isArray(parts.combined)) ? parts.combined.indexOf(value) : -1;
+ let funcIndex = (helpers.isArray(parts.functions)) ? parts.functions.indexOf(value) : -1;
+ let inOutputArray = outputValues.indexOf(value) !== -1;
- /**
- * Parse a where clause to separate functions from values
- *
- * @param {Driver} driver
- * @param {State} state
- * @return {String} - The parsed/escaped where condition
- */
+ // Remove the identifier in question,
+ // and add to the output values array
+ if (identIndex !== -1)
+ {
+ parts.identifiers.splice(identIndex, 1);
- }, {
- key: 'parseWhere',
- value: function parseWhere(driver, state) {
- var _this3 = this;
-
- var whereMap = state.whereMap;
- var whereValues = state.rawWhereValues;
-
- var outputMap = [];
- var outputValues = [];
-
- Object.keys(whereMap).forEach(function (key) {
- // Combine fields, operators, functions and values into a full clause
- // to have a common starting flow
- var fullClause = '';
-
- // Add an explicit = sign where one is inferred
- if (!_this3.hasOperator(key)) {
- fullClause = key + ' = ' + whereMap[key];
- } else if (whereMap[key] === key) {
- fullClause = key;
- } else {
- fullClause = key + ' ' + whereMap[key];
+ if ( ! inOutputArray)
+ {
+ outputValues.push(value);
+ inOutputArray = true;
+ }
}
- // Separate the clause into separate pieces
- var parts = _this3.parseJoin(fullClause);
+ // Remove the value from the literals list
+ // so it is not added twice
+ if (litIndex !== -1)
+ {
+ parts.literals.splice(litIndex, 1);
- // Filter explicit literals from lists of matches
- if (whereValues.indexOf(whereMap[key]) !== -1) {
- var value = whereMap[key];
- var identIndex = _helpers2.default.isArray(parts.identifiers) ? parts.identifiers.indexOf(value) : -1;
- var litIndex = _helpers2.default.isArray(parts.literals) ? parts.literals.indexOf(value) : -1;
- var combIndex = _helpers2.default.isArray(parts.combined) ? parts.combined.indexOf(value) : -1;
- var funcIndex = _helpers2.default.isArray(parts.functions) ? parts.functions.indexOf(value) : -1;
- var inOutputArray = outputValues.indexOf(value) !== -1;
+ if ( ! inOutputArray)
+ {
+ outputValues.push(value);
+ inOutputArray = true;
+ }
+ }
- // Remove the identifier in question,
- // and add to the output values array
- if (identIndex !== -1) {
- parts.identifiers.splice(identIndex, 1);
+ // Remove the value from the combined list
+ // and replace it with a placeholder
+ if (combIndex !== -1)
+ {
+ // Make sure to skip functions when replacing values
+ if (funcIndex === -1)
+ {
+ parts.combined[combIndex] = '?';
- if (!inOutputArray) {
+ 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);
+ // Filter false positive identifiers
+ parts.identifiers = parts.identifiers || [];
+ parts.identifiers = parts.identifiers.filter(item => {
+ let isInCombinedMatches = parts.combined.indexOf(item) !== -1;
+ let isNotInBlackList = this.identifierBlacklist.indexOf(item.toLowerCase()) === -1;
- if (!inOutputArray) {
- outputValues.push(value);
- inOutputArray = true;
- }
+ return isInCombinedMatches && isNotInBlackList;
+ }, this);
+
+ // Quote identifiers
+ if (helpers.isArray(parts.identifiers))
+ {
+ parts.identifiers.forEach(ident => {
+ let index = parts.combined.indexOf(ident);
+ if (index !== -1)
+ {
+ parts.combined[index] = driver.quoteIdentifiers(ident);
}
+ });
+ }
- // Remove the value from the combined list
- // and replace it with a placeholder
- if (combIndex !== -1) {
- // Make sure to skip functions when replacing values
- if (funcIndex === -1) {
- parts.combined[combIndex] = '?';
+ // Replace each literal with a placeholder in the map
+ // and add the literal to the values,
+ // This should only apply to literal values that are not
+ // explicitly mapped to values, but have to be parsed from
+ // a where condition,
+ if (helpers.isArray(parts.literals))
+ {
+ parts.literals.forEach(lit => {
+ let litIndex = parts.combined.indexOf(lit);
- if (!inOutputArray) {
- outputValues.push(value);
- inOutputArray = true;
- }
- }
+ if (litIndex !== -1)
+ {
+ parts.combined[litIndex] = (helpers.isArray(parts.operators)) ? '?' : '= ?';
+ outputValues.push(lit);
}
- }
+ });
+ }
- // Filter false positive identifiers
- parts.identifiers = parts.identifiers || [];
- parts.identifiers = parts.identifiers.filter(function (item) {
- var isInCombinedMatches = parts.combined.indexOf(item) !== -1;
- var isNotInBlackList = _this3.identifierBlacklist.indexOf(item.toLowerCase()) === -1;
+ outputMap.push(parts.combined.join(' '));
+ });
- return isInCombinedMatches && isNotInBlackList;
- }, _this3);
+ state.rawWhereValues = [];
+ state.whereValues = state.whereValues.concat(outputValues);
+ state.whereMap = outputMap;
- // Quote identifiers
- if (_helpers2.default.isArray(parts.identifiers)) {
- parts.identifiers.forEach(function (ident) {
- var index = parts.combined.indexOf(ident);
- if (index !== -1) {
- parts.combined[index] = driver.quoteIdentifiers(ident);
- }
- });
- }
-
- // Replace each literal with a placeholder in the map
- // and add the literal to the values,
- // This should only apply to literal values that are not
- // explicitly mapped to values, but have to be parsed from
- // a where condition,
- if (_helpers2.default.isArray(parts.literals)) {
- parts.literals.forEach(function (lit) {
- var litIndex = parts.combined.indexOf(lit);
-
- if (litIndex !== -1) {
- parts.combined[litIndex] = _helpers2.default.isArray(parts.operators) ? '?' : '= ?';
- outputValues.push(lit);
- }
- });
- }
-
- outputMap.push(parts.combined.join(' '));
- });
-
- state.rawWhereValues = [];
- state.whereValues = state.whereValues.concat(outputValues);
- state.whereMap = outputMap;
-
- return state;
- }
- }]);
-
- return QueryParser;
-})();
-//# sourceMappingURL=QueryParser.js.map
+ return state;
+ }
+}
\ No newline at end of file
diff --git a/lib/QueryParser.js.map b/lib/QueryParser.js.map
deleted file mode 100644
index 5a11709..0000000
--- a/lib/QueryParser.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"sources":["QueryParser.js"],"names":[],"mappings":"AAAA,YAAY,CAAC;;;;;;;;;;;;;;;;;;;AAYb,MAAM,CAAC,OAAO;;;;;;;AAMb,UANsB,WAAW,CAMrB,MAAM,EAAE;wBANE,WAAW;;AAOhC,MAAI,CAAC,MAAM,GAAG,MAAM,CAAC;;AAErB,MAAI,aAAa,GAAG;AACnB,aAAU,EAAE,uBAAuB;AACnC,WAAQ,EAAE,+DAA+D;AACzE,UAAO,EAAE,+BAA+B;GACxC;;;;AAAC,AAIF,eAAa,CAAC,UAAU,GAAG,IAAI,MAAM,CACpC,GAAG,GACA,KAAK,GACJ,aAAa,CAAC,UAAU,CAAC,CAAC,MAAM,GAAG,GAAG,GACtC,aAAa,CAAC,OAAO,CAAC,MAAM,GAC7B,GAAG,GACH,uBAAuB,GACxB,IAAI,EACL,IAAI,CAAC;;;AAAC,AAGR,eAAa,CAAC,YAAY,GAAG,IAAI,MAAM,CACtC,aAAa,CAAC,UAAU,CAAC,CAAC,MAAM,GAAG,IAAI,GACrC,aAAa,CAAC,OAAO,CAAC,MAAM,GAAG,IAAI,GACnC,aAAa,CAAC,UAAU,CAAC,MAAM,GAC/B,IAAI,GAAG,aAAa,CAAC,QAAQ,CAAC,MAAM,GAAG,IAAI,EAC5C,IAAI,CAAC,CAAC;;AAER,MAAI,CAAC,aAAa,GAAG,aAAa,CAAC;AACnC,MAAI,CAAC,mBAAmB,GAAG,CAAC,MAAM,EAAC,OAAO,EAAC,MAAM,CAAC,CAAC;EACnD;;;;;;;;AAAA;cArCqB,WAAW;;gCA6CnB,KAAK,EAAE;AACpB,OAAI,MAAM,GAAG,EAAE;;;AAAC,AAGhB,OAAI,kBAAQ,MAAM,CAAC,KAAK,CAAC,EAAE,OAAO,IAAI,CAAC;AACvC,OAAI,kBAAQ,QAAQ,CAAC,KAAK,CAAC,IAAI,kBAAQ,WAAW,CAAC,KAAK,CAAC,EAAE,OAAO,MAAM,CAAC;;AAEzE,QAAK,CAAC,OAAO,CAAC,UAAC,IAAI,EAAK;AACvB,UAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClB,CAAC,CAAC;AACH,UAAO,MAAM,CAAC;GACd;;;;;;;;;;;;8BASW,MAAM,EAAE;AACnB,UAAO,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC;GACrE;;;;;;;;;;;4BAQS,GAAG,EAAE;;;AACd,OAAI,OAAO,GAAG,EAAE,CAAC;AACjB,OAAI,MAAM,GAAG;AACZ,aAAS,EAAE,EAAE;AACb,eAAW,EAAE,EAAE;AACf,aAAS,EAAE,EAAE;AACb,YAAQ,EAAE,EAAE;IACZ;;;AAAC,AAGF,UAAO,CAAC,SAAS,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;AACvF,UAAO,CAAC,WAAW,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;AAC/D,UAAO,CAAC,SAAS,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;AAC3D,UAAO,CAAC,QAAQ,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC;;;AAAC,AAGzD,UAAO,CAAC,QAAQ,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC;;;AAAC,AAG9D,SAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,UAAC,GAAG,EAAK;AACrC,UAAM,CAAC,GAAG,CAAC,GAAG,MAAK,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;IAC/C,CAAC,CAAC;;AAEH,UAAO,MAAM,CAAC;GACd;;;;;;;;;;;8BAQW,SAAS,EAAE;;;AACtB,OAAI,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;AACtC,OAAI,KAAK,GAAG,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC;AACrC,OAAI,CAAC,YAAA;;;AAAC,AAGN,QAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,UAAC,IAAI,EAAE,CAAC,EAAK;AACnC,QAAI,KAAK,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAE,kBAAQ,QAAQ,CAAC,IAAI,CAAC,EACtE;AACC,UAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,OAAK,MAAM,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;KACvD;IACD,CAAC,CAAC;;AAEH,UAAO,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;GAChC;;;;;;;;;;;;6BASU,MAAM,EAAE,KAAK,EAAE;;;AACzB,OAAI,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;AAC9B,OAAI,WAAW,GAAG,KAAK,CAAC,cAAc,CAAC;;AAEvC,OAAI,SAAS,GAAG,EAAE,CAAC;AACnB,OAAI,YAAY,GAAG,EAAE,CAAC;;AAEtB,SAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,UAAC,GAAG,EAAK;;;AAGtC,QAAI,UAAU,GAAG,EAAE;;;AAAC,AAGpB,QAAK,CAAE,OAAK,WAAW,CAAC,GAAG,CAAC,EAC5B;AACC,eAAU,GAAG,GAAG,GAAG,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;KACzC,MACI,IAAI,QAAQ,CAAC,GAAG,CAAC,KAAK,GAAG,EAC9B;AACC,eAAU,GAAG,GAAG,CAAC;KACjB,MAED;AACC,eAAU,GAAG,GAAG,GAAG,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;KACvC;;;AAAA,AAGD,QAAI,KAAK,GAAG,OAAK,SAAS,CAAC,UAAU,CAAC;;;AAAC,AAGvC,QAAI,WAAW,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAC7C;AACC,SAAI,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;AAC1B,SAAI,UAAU,GAAG,AAAC,kBAAQ,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,GAAI,KAAK,CAAC,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;AAC9F,SAAI,QAAQ,GAAG,AAAC,kBAAQ,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAI,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;AACtF,SAAI,SAAS,GAAG,AAAC,kBAAQ,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAI,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;AACvF,SAAI,SAAS,GAAG,AAAC,kBAAQ,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,GAAI,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;AACzF,SAAI,aAAa,GAAG,YAAY,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;;;;AAAC,AAIvD,SAAI,UAAU,KAAK,CAAC,CAAC,EACrB;AACC,WAAK,CAAC,WAAW,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;;AAExC,UAAK,CAAE,aAAa,EACpB;AACC,mBAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACzB,oBAAa,GAAG,IAAI,CAAC;OACrB;MACD;;;;AAAA,AAID,SAAI,QAAQ,KAAK,CAAC,CAAC,EACnB;AACC,WAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;;AAEnC,UAAK,CAAE,aAAa,EACpB;AACC,mBAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACzB,oBAAa,GAAG,IAAI,CAAC;OACrB;MACD;;;;AAAA,AAID,SAAI,SAAS,KAAK,CAAC,CAAC,EACpB;;AAEC,UAAI,SAAS,KAAK,CAAC,CAAC,EACpB;AACC,YAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,GAAG,GAAG,CAAC;;AAEhC,WAAK,CAAE,aAAa,EACpB;AACC,oBAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACzB,qBAAa,GAAG,IAAI,CAAC;QACrB;OACD;MACD;KACD;;;AAAA,AAGD,SAAK,CAAC,WAAW,GAAG,KAAK,CAAC,WAAW,IAAI,EAAE,CAAC;AAC5C,SAAK,CAAC,WAAW,GAAG,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,UAAC,IAAI,EAAK;AACtD,SAAI,mBAAmB,GAAG,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;AAC9D,SAAI,gBAAgB,GAAG,OAAK,mBAAmB,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;;AAEnF,YAAO,mBAAmB,IAAI,gBAAgB,CAAC;KAC/C,SAAO;;;AAAC,AAGT,QAAI,kBAAQ,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,EACtC;AACC,UAAK,CAAC,WAAW,CAAC,OAAO,CAAC,UAAC,KAAK,EAAK;AACpC,UAAI,KAAK,GAAG,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC1C,UAAI,KAAK,KAAK,CAAC,CAAC,EAChB;AACC,YAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;OACvD;MACD,CAAC,CAAC;KACH;;;;;;;AAAA,AAOD,QAAI,kBAAQ,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,EACnC;AACC,UAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,UAAC,GAAG,EAAK;AAC/B,UAAI,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;;AAE3C,UAAI,QAAQ,KAAK,CAAC,CAAC,EACnB;AACC,YAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,AAAC,kBAAQ,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,GAAI,GAAG,GAAG,KAAK,CAAC;AAC5E,mBAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;OACvB;MACD,CAAC,CAAC;KACH;;AAED,aAAS,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACzC,CAAC,CAAC;;AAEH,QAAK,CAAC,cAAc,GAAG,EAAE,CAAC;AAC1B,QAAK,CAAC,WAAW,GAAG,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;AAC3D,QAAK,CAAC,QAAQ,GAAG,SAAS,CAAC;;AAE3B,UAAO,KAAK,CAAC;GACb;;;QApQqB,WAAW;IAqQjC,CAAA","file":"QueryParser.js","sourcesContent":["'use strict';\n\nimport helpers from './helpers';\n\n\n// --------------------------------------------------------------------------\n\n/**\n * @constructor\n * @param {Driver} - The driver object for the database in use\n * @module query-parser\n */\nmodule.exports = class QueryParser {\n\t/**\n\t * @constructor\n\t * @param {Driver} - The driver object for the database in use\n\t * @return {void}\n\t */\n\tconstructor(driver) {\n\t\tthis.driver = driver;\n\n\t\tlet matchPatterns = {\n\t\t\t'function': /([a-z0-9_]+\\((.*)\\))/i,\n\t\t\toperator: /\\!=?|\\=|\\+|&&?|~|\\|\\|?|\\^|\\/|<>|>=?|<=?|\\-|%|OR|AND|NOT|XOR/ig,\n\t\t\tliteral: /([0-9]+)|'(.*?)'|true|false/ig\n\t\t};\n\n\t\t// Full pattern for identifiers\n\t\t// Making sure that literals and functions aren't matched\n\t\tmatchPatterns.identifier = new RegExp(\n\t\t\t'('\n\t\t\t\t+ '(?!'\n\t\t\t\t\t+ matchPatterns['function'].source + '|'\n\t\t\t\t\t+ matchPatterns.literal.source\n\t\t\t\t+ ')'\n\t\t\t\t+ '([a-z_\\-]+[0-9]*\\\\.?)'\n\t\t\t+ ')+'\n\t\t, 'ig');\n\n\t\t// Full pattern for determining ordering of the pieces\n\t\tmatchPatterns.joinCombined = new RegExp(\n\t\t\tmatchPatterns['function'].source + \"+|\"\n\t\t\t+ matchPatterns.literal.source + '+|'\n\t\t\t+ matchPatterns.identifier.source\n\t\t\t+ '|(' + matchPatterns.operator.source + ')+'\n\t\t, 'ig');\n\n\t\tthis.matchPatterns = matchPatterns;\n\t\tthis.identifierBlacklist = ['true','false','null'];\n\t}\n\n\t/**\n\t * Filter matched patterns\n\t *\n\t * @param {Array} array\n\t * @return {Array|null}\n\t */\n\tfilterMatches(array) {\n\t\tlet output = [];\n\n\t\t// Return non-array matches\n\t\tif (helpers.isNull(array)) return null;\n\t\tif (helpers.isScalar(array) || helpers.isUndefined(array)) return output;\n\n\t\tarray.forEach((item) => {\n\t\t\toutput.push(item);\n\t\t});\n\t\treturn output;\n\t}\n\n\t/**\n\t * Check if the string contains an operator, and if so, return the operator(s).\n\t * If there are no matches, return null\n\t *\n\t * @param {String} string - the string to check\n\t * @return {Array|null}\n\t */\n\thasOperator(string) {\n\t\treturn this.filterMatches(string.match(this.matchPatterns.operator));\n\t}\n\n\t/**\n\t * Tokenize the sql into parts for additional processing\n\t *\n\t * @param {String} sql\n\t * @return {Object}\n\t */\n\tparseJoin(sql) {\n\t\tlet matches = {};\n\t\tlet output = {\n\t\t\tfunctions: [],\n\t\t\tidentifiers: [],\n\t\t\toperators: [],\n\t\t\tliterals: []\n\t\t};\n\n\t\t// Get clause components\n\t\tmatches.functions = sql.match(new RegExp(this.matchPatterns['function'].source, 'ig'));\n\t\tmatches.identifiers = sql.match(this.matchPatterns.identifier);\n\t\tmatches.operators = sql.match(this.matchPatterns.operator);\n\t\tmatches.literals = sql.match(this.matchPatterns.literal);\n\n\t\t// Get everything at once for ordering\n\t\tmatches.combined = sql.match(this.matchPatterns.joinCombined);\n\n\t\t// Flatten the matches to increase relevance\n\t\tObject.keys(matches).forEach((key) => {\n\t\t\toutput[key] = this.filterMatches(matches[key]);\n\t\t});\n\n\t\treturn output;\n\t}\n\n\t/**\n\t * Return the output of the parsing of the join condition\n\t *\n\t * @param {String} condition - The join condition to evalate\n\t * @return {String} - The parsed/escaped join condition\n\t */\n\tcompileJoin(condition) {\n\t\tlet parts = this.parseJoin(condition);\n\t\tlet count = parts.identifiers.length;\n\t\tlet i;\n\n\t\t// Quote the identifiers\n\t\tparts.combined.forEach((part, i) => {\n\t\t\tif (parts.identifiers.indexOf(part) !== -1 && ! helpers.isNumber(part))\n\t\t\t{\n\t\t\t\tparts.combined[i] = this.driver.quoteIdentifiers(part);\n\t\t\t}\n\t\t});\n\n\t\treturn parts.combined.join(' ');\n\t}\n\n\t/**\n\t * Parse a where clause to separate functions from values\n\t *\n\t * @param {Driver} driver\n\t * @param {State} state\n\t * @return {String} - The parsed/escaped where condition\n\t */\n\tparseWhere(driver, state) {\n\t\tlet whereMap = state.whereMap;\n\t\tlet\twhereValues = state.rawWhereValues;\n\n\t\tlet outputMap = [];\n\t\tlet outputValues = [];\n\n\t\tObject.keys(whereMap).forEach((key) => {\n\t\t\t// Combine fields, operators, functions and values into a full clause\n\t\t\t// to have a common starting flow\n\t\t\tlet fullClause = '';\n\n\t\t\t// Add an explicit = sign where one is inferred\n\t\t\tif ( ! this.hasOperator(key))\n\t\t\t{\n\t\t\t\tfullClause = key + ' = ' + whereMap[key];\n\t\t\t}\n\t\t\telse if (whereMap[key] === key)\n\t\t\t{\n\t\t\t\tfullClause = key;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tfullClause = key + ' ' + whereMap[key];\n\t\t\t}\n\n\t\t\t// Separate the clause into separate pieces\n\t\t\tlet parts = this.parseJoin(fullClause);\n\n\t\t\t// Filter explicit literals from lists of matches\n\t\t\tif (whereValues.indexOf(whereMap[key]) !== -1)\n\t\t\t{\n\t\t\t\tlet value = whereMap[key];\n\t\t\t\tlet identIndex = (helpers.isArray(parts.identifiers)) ? parts.identifiers.indexOf(value) : -1;\n\t\t\t\tlet litIndex = (helpers.isArray(parts.literals)) ? parts.literals.indexOf(value) : -1;\n\t\t\t\tlet combIndex = (helpers.isArray(parts.combined)) ? parts.combined.indexOf(value) : -1;\n\t\t\t\tlet funcIndex = (helpers.isArray(parts.functions)) ? parts.functions.indexOf(value) : -1;\n\t\t\t\tlet inOutputArray = outputValues.indexOf(value) !== -1;\n\n\t\t\t\t// Remove the identifier in question,\n\t\t\t\t// and add to the output values array\n\t\t\t\tif (identIndex !== -1)\n\t\t\t\t{\n\t\t\t\t\tparts.identifiers.splice(identIndex, 1);\n\n\t\t\t\t\tif ( ! inOutputArray)\n\t\t\t\t\t{\n\t\t\t\t\t\toutputValues.push(value);\n\t\t\t\t\t\tinOutputArray = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Remove the value from the literals list\n\t\t\t\t// so it is not added twice\n\t\t\t\tif (litIndex !== -1)\n\t\t\t\t{\n\t\t\t\t\tparts.literals.splice(litIndex, 1);\n\n\t\t\t\t\tif ( ! inOutputArray)\n\t\t\t\t\t{\n\t\t\t\t\t\toutputValues.push(value);\n\t\t\t\t\t\tinOutputArray = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Remove the value from the combined list\n\t\t\t\t// and replace it with a placeholder\n\t\t\t\tif (combIndex !== -1)\n\t\t\t\t{\n\t\t\t\t\t// Make sure to skip functions when replacing values\n\t\t\t\t\tif (funcIndex === -1)\n\t\t\t\t\t{\n\t\t\t\t\t\tparts.combined[combIndex] = '?';\n\n\t\t\t\t\t\tif ( ! inOutputArray)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\toutputValues.push(value);\n\t\t\t\t\t\t\tinOutputArray = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Filter false positive identifiers\n\t\t\tparts.identifiers = parts.identifiers || [];\n\t\t\tparts.identifiers = parts.identifiers.filter((item) => {\n\t\t\t\tlet isInCombinedMatches = parts.combined.indexOf(item) !== -1;\n\t\t\t\tlet isNotInBlackList = this.identifierBlacklist.indexOf(item.toLowerCase()) === -1;\n\n\t\t\t\treturn isInCombinedMatches && isNotInBlackList;\n\t\t\t}, this);\n\n\t\t\t// Quote identifiers\n\t\t\tif (helpers.isArray(parts.identifiers))\n\t\t\t{\n\t\t\t\tparts.identifiers.forEach((ident) => {\n\t\t\t\t\tlet index = parts.combined.indexOf(ident);\n\t\t\t\t\tif (index !== -1)\n\t\t\t\t\t{\n\t\t\t\t\t\tparts.combined[index] = driver.quoteIdentifiers(ident);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// Replace each literal with a placeholder in the map\n\t\t\t// and add the literal to the values,\n\t\t\t// This should only apply to literal values that are not\n\t\t\t// explicitly mapped to values, but have to be parsed from\n\t\t\t// a where condition,\n\t\t\tif (helpers.isArray(parts.literals))\n\t\t\t{\n\t\t\t\tparts.literals.forEach((lit) => {\n\t\t\t\t\tlet litIndex = parts.combined.indexOf(lit);\n\n\t\t\t\t\tif (litIndex !== -1)\n\t\t\t\t\t{\n\t\t\t\t\t\tparts.combined[litIndex] = (helpers.isArray(parts.operators)) ? '?' : '= ?';\n\t\t\t\t\t\toutputValues.push(lit);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\n\t\t\toutputMap.push(parts.combined.join(' '));\n\t\t});\n\n\t\tstate.rawWhereValues = [];\n\t\tstate.whereValues = state.whereValues.concat(outputValues);\n\t\tstate.whereMap = outputMap;\n\n\t\treturn state;\n\t}\n}"],"sourceRoot":"/source/"}
\ No newline at end of file
diff --git a/lib/State.js b/lib/State.js
index f290f7d..1e6a889 100644
--- a/lib/State.js
+++ b/lib/State.js
@@ -1,34 +1,29 @@
-'use strict'
+'use strict';
/** @module State */
-;
+module.exports = class State {
+ constructor() {
+ // Arrays/maps
+ this.queryMap = [];
+ this.values = [];
+ this.whereValues = [];
+ this.setArrayKeys = [];
+ this.orderArray = [];
+ this.groupArray = [];
+ this.havingMap = [];
+ this.whereMap = [];
+ this.rawWhereValues = [];
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+ // Partials
+ this.selectString = '';
+ this.fromString = '';
+ this.setString = '';
+ this.orderString = '';
+ this.groupString = '';
-module.exports = function State() {
- _classCallCheck(this, State);
-
- // Arrays/maps
- this.queryMap = [];
- this.values = [];
- this.whereValues = [];
- this.setArrayKeys = [];
- this.orderArray = [];
- this.groupArray = [];
- this.havingMap = [];
- this.whereMap = [];
- this.rawWhereValues = [];
-
- // Partials
- this.selectString = '';
- this.fromString = '';
- this.setString = '';
- this.orderString = '';
- this.groupString = '';
-
- // Other various values
- this.limit = null;
- this.offset = null;
-};
-// End of module State
-//# sourceMappingURL=State.js.map
+ // Other various values
+ this.limit = null;
+ this.offset = null;
+ }
+}
+// End of module State
\ No newline at end of file
diff --git a/lib/State.js.map b/lib/State.js.map
deleted file mode 100644
index 25d0f9b..0000000
--- a/lib/State.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"sources":["State.js"],"names":[],"mappings":"AAAA;;;AAAY,CAAC;;;;AAGb,MAAM,CAAC,OAAO,GACb,SADsB,KAAK,GACb;uBADQ,KAAK;;;AAG1B,KAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;AACnB,KAAI,CAAC,MAAM,GAAG,EAAE,CAAC;AACjB,KAAI,CAAC,WAAW,GAAG,EAAE,CAAC;AACtB,KAAI,CAAC,YAAY,GAAG,EAAE,CAAC;AACvB,KAAI,CAAC,UAAU,GAAG,EAAE,CAAC;AACrB,KAAI,CAAC,UAAU,GAAG,EAAE,CAAC;AACrB,KAAI,CAAC,SAAS,GAAG,EAAE,CAAC;AACpB,KAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;AACnB,KAAI,CAAC,cAAc,GAAG,EAAE;;;AAAC,AAGzB,KAAI,CAAC,YAAY,GAAG,EAAE,CAAC;AACvB,KAAI,CAAC,UAAU,GAAG,EAAE,CAAC;AACrB,KAAI,CAAC,SAAS,GAAG,EAAE,CAAC;AACpB,KAAI,CAAC,WAAW,GAAG,EAAE,CAAC;AACtB,KAAI,CAAC,WAAW,GAAG,EAAE;;;AAAC,AAGtB,KAAI,CAAC,KAAK,GAAG,IAAI,CAAC;AAClB,KAAI,CAAC,MAAM,GAAG,IAAI,CAAC;CACnB,AACD;;AAAA","file":"State.js","sourcesContent":["'use strict';\n\n/** @module State */\nmodule.exports = class State {\n\tconstructor() {\n\t\t// Arrays/maps\n\t\tthis.queryMap = [];\n\t\tthis.values = [];\n\t\tthis.whereValues = [];\n\t\tthis.setArrayKeys = [];\n\t\tthis.orderArray = [];\n\t\tthis.groupArray = [];\n\t\tthis.havingMap = [];\n\t\tthis.whereMap = [];\n\t\tthis.rawWhereValues = [];\n\n\t\t// Partials\n\t\tthis.selectString = '';\n\t\tthis.fromString = '';\n\t\tthis.setString = '';\n\t\tthis.orderString = '';\n\t\tthis.groupString = '';\n\n\t\t// Other various values\n\t\tthis.limit = null;\n\t\tthis.offset = null;\n\t}\n}\n// End of module State"],"sourceRoot":"/source/"}
\ No newline at end of file
diff --git a/lib/adapters/dblite.js b/lib/adapters/dblite.js
index 3640241..e649d2d 100644
--- a/lib/adapters/dblite.js
+++ b/lib/adapters/dblite.js
@@ -1,50 +1,19 @@
'use strict';
-var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+let Adapter = require('../Adapter'),
+ getArgs = require('getargs');
-var _Adapter2 = require('../Adapter');
-
-var _Adapter3 = _interopRequireDefault(_Adapter2);
-
-var _getargs = require('getargs');
-
-var _getargs2 = _interopRequireDefault(_getargs);
-
-function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
-
-function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
-
-/** @module adapters/dblite */
-module.exports = (function (_Adapter) {
- _inherits(dblite, _Adapter);
-
- function dblite() {
- _classCallCheck(this, dblite);
-
- return _possibleConstructorReturn(this, Object.getPrototypeOf(dblite).apply(this, arguments));
+module.exports = class dblite extends Adapter {
+ /**
+ * Run the sql query as a prepared statement
+ *
+ * @param {String} sql - The sql with placeholders
+ * @param {Array} params - The values to insert into the query
+ * @param {Function} callback - Callback to run when a response is recieved
+ * @return {void}
+ */
+ execute(/*sql, params, callback*/) {
+ let args = getArgs('sql:string, [params]:array, callback:function', arguments);
+ this.instance.query(args.sql, args.params, args.callback);
}
-
- _createClass(dblite, [{
- key: 'execute',
-
- /**
- * Run the sql query as a prepared statement
- *
- * @param {String} sql - The sql with placeholders
- * @param {Array} params - The values to insert into the query
- * @param {Function} callback - Callback to run when a response is recieved
- * @return void
- */
- value: function execute() /*sql, params, callback*/{
- var args = (0, _getargs2.default)('sql:string, [params]:array, callback:function', arguments);
- this.instance.query(args.sql, args.params, args.callback);
- }
- }]);
-
- return dblite;
-})(_Adapter3.default);
-//# sourceMappingURL=dblite.js.map
+}
\ No newline at end of file
diff --git a/lib/adapters/dblite.js.map b/lib/adapters/dblite.js.map
deleted file mode 100644
index 9579bdd..0000000
--- a/lib/adapters/dblite.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"sources":["dblite.js"],"names":[],"mappings":"AAAA,YAAY,CAAC;;;;;;;;;;;;;;;;;;;;;AAMb,MAAM,CAAC,OAAO;WAAS,MAAM;;UAAN,MAAM;wBAAN,MAAM;;gEAAN,MAAM;;;cAAN,MAAM;;;;;;;;;;;qDASO;AAClC,OAAI,IAAI,GAAG,uBAAQ,+CAA+C,EAAE,SAAS,CAAC,CAAC;AAC/E,OAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;GAC1D;;;QAZqB,MAAM;qBAa5B,CAAA","file":"adapters/dblite.js","sourcesContent":["'use strict';\n\nimport Adapter from '../Adapter';\nimport getArgs from 'getargs';\n\n/** @module adapters/dblite */\nmodule.exports = class dblite extends Adapter {\n\t/**\n\t * Run the sql query as a prepared statement\n\t *\n\t * @param {String} sql - The sql with placeholders\n\t * @param {Array} params - The values to insert into the query\n\t * @param {Function} callback - Callback to run when a response is recieved\n\t * @return void\n\t */\n\texecute(/*sql, params, callback*/) {\n\t\tlet args = getArgs('sql:string, [params]:array, callback:function', arguments);\n\t\tthis.instance.query(args.sql, args.params, args.callback);\n\t};\n}"],"sourceRoot":"/source/"}
\ No newline at end of file
diff --git a/lib/adapters/mysql.js b/lib/adapters/mysql.js
index 9e934ab..f09da40 100644
--- a/lib/adapters/mysql.js
+++ b/lib/adapters/mysql.js
@@ -1,45 +1,20 @@
'use strict';
-var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+let Adapter = require('../Adapter'),
+ getArgs = require('getargs');
-var _Adapter2 = require('../Adapter');
-
-var _Adapter3 = _interopRequireDefault(_Adapter2);
-
-function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
-
-function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
-
-/** @module adapters/mysql */
-module.exports = (function (_Adapter) {
- _inherits(mysql, _Adapter);
-
- function mysql() {
- _classCallCheck(this, mysql);
-
- return _possibleConstructorReturn(this, Object.getPrototypeOf(mysql).apply(this, arguments));
+module.exports = class mysql extends Adapter {
+ /**
+ * Run the sql query as a prepared statement
+ *
+ * @param {String} sql - The sql with placeholders
+ * @param {Array} params - The values to insert into the query
+ * @param {Function} callback - Callback to run when a response is recieved
+ * @return {void}
+ */
+ execute(sql, params, callback) {
+ let args = getArgs('sql:string, [params], callback:function', arguments);
+ return this.instance.query(args.sql, args.params, args.callback);
+ //this.instance.query.apply(this.instance, Array(args));
}
-
- _createClass(mysql, [{
- key: 'execute',
-
- /**
- * Run the sql query as a prepared statement
- *
- * @param {String} sql - The sql with placeholders
- * @param {Array} params - The values to insert into the query
- * @param {Function} callback - Callback to run when a response is recieved
- * @return void
- */
- value: function execute(sql, params, callback) {
- this.instance.query.apply(instance, arguments);
- }
- }]);
-
- return mysql;
-})(_Adapter3.default);
-//# sourceMappingURL=mysql.js.map
+}
\ No newline at end of file
diff --git a/lib/adapters/mysql.js.map b/lib/adapters/mysql.js.map
deleted file mode 100644
index 4d83827..0000000
--- a/lib/adapters/mysql.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"sources":["mysql.js"],"names":[],"mappings":"AAAA,YAAY,CAAC;;;;;;;;;;;;;;;;;AAKb,MAAM,CAAC,OAAO;WAAS,KAAK;;UAAL,KAAK;wBAAL,KAAK;;gEAAL,KAAK;;;cAAL,KAAK;;;;;;;;;;;0BASnB,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE;AAC9B,OAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;GAC/C;;;QAXqB,KAAK;qBAY3B,CAAA","file":"adapters/mysql.js","sourcesContent":["'use strict';\n\nimport Adapter from '../Adapter';\n\n/** @module adapters/mysql */\nmodule.exports = class mysql extends Adapter {\n\t/**\n\t * Run the sql query as a prepared statement\n\t *\n\t * @param {String} sql - The sql with placeholders\n\t * @param {Array} params - The values to insert into the query\n\t * @param {Function} callback - Callback to run when a response is recieved\n\t * @return void\n\t */\n\texecute(sql, params, callback) {\n\t\tthis.instance.query.apply(instance, arguments);\n\t}\n}"],"sourceRoot":"/source/"}
\ No newline at end of file
diff --git a/lib/adapters/mysql2.js b/lib/adapters/mysql2.js
index ed73744..f559f88 100644
--- a/lib/adapters/mysql2.js
+++ b/lib/adapters/mysql2.js
@@ -1,45 +1,20 @@
'use strict';
-var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+let Adapter = require('../Adapter'),
+ getArgs = require('getargs');
-var _Adapter2 = require('../Adapter');
-
-var _Adapter3 = _interopRequireDefault(_Adapter2);
-
-function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
-
-function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
-
-/** @module adapters/mysql2 */
-module.exports = (function (_Adapter) {
- _inherits(mysql2, _Adapter);
-
- function mysql2() {
- _classCallCheck(this, mysql2);
-
- return _possibleConstructorReturn(this, Object.getPrototypeOf(mysql2).apply(this, arguments));
+module.exports = class mysql2 extends Adapter {
+ /**
+ * Run the sql query as a prepared statement
+ *
+ * @param {String} sql - The sql with placeholders
+ * @param {Array} params - The values to insert into the query
+ * @param {Function} callback - Callback to run when a response is recieved
+ * @return {void}
+ */
+ execute(/*sql, params, callback*/) {
+ let args = getArgs('sql:string, [params], callback:function', arguments);
+ return this.instance.execute(args.sql, args.params, args.callback);
+ //this.instance.execute.apply(this.instance, args);
}
-
- _createClass(mysql2, [{
- key: 'execute',
-
- /**
- * Run the sql query as a prepared statement
- *
- * @param {String} sql - The sql with placeholders
- * @param {Array} params - The values to insert into the query
- * @param {Function} callback - Callback to run when a response is recieved
- * @return void
- */
- value: function execute(sql, params, callback) {
- this.instance.execute.apply(this.instance, arguments);
- }
- }]);
-
- return mysql2;
-})(_Adapter3.default);
-//# sourceMappingURL=mysql2.js.map
+}
\ No newline at end of file
diff --git a/lib/adapters/mysql2.js.map b/lib/adapters/mysql2.js.map
deleted file mode 100644
index 7be47b9..0000000
--- a/lib/adapters/mysql2.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"sources":["mysql2.js"],"names":[],"mappings":"AAAA,YAAY,CAAC;;;;;;;;;;;;;;;;;AAKb,MAAM,CAAC,OAAO;WAAS,MAAM;;UAAN,MAAM;wBAAN,MAAM;;gEAAN,MAAM;;;cAAN,MAAM;;;;;;;;;;;0BASpB,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE;AAC9B,OAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;GACtD;;;QAXqB,MAAM;qBAY5B,CAAA","file":"adapters/mysql2.js","sourcesContent":["'use strict';\n\nimport Adapter from '../Adapter';\n\n/** @module adapters/mysql2 */\nmodule.exports = class mysql2 extends Adapter {\n\t/**\n\t * Run the sql query as a prepared statement\n\t *\n\t * @param {String} sql - The sql with placeholders\n\t * @param {Array} params - The values to insert into the query\n\t * @param {Function} callback - Callback to run when a response is recieved\n\t * @return void\n\t */\n\texecute(sql, params, callback) {\n\t\tthis.instance.execute.apply(this.instance, arguments);\n\t};\n}"],"sourceRoot":"/source/"}
\ No newline at end of file
diff --git a/lib/adapters/node-firebird.js b/lib/adapters/node-firebird.js
index a8a2ff5..83ac9e4 100644
--- a/lib/adapters/node-firebird.js
+++ b/lib/adapters/node-firebird.js
@@ -1,50 +1,19 @@
'use strict';
-var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+let Adapter = require('../Adapter'),
+ getArgs = require('getargs');
-var _Adapter2 = require('../Adapter');
-
-var _Adapter3 = _interopRequireDefault(_Adapter2);
-
-var _getargs = require('getargs');
-
-var _getargs2 = _interopRequireDefault(_getargs);
-
-function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
-
-function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
-
-/** @module adapters/node-firebird */
-module.exports = (function (_Adapter) {
- _inherits(nodefirebird, _Adapter);
-
- function nodefirebird() {
- _classCallCheck(this, nodefirebird);
-
- return _possibleConstructorReturn(this, Object.getPrototypeOf(nodefirebird).apply(this, arguments));
+module.exports = class nodefirebird extends Adapter {
+ /**
+ * Run the sql query as a prepared statement
+ *
+ * @param {String} sql - The sql with placeholders
+ * @param {Array} params - The values to insert into the query
+ * @param {Function} callback - Callback to run when a response is recieved
+ * @return {void}
+ */
+ execute(/*sql, params, callback*/) {
+ let args = getArgs('sql:string, [params], callback:function', arguments);
+ return this.instance.execute(args.sql, args.params, args.callback);
}
-
- _createClass(nodefirebird, [{
- key: 'execute',
-
- /**
- * Run the sql query as a prepared statement
- *
- * @param {String} sql - The sql with placeholders
- * @param {Array} params - The values to insert into the query
- * @param {Function} callback - Callback to run when a response is recieved
- * @return void
- */
- value: function execute() /*sql, params, callback*/{
- var args = (0, _getargs2.default)('sql:string, [params], callback:function', arguments);
- this.instance.execute(args.sql, args.params, args.callback);
- }
- }]);
-
- return nodefirebird;
-})(_Adapter3.default);
-//# sourceMappingURL=node-firebird.js.map
+}
\ No newline at end of file
diff --git a/lib/adapters/node-firebird.js.map b/lib/adapters/node-firebird.js.map
deleted file mode 100644
index b29163d..0000000
--- a/lib/adapters/node-firebird.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"sources":["node-firebird.js"],"names":[],"mappings":"AAAA,YAAY,CAAC;;;;;;;;;;;;;;;;;;;;;AAMb,MAAM,CAAC,OAAO;WAAS,YAAY;;UAAZ,YAAY;wBAAZ,YAAY;;gEAAZ,YAAY;;;cAAZ,YAAY;;;;;;;;;;;qDASC;AAClC,OAAI,IAAI,GAAG,uBAAQ,yCAAyC,EAAE,SAAS,CAAC,CAAC;AACzE,OAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;GAC5D;;;QAZqB,YAAY;qBAalC,CAAA","file":"adapters/node-firebird.js","sourcesContent":["'use strict';\n\nimport Adapter from '../Adapter';\nimport getArgs from 'getargs';\n\n/** @module adapters/node-firebird */\nmodule.exports = class nodefirebird extends Adapter {\n\t/**\n\t * Run the sql query as a prepared statement\n\t *\n\t * @param {String} sql - The sql with placeholders\n\t * @param {Array} params - The values to insert into the query\n\t * @param {Function} callback - Callback to run when a response is recieved\n\t * @return void\n\t */\n\texecute(/*sql, params, callback*/) {\n\t\tlet args = getArgs('sql:string, [params], callback:function', arguments);\n\t\tthis.instance.execute(args.sql, args.params, args.callback);\n\t}\n}"],"sourceRoot":"/source/"}
\ No newline at end of file
diff --git a/lib/adapters/pg.js b/lib/adapters/pg.js
index 05a211e..a51e57d 100644
--- a/lib/adapters/pg.js
+++ b/lib/adapters/pg.js
@@ -1,58 +1,27 @@
'use strict';
-var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+let Adapter = require('../Adapter'),
+ getArgs = require('getargs');
-var _Adapter2 = require('../Adapter');
+module.exports = class pg extends Adapter {
+ /**
+ * Run the sql query as a prepared statement
+ *
+ * @param {String} sql - The sql with placeholders
+ * @param {Array} params - The values to insert into the query
+ * @param {Function} callback - Callback to run when a response is recieved
+ * @return {void}
+ */
+ execute(/*sql, params, callback*/) {
+ let args = getArgs('sql:string, [params]:array, callback:function', arguments);
-var _Adapter3 = _interopRequireDefault(_Adapter2);
+ // Replace question marks with numbered placeholders, because this adapter is different...
+ let count = 0;
+ args.sql = args.sql.replace(/\?/g, () => {
+ count++;
+ return '$' + count;
+ });
-var _getargs = require('getargs');
-
-var _getargs2 = _interopRequireDefault(_getargs);
-
-function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
-
-function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
-
-/** @module adapters/pg */
-module.exports = (function (_Adapter) {
- _inherits(pg, _Adapter);
-
- function pg() {
- _classCallCheck(this, pg);
-
- return _possibleConstructorReturn(this, Object.getPrototypeOf(pg).apply(this, arguments));
+ this.instance.query(args.sql, args.params, args.callback);
}
-
- _createClass(pg, [{
- key: 'execute',
-
- /**
- * Run the sql query as a prepared statement
- *
- * @param {String} sql - The sql with placeholders
- * @param {Array} params - The values to insert into the query
- * @param {Function} callback - Callback to run when a response is recieved
- * @return void
- */
- value: function execute() /*sql, params, callback*/{
- var args = (0, _getargs2.default)('sql:string, [params]:array, callback:function', arguments);
-
- // Replace question marks with numbered placeholders, because this adapter is different...
- var count = 0;
- args.sql = args.sql.replace(/\?/g, function () {
- count++;
- return '$' + count;
- });
-
- this.instance.query(args.sql, args.params, args.callback);
- }
- }]);
-
- return pg;
-})(_Adapter3.default);
-//# sourceMappingURL=pg.js.map
+}
\ No newline at end of file
diff --git a/lib/adapters/pg.js.map b/lib/adapters/pg.js.map
deleted file mode 100644
index fa33d5f..0000000
--- a/lib/adapters/pg.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"sources":["pg.js"],"names":[],"mappings":"AAAA,YAAY,CAAC;;;;;;;;;;;;;;;;;;;;;AAMb,MAAM,CAAC,OAAO;WAAS,EAAE;;UAAF,EAAE;wBAAF,EAAE;;gEAAF,EAAE;;;cAAF,EAAE;;;;;;;;;;;qDASW;AAClC,OAAI,IAAI,GAAG,uBAAQ,+CAA+C,EAAE,SAAS,CAAC;;;AAAC,AAG/E,OAAI,KAAK,GAAG,CAAC,CAAC;AACd,OAAI,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,YAAM;AACxC,SAAK,EAAE,CAAC;AACR,WAAO,GAAG,GAAG,KAAK,CAAC;IACnB,CAAC,CAAC;;AAEH,OAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;GAC1D;;;QApBqB,EAAE;qBAqBxB,CAAA","file":"adapters/pg.js","sourcesContent":["'use strict';\n\nimport Adapter from '../Adapter';\nimport getArgs from 'getargs';\n\n/** @module adapters/pg */\nmodule.exports = class pg extends Adapter {\n\t/**\n\t * Run the sql query as a prepared statement\n\t *\n\t * @param {String} sql - The sql with placeholders\n\t * @param {Array} params - The values to insert into the query\n\t * @param {Function} callback - Callback to run when a response is recieved\n\t * @return void\n\t */\n\texecute(/*sql, params, callback*/) {\n\t\tlet args = getArgs('sql:string, [params]:array, callback:function', arguments);\n\n\t\t// Replace question marks with numbered placeholders, because this adapter is different...\n\t\tlet count = 0;\n\t\targs.sql = args.sql.replace(/\\?/g, () => {\n\t\t\tcount++;\n\t\t\treturn '$' + count;\n\t\t});\n\n\t\tthis.instance.query(args.sql, args.params, args.callback);\n\t}\n}"],"sourceRoot":"/source/"}
\ No newline at end of file
diff --git a/lib/drivers/Firebird.js b/lib/drivers/Firebird.js
index 8b9143f..51ffd67 100644
--- a/lib/drivers/Firebird.js
+++ b/lib/drivers/Firebird.js
@@ -1,78 +1,44 @@
"use strict";
-var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+let helpers = require('../helpers'),
+ Driver = require('../DriverClass');
-var _helpers = require('../helpers');
-
-var _helpers2 = _interopRequireDefault(_helpers);
-
-var _DriverClass = require('../DriverClass');
-
-var _DriverClass2 = _interopRequireDefault(_DriverClass);
-
-function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
-
-function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
-
-/**
- * Driver for Firebird databases
- *
- * @module drivers/firebird
- */
-
-var Firebird = (function (_Driver) {
- _inherits(Firebird, _Driver);
-
- function Firebird() {
- _classCallCheck(this, Firebird);
-
- return _possibleConstructorReturn(this, Object.getPrototypeOf(Firebird).call(this, {
+class Firebird extends Driver {
+ constructor() {
+ super({
hasTruncate: false
- }));
+ });
}
/**
- * Generate a limit clause for firebird, which uses the syntax closest to the SQL standard
- *
- * @param {String} sql
- * @param {Number} limit
- * @param {Number} offset
- * @return {String}
- */
+ * 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
+ */
+ limit(origSql, limit, offset) {
+ let sql = `FIRST ${limit}`;
- _createClass(Firebird, [{
- key: 'limit',
- value: function limit(origSql, _limit, offset) {
- var sql = 'FIRST ' + _limit;
-
- if (_helpers2.default.isNumber(offset)) {
- sql += ' SKIP ' + offset;
- }
-
- return origSql.replace(/SELECT/i, "SELECT " + sql);
+ if (helpers.isNumber(offset))
+ {
+ sql += ` SKIP ${offset}`;
}
- /**
- * SQL to insert a group of rows
- *
- * @param {String} table - The table to insert to
- * @param {Array} [data] - The array of object containing data to insert
- * @return {String}
- */
+ return origSql.replace(/SELECT/i, "SELECT " + sql);
+ }
- }, {
- key: 'insertBatch',
- value: function insertBatch() {
- throw new Error("Not Implemented");
- }
- }]);
+ /**
+ * SQL to insert a group of rows
+ *
+ * @param {String} table - The table to insert to
+ * @param {Array} [data] - The array of object containing data to insert
+ * @return {String} - Query and data to insert
+ */
+ insertBatch() {
+ throw new Error("Not Implemented");
+ }
+}
- return Firebird;
-})(_DriverClass2.default);
-
-module.exports = new Firebird();
-//# sourceMappingURL=Firebird.js.map
+module.exports = new Firebird();
\ No newline at end of file
diff --git a/lib/drivers/Firebird.js.map b/lib/drivers/Firebird.js.map
deleted file mode 100644
index 51e756b..0000000
--- a/lib/drivers/Firebird.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"sources":["Firebird.js"],"names":[],"mappings":"AAAA,YAAY,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;IAUP,QAAQ;WAAR,QAAQ;;AACb,UADK,QAAQ,GACC;wBADT,QAAQ;;gEAAR,QAAQ,aAEN;AACL,cAAW,EAAE,KAAK;GAClB;EACD;;;;;;;;;;AAAA;cALI,QAAQ;;wBAeP,OAAO,EAAE,MAAK,EAAE,MAAM,EAAE;AAC7B,OAAI,GAAG,eAAa,MAAK,AAAE,CAAC;;AAE5B,OAAI,kBAAQ,QAAQ,CAAC,MAAM,CAAC,EAC5B;AACC,OAAG,gBAAc,MAAM,AAAE,CAAC;IAC1B;;AAED,UAAO,OAAO,CAAC,OAAO,CAAC,SAAS,EAAE,SAAS,GAAG,GAAG,CAAC,CAAC;GACnD;;;;;;;;;;;;gCASa;AACb,SAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;GACnC;;;QAnCI,QAAQ;;;AAsCd,MAAM,CAAC,OAAO,GAAG,IAAI,QAAQ,EAAE,CAAC","file":"drivers/Firebird.js","sourcesContent":["\"use strict\";\n\nimport helpers from '../helpers';\nimport Driver from '../DriverClass';\n\n/**\n * Driver for Firebird databases\n *\n * @module drivers/firebird\n */\nclass Firebird extends Driver {\n\tconstructor() {\n\t\tsuper({\n\t\t\thasTruncate: false\n\t\t});\n\t}\n\n\t/**\n\t * Generate a limit clause for firebird, which uses the syntax closest to the SQL standard\n\t *\n\t * @param {String} sql\n\t * @param {Number} limit\n\t * @param {Number} offset\n\t * @return {String}\n\t */\n\tlimit(origSql, limit, offset) {\n\t\tlet sql = `FIRST ${limit}`;\n\n\t\tif (helpers.isNumber(offset))\n\t\t{\n\t\t\tsql += ` SKIP ${offset}`;\n\t\t}\n\n\t\treturn origSql.replace(/SELECT/i, \"SELECT \" + sql);\n\t}\n\n\t/**\n\t * SQL to insert a group of rows\n\t *\n\t * @param {String} table - The table to insert to\n\t * @param {Array} [data] - The array of object containing data to insert\n\t * @return {String}\n\t */\n\tinsertBatch() {\n\t\tthrow new Error(\"Not Implemented\");\n\t}\n}\n\nmodule.exports = new Firebird();"],"sourceRoot":"/source/"}
\ No newline at end of file
diff --git a/lib/drivers/Mysql.js b/lib/drivers/Mysql.js
index a52450e..a1f9ea7 100755
--- a/lib/drivers/Mysql.js
+++ b/lib/drivers/Mysql.js
@@ -1,54 +1,32 @@
"use strict";
-var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+let helpers = require('../helpers'),
+ Driver = require('../DriverClass');
-var _helpers = require('../helpers');
-
-var _helpers2 = _interopRequireDefault(_helpers);
-
-var _DriverClass = require('../DriverClass');
-
-var _DriverClass2 = _interopRequireDefault(_DriverClass);
-
-function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
-
-function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
-
-/**
- * Driver for MySQL databases
- *
- * @module drivers/mysql
- */
-
-var Mysql = (function (_Driver) {
- _inherits(Mysql, _Driver);
-
- function Mysql() {
- _classCallCheck(this, Mysql);
-
- return _possibleConstructorReturn(this, Object.getPrototypeOf(Mysql).call(this, {
+class Mysql extends Driver {
+ constructor() {
+ super({
identifierStartChar: '`',
identifierEndChar: '`'
- }));
+ });
}
- _createClass(Mysql, [{
- key: 'limit',
- value: function limit(sql, _limit, offset) {
- if (!_helpers2.default.isNumber(offset)) {
- return sql += ' LIMIT ' + _limit;
- }
-
- return sql += ' LIMIT ' + offset + ', ' + _limit;
+ /**
+ * 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
+ */
+ limit(sql, limit, offset) {
+ if ( ! helpers.isNumber(offset))
+ {
+ return sql += ` LIMIT ${limit}`;
}
- }]);
- return Mysql;
-})(_DriverClass2.default);
+ return sql += ` LIMIT ${offset}, ${limit}`;
+ }
+}
-module.exports = new Mysql();
-//# sourceMappingURL=Mysql.js.map
+module.exports = new Mysql();
\ No newline at end of file
diff --git a/lib/drivers/Mysql.js.map b/lib/drivers/Mysql.js.map
deleted file mode 100644
index 0db23ec..0000000
--- a/lib/drivers/Mysql.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"sources":["Mysql.js"],"names":[],"mappings":"AAAA,YAAY,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;IAUP,KAAK;WAAL,KAAK;;AACV,UADK,KAAK,GACI;wBADT,KAAK;;gEAAL,KAAK,aAEH;AACL,sBAAmB,EAAE,GAAG;AACxB,oBAAiB,EAAE,GAAG;GACtB;EACD;;cANI,KAAK;;wBAQJ,GAAG,EAAE,MAAK,EAAE,MAAM,EAAE;AACzB,OAAK,CAAE,kBAAQ,QAAQ,CAAC,MAAM,CAAC,EAC/B;AACC,WAAO,GAAG,gBAAc,MAAK,AAAE,CAAC;IAChC;;AAED,UAAO,GAAG,gBAAc,MAAM,UAAK,MAAK,AAAE,CAAC;GAC3C;;;QAfI,KAAK;;;AAkBX,MAAM,CAAC,OAAO,GAAG,IAAI,KAAK,EAAE,CAAC","file":"drivers/Mysql.js","sourcesContent":["\"use strict\";\n\nimport helpers from '../helpers';\nimport Driver from '../DriverClass';\n\n/**\n * Driver for MySQL databases\n *\n * @module drivers/mysql\n */\nclass Mysql extends Driver {\n\tconstructor() {\n\t\tsuper({\n\t\t\tidentifierStartChar: '`',\n\t\t\tidentifierEndChar: '`'\n\t\t});\n\t}\n\n\tlimit(sql, limit, offset) {\n\t\tif ( ! helpers.isNumber(offset))\n\t\t{\n\t\t\treturn sql += ` LIMIT ${limit}`;\n\t\t}\n\n\t\treturn sql += ` LIMIT ${offset}, ${limit}`;\n\t}\n}\n\nmodule.exports = new Mysql();"],"sourceRoot":"/source/"}
\ No newline at end of file
diff --git a/lib/drivers/Pg.js b/lib/drivers/Pg.js
index 2de962c..89a6a48 100755
--- a/lib/drivers/Pg.js
+++ b/lib/drivers/Pg.js
@@ -1,15 +1,10 @@
"use strict";
-var _DriverClass = require("../DriverClass");
-
-var _DriverClass2 = _interopRequireDefault(_DriverClass);
-
-function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+let Driver = require('../DriverClass');
/**
* Driver for PostgreSQL databases
*
* @module drivers/pg
*/
-module.exports = new _DriverClass2.default();
-//# sourceMappingURL=Pg.js.map
+module.exports = new Driver();
\ No newline at end of file
diff --git a/lib/drivers/Pg.js.map b/lib/drivers/Pg.js.map
deleted file mode 100644
index 4537eb6..0000000
--- a/lib/drivers/Pg.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"sources":["Pg.js"],"names":[],"mappings":"AAAA,YAAY,CAAC;;;;;;;;;;;;;AASb,MAAM,CAAC,OAAO,GAAG,2BAAY,CAAC","file":"drivers/Pg.js","sourcesContent":["\"use strict\";\n\nimport Driver from '../DriverClass';\n\n/**\n * Driver for PostgreSQL databases\n *\n * @module drivers/pg\n */\nmodule.exports = new Driver();"],"sourceRoot":"/source/"}
\ No newline at end of file
diff --git a/lib/drivers/Sqlite.js b/lib/drivers/Sqlite.js
index c748268..30f0d7b 100644
--- a/lib/drivers/Sqlite.js
+++ b/lib/drivers/Sqlite.js
@@ -1,94 +1,66 @@
"use strict";
-var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+let helpers = require('../helpers'),
+ Driver = require('../DriverClass');
-var _helpers = require('../helpers');
-
-var _helpers2 = _interopRequireDefault(_helpers);
-
-var _DriverClass = require('../DriverClass');
-
-var _DriverClass2 = _interopRequireDefault(_DriverClass);
-
-function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
-
-function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
-
-/**
- * Driver for Sqlite databases
- *
- * @module drivers/sqlite
- */
-
-var Sqlite = (function (_Driver) {
- _inherits(Sqlite, _Driver);
-
- function Sqlite() {
- _classCallCheck(this, Sqlite);
-
- var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(Sqlite).call(this));
-
- _this.hasTruncate = false;
- return _this;
+class Sqlite extends Driver {
+ constructor() {
+ super({
+ hasTruncate: false
+ });
}
- _createClass(Sqlite, [{
- key: 'insertBatch',
- value: function insertBatch(table, data) {
- var _this2 = this;
+ /**
+ * SQL to insert a group of rows
+ *
+ * @param {String} table - The table to insert to
+ * @param {Array} [data] - The array of object containing data to insert
+ * @return {String} - Query and data to insert
+ */
+ insertBatch(table, data) {
+ // Get the data values to insert, so they can
+ // be parameterized
+ let sql = "",
+ vals = [],
+ cols = [],
+ fields = [],
+ first = data.shift(),
+ params = [],
+ paramString = "",
+ paramList = [];
- // Get the data values to insert, so they can
- // be parameterized
- var sql = "",
- vals = [],
- cols = [],
- fields = [],
- first = data.shift(),
- params = [],
- paramString = "",
- paramList = [];
- data.forEach(function (obj) {
- var row = [];
- Object.keys(obj).forEach(function (key) {
- row.push(obj[key]);
- });
- vals.push(row);
+ data.forEach(obj => {
+ let row = [];
+ Object.keys(obj).forEach(key => {
+ row.push(obj[key]);
});
+ vals.push(row);
+ });
- sql += "INSERT INTO " + this.quoteTable(table) + "\n";
+ sql += "INSERT INTO " + this.quoteTable(table) + "\n";
- // Get the field names from the keys of the first
- // object to be inserted
- fields = Object.keys(first);
- Object.keys(first).forEach(function (key) {
- cols.push("'" + _this2._quote(first[key]) + "' AS " + _this2.quoteIdentifiers(key));
+ // Get the field names from the keys of the first
+ // object to be inserted
+ fields = Object.keys(first);
+ Object.keys(first).forEach(key => {
+ cols.push("'" + this._quote(first[key]) + "' AS " + this.quoteIdentifiers(key));
+ });
+
+ sql += "SELECT " + cols.join(', ') + "\n";
+
+ vals.forEach(row_values => {
+ let quoted = row_values.map(value => {
+ return String(value).replace("'", "'\'");
});
+ sql += "UNION ALL SELECT '" + quoted.join("', '") + "'\n";
+ });
- sql += "SELECT " + cols.join(', ') + "\n";
+ return {
+ sql: sql,
+ values: null
+ };
+ }
+}
- vals.forEach(function (row_values) {
- var quoted = row_values.map(function (value) {
- return String(value).replace("'", "'\'");
- });
- sql += "UNION ALL SELECT '" + quoted.join("', '") + "'\n";
- });
-
- return {
- sql: sql,
- values: null
- };
- }
- }]);
-
- return Sqlite;
-})(_DriverClass2.default);
-
-;
-
-module.exports = new Sqlite();
-//# sourceMappingURL=Sqlite.js.map
+module.exports = new Sqlite();
\ No newline at end of file
diff --git a/lib/drivers/Sqlite.js.map b/lib/drivers/Sqlite.js.map
deleted file mode 100644
index 3306c4d..0000000
--- a/lib/drivers/Sqlite.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"sources":["Sqlite.js"],"names":[],"mappings":"AAAA,YAAY,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;IAUP,MAAM;WAAN,MAAM;;AACX,UADK,MAAM,GACG;wBADT,MAAM;;qEAAN,MAAM;;AAGV,QAAK,WAAW,GAAG,KAAK,CAAC;;EACzB;;cAJI,MAAM;;8BAMC,KAAK,EAAE,IAAI,EAAE;;;;;AAIxB,OAAI,GAAG,GAAG,EAAE;OACX,IAAI,GAAG,EAAE;OACT,IAAI,GAAG,EAAE;OACT,MAAM,GAAG,EAAE;OACX,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE;OACpB,MAAM,GAAG,EAAE;OACX,WAAW,GAAG,EAAE;OAChB,SAAS,GAAG,EAAE,CAAC;;AAGhB,OAAI,CAAC,OAAO,CAAC,UAAC,GAAG,EAAK;AACrB,QAAI,GAAG,GAAG,EAAE,CAAC;AACb,UAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,UAAC,GAAG,EAAK;AACjC,QAAG,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;KACnB,CAAC,CAAC;AACH,QAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACf,CAAC,CAAC;;AAEH,MAAG,IAAI,cAAc,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,IAAI;;;;AAAC,AAItD,SAAM,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC5B,SAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,UAAC,GAAG,EAAK;AACnC,QAAI,CAAC,IAAI,CAAC,GAAG,GAAG,OAAK,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,OAAO,GAAG,OAAK,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC;IAChF,CAAC,CAAC;;AAEH,MAAG,IAAI,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;;AAE1C,OAAI,CAAC,OAAO,CAAC,UAAC,UAAU,EAAK;AAC5B,QAAI,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,UAAC,KAAK,EAAK;AACtC,YAAO,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;KACzC,CAAC,CAAC;AACH,OAAG,IAAI,oBAAoB,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,KAAK,CAAC;IAC1D,CAAC,CAAC;;AAEH,UAAO;AACN,OAAG,EAAE,GAAG;AACR,UAAM,EAAE,IAAI;IACZ,CAAC;GACF;;;QAlDI,MAAM;;;AAmDX,CAAC;;AAEF,MAAM,CAAC,OAAO,GAAG,IAAI,MAAM,EAAE,CAAC","file":"drivers/Sqlite.js","sourcesContent":["\"use strict\";\n\nimport helpers from '../helpers';\nimport Driver from '../DriverClass';\n\n/**\n * Driver for Sqlite databases\n *\n * @module drivers/sqlite\n */\nclass Sqlite extends Driver {\n\tconstructor() {\n\t\tsuper();\n\t\tthis.hasTruncate = false;\n\t}\n\n\tinsertBatch(table, data) {\n\n\t\t// Get the data values to insert, so they can\n\t\t// be parameterized\n\t\tlet sql = \"\",\n\t\t\tvals = [],\n\t\t\tcols = [],\n\t\t\tfields = [],\n\t\t\tfirst = data.shift(),\n\t\t\tparams = [],\n\t\t\tparamString = \"\",\n\t\t\tparamList = [];\n\n\n\t\tdata.forEach((obj) => {\n\t\t\tlet row = [];\n\t\t\tObject.keys(obj).forEach((key) => {\n\t\t\t\trow.push(obj[key]);\n\t\t\t});\n\t\t\tvals.push(row);\n\t\t});\n\n\t\tsql += \"INSERT INTO \" + this.quoteTable(table) + \"\\n\";\n\n\t\t// Get the field names from the keys of the first\n\t\t// object to be inserted\n\t\tfields = Object.keys(first);\n\t\tObject.keys(first).forEach((key) => {\n\t\t\tcols.push(\"'\" + this._quote(first[key]) + \"' AS \" + this.quoteIdentifiers(key));\n\t\t});\n\n\t\tsql += \"SELECT \" + cols.join(', ') + \"\\n\";\n\n\t\tvals.forEach((row_values) => {\n\t\t\tlet quoted = row_values.map((value) => {\n\t\t\t\treturn String(value).replace(\"'\", \"'\\'\");\n\t\t\t});\n\t\t\tsql += \"UNION ALL SELECT '\" + quoted.join(\"', '\") + \"'\\n\";\n\t\t});\n\n\t\treturn {\n\t\t\tsql: sql,\n\t\t\tvalues: null\n\t\t};\n\t}\n};\n\nmodule.exports = new Sqlite();"],"sourceRoot":"/source/"}
\ No newline at end of file
diff --git a/lib/helpers.js b/lib/helpers.js
index d5aefd3..259814b 100755
--- a/lib/helpers.js
+++ b/lib/helpers.js
@@ -1,66 +1,62 @@
-"use strict"
+"use strict";
-//require('es6-shim');
-
-;
-var helpers = {
+let helpers = {
/**
- * Wrap String.prototype.trim in a way that is easily mappable
- *
- * @param {String} str - The string to trim
- * @return {String} - The trimmed string
- */
- stringTrim: function stringTrim(str) {
- return str.trim();
+ * Wrap String.prototype.trim in a way that is easily mappable
+ *
+ * @param {String} str - The string to trim
+ * @return {String} - The trimmed string
+ */
+ stringTrim: str => str.trim(),
+ /**
+ * Get the type of the variable passed
+ *
+ * @see https://techblog.badoo.com/blog/2013/11/01/type-checking-in-javascript/
+ * @see http://toddmotto.com/understanding-javascript-types-and-reliable-type-checking/
+ * @param {mixed} o - Object to type check
+ * @return {String} - Type of the object
+ */
+ type: o => {
+ let type = Object.prototype.toString.call(o).slice(8, -1).toLowerCase();
+
+ // handle NaN and Infinity
+ if (type === 'number') {
+ if (isNaN(o)) {
+ return 'nan';
+ }
+ if (!isFinite(o)) {
+ return 'infinity';
+ }
+ }
+
+ return type;
},
/**
- * Get the type of the variable passed
- *
- * @see https://techblog.badoo.com/blog/2013/11/01/type-checking-in-javascript/
- * @see http://toddmotto.com/understanding-javascript-types-and-reliable-type-checking/
- * @param {mixed} o
- * @return {String}
- */
- type: function type(o) {
- var type = Object.prototype.toString.call(o).slice(8, -1).toLowerCase();
-
- // handle NaN and Infinity
- if (type === 'number') {
- if (isNaN(o)) {
- return 'nan';
- }
- if (!isFinite(o)) {
- return 'infinity';
- }
- }
-
- return type;
- },
- /**
- * Determine whether an object is scalar
- *
- * @param {mixed} obj
- * @return {bool}
- */
- isScalar: function isScalar(obj) {
- var scalar = ['string', 'number', 'boolean'];
+ * Determine whether an object is scalar
+ *
+ * @param {mixed} obj - Object to test
+ * @return {bool} - Is object scalar
+ */
+ isScalar: obj => {
+ let scalar = ['string', 'number', 'boolean'];
return scalar.indexOf(helpers.type(obj)) !== -1;
},
/**
- * Get a list of values with a common key from an array of objects
- *
- * @param {Array} arr - The array of objects to search
- * @param {String} key - The key of the object to get
- * @return {Array}
- */
- arrayPluck: function arrayPluck(arr, key) {
- var output = [];
+ * 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
+ */
+ arrayPluck: (arr, key) => {
+ let output = [];
// Empty case
if (arr.length === 0) return output;
- arr.forEach(function (obj) {
- if (!helpers.isUndefined(obj[key])) {
+ arr.forEach(obj => {
+ if ( ! helpers.isUndefined(obj[key]))
+ {
output.push(obj[key]);
}
});
@@ -68,22 +64,22 @@ var helpers = {
return output;
},
/**
- * Determine if a value matching the passed regular expression is
- * in the passed array
- *
- * @param {Array} arr - The array to search
- * @param {RegExp} pattern - The pattern to match
- * @return {Boolean} - If an array item matches the pattern
- */
- regexInArray: function regexInArray(arr, pattern) {
+ * Determine if a value matching the passed regular expression is
+ * in the passed array
+ *
+ * @param {Array} arr - The array to search
+ * @param {RegExp} pattern - The pattern to match
+ * @return {Boolean} - If an array item matches the pattern
+ */
+ regexInArray: (arr, pattern) => {
// Empty case(s)
- if (!helpers.isArray(arr)) return false;
+ if ( ! helpers.isArray(arr)) return false;
if (arr.length === 0) return false;
- var i = undefined,
- l = arr.length;
+ let i, l = arr.length;
- for (i = 0; i < l; i++) {
+ for(i=0; i< l; i++)
+ {
// Short circuit if any items match
if (pattern.test(arr[i])) return true;
}
@@ -91,39 +87,39 @@ var helpers = {
return false;
},
/**
- * Make the first letter of the string uppercase
- *
- * @param {String} str
- * @return {String}
- */
- upperCaseFirst: function upperCaseFirst(str) {
+ * Make the first letter of the string uppercase
+ *
+ * @param {String} str - The string to modify
+ * @return {String} - The modified string
+ */
+ upperCaseFirst: str => {
str += '';
- var first = str.charAt(0).toUpperCase();
+ let first = str.charAt(0).toUpperCase();
return first + str.substr(1);
}
};
// Define an 'is' method for each type
-var types = ['Null', 'Undefined', 'Object', 'Array', 'String', 'Number', 'Boolean', 'Function', 'RegExp', 'NaN', 'Infinite'];
-types.forEach(function (t) {
+let types = ['Null','Undefined','Object','Array','String','Number','Boolean','Function','RegExp','NaN','Infinite'];
+types.forEach(t => {
/**
- * Determine whether a variable is of the type specified in the
- * function name, eg isNumber
- *
- * Types available are Null, Undefined, Object, Array, String, Number, Boolean, Function, RegExp, NaN and Infinite
- *
- * @name is[type]
- * @param {mixed} o
- * @return {Boolean}
- */
- helpers['is' + t] = function (o) {
- if (t.toLowerCase() === 'infinite') {
- t = 'infinity';
- }
+ * Determine whether a variable is of the type specified in the
+ * function name, eg isNumber
+ *
+ * Types available are Null, Undefined, Object, Array, String, Number, Boolean, Function, RegExp, NaN and Infinite
+ *
+ * @name is[type]
+ * @param {mixed} o
+ * @return {Boolean}
+ */
+ helpers['is' + t] = function (o) {
+ if (t.toLowerCase() === 'infinite')
+ {
+ t = 'infinity';
+ }
- return helpers.type(o) === t.toLowerCase();
- };
+ return helpers.type(o) === t.toLowerCase();
+ };
});
-module.exports = helpers;
-//# sourceMappingURL=helpers.js.map
+module.exports = helpers;
\ No newline at end of file
diff --git a/lib/helpers.js.map b/lib/helpers.js.map
deleted file mode 100644
index 567c6aa..0000000
--- a/lib/helpers.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"sources":["helpers.js"],"names":[],"mappings":"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","file":"helpers.js","sourcesContent":["\"use strict\";\n\n//require('es6-shim');\n\nlet helpers = {\n\t/**\n\t * Wrap String.prototype.trim in a way that is easily mappable\n\t *\n\t * @param {String} str - The string to trim\n\t * @return {String} - The trimmed string\n\t */\n\tstringTrim: (str) => str.trim(),\n\t/**\n\t * Get the type of the variable passed\n\t *\n\t * @see https://techblog.badoo.com/blog/2013/11/01/type-checking-in-javascript/\n\t * @see http://toddmotto.com/understanding-javascript-types-and-reliable-type-checking/\n\t * @param {mixed} o\n\t * @return {String}\n\t */\n\ttype: (o) => {\n\t let type = Object.prototype.toString.call(o).slice(8, -1).toLowerCase();\n\n\t // handle NaN and Infinity\n\t if (type === 'number') {\n\t if (isNaN(o)) {\n\t return 'nan';\n\t }\n\t if (!isFinite(o)) {\n\t return 'infinity';\n\t }\n\t }\n\n\t return type;\n\t},\n\t/**\n\t * Determine whether an object is scalar\n\t *\n\t * @param {mixed} obj\n\t * @return {bool}\n\t */\n\tisScalar: (obj) => {\n\t\tlet scalar = ['string', 'number', 'boolean'];\n\t\treturn scalar.indexOf(helpers.type(obj)) !== -1;\n\t},\n\t/**\n\t * Get a list of values with a common key from an array of objects\n\t *\n\t * @param {Array} arr - The array of objects to search\n\t * @param {String} key - The key of the object to get\n\t * @return {Array}\n\t */\n\tarrayPluck: (arr, key) => {\n\t\tlet output = [];\n\n\t\t// Empty case\n\t\tif (arr.length === 0) return output;\n\n\t\tarr.forEach((obj) => {\n\t\t\tif ( ! helpers.isUndefined(obj[key]))\n\t\t\t{\n\t\t\t\toutput.push(obj[key]);\n\t\t\t}\n\t\t});\n\n\t\treturn output;\n\t},\n\t/**\n\t * Determine if a value matching the passed regular expression is\n\t * in the passed array\n\t *\n\t * @param {Array} arr - The array to search\n\t * @param {RegExp} pattern - The pattern to match\n\t * @return {Boolean} - If an array item matches the pattern\n\t */\n\tregexInArray: (arr, pattern) => {\n\t\t// Empty case(s)\n\t\tif ( ! helpers.isArray(arr)) return false;\n\t\tif (arr.length === 0) return false;\n\n\t\tlet i, l = arr.length;\n\n\t\tfor(i=0; i< l; i++)\n\t\t{\n\t\t\t// Short circuit if any items match\n\t\t\tif (pattern.test(arr[i])) return true;\n\t\t}\n\n\t\treturn false;\n\t},\n\t/**\n\t * Make the first letter of the string uppercase\n\t *\n\t * @param {String} str\n\t * @return {String}\n\t */\n\tupperCaseFirst: (str) => {\n\t\tstr += '';\n\t\tlet first = str.charAt(0).toUpperCase();\n\t\treturn first + str.substr(1);\n\t}\n};\n\n// Define an 'is' method for each type\nlet types = ['Null','Undefined','Object','Array','String','Number','Boolean','Function','RegExp','NaN','Infinite'];\ntypes.forEach((t) => {\n\t/**\n\t * Determine whether a variable is of the type specified in the\n\t * function name, eg isNumber\n\t *\n\t * Types available are Null, Undefined, Object, Array, String, Number, Boolean, Function, RegExp, NaN and Infinite\n\t *\n\t * @name is[type]\n\t * @param {mixed} o\n\t * @return {Boolean}\n\t */\n helpers['is' + t] = function (o) {\n\t if (t.toLowerCase() === 'infinite')\n\t {\n\t\t t = 'infinity';\n\t }\n\n return helpers.type(o) === t.toLowerCase();\n };\n});\n\nmodule.exports = helpers;"],"sourceRoot":"/source/"}
\ No newline at end of file
diff --git a/package.json b/package.json
index 715dfda..d78025c 100644
--- a/package.json
+++ b/package.json
@@ -4,7 +4,7 @@
"description": "A query builder for node based on the one in CodeIgniter",
"author": "Timothy J Warren ",
"engines": {
- "node": ">=0.10.0"
+ "node": ">=4.0.0"
},
"contributors": [
{
@@ -38,10 +38,7 @@
"mysql2": "^0.15.8",
"node-firebird": "^0.7.0",
"pg": "^4.4.3",
- "es6-shim": "",
- "babel": "",
- "babel-preset-es2015": "",
- "babel-plugin-transform-es2015-modules-commonjs": ""
+ "require-reload": "*"
},
"optionalDependencies": {
"dblite": "*",
@@ -49,22 +46,21 @@
"pg": "*"
},
"devDependencies": {
+ "chai": "",
"documentation": "",
- "nodeunit": "",
- "gulp": "",
- "gulp-babel": "",
- "gulp-babel-istanbul": "",
- "gulp-sourcemaps": "",
- "gulp-concat": "",
- "gulp-documentation": "",
- "gulp-nodeunit-runner": "",
- "gulp-sloc": "",
- "gulp-eslint": "",
"eslint": "",
- "istanbul": ""
+ "gulp": "",
+ "gulp-documentation": "^2.1.0",
+ "gulp-eslint": "",
+ "gulp-istanbul": "^0.10.3",
+ "gulp-mocha": "^2.2.0",
+ "gulp-pipe": "^1.0.4",
+ "gulp-sloc": "",
+ "istanbul": "",
+ "mocha": ""
},
"license": "MIT",
"scripts": {
- "test": "gulp nodeunit"
+ "test": "gulp test"
}
}
diff --git a/sonar-project.properties b/sonar-project.properties
index 6c7cb44..b7c3b7c 100644
--- a/sonar-project.properties
+++ b/sonar-project.properties
@@ -1,5 +1,5 @@
sonar.projectKey=node-query
sonar.projectName=NodeJS Query Builder
-sonar.projectVersion=2.2.1
+sonar.projectVersion=3.0.0
sonar.sources=lib
sonar.javascript.lcov.reportPath=coverage/lcov.info
\ No newline at end of file
diff --git a/src/Adapter.js b/src/Adapter.js
deleted file mode 100755
index bb1627d..0000000
--- a/src/Adapter.js
+++ /dev/null
@@ -1,26 +0,0 @@
-'use strict';
-
-/** @module Adapter */
-module.exports = class Adapter {
- /**
- * Invoke an adapter
- *
- * @param {Object} instance - The connection objec
- * @return {void}
- */
- constructor(instance) {
- this.instance = instance;
- }
-
- /**
- * Run the sql query as a prepared statement
- *
- * @param {String} sql - The sql with placeholders
- * @param {Array} params - The values to insert into the query
- * @param {Function} callback - Callback to run when a response is recieved
- * @return {void}
- */
- execute(/*sql, params, callback*/) {
- throw new Error("Correct adapter not defined for query execution");
- }
-}
\ No newline at end of file
diff --git a/src/DriverBase.js b/src/DriverBase.js
deleted file mode 100755
index c4a257e..0000000
--- a/src/DriverBase.js
+++ /dev/null
@@ -1,164 +0,0 @@
-'use strict';
-
-import helpers from './helpers'
-
-/**
- * Base Database Driver
- *
- * @module driver
- */
-var d = {
- identifierStartChar: '"',
- identifierEndChar: '"',
- tablePrefix: null,
- hasTruncate: true,
-
- /**
- * Low level function for naive quoting of strings
-
- * @param {String} str
- * @return {String}
- * @private
- */
- _quote: function(str) {
- return (helpers.isString(str) && ! (str.startsWith(d.identifierStartChar) || str.endsWith(d.identifierEndChar)))
- ? d.identifierStartChar + str + d.identifierEndChar
- : str;
- },
-
- /**
- * Set the limit clause
-
- * @param {String} sql
- * @param {Number} limit
- * @param {Number|null} offset
- * @return {String}
- */
- limit: function(sql, limit, offset) {
- sql += " LIMIT " + limit;
-
- if (helpers.isNumber(offset))
- {
- sql += " OFFSET " + offset;
- }
-
- return sql;
- },
-
- /**
- * Quote database table name, and set prefix
- *
- * @param {String} table
- * @return {String}
- */
- quoteTable: function(table) {
- // Quote after prefix
- return d.quoteIdentifiers(table);
- },
-
- /**
- * Use the driver's escape character to quote identifiers
- *
- * @param {String|Array}
- * @return {String|Array}
- */
- quoteIdentifiers: function(str) {
- var hiers, raw;
- var pattern = new RegExp(d.identifierStartChar + '(' + '([a-zA-Z0-9_]+)' + '(\((.*?)\))' + ')' + d.identifierEndChar, 'ig');
-
- // Recurse for arrays of identifiiers
- if (Array.isArray(str))
- {
- return str.map(d.quoteIdentifiers);
- }
-
- // Handle commas
- if (str.includes(','))
- {
- var parts = str.split(',').map(helpers.stringTrim);
- str = parts.map(d.quoteIdentifiers).join(',');
- }
-
- // Split identifiers by period
- hiers = str.split('.').map(d._quote);
- raw = hiers.join('.');
-
- // Fix functions
- if (raw.includes('(') && raw.includes(')'))
- {
- var funcs = pattern.exec(raw);
-
- // Unquote the function
- raw = raw.replace(funcs[0], funcs[1]);
-
- // Quote the identifiers inside of the parens
- var inParens = funcs[3].substring(1, funcs[3].length -1);
- raw = raw.replace(inParens, d.quoteIdentifiers(inParens));
- }
-
- return raw;
- },
-
- /**
- * SQL to truncate the passed table
- *
- * @param {String} table
- * @return {String} - sql
- */
- truncate: function(table) {
- var sql = (d.hasTruncate)
- ? 'TRUNCATE '
- : 'DELETE FROM ';
-
- sql += d.quoteTable(table);
-
- return sql;
- },
-
- /**
- * SQL to insert a group of rows
- *
- * @param {String} table - The table to insert to
- * @param {Array} [data] - The array of object containing data to insert
- * @return {String}
- */
- insertBatch: function(table, data) {
- var vals = [],
- fields = Object.keys(data[0]),
- sql = "",
- params = [],
- paramString = "",
- paramList = [];
-
- // Get the data values to insert, so they can
- // be parameterized
- data.forEach(function(obj) {
- Object.keys(obj).forEach(function(key) {
- vals.push(obj[key]);
- });
- });
-
- // Get the field names from the keys of the first
- // object inserted
- table = d.quoteTable(table);
-
- sql += "INSERT INTO " + table + " ("
- + d.quoteIdentifiers(fields).join(",")
- + ") VALUES ";
-
- // Create placeholder groups
- params = Array(fields.length).fill('?');
- paramString = "(" + params.join(',') + ")";
- paramList = Array(data.length).fill(paramString);
-
- sql += paramList.join(',');
-
- return {
- sql: sql,
- values: vals
- };
- }
-
-};
-
-module.exports = d;
\ No newline at end of file
diff --git a/src/DriverClass.js b/src/DriverClass.js
deleted file mode 100644
index bc80b23..0000000
--- a/src/DriverClass.js
+++ /dev/null
@@ -1,13 +0,0 @@
-'use strict';
-
-import driverBase from './DriverBase';
-
-module.exports = class DriverClass {
- constructor(properties = {}) {
- Object.keys(driverBase).forEach((key) => {
- this[key] = (Object.keys(properties).indexOf(key) !== -1)
- ? properties[key]
- : driverBase[key];
- });
- }
-}
\ No newline at end of file
diff --git a/src/NodeQuery.js b/src/NodeQuery.js
deleted file mode 100755
index fc8abe3..0000000
--- a/src/NodeQuery.js
+++ /dev/null
@@ -1,74 +0,0 @@
-"use strict";
-
-let instance = null;
-import fs from 'fs';
-import helpers from './helpers';
-import QueryBuilder from './QueryBuilder';
-
-/**
- * @module NodeQuery
- */
-class NodeQuery {
-
- /**
- * Constructor
- */
- constructor() {
- this.instance = null;
- }
-
- /**
- * Create a query builder object
- *
- * @memberOf NodeQuery
- * @param {String} drivername - The name of the database type, eg. mysql or pg
- * @param {Object} connObject - A connection object from the database library you are connecting with
- * @param {String} [connLib] - The name of the db connection library you are using, eg. mysql or mysql2. Optional if the same as drivername
- * @return {QueryBuilder}
- */
- init(driverType, connObject, connLib) {
- connLib = connLib || driverType;
-
- let paths = {
- driver: `${__dirname}/drivers/` + helpers.upperCaseFirst(driverType),
- adapter: `${__dirname}/adapters/${connLib}`
- };
-
- /*Object.keys(paths).forEach((type) => {
- if ( ! fs.existsSync(paths[type]))
- {
- console.log(paths[type]);
- throw new Error(
- `Selected ${type} (` +
- helpers.upperCaseFirst(driverType) +
- `) does not exist!`
- );
- }
- });*/
-
- let driver = require(paths.driver);
- let $adapter = require(paths.adapter);
- let adapter = new $adapter(connObject);
-
- this.instance = new QueryBuilder(driver, adapter);
-
- return this.instance;
- };
-
- /**
- * Return an existing query builder instance
- *
- * @memberOf NodeQuery
- * @return {QueryBuilder}
- */
- getQuery() {
- if ( ! this.instance) {
- throw new Error("No Query Builder instance to return");
- }
-
- return this.instance;
- };
-
-};
-
-module.exports = new NodeQuery();
\ No newline at end of file
diff --git a/src/QueryBuilder.js b/src/QueryBuilder.js
deleted file mode 100755
index 7d4d120..0000000
--- a/src/QueryBuilder.js
+++ /dev/null
@@ -1,924 +0,0 @@
-'use strict';
-
-/** @module QueryBuilder */
-import getArgs from 'getargs';
-import helpers from './helpers';
-import State from './State';
-import QueryParser from './QueryParser';
-
-module.exports = class QueryBuilder {
- /*
- * SQL generation object
- *
- * @param {driver} - The syntax driver for the database
- * @param {adapter} - The database module adapter for running queries
- * @returns {QueryBuilder}
- * @constructor
- */
- constructor(driver, adapter) {
- this.driver = driver;
- this.adapter = adapter;
- this.parser = new QueryParser(this.driver);
- this.state = new State();
- }
-
- /**
- * Complete the sql building based on the type provided
- *
- * @param {String} type
- * @param {String} table
- * @private
- * @return {String}
- */
- _compile(type, table) {
- // Put together the basic query
- let sql = this._compileType(type, table);
-
- // Set each subClause
- ['queryMap', 'groupString', 'orderString', 'havingMap'].forEach((clause) => {
- let param = this.state[clause];
-
- if ( ! helpers.isScalar(param))
- {
- Object.keys(param).forEach((part) => {
- sql += param[part].conjunction + param[part].string;
- });
- }
- else
- {
- sql += param;
- }
- });
-
- // Append the limit, if it exists
- if (helpers.isNumber(this.state.limit))
- {
- sql = this.driver.limit(sql, this.state.limit, this.state.offset);
- }
-
- return sql;
- }
-
- _compileType(type, table) {
- let sql = '';
-
- switch(type) {
- case "insert":
- let params = Array(this.state.setArrayKeys.length).fill('?');
-
- sql = `INSERT INTO ${table} (`;
- sql += this.state.setArrayKeys.join(',');
- sql += ") VALUES (";
- sql += params.join(',') + ')';
- break;
-
- case "update":
- sql = `UPDATE ${table} SET ${this.state.setString}`;
- break;
-
- case "delete":
- sql = `DELETE FROM ${table}`;
- break;
-
- default:
- sql = `SELECT * FROM ${this.state.fromString}`;
-
- // Set the select string
- if (this.state.selectString.length > 0)
- {
- // Replace the star with the selected fields
- sql = sql.replace('*', this.state.selectString);
- }
- break;
- }
-
- return sql;
- }
-
- _like(field, val, pos, like, conj) {
- field = this.driver.quoteIdentifiers(field);
-
- like = `${field} ${like} ?`;
-
- if (pos == 'before')
- {
- val = `%${val}`;
- }
- else if (pos == 'after')
- {
- val = `${val}%`;
- }
- else
- {
- val = `%${val}%`;
- }
-
- conj = (this.state.queryMap.length < 1) ? ' WHERE ' : ` ${conj} `;
- this._appendMap(conj, like, 'like');
-
- this.state.whereValues.push(val);
- }
-
- /**
- * Append a clause to the query map
- *
- * @param {String} conjunction
- * @param {String} string
- * @param {String} type
- * @return {void}
- */
- _appendMap(conjunction, string, type) {
- this.state.queryMap.push({
- type: type,
- conjunction: conjunction,
- string: string
- });
- }
-
- /**
- * Handle key/value pairs in an object the same way as individual arguments,
- * when appending to state
- *
- * @private
- */
- _mixedSet(/* $letName, $valType, $key, [$val] */) {
- let args = getArgs('$letName:string, $valType:string, $key:object|string|number, [$val]', arguments);
-
- let obj = {};
-
-
- if (helpers.isScalar(args.$key) && !helpers.isUndefined(args.$val))
- {
- // Convert key/val pair to a simple object
- obj[args.$key] = args.$val;
- }
- else if (helpers.isScalar(args.$key) && helpers.isUndefined(args.$val))
- {
- // If just a string for the key, and no value, create a simple object with duplicate key/val
- obj[args.$key] = args.$key;
- }
- else
- {
- obj = args.$key;
- }
-
- Object.keys(obj).forEach((k) => {
- // If a single value for the return
- if (['key','value'].indexOf(args.$valType) !== -1)
- {
- let pushVal = (args.$valType === 'key') ? k : obj[k];
- this.state[args.$letName].push(pushVal);
- }
- else
- {
- this.state[args.$letName][k] = obj[k];
- }
- });
-
-
- return this.state[args.$letName];
- }
-
- _whereMixedSet(/*key, val*/) {
- let args = getArgs('key:string|object, [val]', arguments);
-
- this.state.whereMap = [];
- this.state.rawWhereValues = [];
-
- this._mixedSet('whereMap', 'both', args.key, args.val);
- this._mixedSet('rawWhereValues', 'value', args.key, args.val);
- }
-
- _fixConjunction(conj) {
- let lastItem = this.state.queryMap[this.state.queryMap.length - 1];
- let conjunctionList = helpers.arrayPluck(this.state.queryMap, 'conjunction');
-
- if (this.state.queryMap.length === 0 || ( ! helpers.regexInArray(conjunctionList, /^ ?WHERE/i)))
- {
- conj = " WHERE ";
- }
- else if (lastItem.type === 'groupStart')
- {
- conj = '';
- }
- else
- {
- conj = ' ' + conj + ' ';
- }
-
- return conj;
- }
-
- _where(key, val, defaultConj) {
- // Normalize key and value and insert into this.state.whereMap
- this._whereMixedSet(key, val);
-
- // Parse the where condition to account for operators,
- // functions, identifiers, and literal values
- this.state = this.parser.parseWhere(this.driver, this.state);
-
- this.state.whereMap.forEach((clause) => {
- let conj = this._fixConjunction(defaultConj);
- this._appendMap(conj, clause, 'where');
- });
-
- this.state.whereMap = {};
- }
-
- _whereNull(field, stmt, conj) {
- field = this.driver.quoteIdentifiers(field);
- let item = field + ' ' + stmt;
-
- this._appendMap(this._fixConjunction(conj), item, 'whereNull');
- }
-
- _having(/*key, val, conj*/) {
- let args = getArgs('key:string|object, [val]:string|number, [conj]:string', arguments);
- args.conj = args.conj || 'AND';
- args.val = args.val || null;
-
- // Normalize key/val and put in state.whereMap
- this._whereMixedSet(args.key, args.val);
-
- // Parse the having condition to account for operators,
- // functions, identifiers, and literal values
- this.state = this.parser.parseWhere(this.driver, this.state);
-
- this.state.whereMap.forEach((clause) => {
- // Put in the having map
- this.state.havingMap.push({
- conjunction: (this.state.havingMap.length > 0) ? ` ${args.conj} ` : ' HAVING ',
- string: clause
- });
- });
-
- // Clear the where Map
- this.state.whereMap = {};
- }
- _whereIn(/*key, val, inClause, conj*/) {
- let args = getArgs('key:string, val:array, inClause:string, conj:string', arguments);
-
- args.key = this.driver.quoteIdentifiers(args.key);
- let params = new Array(args.val.length);
- params.fill('?');
-
- args.val.forEach((value) => {
- this.state.whereValues.push(value);
- });
-
- args.conj = (this.state.queryMap.length > 0) ? " " + args.conj + " " : ' WHERE ';
- let str = args.key + " " + args.inClause + " (" + params.join(',') + ") ";
-
- this._appendMap(args.conj, str, 'whereIn');
- }
-
- _run(type, table, callback, sql, vals) {
-
- if ( ! sql)
- {
- sql = this._compile(type, table);
- }
-
- if ( ! vals)
- {
- vals = this.state.values.concat(this.state.whereValues);
- }
-
-//console.log(this.state);
-//console.log(sql);
-//console.log(vals);
-//console.log(callback);
-//console.log('------------------------');
-
- // Reset the state so another query can be built
- this._resetState();
-
- // Pass the sql and values to the adapter to run on the database
- this.adapter.execute(sql, vals, callback);
-
- }
-
- _getCompile(type, table, reset) {
- reset = reset || false;
-
- let sql = this._compile(type, table);
-
- if (reset) this._resetState();
-
- return sql;
- }
-
- _resetState() {
- this.state = new State();
- }
-
- // ----------------------------------------------------------------------------
- // ! Miscellaneous Methods
- // ----------------------------------------------------------------------------
-
- /**
- * Reset the object state for a new query
- *
- * @memberOf QueryBuilder
- * @return {void}
- */
- resetQuery() {
- this._resetState();
- }
-
- /**
- * Returns the current class state for testing or other purposes
- *
- * @private
- * @return {Object}
- */
- getState() {
- return this.state;
- }
-
- /**
- * Closes the database connection for the current adapter
- *
- * @return {void}
- */
- end() {
- this.adapter.close();
- }
-
- // ------------------------------------------------------------------------
- // ! Query Builder Methods
- // ------------------------------------------------------------------------
-
- /**
- * Specify rows to select in the query
- *
- * @memberOf QueryBuilder
- * @param {String|Array} fields - The fields to select from the current table
- * @return {QueryBuilder}
- */
- select(fields) {
-
- // Split/trim fields by comma
- fields = (Array.isArray(fields))
- ? fields
- : fields.split(",").map(helpers.stringTrim);
-
- // Split on 'As'
- fields.forEach((field, index) => {
- if (field.match(/as/i))
- {
- fields[index] = field.split(/ as /i).map(helpers.stringTrim);
- }
- });
-
- let safeArray = this.driver.quoteIdentifiers(fields);
-
- // Join the strings back together
- safeArray.forEach((field, index) => {
- if (Array.isArray(field))
- {
- safeArray[index] = safeArray[index].join(' AS ');
- }
- });
-
- this.state.selectString += safeArray.join(', ');
-
- return this;
- }
-
- /**
- * Specify the database table to select from
- *
- * @param {String} tableName - The table to use for the current query
- * @return {QueryBuilder}
- */
- from(tableName) {
- // Split identifiers on spaces
- let identArray = tableName.trim().split(' ').map(helpers.stringTrim);
-
- // Quote/prefix identifiers
- identArray[0] = this.driver.quoteTable(identArray[0]);
- identArray = this.driver.quoteIdentifiers(identArray);
-
- // Put it back together
- this.state.fromString = identArray.join(' ');
-
- return this;
- }
-
- /**
- * Add a 'like/ and like' clause to the query
- *
- * @param {String} field - The name of the field to compare to
- * @param {String} val - The value to compare to
- * @param {String} [pos=both] - The placement of the wildcard character(s): before, after, or both
- * @return {QueryBuilder}
- */
- like(field, val, pos) {
- this._like(field, val, pos, ' LIKE ', 'AND');
- return this;
- }
-
- /**
- * Add a 'not like/ and not like' clause to the query
- *
- * @param {String} field - The name of the field to compare to
- * @param {String} val - The value to compare to
- * @param {String} [pos=both] - The placement of the wildcard character(s): before, after, or both
- * @return {QueryBuilder}
- */
- notLike(field, val, pos) {
- this._like(field, val, pos, ' NOT LIKE ', 'AND');
- return this;
- }
-
- /**
- * Add an 'or like' clause to the query
- *
- * @param {String} field - The name of the field to compare to
- * @param {String} val - The value to compare to
- * @param {String} [pos=both] - The placement of the wildcard character(s): before, after, or both
- * @return {QueryBuilder}
- */
- orLike(field, val, pos) {
- this._like(field, val, pos, ' LIKE ', 'OR');
- return this;
- }
-
- /**
- * Add an 'or not like' clause to the query
- *
- * @param {String} field - The name of the field to compare to
- * @param {String} val - The value to compare to
- * @param {String} [pos=both] - The placement of the wildcard character(s): before, after, or both
- * @return {QueryBuilder}
- */
- orNotLike(field, val, pos) {
- this._like(field, val, pos, ' NOT LIKE ', 'OR');
- return this;
- }
-
- /**
- * Add a 'having' clause
- *
- * @param {String|Object} key - The name of the field and the comparision operator, or an object
- * @param {String|Number} [val] - The value to compare if the value of key is a string
- * @return {QueryBuilder}
- */
- having(/*key, [val]*/) {
- let args = getArgs('key:string|object, [val]:string|number', arguments);
-
- this._having(args.key, args.val, 'AND');
- return this;
- }
-
- /**
- * Add an 'or having' clause
- *
- * @param {String|Object} key - The name of the field and the comparision operator, or an object
- * @param {String|Number} [val] - The value to compare if the value of key is a string
- * @return {QueryBuilder}
- */
- orHaving(/*key, [val]*/) {
- let args = getArgs('key:string|object, [val]:string|number', arguments);
-
- this._having(args.key, args.val, 'OR');
- return this;
- }
-
- /**
- * Set a 'where' clause
- *
- * @param {String|Object} key - The name of the field and the comparision operator, or an object
- * @param {String|Number} [val] - The value to compare if the value of key is a string
- * @return {QueryBuilder}
- */
- where(key, val) {
- this._where(key, val, 'AND');
- return this;
- }
-
- /**
- * Set a 'or where' clause
- *
- * @param {String|Object} key - The name of the field and the comparision operator, or an object
- * @param {String|Number} [val] - The value to compare if the value of key is a string
- * @return {QueryBuilder}
- */
- orWhere(key, val) {
- this._where(key, val, 'OR');
- return this;
- }
-
- /**
- * Select a field that is Null
- *
- * @param {String} field - The name of the field that has a NULL value
- * @return {QueryBuilder}
- */
- whereIsNull(field) {
- this._whereNull(field, 'IS NULL', 'AND');
- return this;
- }
-
- /**
- * Specify that a field IS NOT NULL
- *
- * @param {String} field
- * @return {QueryBuilder}
- */
- whereIsNotNull(field) {
- this._whereNull(field, 'IS NOT NULL', 'AND');
- return this;
- }
-
- /**
- * Field is null prefixed with 'OR'
- *
- * @param {String} field
- * @return {QueryBuilder}
- */
- orWhereIsNull(field) {
- this._whereNull(field, 'IS NULL', 'OR');
- return this;
- }
-
- /**
- * Field is not null prefixed with 'OR'
- *
- * @param {String} field
- * @return {QueryBuilder}
- */
- orWhereIsNotNull(field) {
- this._whereNull(field, 'IS NOT NULL', 'OR');
- return this;
- }
-
- /**
- * Set a 'where in' clause
- *
- * @param {String} key - the field to search
- * @param {Array} val - the array of items to search in
- * @return {QueryBuilder}
- */
- whereIn(key, val) {
- this._whereIn(key, val, 'IN', 'AND');
- return this;
- }
-
- /**
- * Set a 'or where in' clause
- *
- * @param {String} key - the field to search
- * @param {Array} val - the array of items to search in
- * @return {QueryBuilder}
- */
- orWhereIn(key, val) {
- this._whereIn(key, val, 'IN', 'OR');
- return this;
- }
-
- /**
- * Set a 'where not in' clause
- *
- * @param {String} key - the field to search
- * @param {Array} val - the array of items to search in
- * @return {QueryBuilder}
- */
- whereNotIn(key, val) {
- this._whereIn(key, val, 'NOT IN', 'AND');
- return this;
- }
-
- /**
- * Set a 'or where not in' clause
- *
- * @param {String} key - the field to search
- * @param {Array} val - the array of items to search in
- * @return {QueryBuilder}
- */
- orWhereNotIn(key, val) {
- this._whereIn(key, val, 'NOT IN', 'OR');
- return this;
- }
-
- /**
- * Set values for insertion or updating
- *
- * @param {String|Object} key - The key or object to use
- * @param {String} [val] - The value if using a scalar key
- * @return {QueryBuilder}
- */
- set(/* $key, [$val] */) {
- let args = getArgs('$key, [$val]', arguments);
-
- // Set the appropriate state variables
- this._mixedSet('setArrayKeys', 'key', args.$key, args.$val);
- this._mixedSet('values', 'value', args.$key, args.$val);
-
- // Use the keys of the array to make the insert/update string
- // and escape the field names
- this.state.setArrayKeys = this.state.setArrayKeys.map(this.driver._quote);
-
- // Generate the "set" string
- this.state.setString = this.state.setArrayKeys.join('=?,');
- this.state.setString += '=?';
-
- return this;
- }
-
- /**
- * Add a join clause to the query
- *
- * @param {String} table - The table you are joining
- * @param {String} cond - The join condition.
- * @param {String} [type='inner'] - The type of join, which defaults to inner
- * @return {QueryBuilder}
- */
- join(table, cond, type) {
- type = type || "inner";
-
- // Prefix/quote table name
- table = table.split(' ').map(helpers.stringTrim);
- table[0] = this.driver.quoteTable(table[0]);
- table = table.map(this.driver.quoteIdentifiers);
- table = table.join(' ');
-
- // Parse out the join condition
- let parsedCondition = this.parser.compileJoin(cond);
- let condition = table + ' ON ' + parsedCondition;
-
- // Append the join condition to the query map
- this._appendMap("\n" + type.toUpperCase() + ' JOIN ', condition, 'join');
-
- return this;
- }
-
- /**
- * Group the results by the selected field(s)
- *
- * @param {String|Array} field
- * @return {QueryBuilder}
- */
- groupBy(field) {
- if ( ! helpers.isScalar(field))
- {
- let newGroupArray = field.map(this.driver.quoteIdentifiers);
- this.state.groupArray = this.state.groupArray.concat(newGroupArray);
- }
- else
- {
- this.state.groupArray.push(this.driver.quoteIdentifiers(field));
- }
-
- this.state.groupString = ' GROUP BY ' + this.state.groupArray.join(',');
-
- return this;
- }
-
- /**
- * Order the results by the selected field(s)
- *
- * @param {String} field - The field(s) to order by
- * @param {String} [type='ASC'] - The order direction, ASC or DESC
- * @return {QueryBuilder}
- */
- orderBy(field, type) {
- type = type || 'ASC';
-
- // Set the fields for later manipulation
- field = this.driver.quoteIdentifiers(field);
-
- this.state.orderArray[field] = type;
-
- let orderClauses = [];
-
- // Flatten key/val pairs into an array of space-separated pairs
- Object.keys(this.state.orderArray).forEach((key) => {
- orderClauses.push(key + ' ' + this.state.orderArray[key].toUpperCase());
- });
-
- // Set the final string
- this.state.orderString = ' ORDER BY ' + orderClauses.join(', ');
-
- return this;
- }
-
- /**
- * Put a limit on the query
- *
- * @param {Number} limit - The maximum number of rows to fetch
- * @param {Number} [offset] - The row number to start from
- * @return {QueryBuilder}
- */
- limit(limit, offset) {
- this.state.limit = limit;
- this.state.offset = offset || null;
-
- return this;
- }
-
- /**
- * Adds an open paren to the current query for logical grouping
- *
- * @return {QueryBuilder}
- */
- groupStart() {
- let conj = (this.state.queryMap.length < 1) ? ' WHERE ' : ' AND ';
- this._appendMap(conj, '(', 'groupStart');
-
- return this;
- }
-
- /**
- * Adds an open paren to the current query for logical grouping,
- * prefixed with 'OR'
- *
- * @return {QueryBuilder}
- */
- orGroupStart() {
- this._appendMap('', ' OR (', 'groupStart');
-
- return this;
- }
-
- /**
- * Adds an open paren to the current query for logical grouping,
- * prefixed with 'OR NOT'
- *
- * @return {QueryBuilder}
- */
- orNotGroupStart() {
- this._appendMap('', ' OR NOT (', 'groupStart');
-
- return this;
- }
-
- /**
- * Ends a logical grouping started with one of the groupStart methods
- *
- * @return {QueryBuilder}
- */
- groupEnd() {
- this._appendMap('', ')', 'groupEnd');
-
- return this;
- }
-
- // ------------------------------------------------------------------------
- // ! Result Methods
- // ------------------------------------------------------------------------
-
- /**
- * Get the results of the compiled query
- *
- * @param {String} [table] - The table to select from
- * @param {Number} [limit] - A limit for the query
- * @param {Number} [offset] - An offset for the query
- * @param {Function} callback - A callback for receiving the result
- * @return {void}
- */
- get(/* [table], [limit], [offset], callback */) {
- let args = getArgs('[table]:string, [limit]:number, [offset]:number, callback:function', arguments);
-
- if (args.table) {
- this.from(args.table);
- }
-
- if (args.limit) {
- this.limit(args.limit, args.offset);
- }
-
- // Run the query
- this._run('get', args.table, args.callback);
- }
-
- /**
- * Run the generated insert query
- *
- * @param {String} table - The table to insert into
- * @param {Object} [data] - Data to insert, if not already added with the 'set' method
- * @param {Function} callback - Callback for handling response from the database
- * @return {void}
- */
- insert(/* table, data, callback */) {
- let args = getArgs('table:string, [data]:object, callback:function', arguments);
-
- if (args.data) {
- this.set(args.data);
- }
-
- // Run the query
- this._run('insert', this.driver.quoteTable(args.table), args.callback);
- }
-
- /**
- * Insert multiple sets of rows at a time
- *
- * @param {String} table - The table to insert into
- * @param {Array} data - The array of objects containing data rows to insert
- * @param {Function} callback - Callback for handling database response
- * @example query.insertBatch('foo',[{id:1,val:'bar'},{id:2,val:'baz'}], callbackFunction);
- * @return {void}
- */
- insertBatch(/* table, data, callback */) {
- let args = getArgs('table:string, data:array, callback:function', arguments);
- let batch = this.driver.insertBatch(args.table, args.data);
-
- // Run the query
- this._run('', '', args.callback, batch.sql, batch.values);
- }
-
- /**
- * Run the generated update query
- *
- * @param {String} table - The table to insert into
- * @param {Object} [data] - Data to insert, if not already added with the 'set' method
- * @param {Function} callback - Callback for handling response from the database
- * @return {void}
- */
- update(/*table, data, callback*/) {
- let args = getArgs('table:string, [data]:object, callback:function', arguments);
-
- if (args.data) {
- this.set(args.data);
- }
-
- // Run the query
- this._run('update', this.driver.quoteTable(args.table), args.callback);
- }
-
- /**
- * Run the generated delete query
- *
- * @param {String} table - The table to insert into
- * @param {Object} [where] - Where clause for delete statement
- * @param {Function} callback - Callback for handling response from the database
- * @return {void}
- */
- delete(/*table, [where], callback*/) {
- let args = getArgs('table:string, [where]:object, callback:function', arguments);
-
- if (args.where)
- {
- this.where(args.where);
- }
-
- // Run the query
- this._run('delete', this.driver.quoteTable(args.table), args.callback);
- }
-
- // ------------------------------------------------------------------------
- // ! Methods returning SQL
- // ------------------------------------------------------------------------
-
- /**
- * Return generated select query SQL
- *
- * @param {String} [table] - the name of the table to retrieve from
- * @param {Boolean} [reset=true] - Whether to reset the query builder so another query can be built
- * @return {String}
- */
- getCompiledSelect(/*table, reset*/) {
- let args = getArgs('[table]:string, [reset]:boolean', arguments);
- if (args.table)
- {
- this.from(args.table);
- }
-
- return this._getCompile('get', args.table, args.reset);
- }
-
- /**
- * Return generated insert query SQL
- *
- * @param {String} table - the name of the table to insert into
- * @param {Boolean} [reset=true] - Whether to reset the query builder so another query can be built
- * @return {String}
- */
- getCompiledInsert(table, reset) {
- return this._getCompile('insert', this.driver.quoteTable(table), reset);
- }
-
- /**
- * Return generated update query SQL
- *
- * @param {String} table - the name of the table to update
- * @param {Boolean} [reset=true] - Whether to reset the query builder so another query can be built
- * @return {String}
- */
- getCompiledUpdate(table, reset) {
- return this._getCompile('update', this.driver.quoteTable(table), reset);
- }
-
- /**
- * Return generated delete query SQL
- *
- * @param {String} table - the name of the table to delete from
- * @param {Boolean} [reset=true] - Whether to reset the query builder so another query can be built
- * @return {String}
- */
- getCompiledDelete(table, reset) {
- return this._getCompile('delete', this.driver.quoteTable(table), reset);
- }
-}
\ No newline at end of file
diff --git a/src/QueryParser.js b/src/QueryParser.js
deleted file mode 100644
index 822a3b6..0000000
--- a/src/QueryParser.js
+++ /dev/null
@@ -1,274 +0,0 @@
-'use strict';
-
-import helpers from './helpers';
-
-
-// --------------------------------------------------------------------------
-
-/**
- * @constructor
- * @param {Driver} - The driver object for the database in use
- * @module query-parser
- */
-module.exports = class QueryParser {
- /**
- * @constructor
- * @param {Driver} - The driver object for the database in use
- * @return {void}
- */
- constructor(driver) {
- this.driver = driver;
-
- let matchPatterns = {
- 'function': /([a-z0-9_]+\((.*)\))/i,
- operator: /\!=?|\=|\+|&&?|~|\|\|?|\^|\/|<>|>=?|<=?|\-|%|OR|AND|NOT|XOR/ig,
- literal: /([0-9]+)|'(.*?)'|true|false/ig
- };
-
- // Full pattern for identifiers
- // Making sure that literals and functions aren't matched
- matchPatterns.identifier = new RegExp(
- '('
- + '(?!'
- + matchPatterns['function'].source + '|'
- + matchPatterns.literal.source
- + ')'
- + '([a-z_\-]+[0-9]*\\.?)'
- + ')+'
- , 'ig');
-
- // Full pattern for determining ordering of the pieces
- matchPatterns.joinCombined = new RegExp(
- matchPatterns['function'].source + "+|"
- + matchPatterns.literal.source + '+|'
- + matchPatterns.identifier.source
- + '|(' + matchPatterns.operator.source + ')+'
- , 'ig');
-
- this.matchPatterns = matchPatterns;
- this.identifierBlacklist = ['true','false','null'];
- }
-
- /**
- * Filter matched patterns
- *
- * @param {Array} array
- * @return {Array|null}
- */
- filterMatches(array) {
- let output = [];
-
- // Return non-array matches
- if (helpers.isNull(array)) return null;
- if (helpers.isScalar(array) || helpers.isUndefined(array)) return output;
-
- array.forEach((item) => {
- output.push(item);
- });
- return output;
- }
-
- /**
- * Check if the string contains an operator, and if so, return the operator(s).
- * If there are no matches, return null
- *
- * @param {String} string - the string to check
- * @return {Array|null}
- */
- hasOperator(string) {
- return this.filterMatches(string.match(this.matchPatterns.operator));
- }
-
- /**
- * Tokenize the sql into parts for additional processing
- *
- * @param {String} sql
- * @return {Object}
- */
- parseJoin(sql) {
- let matches = {};
- let output = {
- functions: [],
- identifiers: [],
- operators: [],
- literals: []
- };
-
- // Get clause components
- matches.functions = sql.match(new RegExp(this.matchPatterns['function'].source, 'ig'));
- matches.identifiers = sql.match(this.matchPatterns.identifier);
- matches.operators = sql.match(this.matchPatterns.operator);
- matches.literals = sql.match(this.matchPatterns.literal);
-
- // Get everything at once for ordering
- matches.combined = sql.match(this.matchPatterns.joinCombined);
-
- // Flatten the matches to increase relevance
- Object.keys(matches).forEach((key) => {
- output[key] = this.filterMatches(matches[key]);
- });
-
- return output;
- }
-
- /**
- * Return the output of the parsing of the join condition
- *
- * @param {String} condition - The join condition to evalate
- * @return {String} - The parsed/escaped join condition
- */
- compileJoin(condition) {
- let parts = this.parseJoin(condition);
- let count = parts.identifiers.length;
- let i;
-
- // Quote the identifiers
- parts.combined.forEach((part, i) => {
- if (parts.identifiers.indexOf(part) !== -1 && ! helpers.isNumber(part))
- {
- parts.combined[i] = this.driver.quoteIdentifiers(part);
- }
- });
-
- return parts.combined.join(' ');
- }
-
- /**
- * Parse a where clause to separate functions from values
- *
- * @param {Driver} driver
- * @param {State} state
- * @return {String} - The parsed/escaped where condition
- */
- parseWhere(driver, state) {
- let whereMap = state.whereMap;
- let whereValues = state.rawWhereValues;
-
- let outputMap = [];
- let outputValues = [];
-
- Object.keys(whereMap).forEach((key) => {
- // Combine fields, operators, functions and values into a full clause
- // to have a common starting flow
- let fullClause = '';
-
- // Add an explicit = sign where one is inferred
- if ( ! this.hasOperator(key))
- {
- fullClause = key + ' = ' + whereMap[key];
- }
- else if (whereMap[key] === key)
- {
- fullClause = key;
- }
- else
- {
- fullClause = key + ' ' + whereMap[key];
- }
-
- // Separate the clause into separate pieces
- let parts = this.parseJoin(fullClause);
-
- // Filter explicit literals from lists of matches
- if (whereValues.indexOf(whereMap[key]) !== -1)
- {
- let value = whereMap[key];
- let identIndex = (helpers.isArray(parts.identifiers)) ? parts.identifiers.indexOf(value) : -1;
- let litIndex = (helpers.isArray(parts.literals)) ? parts.literals.indexOf(value) : -1;
- let combIndex = (helpers.isArray(parts.combined)) ? parts.combined.indexOf(value) : -1;
- let funcIndex = (helpers.isArray(parts.functions)) ? parts.functions.indexOf(value) : -1;
- let inOutputArray = outputValues.indexOf(value) !== -1;
-
- // Remove the identifier in question,
- // and add to the output values array
- if (identIndex !== -1)
- {
- parts.identifiers.splice(identIndex, 1);
-
- if ( ! inOutputArray)
- {
- outputValues.push(value);
- inOutputArray = true;
- }
- }
-
- // Remove the value from the literals list
- // so it is not added twice
- if (litIndex !== -1)
- {
- parts.literals.splice(litIndex, 1);
-
- if ( ! inOutputArray)
- {
- outputValues.push(value);
- inOutputArray = true;
- }
- }
-
- // Remove the value from the combined list
- // and replace it with a placeholder
- if (combIndex !== -1)
- {
- // Make sure to skip functions when replacing values
- if (funcIndex === -1)
- {
- parts.combined[combIndex] = '?';
-
- if ( ! inOutputArray)
- {
- outputValues.push(value);
- inOutputArray = true;
- }
- }
- }
- }
-
- // Filter false positive identifiers
- parts.identifiers = parts.identifiers || [];
- parts.identifiers = parts.identifiers.filter((item) => {
- let isInCombinedMatches = parts.combined.indexOf(item) !== -1;
- let isNotInBlackList = this.identifierBlacklist.indexOf(item.toLowerCase()) === -1;
-
- return isInCombinedMatches && isNotInBlackList;
- }, this);
-
- // Quote identifiers
- if (helpers.isArray(parts.identifiers))
- {
- parts.identifiers.forEach((ident) => {
- let index = parts.combined.indexOf(ident);
- if (index !== -1)
- {
- parts.combined[index] = driver.quoteIdentifiers(ident);
- }
- });
- }
-
- // Replace each literal with a placeholder in the map
- // and add the literal to the values,
- // This should only apply to literal values that are not
- // explicitly mapped to values, but have to be parsed from
- // a where condition,
- if (helpers.isArray(parts.literals))
- {
- parts.literals.forEach((lit) => {
- let litIndex = parts.combined.indexOf(lit);
-
- if (litIndex !== -1)
- {
- parts.combined[litIndex] = (helpers.isArray(parts.operators)) ? '?' : '= ?';
- outputValues.push(lit);
- }
- });
- }
-
- outputMap.push(parts.combined.join(' '));
- });
-
- state.rawWhereValues = [];
- state.whereValues = state.whereValues.concat(outputValues);
- state.whereMap = outputMap;
-
- return state;
- }
-}
\ No newline at end of file
diff --git a/src/State.js b/src/State.js
deleted file mode 100644
index 1e6a889..0000000
--- a/src/State.js
+++ /dev/null
@@ -1,29 +0,0 @@
-'use strict';
-
-/** @module State */
-module.exports = class State {
- constructor() {
- // Arrays/maps
- this.queryMap = [];
- this.values = [];
- this.whereValues = [];
- this.setArrayKeys = [];
- this.orderArray = [];
- this.groupArray = [];
- this.havingMap = [];
- this.whereMap = [];
- this.rawWhereValues = [];
-
- // Partials
- this.selectString = '';
- this.fromString = '';
- this.setString = '';
- this.orderString = '';
- this.groupString = '';
-
- // Other various values
- this.limit = null;
- this.offset = null;
- }
-}
-// End of module State
\ No newline at end of file
diff --git a/src/adapters/dblite.js b/src/adapters/dblite.js
deleted file mode 100644
index 337f9fd..0000000
--- a/src/adapters/dblite.js
+++ /dev/null
@@ -1,20 +0,0 @@
-'use strict';
-
-import Adapter from '../Adapter';
-import getArgs from 'getargs';
-
-/** @module adapters/dblite */
-module.exports = class dblite extends Adapter {
- /**
- * Run the sql query as a prepared statement
- *
- * @param {String} sql - The sql with placeholders
- * @param {Array} params - The values to insert into the query
- * @param {Function} callback - Callback to run when a response is recieved
- * @return void
- */
- execute(/*sql, params, callback*/) {
- let args = getArgs('sql:string, [params]:array, callback:function', arguments);
- this.instance.query(args.sql, args.params, args.callback);
- };
-}
\ No newline at end of file
diff --git a/src/adapters/mysql.js b/src/adapters/mysql.js
deleted file mode 100644
index 2a07ccb..0000000
--- a/src/adapters/mysql.js
+++ /dev/null
@@ -1,18 +0,0 @@
-'use strict';
-
-import Adapter from '../Adapter';
-
-/** @module adapters/mysql */
-module.exports = class mysql extends Adapter {
- /**
- * Run the sql query as a prepared statement
- *
- * @param {String} sql - The sql with placeholders
- * @param {Array} params - The values to insert into the query
- * @param {Function} callback - Callback to run when a response is recieved
- * @return void
- */
- execute(sql, params, callback) {
- this.instance.query.apply(instance, arguments);
- }
-}
\ No newline at end of file
diff --git a/src/adapters/mysql2.js b/src/adapters/mysql2.js
deleted file mode 100644
index 85daf2c..0000000
--- a/src/adapters/mysql2.js
+++ /dev/null
@@ -1,18 +0,0 @@
-'use strict';
-
-import Adapter from '../Adapter';
-
-/** @module adapters/mysql2 */
-module.exports = class mysql2 extends Adapter {
- /**
- * Run the sql query as a prepared statement
- *
- * @param {String} sql - The sql with placeholders
- * @param {Array} params - The values to insert into the query
- * @param {Function} callback - Callback to run when a response is recieved
- * @return void
- */
- execute(sql, params, callback) {
- this.instance.execute.apply(this.instance, arguments);
- };
-}
\ No newline at end of file
diff --git a/src/adapters/node-firebird.js b/src/adapters/node-firebird.js
deleted file mode 100644
index d60fae4..0000000
--- a/src/adapters/node-firebird.js
+++ /dev/null
@@ -1,20 +0,0 @@
-'use strict';
-
-import Adapter from '../Adapter';
-import getArgs from 'getargs';
-
-/** @module adapters/node-firebird */
-module.exports = class nodefirebird extends Adapter {
- /**
- * Run the sql query as a prepared statement
- *
- * @param {String} sql - The sql with placeholders
- * @param {Array} params - The values to insert into the query
- * @param {Function} callback - Callback to run when a response is recieved
- * @return void
- */
- execute(/*sql, params, callback*/) {
- let args = getArgs('sql:string, [params], callback:function', arguments);
- this.instance.execute(args.sql, args.params, args.callback);
- }
-}
\ No newline at end of file
diff --git a/src/adapters/pg.js b/src/adapters/pg.js
deleted file mode 100644
index 9ca4bb0..0000000
--- a/src/adapters/pg.js
+++ /dev/null
@@ -1,28 +0,0 @@
-'use strict';
-
-import Adapter from '../Adapter';
-import getArgs from 'getargs';
-
-/** @module adapters/pg */
-module.exports = class pg extends Adapter {
- /**
- * Run the sql query as a prepared statement
- *
- * @param {String} sql - The sql with placeholders
- * @param {Array} params - The values to insert into the query
- * @param {Function} callback - Callback to run when a response is recieved
- * @return void
- */
- execute(/*sql, params, callback*/) {
- let args = getArgs('sql:string, [params]:array, callback:function', arguments);
-
- // Replace question marks with numbered placeholders, because this adapter is different...
- let count = 0;
- args.sql = args.sql.replace(/\?/g, () => {
- count++;
- return '$' + count;
- });
-
- this.instance.query(args.sql, args.params, args.callback);
- }
-}
\ No newline at end of file
diff --git a/src/drivers/Firebird.js b/src/drivers/Firebird.js
deleted file mode 100644
index 92f7bc4..0000000
--- a/src/drivers/Firebird.js
+++ /dev/null
@@ -1,49 +0,0 @@
-"use strict";
-
-import helpers from '../helpers';
-import Driver from '../DriverClass';
-
-/**
- * Driver for Firebird databases
- *
- * @module drivers/firebird
- */
-class Firebird extends Driver {
- constructor() {
- super({
- hasTruncate: false
- });
- }
-
- /**
- * Generate a limit clause for firebird, which uses the syntax closest to the SQL standard
- *
- * @param {String} sql
- * @param {Number} limit
- * @param {Number} offset
- * @return {String}
- */
- limit(origSql, limit, offset) {
- let sql = `FIRST ${limit}`;
-
- if (helpers.isNumber(offset))
- {
- sql += ` SKIP ${offset}`;
- }
-
- return origSql.replace(/SELECT/i, "SELECT " + sql);
- }
-
- /**
- * SQL to insert a group of rows
- *
- * @param {String} table - The table to insert to
- * @param {Array} [data] - The array of object containing data to insert
- * @return {String}
- */
- insertBatch() {
- throw new Error("Not Implemented");
- }
-}
-
-module.exports = new Firebird();
\ No newline at end of file
diff --git a/src/drivers/Mysql.js b/src/drivers/Mysql.js
deleted file mode 100755
index 1146231..0000000
--- a/src/drivers/Mysql.js
+++ /dev/null
@@ -1,29 +0,0 @@
-"use strict";
-
-import helpers from '../helpers';
-import Driver from '../DriverClass';
-
-/**
- * Driver for MySQL databases
- *
- * @module drivers/mysql
- */
-class Mysql extends Driver {
- constructor() {
- super({
- identifierStartChar: '`',
- identifierEndChar: '`'
- });
- }
-
- limit(sql, limit, offset) {
- if ( ! helpers.isNumber(offset))
- {
- return sql += ` LIMIT ${limit}`;
- }
-
- return sql += ` LIMIT ${offset}, ${limit}`;
- }
-}
-
-module.exports = new Mysql();
\ No newline at end of file
diff --git a/src/drivers/Pg.js b/src/drivers/Pg.js
deleted file mode 100755
index 43e2fd7..0000000
--- a/src/drivers/Pg.js
+++ /dev/null
@@ -1,10 +0,0 @@
-"use strict";
-
-import Driver from '../DriverClass';
-
-/**
- * Driver for PostgreSQL databases
- *
- * @module drivers/pg
- */
-module.exports = new Driver();
\ No newline at end of file
diff --git a/src/drivers/Sqlite.js b/src/drivers/Sqlite.js
deleted file mode 100644
index 0dd7872..0000000
--- a/src/drivers/Sqlite.js
+++ /dev/null
@@ -1,64 +0,0 @@
-"use strict";
-
-import helpers from '../helpers';
-import Driver from '../DriverClass';
-
-/**
- * Driver for Sqlite databases
- *
- * @module drivers/sqlite
- */
-class Sqlite extends Driver {
- constructor() {
- super();
- this.hasTruncate = false;
- }
-
- insertBatch(table, data) {
-
- // Get the data values to insert, so they can
- // be parameterized
- let sql = "",
- vals = [],
- cols = [],
- fields = [],
- first = data.shift(),
- params = [],
- paramString = "",
- paramList = [];
-
-
- data.forEach((obj) => {
- let row = [];
- Object.keys(obj).forEach((key) => {
- row.push(obj[key]);
- });
- vals.push(row);
- });
-
- sql += "INSERT INTO " + this.quoteTable(table) + "\n";
-
- // Get the field names from the keys of the first
- // object to be inserted
- fields = Object.keys(first);
- Object.keys(first).forEach((key) => {
- cols.push("'" + this._quote(first[key]) + "' AS " + this.quoteIdentifiers(key));
- });
-
- sql += "SELECT " + cols.join(', ') + "\n";
-
- vals.forEach((row_values) => {
- let quoted = row_values.map((value) => {
- return String(value).replace("'", "'\'");
- });
- sql += "UNION ALL SELECT '" + quoted.join("', '") + "'\n";
- });
-
- return {
- sql: sql,
- values: null
- };
- }
-};
-
-module.exports = new Sqlite();
\ No newline at end of file
diff --git a/src/helpers.js b/src/helpers.js
deleted file mode 100755
index 1458e0d..0000000
--- a/src/helpers.js
+++ /dev/null
@@ -1,127 +0,0 @@
-"use strict";
-
-//require('es6-shim');
-
-let helpers = {
- /**
- * Wrap String.prototype.trim in a way that is easily mappable
- *
- * @param {String} str - The string to trim
- * @return {String} - The trimmed string
- */
- stringTrim: (str) => str.trim(),
- /**
- * Get the type of the variable passed
- *
- * @see https://techblog.badoo.com/blog/2013/11/01/type-checking-in-javascript/
- * @see http://toddmotto.com/understanding-javascript-types-and-reliable-type-checking/
- * @param {mixed} o
- * @return {String}
- */
- type: (o) => {
- let type = Object.prototype.toString.call(o).slice(8, -1).toLowerCase();
-
- // handle NaN and Infinity
- if (type === 'number') {
- if (isNaN(o)) {
- return 'nan';
- }
- if (!isFinite(o)) {
- return 'infinity';
- }
- }
-
- return type;
- },
- /**
- * Determine whether an object is scalar
- *
- * @param {mixed} obj
- * @return {bool}
- */
- isScalar: (obj) => {
- let scalar = ['string', 'number', 'boolean'];
- return scalar.indexOf(helpers.type(obj)) !== -1;
- },
- /**
- * Get a list of values with a common key from an array of objects
- *
- * @param {Array} arr - The array of objects to search
- * @param {String} key - The key of the object to get
- * @return {Array}
- */
- arrayPluck: (arr, key) => {
- let output = [];
-
- // Empty case
- if (arr.length === 0) return output;
-
- arr.forEach((obj) => {
- if ( ! helpers.isUndefined(obj[key]))
- {
- output.push(obj[key]);
- }
- });
-
- return output;
- },
- /**
- * Determine if a value matching the passed regular expression is
- * in the passed array
- *
- * @param {Array} arr - The array to search
- * @param {RegExp} pattern - The pattern to match
- * @return {Boolean} - If an array item matches the pattern
- */
- regexInArray: (arr, pattern) => {
- // Empty case(s)
- if ( ! helpers.isArray(arr)) return false;
- if (arr.length === 0) return false;
-
- let i, l = arr.length;
-
- for(i=0; i< l; i++)
- {
- // Short circuit if any items match
- if (pattern.test(arr[i])) return true;
- }
-
- return false;
- },
- /**
- * Make the first letter of the string uppercase
- *
- * @param {String} str
- * @return {String}
- */
- upperCaseFirst: (str) => {
- str += '';
- let first = str.charAt(0).toUpperCase();
- return first + str.substr(1);
- }
-};
-
-// Define an 'is' method for each type
-let types = ['Null','Undefined','Object','Array','String','Number','Boolean','Function','RegExp','NaN','Infinite'];
-types.forEach((t) => {
- /**
- * Determine whether a variable is of the type specified in the
- * function name, eg isNumber
- *
- * Types available are Null, Undefined, Object, Array, String, Number, Boolean, Function, RegExp, NaN and Infinite
- *
- * @name is[type]
- * @param {mixed} o
- * @return {Boolean}
- */
- helpers['is' + t] = function (o) {
- if (t.toLowerCase() === 'infinite')
- {
- t = 'infinity';
- }
-
- return helpers.type(o) === t.toLowerCase();
- };
-});
-
-module.exports = helpers;
\ No newline at end of file
diff --git a/tests/FB_TEST_DB.FDB b/test/FB_TEST_DB.FDB
similarity index 99%
rename from tests/FB_TEST_DB.FDB
rename to test/FB_TEST_DB.FDB
index bcf765a..b682cad 100755
Binary files a/tests/FB_TEST_DB.FDB and b/test/FB_TEST_DB.FDB differ
diff --git a/test/base_test.js b/test/base_test.js
new file mode 100644
index 0000000..f0c773d
--- /dev/null
+++ b/test/base_test.js
@@ -0,0 +1,39 @@
+'use strict';
+
+let assert = require('chai').assert;
+let nodeQuery = require('../lib/NodeQuery');
+
+suite('Base tests', () => {
+ test('Sanity check', () => {
+ let modules = {
+ helpers: require('../lib/helpers'),
+ driver: require('../lib/DriverBase'),
+ qb: require('../lib/QueryBuilder'),
+ 'node-query': require('../lib/NodeQuery'),
+ 'state': require('../lib/State'),
+ 'drivers/pg': require('../lib/drivers/Pg'),
+ 'drivers/mysql': require('../lib/drivers/Mysql'),
+ 'drivers/sqlite': require('../lib/drivers/Sqlite'),
+ 'adapters/mysql': require('../lib/adapters/mysql'),
+ 'adapters/mysql2': require('../lib/adapters/mysql2'),
+ 'adapters/pg': require('../lib/adapters/pg'),
+ 'adapters/dblite': require('../lib/adapters/dblite')
+ };
+
+ Object.keys(modules).forEach(mod => {
+ assert.ok(modules[mod], mod + " module is sane");
+ });
+ });
+
+ test('NodeQuery.getQuery with no instance', () => {
+ assert.throws(() => {
+ nodeQuery.getQuery();
+ }, Error, "No Query Builder instance to return");
+ });
+
+ test('Invalid driver type', () => {
+ assert.throws(() => {
+ nodeQuery.init('foo', {}, 'bar');
+ }, Error, "Selected driver (Foo) does not exist!");
+ });
+});
\ No newline at end of file
diff --git a/tests/config-travis.json b/test/config-travis.json
similarity index 100%
rename from tests/config-travis.json
rename to test/config-travis.json
diff --git a/tests/config.json b/test/config.json
similarity index 100%
rename from tests/config.json
rename to test/config.json
diff --git a/test/helpers_test.js b/test/helpers_test.js
new file mode 100644
index 0000000..616ae38
--- /dev/null
+++ b/test/helpers_test.js
@@ -0,0 +1,136 @@
+'use strict';
+
+let chai = require('chai'),
+ assert = chai.assert,
+ expect = chai.expect,
+ should = chai.should();
+
+let helpers = require('../lib/helpers');
+
+suite('Helper Module Tests', () => {
+ suite('Type-checking methods', () => {
+ suite('Object wrappers are listed as their native type', () => {
+ test("Boolean Wrapper returns 'boolean' not 'object'", () => {
+ let item = Boolean(true);
+ expect(helpers.type(item)).to.deep.equal('boolean');
+ });
+ test("Number Wrapper returns 'number' not 'object", () => {
+ let item = Number(4867);
+ expect(helpers.type(item)).to.deep.equal('number');
+ });
+ test("String Wrapper returns 'string' not 'object'", () => {
+ let item = String("Foo");
+ expect(helpers.type(item)).to.deep.equal('string');
+ });
+ });
+ suite('is..Method methods exist', () => {
+ let types = ['Null','Undefined','Object','Array','String','Number','Boolean','Function','RegExp','NaN','Infinite'];
+
+ types.forEach(type => {
+ test(`is${type} method exists`, () => {
+ assert.ok(helpers[`is${type}`]);
+ });
+ });
+ });
+ suite('isScalar', () => {
+ let trueCases = {
+ 'Strings are scalar': 'foo',
+ 'Booleans are scalar': true,
+ 'Numbers are scalar': 545
+ };
+ Object.keys(trueCases).forEach(desc => {
+ test(desc, () => {
+ expect(helpers.isScalar(trueCases[desc])).to.be.true;
+ });
+ });
+
+ let falseCases = {
+ 'Arrays are not scalar': [],
+ 'Objects are not scalar': [],
+ };
+ Object.keys(falseCases).forEach(desc => {
+ test(desc, () => {
+ expect(helpers.isScalar(falseCases[desc])).to.be.false;
+ });
+ });
+ });
+ suite('isInfinity', () => {
+ test('The type of 1/0 is infinity', () => {
+ expect(helpers.type(1/0)).to.equal('infinity');
+ });
+ test('isInfinity is the same as isInfinite', () => {
+ expect(helpers.isInfinite(1/0)).to.be.true;
+ });
+ });
+ suite('isNaN', () => {
+ test('The type of 0 / 0 is NaN', () => {
+ expect(helpers.type(0 / 0)).to.equal('nan');
+ });
+ test('isNaN method agrees with type', () => {
+ expect(helpers.isNaN(0 / 0)).to.be.true;
+ });
+ });
+ });
+ suite('Other helper methods', () => {
+ suite('stringTrim', () => {
+ test('stringTrim method works as expected', () => {
+ let orig = [' x y ', 'z ', ' q'];
+ let ret = ['x y', 'z', 'q'];
+
+ expect(orig.map(helpers.stringTrim)).to.be.deep.equal(ret);
+ });
+ });
+ suite('arrayPluck', () => {
+ let orig = [{
+ foo: 1
+ },{
+ foo: 2,
+ bar: 10
+ },{
+ foo: 3,
+ bar: 15
+ }];
+
+ test('Finding members in all objects', () => {
+ expect(helpers.arrayPluck(orig, 'foo')).to.be.deep.equal([1,2,3]);
+ });
+ test('Some members are missing in some objects', () => {
+ expect(helpers.arrayPluck(orig, 'bar')).to.be.deep.equal([10, 15]);
+ });
+ test('Empty case', () => {
+ expect(helpers.arrayPluck([], 'apple')).to.be.deep.equal([]);
+ });
+ });
+ suite('regexInArray', () => {
+ let orig = ['apple', ' string ', 6, 4, 7];
+
+ let cases = [{
+ 'Dollar sign is not in any of the array items': /\$/,
+ 'None of the numbers in the array match /5/': /5/
+ },{
+ "' string ' matches /^ ?string/": /^ ?string/,
+ "'apple' matches /APPLE/i": /APPLE/i
+ }];
+
+ [0, 1].forEach(i => {
+ let boolCase = cases[i];
+ Object.keys(boolCase).forEach(desc => {
+ test(desc, () => {
+ if (i) {
+ expect(helpers.regexInArray(orig, boolCase[desc])).to.be.true;
+ } else {
+ expect(helpers.regexInArray(orig, boolCase[desc])).to.be.false;
+ }
+ });
+ });
+ });
+
+ test('First argument is not an array', () => {
+ expect(helpers.regexInArray(5, /5/)).to.be.false;
+ });
+ test('Array is empty', () => {
+ expect(helpers.regexInArray([], /.*/)).to.be.false;
+ });
+ });
+ });
+});
diff --git a/test/query-parser_test.js b/test/query-parser_test.js
new file mode 100644
index 0000000..d136f6c
--- /dev/null
+++ b/test/query-parser_test.js
@@ -0,0 +1,178 @@
+"use strict";
+
+let expect = require('chai').expect;
+
+// Use the base driver as a mock for testing
+let getArgs = require('getargs');
+let helpers = require('../lib/helpers');
+let driver = require('../lib/DriverBase');
+
+let p = require('../lib/QueryParser');
+let parser = new p(driver);
+
+let State = require('../lib/State');
+
+// Simulate query builder state
+let state = new State();
+
+let mixedSet = function mixedSet(/* $letName, $valType, $key, [$val] */) {
+ let args = getArgs('$letName:string, $valType:string, $key:object|string|number, [$val]', arguments);
+
+ let obj = {};
+
+ if (helpers.isScalar(args.$key) && !helpers.isUndefined(args.$val))
+ {
+ // Convert key/val pair to a simple object
+ obj[args.$key] = args.$val;
+ }
+ else if (helpers.isScalar(args.$key) && helpers.isUndefined(args.$val))
+ {
+ // If just a string for the key, and no value, create a simple object with duplicate key/val
+ obj[args.$key] = args.$key;
+ }
+ else
+ {
+ obj = args.$key;
+ }
+
+ Object.keys(obj).forEach(k => {
+ // If a single value for the return
+ if (['key','value'].indexOf(args.$valType) !== -1)
+ {
+ let pushVal = (args.$valType === 'key') ? k : obj[k];
+ state[args.$letName].push(pushVal);
+ }
+ else
+ {
+ state[args.$letName][k] = obj[k];
+ }
+ });
+
+
+ return state[args.$letName];
+}
+
+let whereMock = function() {
+ let args = getArgs('key:string|object, [val]', arguments);
+
+ state.whereMap = [];
+ state.whereValues = [];
+
+ mixedSet('rawWhereValues', 'value', args.key, args.val);
+ mixedSet('whereMap', 'both', args.key, args.val);
+}
+
+// -----------------------------------------------------------------------------
+// ! Start Tests
+// -----------------------------------------------------------------------------
+
+suite('Query Parser Tests', () => {
+ suite('Has operator tests', () => {
+ test('Has operator', () => {
+ let matches = parser.hasOperator('foo <> 2');
+ expect(matches).to.be.deep.equal(['<>']);
+ });
+ test('Has no operator', () => {
+ let matches = parser.hasOperator('foo');
+ expect(matches).to.be.null;
+ })
+ });
+ suite('Where parser tests', () => {
+ setup(() => {
+ state = new State();
+ });
+ test('Has function full string', () => {
+ whereMock('time < SUM(FOO(BAR()))');
+ parser.parseWhere(driver, state);
+ expect(state.whereMap)
+ .to.be.deep.equal(['"time" < SUM(FOO(BAR()))']);
+ });
+ test('Has function key/val', () => {
+ whereMock('time <', 'SUM(FOO(BAR()))');
+ parser.parseWhere(driver, state);
+ expect(state.whereMap)
+ .to.be.deep.equal(['"time" < SUM(FOO(BAR()))']);
+ });
+ test('Has function key/val object', () => {
+ whereMock({
+ 'time <': "SUM(FOO(BAR('x')))"
+ });
+ parser.parseWhere(driver, state);
+ expect(state.whereMap)
+ .to.be.deep.equal(['"time" < SUM(FOO(BAR(\'x\')))']);
+ });
+ test('Has literal value', () => {
+ whereMock({
+ 'foo': 3
+ });
+ parser.parseWhere(driver, state);
+ expect(state.whereMap)
+ .to.be.deep.equal(['"foo" = ?']);
+ expect(state.whereValues)
+ .to.be.deep.equal(['3']);
+ });
+ test('Has multiple literal values', () => {
+ whereMock({
+ foo: 3,
+ bar: 5
+ });
+ parser.parseWhere(driver, state);
+ expect(state.whereMap)
+ .to.be.deep.equal(['"foo" = ?', '"bar" = ?']);
+ expect(state.whereValues)
+ .to.be.deep.equal(['3','5']);
+ });
+ });
+ suite('Parse join tests', () => {
+ let data = [{
+ desc: 'Simple equals condition',
+ join: 'table1.field1=table2.field2',
+ expected: ['table1.field1','=','table2.field2']
+ },{
+ desc: 'Db.table.field condition',
+ join: 'db1.table1.field1!=db2.table2.field2',
+ expected: ['db1.table1.field1','!=', 'db2.table2.field2']
+ },{
+ desc: 'Underscore in identifier',
+ join: 'table_1.field1 = tab_le2.field_2',
+ expected: ['table_1.field1', '=', 'tab_le2.field_2']
+ },{
+ desc: 'Function in condition',
+ join: 'table1.field1 > SUM(3+6)',
+ expected: ['table1.field1', '>', 'SUM(3+6)']
+ }];
+
+ data.forEach(datum => {
+ test(datum.desc, () => {
+ let matches = parser.parseJoin(datum.join);
+ expect(matches.combined).to.be.deep.equal(datum.expected);
+ })
+ });
+ });
+ suite('Compile join tests', () => {
+ let data = [{
+ desc: 'Simple equals condition',
+ clause: 'table1.field1=table2.field2',
+ expected: '"table1"."field1" = "table2"."field2"'
+ },{
+ desc: 'Db.table.field condition',
+ clause: 'db1.table1.field1!=db2.table2.field2',
+ expected: '"db1"."table1"."field1" != "db2"."table2"."field2"'
+ },{
+ desc: 'Underscore in identifier',
+ clause: 'table_1.field1 = tab_le2.field_2',
+ expected: '"table_1"."field1" = "tab_le2"."field_2"'
+ },{
+ desc: 'Function in condition',
+ clause: 'table1.field1 > SUM(3+6)',
+ expected: '"table1"."field1" > SUM(3+6)'
+ }];
+
+ data.forEach(datum => {
+ test(datum.desc, () => {
+ let join = parser.compileJoin(datum.clause);
+ expect(join).to.be.deep.equal(datum.expected);
+ });
+ });
+ });
+});
\ No newline at end of file
diff --git a/tests/sql/mysql.sql b/test/sql/mysql.sql
similarity index 100%
rename from tests/sql/mysql.sql
rename to test/sql/mysql.sql
diff --git a/tests/sql/pgsql.sql b/test/sql/pgsql.sql
similarity index 100%
rename from tests/sql/pgsql.sql
rename to test/sql/pgsql.sql
diff --git a/tests/sql/sqlite.sql b/test/sql/sqlite.sql
similarity index 100%
rename from tests/sql/sqlite.sql
rename to test/sql/sqlite.sql
diff --git a/tests/adapters/dblite_test.js b/tests/adapters/dblite_test.js
deleted file mode 100644
index 6af9260..0000000
--- a/tests/adapters/dblite_test.js
+++ /dev/null
@@ -1,91 +0,0 @@
-'use strict';
-
-// Load the test base
-delete require.cache[require.resolve('../query-builder-base')];
-var testBase = require('../query-builder-base');
-var tests = testBase.tests;
-
-// Load the test config file
-var adapterName = 'dblite';
-var sqlite = null;
-var connection = null;
-
-// Set up the connection
-try {
- sqlite = require(adapterName).withSQLite('3.7.11');
- connection = sqlite(':memory:');
-} catch (e) {
- // Export an empty testsuite if module not loaded
- console.log(e);
- console.log("Database adapter dblite not found");
- //return {};
-}
-
-if (connection)
-{
- // Set up the query builder object
- var nodeQuery = require('../../lib/NodeQuery');
- var qb = nodeQuery.init('sqlite', connection, adapterName);
-
- // Set up the sqlite database
- var sql = 'CREATE TABLE IF NOT EXISTS "create_test" ("id" INTEGER PRIMARY KEY, "key" TEXT, "val" TEXT);' +
- 'CREATE TABLE IF NOT EXISTS "create_join" ("id" INTEGER PRIMARY KEY, "key" TEXT, "val" TEXT);';
- connection.query(sql);
-
- // Set up the test base
- testBase._setUp(qb, function(test, err, rows) {
- if (err != null) {
- test.done();
- throw new Error(err);
- }
-
- // Insert/Update/Delete queries return undefined
- if (rows === undefined) {
- rows = {};
- }
-
- test.ok(rows, 'dblite: Invalid result for generated query');
- test.done();
- });
-
- tests['nodeQuery.getQuery = nodeQuery.init'] = function(test) {
- test.expect(1);
- test.deepEqual(qb, nodeQuery.getQuery(), "getQuery returns same object");
- test.done();
- };
-
- tests['Select tests']['Select with function and argument in WHERE clause'] = function(test) {
- test.expect(1);
- qb.select('id')
- .from('create_test')
- .where('id', 'ABS(-88)')
- .get(function(err, rows) {
- if (err != null) {
- test.done();
- throw new Error(err);
- }
-
- test.ok(rows, 'dblite: Valid result for generated query');
- test.done();
- });
- };
-
- tests["dblite adapter with query builder"] = function(test) {
- test.expect(1);
- test.ok(testBase.qb);
-
- // Close the db connection
- connection.close();
- test.done();
- };
-
- // Export the final test object
- module.exports = tests;
-}
-else
-{
- module.exports = {};
-}
-
-
-
diff --git a/tests/adapters/mysql2_test.js b/tests/adapters/mysql2_test.js
deleted file mode 100644
index 324071a..0000000
--- a/tests/adapters/mysql2_test.js
+++ /dev/null
@@ -1,51 +0,0 @@
-'use strict';
-
-var configFile = (process.env.CI) ? '../config-travis.json' : '../config.json';
-
-// Load a fresh version of the test base
-delete require.cache[require.resolve('../query-builder-base')];
-var testBase = require('../query-builder-base');
-var tests = testBase.tests;
-
-// Load the test config file
-var adapterName = 'mysql2';
-var config = require(configFile)[adapterName];
-
-// Set up the connection
-var mysql2 = require(adapterName);
-var connection = mysql2.createConnection(config.conn);
-
-// Set up the query builder object
-var nodeQuery = require('../../lib/NodeQuery');
-var qb = nodeQuery.init('mysql', connection, adapterName);
-
-
-
-tests['nodeQuery.getQuery = nodeQuery.init'] = function(test) {
- test.expect(1);
- test.deepEqual(qb, nodeQuery.getQuery(), "getQuery returns same object");
- test.done();
-};
-
-// Export the final test object
-tests["mysql2 adapter with query builder"] = function(test) {
- test.expect(1);
- test.ok(testBase.qb);
-
- // Close the db connection
- connection.end();
- test.done();
-};
-
-// Set up the test base
-testBase._setUp(qb, function(test, err, rows) {
- if (err != null) {
- test.done();
- throw new Error(err);
- }
-
- test.ok(rows, 'mysql2: Invalid result for generated query');
- test.done();
-});
-
-module.exports = tests;
\ No newline at end of file
diff --git a/tests/adapters/mysql_test.js b/tests/adapters/mysql_test.js
deleted file mode 100644
index e46e02e..0000000
--- a/tests/adapters/mysql_test.js
+++ /dev/null
@@ -1,51 +0,0 @@
-'use strict';
-
-var configFile = (process.env.CI) ? '../config-travis.json' : '../config.json';
-
-// Load the test base
-delete require.cache[require.resolve('../query-builder-base')];
-var testBase = require('../query-builder-base');
-var tests = testBase.tests;
-
-// Load the test config file
-var adapterName = 'mysql';
-var config = require(configFile)[adapterName];
-
-// Set up the connection
-var mysql = require(adapterName);
-var connection = mysql.createConnection(config.conn);
-
-// Set up the query builder object
-var nodeQuery = require('../../lib/NodeQuery');
-var qb = nodeQuery.init('mysql', connection);
-
-// Set up the test base
-testBase._setUp(qb, function(test, err, rows) {
- if (err != null) {
- test.done();
- throw new Error(err);
- }
-
- test.ok(rows, 'mysql: Valid result for generated query');
- test.done();
-});
-
-tests['nodeQuery.getQuery = nodeQuery.init'] = function(test) {
- test.expect(1);
- test.deepEqual(qb, nodeQuery.getQuery(), "getQuery returns same object");
- test.done();
-};
-
-tests["mysql adapter with query builder"] = function(test) {
- test.expect(1);
- test.ok(testBase.qb);
-
- // Close the db connection
- qb = null;
- connection.destroy();
-
- test.done();
-};
-
-// Export the final test object
-module.exports = tests;
diff --git a/tests/adapters/node-firebird_test.js b/tests/adapters/node-firebird_test.js
deleted file mode 100644
index d8774c7..0000000
--- a/tests/adapters/node-firebird_test.js
+++ /dev/null
@@ -1,96 +0,0 @@
-'use strict';
-
-// Load the test base
-var testBase = require('../query-builder-base');
-
-// Load the test config file
-var adapterName = 'node-firebird';
-var config = require('../config.json')[adapterName];
-config.conn.database = __dirname + config.conn.database;
-var nodeQuery = require('../../lib/NodeQuery');
-
-// Skip on TravisCi
-if (process.env.CI || process.env.JENKINS_HOME)
-{
- module.exports = {};
- return;
-}
-
-// Set up the connection
-try {
- var Firebird = require(adapterName);
- var conn = null;
- var qb = null;
-
- // Setup testbase from the inside out
- // Because the connection is async, utilize
- // the setUp function from nodeunit to get the connection
- testBase.tests.setUp = function(cb) {
- if ( ! conn)
- {
- // Connect to the database
- Firebird.attach(config.conn, function(err, db) {
- if (err) {
- console.error(err);
- }
- conn = db;
-
- // Set up the query builder object
- qb = nodeQuery.init('firebird', db, adapterName);
-
- testBase._setUp(qb, function(test, err, result) {
- if (err) {
- test.done();
- throw new Error(err);
- }
-
- result = result || [];
-
- test.ok(result, 'firebird: Valid result for generated query');
- test.done();
- });
-
- cb();
- });
- }
- else
- {
- cb();
- }
- };
-
- //delete testBase.tests['DB update tests'];
- testBase.tests['DB update tests']['Test Insert Batch'] = function(test) {
- test.expect(1);
-
- test.throws(function() {
- qb.insertBatch({}, (function() {}));
- }, Error, "Insert Batch not implemented for firebird");
-
- test.done();
- };
-
- testBase.tests['nodeQuery.getQuery = nodeQuery.init'] = function(test) {
- test.expect(1);
- test.deepEqual(qb, nodeQuery.getQuery(), "getQuery returns same object");
- test.done();
- };
-
- testBase.tests["firebird adapter with query builder"] = function(test) {
- test.expect(1);
- test.ok(testBase.qb);
-
- // Disconnect from the db
- conn.detach();
-
- test.done();
- };
-
- module.exports = testBase.tests;
-
-} catch (e) {
- // Export an empty testBase.testsuite if module not loaded
- console.log(e);
- console.log("Database adapter firebird not found");
- module.exports = {};
-}
\ No newline at end of file
diff --git a/tests/adapters/pg_test.js b/tests/adapters/pg_test.js
deleted file mode 100644
index e787420..0000000
--- a/tests/adapters/pg_test.js
+++ /dev/null
@@ -1,54 +0,0 @@
-'use strict';
-
-var configFile = (process.env.CI) ? '../config-travis.json' : '../config.json';
-
-// Load the test base
-delete require.cache[require.resolve('../query-builder-base')];
-var testBase = require('../query-builder-base');
-var tests = testBase.tests;
-
-// Load the test config file
-var adapterName = 'pg';
-var config = require(configFile)[adapterName];
-
-// Set up the connection
-var pg = require(adapterName);
-var connection = new pg.Client(config.conn);
-connection.connect(function(err) {
- if (err) {
- throw new Error(err);
- }
-});
-
-// Set up the query builder object
-var nodeQuery = require('../../lib/NodeQuery');
-var qb = nodeQuery.init('pg', connection);
-
-
-// Set up the test base
-testBase._setUp(qb, function(test, err, result) {
- if (err) {
- console.error('SQL syntax error', err);
- }
-
- test.ok(result, 'pg: Valid result for generated query');
- test.done();
-});
-
-tests['nodeQuery.getQuery = nodeQuery.init'] = function(test) {
- test.expect(1);
- test.deepEqual(qb, nodeQuery.getQuery(), "getQuery returns same object");
- test.done();
-};
-
-tests["pg adapter with query builder"] = function(test) {
- test.expect(1);
- test.ok(testBase.qb);
-
- // Close the db connection
- connection.end();
- test.done();
-};
-
-
-module.exports = tests;
\ No newline at end of file
diff --git a/tests/base_test.js b/tests/base_test.js
deleted file mode 100755
index 8406519..0000000
--- a/tests/base_test.js
+++ /dev/null
@@ -1,42 +0,0 @@
-"use strict";
-
-var modules = {
- helpers: require('../lib/helpers'),
- driver: require('../lib/DriverBase'),
- qb: require('../lib/QueryBuilder'),
- 'node-query': require('../lib/NodeQuery'),
- 'state': require('../lib/State'),
- 'drivers/pg': require('../lib/drivers/Pg'),
- 'drivers/mysql': require('../lib/drivers/Mysql'),
- 'drivers/sqlite': require('../lib/drivers/Sqlite'),
- 'adapters/mysql': require('../lib/adapters/mysql'),
- 'adapters/mysql2': require('../lib/adapters/mysql2'),
- 'adapters/pg': require('../lib/adapters/pg'),
- 'adapters/dblite': require('../lib/adapters/dblite')
-};
-
-module.exports = {
- 'Sanity check': function (test) {
- test.expect(modules.length);
-
- Object.keys(modules).forEach(function(mod) {
- test.ok(modules[mod], mod + " module is sane");
- });
-
- test.done();
- },
- 'NodeQuery.getQuery with no instance': function(test) {
- test.expect(1);
- test.throws(function() {
- nodeQuery.getQuery();
- }, Error, "No query builder instance if none created");
- test.done();
- },
- 'Invalid driver type': function(test) {
- test.expect(1);
- test.throws(function() {
- nodeQuery.init('foo', {}, 'bar');
- }, Error, "Bad driver throws exception");
- test.done();
- }
-};
\ No newline at end of file
diff --git a/tests/helpers_test.js b/tests/helpers_test.js
deleted file mode 100644
index f96be15..0000000
--- a/tests/helpers_test.js
+++ /dev/null
@@ -1,87 +0,0 @@
-'use strict';
-
-var helpers = require('../lib/helpers');
-
-var helperTests = {
- 'Type checking method tests' : {
- "Object wrappers are listed as their native type": function(test) {
- test.deepEqual('boolean', helpers.type(new Boolean(true)), "Boolean Wrapper returns 'boolean' not 'object'");
- test.deepEqual('number', helpers.type(new Number(4867)), "Number Wrapper returns 'number' not 'object");
- test.deepEqual('string', helpers.type(new String("Foo")), "String Wrapper returns 'string' not 'object'");
- test.done();
- }
- },
- 'is..Method tests exist' : function(test) {
- test.expect(11);
-
- var types = ['Null','Undefined','Object','Array','String','Number','Boolean','Function','RegExp','NaN','Infinite'];
-
- types.forEach(function(type) {
- test.ok(helpers['is' + type], 'is' + type + ' method exists');
- });
-
- test.done();
- },
- 'isNaN': function(test) {
- test.expect(2);
- test.equal(helpers.type(0 / 0), 'nan');
- test.deepEqual(helpers.isNaN(0 / 0), true);
-
- test.done();
- },
- 'isInfinity': function(test) {
- test.expect(2);
-
- test.equal(helpers.type(1/0), 'infinity');
- test.deepEqual(helpers.isInfinite(1/0), true);
- test.done();
- },
- 'stringTrim': function(test) {
- test.expect(1);
-
- var orig = [' x y ', 'z ', ' q'];
- var ret = ['x y', 'z', 'q'];
-
- test.deepEqual(ret, orig.map(helpers.stringTrim));
-
- test.done();
- },
- 'arrayPluck': function(test) {
- test.expect(3);
-
- var orig = [{
- foo: 1
- },{
- foo: 2,
- bar: 10
- },{
- foo: 3,
- bar: 15
- }];
-
- test.deepEqual([1,2,3], helpers.arrayPluck(orig, 'foo'), 'Finding members in all objects');
- test.deepEqual([10,15], helpers.arrayPluck(orig, 'bar'), 'Some members are missing in some objects');
-
- // Empty case
- test.deepEqual([], helpers.arrayPluck([], 'apple'));
-
- test.done();
- },
- 'regexInArray': function(test) {
- var orig = ['apple', ' string ', 6, 4, 7];
-
- test.expect(6);
-
- test.equal(false, helpers.regexInArray(orig, /\$/), 'Dollar sign is not in any of the array items');
- test.equal(true, helpers.regexInArray(orig, /^ ?string/), "' string ' matches /^ ?string/");
- test.equal(true, helpers.regexInArray(orig, /APPLE/i), "'apple' matches /APPLE/i");
- test.equal(false, helpers.regexInArray(orig, /5/), 'None of the numbers in the array match /5/');
- test.equal(false, helpers.regexInArray(5, /5/), 'First argument is not an array');
- test.equal(false, helpers.regexInArray([], /.*/), 'Array is empty');
-
- test.done();
- }
-};
-
-
-module.exports = helperTests;
\ No newline at end of file
diff --git a/tests/query-builder-base.js b/tests/query-builder-base.js
deleted file mode 100644
index 8349236..0000000
--- a/tests/query-builder-base.js
+++ /dev/null
@@ -1,526 +0,0 @@
-'use strict';
-
-var helpers = require('../lib/helpers');
-var State = require('../lib/State');
-
-module.exports = (function QueryBuilderTestBase() {
-
- // That 'new' keyword is annoying
- if ( ! (this instanceof QueryBuilderTestBase)) return new QueryBuilderTestBase();
-
- var base = {};
-
- /**
- * Inject the appropriate driver and adapter for the test suite
- *
- * @param {Object} qb - The adapter-specific query builder object
- * @param {Function} callback - The test callback
- * @return void
- */
- this._setUp = function(qb, callback) {
- base.qb = qb;
- base.testCallback = callback;
-
- this.qb = base.qb;
- };
-
- /**
- * Generic query builder tests
- */
- this.tests = {
- // ! Get tests
- 'Get tests' : {
- 'Get with function': function(test) {
- test.expect(1);
- base.qb.select('id, COUNT(id) as count')
- .from('create_test')
- .groupBy('id')
- .get(base.testCallback.bind(this, test));
- },
- 'Basic select all get': function(test) {
- test.expect(1);
- base.qb.get('create_test', base.testCallback.bind(this, test));
- },
- 'Basic select all with from': function(test) {
- test.expect(1);
- base.qb.from('create_test')
- .get(base.testCallback.bind(this, test));
- },
- 'Get with limit': function(test) {
- test.expect(1);
- base.qb.get('create_test', 2, base.testCallback.bind(this, test));
- },
- 'Get with limit and offset': function(test) {
- test.expect(1);
- base.qb.get('create_test', 2, 1, base.testCallback.bind(this, test));
- },
- 'Test get with having': function(test) {
- test.expect(1);
- base.qb.select('id')
- .from('create_test')
- .groupBy('id')
- .having({'id >':1})
- .having('id !=', 3)
- .having('id', 900)
- .get(base.testCallback.bind(this, test));
- },
- "Test get with 'orHaving'": function(test) {
- test.expect(1);
- base.qb.select('id')
- .from('create_test')
- .groupBy('id')
- .having({'id >':1})
- .orHaving('id !=', 3)
- .get(base.testCallback.bind(this, test));
- }
- },
- // ! Select tests
- 'Select tests' : {
- 'Select where get': function(test) {
- test.expect(1);
- base.qb.select(['id', 'key as k', 'val'])
- .where('id >', 1)
- .where('id <', 900)
- .get('create_test', 2, 1, base.testCallback.bind(this, test));
- },
- 'Select where get 2': function(test) {
- test.expect(1);
- base.qb.select('id, key as k, val')
- .where('id !=', 1)
- .get('create_test', 2, 1, base.testCallback.bind(this, test));
- },
- 'Multi Order By': function(test) {
- test.expect(1);
- base.qb.from('create_test')
- .orderBy('id, key')
- .get(base.testCallback.bind(this, test));
- },
- 'Select get': function(test) {
- test.expect(1);
- base.qb.select('id, key as k, val')
- .get('create_test', 2, 1, base.testCallback.bind(this, test));
- },
- 'Select from get': function(test) {
- test.expect(1);
- base.qb.select('id, key as k, val')
- .from('create_test ct')
- .where('id >', 1)
- .get(base.testCallback.bind(this, test));
- },
- 'Select from limit get': function(test) {
- test.expect(1);
- base.qb.select('id, key as k, val')
- .from('create_test ct')
- .where('id >', 1)
- .limit(3)
- .get(base.testCallback.bind(this, test));
- },
- 'Select where IS NOT NULL': function(test) {
- test.expect(1);
- base.qb.select('id', 'key as k', 'val')
- .from('create_test ct')
- .whereIsNotNull('id')
- .get(base.testCallback.bind(this, test));
- },
- 'Select where IS NULL': function(test) {
- test.expect(1);
- base.qb.select('id', 'key as k', 'val')
- .from('create_test ct')
- .whereIsNull('id')
- .get(base.testCallback.bind(this, test));
- },
- 'Select where OR IS NOT NULL': function(test) {
- test.expect(1);
- base.qb.select('id', 'key as k', 'val')
- .from('create_test ct')
- .whereIsNull('id')
- .orWhereIsNotNull('id')
- .get(base.testCallback.bind(this, test));
- },
- 'Select where OR IS NULL': function(test) {
- test.expect(1);
- base.qb.select('id', 'key as k', 'val')
- .from('create_test ct')
- .where('id', 3)
- .orWhereIsNull('id')
- .get(base.testCallback.bind(this, test));
- },
- 'Select with string where value': function(test) {
- test.expect(1);
- base.qb.select('id','key as k', 'val')
- .from('create_test ct')
- .where('id > 3')
- .get(base.testCallback.bind(this, test));
- },
- 'Select with function and argument in WHERE clause': function(test) {
- test.expect(1);
- base.qb.select('id')
- .from('create_test')
- .where('id', 'CEILING(SQRT(88))')
- .get(base.testCallback.bind(this, test));
- }
- },
- // ! Grouping tests
- 'Grouping tests' : {
- 'Using grouping method': function(test) {
- test.expect(1);
- base.qb.select('id, key as k, val')
- .from('create_test')
- .groupStart()
- .where('id >', 1)
- .where('id <', 900)
- .groupEnd()
- .limit(2, 1)
- .get(base.testCallback.bind(this, test));
- },
- 'Using where first grouping': function(test) {
- test.expect(1);
- base.qb.select('id, key as k, val')
- .from('create_test')
- .where('id !=', 5)
- .groupStart()
- .where('id >', 1)
- .where('id <', 900)
- .groupEnd()
- .limit(2, 1)
- .get(base.testCallback.bind(this, test));
- },
- 'Using or grouping method': function(test) {
- test.expect(1);
- base.qb.select('id, key as k, val')
- .from('create_test')
- .groupStart()
- .where('id >', 1)
- .where('id <', 900)
- .groupEnd()
- .orGroupStart()
- .where('id', 0)
- .groupEnd()
- .limit(2, 1)
- .get(base.testCallback.bind(this, test));
- },
- 'Using or not grouping method': function(test) {
- test.expect(1);
- base.qb.select('id, key as k, val')
- .from('create_test')
- .groupStart()
- .where('id >', 1)
- .where('id <', 900)
- .groupEnd()
- .orNotGroupStart()
- .where('id', 0)
- .groupEnd()
- .limit(2, 1)
- .get(base.testCallback.bind(this, test));
- }
- },
- // ! Where in tests
- 'Where in tests' : {
- 'Where in': function(test) {
- test.expect(1);
- base.qb.from('create_test')
- .whereIn('id', [0, 6, 56, 563, 341])
- .get(base.testCallback.bind(this, test));
- },
- 'Or Where in': function(test) {
- test.expect(1);
- base.qb.from('create_test')
- .where('key', 'false')
- .orWhereIn('id', [0, 6, 56, 563, 341])
- .get(base.testCallback.bind(this, test));
- },
- 'Where Not in': function(test) {
- test.expect(1);
- base.qb.from('create_test')
- .where('key', 'false')
- .whereNotIn('id', [0, 6, 56, 563, 341])
- .get(base.testCallback.bind(this, test));
- },
- 'Or Where Not in': function(test) {
- test.expect(1);
- base.qb.from('create_test')
- .where('key', 'false')
- .orWhereNotIn('id', [0, 6, 56, 563, 341])
- .get(base.testCallback.bind(this, test));
- }
- },
- // ! Query modifier tests
- 'Query modifier tests': {
- 'Order By': function(test) {
- test.expect(1);
- base.qb.select('id, key as k, val')
- .from('create_test')
- .where('id >', 0)
- .where('id <', 9000)
- .orderBy('id', 'DESC')
- .orderBy('k', "ASC")
- .limit(5, 2)
- .get(base.testCallback.bind(this, test));
- },
- 'Group by': function(test) {
- test.expect(1);
- base.qb.select('id, key as k, val')
- .from('create_test')
- .where('id >', 0)
- .where('id <', 9000)
- .groupBy('k')
- .groupBy(['id', 'val'])
- .orderBy('id', 'DESC')
- .orderBy('k', "ASC")
- .limit(5, 2)
- .get(base.testCallback.bind(this, test));
- },
- 'Or Where': function(test) {
- test.expect(1);
- base.qb.select('id, key as k, val')
- .from('create_test')
- .where(' id ', 1)
- .orWhere('key >', 0)
- .limit(2, 1)
- .get(base.testCallback.bind(this, test));
- },
- 'Like' : function(test) {
- test.expect(1);
- base.qb.from('create_test')
- .like('key', 'og')
- .get(base.testCallback.bind(this, test));
- },
- 'Or Like': function(test) {
- test.expect(1);
- base.qb.from('create_test')
- .like('key', 'og')
- .orLike('key', 'val')
- .get(base.testCallback.bind(this, test));
- },
- 'Not Like': function(test) {
- test.expect(1);
- base.qb.from('create_test')
- .like('key', 'og', 'before')
- .notLike('key', 'val')
- .get(base.testCallback.bind(this, test));
- },
- 'Or Not Like': function(test) {
- test.expect(1);
- base.qb.from('create_test')
- .like('key', 'og', 'before')
- .orNotLike('key', 'val')
- .get(base.testCallback.bind(this, test));
- },
- 'Like Before': function(test) {
- test.expect(1);
- base.qb.from('create_test')
- .like('key', 'og', 'before')
- .get(base.testCallback.bind(this, test));
- },
- 'Like After': function(test) {
- test.expect(1);
- base.qb.from('create_test')
- .like('key', 'og', 'after')
- .get(base.testCallback.bind(this, test));
- },
- 'Basic Join': function(test) {
- test.expect(1);
- base.qb.from('create_test ct')
- .join('create_join cj', 'cj.id=ct.id')
- .get(base.testCallback.bind(this, test));
- },
- 'Left Join': function(test) {
- test.expect(1);
- base.qb.from('create_test ct')
- .join('create_join cj', 'cj.id=ct.id', 'left')
- .get(base.testCallback.bind(this, test));
- },
- 'InnerJoin': function(test) {
- test.expect(1);
- base.qb.from('create_test ct')
- .join('create_join cj', 'cj.id=ct.id', 'inner')
- .get(base.testCallback.bind(this, test));
- },
- 'Join with multiple where values': function(test) {
- test.expect(1);
- base.qb.from('create_test ct')
- .join('create_join cj', 'cj.id=ct.id', 'inner')
- .where({
- 'ct.id <': 3,
- 'ct.key': 'foo'
- })
- .get(base.testCallback.bind(this, test));
- }
- },
- // ! DB Update test
- 'DB update tests' : {
- setUp: function(callback) {
- var sql = base.qb.driver.truncate('create_test');
- base.qb.adapter.execute(sql, function(err, result) {
- callback();
- });
- },
- tearDown: function(callback) {
- callback();
- },
- 'Test Insert': function(test) {
- test.expect(1);
- base.qb.set('id', 98)
- .set('key', "84")
- .set('val', new Buffer("120"))
- .insert('create_test', base.testCallback.bind(this, test));
- },
- 'Test Insert Object': function(test) {
- test.expect(1);
- base.qb.insert('create_test', {
- id: 587,
- key: 1,
- val: new Buffer('2')
- }, base.testCallback.bind(this, test));
- },
- 'Test Insert Batch': function(test) {
- test.expect(1);
- var data = [{
- id: 544,
- key: 3,
- val: new Buffer('7')
- }, {
- id: 89,
- key: 34,
- val: new Buffer("10 o'clock")
- }, {
- id: 48,
- key: 403,
- val: new Buffer('97')
- }];
-
- base.qb.insertBatch('create_test', data, base.testCallback.bind(this, test));
- },
- 'Test Update': function(test) {
- test.expect(1);
- base.qb.where('id', 7)
- .update('create_test', {
- id: 7,
- key: 'gogle',
- val: new Buffer('non-word')
- }, base.testCallback.bind(this, test));
- },
- 'Test set Array Update': function(test) {
- test.expect(1);
- var object = {
- id: 22,
- key: 'gogle',
- val: new Buffer('non-word')
- };
-
- base.qb.set(object)
- .where('id', 22)
- .update('create_test', base.testCallback.bind(this, test));
- },
- 'Test where set update': function(test) {
- test.expect(1);
- base.qb.where('id', 36)
- .set('id', 36)
- .set('key', 'gogle')
- .set('val', new Buffer('non-word'))
- .update('create_test', base.testCallback.bind(this, test));
- },
- 'Test delete': function(test) {
- test.expect(1);
- base.qb.delete('create_test', {id: 5}, base.testCallback.bind(this, test));
- },
- 'delete with where': function(test) {
- test.expect(1);
- base.qb.where('id', 5)
- .delete('create_test', base.testCallback.bind(this, test));
- },
- 'Delete multiple where values': function(test) {
- test.expect(1);
- base.qb.delete('create_test', {
- id: 5,
- key: 'gogle'
- }, base.testCallback.bind(this, test));
- }
- },
- // ! Get compiled tests
- 'Get compiled tests' : {
- 'select': function(test) {
- test.expect(1);
- var string = base.qb.select('id')
- .from('create_test')
- .getCompiledSelect(true);
-
- test.equal(true, helpers.isString(string));
-
- test.done();
- },
- 'select from': function(test) {
- test.expect(1);
- var string = base.qb.select('id')
- .getCompiledSelect('create_test', true);
-
- test.equal(true, helpers.isString(string));
-
- test.done();
- },
- 'insert': function(test) {
- test.expect(1);
-
- var string = base.qb.set('id', 3)
- .getCompiledInsert('create_test');
-
- test.equal(true, helpers.isString(string));
-
- test.done();
- },
- 'update': function(test) {
- test.expect(1);
-
- var string = base.qb.set('id', 3)
- .where('id', 5)
- .getCompiledUpdate('create_test');
-
- test.equal(true, helpers.isString(string));
-
- test.done();
- },
- 'delete': function(test) {
- test.expect(1);
-
- var string = base.qb.where('id', 5)
- .getCompiledDelete('create_test');
-
- test.equal(true, helpers.isString(string));
-
- test.done();
- }
- },
- // ! Misc tests
- 'Misc tests' : {
- 'Get State': function(test) {
- test.expect(1);
-
- base.qb.select('foo')
- .from('bar')
- .where('baz', 'foobar');
-
- var state = new State();
-
- test.notDeepEqual(JSON.stringify(state), JSON.stringify(base.qb.getState()));
- test.done();
- },
- 'Reset State': function(test) {
- test.expect(1);
-
- base.qb.select('foo')
- .from('bar')
- .where('baz', 'foobar');
-
- base.qb.resetQuery();
-
- var state = new State();
-
- test.deepEqual(state, base.qb.getState());
-
- test.done();
- }
- }
- };
-
- return this;
-}());
\ No newline at end of file
diff --git a/tests/query-parser_test.js b/tests/query-parser_test.js
deleted file mode 100644
index a7fd249..0000000
--- a/tests/query-parser_test.js
+++ /dev/null
@@ -1,178 +0,0 @@
-'use strict';
-
-// Use the base driver as a mock for testing
-var getArgs = require('getargs');
-var helpers = require('../lib/helpers');
-var driver = require('../lib/DriverBase');
-
-var p = require('../lib/QueryParser');
-var parser = new p(driver);
-
-var State = require('../lib/State');
-
-// Simulate query builder state
-var state = new State();
-
-var mixedSet = function(/* $varName, $valType, $key, [$val] */) {
- var args = getArgs('$varName:string, $valType:string, $key:object|string|number, [$val]', arguments);
-
- var obj = {};
-
-
- if (helpers.isScalar(args.$key) && !helpers.isUndefined(args.$val))
- {
- // Convert key/val pair to a simple object
- obj[args.$key] = args.$val;
- }
- else if (helpers.isScalar(args.$key) && helpers.isUndefined(args.$val))
- {
- // If just a string for the key, and no value, create a simple object with duplicate key/val
- obj[args.$key] = args.$key;
- }
- else
- {
- obj = args.$key;
- }
-
- Object.keys(obj).forEach(function(k) {
- // If a single value for the return
- if (['key','value'].indexOf(args.$valType) !== -1)
- {
- var pushVal = (args.$valType === 'key') ? k : obj[k];
- state[args.$varName].push(pushVal);
- }
- else
- {
- state[args.$varName][k] = obj[k];
- }
- });
-
-
- return state[args.$varName];
-}
-
-var whereMock = function() {
- var args = getArgs('key:string|object, [val]', arguments);
-
- state.whereMap = [];
- state.whereValues = [];
-
- mixedSet('rawWhereValues', 'value', args.key, args.val);
- mixedSet('whereMap', 'both', args.key, args.val);
-}
-
-// -----------------------------------------------------------------------------
-// ! Start Tests
-// -----------------------------------------------------------------------------
-
-var tests = {
- 'Has operator tests': {
- 'Has operator': function(test) {
- var matches = parser.hasOperator('foo <> 2');
- test.deepEqual(['<>'], matches);
- test.done();
- },
- 'Has no operator': function(test) {
- var matches = parser.hasOperator('foo');
- test.equal(null, matches);
- test.done();
- }
- },
- 'Where parser tests': {
- 'Has function full string': function(test) {
- test.expect(1);
- whereMock('time < SUM(FOO(BAR()))');
- var result = parser.parseWhere(driver, state);
- test.deepEqual(['"time" < SUM(FOO(BAR()))'], state.whereMap);
-
- test.done();
- },
- 'Has function key/val': function(test) {
- test.expect(1);
- var map = whereMock('time <', 'SUM(FOO(BAR()))');
- state = parser.parseWhere(driver, state);
- test.deepEqual(['"time" < SUM(FOO(BAR()))'], state.whereMap);
-
- test.done();
- },
- 'Has function key/val object': function(test) {
- test.expect(1);
- var map = whereMock({
- 'time <': "SUM(FOO(BAR('x')))"
- });
- state = parser.parseWhere(driver, state);
- test.deepEqual(['"time" < SUM(FOO(BAR(\'x\')))'], state.whereMap);
-
- test.done();
- },
- 'Has literal value': function(test) {
- test.expect(2);
- var map = whereMock({
- 'foo': 3
- });
- state = parser.parseWhere(driver, state);
- test.deepEqual(['"foo" = ?'], state.whereMap);
- test.deepEqual(['3'], state.whereValues);
-
- test.done();
- },
- 'Has multiple literal values': function(test) {
- test.expect(2);
- var map = whereMock({
- foo: 3,
- bar: 5
- });
- state = parser.parseWhere(driver, state);
- test.deepEqual(['"foo" = ?', '"bar" = ?'], state.whereMap);
- test.deepEqual(['3','5'], state.whereValues);
-
- test.done();
- }
- },
- 'Parse join tests' : {
- 'Simple equals condition': function(test) {
- var matches = parser.parseJoin('table1.field1=table2.field2');
- test.deepEqual(['table1.field1','=','table2.field2'], matches.combined);
- test.done();
- },
- 'Db.table.field condition': function(test) {
- var matches = parser.parseJoin('db1.table1.field1!=db2.table2.field2');
- test.deepEqual(['db1.table1.field1','!=', 'db2.table2.field2'], matches.combined);
- test.done();
- },
- 'Underscore in identifier': function(test) {
- var matches = parser.parseJoin('table_1.field1 = tab_le2.field_2');
- test.deepEqual(['table_1.field1', '=', 'tab_le2.field_2'], matches.combined);
- test.done();
- },
- 'Function in condition': function(test) {
- var matches = parser.parseJoin('table1.field1 > SUM(3+6)');
- test.deepEqual(['table1.field1', '>', 'SUM(3+6)'], matches.combined);
- test.done();
- }
- },
- 'Compile join tests': {
- 'Simple equals condition': function(test) {
- var join = parser.compileJoin('table1.field1=table2.field2');
- test.deepEqual('"table1"."field1" = "table2"."field2"', join);
- test.done();
- },
- 'Db.table.field condition': function(test) {
- var join = parser.compileJoin('db1.table1.field1!=db2.table2.field2');
- test.deepEqual('"db1"."table1"."field1" != "db2"."table2"."field2"', join);
- test.done();
- },
- 'Underscore in identifier': function(test) {
- var join = parser.compileJoin('table_1.field1 = tab_le2.field_2');
- test.deepEqual('"table_1"."field1" = "tab_le2"."field_2"', join);
- test.done();
- },
- 'Function in condition': function(test) {
- var join = parser.compileJoin('table1.field1 > SUM(3+6)');
- test.deepEqual('"table1"."field1" > SUM(3+6)', join);
- test.done();
- }
- }
-};
-
-module.exports = tests;
\ No newline at end of file