Add updateBatch method to query builder
This commit is contained in:
parent
a94038cd47
commit
4064a99419
68
.eslintrc
68
.eslintrc
@ -1,39 +1,43 @@
|
|||||||
{
|
{
|
||||||
"env": {
|
"env": {
|
||||||
"node": true,
|
"commonjs": true,
|
||||||
"es6": true
|
"es6": true,
|
||||||
|
"jest": true,
|
||||||
|
"node": true
|
||||||
},
|
},
|
||||||
|
"extends": ["eslint:recommended", "happiness"],
|
||||||
"rules": {
|
"rules": {
|
||||||
"arrow-parens": [2, "as-needed"],
|
"arrow-parens": ["error", "as-needed"],
|
||||||
"no-console": [1],
|
"callback-return": ["warn"],
|
||||||
"no-constant-condition": [1],
|
"constructor-super": ["error"],
|
||||||
"no-extra-semi": [1],
|
"curly" : ["error", "multi-line"],
|
||||||
"no-func-assign": [1],
|
"no-case-declarations": "off",
|
||||||
"no-obj-calls": [2],
|
"no-console": ["warn"],
|
||||||
"no-unexpected-multiline" : [2],
|
"no-constant-condition": ["warn"],
|
||||||
"no-unneeded-ternary": [2],
|
"no-dupe-args": ["error"],
|
||||||
"radix": [2],
|
"no-dupe-class-members": ["error"],
|
||||||
"no-with": [2],
|
"no-dupe-keys": ["error"],
|
||||||
"no-eval": [2],
|
"no-eval": ["error"],
|
||||||
"no-unreachable": [1],
|
"no-extra-semi": ["warn"],
|
||||||
"no-irregular-whitespace": [1],
|
"no-func-assign": ["warn"],
|
||||||
"no-new-wrappers": [2],
|
"no-implied-eval": ["error"],
|
||||||
"no-new-func": [2],
|
"no-invalid-this": ["error"],
|
||||||
"curly" : [2, "multi-line"],
|
"no-irregular-whitespace": ["warn"],
|
||||||
"no-implied-eval": [2],
|
"no-new-func": ["error"],
|
||||||
"no-invalid-this": [2],
|
"no-new-wrappers": ["error"],
|
||||||
"constructor-super": [2],
|
"no-obj-calls": ["error"],
|
||||||
"no-dupe-args": [2],
|
"no-this-before-super": ["error"],
|
||||||
"no-dupe-keys": [2],
|
"no-unexpected-multiline" : ["error"],
|
||||||
"no-dupe-class-members": [2],
|
"no-unneeded-ternary": ["error"],
|
||||||
"no-this-before-super": [2],
|
"no-unreachable": ["warn"],
|
||||||
"prefer-arrow-callback": [1],
|
"no-var": ["error"],
|
||||||
"no-var": [2],
|
"no-with": ["error"],
|
||||||
"valid-jsdoc": [1],
|
"object-shorthand": ["warn", "methods"],
|
||||||
"strict": [2, "global"],
|
"prefer-arrow-callback": ["warn"],
|
||||||
"callback-return": [1],
|
"prefer-template": ["warn"],
|
||||||
"object-shorthand": [1, "methods"],
|
"radix": ["error"],
|
||||||
"prefer-template": [1]
|
"strict": ["error", "global"],
|
||||||
|
"valid-jsdoc": ["warn"]
|
||||||
},
|
},
|
||||||
"parser": "babel-eslint"
|
"parser": "babel-eslint"
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
const array = require('locutus/php/array');
|
||||||
const Helpers = require('./Helpers');
|
const Helpers = require('./Helpers');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -64,36 +65,38 @@ const Driver = {
|
|||||||
* @return {String|Array} - Quoted identifier(s)
|
* @return {String|Array} - Quoted identifier(s)
|
||||||
*/
|
*/
|
||||||
quoteIdentifiers (str) {
|
quoteIdentifiers (str) {
|
||||||
let hiers, raw;
|
const pattern = new RegExp(
|
||||||
let pattern = new RegExp(
|
|
||||||
`${Driver.identifierStartChar}(` +
|
`${Driver.identifierStartChar}(` +
|
||||||
'([a-zA-Z0-9_]+)' + '(((.*?)))' +
|
'([a-zA-Z0-9_]+)' + '(((.*?)))' +
|
||||||
`)${Driver.identifierEndChar}`, 'ig');
|
`)${Driver.identifierEndChar}`, 'ig');
|
||||||
|
|
||||||
// Recurse for arrays of identifiiers
|
// Recurse for arrays of identifiers
|
||||||
if (Array.isArray(str)) {
|
if (Array.isArray(str)) {
|
||||||
return str.map(Driver.quoteIdentifiers);
|
return str.map(Driver.quoteIdentifiers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// cast to string so that you don't have undefined method errors with junk data
|
||||||
|
str = String(str);
|
||||||
|
|
||||||
// Handle commas
|
// Handle commas
|
||||||
if (str.includes(',')) {
|
if (str.includes(',')) {
|
||||||
let parts = str.split(',').map(Helpers.stringTrim);
|
const parts = str.split(',').map(Helpers.stringTrim);
|
||||||
str = parts.map(Driver.quoteIdentifiers).join(',');
|
str = parts.map(Driver.quoteIdentifiers).join(',');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Split identifiers by period
|
// Split identifiers by period
|
||||||
hiers = str.split('.').map(Driver._quote);
|
const hierarchies = str.split('.').map(Driver._quote);
|
||||||
raw = hiers.join('.');
|
let raw = hierarchies.join('.');
|
||||||
|
|
||||||
// Fix functions
|
// Fix functions
|
||||||
if (raw.includes('(') && raw.includes(')')) {
|
if (raw.includes('(') && raw.includes(')')) {
|
||||||
let funcs = pattern.exec(raw);
|
const functionCalls = pattern.exec(raw);
|
||||||
|
|
||||||
// Unquote the function
|
// Unquote the function
|
||||||
raw = raw.replace(funcs[0], funcs[1]);
|
raw = raw.replace(functionCalls[0], functionCalls[1]);
|
||||||
|
|
||||||
// Quote the identifiers inside of the parens
|
// Quote the identifiers inside of the parens
|
||||||
let inParens = funcs[3].substring(1, funcs[3].length - 1);
|
const inParens = functionCalls[3].substring(1, functionCalls[3].length - 1);
|
||||||
raw = raw.replace(inParens, Driver.quoteIdentifiers(inParens));
|
raw = raw.replace(inParens, Driver.quoteIdentifiers(inParens));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,7 +129,7 @@ const Driver = {
|
|||||||
* @return {String} - Query and data to insert
|
* @return {String} - Query and data to insert
|
||||||
*/
|
*/
|
||||||
insertBatch (table, data) {
|
insertBatch (table, data) {
|
||||||
const vals = [];
|
const values = [];
|
||||||
const fields = Object.keys(data[0]);
|
const fields = Object.keys(data[0]);
|
||||||
let sql = '';
|
let sql = '';
|
||||||
|
|
||||||
@ -134,7 +137,7 @@ const Driver = {
|
|||||||
// be parameterized
|
// be parameterized
|
||||||
data.forEach(obj => {
|
data.forEach(obj => {
|
||||||
Object.keys(obj).forEach(key => {
|
Object.keys(obj).forEach(key => {
|
||||||
vals.push(obj[key]);
|
values.push(obj[key]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -145,16 +148,79 @@ const Driver = {
|
|||||||
sql += `INSERT INTO ${table} (${Driver.quoteIdentifiers(fields).join(',')}) VALUES `;
|
sql += `INSERT INTO ${table} (${Driver.quoteIdentifiers(fields).join(',')}) VALUES `;
|
||||||
|
|
||||||
// Create placeholder groups
|
// Create placeholder groups
|
||||||
let params = Array(fields.length).fill('?');
|
const params = Array(fields.length).fill('?');
|
||||||
let paramString = `(${params.join(',')})`;
|
const paramString = `(${params.join(',')})`;
|
||||||
let paramList = Array(data.length).fill(paramString);
|
const paramList = Array(data.length).fill(paramString);
|
||||||
|
|
||||||
sql += paramList.join(',');
|
sql += paramList.join(',');
|
||||||
|
|
||||||
return {
|
return {
|
||||||
sql: sql,
|
sql: sql,
|
||||||
values: vals
|
values: values
|
||||||
};
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a batch update sql statement
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {String} table
|
||||||
|
* @param {Array<Object>} data
|
||||||
|
* @param {String} updateKey
|
||||||
|
* @return {Array<String,Object,Number>} array
|
||||||
|
*/
|
||||||
|
updateBatch (table, data, updateKey) {
|
||||||
|
let affectedRows = 0;
|
||||||
|
let insertData = [];
|
||||||
|
const fieldLines = [];
|
||||||
|
|
||||||
|
let sql = `UPDATE ${Driver.quoteTable(table)} SET `;
|
||||||
|
|
||||||
|
// get the keys of the current set of data, except the one used to
|
||||||
|
// set the update condition
|
||||||
|
const fields = data.reduce((previous, current) => {
|
||||||
|
affectedRows++;
|
||||||
|
const keys = Object.keys(current).filter(key => {
|
||||||
|
return key !== updateKey && !previous.includes(key);
|
||||||
|
});
|
||||||
|
return previous.concat(keys);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// Create the CASE blocks for each data set
|
||||||
|
fields.forEach(field => {
|
||||||
|
let line = `${Driver.quoteIdentifiers(field)} = CASE\n`;
|
||||||
|
const cases = [];
|
||||||
|
data.forEach(currentCase => {
|
||||||
|
insertData.push(currentCase[updateKey]);
|
||||||
|
insertData.push(currentCase[field]);
|
||||||
|
|
||||||
|
const newCase = `WHEN ${Driver.quoteIdentifiers(updateKey)} =? THEN ? `;
|
||||||
|
cases.push(newCase);
|
||||||
|
});
|
||||||
|
|
||||||
|
line += `${cases.join('\n')}\n`;
|
||||||
|
line += `ELSE ${Driver.quoteIdentifiers(field)} END`;
|
||||||
|
|
||||||
|
fieldLines.push(line);
|
||||||
|
});
|
||||||
|
|
||||||
|
sql += `${fieldLines.join(',\n')}\n`;
|
||||||
|
|
||||||
|
const whereValues = [];
|
||||||
|
data.forEach(entry => {
|
||||||
|
const insertValue = entry[updateKey];
|
||||||
|
whereValues.push(insertValue);
|
||||||
|
insertData.push(insertValue);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Create the placeholders for the WHERE IN clause
|
||||||
|
const placeholders = Array(whereValues.length);
|
||||||
|
placeholders.fill('?');
|
||||||
|
|
||||||
|
sql += `WHERE ${Driver.quoteIdentifiers(updateKey)} IN `;
|
||||||
|
sql += `( ${placeholders.join(',')} )`;
|
||||||
|
|
||||||
|
return [sql, insertData, affectedRows];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ class Helpers {
|
|||||||
* @return {String} - Type of the object
|
* @return {String} - Type of the object
|
||||||
*/
|
*/
|
||||||
static type (o) {
|
static type (o) {
|
||||||
let type = Object.prototype.toString.call(o).slice(8, -1).toLowerCase();
|
const type = Object.prototype.toString.call(o).slice(8, -1).toLowerCase();
|
||||||
|
|
||||||
// handle NaN and Infinity
|
// handle NaN and Infinity
|
||||||
if (type === 'number') {
|
if (type === 'number') {
|
||||||
@ -62,11 +62,10 @@ class Helpers {
|
|||||||
* Determine whether an object is scalar
|
* Determine whether an object is scalar
|
||||||
*
|
*
|
||||||
* @param {mixed} obj - Object to test
|
* @param {mixed} obj - Object to test
|
||||||
* @return {bool} - Is object scalar
|
* @return {boolean} - Is object scalar
|
||||||
*/
|
*/
|
||||||
static isScalar (obj) {
|
static isScalar (obj) {
|
||||||
let scalar = ['string', 'number', 'boolean'];
|
return ['string', 'number', 'boolean'].includes(Helpers.type(obj));
|
||||||
return scalar.indexOf(Helpers.type(obj)) !== -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -77,7 +76,7 @@ class Helpers {
|
|||||||
* @return {Array} - The new array of plucked values
|
* @return {Array} - The new array of plucked values
|
||||||
*/
|
*/
|
||||||
static arrayPluck (arr, key) {
|
static arrayPluck (arr, key) {
|
||||||
let output = [];
|
const output = [];
|
||||||
|
|
||||||
// Empty case
|
// Empty case
|
||||||
if (arr.length === 0) {
|
if (arr.length === 0) {
|
||||||
@ -119,20 +118,20 @@ class Helpers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make the first letter of the string uppercase
|
* Make the first constter of the string uppercase
|
||||||
*
|
*
|
||||||
* @param {String} str - The string to modify
|
* @param {String} str - The string to modify
|
||||||
* @return {String} - The modified string
|
* @return {String} - The modified string
|
||||||
*/
|
*/
|
||||||
static upperCaseFirst (str) {
|
static upperCaseFirst (str) {
|
||||||
str += '';
|
str += '';
|
||||||
let first = str.charAt(0).toUpperCase();
|
const first = str.charAt(0).toUpperCase();
|
||||||
return first + str.substr(1);
|
return first + str.substr(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Define an 'is' method for each type
|
// Define an 'is' method for each type
|
||||||
let types = [
|
const types = [
|
||||||
'Null',
|
'Null',
|
||||||
'Undefined',
|
'Undefined',
|
||||||
'Object',
|
'Object',
|
||||||
|
@ -50,17 +50,16 @@ class NodeQuery {
|
|||||||
this.instance = null;
|
this.instance = null;
|
||||||
|
|
||||||
if (config !== undefined) {
|
if (config !== undefined) {
|
||||||
let drivername = dbDriverMap.get(config.driver);
|
const driverName = dbDriverMap.get(config.driver);
|
||||||
|
|
||||||
if (!drivername) {
|
if (!driverName) {
|
||||||
throw new Error(`Selected driver (${config.driver}) does not exist!`);
|
throw new Error(`Selected driver (${config.driver}) does not exist!`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const driver = require(`./drivers/${drivername}`);
|
const driver = require(`./drivers/${driverName}`);
|
||||||
const Adapter = require(`./adapters/${drivername}`);
|
const Adapter = require(`./adapters/${driverName}`);
|
||||||
|
|
||||||
let adapter = Adapter(config);
|
this.instance = new QueryBuilder(driver, Adapter(config));
|
||||||
this.instance = new QueryBuilder(driver, adapter);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,7 +107,7 @@ class QueryBuilder extends QueryBuilderBase {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let safeArray = this.driver.quoteIdentifiers(fields);
|
const safeArray = this.driver.quoteIdentifiers(fields);
|
||||||
|
|
||||||
// Join the strings back together
|
// Join the strings back together
|
||||||
safeArray.forEach((field, index) => {
|
safeArray.forEach((field, index) => {
|
||||||
@ -378,8 +378,8 @@ class QueryBuilder extends QueryBuilderBase {
|
|||||||
table = table.join(' ');
|
table = table.join(' ');
|
||||||
|
|
||||||
// Parse out the join condition
|
// Parse out the join condition
|
||||||
let parsedCondition = this.parser.compileJoin(cond);
|
const parsedCondition = this.parser.compileJoin(cond);
|
||||||
let condition = `${table} ON ${parsedCondition}`;
|
const condition = `${table} ON ${parsedCondition}`;
|
||||||
|
|
||||||
// Append the join condition to the query map
|
// Append the join condition to the query map
|
||||||
this._appendMap(`\n${type.toUpperCase()} JOIN `, condition, 'join');
|
this._appendMap(`\n${type.toUpperCase()} JOIN `, condition, 'join');
|
||||||
@ -395,7 +395,7 @@ class QueryBuilder extends QueryBuilderBase {
|
|||||||
*/
|
*/
|
||||||
groupBy (field) {
|
groupBy (field) {
|
||||||
if (!Helpers.isScalar(field)) {
|
if (!Helpers.isScalar(field)) {
|
||||||
let newGroupArray = field.map(this.driver.quoteIdentifiers);
|
const newGroupArray = field.map(this.driver.quoteIdentifiers);
|
||||||
this.state.groupArray = this.state.groupArray.concat(newGroupArray);
|
this.state.groupArray = this.state.groupArray.concat(newGroupArray);
|
||||||
} else {
|
} else {
|
||||||
this.state.groupArray.push(this.driver.quoteIdentifiers(field));
|
this.state.groupArray.push(this.driver.quoteIdentifiers(field));
|
||||||
@ -421,7 +421,7 @@ class QueryBuilder extends QueryBuilderBase {
|
|||||||
|
|
||||||
this.state.orderArray[field] = type;
|
this.state.orderArray[field] = type;
|
||||||
|
|
||||||
let orderClauses = [];
|
const orderClauses = [];
|
||||||
|
|
||||||
// Flatten key/val pairs into an array of space-separated pairs
|
// Flatten key/val pairs into an array of space-separated pairs
|
||||||
Object.keys(this.state.orderArray).forEach(key => {
|
Object.keys(this.state.orderArray).forEach(key => {
|
||||||
@ -454,7 +454,7 @@ class QueryBuilder extends QueryBuilderBase {
|
|||||||
* @return {QueryBuilder} - The Query Builder object, for chaining
|
* @return {QueryBuilder} - The Query Builder object, for chaining
|
||||||
*/
|
*/
|
||||||
groupStart () {
|
groupStart () {
|
||||||
let conj = (this.state.queryMap.length < 1) ? ' WHERE ' : ' AND ';
|
const conj = (this.state.queryMap.length < 1) ? ' WHERE ' : ' AND ';
|
||||||
this._appendMap(conj, '(', 'groupStart');
|
this._appendMap(conj, '(', 'groupStart');
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
@ -549,7 +549,7 @@ class QueryBuilder extends QueryBuilderBase {
|
|||||||
* @return {Promise<Result>} - Promise containing the result of the query
|
* @return {Promise<Result>} - Promise containing the result of the query
|
||||||
*/
|
*/
|
||||||
insertBatch (table, data) {
|
insertBatch (table, data) {
|
||||||
let batch = this.driver.insertBatch(table, data);
|
const batch = this.driver.insertBatch(table, data);
|
||||||
|
|
||||||
// Run the query
|
// Run the query
|
||||||
return this.query(batch.sql, batch.values);
|
return this.query(batch.sql, batch.values);
|
||||||
@ -571,6 +571,20 @@ class QueryBuilder extends QueryBuilderBase {
|
|||||||
return this._run('update', this.driver.quoteTable(table));
|
return this._run('update', this.driver.quoteTable(table));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a batch update sql statement
|
||||||
|
*
|
||||||
|
* @param {String} table - The table to update
|
||||||
|
* @param {Object} data - Batch insert data
|
||||||
|
* @param {String} updateKey - The field in the table to compare against for updating
|
||||||
|
* @return {Number} Number of rows updated
|
||||||
|
*/
|
||||||
|
updateBatch (table, data, updateKey) {
|
||||||
|
const [sql, insertData, affectedRows] = this.driver.updateBatch(table, data, updateKey);
|
||||||
|
this._run('', table, sql, insertData);
|
||||||
|
return affectedRows;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run the generated delete query
|
* Run the generated delete query
|
||||||
*
|
*
|
||||||
@ -613,7 +627,7 @@ class QueryBuilder extends QueryBuilderBase {
|
|||||||
* @param {Boolean} [reset=true] - Whether to reset the query builder so another query can be built
|
* @param {Boolean} [reset=true] - Whether to reset the query builder so another query can be built
|
||||||
* @return {String} - The compiled sql statement
|
* @return {String} - The compiled sql statement
|
||||||
*/
|
*/
|
||||||
getCompiledInsert (table, reset) {
|
getCompiledInsert (table, reset = true) {
|
||||||
return this._getCompile('insert', this.driver.quoteTable(table), reset);
|
return this._getCompile('insert', this.driver.quoteTable(table), reset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -624,7 +638,7 @@ class QueryBuilder extends QueryBuilderBase {
|
|||||||
* @param {Boolean} [reset=true] - Whether to reset the query builder so another query can be built
|
* @param {Boolean} [reset=true] - Whether to reset the query builder so another query can be built
|
||||||
* @return {String} - The compiled sql statement
|
* @return {String} - The compiled sql statement
|
||||||
*/
|
*/
|
||||||
getCompiledUpdate (table, reset) {
|
getCompiledUpdate (table, reset = true) {
|
||||||
return this._getCompile('update', this.driver.quoteTable(table), reset);
|
return this._getCompile('update', this.driver.quoteTable(table), reset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -635,7 +649,7 @@ class QueryBuilder extends QueryBuilderBase {
|
|||||||
* @param {Boolean} [reset=true] - Whether to reset the query builder so another query can be built
|
* @param {Boolean} [reset=true] - Whether to reset the query builder so another query can be built
|
||||||
* @return {String} - The compiled sql statement
|
* @return {String} - The compiled sql statement
|
||||||
*/
|
*/
|
||||||
getCompiledDelete (table, reset) {
|
getCompiledDelete (table, reset = true) {
|
||||||
return this._getCompile('delete', this.driver.quoteTable(table), reset);
|
return this._getCompile('delete', this.driver.quoteTable(table), reset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,74 +16,6 @@ class QueryBuilderBase {
|
|||||||
this.state = new State();
|
this.state = new State();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Complete the sql building based on the type provided
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @param {String} type - Type of SQL query
|
|
||||||
* @param {String} table - The table to run the query on
|
|
||||||
* @return {String} - The compiled sql
|
|
||||||
*/
|
|
||||||
_compile (type, table) {
|
|
||||||
// Put together the basic query
|
|
||||||
let sql = this._compileType(type, table);
|
|
||||||
|
|
||||||
// Set each subClause
|
|
||||||
['queryMap', 'groupString', 'orderString', 'havingMap'].forEach(clause => {
|
|
||||||
let param = this.state[clause];
|
|
||||||
|
|
||||||
if (!Helpers.isScalar(param)) {
|
|
||||||
Object.keys(param).forEach(part => {
|
|
||||||
sql += param[part].conjunction + param[part].string;
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
sql += param;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Append the limit, if it exists
|
|
||||||
if (Helpers.isNumber(this.state.limit)) {
|
|
||||||
sql = this.driver.limit(sql, this.state.limit, this.state.offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
return sql;
|
|
||||||
}
|
|
||||||
|
|
||||||
_compileType (type, table) {
|
|
||||||
let sql = '';
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
case 'insert':
|
|
||||||
let params = Array(this.state.setArrayKeys.length).fill('?');
|
|
||||||
|
|
||||||
sql = `INSERT INTO ${table} (`;
|
|
||||||
sql += this.state.setArrayKeys.join(',');
|
|
||||||
sql += `) VALUES (${params.join(',')})`;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'update':
|
|
||||||
sql = `UPDATE ${table} SET ${this.state.setString}`;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'delete':
|
|
||||||
sql = `DELETE FROM ${table}`;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
sql = `SELECT * FROM ${this.state.fromString}`;
|
|
||||||
|
|
||||||
// Set the select string
|
|
||||||
if (this.state.selectString.length > 0) {
|
|
||||||
// Replace the star with the selected fields
|
|
||||||
sql = sql.replace('*', this.state.selectString);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return sql;
|
|
||||||
}
|
|
||||||
|
|
||||||
_like (field, val, pos, like, conj) {
|
_like (field, val, pos, like, conj) {
|
||||||
field = this.driver.quoteIdentifiers(field);
|
field = this.driver.quoteIdentifiers(field);
|
||||||
|
|
||||||
@ -147,7 +79,7 @@ class QueryBuilderBase {
|
|||||||
Object.keys(obj).forEach(k => {
|
Object.keys(obj).forEach(k => {
|
||||||
// If a single value for the return
|
// If a single value for the return
|
||||||
if (['key', 'value'].indexOf(valType) !== -1) {
|
if (['key', 'value'].indexOf(valType) !== -1) {
|
||||||
let pushVal = (valType === 'key') ? k : obj[k];
|
const pushVal = (valType === 'key') ? k : obj[k];
|
||||||
this.state[letName].push(pushVal);
|
this.state[letName].push(pushVal);
|
||||||
} else {
|
} else {
|
||||||
this.state[letName][k] = obj[k];
|
this.state[letName][k] = obj[k];
|
||||||
@ -166,8 +98,8 @@ class QueryBuilderBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_fixConjunction (conj) {
|
_fixConjunction (conj) {
|
||||||
let lastItem = this.state.queryMap[this.state.queryMap.length - 1];
|
const lastItem = this.state.queryMap[this.state.queryMap.length - 1];
|
||||||
let conjunctionList = Helpers.arrayPluck(this.state.queryMap, 'conjunction');
|
const conjunctionList = Helpers.arrayPluck(this.state.queryMap, 'conjunction');
|
||||||
|
|
||||||
if (this.state.queryMap.length === 0 || (!Helpers.regexInArray(conjunctionList, /^ ?WHERE/i))) {
|
if (this.state.queryMap.length === 0 || (!Helpers.regexInArray(conjunctionList, /^ ?WHERE/i))) {
|
||||||
conj = ' WHERE ';
|
conj = ' WHERE ';
|
||||||
@ -189,7 +121,7 @@ class QueryBuilderBase {
|
|||||||
this.state = this.parser.parseWhere(this.driver, this.state);
|
this.state = this.parser.parseWhere(this.driver, this.state);
|
||||||
|
|
||||||
this.state.whereMap.forEach(clause => {
|
this.state.whereMap.forEach(clause => {
|
||||||
let conj = this._fixConjunction(defaultConj);
|
const conj = this._fixConjunction(defaultConj);
|
||||||
this._appendMap(conj, clause, 'where');
|
this._appendMap(conj, clause, 'where');
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -198,7 +130,7 @@ class QueryBuilderBase {
|
|||||||
|
|
||||||
_whereNull (field, stmt, conj) {
|
_whereNull (field, stmt, conj) {
|
||||||
field = this.driver.quoteIdentifiers(field);
|
field = this.driver.quoteIdentifiers(field);
|
||||||
let item = `${field} ${stmt}`;
|
const item = `${field} ${stmt}`;
|
||||||
|
|
||||||
this._appendMap(this._fixConjunction(conj), item, 'whereNull');
|
this._appendMap(this._fixConjunction(conj), item, 'whereNull');
|
||||||
}
|
}
|
||||||
@ -225,7 +157,7 @@ class QueryBuilderBase {
|
|||||||
|
|
||||||
_whereIn (key, val, inClause, conj) {
|
_whereIn (key, val, inClause, conj) {
|
||||||
key = this.driver.quoteIdentifiers(key);
|
key = this.driver.quoteIdentifiers(key);
|
||||||
let params = Array(val.length);
|
const params = Array(val.length);
|
||||||
params.fill('?');
|
params.fill('?');
|
||||||
|
|
||||||
val.forEach(value => {
|
val.forEach(value => {
|
||||||
@ -233,7 +165,7 @@ class QueryBuilderBase {
|
|||||||
});
|
});
|
||||||
|
|
||||||
conj = (this.state.queryMap.length > 0) ? ` ${conj} ` : ' WHERE ';
|
conj = (this.state.queryMap.length > 0) ? ` ${conj} ` : ' WHERE ';
|
||||||
let str = `${key} ${inClause} (${params.join(',')}) `;
|
const str = `${key} ${inClause} (${params.join(',')}) `;
|
||||||
|
|
||||||
this._appendMap(conj, str, 'whereIn');
|
this._appendMap(conj, str, 'whereIn');
|
||||||
}
|
}
|
||||||
@ -257,7 +189,7 @@ class QueryBuilderBase {
|
|||||||
_getCompile (type, table, reset) {
|
_getCompile (type, table, reset) {
|
||||||
reset = reset || false;
|
reset = reset || false;
|
||||||
|
|
||||||
let sql = this._compile(type, table);
|
const sql = this._compile(type, table);
|
||||||
|
|
||||||
if (reset) {
|
if (reset) {
|
||||||
this._resetState();
|
this._resetState();
|
||||||
@ -266,6 +198,74 @@ class QueryBuilderBase {
|
|||||||
return sql;
|
return sql;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Complete the sql building based on the type provided
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {String} type - Type of SQL query
|
||||||
|
* @param {String} table - The table to run the query on
|
||||||
|
* @return {String} - The compiled sql
|
||||||
|
*/
|
||||||
|
_compile (type, table) {
|
||||||
|
// Put together the basic query
|
||||||
|
let sql = this._compileType(type, table);
|
||||||
|
|
||||||
|
// Set each subClause
|
||||||
|
['queryMap', 'groupString', 'orderString', 'havingMap'].forEach(clause => {
|
||||||
|
const param = this.state[clause];
|
||||||
|
|
||||||
|
if (!Helpers.isScalar(param)) {
|
||||||
|
Object.keys(param).forEach(part => {
|
||||||
|
sql += param[part].conjunction + param[part].string;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
sql += param;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Append the limit, if it exists
|
||||||
|
if (Helpers.isNumber(this.state.limit)) {
|
||||||
|
sql = this.driver.limit(sql, this.state.limit, this.state.offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
return sql;
|
||||||
|
}
|
||||||
|
|
||||||
|
_compileType (type, table) {
|
||||||
|
let sql = '';
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case 'insert':
|
||||||
|
const params = Array(this.state.setArrayKeys.length).fill('?');
|
||||||
|
|
||||||
|
sql = `INSERT INTO ${table} (`;
|
||||||
|
sql += this.state.setArrayKeys.join(',');
|
||||||
|
sql += `) VALUES (${params.join(',')})`;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'update':
|
||||||
|
sql = `UPDATE ${table} SET ${this.state.setString}`;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'delete':
|
||||||
|
sql = `DELETE FROM ${table}`;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
sql = `SELECT * FROM ${this.state.fromString}`;
|
||||||
|
|
||||||
|
// Set the select string
|
||||||
|
if (this.state.selectString.length > 0) {
|
||||||
|
// Replace the star with the selected fields
|
||||||
|
sql = sql.replace('*', this.state.selectString);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sql;
|
||||||
|
}
|
||||||
|
|
||||||
_resetState () {
|
_resetState () {
|
||||||
this.state = new State();
|
this.state = new State();
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,7 @@ class QueryParser {
|
|||||||
* @return {Array|null} - Filtered set of possible matches
|
* @return {Array|null} - Filtered set of possible matches
|
||||||
*/
|
*/
|
||||||
filterMatches (array) {
|
filterMatches (array) {
|
||||||
let output = [];
|
const output = [];
|
||||||
|
|
||||||
// Return non-array matches
|
// Return non-array matches
|
||||||
if (Helpers.isNull(array)) {
|
if (Helpers.isNull(array)) {
|
||||||
@ -85,8 +85,8 @@ class QueryParser {
|
|||||||
* @return {Object} - Join condition components
|
* @return {Object} - Join condition components
|
||||||
*/
|
*/
|
||||||
parseJoin (sql) {
|
parseJoin (sql) {
|
||||||
let matches = {};
|
const matches = {};
|
||||||
let output = {
|
const output = {
|
||||||
functions: [],
|
functions: [],
|
||||||
identifiers: [],
|
identifiers: [],
|
||||||
operators: [],
|
operators: [],
|
||||||
@ -117,7 +117,7 @@ class QueryParser {
|
|||||||
* @return {String} - The parsed/escaped join condition
|
* @return {String} - The parsed/escaped join condition
|
||||||
*/
|
*/
|
||||||
compileJoin (condition) {
|
compileJoin (condition) {
|
||||||
let parts = this.parseJoin(condition);
|
const parts = this.parseJoin(condition);
|
||||||
|
|
||||||
// Quote the identifiers
|
// Quote the identifiers
|
||||||
parts.combined.forEach((part, i) => {
|
parts.combined.forEach((part, i) => {
|
||||||
@ -137,11 +137,11 @@ class QueryParser {
|
|||||||
* @return {String} - The parsed/escaped where condition
|
* @return {String} - The parsed/escaped where condition
|
||||||
*/
|
*/
|
||||||
parseWhere (driver, state) {
|
parseWhere (driver, state) {
|
||||||
let whereMap = state.whereMap;
|
const whereMap = state.whereMap;
|
||||||
let whereValues = state.rawWhereValues;
|
let whereValues = state.rawWhereValues;
|
||||||
|
|
||||||
let outputMap = [];
|
const outputMap = [];
|
||||||
let outputValues = [];
|
const outputValues = [];
|
||||||
|
|
||||||
Object.keys(whereMap).forEach(key => {
|
Object.keys(whereMap).forEach(key => {
|
||||||
// Combine fields, operators, functions and values into a full clause
|
// Combine fields, operators, functions and values into a full clause
|
||||||
@ -158,16 +158,16 @@ class QueryParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Separate the clause into separate pieces
|
// Separate the clause into separate pieces
|
||||||
let parts = this.parseJoin(fullClause);
|
const parts = this.parseJoin(fullClause);
|
||||||
|
|
||||||
// Filter explicit literals from lists of matches
|
// Filter explicit literals from lists of matches
|
||||||
if (whereValues.indexOf(whereMap[key]) !== -1) {
|
if (whereValues.indexOf(whereMap[key]) !== -1) {
|
||||||
let value = whereMap[key];
|
const value = whereMap[key];
|
||||||
let identIndex = parts.identifiers.indexOf(value);
|
const identIndex = parts.identifiers.indexOf(value);
|
||||||
let litIndex = (Helpers.isArray(parts.literals)) ? parts.literals.indexOf(value) : -1;
|
const litIndex = (Helpers.isArray(parts.literals)) ? parts.literals.indexOf(value) : -1;
|
||||||
let combIndex = parts.combined.indexOf(value);
|
const combIndex = parts.combined.indexOf(value);
|
||||||
let funcIndex = (Helpers.isArray(parts.functions)) ? parts.functions.indexOf(value) : -1;
|
const funcIndex = (Helpers.isArray(parts.functions)) ? parts.functions.indexOf(value) : -1;
|
||||||
let inOutputArray = outputValues.indexOf(value) !== -1;
|
let inOutputArray = outputValues.includes(value);
|
||||||
|
|
||||||
// Remove the identifier in question,
|
// Remove the identifier in question,
|
||||||
// and add to the output values array
|
// and add to the output values array
|
||||||
@ -201,8 +201,8 @@ class QueryParser {
|
|||||||
|
|
||||||
// Filter false positive identifiers
|
// Filter false positive identifiers
|
||||||
parts.identifiers = parts.identifiers.filter(item => {
|
parts.identifiers = parts.identifiers.filter(item => {
|
||||||
let isInCombinedMatches = parts.combined.indexOf(item) !== -1;
|
const isInCombinedMatches = parts.combined.indexOf(item) !== -1;
|
||||||
let isNotInBlackList = this.identifierBlacklist.indexOf(item.toLowerCase()) === -1;
|
const isNotInBlackList = this.identifierBlacklist.indexOf(item.toLowerCase()) === -1;
|
||||||
|
|
||||||
return isInCombinedMatches && isNotInBlackList;
|
return isInCombinedMatches && isNotInBlackList;
|
||||||
}, this);
|
}, this);
|
||||||
@ -210,7 +210,7 @@ class QueryParser {
|
|||||||
// Quote identifiers
|
// Quote identifiers
|
||||||
if (Helpers.isArray(parts.identifiers)) {
|
if (Helpers.isArray(parts.identifiers)) {
|
||||||
parts.identifiers.forEach(ident => {
|
parts.identifiers.forEach(ident => {
|
||||||
let index = parts.combined.indexOf(ident);
|
const index = parts.combined.indexOf(ident);
|
||||||
if (index !== -1) {
|
if (index !== -1) {
|
||||||
parts.combined[index] = driver.quoteIdentifiers(ident);
|
parts.combined[index] = driver.quoteIdentifiers(ident);
|
||||||
}
|
}
|
||||||
@ -224,7 +224,7 @@ class QueryParser {
|
|||||||
// a where condition,
|
// a where condition,
|
||||||
if (Helpers.isArray(parts.literals)) {
|
if (Helpers.isArray(parts.literals)) {
|
||||||
parts.literals.forEach(lit => {
|
parts.literals.forEach(lit => {
|
||||||
let litIndex = parts.combined.indexOf(lit);
|
const litIndex = parts.combined.indexOf(lit);
|
||||||
|
|
||||||
if (litIndex !== -1) {
|
if (litIndex !== -1) {
|
||||||
parts.combined[litIndex] = '?';
|
parts.combined[litIndex] = '?';
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
module.exports = config => {
|
module.exports = config => {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -36,7 +36,7 @@ class Mysql extends Adapter {
|
|||||||
* Run the sql query as a prepared statement
|
* Run the sql query as a prepared statement
|
||||||
*
|
*
|
||||||
* @param {String} sql - The sql with placeholders
|
* @param {String} sql - The sql with placeholders
|
||||||
* @param {Array|undefined} params - The values to insert into the query
|
* @param {Array} params - The values to insert into the query
|
||||||
* @return {Promise} Result of query
|
* @return {Promise} Result of query
|
||||||
*/
|
*/
|
||||||
execute (sql, params) {
|
execute (sql, params) {
|
||||||
|
@ -7,28 +7,10 @@ const url = require('url');
|
|||||||
class Pg extends Adapter {
|
class Pg extends Adapter {
|
||||||
constructor (config) {
|
constructor (config) {
|
||||||
let instance = null;
|
let instance = null;
|
||||||
let connectionString = '';
|
let connectionString = Pg.formatConnectionString(config);
|
||||||
if (Helpers.isObject(config)) {
|
|
||||||
let host = config.host || 'localhost';
|
|
||||||
let user = config.user || 'postgres';
|
|
||||||
let password = `:${config.password}` || '';
|
|
||||||
let port = config.port || 5432;
|
|
||||||
|
|
||||||
let conn = {
|
|
||||||
protocol: 'postgres',
|
|
||||||
slashes: true,
|
|
||||||
host: `${host}:${port}`,
|
|
||||||
auth: `${user}${password}`,
|
|
||||||
pathname: config.database
|
|
||||||
};
|
|
||||||
|
|
||||||
connectionString = url.format(conn);
|
|
||||||
} else if (Helpers.isString(config)) {
|
|
||||||
connectionString = config;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (connectionString !== '') {
|
if (connectionString !== '') {
|
||||||
let conn = new pg.Client(connectionString);
|
const conn = new pg.Client(connectionString);
|
||||||
conn.connect(err => {
|
conn.connect(err => {
|
||||||
if (err) {
|
if (err) {
|
||||||
throw new Error(err);
|
throw new Error(err);
|
||||||
@ -41,6 +23,37 @@ class Pg extends Adapter {
|
|||||||
super(instance);
|
super(instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert the connection object to a connection string
|
||||||
|
*
|
||||||
|
* @param {Object} config - the configuration object
|
||||||
|
* @return {String} - the connection string
|
||||||
|
*/
|
||||||
|
static formatConnectionString (config) {
|
||||||
|
let connectionString = '';
|
||||||
|
|
||||||
|
if (Helpers.isObject(config)) {
|
||||||
|
const host = config.host || 'localhost';
|
||||||
|
const user = config.user || 'postgres';
|
||||||
|
const password = `:${config.password}` || '';
|
||||||
|
const port = config.port || 5432;
|
||||||
|
|
||||||
|
const conn = {
|
||||||
|
protocol: 'postgres',
|
||||||
|
slashes: true,
|
||||||
|
host: `${host}:${port}`,
|
||||||
|
auth: `${user}${password}`,
|
||||||
|
pathname: config.database
|
||||||
|
};
|
||||||
|
|
||||||
|
connectionString = url.format(conn);
|
||||||
|
} else if (Helpers.isString(config)) {
|
||||||
|
connectionString = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
return connectionString;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transform the adapter's result into a standard format
|
* Transform the adapter's result into a standard format
|
||||||
*
|
*
|
||||||
@ -52,9 +65,9 @@ class Pg extends Adapter {
|
|||||||
return new Result();
|
return new Result();
|
||||||
}
|
}
|
||||||
|
|
||||||
let cols = [];
|
const cols = [];
|
||||||
result.fields.forEach(field => {
|
result.fields.forEach(field => {
|
||||||
cols = field.name;
|
cols.push(field.name);
|
||||||
});
|
});
|
||||||
|
|
||||||
return new Result(result.rows, cols);
|
return new Result(result.rows, cols);
|
||||||
|
@ -1,25 +0,0 @@
|
|||||||
const Pg = require('./Pg');
|
|
||||||
const pg = require('pg').native;
|
|
||||||
|
|
||||||
class PgNative extends Pg {
|
|
||||||
constructor (config) {
|
|
||||||
super(config);
|
|
||||||
let instance = null;
|
|
||||||
let connectionString = Pg._formatConnectionString(config);
|
|
||||||
|
|
||||||
if (connectionString !== '') {
|
|
||||||
let conn = new pg.Client(connectionString);
|
|
||||||
conn.connect(err => {
|
|
||||||
if (err) {
|
|
||||||
throw new Error(err);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
instance = Promise.resolve(conn);
|
|
||||||
}
|
|
||||||
|
|
||||||
super.instance = instance;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = PgNative;
|
|
@ -1,8 +1,2 @@
|
|||||||
const Pg = require('./Pg');
|
const Pg = require('./Pg');
|
||||||
const PgNative = require('./PgNative');
|
module.exports = config => new Pg(config.connection);
|
||||||
|
|
||||||
module.exports = config => {
|
|
||||||
return (config.native)
|
|
||||||
? new PgNative(config.connection)
|
|
||||||
: new Pg(config.connection);
|
|
||||||
};
|
|
||||||
|
@ -5,10 +5,10 @@ const dbliteAdapter = require('dblite');
|
|||||||
|
|
||||||
class SqliteDblite extends Adapter {
|
class SqliteDblite extends Adapter {
|
||||||
constructor (config) {
|
constructor (config) {
|
||||||
let file = (Helpers.isString(config)) ? config : config.file;
|
const file = (Helpers.isString(config)) ? config : config.file;
|
||||||
|
|
||||||
const instance = new Promise((resolve, reject) => {
|
const instance = new Promise((resolve, reject) => {
|
||||||
let conn = dbliteAdapter(file);
|
const conn = dbliteAdapter(file);
|
||||||
|
|
||||||
// Stop the stupid 'bye bye' message being output
|
// Stop the stupid 'bye bye' message being output
|
||||||
conn.on('close', () => {});
|
conn.on('close', () => {});
|
||||||
|
@ -5,10 +5,10 @@ const sqlite3 = require('sqlite3').verbose();
|
|||||||
|
|
||||||
class SqliteSqlite3 extends Adapter {
|
class SqliteSqlite3 extends Adapter {
|
||||||
constructor (config) {
|
constructor (config) {
|
||||||
let file = (Helpers.isString(config)) ? config : config.file;
|
const file = (Helpers.isString(config)) ? config : config.file;
|
||||||
|
|
||||||
const instance = new Promise((resolve, reject) => {
|
const instance = new Promise((resolve, reject) => {
|
||||||
let conn = new sqlite3.Database(file, sqlite3.OPEN_READWRITE | sqlite3.OPEN_CREATE, err => {
|
const conn = new sqlite3.Database(file, sqlite3.OPEN_READWRITE | sqlite3.OPEN_CREATE, err => {
|
||||||
if (err) {
|
if (err) {
|
||||||
reject(err);
|
reject(err);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Driver for Microsoft SQL Server databases
|
* Driver for Microsoft SQL Server databases
|
||||||
*
|
*
|
||||||
@ -8,7 +6,6 @@
|
|||||||
module.exports = (() => {
|
module.exports = (() => {
|
||||||
delete require.cache[require.resolve('../Driver')];
|
delete require.cache[require.resolve('../Driver')];
|
||||||
const driver = require('../Driver');
|
const driver = require('../Driver');
|
||||||
const Helpers = require('../Helpers');
|
|
||||||
|
|
||||||
driver.identifierStartChar = '[';
|
driver.identifierStartChar = '[';
|
||||||
driver.identifierEndChar = ']';
|
driver.identifierEndChar = ']';
|
||||||
|
@ -5,7 +5,5 @@
|
|||||||
*/
|
*/
|
||||||
module.exports = (() => {
|
module.exports = (() => {
|
||||||
delete require.cache[require.resolve('../Driver')];
|
delete require.cache[require.resolve('../Driver')];
|
||||||
let driver = require('../Driver');
|
return require('../Driver');
|
||||||
|
|
||||||
return driver;
|
|
||||||
})();
|
})();
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
module.exports = (() => {
|
module.exports = (() => {
|
||||||
delete require.cache[require.resolve('../Driver')];
|
delete require.cache[require.resolve('../Driver')];
|
||||||
let driver = require('../Driver');
|
const driver = require('../Driver');
|
||||||
|
|
||||||
// Sqlite doesn't have a truncate command
|
// Sqlite doesn't have a truncate command
|
||||||
driver.hasTruncate = false;
|
driver.hasTruncate = false;
|
||||||
@ -22,11 +22,11 @@ module.exports = (() => {
|
|||||||
// Get the data values to insert, so they can
|
// Get the data values to insert, so they can
|
||||||
// be parameterized
|
// be parameterized
|
||||||
let sql = '';
|
let sql = '';
|
||||||
let first = data.shift();
|
const first = data.shift();
|
||||||
|
|
||||||
let vals = [];
|
const vals = [];
|
||||||
data.forEach(obj => {
|
data.forEach(obj => {
|
||||||
let row = [];
|
const row = [];
|
||||||
Object.keys(obj).forEach(key => {
|
Object.keys(obj).forEach(key => {
|
||||||
row.push(obj[key]);
|
row.push(obj[key]);
|
||||||
});
|
});
|
||||||
@ -37,8 +37,8 @@ module.exports = (() => {
|
|||||||
|
|
||||||
// Get the field names from the keys of the first
|
// Get the field names from the keys of the first
|
||||||
// object to be inserted
|
// object to be inserted
|
||||||
let fields = Object.keys(first);
|
const fields = Object.keys(first);
|
||||||
let cols = [];
|
const cols = [];
|
||||||
fields.forEach(key => {
|
fields.forEach(key => {
|
||||||
cols.push(`'${driver._quote(first[key])}' AS ${driver.quoteIdentifiers(key)}`);
|
cols.push(`'${driver._quote(first[key])}' AS ${driver.quoteIdentifiers(key)}`);
|
||||||
});
|
});
|
||||||
@ -46,7 +46,7 @@ module.exports = (() => {
|
|||||||
sql += `SELECT ${cols.join(', ')}\n`;
|
sql += `SELECT ${cols.join(', ')}\n`;
|
||||||
|
|
||||||
vals.forEach(rowValues => {
|
vals.forEach(rowValues => {
|
||||||
let quoted = rowValues.map(value => String(value).replace('\'', '\'\''));
|
const quoted = rowValues.map(value => String(value).replace('\'', '\'\''));
|
||||||
sql += `UNION ALL SELECT '${quoted.join('\', \'')}'\n`;
|
sql += `UNION ALL SELECT '${quoted.join('\', \'')}'\n`;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
30
package.json
30
package.json
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "ci-node-query",
|
"name": "ci-node-query",
|
||||||
"version": "6.0.0",
|
"version": "5.0.0",
|
||||||
"description": "A query builder for node based on the one in CodeIgniter",
|
"description": "A query builder for node based on the one in CodeIgniter",
|
||||||
"author": "Timothy J Warren <tim@timshomepage.net>",
|
"author": "Timothy J Warren <tim@timshomepage.net>",
|
||||||
"engines": {
|
"engines": {
|
||||||
@ -42,27 +42,31 @@
|
|||||||
"glob": "^7.0.3",
|
"glob": "^7.0.3",
|
||||||
"mysql2": "^1.2.0",
|
"mysql2": "^1.2.0",
|
||||||
"pg": "^7.4",
|
"pg": "^7.4",
|
||||||
"require-reload": "~0.2.2",
|
|
||||||
"sqlite3": "^3.1.8",
|
"sqlite3": "^3.1.8",
|
||||||
"tedious": "^2.0.0",
|
"tedious": "^2.0.0",
|
||||||
"xregexp": "^4.0.0"
|
"xregexp": "^4.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"babel-eslint": "^8.2.1",
|
"babel-eslint": "^8.2.1",
|
||||||
"chai": "^4.1",
|
|
||||||
"chai-as-promised": "^7.1",
|
|
||||||
"documentation": "latest",
|
"documentation": "latest",
|
||||||
"eslint": "^4.16.0",
|
"eslint": "^4.16.0",
|
||||||
|
"eslint-config-happiness": "^10.2.1",
|
||||||
|
"eslint-plugin-import": "^2.8.0",
|
||||||
|
"eslint-plugin-node": "^5.2.1",
|
||||||
|
"eslint-plugin-promise": "^3.6.0",
|
||||||
|
"eslint-plugin-standard": "^3.0.1",
|
||||||
"globstar": "^1.0.0",
|
"globstar": "^1.0.0",
|
||||||
"happiness": "^10.0",
|
|
||||||
"jest": "^22.0.0",
|
"jest": "^22.0.0",
|
||||||
"jsdoc": "^3.4.3",
|
"jsdoc": "^3.4.3",
|
||||||
"npm-run-all": "^4.0.2",
|
"npm-run-all": "^4.0.2",
|
||||||
"nsp": "^3.1",
|
"nsp": "^3.1",
|
||||||
"pg-native": "^2.2"
|
"require-reload": "~0.2.2"
|
||||||
},
|
},
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"jest": {
|
"jest": {
|
||||||
|
"collectCoverageFrom": [
|
||||||
|
"lib/**/*.js"
|
||||||
|
],
|
||||||
"coverageDirectory": "coverage",
|
"coverageDirectory": "coverage",
|
||||||
"coverageReporters": [
|
"coverageReporters": [
|
||||||
"html",
|
"html",
|
||||||
@ -82,21 +86,11 @@
|
|||||||
"default": "npm-run-all --parallel audit lint:src lint:tests && npm run test",
|
"default": "npm-run-all --parallel audit lint:src lint:tests && npm run test",
|
||||||
"predocs": "globstar -- documentation build -f md -o API.md \"lib/*.js\"",
|
"predocs": "globstar -- documentation build -f md -o API.md \"lib/*.js\"",
|
||||||
"docs": "globstar -- documentation build -f html -o docs \"lib/*.js\"",
|
"docs": "globstar -- documentation build -f html -o docs \"lib/*.js\"",
|
||||||
"fix": "happiness --fix \"lib/**/*.js\" \"test/**/*.js\"",
|
"fix": "eslint --fix ./lib ./test",
|
||||||
"postdocs": "jsdoc lib -r -d documentation",
|
"postdocs": "jsdoc lib -r -d documentation",
|
||||||
"happy": "happiness \"lib/**/*.js\" \"test/**/*.js\"",
|
"lint": "npm-run-all lint:src lint:tests",
|
||||||
"happy:src": "happiness \"lib/**/*.js\"",
|
|
||||||
"happy:tests": "happiness \"test/**/*.js\"",
|
|
||||||
"lint": "npm-run-all lint:tests lint:src happy",
|
|
||||||
"lint:src": "eslint ./lib",
|
"lint:src": "eslint ./lib",
|
||||||
"lint:tests": "eslint ./test",
|
"lint:tests": "eslint ./test",
|
||||||
"test": "jest"
|
"test": "jest"
|
||||||
},
|
|
||||||
"happiness": {
|
|
||||||
"env": {
|
|
||||||
"es6": true,
|
|
||||||
"jest": true
|
|
||||||
},
|
|
||||||
"parser": "babel-eslint"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
11
test/adapters/__snapshots__/dblite_test.js.snap
Normal file
11
test/adapters/__snapshots__/dblite_test.js.snap
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`Dblite adapter tests - Get compiled - getCompiledDelete 1`] = `"DELETE FROM \\"create_test\\" WHERE \\"id\\" = ?"`;
|
||||||
|
|
||||||
|
exports[`Dblite adapter tests - Get compiled - getCompiledInsert 1`] = `"INSERT INTO \\"create_test\\" (\\"id\\",\\"key\\",\\"val\\") VALUES (?,?,?)"`;
|
||||||
|
|
||||||
|
exports[`Dblite adapter tests - Get compiled - getCompiledSelect 1`] = `"SELECT \\"id\\", \\"key\\" AS \\"k\\", \\"val\\" FROM \\"create_test\\" WHERE (\\"id\\" > ? AND \\"id\\" < ?) LIMIT 2 OFFSET 1"`;
|
||||||
|
|
||||||
|
exports[`Dblite adapter tests - Get compiled - getCompiledSelect 2 1`] = `"SELECT \\"id\\", \\"key\\" AS \\"k\\", \\"val\\" FROM \\"create_test\\" WHERE (\\"id\\" > ? AND \\"id\\" < ?) LIMIT 2 OFFSET 1"`;
|
||||||
|
|
||||||
|
exports[`Dblite adapter tests - Get compiled - getCompiledUpdate 1`] = `"UPDATE \\"create_test\\" SET \\"id\\"=?,\\"key\\"=?,\\"val\\"=? WHERE \\"id\\" = ?"`;
|
11
test/adapters/__snapshots__/mysql2_test.js.snap
Normal file
11
test/adapters/__snapshots__/mysql2_test.js.snap
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`Mysql2 adapter tests - Get compiled - getCompiledDelete 1`] = `"DELETE FROM \`create_test\` WHERE \`id\` = ?"`;
|
||||||
|
|
||||||
|
exports[`Mysql2 adapter tests - Get compiled - getCompiledInsert 1`] = `"INSERT INTO \`create_test\` (\`id\`,\`key\`,\`val\`) VALUES (?,?,?)"`;
|
||||||
|
|
||||||
|
exports[`Mysql2 adapter tests - Get compiled - getCompiledSelect 1`] = `"SELECT \`id\`, \`key\` AS \`k\`, \`val\` FROM \`create_test\` WHERE (\`id\` > ? AND \`id\` < ?) LIMIT 1,2"`;
|
||||||
|
|
||||||
|
exports[`Mysql2 adapter tests - Get compiled - getCompiledSelect 2 1`] = `"SELECT \`id\`, \`key\` AS \`k\`, \`val\` FROM \`create_test\` WHERE (\`id\` > ? AND \`id\` < ?) LIMIT 1,2"`;
|
||||||
|
|
||||||
|
exports[`Mysql2 adapter tests - Get compiled - getCompiledUpdate 1`] = `"UPDATE \`create_test\` SET \`id\`=?,\`key\`=?,\`val\`=? WHERE \`id\` = ?"`;
|
11
test/adapters/__snapshots__/pg_test.js.snap
Normal file
11
test/adapters/__snapshots__/pg_test.js.snap
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`Pg adapter tests - Get compiled - getCompiledDelete 1`] = `"DELETE FROM \\"create_test\\" WHERE \\"id\\" = ?"`;
|
||||||
|
|
||||||
|
exports[`Pg adapter tests - Get compiled - getCompiledInsert 1`] = `"INSERT INTO \\"create_test\\" (\\"id\\",\\"key\\",\\"val\\") VALUES (?,?,?)"`;
|
||||||
|
|
||||||
|
exports[`Pg adapter tests - Get compiled - getCompiledSelect 1`] = `"SELECT \\"id\\", \\"key\\" AS \\"k\\", \\"val\\" FROM \\"create_test\\" WHERE (\\"id\\" > ? AND \\"id\\" < ?) LIMIT 2 OFFSET 1"`;
|
||||||
|
|
||||||
|
exports[`Pg adapter tests - Get compiled - getCompiledSelect 2 1`] = `"SELECT \\"id\\", \\"key\\" AS \\"k\\", \\"val\\" FROM \\"create_test\\" WHERE (\\"id\\" > ? AND \\"id\\" < ?) LIMIT 2 OFFSET 1"`;
|
||||||
|
|
||||||
|
exports[`Pg adapter tests - Get compiled - getCompiledUpdate 1`] = `"UPDATE \\"create_test\\" SET \\"id\\"=?,\\"key\\"=?,\\"val\\"=? WHERE \\"id\\" = ?"`;
|
11
test/adapters/__snapshots__/sqlite3_test.js.snap
Normal file
11
test/adapters/__snapshots__/sqlite3_test.js.snap
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`Sqlite3 adapter tests - Get compiled - getCompiledDelete 1`] = `"DELETE FROM \\"create_test\\" WHERE \\"id\\" = ?"`;
|
||||||
|
|
||||||
|
exports[`Sqlite3 adapter tests - Get compiled - getCompiledInsert 1`] = `"INSERT INTO \\"create_test\\" (\\"id\\",\\"key\\",\\"val\\") VALUES (?,?,?)"`;
|
||||||
|
|
||||||
|
exports[`Sqlite3 adapter tests - Get compiled - getCompiledSelect 1`] = `"SELECT \\"id\\", \\"key\\" AS \\"k\\", \\"val\\" FROM \\"create_test\\" WHERE (\\"id\\" > ? AND \\"id\\" < ?) LIMIT 2 OFFSET 1"`;
|
||||||
|
|
||||||
|
exports[`Sqlite3 adapter tests - Get compiled - getCompiledSelect 2 1`] = `"SELECT \\"id\\", \\"key\\" AS \\"k\\", \\"val\\" FROM \\"create_test\\" WHERE (\\"id\\" > ? AND \\"id\\" < ?) LIMIT 2 OFFSET 1"`;
|
||||||
|
|
||||||
|
exports[`Sqlite3 adapter tests - Get compiled - getCompiledUpdate 1`] = `"UPDATE \\"create_test\\" SET \\"id\\"=?,\\"key\\"=?,\\"val\\"=? WHERE \\"id\\" = ?"`;
|
@ -19,7 +19,7 @@ describe('Dblite adapter tests -', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testRunner(qb);
|
testRunner(qb);
|
||||||
it('Promise - Select with function and argument in WHERE clause', async () => {
|
it('Select with function and argument in WHERE clause', async () => {
|
||||||
let promise = await qb.select('id')
|
let promise = await qb.select('id')
|
||||||
.from('create_test')
|
.from('create_test')
|
||||||
.where('id', 'ABS(-88)')
|
.where('id', 'ABS(-88)')
|
||||||
@ -27,26 +27,6 @@ describe('Dblite adapter tests -', () => {
|
|||||||
|
|
||||||
expect(promise).toEqual(expect.anything());
|
expect(promise).toEqual(expect.anything());
|
||||||
});
|
});
|
||||||
it('Promise - Test Insert Batch', async () => {
|
|
||||||
let data = [
|
|
||||||
{
|
|
||||||
id: 544,
|
|
||||||
key: 3,
|
|
||||||
val: Buffer.from('7')
|
|
||||||
}, {
|
|
||||||
id: 89,
|
|
||||||
key: 34,
|
|
||||||
val: Buffer.from('10 o\'clock')
|
|
||||||
}, {
|
|
||||||
id: 48,
|
|
||||||
key: 403,
|
|
||||||
val: Buffer.from('97')
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
let promise = await qb.insertBatch('create_test', data);
|
|
||||||
expect(promise).toEqual(expect.anything());
|
|
||||||
});
|
|
||||||
afterAll(() => {
|
afterAll(() => {
|
||||||
qb.end();
|
qb.end();
|
||||||
});
|
});
|
||||||
|
@ -24,7 +24,7 @@ describe('Mysql2 adapter tests -', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testRunner(qb);
|
testRunner(qb);
|
||||||
it('Promise - Select with function and argument in WHERE clause', async () => {
|
it('Select with function and argument in WHERE clause', async () => {
|
||||||
let promise = await qb.select('id')
|
let promise = await qb.select('id')
|
||||||
.from('create_test')
|
.from('create_test')
|
||||||
.where('id', 'CEILING(SQRT(88))')
|
.where('id', 'CEILING(SQRT(88))')
|
||||||
@ -36,28 +36,7 @@ describe('Mysql2 adapter tests -', () => {
|
|||||||
let promise = await qb.truncate('create_test');
|
let promise = await qb.truncate('create_test');
|
||||||
expect(promise).toEqual(expect.anything());
|
expect(promise).toEqual(expect.anything());
|
||||||
});
|
});
|
||||||
it('Test Insert Batch', async () => {
|
afterAll(() => {
|
||||||
let data = [
|
|
||||||
{
|
|
||||||
id: 5442,
|
|
||||||
key: 4,
|
|
||||||
val: Buffer.from('7')
|
|
||||||
}, {
|
|
||||||
id: 892,
|
|
||||||
key: 35,
|
|
||||||
val: Buffer.from('10 o\'clock')
|
|
||||||
}, {
|
|
||||||
id: 482,
|
|
||||||
key: 404,
|
|
||||||
val: 97
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
const promise = await qb.insertBatch('create_test', data);
|
|
||||||
expect(promise).toEqual(expect.anything());
|
|
||||||
});
|
|
||||||
|
|
||||||
/* describeTeardown(() => {
|
|
||||||
qb.end();
|
qb.end();
|
||||||
}); */
|
});
|
||||||
});
|
});
|
||||||
|
@ -45,36 +45,16 @@ describe('Pg adapter tests -', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testRunner(qb);
|
testRunner(qb);
|
||||||
it('Promise - Select with function and argument in WHERE clause', async () => {
|
it('Select with function and argument in WHERE clause', async () => {
|
||||||
let promise = await qb.select('id')
|
const promise = await qb.select('id')
|
||||||
.from('create_test')
|
.from('create_test')
|
||||||
.where('id', 'CEILING(SQRT(88))')
|
.where('id', 'CEILING(SQRT(88))')
|
||||||
.get();
|
.get();
|
||||||
|
|
||||||
expect(promise).toEqual(expect.anything());
|
expect(promise).toEqual(expect.anything());
|
||||||
});
|
});
|
||||||
it('Promise - Test Truncate', async () => {
|
it('Test Truncate', async () => {
|
||||||
let promise = await qb.truncate('create_test');
|
const promise = await qb.truncate('create_test');
|
||||||
expect(promise).toEqual(expect.anything());
|
|
||||||
});
|
|
||||||
it('Promise - Test Insert Batch', async () => {
|
|
||||||
let data = [
|
|
||||||
{
|
|
||||||
id: 544,
|
|
||||||
key: 3,
|
|
||||||
val: Buffer.from('7')
|
|
||||||
}, {
|
|
||||||
id: 89,
|
|
||||||
key: 34,
|
|
||||||
val: Buffer.from('10 o\'clock')
|
|
||||||
}, {
|
|
||||||
id: 48,
|
|
||||||
key: 403,
|
|
||||||
val: Buffer.from('97')
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
let promise = await qb.insertBatch('create_test', data);
|
|
||||||
expect(promise).toEqual(expect.anything());
|
expect(promise).toEqual(expect.anything());
|
||||||
});
|
});
|
||||||
afterAll(() => {
|
afterAll(() => {
|
||||||
|
@ -20,7 +20,7 @@ describe('Sqlite3 adapter tests -', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testRunner(qb);
|
testRunner(qb);
|
||||||
it('Promise - Select with function and argument in WHERE clause', async () => {
|
it('Select with function and argument in WHERE clause', async () => {
|
||||||
let promise = await qb.select('id')
|
let promise = await qb.select('id')
|
||||||
.from('create_test')
|
.from('create_test')
|
||||||
.where('id', 'ABS(-88)')
|
.where('id', 'ABS(-88)')
|
||||||
@ -28,26 +28,6 @@ describe('Sqlite3 adapter tests -', () => {
|
|||||||
|
|
||||||
expect(promise).toEqual(expect.anything());
|
expect(promise).toEqual(expect.anything());
|
||||||
});
|
});
|
||||||
it('Promise - Test Insert Batch', async () => {
|
|
||||||
let data = [
|
|
||||||
{
|
|
||||||
id: 544,
|
|
||||||
key: 3,
|
|
||||||
val: Buffer.from('7')
|
|
||||||
}, {
|
|
||||||
id: 89,
|
|
||||||
key: 34,
|
|
||||||
val: Buffer.from('10 o\'clock')
|
|
||||||
}, {
|
|
||||||
id: 48,
|
|
||||||
key: 403,
|
|
||||||
val: Buffer.from('97')
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
let promise = await qb.insertBatch('create_test', data);
|
|
||||||
expect(promise).toEqual(expect.anything());
|
|
||||||
});
|
|
||||||
afterAll(() => {
|
afterAll(() => {
|
||||||
qb.end();
|
qb.end();
|
||||||
});
|
});
|
||||||
|
@ -1,13 +1,8 @@
|
|||||||
const chai = require('chai');
|
|
||||||
const chaiAsPromised = require('chai-as-promised');
|
|
||||||
chai.use(chaiAsPromised);
|
|
||||||
|
|
||||||
// Load the test config file
|
// Load the test config file
|
||||||
const configFile = './config.json';
|
const configFile = './config.json';
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
config: require(configFile),
|
config: require(configFile),
|
||||||
expect: chai.expect,
|
|
||||||
tests: require('./base/tests'),
|
tests: require('./base/tests'),
|
||||||
promiseTestRunner: require('./base/adapterPromiseTestRunner')
|
promiseTestRunner: require('./base/adapterPromiseTestRunner')
|
||||||
};
|
};
|
||||||
|
@ -37,13 +37,14 @@ module.exports = function promiseTestRunner (qb) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('DB update tests -', async () => {
|
|
||||||
|
describe('DB update tests -', () => {
|
||||||
beforeAll(done => {
|
beforeAll(done => {
|
||||||
let sql = qb.driver.truncate('create_test');
|
let sql = qb.driver.truncate('create_test');
|
||||||
qb.query(sql).then(res => done())
|
qb.query(sql).then(() => done())
|
||||||
.catch(err => done(err));
|
.catch(err => done(err));
|
||||||
});
|
});
|
||||||
it('Promise - Test Insert', async () => {
|
it('Test Insert', async () => {
|
||||||
const promise = await qb.set('id', 98)
|
const promise = await qb.set('id', 98)
|
||||||
.set('key', '84')
|
.set('key', '84')
|
||||||
.set('val', Buffer.from('120'))
|
.set('val', Buffer.from('120'))
|
||||||
@ -51,7 +52,7 @@ module.exports = function promiseTestRunner (qb) {
|
|||||||
|
|
||||||
expect(promise).toEqual(expect.anything());
|
expect(promise).toEqual(expect.anything());
|
||||||
});
|
});
|
||||||
it('Promise - Test Insert Object', async () => {
|
it('Test Insert Object', async () => {
|
||||||
const promise = await qb.insert('create_test', {
|
const promise = await qb.insert('create_test', {
|
||||||
id: 587,
|
id: 587,
|
||||||
key: 1,
|
key: 1,
|
||||||
@ -60,7 +61,7 @@ module.exports = function promiseTestRunner (qb) {
|
|||||||
|
|
||||||
expect(promise).toEqual(expect.anything());
|
expect(promise).toEqual(expect.anything());
|
||||||
});
|
});
|
||||||
it('Promise - Test Update', async () => {
|
it('Test Update', async () => {
|
||||||
const promise = await qb.where('id', 7)
|
const promise = await qb.where('id', 7)
|
||||||
.update('create_test', {
|
.update('create_test', {
|
||||||
id: 7,
|
id: 7,
|
||||||
@ -70,7 +71,7 @@ module.exports = function promiseTestRunner (qb) {
|
|||||||
|
|
||||||
expect(promise).toEqual(expect.anything());
|
expect(promise).toEqual(expect.anything());
|
||||||
});
|
});
|
||||||
it('Promise - Test set Array Update', async () => {
|
it('Test set Array Update', async () => {
|
||||||
let object = {
|
let object = {
|
||||||
id: 22,
|
id: 22,
|
||||||
key: 'gogle',
|
key: 'gogle',
|
||||||
@ -83,7 +84,7 @@ module.exports = function promiseTestRunner (qb) {
|
|||||||
|
|
||||||
expect(promise).toEqual(expect.anything());
|
expect(promise).toEqual(expect.anything());
|
||||||
});
|
});
|
||||||
it('Promise - Test where set update', async () => {
|
it('Test where set update', async () => {
|
||||||
const promise = await qb.where('id', 36)
|
const promise = await qb.where('id', 36)
|
||||||
.set('id', 36)
|
.set('id', 36)
|
||||||
.set('key', 'gogle')
|
.set('key', 'gogle')
|
||||||
@ -92,17 +93,17 @@ module.exports = function promiseTestRunner (qb) {
|
|||||||
|
|
||||||
expect(promise).toEqual(expect.anything());
|
expect(promise).toEqual(expect.anything());
|
||||||
});
|
});
|
||||||
it('Promise - Test delete', async () => {
|
it('Test delete', async () => {
|
||||||
const promise = await qb.delete('create_test', {id: 5});
|
const promise = await qb.delete('create_test', {id: 5});
|
||||||
expect(promise).toEqual(expect.anything());
|
expect(promise).toEqual(expect.anything());
|
||||||
});
|
});
|
||||||
it('Promise - Delete with where', async () => {
|
it('Delete with where', async () => {
|
||||||
const promise = await qb.where('id', 5)
|
const promise = await qb.where('id', 5)
|
||||||
.delete('create_test');
|
.delete('create_test');
|
||||||
|
|
||||||
expect(promise).toEqual(expect.anything());
|
expect(promise).toEqual(expect.anything());
|
||||||
});
|
});
|
||||||
it('Promise - Delete multiple where values', async () => {
|
it('Delete multiple where values', async () => {
|
||||||
const promise = await qb.delete('create_test', {
|
const promise = await qb.delete('create_test', {
|
||||||
id: 5,
|
id: 5,
|
||||||
key: 'gogle'
|
key: 'gogle'
|
||||||
@ -111,8 +112,46 @@ module.exports = function promiseTestRunner (qb) {
|
|||||||
expect(promise).toEqual(expect.anything());
|
expect(promise).toEqual(expect.anything());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('Grouping tests -', async () => {
|
|
||||||
it('Promise - Using grouping method', async () => {
|
describe('Batch tests -', () => {
|
||||||
|
it('Test Insert Batch', async () => {
|
||||||
|
const data = [
|
||||||
|
{
|
||||||
|
id: 544,
|
||||||
|
key: 3,
|
||||||
|
val: Buffer.from('7')
|
||||||
|
}, {
|
||||||
|
id: 89,
|
||||||
|
key: 34,
|
||||||
|
val: Buffer.from('10 o\'clock')
|
||||||
|
}, {
|
||||||
|
id: 48,
|
||||||
|
key: 403,
|
||||||
|
val: Buffer.from('97')
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
const promise = await qb.insertBatch('create_test', data);
|
||||||
|
expect(promise).toEqual(expect.anything());
|
||||||
|
});
|
||||||
|
it('Test Update Batch', async () => {
|
||||||
|
const data = [{
|
||||||
|
id: 480,
|
||||||
|
key: 49,
|
||||||
|
val: '7x7'
|
||||||
|
}, {
|
||||||
|
id: 890,
|
||||||
|
key: 100,
|
||||||
|
val: '10x10'
|
||||||
|
}];
|
||||||
|
|
||||||
|
const affectedRows = qb.updateBatch('create_test', data, 'id');
|
||||||
|
expect(affectedRows).toBe(2);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Grouping tests -', () => {
|
||||||
|
it('Using grouping method', async () => {
|
||||||
const promise = await qb.select('id, key as k, val')
|
const promise = await qb.select('id, key as k, val')
|
||||||
.from('create_test')
|
.from('create_test')
|
||||||
.groupStart()
|
.groupStart()
|
||||||
@ -124,7 +163,7 @@ module.exports = function promiseTestRunner (qb) {
|
|||||||
|
|
||||||
expect(promise).toEqual(expect.anything());
|
expect(promise).toEqual(expect.anything());
|
||||||
});
|
});
|
||||||
it('Promise - Using where first grouping', async () => {
|
it('Using where first grouping', async () => {
|
||||||
const promise = await qb.select('id, key as k, val')
|
const promise = await qb.select('id, key as k, val')
|
||||||
.from('create_test')
|
.from('create_test')
|
||||||
.where('id !=', 5)
|
.where('id !=', 5)
|
||||||
@ -137,7 +176,7 @@ module.exports = function promiseTestRunner (qb) {
|
|||||||
|
|
||||||
expect(promise).toEqual(expect.anything());
|
expect(promise).toEqual(expect.anything());
|
||||||
});
|
});
|
||||||
it('Promise - Using or grouping method', async () => {
|
it('Using or grouping method', async () => {
|
||||||
const promise = await qb.select('id, key as k, val')
|
const promise = await qb.select('id, key as k, val')
|
||||||
.from('create_test')
|
.from('create_test')
|
||||||
.groupStart()
|
.groupStart()
|
||||||
@ -152,7 +191,7 @@ module.exports = function promiseTestRunner (qb) {
|
|||||||
|
|
||||||
expect(promise).toEqual(expect.anything());
|
expect(promise).toEqual(expect.anything());
|
||||||
});
|
});
|
||||||
it('Promise - Using or not grouping method', async () => {
|
it('Using or not grouping method', async () => {
|
||||||
const promise = await qb.select('id, key as k, val')
|
const promise = await qb.select('id, key as k, val')
|
||||||
.from('create_test')
|
.from('create_test')
|
||||||
.groupStart()
|
.groupStart()
|
||||||
@ -168,4 +207,51 @@ module.exports = function promiseTestRunner (qb) {
|
|||||||
expect(promise).toEqual(expect.anything());
|
expect(promise).toEqual(expect.anything());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
describe('Get compiled - ', () => {
|
||||||
|
it('getCompiledSelect', () => {
|
||||||
|
const sql = qb.select('id, key as k, val')
|
||||||
|
.from('create_test')
|
||||||
|
.groupStart()
|
||||||
|
.where('id >', 1)
|
||||||
|
.where('id <', 900)
|
||||||
|
.groupEnd()
|
||||||
|
.limit(2, 1)
|
||||||
|
.getCompiledSelect();
|
||||||
|
|
||||||
|
expect(sql).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
it('getCompiledSelect 2', () => {
|
||||||
|
const sql = qb.select('id, key as k, val')
|
||||||
|
.groupStart()
|
||||||
|
.where('id >', 1)
|
||||||
|
.where('id <', 900)
|
||||||
|
.groupEnd()
|
||||||
|
.limit(2, 1)
|
||||||
|
.getCompiledSelect('create_test');
|
||||||
|
|
||||||
|
expect(sql).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
it('getCompiledInsert', () => {
|
||||||
|
const sql = qb.set({
|
||||||
|
id: 587,
|
||||||
|
key: 1,
|
||||||
|
val: Buffer.from('2')
|
||||||
|
}).getCompiledInsert('create_test');
|
||||||
|
|
||||||
|
expect(sql).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
it('getCompiledUpdate', () => {
|
||||||
|
const sql = qb.where('id', 36)
|
||||||
|
.set('id', 36)
|
||||||
|
.set('key', 'gogle')
|
||||||
|
.set('val', Buffer.from('non-word'))
|
||||||
|
.getCompiledUpdate('create_test');
|
||||||
|
|
||||||
|
expect(sql).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
it('getCompiledDelete', () => {
|
||||||
|
const sql = qb.where({id: 5}).getCompiledDelete('create_test');
|
||||||
|
expect(sql).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
@ -18,6 +18,18 @@
|
|||||||
"database": "test"
|
"database": "test"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"pg-native": {
|
||||||
|
"driver": "pg",
|
||||||
|
"native": true,
|
||||||
|
"connection": "postgres://test:test@posgres/test"
|
||||||
|
},
|
||||||
|
"pg-object-native": {
|
||||||
|
"driver": "pg",
|
||||||
|
"native": true,
|
||||||
|
"connection": {
|
||||||
|
"database": "test"
|
||||||
|
}
|
||||||
|
},
|
||||||
"dblite": {
|
"dblite": {
|
||||||
"adapter": "dblite",
|
"adapter": "dblite",
|
||||||
"driver": "sqlite",
|
"driver": "sqlite",
|
||||||
@ -26,14 +38,5 @@
|
|||||||
"sqlite3": {
|
"sqlite3": {
|
||||||
"driver": "sqlite",
|
"driver": "sqlite",
|
||||||
"connection": ":memory:"
|
"connection": ":memory:"
|
||||||
},
|
|
||||||
"node-firebird": {
|
|
||||||
"driver": "firebird",
|
|
||||||
"connection": {
|
|
||||||
"host": "127.0.0.1",
|
|
||||||
"database": "/../FB_TEST_DB.FDB",
|
|
||||||
"user": "SYSDBA",
|
|
||||||
"password": "masterkey"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user