Add promise interface to database execution methods
This commit is contained in:
parent
4b24771716
commit
da8b473bc7
@ -18,6 +18,7 @@ A node query builder for various SQL databases, based on CodeIgniter's query bui
|
||||
### Installation
|
||||
|
||||
npm install ci-node-query
|
||||
[![NPM](https://nodei.co/npm/ci-node-query.png?downloads=true&downloadRank=true&stars=true)](https://nodei.co/npm/ci-node-query/)
|
||||
|
||||
### Basic use
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
margin:0;
|
||||
}
|
||||
|
||||
.force-inline p {
|
||||
.force-inline, .force-inline p {
|
||||
display: inline;
|
||||
color: #222;
|
||||
}
|
||||
|
3411
docs/index.html
3411
docs/index.html
File diff suppressed because it is too large
Load Diff
24
gulpfile.js
24
gulpfile.js
@ -54,6 +54,13 @@ const ESLINT_SETTINGS = {
|
||||
}
|
||||
};
|
||||
|
||||
const MOCHA_OPTIONS = {
|
||||
ui: 'tdd',
|
||||
bail: true,
|
||||
reporter: 'list',
|
||||
timeout: 10000,
|
||||
};
|
||||
|
||||
gulp.task('lint', () => {
|
||||
pipe(gulp.src(SRC_FILES), [
|
||||
eslint(ESLINT_SETTINGS),
|
||||
@ -82,22 +89,14 @@ gulp.task('sloc', () => gulp.src(SRC_FILES).pipe(sloc()));
|
||||
gulp.task('test-sloc', () => gulp.src(TEST_FILES).pipe(sloc()));
|
||||
|
||||
gulp.task('docs', () => {
|
||||
gulp.src('./lib/QueryBuilder.js')
|
||||
gulp.src(['lib/*.js'])
|
||||
.pipe(documentation({format: 'html'}))
|
||||
.pipe(gulp.dest('docs'));
|
||||
/*gulp.src('./lib/QueryBuilder.js')
|
||||
.pipe(documentation({format: 'md'}))
|
||||
.pipe(gulp.dest('api-docs'));*/
|
||||
});
|
||||
|
||||
gulp.task('mocha', ['lint-tests', 'sloc'], () => {
|
||||
return gulp.src(TEST_FILES)
|
||||
.pipe(mocha({
|
||||
ui: 'tdd',
|
||||
bail: true,
|
||||
reporter: 'list',
|
||||
timeout: 5000
|
||||
}))
|
||||
.pipe(mocha(MOCHA_OPTIONS))
|
||||
.once('error', () => {
|
||||
process.exit(1);
|
||||
})
|
||||
@ -112,10 +111,7 @@ gulp.task('test', ['test-sloc', 'lint-tests'], function(cb) {
|
||||
istanbul.hookRequire()
|
||||
]).on('finish', () => {
|
||||
pipe(gulp.src(TEST_FILES), [
|
||||
mocha({
|
||||
ui: 'tdd',
|
||||
bail: true
|
||||
}),
|
||||
mocha(MOCHA_OPTIONS),
|
||||
istanbul.writeReports({
|
||||
dir: './coverage',
|
||||
reporters: ['lcov', 'lcovonly', 'html', 'text']
|
||||
|
@ -1,12 +1,18 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
/** @module Adapter */
|
||||
module.exports = class Adapter {
|
||||
/**
|
||||
* Class that wraps database connection libraries
|
||||
*
|
||||
* @private
|
||||
* @param {Object} instance - The connection object
|
||||
*/
|
||||
class Adapter {
|
||||
/**
|
||||
* Invoke an adapter
|
||||
*
|
||||
* @param {Object} instance - The connection objec
|
||||
* @return {void}
|
||||
* @constructor
|
||||
* @param {Object} instance - The connection object
|
||||
*/
|
||||
constructor(instance) {
|
||||
this.instance = instance;
|
||||
@ -17,8 +23,8 @@ module.exports = class Adapter {
|
||||
*
|
||||
* @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}
|
||||
* @param {Function} [callback] - Callback to run when a response is recieved
|
||||
* @return {void|Promise} - returns a promise if no callback is passed
|
||||
*/
|
||||
execute(/*sql, params, callback*/) {
|
||||
throw new Error('Correct adapter not defined for query execution');
|
||||
@ -31,4 +37,6 @@ module.exports = class Adapter {
|
||||
close() {
|
||||
this.instance.end();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = Adapter;
|
@ -1,13 +1,13 @@
|
||||
'use strict';
|
||||
|
||||
let helpers = require('./helpers');
|
||||
const helpers = require('./helpers');
|
||||
|
||||
/**
|
||||
* Base Database Driver
|
||||
*
|
||||
* @module driver
|
||||
* @private
|
||||
*/
|
||||
let d = {
|
||||
let Driver = {
|
||||
identifierStartChar: '"',
|
||||
identifierEndChar: '"',
|
||||
tablePrefix: null,
|
||||
@ -15,14 +15,14 @@ let d = {
|
||||
|
||||
/**
|
||||
* Low level function for naive quoting of strings
|
||||
|
||||
*
|
||||
* @param {String} str - The sql fragment to quote
|
||||
* @return {String} - The quoted sql fragment
|
||||
* @private
|
||||
*/
|
||||
_quote(str) {
|
||||
return (helpers.isString(str) && ! (str.startsWith(d.identifierStartChar) || str.endsWith(d.identifierEndChar)))
|
||||
? `${d.identifierStartChar}${str}${d.identifierEndChar}`
|
||||
return (helpers.isString(str) && ! (str.startsWith(Driver.identifierStartChar) || str.endsWith(Driver.identifierEndChar)))
|
||||
? `${Driver.identifierStartChar}${str}${Driver.identifierEndChar}`
|
||||
: str;
|
||||
},
|
||||
|
||||
@ -31,7 +31,7 @@ let d = {
|
||||
|
||||
* @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
|
||||
* @param {Number} [offset] - Number of rows to skip
|
||||
* @return {String} - Modified SQL statement
|
||||
*/
|
||||
limit(sql, limit, offset) {
|
||||
@ -53,37 +53,37 @@ let d = {
|
||||
*/
|
||||
quoteTable(table) {
|
||||
// Quote after prefix
|
||||
return d.quoteIdentifiers(table);
|
||||
return Driver.quoteIdentifiers(table);
|
||||
},
|
||||
|
||||
/**
|
||||
* 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)
|
||||
* @param {String|Array} str - String or array of strings to quote identifiers
|
||||
* @return {String|Array} - Quoted identifier(s)
|
||||
*/
|
||||
quoteIdentifiers(str) {
|
||||
let hiers, raw;
|
||||
let pattern = new RegExp(
|
||||
`${d.identifierStartChar}(`
|
||||
`${Driver.identifierStartChar}(`
|
||||
+ '([a-zA-Z0-9_]+)' + '(\((.*?)\))'
|
||||
+ `)${d.identifierEndChar}`, 'ig');
|
||||
+ `)${Driver.identifierEndChar}`, 'ig');
|
||||
|
||||
// Recurse for arrays of identifiiers
|
||||
if (Array.isArray(str))
|
||||
{
|
||||
return str.map(d.quoteIdentifiers);
|
||||
return str.map(Driver.quoteIdentifiers);
|
||||
}
|
||||
|
||||
// Handle commas
|
||||
if (str.includes(','))
|
||||
{
|
||||
let parts = str.split(',').map(helpers.stringTrim);
|
||||
str = parts.map(d.quoteIdentifiers).join(',');
|
||||
str = parts.map(Driver.quoteIdentifiers).join(',');
|
||||
}
|
||||
|
||||
// Split identifiers by period
|
||||
hiers = str.split('.').map(d._quote);
|
||||
hiers = str.split('.').map(Driver._quote);
|
||||
raw = hiers.join('.');
|
||||
|
||||
// Fix functions
|
||||
@ -96,30 +96,30 @@ let d = {
|
||||
|
||||
// Quote the identifiers inside of the parens
|
||||
let inParens = funcs[3].substring(1, funcs[3].length - 1);
|
||||
raw = raw.replace(inParens, d.quoteIdentifiers(inParens));
|
||||
raw = raw.replace(inParens, Driver.quoteIdentifiers(inParens));
|
||||
}
|
||||
|
||||
return raw;
|
||||
},
|
||||
|
||||
/**
|
||||
* SQL to truncate the passed table
|
||||
* Generate SQL to truncate the passed table
|
||||
*
|
||||
* @param {String} table - Table to truncate
|
||||
* @return {String} - Truncation SQL
|
||||
*/
|
||||
truncate(table) {
|
||||
let sql = (d.hasTruncate)
|
||||
let sql = (Driver.hasTruncate)
|
||||
? 'TRUNCATE '
|
||||
: 'DELETE FROM ';
|
||||
|
||||
sql += d.quoteTable(table);
|
||||
sql += Driver.quoteTable(table);
|
||||
|
||||
return sql;
|
||||
},
|
||||
|
||||
/**
|
||||
* SQL to insert a group of rows
|
||||
* Generate 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
|
||||
@ -143,9 +143,9 @@ let d = {
|
||||
|
||||
// Get the field names from the keys of the first
|
||||
// object inserted
|
||||
table = d.quoteTable(table);
|
||||
table = Driver.quoteTable(table);
|
||||
|
||||
sql += `INSERT INTO ${table} (${d.quoteIdentifiers(fields).join(',')}) VALUES `;
|
||||
sql += `INSERT INTO ${table} (${Driver.quoteIdentifiers(fields).join(',')}) VALUES `;
|
||||
|
||||
// Create placeholder groups
|
||||
params = Array(fields.length).fill('?');
|
||||
@ -161,4 +161,4 @@ let d = {
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = d;
|
||||
module.exports = Driver;
|
@ -5,14 +5,15 @@ let fs = require('fs'),
|
||||
QueryBuilder = require('./QueryBuilder');
|
||||
|
||||
/**
|
||||
* @module NodeQuery
|
||||
* Class for connection management
|
||||
*/
|
||||
class NodeQuery {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @return {void}
|
||||
* @private
|
||||
* @constructor
|
||||
*/
|
||||
constructor() {
|
||||
this.instance = null;
|
||||
@ -23,7 +24,7 @@ class 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
|
||||
* @param {String} [connLib] - The name of the db connection library you are using, eg. mysql or mysql2. Optional if the same as driverType
|
||||
* @return {QueryBuilder} - The Query Builder object
|
||||
*/
|
||||
init(driverType, connObject, connLib) {
|
||||
|
@ -1,23 +1,26 @@
|
||||
'use strict';
|
||||
|
||||
/** @module QueryBuilder */
|
||||
let getArgs = require('getargs'),
|
||||
helpers = require('./helpers'),
|
||||
State = require('./State'),
|
||||
QueryParser = require('./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
|
||||
* @return {QueryBuilder} - The Query Builder object, for chaining
|
||||
/**
|
||||
* Main object that builds SQL queries.
|
||||
*
|
||||
* @param {Driver} Driver - The syntax driver for the database
|
||||
* @param {Adapter} Adapter - The database module adapter for running queries
|
||||
*/
|
||||
class QueryBuilder {
|
||||
/**
|
||||
* @private
|
||||
* @constructor
|
||||
* @param {Driver} Driver - The syntax driver for the database
|
||||
* @param {Adapter} Adapter - The database module adapter for running queries
|
||||
*/
|
||||
constructor(driver, adapter) {
|
||||
this.driver = driver;
|
||||
this.adapter = adapter;
|
||||
constructor(Driver, Adapter) {
|
||||
this.driver = Driver;
|
||||
this.adapter = Adapter;
|
||||
this.parser = new QueryParser(this.driver);
|
||||
this.state = new State();
|
||||
}
|
||||
@ -265,8 +268,11 @@ module.exports = class QueryBuilder {
|
||||
this._resetState();
|
||||
|
||||
// Pass the sql and values to the adapter to run on the database
|
||||
this.adapter.execute(sql, vals, callback);
|
||||
|
||||
if (callback) {
|
||||
return this.adapter.execute(sql, vals, callback);
|
||||
} else {
|
||||
return this.adapter.execute(sql, vals);
|
||||
}
|
||||
}
|
||||
|
||||
_getCompile(type, table, reset) {
|
||||
@ -743,11 +749,11 @@ module.exports = class QueryBuilder {
|
||||
* @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}
|
||||
* @param {Function} [callback] - A callback for receiving the result
|
||||
* @return {void|Promise} - If no callback is passed, a promise is returned
|
||||
*/
|
||||
get(/* [table], [limit], [offset], callback */) {
|
||||
let args = getArgs('[table]:string, [limit]:number, [offset]:number, callback:function', arguments);
|
||||
get(/* [table], [limit], [offset], [callback] */) {
|
||||
let args = getArgs('[table]:string, [limit]:number, [offset]:number, [callback]:function', arguments);
|
||||
|
||||
if (args.table) {
|
||||
this.from(args.table);
|
||||
@ -758,7 +764,7 @@ module.exports = class QueryBuilder {
|
||||
}
|
||||
|
||||
// Run the query
|
||||
this._run('get', args.table, args.callback);
|
||||
return this._run('get', args.table, args.callback);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -766,18 +772,18 @@ module.exports = class QueryBuilder {
|
||||
*
|
||||
* @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}
|
||||
* @param {Function} [callback] - Callback for handling response from the database
|
||||
* @return {void|Promise} - If no callback is passed, a promise is returned
|
||||
*/
|
||||
insert(/* table, data, callback */) {
|
||||
let args = getArgs('table:string, [data]:object, callback:function', arguments);
|
||||
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);
|
||||
return this._run('insert', this.driver.quoteTable(args.table), args.callback);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -785,16 +791,16 @@ module.exports = class QueryBuilder {
|
||||
*
|
||||
* @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
|
||||
* @param {Function} [callback] - Callback for handling database response
|
||||
* @example query.insertBatch('foo',[{id:1,val:'bar'},{id:2,val:'baz'}], callbackFunction);
|
||||
* @return {void}
|
||||
* @return {void|Promise} - If no callback is passed, a promise is returned
|
||||
*/
|
||||
insertBatch(/* table, data, callback */) {
|
||||
let args = getArgs('table:string, data:array, callback:function', arguments);
|
||||
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);
|
||||
return this._run('', '', args.callback, batch.sql, batch.values);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -802,18 +808,18 @@ module.exports = class QueryBuilder {
|
||||
*
|
||||
* @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}
|
||||
* @param {Function} [callback] - Callback for handling response from the database
|
||||
* @return {void|Promise} - If no callback is passed, a promise is returned
|
||||
*/
|
||||
update(/*table, data, callback*/) {
|
||||
let args = getArgs('table:string, [data]:object, callback:function', arguments);
|
||||
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);
|
||||
return this._run('update', this.driver.quoteTable(args.table), args.callback);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -821,18 +827,18 @@ module.exports = class QueryBuilder {
|
||||
*
|
||||
* @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}
|
||||
* @param {Function} [callback] - Callback for handling response from the database
|
||||
* @return {void|Promise} - If no callback is passed, a promise is returned
|
||||
*/
|
||||
delete(/*table, [where], callback*/) {
|
||||
let args = getArgs('table:string, [where]:object, callback:function', arguments);
|
||||
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);
|
||||
return this._run('delete', this.driver.quoteTable(args.table), args.callback);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
@ -887,4 +893,6 @@ module.exports = class QueryBuilder {
|
||||
getCompiledDelete(table, reset) {
|
||||
return this._getCompile('delete', this.driver.quoteTable(table), reset);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = QueryBuilder;
|
@ -4,7 +4,13 @@ let helpers = require('./helpers');
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
module.exports = class QueryParser {
|
||||
/**
|
||||
* Internal object for parsing query fragments
|
||||
*
|
||||
* @private
|
||||
* @param {Driver} driver - The driver object for the database in use
|
||||
*/
|
||||
class QueryParser {
|
||||
/**
|
||||
* @constructor
|
||||
*
|
||||
@ -237,4 +243,6 @@ module.exports = class QueryParser {
|
||||
|
||||
return state;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = QueryParser;
|
11
lib/State.js
11
lib/State.js
@ -1,7 +1,10 @@
|
||||
'use strict';
|
||||
|
||||
/** @module State */
|
||||
module.exports = class State {
|
||||
/**
|
||||
* Class for objects containing the query builder state
|
||||
* @private
|
||||
*/
|
||||
class State {
|
||||
constructor() {
|
||||
// Arrays/maps
|
||||
this.queryMap = [];
|
||||
@ -25,6 +28,8 @@ module.exports = class State {
|
||||
this.limit = null;
|
||||
this.offset = null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = State;
|
||||
|
||||
// End of module State
|
@ -1,7 +1,8 @@
|
||||
'use strict';
|
||||
|
||||
let Adapter = require('../Adapter'),
|
||||
getArgs = require('getargs');
|
||||
getArgs = require('getargs'),
|
||||
Promise = require('bluebird');
|
||||
|
||||
module.exports = class dblite extends Adapter {
|
||||
/**
|
||||
@ -9,16 +10,23 @@ module.exports = class dblite extends Adapter {
|
||||
*
|
||||
* @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}
|
||||
* @param {Function} [callback] - Callback to run when a response is recieved
|
||||
* @return {void|Promise} - Returns a promise if no callback is provided
|
||||
*/
|
||||
execute(/*sql, params, callback*/) {
|
||||
let args = getArgs('sql:string, [params]:array, callback:function', arguments);
|
||||
this.instance.query(args.sql, args.params, args.callback);
|
||||
let args = getArgs('sql:string, [params]:array, [callback]:function', arguments);
|
||||
let instance = Promise.promisifyAll(this.instance);
|
||||
|
||||
if (! args.callback) {
|
||||
return instance.queryAsync(args.sql, args.params);
|
||||
}
|
||||
|
||||
return this.instance.query(args.sql, args.params, args.callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the current database connection
|
||||
|
||||
* @return {void}
|
||||
*/
|
||||
close() {
|
||||
|
@ -1,7 +1,8 @@
|
||||
'use strict';
|
||||
|
||||
let Adapter = require('../Adapter'),
|
||||
getArgs = require('getargs');
|
||||
getArgs = require('getargs'),
|
||||
Promise = require('bluebird');
|
||||
|
||||
module.exports = class mysql extends Adapter {
|
||||
/**
|
||||
@ -9,11 +10,17 @@ module.exports = class mysql extends Adapter {
|
||||
*
|
||||
* @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}
|
||||
* @param {Function} [callback] - Callback to run when a response is recieved
|
||||
* @return {void|Promise} - Returns a promise if no callback is provided
|
||||
*/
|
||||
execute(sql, params, callback) {
|
||||
let args = getArgs('sql:string, [params], callback:function', arguments);
|
||||
let args = getArgs('sql:string, [params], [callback]:function', arguments);
|
||||
let instance = Promise.promisifyAll(this.instance);
|
||||
|
||||
if (! args.callback) {
|
||||
return instance.queryAsync(args.sql, args.params);
|
||||
}
|
||||
|
||||
return this.instance.query(args.sql, args.params, args.callback);
|
||||
}
|
||||
};
|
@ -1,7 +1,8 @@
|
||||
'use strict';
|
||||
|
||||
let Adapter = require('../Adapter'),
|
||||
getArgs = require('getargs');
|
||||
getArgs = require('getargs'),
|
||||
Promise = require('bluebird');
|
||||
|
||||
module.exports = class mysql2 extends Adapter {
|
||||
/**
|
||||
@ -9,11 +10,17 @@ module.exports = class mysql2 extends Adapter {
|
||||
*
|
||||
* @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}
|
||||
* @param {Function} [callback] - Callback to run when a response is recieved
|
||||
* @return {void|Promise} - Returns a promise if no callback is provided
|
||||
*/
|
||||
execute(/*sql, params, callback*/) {
|
||||
let args = getArgs('sql:string, [params], callback:function', arguments);
|
||||
let args = getArgs('sql:string, [params], [callback]:function', arguments);
|
||||
let instance = Promise.promisifyAll(this.instance);
|
||||
|
||||
if (! args.callback) {
|
||||
return instance.executeAsync(args.sql, args.params);
|
||||
}
|
||||
|
||||
return this.instance.execute(args.sql, args.params, args.callback);
|
||||
}
|
||||
};
|
@ -1,7 +1,8 @@
|
||||
'use strict';
|
||||
|
||||
let Adapter = require('../Adapter'),
|
||||
getArgs = require('getargs');
|
||||
getArgs = require('getargs'),
|
||||
Promise = require('bluebird');
|
||||
|
||||
module.exports = class nodefirebird extends Adapter {
|
||||
/**
|
||||
@ -9,11 +10,25 @@ module.exports = class nodefirebird extends Adapter {
|
||||
*
|
||||
* @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}
|
||||
* @param {Function} [callback] - Callback to run when a response is recieved
|
||||
* @return {void|Promise} - Returns a promise if no callback is provided
|
||||
*/
|
||||
execute(/*sql, params, callback*/) {
|
||||
let args = getArgs('sql:string, [params], callback:function', arguments);
|
||||
return this.instance.execute(args.sql, args.params, args.callback);
|
||||
let args = getArgs('sql:string, [params], [callback]:function', arguments);
|
||||
let instance = Promise.promisifyAll(this.instance);
|
||||
|
||||
if (! args.callback) {
|
||||
return instance.queryAsync(args.sql, args.params);
|
||||
}
|
||||
|
||||
return this.instance.query(args.sql, args.params, args.callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the current database connection
|
||||
* @return {void}
|
||||
*/
|
||||
close() {
|
||||
this.instance.detach();
|
||||
}
|
||||
};
|
@ -1,7 +1,8 @@
|
||||
'use strict';
|
||||
|
||||
let Adapter = require('../Adapter'),
|
||||
getArgs = require('getargs');
|
||||
getArgs = require('getargs'),
|
||||
Promise = require('bluebird');
|
||||
|
||||
module.exports = class pg extends Adapter {
|
||||
/**
|
||||
@ -9,11 +10,12 @@ module.exports = class pg extends Adapter {
|
||||
*
|
||||
* @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}
|
||||
* @param {Function} [callback] - Callback to run when a response is recieved
|
||||
* @return {void|Promise} - Returns a promise if no callback is provided
|
||||
*/
|
||||
execute(/*sql, params, callback*/) {
|
||||
let args = getArgs('sql:string, [params]:array, callback:function', arguments);
|
||||
let args = getArgs('sql:string, [params]:array, [callback]:function', arguments);
|
||||
let instance = Promise.promisifyAll(this.instance);
|
||||
|
||||
// Replace question marks with numbered placeholders, because this adapter is different...
|
||||
let count = 0;
|
||||
@ -22,6 +24,10 @@ module.exports = class pg extends Adapter {
|
||||
return `$${count}`;
|
||||
});
|
||||
|
||||
this.instance.query(args.sql, args.params, args.callback);
|
||||
if (! args.callback) {
|
||||
return instance.queryAsync(args.sql, args.params);
|
||||
}
|
||||
|
||||
return this.instance.query(args.sql, args.params, args.callback);
|
||||
}
|
||||
};
|
@ -1,5 +1,10 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Various internal helper functions
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
let helpers = {
|
||||
/**
|
||||
* Wrap String.prototype.trim in a way that is easily mappable
|
||||
@ -124,9 +129,9 @@ types.forEach(t => {
|
||||
*
|
||||
* Types available are Null, Undefined, Object, Array, String, Number, Boolean, Function, RegExp, NaN and Infinite
|
||||
*
|
||||
* @name is[type]
|
||||
* @param {mixed} o
|
||||
* @return {Boolean}
|
||||
* @private
|
||||
* @param {mixed} o - The object to check its type
|
||||
* @return {Boolean} - If the type matches
|
||||
*/
|
||||
helpers[`is${t}`] = function(o) {
|
||||
if (t.toLowerCase() === 'infinite') {
|
||||
|
43
package.json
43
package.json
@ -1,11 +1,14 @@
|
||||
{
|
||||
"name": "ci-node-query",
|
||||
"version": "3.0.1",
|
||||
"version": "3.1.0",
|
||||
"description": "A query builder for node based on the one in CodeIgniter",
|
||||
"author": "Timothy J Warren <tim@timshomepage.net>",
|
||||
"engines": {
|
||||
"node": ">=4.0.0"
|
||||
},
|
||||
"files": [
|
||||
"lib/"
|
||||
],
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Timothy J Warren",
|
||||
@ -33,36 +36,34 @@
|
||||
},
|
||||
"main": "lib/NodeQuery.js",
|
||||
"dependencies": {
|
||||
"getargs": "",
|
||||
"mysql": "^2.9.0",
|
||||
"mysql2": "^0.15.8",
|
||||
"node-firebird": "^0.7.0",
|
||||
"pg": "^4.4.3",
|
||||
"require-reload": "*"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"dblite": "*",
|
||||
"node-firebird": "*",
|
||||
"pg": "*"
|
||||
"bluebird": "^3.1.4",
|
||||
"dblite": "~0.7.6",
|
||||
"getargs": "~0.0.8",
|
||||
"mysql": "~2.10.2",
|
||||
"mysql2": "~0.15.8",
|
||||
"node-firebird": "~0.7.2",
|
||||
"pg": "~4.4.3",
|
||||
"require-reload": "~0.2.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"chai": "",
|
||||
"chai": "~3.4.1",
|
||||
"chai-as-promised": "^5.2.0",
|
||||
"documentation": "",
|
||||
"eslint": "",
|
||||
"glob": "^6.0.1",
|
||||
"gulp": "",
|
||||
"gulp-documentation": "^2.1.0",
|
||||
"gulp-eslint": "",
|
||||
"eslint": "~1.10.3",
|
||||
"glob": "~6.0.4",
|
||||
"gulp": "~3.9.0",
|
||||
"gulp-documentation": "~2.1.0",
|
||||
"gulp-eslint": "~1.1.1",
|
||||
"gulp-istanbul": "^0.10.3",
|
||||
"gulp-jscs": "^3.0.2",
|
||||
"gulp-mocha": "^2.2.0",
|
||||
"gulp-pipe": "^1.0.4",
|
||||
"gulp-sloc": "",
|
||||
"istanbul": "",
|
||||
"gulp-sloc": "~1.0.4",
|
||||
"istanbul": "~0.4.2",
|
||||
"mocha": ""
|
||||
},
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"test": "gulp test"
|
||||
}
|
||||
}
|
||||
}
|
@ -1,479 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
module.exports.tests = {
|
||||
'Get tests': {
|
||||
'Get with function': {
|
||||
select: ['id, COUNT(id) as count'],
|
||||
from: ['create_test'],
|
||||
groupBy: ['id'],
|
||||
get: [],
|
||||
},
|
||||
'Basic select all get': {
|
||||
get: ['create_test'],
|
||||
},
|
||||
'Basic select all with from': {
|
||||
from: ['create_test'],
|
||||
get: [],
|
||||
},
|
||||
'Get with limit': {
|
||||
get: ['create_test', 2],
|
||||
},
|
||||
'Get with limit and offset': {
|
||||
get: ['create_test', 2, 1],
|
||||
},
|
||||
'Get with having': {
|
||||
select: ['id'],
|
||||
from: ['create_test'],
|
||||
groupBy: ['id'],
|
||||
having: [
|
||||
'multiple',
|
||||
[{'id >': 1}],
|
||||
['id !=', 3],
|
||||
['id', 900],
|
||||
],
|
||||
get: [],
|
||||
},
|
||||
'Get with orHaving': {
|
||||
select: ['id'],
|
||||
from: ['create_test'],
|
||||
groupBy: ['id'],
|
||||
having: [{'id >': 1}],
|
||||
orHaving: ['id !=', 3],
|
||||
get: [],
|
||||
},
|
||||
},
|
||||
'Select tests': {
|
||||
'Select where get': {
|
||||
select: [['id', 'key as k', 'val']],
|
||||
where: [
|
||||
'multiple',
|
||||
['id >', 1],
|
||||
['id <', 900],
|
||||
],
|
||||
get: ['create_test', 2, 1],
|
||||
},
|
||||
'Select where get 2': {
|
||||
select: ['id, key as k, val'],
|
||||
where: ['id !=', 1],
|
||||
get: ['create_test', 2, 1],
|
||||
},
|
||||
'Multi Order By': {
|
||||
from: ['create_test'],
|
||||
orderBy: ['id, key'],
|
||||
get: [],
|
||||
},
|
||||
'Select get': {
|
||||
select: ['id, key as k, val'],
|
||||
get: ['create_test', 2, 1],
|
||||
},
|
||||
'Select from get': {
|
||||
select: ['id, key as k, val'],
|
||||
from: ['create_test ct'],
|
||||
where: ['id >', 1],
|
||||
get: [],
|
||||
},
|
||||
'Select from limit get': {
|
||||
select: ['id, key as k, val'],
|
||||
from: ['create_test ct'],
|
||||
where: ['id >', 1],
|
||||
limit: [3],
|
||||
get: [],
|
||||
},
|
||||
'Select where IS NOT NULL': {
|
||||
select: ['id', 'key as k', 'val'],
|
||||
from: ['create_test ct'],
|
||||
whereIsNotNull: ['id'],
|
||||
get: [],
|
||||
},
|
||||
'Select where IS NULL': {
|
||||
select: ['id', 'key as k', 'val'],
|
||||
from: ['create_test ct'],
|
||||
whereIsNull: ['id'],
|
||||
get: [],
|
||||
},
|
||||
'Select where OR IS NOT NULL': {
|
||||
select: ['id', 'key as k', 'val'],
|
||||
from: ['create_test ct'],
|
||||
whereIsNull: ['id'],
|
||||
orWhereIsNotNull: ['id'],
|
||||
get: [],
|
||||
},
|
||||
'Select where OR IS NULL': {
|
||||
select: ['id', 'key as k', 'val'],
|
||||
from: ['create_test ct'],
|
||||
where: ['id', 3],
|
||||
orWhereIsNull: ['id'],
|
||||
get: [],
|
||||
},
|
||||
'Select with string where value': {
|
||||
select: ['id', 'key as k', 'val'],
|
||||
from: ['create_test ct'],
|
||||
where: ['id > 3'],
|
||||
get: [],
|
||||
},
|
||||
'Select with function and argument in WHERE clause': {
|
||||
select: ['id'],
|
||||
from: ['create_test ct'],
|
||||
where: ['id', 'CEILING(SQRT(88))'],
|
||||
get: [],
|
||||
},
|
||||
},
|
||||
'Where in tests': {
|
||||
'Where in': {
|
||||
from: ['create_test'],
|
||||
whereIn: ['id', [0, 6, 56, 563, 341]],
|
||||
get: [],
|
||||
},
|
||||
'Or Where in': {
|
||||
from: ['create_test'],
|
||||
where: ['key', 'false'],
|
||||
orWhereIn: ['id', [0, 6, 56, 563, 341]],
|
||||
get: [],
|
||||
},
|
||||
'Where Not in': {
|
||||
from: ['create_test'],
|
||||
where: ['key', 'false'],
|
||||
whereNotIn: ['id', [0, 6, 56, 563, 341]],
|
||||
get: [],
|
||||
},
|
||||
'Or Where Not in': {
|
||||
from: ['create_test'],
|
||||
where: ['key', 'false'],
|
||||
orWhereNotIn: ['id', [0, 6, 56, 563, 341]],
|
||||
get: [],
|
||||
},
|
||||
},
|
||||
'Query modifier tests': {
|
||||
'Order By': {
|
||||
select: ['id, key as k, val'],
|
||||
from: ['create_test'],
|
||||
where: [
|
||||
'multiple',
|
||||
['id >', 0],
|
||||
['id <', 9000],
|
||||
],
|
||||
orderBy: [
|
||||
'multiple',
|
||||
['id', 'DESC'],
|
||||
['k', 'ASC'],
|
||||
],
|
||||
limit: [5, 2],
|
||||
get: [],
|
||||
},
|
||||
'Group By': {
|
||||
select: ['id, key as k, val'],
|
||||
from: ['create_test'],
|
||||
where: [
|
||||
'multiple',
|
||||
['id >', 0],
|
||||
['id <', 9000],
|
||||
],
|
||||
groupBy: [
|
||||
'multiple',
|
||||
['k'],
|
||||
[['id', 'val']],
|
||||
],
|
||||
orderBy: [
|
||||
'multiple',
|
||||
['id', 'DESC'],
|
||||
['k', 'ASC'],
|
||||
],
|
||||
limit: [5, 2],
|
||||
get: [],
|
||||
},
|
||||
'Or Where': {
|
||||
select: ['id, key as k, val'],
|
||||
from: ['create_test'],
|
||||
where: [' id ', 1],
|
||||
orWhere: ['key > ', 0],
|
||||
limit: [2, 1],
|
||||
get: [],
|
||||
},
|
||||
Like: {
|
||||
from: ['create_test'],
|
||||
like: ['key', 'og'],
|
||||
get: [],
|
||||
},
|
||||
'Or Like': {
|
||||
from: ['create_test'],
|
||||
like: ['key', 'og'],
|
||||
orLike: ['key', 'val'],
|
||||
get: [],
|
||||
},
|
||||
'Not Like': {
|
||||
from: ['create_test'],
|
||||
like: ['key', 'og', 'before'],
|
||||
notLike: ['key', 'val'],
|
||||
get: [],
|
||||
},
|
||||
'Or Not Like': {
|
||||
from: ['create_test'],
|
||||
like: ['key', 'og', 'before'],
|
||||
orNotLike: ['key', 'val'],
|
||||
get: [],
|
||||
},
|
||||
'Like Before': {
|
||||
from: ['create_test'],
|
||||
like: ['key', 'og', 'before'],
|
||||
get: [],
|
||||
},
|
||||
'Like After': {
|
||||
from: ['create_test'],
|
||||
like: ['key', 'og', 'after'],
|
||||
get: [],
|
||||
},
|
||||
'Basic Join': {
|
||||
from: ['create_test ct'],
|
||||
join: ['create_join cj', 'cj.id=ct.id'],
|
||||
get: [],
|
||||
},
|
||||
'Left Join': {
|
||||
from: ['create_test ct'],
|
||||
join: ['create_join cj', 'cj.id=ct.id', 'left'],
|
||||
get: [],
|
||||
},
|
||||
'Inner Join': {
|
||||
from: ['create_test ct'],
|
||||
join: ['create_join cj', 'cj.id=ct.id', 'inner'],
|
||||
get: [],
|
||||
},
|
||||
'Join with multiple where values': {
|
||||
from: ['create_test ct'],
|
||||
join: ['create_join cj', 'cj.id=ct.id', 'inner'],
|
||||
where: [
|
||||
{
|
||||
'ct.id < ': 3,
|
||||
'ct.key ': 'foo',
|
||||
},
|
||||
],
|
||||
get: [],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
let expect = require('chai').expect,
|
||||
helpers = require('../../lib/helpers'),
|
||||
State = require('../../lib/State');
|
||||
|
||||
module.exports.runner = (tests, qb, callback) => {
|
||||
Object.keys(tests).forEach(suiteName => {
|
||||
suite(suiteName, () => {
|
||||
let currentSuite = tests[suiteName];
|
||||
Object.keys(currentSuite).forEach(testDesc => {
|
||||
test(testDesc, done => {
|
||||
let methodObj = currentSuite[testDesc];
|
||||
let methodNames = Object.keys(methodObj);
|
||||
let lastMethodIndex = methodNames[methodNames.length - 1];
|
||||
|
||||
methodObj[lastMethodIndex].push((err, rows) => {
|
||||
callback(err, done);
|
||||
});
|
||||
|
||||
methodNames.forEach(name => {
|
||||
let args = methodObj[name],
|
||||
method = qb[name];
|
||||
|
||||
if (args[0] === 'multiple') {
|
||||
args.shift();
|
||||
args.forEach(argSet => {
|
||||
method.apply(qb, argSet);
|
||||
});
|
||||
|
||||
} else {
|
||||
method.apply(qb, args);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
suite('DB update tests', () => {
|
||||
setup(done => {
|
||||
let sql = qb.driver.truncate('create_test');
|
||||
qb.adapter.execute(sql, (err, res) => {
|
||||
done();
|
||||
});
|
||||
});
|
||||
test('Test Insert', done => {
|
||||
qb.set('id', 98)
|
||||
.set('key', '84')
|
||||
.set('val', new Buffer('120'))
|
||||
.insert('create_test', (err, rows) => {
|
||||
return callback(err, done);
|
||||
});
|
||||
});
|
||||
test('Test Insert Object', done => {
|
||||
qb.insert('create_test', {
|
||||
id: 587,
|
||||
key: 1,
|
||||
val: new Buffer('2'),
|
||||
}, (err, rows) => {
|
||||
return callback(err, done);
|
||||
});
|
||||
});
|
||||
test('Test Update', done => {
|
||||
qb.where('id', 7)
|
||||
.update('create_test', {
|
||||
id: 7,
|
||||
key: 'gogle',
|
||||
val: new Buffer('non-word'),
|
||||
}, (err, rows) => {
|
||||
return callback(err, done);
|
||||
});
|
||||
});
|
||||
test('Test set Array Update', done => {
|
||||
let object = {
|
||||
id: 22,
|
||||
key: 'gogle',
|
||||
val: new Buffer('non-word'),
|
||||
};
|
||||
|
||||
qb.set(object)
|
||||
.where('id', 22)
|
||||
.update('create_test', (err, rows) => {
|
||||
return callback(err, done);
|
||||
});
|
||||
});
|
||||
test('Test where set update', done => {
|
||||
qb.where('id', 36)
|
||||
.set('id', 36)
|
||||
.set('key', 'gogle')
|
||||
.set('val', new Buffer('non-word'))
|
||||
.update('create_test', (err, rows) => {
|
||||
return callback(err, done);
|
||||
});
|
||||
});
|
||||
test('Test delete', done => {
|
||||
qb.delete('create_test', {id: 5}, (err, rows) => {
|
||||
return callback(err, done);
|
||||
});
|
||||
});
|
||||
test('Delete with where', done => {
|
||||
qb.where('id', 5)
|
||||
.delete('create_test', (err, rows) => {
|
||||
return callback(err, done);
|
||||
});
|
||||
});
|
||||
test('Delete multiple where values', done => {
|
||||
qb.delete('create_test', {
|
||||
id: 5,
|
||||
key: 'gogle',
|
||||
}, (err, rows) => {
|
||||
return callback(err, done);
|
||||
});
|
||||
});
|
||||
});
|
||||
suite('Grouping tests', () => {
|
||||
test('Using grouping method', done => {
|
||||
qb.select('id, key as k, val')
|
||||
.from('create_test')
|
||||
.groupStart()
|
||||
.where('id >', 1)
|
||||
.where('id <', 900)
|
||||
.groupEnd()
|
||||
.limit(2, 1)
|
||||
.get((err, rows) => {
|
||||
return callback(err, done);
|
||||
});
|
||||
});
|
||||
test('Using where first grouping', done => {
|
||||
qb.select('id, key as k, val')
|
||||
.from('create_test')
|
||||
.where('id !=', 5)
|
||||
.groupStart()
|
||||
.where('id >', 1)
|
||||
.where('id <', 900)
|
||||
.groupEnd()
|
||||
.limit(2, 1)
|
||||
.get((err, rows) => {
|
||||
return callback(err, done);
|
||||
});
|
||||
});
|
||||
test('Using or grouping method', done => {
|
||||
qb.select('id, key as k, val')
|
||||
.from('create_test')
|
||||
.groupStart()
|
||||
.where('id >', 1)
|
||||
.where('id <', 900)
|
||||
.groupEnd()
|
||||
.orGroupStart()
|
||||
.where('id', 0)
|
||||
.groupEnd()
|
||||
.limit(2, 1)
|
||||
.get((err, rows) => {
|
||||
return callback(err, done);
|
||||
});
|
||||
});
|
||||
test('Using or not grouping method', done => {
|
||||
qb.select('id, key as k, val')
|
||||
.from('create_test')
|
||||
.groupStart()
|
||||
.where('id >', 1)
|
||||
.where('id <', 900)
|
||||
.groupEnd()
|
||||
.orNotGroupStart()
|
||||
.where('id', 0)
|
||||
.groupEnd()
|
||||
.limit(2, 1)
|
||||
.get((err, rows) => {
|
||||
return callback(err, done);
|
||||
});
|
||||
});
|
||||
});
|
||||
suite('Get compiled tests', () => {
|
||||
test('select', () => {
|
||||
let sql = qb.select('id')
|
||||
.from('create_test')
|
||||
.getCompiledSelect(true);
|
||||
|
||||
expect(helpers.isString(sql)).to.be.true;
|
||||
});
|
||||
test('select from', () => {
|
||||
let sql = qb.select('id')
|
||||
.getCompiledSelect('create_test', true);
|
||||
|
||||
expect(helpers.isString(sql)).to.be.true;
|
||||
});
|
||||
test('insert', () => {
|
||||
let sql = qb.set('id', 3)
|
||||
.getCompiledInsert('create_test');
|
||||
|
||||
expect(helpers.isString(sql)).to.be.true;
|
||||
});
|
||||
test('update', () => {
|
||||
let sql = qb.set('id', 3)
|
||||
.where('id', 5)
|
||||
.getCompiledUpdate('create_test');
|
||||
|
||||
expect(helpers.isString(sql)).to.be.true;
|
||||
});
|
||||
test('delete', () => {
|
||||
let sql = qb.where('id', 5)
|
||||
.getCompiledDelete('create_test');
|
||||
|
||||
expect(helpers.isString(sql)).to.be.true;
|
||||
});
|
||||
});
|
||||
suite('Misc tests', () => {
|
||||
test('Get State', () => {
|
||||
qb.select('foo')
|
||||
.from('bar')
|
||||
.where('baz', 'foobar');
|
||||
|
||||
let state = new State();
|
||||
|
||||
expect(JSON.stringify(state)).to.not.be.deep.equal(qb.getState());
|
||||
});
|
||||
test('Reset State', () => {
|
||||
qb.select('foo')
|
||||
.from('bar')
|
||||
.where('baz', 'foobar');
|
||||
|
||||
qb.resetQuery();
|
||||
|
||||
let state = new State();
|
||||
|
||||
expect(qb.getState()).to.be.deep.equal(state);
|
||||
});
|
||||
});
|
||||
};
|
@ -1,11 +1,14 @@
|
||||
'use strict';
|
||||
|
||||
// Load the test base
|
||||
let reload = require('require-reload')(require);
|
||||
let getArgs = require('getargs');
|
||||
let expect = require('chai').expect;
|
||||
let tests = reload('./adapterTestBase').tests;
|
||||
let testRunner = reload('./adapterTestBase').runner;
|
||||
const reload = require('require-reload')(require);
|
||||
reload.emptyCache();
|
||||
const testBase = reload('../base');
|
||||
const expect = testBase.expect,
|
||||
promiseTestRunner = testBase.promiseTestRunner,
|
||||
testRunner = testBase.testRunner;
|
||||
|
||||
let tests = reload('../base/tests');
|
||||
|
||||
// Load the test config file
|
||||
let adapterName = 'dblite';
|
||||
@ -25,53 +28,73 @@ if (connection) {
|
||||
let nodeQuery = require('../../lib/NodeQuery');
|
||||
let qb = nodeQuery.init('sqlite', connection, adapterName);
|
||||
|
||||
// Add a test for this adapter
|
||||
tests['Select tests']['Select with function and argument in WHERE clause'] = {
|
||||
select: ['id'],
|
||||
from: ['create_test'],
|
||||
where: ['id', 'ABS(-88)'],
|
||||
get: [],
|
||||
};
|
||||
|
||||
suite('Dblite adapter tests', () => {
|
||||
suiteSetup(() => {
|
||||
suite('Dblite adapter tests -', () => {
|
||||
suiteSetup(done => {
|
||||
// Set up the sqlite database
|
||||
let 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);
|
||||
connection.query(sql, () => {
|
||||
return done();
|
||||
});
|
||||
});
|
||||
testRunner(tests, qb, (err, done) => {
|
||||
test('nodeQuery.getQuery = nodeQuery.init', () => {
|
||||
expect(nodeQuery.getQuery())
|
||||
.to.be.deep.equal(qb);
|
||||
});
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Callback Tests
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
testRunner(qb, (err, done) => {
|
||||
expect(err).is.not.ok;
|
||||
done();
|
||||
});
|
||||
suite('Adapter-specific tests', () => {
|
||||
test('nodeQuery.getQuery = nodeQuery.init', () => {
|
||||
expect(nodeQuery.getQuery())
|
||||
.to.be.deep.equal(qb);
|
||||
});
|
||||
test('Test Insert Batch', done => {
|
||||
let data = [
|
||||
{
|
||||
id: 544,
|
||||
key: 3,
|
||||
val: new Buffer('7'),
|
||||
}, {
|
||||
id: 89,
|
||||
key: 34,
|
||||
val: new Buffer('10 o\'clock'),
|
||||
}, {
|
||||
id: 48,
|
||||
key: 403,
|
||||
val: new Buffer('97'),
|
||||
},
|
||||
];
|
||||
|
||||
qb.insertBatch('create_test', data, (err, rows) => {
|
||||
test('Callback - Select with function and argument in WHERE clause', done => {
|
||||
qb.select('id')
|
||||
.from('create_test')
|
||||
.where('id', 'ABS(-88)')
|
||||
.get((err, rows) => {
|
||||
expect(err).is.not.ok;
|
||||
return done();
|
||||
});
|
||||
});
|
||||
test('Callback - Test Insert Batch', done => {
|
||||
let data = [
|
||||
{
|
||||
id: 544,
|
||||
key: 3,
|
||||
val: new Buffer('7'),
|
||||
}, {
|
||||
id: 89,
|
||||
key: 34,
|
||||
val: new Buffer('10 o\'clock'),
|
||||
}, {
|
||||
id: 48,
|
||||
key: 403,
|
||||
val: new Buffer('97'),
|
||||
},
|
||||
];
|
||||
|
||||
qb.insertBatch('create_test', data, (err, rows) => {
|
||||
expect(err).is.not.ok;
|
||||
return done();
|
||||
});
|
||||
});
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Promise Tests
|
||||
---------------------------------------------------------------------------*/
|
||||
promiseTestRunner(qb);
|
||||
test('Promise - Select with function and argument in WHERE clause', () => {
|
||||
let promise = qb.select('id')
|
||||
.from('create_test')
|
||||
.where('id', 'ABS(-88)')
|
||||
.get();
|
||||
|
||||
expect(promise).to.be.fulfilled;
|
||||
});
|
||||
|
||||
suiteTeardown(() => {
|
||||
qb.end();
|
||||
});
|
||||
|
64
test/adapters/mysql-base.js
Normal file
64
test/adapters/mysql-base.js
Normal file
@ -0,0 +1,64 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = function mysqlBase(qb, nodeQuery, expect, testRunner, promiseTestRunner) {
|
||||
test('nodeQuery.getQuery = nodeQuery.init', () => {
|
||||
expect(nodeQuery.getQuery())
|
||||
.to.be.deep.equal(qb);
|
||||
});
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Callback Tests
|
||||
---------------------------------------------------------------------------*/
|
||||
testRunner(qb, (err, done) => {
|
||||
expect(err).is.not.ok;
|
||||
done();
|
||||
});
|
||||
test('Callback - Select with function and argument in WHERE clause', done => {
|
||||
qb.select('id')
|
||||
.from('create_test')
|
||||
.where('id', 'CEILING(SQRT(88))')
|
||||
.get((err, rows) => {
|
||||
expect(err).is.not.ok;
|
||||
return done();
|
||||
});
|
||||
});
|
||||
test('Test Insert Batch', done => {
|
||||
let data = [
|
||||
{
|
||||
id: 544,
|
||||
key: 3,
|
||||
val: new Buffer('7'),
|
||||
}, {
|
||||
id: 89,
|
||||
key: 34,
|
||||
val: new Buffer('10 o\'clock'),
|
||||
}, {
|
||||
id: 48,
|
||||
key: 403,
|
||||
val: new Buffer('97'),
|
||||
},
|
||||
];
|
||||
|
||||
qb.insertBatch('create_test', data, (err, rows) => {
|
||||
expect(err).is.not.ok;
|
||||
return done();
|
||||
});
|
||||
});
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Promise Tests
|
||||
---------------------------------------------------------------------------*/
|
||||
promiseTestRunner(qb);
|
||||
test('Promise - Select with function and argument in WHERE clause', () => {
|
||||
let promise = qb.select('id')
|
||||
.from('create_test')
|
||||
.where('id', 'CEILING(SQRT(88))')
|
||||
.get();
|
||||
|
||||
expect(promise).to.be.fulfilled;
|
||||
});
|
||||
|
||||
suiteTeardown(() => {
|
||||
qb.end();
|
||||
});
|
||||
};
|
@ -1,14 +1,16 @@
|
||||
'use strict';
|
||||
|
||||
let configFile = (process.env.CI) ? '../config-travis.json' : '../config.json';
|
||||
const configFile = (process.env.CI) ? '../config-travis.json' : '../config.json';
|
||||
|
||||
// Load the test base
|
||||
let reload = require('require-reload')(require);
|
||||
const reload = require('require-reload')(require);
|
||||
reload.emptyCache();
|
||||
const testBase = reload('../base');
|
||||
const expect = testBase.expect,
|
||||
promiseTestRunner = testBase.promiseTestRunner,
|
||||
testRunner = testBase.testRunner;
|
||||
|
||||
let getArgs = reload('getargs');
|
||||
let expect = reload('chai').expect;
|
||||
let tests = reload('./adapterTestBase').tests;
|
||||
let testRunner = reload('./adapterTestBase').runner;
|
||||
|
||||
// Load the test config file
|
||||
let adapterName = 'mysql2';
|
||||
@ -22,40 +24,6 @@ let connection = mysql2.createConnection(config.conn);
|
||||
let nodeQuery = reload('../../lib/NodeQuery');
|
||||
let qb = nodeQuery.init('mysql', connection, adapterName);
|
||||
|
||||
suite('Mysql2 adapter tests', () => {
|
||||
testRunner(tests, qb, (err, done) => {
|
||||
expect(err).is.not.ok;
|
||||
done();
|
||||
});
|
||||
suite('Adapter-specific tests', () => {
|
||||
test('nodeQuery.getQuery = nodeQuery.init', () => {
|
||||
expect(nodeQuery.getQuery())
|
||||
.to.be.deep.equal(qb);
|
||||
});
|
||||
test('Test Insert Batch', done => {
|
||||
let data = [
|
||||
{
|
||||
id: 544,
|
||||
key: 3,
|
||||
val: new Buffer('7'),
|
||||
}, {
|
||||
id: 89,
|
||||
key: 34,
|
||||
val: new Buffer('10 o\'clock'),
|
||||
}, {
|
||||
id: 48,
|
||||
key: 403,
|
||||
val: new Buffer('97'),
|
||||
},
|
||||
];
|
||||
|
||||
qb.insertBatch('create_test', data, (err, rows) => {
|
||||
expect(err).is.not.ok;
|
||||
return done();
|
||||
});
|
||||
});
|
||||
});
|
||||
suiteTeardown(() => {
|
||||
qb.end();
|
||||
});
|
||||
suite('Mysql2 adapter tests -', () => {
|
||||
require('./mysql-base')(qb, nodeQuery, expect, testRunner, promiseTestRunner);
|
||||
});
|
@ -1,14 +1,16 @@
|
||||
'use strict';
|
||||
|
||||
let configFile = (process.env.CI) ? '../config-travis.json' : '../config.json';
|
||||
const configFile = (process.env.CI) ? '../config-travis.json' : '../config.json';
|
||||
|
||||
// Load the test base
|
||||
let reload = require('require-reload')(require);
|
||||
const reload = require('require-reload')(require);
|
||||
reload.emptyCache();
|
||||
const testBase = reload('../base');
|
||||
const expect = testBase.expect,
|
||||
promiseTestRunner = testBase.promiseTestRunner,
|
||||
testRunner = testBase.testRunner;
|
||||
|
||||
let getArgs = reload('getargs');
|
||||
let expect = reload('chai').expect;
|
||||
let tests = reload('./adapterTestBase').tests;
|
||||
let testRunner = reload('./adapterTestBase').runner;
|
||||
|
||||
// Load the test config file
|
||||
let adapterName = 'mysql';
|
||||
@ -22,40 +24,6 @@ let connection = mysql.createConnection(config.conn);
|
||||
let nodeQuery = reload('../../lib/NodeQuery');
|
||||
let qb = nodeQuery.init('mysql', connection);
|
||||
|
||||
suite('Mysql adapter tests', () => {
|
||||
testRunner(tests, qb, (err, done) => {
|
||||
expect(err).is.not.ok;
|
||||
done();
|
||||
});
|
||||
suite('Adapter-specific tests', () => {
|
||||
test('nodeQuery.getQuery = nodeQuery.init', () => {
|
||||
expect(nodeQuery.getQuery())
|
||||
.to.be.deep.equal(qb);
|
||||
});
|
||||
test('Test Insert Batch', done => {
|
||||
let data = [
|
||||
{
|
||||
id: 544,
|
||||
key: 3,
|
||||
val: new Buffer('7'),
|
||||
}, {
|
||||
id: 89,
|
||||
key: 34,
|
||||
val: new Buffer('10 o\'clock'),
|
||||
}, {
|
||||
id: 48,
|
||||
key: 403,
|
||||
val: new Buffer('97'),
|
||||
},
|
||||
];
|
||||
|
||||
qb.insertBatch('create_test', data, (err, rows) => {
|
||||
expect(err).is.not.ok;
|
||||
return done();
|
||||
});
|
||||
});
|
||||
});
|
||||
suiteTeardown(() => {
|
||||
qb.end();
|
||||
});
|
||||
suite('Mysql adapter tests -', () => {
|
||||
require('./mysql-base')(qb, nodeQuery, expect, testRunner, promiseTestRunner);
|
||||
});
|
51
test/adapters/node-firebird.js
Normal file
51
test/adapters/node-firebird.js
Normal file
@ -0,0 +1,51 @@
|
||||
'use strict';
|
||||
|
||||
// Load the test base
|
||||
const path = require('path');
|
||||
const reload = require('require-reload')(require);
|
||||
const testBase = reload('../base');
|
||||
const expect = reload('chai').expect;
|
||||
const testRunner = testBase.testRunner;
|
||||
const promiseTestRunner = testBase.promiseTestRunner;
|
||||
|
||||
// Load the test config file
|
||||
let adapterName = 'node-firebird';
|
||||
let Firebird = reload(adapterName);
|
||||
const config = reload('../config.json')[adapterName];
|
||||
config.conn.database = path.join(__dirname, config.conn.database);
|
||||
let nodeQuery = reload('../../lib/NodeQuery');
|
||||
|
||||
let qb = null;
|
||||
|
||||
// Skip on TravisCi
|
||||
if (process.env.CI || process.env.JENKINS_HOME) {
|
||||
return;
|
||||
}
|
||||
|
||||
suite('Firebird adapter tests -', () => {
|
||||
// Set up the query builder object
|
||||
suiteSetup('Database connection', connected => {
|
||||
Firebird.attach(config.conn, (err, db) => {
|
||||
qb = nodeQuery.init('firebird', db, adapterName);
|
||||
return connected(err);
|
||||
});
|
||||
});
|
||||
testRunner(qb, (err, done) => {
|
||||
expect(err).is.not.ok;
|
||||
done();
|
||||
});
|
||||
suite('Adapter-specific tests', () => {
|
||||
test('nodeQuery.getQuery = nodeQuery.init', () => {
|
||||
expect(nodeQuery.getQuery())
|
||||
.to.be.deep.equal(qb);
|
||||
});
|
||||
test('insertBatch throws error', () => {
|
||||
expect(() => {
|
||||
qb.driver.insertBatch('create_test', []);
|
||||
}).to.throw(Error, "Not Implemented");
|
||||
});
|
||||
});
|
||||
suiteTeardown(() => {
|
||||
qb.end();
|
||||
});
|
||||
});
|
@ -1,46 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
// Load the test base
|
||||
let reload = require('require-reload')(require);
|
||||
let expect = reload('chai').expect;
|
||||
let tests = reload('./adapterTestBase').tests;
|
||||
let testRunner = reload('./adapterTestBase').runner;
|
||||
|
||||
// Load the test config file
|
||||
let adapterName = 'node-firebird';
|
||||
let Firebird = reload(adapterName);
|
||||
let config = reload('../config.json')[adapterName];
|
||||
config.conn.database = __dirname + config.conn.database;
|
||||
let nodeQuery = reload('../../lib/NodeQuery');
|
||||
|
||||
// Skip on TravisCi
|
||||
if (process.env.CI || process.env.JENKINS_HOME)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
suite('Firebird adapter tests', () => {
|
||||
Firebird.attach(config.conn, (err, db) => {
|
||||
// Set up the query builder object
|
||||
let qb = nodeQuery.init('firebird', db, adapterName);
|
||||
|
||||
testRunner(tests, qb, (err, done) => {
|
||||
expect(err).is.not.ok;
|
||||
done();
|
||||
});
|
||||
suite('Adapter-specific tests', () => {
|
||||
test('nodeQuery.getQuery = nodeQuery.init', () => {
|
||||
expect(nodeQuery.getQuery())
|
||||
.to.be.deep.equal(qb);
|
||||
});
|
||||
test('insertBatch throws error', () => {
|
||||
expect(() => {
|
||||
qb.driver.insertBatch('create_test', []);
|
||||
}).to.throw(Error, "Not Implemented");
|
||||
});
|
||||
});
|
||||
suiteTeardown(() => {
|
||||
db.detach();
|
||||
});
|
||||
});
|
||||
});
|
@ -3,10 +3,12 @@
|
||||
let configFile = (process.env.CI) ? '../config-travis.json' : '../config.json';
|
||||
|
||||
// Load the test base
|
||||
let reload = require('require-reload')(require);
|
||||
let expect = reload('chai').expect;
|
||||
let tests = reload('./adapterTestBase').tests;
|
||||
let testRunner = reload('./adapterTestBase').runner;
|
||||
const reload = require('require-reload')(require);
|
||||
reload.emptyCache();
|
||||
const testBase = reload('../base');
|
||||
const expect = testBase.expect,
|
||||
promiseTestRunner = testBase.promiseTestRunner,
|
||||
testRunner = testBase.testRunner;
|
||||
|
||||
// Load the test config file
|
||||
let adapterName = 'pg';
|
||||
@ -25,40 +27,59 @@ connection.connect(err => {
|
||||
let nodeQuery = reload('../../lib/NodeQuery');
|
||||
let qb = nodeQuery.init('pg', connection);
|
||||
|
||||
suite('Pg adapter tests', () => {
|
||||
testRunner(tests, qb, (err, done) => {
|
||||
suite('Pg adapter tests -', () => {
|
||||
test('nodeQuery.getQuery = nodeQuery.init', () => {
|
||||
expect(nodeQuery.getQuery())
|
||||
.to.be.deep.equal(qb);
|
||||
});
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Callback Tests
|
||||
---------------------------------------------------------------------------*/
|
||||
testRunner(qb, (err, done) => {
|
||||
expect(err).is.not.ok;
|
||||
done();
|
||||
});
|
||||
suite('Adapter-specific tests', () => {
|
||||
test('nodeQuery.getQuery = nodeQuery.init', () => {
|
||||
expect(nodeQuery.getQuery())
|
||||
.to.be.deep.equal(qb);
|
||||
});
|
||||
test('Test Insert Batch', done => {
|
||||
let data = [
|
||||
{
|
||||
id: 544,
|
||||
key: 3,
|
||||
val: new Buffer('7'),
|
||||
}, {
|
||||
id: 89,
|
||||
key: 34,
|
||||
val: new Buffer('10 o\'clock'),
|
||||
}, {
|
||||
id: 48,
|
||||
key: 403,
|
||||
val: new Buffer('97'),
|
||||
},
|
||||
];
|
||||
|
||||
qb.insertBatch('create_test', data, (err, rows) => {
|
||||
test('Callback - Select with function and argument in WHERE clause', done => {
|
||||
qb.select('id')
|
||||
.from('create_test')
|
||||
.where('id', 'CEILING(SQRT(88))')
|
||||
.get((err, rows) => {
|
||||
expect(err).is.not.ok;
|
||||
return done();
|
||||
});
|
||||
});
|
||||
});
|
||||
suiteTeardown(() => {
|
||||
qb.end();
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Promise Tests
|
||||
---------------------------------------------------------------------------*/
|
||||
promiseTestRunner(qb);
|
||||
test('Promise - Select with function and argument in WHERE clause', () => {
|
||||
let promise = qb.select('id')
|
||||
.from('create_test')
|
||||
.where('id', 'CEILING(SQRT(88))')
|
||||
.get();
|
||||
|
||||
expect(promise).to.be.fulfilled;
|
||||
});
|
||||
test('Promise - Test Insert Batch', () => {
|
||||
let data = [
|
||||
{
|
||||
id: 544,
|
||||
key: 3,
|
||||
val: new Buffer('7'),
|
||||
}, {
|
||||
id: 89,
|
||||
key: 34,
|
||||
val: new Buffer('10 o\'clock'),
|
||||
}, {
|
||||
id: 48,
|
||||
key: 403,
|
||||
val: new Buffer('97'),
|
||||
},
|
||||
];
|
||||
|
||||
let promise = qb.insertBatch('create_test', data);
|
||||
return expect(promise).to.be.fulfilled;
|
||||
});
|
||||
});
|
13
test/base.js
Normal file
13
test/base.js
Normal file
@ -0,0 +1,13 @@
|
||||
'use strict';
|
||||
|
||||
const chai = require('chai');
|
||||
const chaiAsPromised = require('chai-as-promised');
|
||||
chai.use(chaiAsPromised);
|
||||
const expect = chai.expect;
|
||||
|
||||
module.exports = {
|
||||
expect: expect,
|
||||
tests: require('./base/tests'),
|
||||
testRunner: require('./base/adapterCallbackTestRunner'),
|
||||
promiseTestRunner: require('./base/adapterPromiseTestRunner'),
|
||||
};
|
236
test/base/adapterCallbackTestRunner.js
Normal file
236
test/base/adapterCallbackTestRunner.js
Normal file
@ -0,0 +1,236 @@
|
||||
'use strict';
|
||||
|
||||
// Load the test base
|
||||
const chai = require('chai');
|
||||
const chaiAsPromised = require('chai-as-promised');
|
||||
chai.use(chaiAsPromised);
|
||||
const expect = chai.expect;
|
||||
|
||||
const reload = require('require-reload')(require);
|
||||
let tests = reload('../base/tests');
|
||||
|
||||
let helpers = reload('../../lib/helpers'),
|
||||
State = reload('../../lib/State');
|
||||
|
||||
module.exports = function testRunner(qb, callback) {
|
||||
Object.keys(tests).forEach(suiteName => {
|
||||
suite(suiteName, () => {
|
||||
let currentSuite = tests[suiteName];
|
||||
Object.keys(currentSuite).forEach(testDesc => {
|
||||
test(`Callback - ${testDesc}`, done => {
|
||||
let methodObj = currentSuite[testDesc];
|
||||
let methodNames = Object.keys(methodObj);
|
||||
let lastMethodIndex = methodNames[methodNames.length - 1];
|
||||
|
||||
methodObj[lastMethodIndex].push((err, rows) => {
|
||||
callback(err, done);
|
||||
});
|
||||
|
||||
methodNames.forEach(name => {
|
||||
let args = methodObj[name],
|
||||
method = qb[name];
|
||||
|
||||
if (args[0] === 'multiple') {
|
||||
args.shift();
|
||||
args.forEach(argSet => {
|
||||
method.apply(qb, argSet);
|
||||
});
|
||||
|
||||
} else {
|
||||
method.apply(qb, args);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
suite('DB update tests -', () => {
|
||||
setup(done => {
|
||||
let sql = qb.driver.truncate('create_test');
|
||||
qb.adapter.execute(sql, (err, res) => {
|
||||
done();
|
||||
});
|
||||
});
|
||||
test('Callback - Test Insert', done => {
|
||||
qb.set('id', 98)
|
||||
.set('key', '84')
|
||||
.set('val', new Buffer('120'))
|
||||
.insert('create_test', (err, rows) => {
|
||||
return callback(err, done);
|
||||
});
|
||||
});
|
||||
test('Callback - Test Insert Object', done => {
|
||||
qb.insert('create_test', {
|
||||
id: 587,
|
||||
key: 1,
|
||||
val: new Buffer('2'),
|
||||
}, (err, rows) => {
|
||||
return callback(err, done);
|
||||
});
|
||||
});
|
||||
test('Callback - Test Update', done => {
|
||||
qb.where('id', 7)
|
||||
.update('create_test', {
|
||||
id: 7,
|
||||
key: 'gogle',
|
||||
val: new Buffer('non-word'),
|
||||
}, (err, rows) => {
|
||||
return callback(err, done);
|
||||
});
|
||||
});
|
||||
test('Callback - Test set Array Update', done => {
|
||||
let object = {
|
||||
id: 22,
|
||||
key: 'gogle',
|
||||
val: new Buffer('non-word'),
|
||||
};
|
||||
|
||||
qb.set(object)
|
||||
.where('id', 22)
|
||||
.update('create_test', (err, rows) => {
|
||||
return callback(err, done);
|
||||
});
|
||||
});
|
||||
test('Callback - Test where set update', done => {
|
||||
qb.where('id', 36)
|
||||
.set('id', 36)
|
||||
.set('key', 'gogle')
|
||||
.set('val', new Buffer('non-word'))
|
||||
.update('create_test', (err, rows) => {
|
||||
return callback(err, done);
|
||||
});
|
||||
});
|
||||
test('Callback - Test delete', done => {
|
||||
qb.delete('create_test', {id: 5}, (err, rows) => {
|
||||
return callback(err, done);
|
||||
});
|
||||
});
|
||||
test('Callback - Delete with where', done => {
|
||||
qb.where('id', 5)
|
||||
.delete('create_test', (err, rows) => {
|
||||
return callback(err, done);
|
||||
});
|
||||
});
|
||||
test('Callback - Delete multiple where values', done => {
|
||||
qb.delete('create_test', {
|
||||
id: 5,
|
||||
key: 'gogle',
|
||||
}, (err, rows) => {
|
||||
return callback(err, done);
|
||||
});
|
||||
});
|
||||
});
|
||||
suite('Grouping tests -', () => {
|
||||
test('Callback - Using grouping method', done => {
|
||||
qb.select('id, key as k, val')
|
||||
.from('create_test')
|
||||
.groupStart()
|
||||
.where('id >', 1)
|
||||
.where('id <', 900)
|
||||
.groupEnd()
|
||||
.limit(2, 1)
|
||||
.get((err, rows) => {
|
||||
return callback(err, done);
|
||||
});
|
||||
});
|
||||
test('Callback - Using where first grouping', done => {
|
||||
qb.select('id, key as k, val')
|
||||
.from('create_test')
|
||||
.where('id !=', 5)
|
||||
.groupStart()
|
||||
.where('id >', 1)
|
||||
.where('id <', 900)
|
||||
.groupEnd()
|
||||
.limit(2, 1)
|
||||
.get((err, rows) => {
|
||||
return callback(err, done);
|
||||
});
|
||||
});
|
||||
test('Callback - Using or grouping method', done => {
|
||||
qb.select('id, key as k, val')
|
||||
.from('create_test')
|
||||
.groupStart()
|
||||
.where('id >', 1)
|
||||
.where('id <', 900)
|
||||
.groupEnd()
|
||||
.orGroupStart()
|
||||
.where('id', 0)
|
||||
.groupEnd()
|
||||
.limit(2, 1)
|
||||
.get((err, rows) => {
|
||||
return callback(err, done);
|
||||
});
|
||||
});
|
||||
test('Callback - Using or not grouping method', done => {
|
||||
qb.select('id, key as k, val')
|
||||
.from('create_test')
|
||||
.groupStart()
|
||||
.where('id >', 1)
|
||||
.where('id <', 900)
|
||||
.groupEnd()
|
||||
.orNotGroupStart()
|
||||
.where('id', 0)
|
||||
.groupEnd()
|
||||
.limit(2, 1)
|
||||
.get((err, rows) => {
|
||||
return callback(err, done);
|
||||
});
|
||||
});
|
||||
});
|
||||
suite('Get compiled tests -', () => {
|
||||
test('select', () => {
|
||||
let sql = qb.select('id')
|
||||
.from('create_test')
|
||||
.getCompiledSelect(true);
|
||||
|
||||
expect(helpers.isString(sql)).to.be.true;
|
||||
});
|
||||
test('select from', () => {
|
||||
let sql = qb.select('id')
|
||||
.getCompiledSelect('create_test', true);
|
||||
|
||||
expect(helpers.isString(sql)).to.be.true;
|
||||
});
|
||||
test('insert', () => {
|
||||
let sql = qb.set('id', 3)
|
||||
.getCompiledInsert('create_test');
|
||||
|
||||
expect(helpers.isString(sql)).to.be.true;
|
||||
});
|
||||
test('update', () => {
|
||||
let sql = qb.set('id', 3)
|
||||
.where('id', 5)
|
||||
.getCompiledUpdate('create_test');
|
||||
|
||||
expect(helpers.isString(sql)).to.be.true;
|
||||
});
|
||||
test('delete', () => {
|
||||
let sql = qb.where('id', 5)
|
||||
.getCompiledDelete('create_test');
|
||||
|
||||
expect(helpers.isString(sql)).to.be.true;
|
||||
});
|
||||
});
|
||||
suite('Misc tests -', () => {
|
||||
test('Get State', () => {
|
||||
qb.select('foo')
|
||||
.from('bar')
|
||||
.where('baz', 'foobar');
|
||||
|
||||
let state = new State();
|
||||
|
||||
expect(JSON.stringify(state)).to.not.be.deep.equal(qb.getState());
|
||||
});
|
||||
test('Reset State', () => {
|
||||
qb.select('foo')
|
||||
.from('bar')
|
||||
.where('baz', 'foobar');
|
||||
|
||||
qb.resetQuery();
|
||||
|
||||
let state = new State();
|
||||
|
||||
expect(qb.getState()).to.be.deep.equal(state);
|
||||
});
|
||||
});
|
||||
};
|
181
test/base/adapterPromiseTestRunner.js
Normal file
181
test/base/adapterPromiseTestRunner.js
Normal file
@ -0,0 +1,181 @@
|
||||
'use strict';
|
||||
|
||||
// Load the test base
|
||||
const chai = require('chai');
|
||||
const chaiAsPromised = require('chai-as-promised');
|
||||
chai.use(chaiAsPromised);
|
||||
const expect = chai.expect;
|
||||
|
||||
const reload = require('require-reload')(require);
|
||||
let tests = reload('../base/tests');
|
||||
|
||||
let helpers = reload('../../lib/helpers'),
|
||||
State = reload('../../lib/State');
|
||||
|
||||
module.exports = function promiseTestRunner(qb) {
|
||||
Object.keys(tests).forEach(suiteName => {
|
||||
suite(suiteName, () => {
|
||||
let currentSuite = tests[suiteName];
|
||||
Object.keys(currentSuite).forEach(testDesc => {
|
||||
test(`Promise - ${testDesc}`, () => {
|
||||
let methodObj = currentSuite[testDesc];
|
||||
let methodNames = Object.keys(methodObj);
|
||||
let lastMethodIndex = methodNames[methodNames.length - 1];
|
||||
let results = [];
|
||||
|
||||
methodNames.forEach(name => {
|
||||
let args = methodObj[name],
|
||||
method = qb[name];
|
||||
|
||||
if (args[0] === 'multiple') {
|
||||
args.shift();
|
||||
args.forEach(argSet => {
|
||||
results.push(method.apply(qb, argSet));
|
||||
});
|
||||
|
||||
} else {
|
||||
results.push(method.apply(qb, args));
|
||||
}
|
||||
});
|
||||
|
||||
let promise = results.pop();
|
||||
expect(promise).to.be.fulfilled;
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
suite('DB update tests -', () => {
|
||||
suiteSetup(done => {
|
||||
let sql = qb.driver.truncate('create_test');
|
||||
qb.adapter.execute(sql).then(res => {
|
||||
return done();
|
||||
}).catch(err => {
|
||||
return done(err);
|
||||
});
|
||||
});
|
||||
test('Promise - Test Insert', () => {
|
||||
let promise = qb.set('id', 98)
|
||||
.set('key', '84')
|
||||
.set('val', new Buffer('120'))
|
||||
.insert('create_test');
|
||||
|
||||
expect(promise).to.be.fulfilled;
|
||||
});
|
||||
test('Promise - Test Insert Object', () => {
|
||||
let promise = qb.insert('create_test', {
|
||||
id: 587,
|
||||
key: 1,
|
||||
val: new Buffer('2'),
|
||||
});
|
||||
|
||||
expect(promise).to.be.fulfilled;
|
||||
});
|
||||
test('Promise - Test Update', () => {
|
||||
let promise = qb.where('id', 7)
|
||||
.update('create_test', {
|
||||
id: 7,
|
||||
key: 'gogle',
|
||||
val: new Buffer('non-word'),
|
||||
});
|
||||
|
||||
expect(promise).to.be.fulfilled;
|
||||
});
|
||||
test('Promise - Test set Array Update', () => {
|
||||
let object = {
|
||||
id: 22,
|
||||
key: 'gogle',
|
||||
val: new Buffer('non-word'),
|
||||
};
|
||||
|
||||
let promise = qb.set(object)
|
||||
.where('id', 22)
|
||||
.update('create_test');
|
||||
|
||||
expect(promise).to.be.fulfilled;
|
||||
});
|
||||
test('Promise - Test where set update', () => {
|
||||
let promise = qb.where('id', 36)
|
||||
.set('id', 36)
|
||||
.set('key', 'gogle')
|
||||
.set('val', new Buffer('non-word'))
|
||||
.update('create_test');
|
||||
|
||||
expect(promise).to.be.fulfilled;
|
||||
});
|
||||
test('Promise - Test delete', () => {
|
||||
let promise = qb.delete('create_test', {id: 5});
|
||||
expect(promise).to.be.fulfilled;
|
||||
});
|
||||
test('Promise - Delete with where', () => {
|
||||
let promise = qb.where('id', 5)
|
||||
.delete('create_test');
|
||||
|
||||
expect(promise).to.be.fulfilled;
|
||||
});
|
||||
test('Promise - Delete multiple where values', () => {
|
||||
let promise = qb.delete('create_test', {
|
||||
id: 5,
|
||||
key: 'gogle',
|
||||
});
|
||||
|
||||
expect(promise).to.be.fulfilled;
|
||||
});
|
||||
});
|
||||
suite('Grouping tests -', () => {
|
||||
test('Promise - Using grouping method', () => {
|
||||
let promise = qb.select('id, key as k, val')
|
||||
.from('create_test')
|
||||
.groupStart()
|
||||
.where('id >', 1)
|
||||
.where('id <', 900)
|
||||
.groupEnd()
|
||||
.limit(2, 1)
|
||||
.get();
|
||||
|
||||
expect(promise).to.be.fulfilled;
|
||||
});
|
||||
test('Promise - Using where first grouping', () => {
|
||||
let promise = 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();
|
||||
|
||||
expect(promise).to.be.fulfilled;
|
||||
});
|
||||
test('Promise - Using or grouping method', () => {
|
||||
let promise = 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();
|
||||
|
||||
expect(promise).to.be.fulfilled;
|
||||
});
|
||||
test('Promise - Using or not grouping method', () => {
|
||||
let promise = 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();
|
||||
|
||||
expect(promise).to.be.fulfilled;
|
||||
});
|
||||
});
|
||||
};
|
246
test/base/tests.js
Normal file
246
test/base/tests.js
Normal file
@ -0,0 +1,246 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
'Get tests -': {
|
||||
'Get with function': {
|
||||
select: ['id, COUNT(id) as count'],
|
||||
from: ['create_test'],
|
||||
groupBy: ['id'],
|
||||
get: [],
|
||||
},
|
||||
'Basic select all get': {
|
||||
get: ['create_test'],
|
||||
},
|
||||
'Basic select all with from': {
|
||||
from: ['create_test'],
|
||||
get: [],
|
||||
},
|
||||
'Get with limit': {
|
||||
get: ['create_test', 2],
|
||||
},
|
||||
'Get with limit and offset': {
|
||||
get: ['create_test', 2, 1],
|
||||
},
|
||||
'Get with having': {
|
||||
select: ['id'],
|
||||
from: ['create_test'],
|
||||
groupBy: ['id'],
|
||||
having: [
|
||||
'multiple',
|
||||
[{'id >': 1}],
|
||||
['id !=', 3],
|
||||
['id', 900],
|
||||
],
|
||||
get: [],
|
||||
},
|
||||
'Get with orHaving': {
|
||||
select: ['id'],
|
||||
from: ['create_test'],
|
||||
groupBy: ['id'],
|
||||
having: [{'id >': 1}],
|
||||
orHaving: ['id !=', 3],
|
||||
get: [],
|
||||
},
|
||||
},
|
||||
'Select tests -': {
|
||||
'Select where get': {
|
||||
select: [['id', 'key as k', 'val']],
|
||||
where: [
|
||||
'multiple',
|
||||
['id >', 1],
|
||||
['id <', 900],
|
||||
],
|
||||
get: ['create_test', 2, 1],
|
||||
},
|
||||
'Select where get 2': {
|
||||
select: ['id, key as k, val'],
|
||||
where: ['id !=', 1],
|
||||
get: ['create_test', 2, 1],
|
||||
},
|
||||
'Multi Order By': {
|
||||
from: ['create_test'],
|
||||
orderBy: ['id, key'],
|
||||
get: [],
|
||||
},
|
||||
'Select get': {
|
||||
select: ['id, key as k, val'],
|
||||
get: ['create_test', 2, 1],
|
||||
},
|
||||
'Select from get': {
|
||||
select: ['id, key as k, val'],
|
||||
from: ['create_test ct'],
|
||||
where: ['id >', 1],
|
||||
get: [],
|
||||
},
|
||||
'Select from limit get': {
|
||||
select: ['id, key as k, val'],
|
||||
from: ['create_test ct'],
|
||||
where: ['id >', 1],
|
||||
limit: [3],
|
||||
get: [],
|
||||
},
|
||||
'Select where IS NOT NULL': {
|
||||
select: ['id', 'key as k', 'val'],
|
||||
from: ['create_test ct'],
|
||||
whereIsNotNull: ['id'],
|
||||
get: [],
|
||||
},
|
||||
'Select where IS NULL': {
|
||||
select: ['id', 'key as k', 'val'],
|
||||
from: ['create_test ct'],
|
||||
whereIsNull: ['id'],
|
||||
get: [],
|
||||
},
|
||||
'Select where OR IS NOT NULL': {
|
||||
select: ['id', 'key as k', 'val'],
|
||||
from: ['create_test ct'],
|
||||
whereIsNull: ['id'],
|
||||
orWhereIsNotNull: ['id'],
|
||||
get: [],
|
||||
},
|
||||
'Select where OR IS NULL': {
|
||||
select: ['id', 'key as k', 'val'],
|
||||
from: ['create_test ct'],
|
||||
where: ['id', 3],
|
||||
orWhereIsNull: ['id'],
|
||||
get: [],
|
||||
},
|
||||
'Select with string where value': {
|
||||
select: ['id', 'key as k', 'val'],
|
||||
from: ['create_test ct'],
|
||||
where: ['id > 3'],
|
||||
get: [],
|
||||
},
|
||||
},
|
||||
'Where in tests -': {
|
||||
'Where in': {
|
||||
from: ['create_test'],
|
||||
whereIn: ['id', [0, 6, 56, 563, 341]],
|
||||
get: [],
|
||||
},
|
||||
'Or Where in': {
|
||||
from: ['create_test'],
|
||||
where: ['key', 'false'],
|
||||
orWhereIn: ['id', [0, 6, 56, 563, 341]],
|
||||
get: [],
|
||||
},
|
||||
'Where Not in': {
|
||||
from: ['create_test'],
|
||||
where: ['key', 'false'],
|
||||
whereNotIn: ['id', [0, 6, 56, 563, 341]],
|
||||
get: [],
|
||||
},
|
||||
'Or Where Not in': {
|
||||
from: ['create_test'],
|
||||
where: ['key', 'false'],
|
||||
orWhereNotIn: ['id', [0, 6, 56, 563, 341]],
|
||||
get: [],
|
||||
},
|
||||
},
|
||||
'Query modifier tests -': {
|
||||
'Order By': {
|
||||
select: ['id, key as k, val'],
|
||||
from: ['create_test'],
|
||||
where: [
|
||||
'multiple',
|
||||
['id >', 0],
|
||||
['id <', 9000],
|
||||
],
|
||||
orderBy: [
|
||||
'multiple',
|
||||
['id', 'DESC'],
|
||||
['k', 'ASC'],
|
||||
],
|
||||
limit: [5, 2],
|
||||
get: [],
|
||||
},
|
||||
'Group By': {
|
||||
select: ['id, key as k, val'],
|
||||
from: ['create_test'],
|
||||
where: [
|
||||
'multiple',
|
||||
['id >', 0],
|
||||
['id <', 9000],
|
||||
],
|
||||
groupBy: [
|
||||
'multiple',
|
||||
['k'],
|
||||
[['id', 'val']],
|
||||
],
|
||||
orderBy: [
|
||||
'multiple',
|
||||
['id', 'DESC'],
|
||||
['k', 'ASC'],
|
||||
],
|
||||
limit: [5, 2],
|
||||
get: [],
|
||||
},
|
||||
'Or Where': {
|
||||
select: ['id, key as k, val'],
|
||||
from: ['create_test'],
|
||||
where: [' id ', 1],
|
||||
orWhere: ['key > ', 0],
|
||||
limit: [2, 1],
|
||||
get: [],
|
||||
},
|
||||
Like: {
|
||||
from: ['create_test'],
|
||||
like: ['key', 'og'],
|
||||
get: [],
|
||||
},
|
||||
'Or Like': {
|
||||
from: ['create_test'],
|
||||
like: ['key', 'og'],
|
||||
orLike: ['key', 'val'],
|
||||
get: [],
|
||||
},
|
||||
'Not Like': {
|
||||
from: ['create_test'],
|
||||
like: ['key', 'og', 'before'],
|
||||
notLike: ['key', 'val'],
|
||||
get: [],
|
||||
},
|
||||
'Or Not Like': {
|
||||
from: ['create_test'],
|
||||
like: ['key', 'og', 'before'],
|
||||
orNotLike: ['key', 'val'],
|
||||
get: [],
|
||||
},
|
||||
'Like Before': {
|
||||
from: ['create_test'],
|
||||
like: ['key', 'og', 'before'],
|
||||
get: [],
|
||||
},
|
||||
'Like After': {
|
||||
from: ['create_test'],
|
||||
like: ['key', 'og', 'after'],
|
||||
get: [],
|
||||
},
|
||||
'Basic Join': {
|
||||
from: ['create_test ct'],
|
||||
join: ['create_join cj', 'cj.id=ct.id'],
|
||||
get: [],
|
||||
},
|
||||
'Left Join': {
|
||||
from: ['create_test ct'],
|
||||
join: ['create_join cj', 'cj.id=ct.id', 'left'],
|
||||
get: [],
|
||||
},
|
||||
'Inner Join': {
|
||||
from: ['create_test ct'],
|
||||
join: ['create_join cj', 'cj.id=ct.id', 'inner'],
|
||||
get: [],
|
||||
},
|
||||
'Join with multiple where values': {
|
||||
from: ['create_test ct'],
|
||||
join: ['create_join cj', 'cj.id=ct.id', 'inner'],
|
||||
where: [
|
||||
{
|
||||
'ct.id < ': 3,
|
||||
'ct.key ': 'foo',
|
||||
},
|
||||
],
|
||||
get: [],
|
||||
},
|
||||
},
|
||||
};
|
@ -6,7 +6,7 @@ let expect = require('chai').expect,
|
||||
nodeQuery = reload('../lib/NodeQuery'),
|
||||
Adapter = reload('../lib/Adapter');
|
||||
|
||||
suite('Base tests', () => {
|
||||
suite('Base tests -', () => {
|
||||
suite('Sanity check', () => {
|
||||
let files = glob.sync(`${__dirname}/../lib/**/*.js`);
|
||||
files.forEach(mod => {
|
||||
|
@ -7,8 +7,8 @@ let chai = require('chai'),
|
||||
|
||||
let helpers = require('../lib/helpers');
|
||||
|
||||
suite('Helper Module Tests', () => {
|
||||
suite('Type-checking methods', () => {
|
||||
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);
|
||||
@ -23,7 +23,7 @@ suite('Helper Module Tests', () => {
|
||||
expect(helpers.type(item)).to.deep.equal('string');
|
||||
});
|
||||
});
|
||||
suite('is..Method methods exist', () => {
|
||||
suite('is..Method methods exist -', () => {
|
||||
let types = [
|
||||
'Null',
|
||||
'Undefined',
|
||||
@ -44,7 +44,7 @@ suite('Helper Module Tests', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
suite('isScalar', () => {
|
||||
suite('isScalar -', () => {
|
||||
let trueCases = {
|
||||
'Strings are scalar': 'foo',
|
||||
'Booleans are scalar': true,
|
||||
@ -66,7 +66,7 @@ suite('Helper Module Tests', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
suite('isInfinity', () => {
|
||||
suite('isInfinity -', () => {
|
||||
test('The type of 1/0 is infinity', () => {
|
||||
expect(helpers.type(1 / 0)).to.equal('infinity');
|
||||
});
|
||||
@ -74,7 +74,7 @@ suite('Helper Module Tests', () => {
|
||||
expect(helpers.isInfinite(1 / 0)).to.be.true;
|
||||
});
|
||||
});
|
||||
suite('isNaN', () => {
|
||||
suite('isNaN -', () => {
|
||||
test('The type of 0 / 0 is NaN', () => {
|
||||
expect(helpers.type(0 / 0)).to.equal('nan');
|
||||
});
|
||||
@ -83,8 +83,8 @@ suite('Helper Module Tests', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
suite('Other helper methods', () => {
|
||||
suite('stringTrim', () => {
|
||||
suite('Other helper methods -', () => {
|
||||
suite('stringTrim -', () => {
|
||||
test('stringTrim method works as expected', () => {
|
||||
let orig = [' x y ', 'z ', ' q'];
|
||||
let ret = ['x y', 'z', 'q'];
|
||||
@ -92,7 +92,7 @@ suite('Helper Module Tests', () => {
|
||||
expect(orig.map(helpers.stringTrim)).to.be.deep.equal(ret);
|
||||
});
|
||||
});
|
||||
suite('arrayPluck', () => {
|
||||
suite('arrayPluck -', () => {
|
||||
let orig = [
|
||||
{
|
||||
foo: 1,
|
||||
@ -115,7 +115,7 @@ suite('Helper Module Tests', () => {
|
||||
expect(helpers.arrayPluck([], 'apple')).to.be.deep.equal([]);
|
||||
});
|
||||
});
|
||||
suite('regexInArray', () => {
|
||||
suite('regexInArray -', () => {
|
||||
let orig = ['apple', ' string ', 6, 4, 7];
|
||||
|
||||
let cases = [
|
||||
|
@ -1,7 +1,9 @@
|
||||
--ui tdd
|
||||
--bail
|
||||
--recursive
|
||||
--reporter dot
|
||||
--slow 100
|
||||
--timeout 5000
|
||||
--check-leaks
|
||||
--reporter list
|
||||
--slow 200
|
||||
--timeout 10000
|
||||
--check-leaks
|
||||
--growl
|
||||
test/**/*_test.js
|
@ -1,172 +1,172 @@
|
||||
'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/Driver');
|
||||
|
||||
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);
|
||||
});
|
||||
});
|
||||
});
|
||||
'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/Driver');
|
||||
|
||||
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);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue
Block a user