From 988fb243898d746a759d422762685a79eddf99ca Mon Sep 17 00:00:00 2001 From: Igor Savin Date: Sun, 6 Oct 2019 20:21:32 +0200 Subject: [PATCH] Fix MSSQL escaping (#3382) --- CHANGELOG.md | 4 + lib/dialects/mssql/index.js | 6 +- lib/helpers.js | 2 +- lib/query/compiler.js | 6 +- lib/raw.js | 4 +- lib/transaction.js | 10 +- test/unit/dialects/mssql.js | 37 ++ test/unit/dialects/oracledb.js | 2 +- test/unit/dialects/postgres.js | 23 + test/unit/query/builder.js | 970 ++++++++++++++++----------------- test/unit/schema/mssql.js | 3 +- 11 files changed, 569 insertions(+), 498 deletions(-) create mode 100644 test/unit/dialects/mssql.js diff --git a/CHANGELOG.md b/CHANGELOG.md index ae1cd80f14..ccfce49441 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Master (Unreleased) +### Bug fixes: + +- MSSQL: Escape column ids correctly in all cases (reported by Snyk Security Research Team) + # 0.19.4 - 09 September, 2019 ### New features: diff --git a/lib/dialects/mssql/index.js b/lib/dialects/mssql/index.js index 59d2ec0cae..f1f898cfed 100644 --- a/lib/dialects/mssql/index.js +++ b/lib/dialects/mssql/index.js @@ -207,7 +207,11 @@ Object.assign(Client_MSSQL.prototype, { }, wrapIdentifierImpl(value) { - return value !== '*' ? `[${value.replace(/\[/g, '[')}]` : '*'; + if (value === '*') { + return '*'; + } + + return `[${value.replace(/[[\]']+/g, '')}]`; }, // Get a raw connection, called by the `pool` whenever a new diff --git a/lib/helpers.js b/lib/helpers.js index 83ea59e2bb..d0fcede79f 100644 --- a/lib/helpers.js +++ b/lib/helpers.js @@ -65,7 +65,7 @@ function getUndefinedIndices(mixed) { if (containsUndefined(mixed[key])) { indices.push(key); } - }) + }); } else { indices.push(0); } diff --git a/lib/query/compiler.js b/lib/query/compiler.js index 7a7620346e..f31de0af04 100644 --- a/lib/query/compiler.js +++ b/lib/query/compiler.js @@ -100,7 +100,9 @@ assign(QueryCompiler.prototype, { debugBindings(query.bindings); throw new Error( `Undefined binding(s) detected when compiling ` + - `${method.toUpperCase()}. Undefined column(s): [${this.undefinedBindingsInfo.join(', ')}] query: ${query.sql}` + `${method.toUpperCase()}. Undefined column(s): [${this.undefinedBindingsInfo.join( + ', ' + )}] query: ${query.sql}` ); } @@ -373,7 +375,7 @@ assign(QueryCompiler.prototype, { Object.prototype.hasOwnProperty.call(stmt, 'value') && helpers.containsUndefined(stmt.value) ) { - this.undefinedBindingsInfo.push(stmt.column) + this.undefinedBindingsInfo.push(stmt.column); this._undefinedInWhereClause = true; } const val = this[stmt.type](stmt); diff --git a/lib/raw.js b/lib/raw.js index 318060135e..1de0b9ed8a 100644 --- a/lib/raw.js +++ b/lib/raw.js @@ -104,7 +104,9 @@ assign(Raw.prototype, { obj.bindings = obj.bindings || []; if (helpers.containsUndefined(obj.bindings)) { - const undefinedBindingIndices = helpers.getUndefinedIndices(this.bindings); + const undefinedBindingIndices = helpers.getUndefinedIndices( + this.bindings + ); debugBindings(obj.bindings); throw new Error( `Undefined binding(s) detected for keys [${undefinedBindingIndices}] when compiling RAW query: ${obj.sql}` diff --git a/lib/transaction.js b/lib/transaction.js index a58970cf2d..62c77596c6 100644 --- a/lib/transaction.js +++ b/lib/transaction.js @@ -221,10 +221,12 @@ class Transaction extends EventEmitter { .then(function(connection) { connection.__knexTxId = txid; - return (trx._previousSibling ? trx._previousSibling.reflect() : Promise.resolve()) - .then(function () { - return connection; - }); + return (trx._previousSibling + ? trx._previousSibling.reflect() + : Promise.resolve() + ).then(function() { + return connection; + }); }) .disposer(function(connection) { if (!configConnection) { diff --git a/test/unit/dialects/mssql.js b/test/unit/dialects/mssql.js new file mode 100644 index 0000000000..86dd72456a --- /dev/null +++ b/test/unit/dialects/mssql.js @@ -0,0 +1,37 @@ +// global it, describe + +'use strict'; +const expect = require('chai').expect; +const knex = require('../../../knex'); + +describe('MSSQL unit tests', () => { + const knexInstance = knex({ + client: 'mssql', + connection: { + port: 1433, + host: '127.0.0.1', + password: 'yourStrong(!)Password', + user: 'sa', + }, + }); + + it('should escape statements with [] correctly', async () => { + const sql = knexInstance('projects') + .where('id] = 1 UNION SELECT 1, @@version -- --', 1) + .toSQL(); + console.log(sql); + expect(sql.sql).to.equal( + 'select * from [projects] where [id = 1 UNION SELECT 1, @@version -- --] = ?' + ); + }); + + it('should escape statements with "" correctly', async () => { + const sql = knexInstance('projects') + .where('id]" = 1 UNION SELECT 1, @@version -- --', 1) + .toSQL(); + console.log(sql); + expect(sql.sql).to.equal( + 'select * from [projects] where [id" = 1 UNION SELECT 1, @@version -- --] = ?' + ); + }); +}); diff --git a/test/unit/dialects/oracledb.js b/test/unit/dialects/oracledb.js index a7affe77d3..3819a24ca9 100644 --- a/test/unit/dialects/oracledb.js +++ b/test/unit/dialects/oracledb.js @@ -1,4 +1,4 @@ -// global it, describe, expect +// global it, describe 'use strict'; const _ = require('lodash'); diff --git a/test/unit/dialects/postgres.js b/test/unit/dialects/postgres.js index 56ced14c32..6c881e762d 100644 --- a/test/unit/dialects/postgres.js +++ b/test/unit/dialects/postgres.js @@ -51,6 +51,29 @@ describe('Postgres Unit Tests', function() { }); }); + it('escape statements correctly', async () => { + const knexInstance = knex({ + client: 'postgresql', + version: '10.5', + connection: { + pool: {}, + }, + }); + const sql = knexInstance('projects') + .where('id = 1 UNION SELECT 1, version();', 1) + .toSQL(); + expect(sql.sql).to.equal( + 'select * from "projects" where "id = 1 UNION SELECT 1, version();" = ?' + ); + + const sql2 = knexInstance('projects') + .where('id = 1" UNION SELECT 1, version();', 1) + .toSQL(); + expect(sql2.sql).to.equal( + 'select * from "projects" where "id = 1"" UNION SELECT 1, version();" = ?' + ); + }); + it('resolve client version if not specified explicitly', (done) => { const knexInstance = knex({ client: 'postgresql', diff --git a/test/unit/query/builder.js b/test/unit/query/builder.js index 2a5654c179..78a1b1a376 100644 --- a/test/unit/query/builder.js +++ b/test/unit/query/builder.js @@ -2,15 +2,15 @@ /*eslint no-var:0, indent:0, max-len:0 */ 'use strict'; -var MySQL_Client = require('../../../lib/dialects/mysql'); -var PG_Client = require('../../../lib/dialects/postgres'); -var Redshift_Client = require('../../../lib/dialects/redshift'); -var Oracledb_Client = require('../../../lib/dialects/oracledb'); -var SQLite3_Client = require('../../../lib/dialects/sqlite3'); -var MSSQL_Client = require('../../../lib/dialects/mssql'); +const MySQL_Client = require('../../../lib/dialects/mysql'); +const PG_Client = require('../../../lib/dialects/postgres'); +const Redshift_Client = require('../../../lib/dialects/redshift'); +const Oracledb_Client = require('../../../lib/dialects/oracledb'); +const SQLite3_Client = require('../../../lib/dialects/sqlite3'); +const MSSQL_Client = require('../../../lib/dialects/mssql'); // use driverName as key -var clients = { +const clients = { mysql: new MySQL_Client({ client: 'mysql' }), pg: new PG_Client({ client: 'pg' }), 'pg-redshift': new Redshift_Client({ client: 'redshift' }), @@ -19,9 +19,9 @@ var clients = { mssql: new MSSQL_Client({ client: 'mssql' }), }; -var useNullAsDefaultConfig = { useNullAsDefault: true }; +const useNullAsDefaultConfig = { useNullAsDefault: true }; // use driverName as key -var clientsWithNullAsDefault = { +const clientsWithNullAsDefault = { mysql: new MySQL_Client( Object.assign({ client: 'mysql' }, useNullAsDefaultConfig) ), @@ -55,7 +55,7 @@ function ref(ref) { } function verifySqlResult(dialect, expectedObj, sqlObj) { - Object.keys(expectedObj).forEach(function(key) { + Object.keys(expectedObj).forEach((key) => { if (typeof expectedObj[key] === 'function') { expectedObj[key](sqlObj[key]); } else { @@ -71,12 +71,12 @@ function verifySqlResult(dialect, expectedObj, sqlObj) { function testsql(chain, valuesToCheck, selectedClients) { selectedClients = selectedClients || clients; - Object.keys(valuesToCheck).forEach(function(key) { - var newChain = chain.clone(); + Object.keys(valuesToCheck).forEach((key) => { + const newChain = chain.clone(); newChain.client = selectedClients[key]; - var sqlAndBindings = newChain.toSQL(); + const sqlAndBindings = newChain.toSQL(); - var checkValue = valuesToCheck[key]; + const checkValue = valuesToCheck[key]; if (typeof checkValue === 'string') { verifySqlResult(key, { sql: checkValue }, sqlAndBindings); } else { @@ -87,30 +87,30 @@ function testsql(chain, valuesToCheck, selectedClients) { function testNativeSql(chain, valuesToCheck, selectedClients) { selectedClients = selectedClients || clients; - Object.keys(valuesToCheck).forEach(function(key) { - var newChain = chain.clone(); + Object.keys(valuesToCheck).forEach((key) => { + const newChain = chain.clone(); newChain.client = selectedClients[key]; - var sqlAndBindings = newChain.toSQL().toNative(); - var checkValue = valuesToCheck[key]; + const sqlAndBindings = newChain.toSQL().toNative(); + const checkValue = valuesToCheck[key]; verifySqlResult(key, checkValue, sqlAndBindings); }); } function testquery(chain, valuesToCheck, selectedClients) { selectedClients = selectedClients || clients; - Object.keys(valuesToCheck).forEach(function(key) { - var newChain = chain.clone(); + Object.keys(valuesToCheck).forEach((key) => { + const newChain = chain.clone(); newChain.client = selectedClients[key]; - var sqlString = newChain.toQuery(); - var checkValue = valuesToCheck[key]; + const sqlString = newChain.toQuery(); + const checkValue = valuesToCheck[key]; expect(checkValue).to.equal(sqlString); }); } -describe('Custom identifier wrapping', function() { - var customWrapperConfig = { +describe('Custom identifier wrapping', () => { + const customWrapperConfig = { wrapIdentifier: (value, clientImpl, context) => { - var suffix = '_wrapper_was_here'; + let suffix = '_wrapper_was_here'; if (context && context.fancy) { suffix = '_fancy_wrapper_was_here'; } @@ -119,7 +119,7 @@ describe('Custom identifier wrapping', function() { }; // use driverName as key - var clientsWithCustomIdentifierWrapper = { + const clientsWithCustomIdentifierWrapper = { mysql: new MySQL_Client( Object.assign({ client: 'mysql' }, customWrapperConfig) ), @@ -162,7 +162,7 @@ describe('Custom identifier wrapping', function() { ); }); - it('should use custom wrapper on multiple inserts with returning', function() { + it('should use custom wrapper on multiple inserts with returning', () => { // returning only supported directly by postgres and with workaround with oracle // other databases implicitly return the inserted id testsql( @@ -200,7 +200,7 @@ describe('Custom identifier wrapping', function() { oracledb: { sql: 'begin execute immediate \'insert into "users_wrapper_was_here" ("email_wrapper_was_here", "name_wrapper_was_here") values (:1, :2) returning "id_wrapper_was_here" into :3\' using ?, ?, out ?; execute immediate \'insert into "users_wrapper_was_here" ("email_wrapper_was_here", "name_wrapper_was_here") values (:1, :2) returning "id_wrapper_was_here" into :3\' using ?, ?, out ?;end;', - bindings: function(bindings) { + bindings: (bindings) => { expect(bindings.length).to.equal(6); expect(bindings[0]).to.equal('foo'); expect(bindings[1]).to.equal('taylor'); @@ -219,7 +219,7 @@ describe('Custom identifier wrapping', function() { ); }); - it('should use custom wrapper on multiple inserts with multiple returning', function() { + it('should use custom wrapper on multiple inserts with multiple returning', () => { testsql( qb() .from('users') @@ -256,7 +256,7 @@ describe('Custom identifier wrapping', function() { oracledb: { sql: 'begin execute immediate \'insert into "users_wrapper_was_here" ("email_wrapper_was_here", "name_wrapper_was_here") values (:1, :2) returning "id_wrapper_was_here","name_wrapper_was_here" into :3, :4\' using ?, ?, out ?, out ?; execute immediate \'insert into "users_wrapper_was_here" ("email_wrapper_was_here", "name_wrapper_was_here") values (:1, :2) returning "id_wrapper_was_here","name_wrapper_was_here" into :3, :4\' using ?, ?, out ?, out ?;end;', - bindings: function(bindings) { + bindings: (bindings) => { expect(bindings.length).to.equal(8); expect(bindings[0]).to.equal('foo'); expect(bindings[1]).to.equal('taylor'); @@ -328,7 +328,7 @@ describe('Custom identifier wrapping', function() { }); it('should allow chaining', () => { - var builder = qb(); + const builder = qb(); expect(builder.queryContext({ foo: 'foo' })).to.deep.equal(builder); }); @@ -351,15 +351,15 @@ describe('Custom identifier wrapping', function() { }); it('should not modify the original query context if the clone is modified', () => { - var original = qb().queryContext({ foo: 'foo' }); - var clone = original.clone().queryContext({ foo: 'bar' }); + const original = qb().queryContext({ foo: 'foo' }); + const clone = original.clone().queryContext({ foo: 'bar' }); expect(original.queryContext()).to.deep.equal({ foo: 'foo' }); expect(clone.queryContext()).to.deep.equal({ foo: 'bar' }); }); it('should only shallow clone the query context', () => { - var original = qb().queryContext({ foo: { bar: 'baz' } }); - var clone = original.clone(); + const original = qb().queryContext({ foo: { bar: 'baz' } }); + const clone = original.clone(); clone.queryContext().foo.bar = 'quux'; expect(original.queryContext()).to.deep.equal({ foo: { bar: 'quux' } }); expect(clone.queryContext()).to.deep.equal({ foo: { bar: 'quux' } }); @@ -368,8 +368,8 @@ describe('Custom identifier wrapping', function() { }); }); -describe('QueryBuilder', function() { - it('basic select', function() { +describe('QueryBuilder', () => { + it('basic select', () => { testsql( qb() .select('*') @@ -383,7 +383,7 @@ describe('QueryBuilder', function() { ); }); - it('adding selects', function() { + it('adding selects', () => { testsql( qb() .select('foo') @@ -399,7 +399,7 @@ describe('QueryBuilder', function() { ); }); - it('basic select distinct', function() { + it('basic select distinct', () => { testsql( qb() .distinct() @@ -422,7 +422,7 @@ describe('QueryBuilder', function() { ); }); - it('basic select with alias as property-value pairs', function() { + it('basic select with alias as property-value pairs', () => { testsql( qb() .select({ bar: 'foo' }) @@ -436,7 +436,7 @@ describe('QueryBuilder', function() { ); }); - it('basic select with mixed pure column and alias pair', function() { + it('basic select with mixed pure column and alias pair', () => { testsql( qb() .select('baz', { bar: 'foo' }) @@ -450,7 +450,7 @@ describe('QueryBuilder', function() { ); }); - it('basic select with array-wrapped alias pair', function() { + it('basic select with array-wrapped alias pair', () => { testsql( qb() .select(['baz', { bar: 'foo' }]) @@ -464,7 +464,7 @@ describe('QueryBuilder', function() { ); }); - it('basic select with mixed pure column and alias pair', function() { + it('basic select with mixed pure column and alias pair', () => { testsql( qb() .select({ bar: 'foo' }) @@ -478,7 +478,7 @@ describe('QueryBuilder', function() { ); }); - it('basic old-style alias', function() { + it('basic old-style alias', () => { testsql( qb() .select('foo as bar') @@ -493,7 +493,7 @@ describe('QueryBuilder', function() { ); }); - it('basic alias trims spaces', function() { + it('basic alias trims spaces', () => { testsql( qb() .select(' foo as bar ') @@ -508,7 +508,7 @@ describe('QueryBuilder', function() { ); }); - it('allows for case-insensitive alias', function() { + it('allows for case-insensitive alias', () => { testsql( qb() .select(' foo aS bar ') @@ -523,7 +523,7 @@ describe('QueryBuilder', function() { ); }); - it('allows alias with dots in the identifier name', function() { + it('allows alias with dots in the identifier name', () => { testsql( qb() .select('foo as bar.baz') @@ -569,7 +569,7 @@ describe('QueryBuilder', function() { ); }); - it('basic table wrapping', function() { + it('basic table wrapping', () => { testsql( qb() .select('*') @@ -583,7 +583,7 @@ describe('QueryBuilder', function() { ); }); - it('basic table wrapping with declared schema', function() { + it('basic table wrapping with declared schema', () => { testsql( qb() .withSchema('myschema') @@ -598,7 +598,7 @@ describe('QueryBuilder', function() { ); }); - it('selects from only', function() { + it('selects from only', () => { testsql( qb() .select('*') @@ -609,7 +609,7 @@ describe('QueryBuilder', function() { ); }); - it('clear a select', function() { + it('clear a select', () => { testsql( qb() .select('id', 'email') @@ -654,7 +654,7 @@ describe('QueryBuilder', function() { ); }); - it('clear a where', function() { + it('clear a where', () => { testsql( qb() .select('id') @@ -705,7 +705,7 @@ describe('QueryBuilder', function() { ); }); - it('clear an order', function() { + it('clear an order', () => { testsql( qb() .table('users') @@ -750,7 +750,7 @@ describe('QueryBuilder', function() { ); }); - it('clear a having', function() { + it('clear a having', () => { testsql( qb() .table('users') @@ -778,7 +778,7 @@ describe('QueryBuilder', function() { ); }); - it('basic wheres', function() { + it('basic wheres', () => { testsql( qb() .select('*') @@ -834,7 +834,7 @@ describe('QueryBuilder', function() { ); }); - it('where not', function() { + it('where not', () => { testsql( qb() .select('*') @@ -874,7 +874,7 @@ describe('QueryBuilder', function() { ); }); - it('grouped or where not', function() { + it('grouped or where not', () => { testsql( qb() .select('*') @@ -919,7 +919,7 @@ describe('QueryBuilder', function() { ); }); - it('grouped or where not alternate', function() { + it('grouped or where not alternate', () => { testsql( qb() .select('*') @@ -963,7 +963,7 @@ describe('QueryBuilder', function() { ); }); - it('where not object', function() { + it('where not object', () => { testsql( qb() .select('*') @@ -1011,7 +1011,7 @@ describe('QueryBuilder', function() { ); }); - it('where bool', function() { + it('where bool', () => { testquery( qb() .select('*') @@ -1026,7 +1026,7 @@ describe('QueryBuilder', function() { ); }); - it('where betweens', function() { + it('where betweens', () => { testsql( qb() .select('*') @@ -1053,7 +1053,7 @@ describe('QueryBuilder', function() { ); }); - it('and where betweens', function() { + it('and where betweens', () => { testsql( qb() .select('*') @@ -1085,7 +1085,7 @@ describe('QueryBuilder', function() { ); }); - it('and where not betweens', function() { + it('and where not betweens', () => { testsql( qb() .select('*') @@ -1117,7 +1117,7 @@ describe('QueryBuilder', function() { ); }); - it('where betweens, alternate', function() { + it('where betweens, alternate', () => { testsql( qb() .select('*') @@ -1144,7 +1144,7 @@ describe('QueryBuilder', function() { ); }); - it('where not between', function() { + it('where not between', () => { testsql( qb() .select('*') @@ -1171,7 +1171,7 @@ describe('QueryBuilder', function() { ); }); - it('where not between, alternate', function() { + it('where not between, alternate', () => { testsql( qb() .select('*') @@ -1198,7 +1198,7 @@ describe('QueryBuilder', function() { ); }); - it('basic or wheres', function() { + it('basic or wheres', () => { testsql( qb() .select('*') @@ -1226,7 +1226,7 @@ describe('QueryBuilder', function() { ); }); - it('chained or wheres', function() { + it('chained or wheres', () => { testsql( qb() .select('*') @@ -1254,7 +1254,7 @@ describe('QueryBuilder', function() { ); }); - it('raw column wheres', function() { + it('raw column wheres', () => { testsql( qb() .select('*') @@ -1281,7 +1281,7 @@ describe('QueryBuilder', function() { ); }); - it('raw wheres', function() { + it('raw wheres', () => { testsql( qb() .select('*') @@ -1308,7 +1308,7 @@ describe('QueryBuilder', function() { ); }); - it('raw or wheres', function() { + it('raw or wheres', () => { testsql( qb() .select('*') @@ -1336,7 +1336,7 @@ describe('QueryBuilder', function() { ); }); - it('chained raw or wheres', function() { + it('chained raw or wheres', () => { testsql( qb() .select('*') @@ -1364,7 +1364,7 @@ describe('QueryBuilder', function() { ); }); - it('basic where ins', function() { + it('basic where ins', () => { testsql( qb() .select('*') @@ -1391,7 +1391,7 @@ describe('QueryBuilder', function() { ); }); - it('multi column where ins', function() { + it('multi column where ins', () => { testsql( qb() .select('*') @@ -1432,7 +1432,7 @@ describe('QueryBuilder', function() { ); }); - it('orWhereIn', function() { + it('orWhereIn', () => { testsql( qb() .select('*') @@ -1460,7 +1460,7 @@ describe('QueryBuilder', function() { ); }); - it('basic where not ins', function() { + it('basic where not ins', () => { testsql( qb() .select('*') @@ -1487,7 +1487,7 @@ describe('QueryBuilder', function() { ); }); - it('chained or where not in', function() { + it('chained or where not in', () => { testsql( qb() .select('*') @@ -1515,7 +1515,7 @@ describe('QueryBuilder', function() { ); }); - it('or.whereIn', function() { + it('or.whereIn', () => { testsql( qb() .select('*') @@ -1543,7 +1543,7 @@ describe('QueryBuilder', function() { ); }); - it('chained basic where not ins', function() { + it('chained basic where not ins', () => { testsql( qb() .select('*') @@ -1570,7 +1570,7 @@ describe('QueryBuilder', function() { ); }); - it('chained or where not in', function() { + it('chained or where not in', () => { testsql( qb() .select('*') @@ -1598,7 +1598,7 @@ describe('QueryBuilder', function() { ); }); - it('whereIn with empty array, #477', function() { + it('whereIn with empty array, #477', () => { testsql( qb() .select('*') @@ -1629,7 +1629,7 @@ describe('QueryBuilder', function() { ); }); - it('whereNotIn with empty array, #477', function() { + it('whereNotIn with empty array, #477', () => { testsql( qb() .select('*') @@ -1660,8 +1660,8 @@ describe('QueryBuilder', function() { ); }); - it('should allow a function as the first argument, for a grouped where clause', function() { - var partial = qb() + it('should allow a function as the first argument, for a grouped where clause', () => { + const partial = qb() .table('test') .where('id', '=', 1); testsql(partial, { @@ -1670,7 +1670,7 @@ describe('QueryBuilder', function() { pg: 'select * from "test" where "id" = ?', }); - var subWhere = function(sql) { + const subWhere = function(sql) { expect(this).to.equal(sql); this.where({ id: 3 }).orWhere('id', 4); }; @@ -1695,8 +1695,8 @@ describe('QueryBuilder', function() { }); }); - it('should accept a function as the "value", for a sub select', function() { - var chain = qb().where('id', '=', function(qb) { + it('should accept a function as the "value", for a sub select', () => { + const chain = qb().where('id', '=', function(qb) { expect(this).to.equal(qb); this.select('account_id') .from('names') @@ -1745,8 +1745,8 @@ describe('QueryBuilder', function() { }); }); - it('should accept a function as the "value", for a sub select when chained', function() { - var chain = qb().where('id', '=', function(qb) { + it('should accept a function as the "value", for a sub select when chained', () => { + const chain = qb().where('id', '=', function(qb) { expect(this).to.equal(qb); this.select('account_id') .from('names') @@ -1784,7 +1784,7 @@ describe('QueryBuilder', function() { }); }); - it('should not do whereNull on where("foo", "<>", null) #76', function() { + it('should not do whereNull on where("foo", "<>", null) #76', () => { testquery(qb().where('foo', '<>', null), { mysql: 'select * where `foo` <> NULL', mssql: 'select * where [foo] <> NULL', @@ -1792,7 +1792,7 @@ describe('QueryBuilder', function() { }); }); - it('should expand where("foo", "!=") to - where id = "!="', function() { + it('should expand where("foo", "!=") to - where id = "!="', () => { testquery(qb().where('foo', '!='), { mysql: "select * where `foo` = '!='", mssql: "select * where [foo] = '!='", @@ -1800,8 +1800,8 @@ describe('QueryBuilder', function() { }); }); - it('unions', function() { - var chain = qb() + it('unions', () => { + const chain = qb() .select('*') .from('users') .where('id', '=', 1) @@ -1833,7 +1833,7 @@ describe('QueryBuilder', function() { }, }); - var multipleArgumentsChain = qb() + const multipleArgumentsChain = qb() .select('*') .from('users') .where({ id: 1 }) @@ -1872,7 +1872,7 @@ describe('QueryBuilder', function() { }, }); - var arrayChain = qb() + const arrayChain = qb() .select('*') .from('users') .where({ id: 1 }) @@ -1912,8 +1912,8 @@ describe('QueryBuilder', function() { }); }); - it('wraps unions', function() { - var wrappedChain = qb() + it('wraps unions', () => { + const wrappedChain = qb() .select('*') .from('users') .where('id', 'in', function() { @@ -1947,7 +1947,7 @@ describe('QueryBuilder', function() { }); // worthwhile since we're playing games with the 'wrap' specification with arguments - var multipleArgumentsWrappedChain = qb() + const multipleArgumentsWrappedChain = qb() .select('*') .from('users') .where({ id: 1 }) @@ -1987,7 +1987,7 @@ describe('QueryBuilder', function() { }, }); - var arrayWrappedChain = qb() + const arrayWrappedChain = qb() .select('*') .from('users') .where({ id: 1 }) @@ -2030,8 +2030,8 @@ describe('QueryBuilder', function() { }); }); - it('wraps union alls', function() { - var wrappedChain = qb() + it('wraps union alls', () => { + const wrappedChain = qb() .select('*') .from('users') .where('id', 'in', function() { @@ -2065,7 +2065,7 @@ describe('QueryBuilder', function() { }); // worthwhile since we're playing games with the 'wrap' specification with arguments - var multipleArgumentsWrappedChain = qb() + const multipleArgumentsWrappedChain = qb() .select('*') .from('users') .where({ id: 1 }) @@ -2105,7 +2105,7 @@ describe('QueryBuilder', function() { }, }); - var arrayWrappedChain = qb() + const arrayWrappedChain = qb() .select('*') .from('users') .where({ id: 1 }) @@ -2157,8 +2157,8 @@ describe('QueryBuilder', function() { // expect(chain.bindings).to.eql([1, 2, 10]); // }); - it('union alls', function() { - var chain = qb() + it('union alls', () => { + const chain = qb() .select('*') .from('users') .where('id', '=', 1) @@ -2190,7 +2190,7 @@ describe('QueryBuilder', function() { }, }); - var multipleArgumentsChain = qb() + const multipleArgumentsChain = qb() .select('*') .from('users') .where({ id: 1 }) @@ -2229,7 +2229,7 @@ describe('QueryBuilder', function() { }, }); - var arrayChain = qb() + const arrayChain = qb() .select('*') .from('users') .where({ id: 1 }) @@ -2269,8 +2269,8 @@ describe('QueryBuilder', function() { }); }); - it('multiple unions', function() { - var chain = qb() + it('multiple unions', () => { + const chain = qb() .select('*') .from('users') .where('id', '=', 1) @@ -2308,7 +2308,7 @@ describe('QueryBuilder', function() { }, }); - var arrayChain = qb() + const arrayChain = qb() .select('*') .from('users') .where({ id: 1 }) @@ -2342,7 +2342,7 @@ describe('QueryBuilder', function() { }, }); - var multipleArgumentsChain = qb() + const multipleArgumentsChain = qb() .select('*') .from('users') .where({ id: 1 }) @@ -2377,8 +2377,8 @@ describe('QueryBuilder', function() { }); }); - it('multiple union alls', function() { - var chain = qb() + it('multiple union alls', () => { + const chain = qb() .select('*') .from('users') .where('id', '=', 1) @@ -2418,7 +2418,7 @@ describe('QueryBuilder', function() { }, }); - var arrayChain = qb() + const arrayChain = qb() .select('*') .from('users') .where({ id: 1 }) @@ -2452,7 +2452,7 @@ describe('QueryBuilder', function() { }, }); - var multipleArgumentsChain = qb() + const multipleArgumentsChain = qb() .select('*') .from('users') .where({ id: 1 }) @@ -2487,7 +2487,7 @@ describe('QueryBuilder', function() { }); }); - it('intersects', function() { + it('intersects', () => { const chain = qb() .select('*') .from('users') @@ -2570,7 +2570,7 @@ describe('QueryBuilder', function() { }, }); - var arrayChain = qb() + const arrayChain = qb() .select('*') .from('users') .where({ id: 1 }) @@ -2615,8 +2615,8 @@ describe('QueryBuilder', function() { }); }); - it('wraps intersects', function() { - var wrappedChain = qb() + it('wraps intersects', () => { + const wrappedChain = qb() .select('*') .from('users') .where('id', 'in', function() { @@ -2645,7 +2645,7 @@ describe('QueryBuilder', function() { }); // worthwhile since we're playing games with the 'wrap' specification with arguments - var multipleArgumentsWrappedChain = qb() + const multipleArgumentsWrappedChain = qb() .select('*') .from('users') .where({ id: 1 }) @@ -2680,7 +2680,7 @@ describe('QueryBuilder', function() { }, }); - var arrayWrappedChain = qb() + const arrayWrappedChain = qb() .select('*') .from('users') .where({ id: 1 }) @@ -2718,8 +2718,8 @@ describe('QueryBuilder', function() { }); }); - it('multiple intersects', function() { - var chain = qb() + it('multiple intersects', () => { + const chain = qb() .select('*') .from('users') .where('id', '=', 1) @@ -2752,7 +2752,7 @@ describe('QueryBuilder', function() { }, }); - var arrayChain = qb() + const arrayChain = qb() .select('*') .from('users') .where({ id: 1 }) @@ -2781,7 +2781,7 @@ describe('QueryBuilder', function() { }, }); - var multipleArgumentsChain = qb() + const multipleArgumentsChain = qb() .select('*') .from('users') .where({ id: 1 }) @@ -2811,12 +2811,12 @@ describe('QueryBuilder', function() { }); }); - it('sub select where ins', function() { + it('sub select where ins', () => { testsql( qb() .select('*') .from('users') - .whereIn('id', function(qb) { + .whereIn('id', (qb) => { qb.select('id') .from('users') .where('age', '>', 25) @@ -2852,12 +2852,12 @@ describe('QueryBuilder', function() { ); }); - it('sub select multi column where ins', function() { + it('sub select multi column where ins', () => { testsql( qb() .select('*') .from('users') - .whereIn(['id_a', 'id_b'], function(qb) { + .whereIn(['id_a', 'id_b'], (qb) => { qb.select('id_a', 'id_b') .from('users') .where('age', '>', 25) @@ -2893,12 +2893,12 @@ describe('QueryBuilder', function() { ); }); - it('sub select where not ins', function() { + it('sub select where not ins', () => { testsql( qb() .select('*') .from('users') - .whereNotIn('id', function(qb) { + .whereNotIn('id', (qb) => { qb.select('id') .from('users') .where('age', '>', 25); @@ -2928,7 +2928,7 @@ describe('QueryBuilder', function() { ); }); - it('basic where nulls', function() { + it('basic where nulls', () => { testsql( qb() .select('*') @@ -2955,7 +2955,7 @@ describe('QueryBuilder', function() { ); }); - it('basic or where nulls', function() { + it('basic or where nulls', () => { testsql( qb() .select('*') @@ -2983,7 +2983,7 @@ describe('QueryBuilder', function() { ); }); - it('basic where not nulls', function() { + it('basic where not nulls', () => { testsql( qb() .select('*') @@ -3010,7 +3010,7 @@ describe('QueryBuilder', function() { ); }); - it('basic or where not nulls', function() { + it('basic or where not nulls', () => { testsql( qb() .select('*') @@ -3038,7 +3038,7 @@ describe('QueryBuilder', function() { ); }); - it('group bys', function() { + it('group bys', () => { testsql( qb() .select('*') @@ -3065,7 +3065,7 @@ describe('QueryBuilder', function() { ); }); - it('order bys', function() { + it('order bys', () => { testsql( qb() .select('*') @@ -3093,7 +3093,7 @@ describe('QueryBuilder', function() { ); }); - it('order by array', function() { + it('order by array', () => { testsql( qb() .select('*') @@ -3120,7 +3120,7 @@ describe('QueryBuilder', function() { ); }); - it('order by array without order', function() { + it('order by array without order', () => { testsql( qb() .select('*') @@ -3147,7 +3147,7 @@ describe('QueryBuilder', function() { ); }); - it('raw group bys', function() { + it('raw group bys', () => { testsql( qb() .select('*') @@ -3174,7 +3174,7 @@ describe('QueryBuilder', function() { ); }); - it('raw order bys with default direction', function() { + it('raw order bys with default direction', () => { testsql( qb() .select('*') @@ -3201,7 +3201,7 @@ describe('QueryBuilder', function() { ); }); - it('raw order bys with specified direction', function() { + it('raw order bys with specified direction', () => { testsql( qb() .select('*') @@ -3228,7 +3228,7 @@ describe('QueryBuilder', function() { ); }); - it('orderByRaw', function() { + it('orderByRaw', () => { testsql( qb() .select('*') @@ -3255,7 +3255,7 @@ describe('QueryBuilder', function() { ); }); - it('orderByRaw second argument is the binding', function() { + it('orderByRaw second argument is the binding', () => { testsql( qb() .select('*') @@ -3282,7 +3282,7 @@ describe('QueryBuilder', function() { ); }); - it('multiple order bys', function() { + it('multiple order bys', () => { testsql( qb() .select('*') @@ -3310,7 +3310,7 @@ describe('QueryBuilder', function() { ); }); - it('havings', function() { + it('havings', () => { testsql( qb() .select('*') @@ -3326,7 +3326,7 @@ describe('QueryBuilder', function() { ); }); - it('or having', function() { + it('or having', () => { testsql( qb() .select('*') @@ -3343,7 +3343,7 @@ describe('QueryBuilder', function() { ); }); - it('nested having', function() { + it('nested having', () => { testsql( qb() .select('*') @@ -3361,7 +3361,7 @@ describe('QueryBuilder', function() { ); }); - it('nested or havings', function() { + it('nested or havings', () => { testsql( qb() .select('*') @@ -3381,7 +3381,7 @@ describe('QueryBuilder', function() { ); }); - it('grouped having', function() { + it('grouped having', () => { testsql( qb() .select('*') @@ -3399,7 +3399,7 @@ describe('QueryBuilder', function() { ); }); - it('having from', function() { + it('having from', () => { testsql( qb() .select('email as foo_email') @@ -3417,7 +3417,7 @@ describe('QueryBuilder', function() { ); }); - it('raw havings', function() { + it('raw havings', () => { testsql( qb() .select('*') @@ -3433,7 +3433,7 @@ describe('QueryBuilder', function() { ); }); - it('raw or havings', function() { + it('raw or havings', () => { testsql( qb() .select('*') @@ -3452,7 +3452,7 @@ describe('QueryBuilder', function() { ); }); - it('having null', function() { + it('having null', () => { testsql( qb() .select('*') @@ -3468,7 +3468,7 @@ describe('QueryBuilder', function() { ); }); - it('or having null', function() { + it('or having null', () => { testsql( qb() .select('*') @@ -3486,7 +3486,7 @@ describe('QueryBuilder', function() { ); }); - it('having not null', function() { + it('having not null', () => { testsql( qb() .select('*') @@ -3502,7 +3502,7 @@ describe('QueryBuilder', function() { ); }); - it('or having not null', function() { + it('or having not null', () => { testsql( qb() .select('*') @@ -3524,7 +3524,7 @@ describe('QueryBuilder', function() { ); }); - it('having exists', function() { + it('having exists', () => { testsql( qb() .select('*') @@ -3546,7 +3546,7 @@ describe('QueryBuilder', function() { ); }); - it('or having exists', function() { + it('or having exists', () => { testsql( qb() .select('*') @@ -3572,7 +3572,7 @@ describe('QueryBuilder', function() { ); }); - it('having not exists', function() { + it('having not exists', () => { testsql( qb() .select('*') @@ -3595,7 +3595,7 @@ describe('QueryBuilder', function() { ); }); - it('or having not exists', function() { + it('or having not exists', () => { testsql( qb() .select('*') @@ -3621,7 +3621,7 @@ describe('QueryBuilder', function() { ); }); - it('having between', function() { + it('having between', () => { testsql( qb() .select('*') @@ -3637,7 +3637,7 @@ describe('QueryBuilder', function() { ); }); - it('or having between', function() { + it('or having between', () => { testsql( qb() .select('*') @@ -3659,7 +3659,7 @@ describe('QueryBuilder', function() { ); }); - it('having not between', function() { + it('having not between', () => { testsql( qb() .select('*') @@ -3675,7 +3675,7 @@ describe('QueryBuilder', function() { ); }); - it('or having not between', function() { + it('or having not between', () => { testsql( qb() .select('*') @@ -3697,7 +3697,7 @@ describe('QueryBuilder', function() { ); }); - it('having in', function() { + it('having in', () => { testsql( qb() .select('*') @@ -3713,7 +3713,7 @@ describe('QueryBuilder', function() { ); }); - it('or having in', function() { + it('or having in', () => { testsql( qb() .select('*') @@ -3735,7 +3735,7 @@ describe('QueryBuilder', function() { ); }); - it('having not in', function() { + it('having not in', () => { testsql( qb() .select('*') @@ -3751,7 +3751,7 @@ describe('QueryBuilder', function() { ); }); - it('or having not in', function() { + it('or having not in', () => { testsql( qb() .select('*') @@ -3773,7 +3773,7 @@ describe('QueryBuilder', function() { ); }); - it('limits', function() { + it('limits', () => { testsql( qb() .select('*') @@ -3804,7 +3804,7 @@ describe('QueryBuilder', function() { ); }); - it('can limit 0', function() { + it('can limit 0', () => { testsql( qb() .select('*') @@ -3835,7 +3835,7 @@ describe('QueryBuilder', function() { ); }); - it('limits and offsets', function() { + it('limits and offsets', () => { testsql( qb() .select('*') @@ -3868,7 +3868,7 @@ describe('QueryBuilder', function() { ); }); - it('limits and raw selects', function() { + it('limits and raw selects', () => { testsql( qb() .select(raw('name = ? as isJohn', ['john'])) @@ -3900,7 +3900,7 @@ describe('QueryBuilder', function() { ); }); - it('first', function() { + it('first', () => { testsql( qb() .first('*') @@ -3930,7 +3930,7 @@ describe('QueryBuilder', function() { ); }); - it('offsets only', function() { + it('offsets only', () => { testsql( qb() .select('*') @@ -3966,7 +3966,7 @@ describe('QueryBuilder', function() { ); }); - it('where shortcut', function() { + it('where shortcut', () => { testsql( qb() .select('*') @@ -3994,13 +3994,13 @@ describe('QueryBuilder', function() { ); }); - it('nested wheres', function() { + it('nested wheres', () => { testsql( qb() .select('*') .from('users') .where('email', '=', 'foo') - .orWhere(function(qb) { + .orWhere((qb) => { qb.where('name', '=', 'bar').where('age', '=', 25); }), { @@ -4028,13 +4028,13 @@ describe('QueryBuilder', function() { ); }); - it('clear nested wheres', function() { + it('clear nested wheres', () => { testsql( qb() .select('*') .from('users') .where('email', '=', 'foo') - .orWhere(function(qb) { + .orWhere((qb) => { qb.where('name', '=', 'bar') .where('age', '=', 25) .clearWhere(); @@ -4060,13 +4060,13 @@ describe('QueryBuilder', function() { ); }); - it('clear where and nested wheres', function() { + it('clear where and nested wheres', () => { testsql( qb() .select('*') .from('users') .where('email', '=', 'foo') - .orWhere(function(qb) { + .orWhere((qb) => { qb.where('name', '=', 'bar').where('age', '=', 25); }) .clearWhere(), @@ -4087,13 +4087,13 @@ describe('QueryBuilder', function() { ); }); - it('full sub selects', function() { + it('full sub selects', () => { testsql( qb() .select('*') .from('users') .where('email', '=', 'foo') - .orWhere('id', '=', function(qb) { + .orWhere('id', '=', (qb) => { qb.select(raw('max(id)')) .from('users') .where('email', '=', 'bar'); @@ -4123,13 +4123,13 @@ describe('QueryBuilder', function() { ); }); - it('clear nested selects', function() { + it('clear nested selects', () => { testsql( qb() .select('email') .from('users') .where('email', '=', 'foo') - .orWhere('id', '=', function(qb) { + .orWhere('id', '=', (qb) => { qb.select(raw('max(id)')) .from('users') .where('email', '=', 'bar') @@ -4160,13 +4160,13 @@ describe('QueryBuilder', function() { ); }); - it('clear non nested selects', function() { + it('clear non nested selects', () => { testsql( qb() .select('email') .from('users') .where('email', '=', 'foo') - .orWhere('id', '=', function(qb) { + .orWhere('id', '=', (qb) => { qb.select(raw('max(id)')) .from('users') .where('email', '=', 'bar'); @@ -4197,12 +4197,12 @@ describe('QueryBuilder', function() { ); }); - it('where exists', function() { + it('where exists', () => { testsql( qb() .select('*') .from('orders') - .whereExists(function(qb) { + .whereExists((qb) => { qb.select('*') .from('products') .where('products.id', '=', raw('"orders"."id"')); @@ -4232,7 +4232,7 @@ describe('QueryBuilder', function() { ); }); - it('where exists with builder', function() { + it('where exists with builder', () => { testsql( qb() .select('*') @@ -4268,12 +4268,12 @@ describe('QueryBuilder', function() { ); }); - it('where not exists', function() { + it('where not exists', () => { testsql( qb() .select('*') .from('orders') - .whereNotExists(function(qb) { + .whereNotExists((qb) => { qb.select('*') .from('products') .where('products.id', '=', raw('"orders"."id"')); @@ -4303,13 +4303,13 @@ describe('QueryBuilder', function() { ); }); - it('or where exists', function() { + it('or where exists', () => { testsql( qb() .select('*') .from('orders') .where('id', '=', 1) - .orWhereExists(function(qb) { + .orWhereExists((qb) => { qb.select('*') .from('products') .where('products.id', '=', raw('"orders"."id"')); @@ -4339,13 +4339,13 @@ describe('QueryBuilder', function() { ); }); - it('or where not exists', function() { + it('or where not exists', () => { testsql( qb() .select('*') .from('orders') .where('id', '=', 1) - .orWhereNotExists(function(qb) { + .orWhereNotExists((qb) => { qb.select('*') .from('products') .where('products.id', '=', raw('"orders"."id"')); @@ -4375,7 +4375,7 @@ describe('QueryBuilder', function() { ); }); - it('cross join', function() { + it('cross join', () => { testsql( qb() .select('*') @@ -4417,7 +4417,7 @@ describe('QueryBuilder', function() { ); }); - it('full outer join', function() { + it('full outer join', () => { testsql( qb() .select('*') @@ -4448,7 +4448,7 @@ describe('QueryBuilder', function() { ); }); - it('cross join on', function() { + it('cross join on', () => { testsql( qb() .select('*') @@ -4469,7 +4469,7 @@ describe('QueryBuilder', function() { ); }); - it('basic joins', function() { + it('basic joins', () => { testsql( qb() .select('*') @@ -4501,7 +4501,7 @@ describe('QueryBuilder', function() { ); }); - it('right (outer) joins', function() { + it('right (outer) joins', () => { testsql( qb() .select('*') @@ -4538,12 +4538,12 @@ describe('QueryBuilder', function() { ); }); - it('complex join', function() { + it('complex join', () => { testsql( qb() .select('*') .from('users') - .join('contacts', function(qb) { + .join('contacts', (qb) => { qb.on('users.id', '=', 'contacts.id').orOn( 'users.name', '=', @@ -4575,13 +4575,13 @@ describe('QueryBuilder', function() { ); }); - it('complex join with nest conditional statements', function() { + it('complex join with nest conditional statements', () => { testsql( qb() .select('*') .from('users') - .join('contacts', function(qb) { - qb.on(function(qb) { + .join('contacts', (qb) => { + qb.on((qb) => { qb.on('users.id', '=', 'contacts.id'); qb.orOn('users.name', '=', 'contacts.name'); }); @@ -4611,12 +4611,12 @@ describe('QueryBuilder', function() { ); }); - it('complex join with empty in', function() { + it('complex join with empty in', () => { testsql( qb() .select('*') .from('users') - .join('contacts', function(qb) { + .join('contacts', (qb) => { qb.on('users.id', '=', 'contacts.id').onIn('users.name', []); }), { @@ -4644,7 +4644,7 @@ describe('QueryBuilder', function() { ); }); - it('joins with raw', function() { + it('joins with raw', () => { testsql( qb() .select('*') @@ -4676,7 +4676,7 @@ describe('QueryBuilder', function() { ); }); - it('joins with schema', function() { + it('joins with schema', () => { testsql( qb() .withSchema('myschema') @@ -4709,12 +4709,12 @@ describe('QueryBuilder', function() { ); }); - it('on null', function() { + it('on null', () => { testsql( qb() .select('*') .from('users') - .join('contacts', function(qb) { + .join('contacts', (qb) => { qb.on('users.id', '=', 'contacts.id').onNull('contacts.address'); }), { @@ -4732,12 +4732,12 @@ describe('QueryBuilder', function() { ); }); - it('or on null', function() { + it('or on null', () => { testsql( qb() .select('*') .from('users') - .join('contacts', function(qb) { + .join('contacts', (qb) => { qb.on('users.id', '=', 'contacts.id') .onNull('contacts.address') .orOnNull('contacts.phone'); @@ -4757,12 +4757,12 @@ describe('QueryBuilder', function() { ); }); - it('on not null', function() { + it('on not null', () => { testsql( qb() .select('*') .from('users') - .join('contacts', function(qb) { + .join('contacts', (qb) => { qb.on('users.id', '=', 'contacts.id').onNotNull('contacts.address'); }), { @@ -4780,12 +4780,12 @@ describe('QueryBuilder', function() { ); }); - it('or on not null', function() { + it('or on not null', () => { testsql( qb() .select('*') .from('users') - .join('contacts', function(qb) { + .join('contacts', (qb) => { qb.on('users.id', '=', 'contacts.id') .onNotNull('contacts.address') .orOnNotNull('contacts.phone'); @@ -4805,12 +4805,12 @@ describe('QueryBuilder', function() { ); }); - it('on exists', function() { + it('on exists', () => { testsql( qb() .select('*') .from('users') - .join('contacts', function(qb) { + .join('contacts', (qb) => { qb.on('users.id', '=', 'contacts.id').onExists(function() { this.select('*').from('foo'); }); @@ -4830,12 +4830,12 @@ describe('QueryBuilder', function() { ); }); - it('or on exists', function() { + it('or on exists', () => { testsql( qb() .select('*') .from('users') - .join('contacts', function(qb) { + .join('contacts', (qb) => { qb.on('users.id', '=', 'contacts.id') .onExists(function() { this.select('*').from('foo'); @@ -4859,12 +4859,12 @@ describe('QueryBuilder', function() { ); }); - it('on not exists', function() { + it('on not exists', () => { testsql( qb() .select('*') .from('users') - .join('contacts', function(qb) { + .join('contacts', (qb) => { qb.on('users.id', '=', 'contacts.id').onNotExists(function() { this.select('*').from('foo'); }); @@ -4884,12 +4884,12 @@ describe('QueryBuilder', function() { ); }); - it('or on not exists', function() { + it('or on not exists', () => { testsql( qb() .select('*') .from('users') - .join('contacts', function(qb) { + .join('contacts', (qb) => { qb.on('users.id', '=', 'contacts.id') .onNotExists(function() { this.select('*').from('foo'); @@ -4913,12 +4913,12 @@ describe('QueryBuilder', function() { ); }); - it('on between', function() { + it('on between', () => { testsql( qb() .select('*') .from('users') - .join('contacts', function(qb) { + .join('contacts', (qb) => { qb.on('users.id', '=', 'contacts.id').onBetween('contacts.id', [ 7, 15, @@ -4939,12 +4939,12 @@ describe('QueryBuilder', function() { ); }); - it('or on between', function() { + it('or on between', () => { testsql( qb() .select('*') .from('users') - .join('contacts', function(qb) { + .join('contacts', (qb) => { qb.on('users.id', '=', 'contacts.id') .onBetween('contacts.id', [7, 15]) .orOnBetween('users.id', [9, 14]); @@ -4964,12 +4964,12 @@ describe('QueryBuilder', function() { ); }); - it('on not between', function() { + it('on not between', () => { testsql( qb() .select('*') .from('users') - .join('contacts', function(qb) { + .join('contacts', (qb) => { qb.on('users.id', '=', 'contacts.id').onNotBetween('contacts.id', [ 7, 15, @@ -4990,12 +4990,12 @@ describe('QueryBuilder', function() { ); }); - it('or on not between', function() { + it('or on not between', () => { testsql( qb() .select('*') .from('users') - .join('contacts', function(qb) { + .join('contacts', (qb) => { qb.on('users.id', '=', 'contacts.id') .onNotBetween('contacts.id', [7, 15]) .orOnNotBetween('users.id', [9, 14]); @@ -5015,12 +5015,12 @@ describe('QueryBuilder', function() { ); }); - it('on in', function() { + it('on in', () => { testsql( qb() .select('*') .from('users') - .join('contacts', function(qb) { + .join('contacts', (qb) => { qb.on('users.id', '=', 'contacts.id').onIn('contacts.id', [ 7, 15, @@ -5043,12 +5043,12 @@ describe('QueryBuilder', function() { ); }); - it('or on in', function() { + it('or on in', () => { testsql( qb() .select('*') .from('users') - .join('contacts', function(qb) { + .join('contacts', (qb) => { qb.on('users.id', '=', 'contacts.id') .onIn('contacts.id', [7, 15, 23, 41]) .orOnIn('users.id', [21, 37]); @@ -5068,12 +5068,12 @@ describe('QueryBuilder', function() { ); }); - it('on not in', function() { + it('on not in', () => { testsql( qb() .select('*') .from('users') - .join('contacts', function(qb) { + .join('contacts', (qb) => { qb.on('users.id', '=', 'contacts.id').onNotIn('contacts.id', [ 7, 15, @@ -5096,12 +5096,12 @@ describe('QueryBuilder', function() { ); }); - it('or on not in', function() { + it('or on not in', () => { testsql( qb() .select('*') .from('users') - .join('contacts', function(qb) { + .join('contacts', (qb) => { qb.on('users.id', '=', 'contacts.id') .onNotIn('contacts.id', [7, 15, 23, 41]) .orOnNotIn('users.id', [21, 37]); @@ -5121,7 +5121,7 @@ describe('QueryBuilder', function() { ); }); - it('raw expressions in select', function() { + it('raw expressions in select', () => { testsql( qb() .select(raw('substr(foo, 6)')) @@ -5147,7 +5147,7 @@ describe('QueryBuilder', function() { ); }); - it('count', function() { + it('count', () => { testsql( qb() .from('users') @@ -5173,7 +5173,7 @@ describe('QueryBuilder', function() { ); }); - it('count distinct', function() { + it('count distinct', () => { testsql( qb() .from('users') @@ -5199,7 +5199,7 @@ describe('QueryBuilder', function() { ); }); - it('count with string alias', function() { + it('count with string alias', () => { testsql( qb() .from('users') @@ -5229,7 +5229,7 @@ describe('QueryBuilder', function() { ); }); - it('count with object alias', function() { + it('count with object alias', () => { testsql( qb() .from('users') @@ -5259,7 +5259,7 @@ describe('QueryBuilder', function() { ); }); - it('count distinct with string alias', function() { + it('count distinct with string alias', () => { testsql( qb() .from('users') @@ -5289,7 +5289,7 @@ describe('QueryBuilder', function() { ); }); - it('count distinct with object alias', function() { + it('count distinct with object alias', () => { testsql( qb() .from('users') @@ -5319,7 +5319,7 @@ describe('QueryBuilder', function() { ); }); - it('count with raw values', function() { + it('count with raw values', () => { testsql( qb() .from('users') @@ -5341,7 +5341,7 @@ describe('QueryBuilder', function() { ); }); - it('count distinct with raw values', function() { + it('count distinct with raw values', () => { testsql( qb() .from('users') @@ -5363,7 +5363,7 @@ describe('QueryBuilder', function() { ); }); - it('count distinct with multiple columns', function() { + it('count distinct with multiple columns', () => { testsql( qb() .from('users') @@ -5389,7 +5389,7 @@ describe('QueryBuilder', function() { ); }); - it('count distinct with multiple columns with alias', function() { + it('count distinct with multiple columns with alias', () => { testsql( qb() .from('users') @@ -5415,7 +5415,7 @@ describe('QueryBuilder', function() { ); }); - it('max', function() { + it('max', () => { testsql( qb() .from('users') @@ -5441,7 +5441,7 @@ describe('QueryBuilder', function() { ); }); - it('max with raw values', function() { + it('max with raw values', () => { testsql( qb() .from('users') @@ -5463,7 +5463,7 @@ describe('QueryBuilder', function() { ); }); - it('min', function() { + it('min', () => { testsql( qb() .from('users') @@ -5489,7 +5489,7 @@ describe('QueryBuilder', function() { ); }); - it('min with raw values', function() { + it('min with raw values', () => { testsql( qb() .from('users') @@ -5511,7 +5511,7 @@ describe('QueryBuilder', function() { ); }); - it('sum', function() { + it('sum', () => { testsql( qb() .from('users') @@ -5537,7 +5537,7 @@ describe('QueryBuilder', function() { ); }); - it('sum with raw values', function() { + it('sum with raw values', () => { testsql( qb() .from('users') @@ -5559,7 +5559,7 @@ describe('QueryBuilder', function() { ); }); - it('sum distinct', function() { + it('sum distinct', () => { testsql( qb() .from('users') @@ -5585,7 +5585,7 @@ describe('QueryBuilder', function() { ); }); - it('sum distinct with raw values', function() { + it('sum distinct with raw values', () => { testsql( qb() .from('users') @@ -5607,7 +5607,7 @@ describe('QueryBuilder', function() { ); }); - it('avg', function() { + it('avg', () => { testsql( qb() .from('users') @@ -5629,7 +5629,7 @@ describe('QueryBuilder', function() { ); }); - it('avg with raw values', function() { + it('avg with raw values', () => { testsql( qb() .from('users') @@ -5651,7 +5651,7 @@ describe('QueryBuilder', function() { ); }); - it('avg distinct with raw values', function() { + it('avg distinct with raw values', () => { testsql( qb() .from('users') @@ -5673,7 +5673,7 @@ describe('QueryBuilder', function() { ); }); - it('insert method', function() { + it('insert method', () => { testsql( qb() .into('users') @@ -5699,7 +5699,7 @@ describe('QueryBuilder', function() { ); }); - it('multiple inserts', function() { + it('multiple inserts', () => { testsql( qb() .from('users') @@ -5738,7 +5738,7 @@ describe('QueryBuilder', function() { ); }); - it('multiple inserts with partly undefined keys client with configuration nullAsDefault: true', function() { + it('multiple inserts with partly undefined keys client with configuration nullAsDefault: true', () => { testquery( qb() .from('users') @@ -5761,7 +5761,7 @@ describe('QueryBuilder', function() { ); }); - it('multiple inserts with partly undefined keys', function() { + it('multiple inserts with partly undefined keys', () => { testquery( qb() .from('users') @@ -5781,8 +5781,8 @@ describe('QueryBuilder', function() { ); }); - it('multiple inserts with partly undefined keys throw error with sqlite', function() { - expect(function() { + it('multiple inserts with partly undefined keys throw error with sqlite', () => { + expect(() => { testquery( qb() .from('users') @@ -5794,7 +5794,7 @@ describe('QueryBuilder', function() { }).to.throw(TypeError); }); - it('multiple inserts with returning', function() { + it('multiple inserts with returning', () => { // returning only supported directly by postgres and with workaround with oracle // other databases implicitly return the inserted id testsql( @@ -5830,7 +5830,7 @@ describe('QueryBuilder', function() { oracledb: { sql: 'begin execute immediate \'insert into "users" ("email", "name") values (:1, :2) returning "id" into :3\' using ?, ?, out ?; execute immediate \'insert into "users" ("email", "name") values (:1, :2) returning "id" into :3\' using ?, ?, out ?;end;', - bindings: function(bindings) { + bindings: (bindings) => { expect(bindings.length).to.equal(6); expect(bindings[0]).to.equal('foo'); expect(bindings[1]).to.equal('taylor'); @@ -5848,7 +5848,7 @@ describe('QueryBuilder', function() { ); }); - it('multiple inserts with multiple returning', function() { + it('multiple inserts with multiple returning', () => { testsql( qb() .from('users') @@ -5883,7 +5883,7 @@ describe('QueryBuilder', function() { oracledb: { sql: 'begin execute immediate \'insert into "users" ("email", "name") values (:1, :2) returning "id","name" into :3, :4\' using ?, ?, out ?, out ?; execute immediate \'insert into "users" ("email", "name") values (:1, :2) returning "id","name" into :3, :4\' using ?, ?, out ?, out ?;end;', - bindings: function(bindings) { + bindings: (bindings) => { expect(bindings.length).to.equal(8); expect(bindings[0]).to.equal('foo'); expect(bindings[1]).to.equal('taylor'); @@ -5907,7 +5907,7 @@ describe('QueryBuilder', function() { ); }); - it('insert method respects raw bindings', function() { + it('insert method respects raw bindings', () => { testsql( qb() .insert({ email: raw('CURRENT TIMESTAMP') }) @@ -5933,13 +5933,13 @@ describe('QueryBuilder', function() { ); }); - it('normalizes for missing keys in insert', function() { - var data = [{ a: 1 }, { b: 2 }, { a: 2, c: 3 }]; + it('normalizes for missing keys in insert', () => { + const data = [{ a: 1 }, { b: 2 }, { a: 2, c: 3 }]; //This is done because sqlite3 does not support valueForUndefined, and can't manipulate testsql to use 'clientsWithUseNullForUndefined'. //But we still want to make sure that when `useNullAsDefault` is explicitly defined, that the query still works as expected. (Bindings being undefined) //It's reset at the end of the test. - var previousValuesForUndefinedSqlite3 = clients.sqlite3.valueForUndefined; + const previousValuesForUndefinedSqlite3 = clients.sqlite3.valueForUndefined; clients.sqlite3.valueForUndefined = null; testsql( @@ -5992,7 +5992,7 @@ describe('QueryBuilder', function() { clients.sqlite3.valueForUndefined = previousValuesForUndefinedSqlite3; }); - it('empty insert should be a noop', function() { + it('empty insert should be a noop', () => { testsql( qb() .into('users') @@ -6022,7 +6022,7 @@ describe('QueryBuilder', function() { ); }); - it('insert with empty array should be a noop', function() { + it('insert with empty array should be a noop', () => { testsql( qb() .into('users') @@ -6052,7 +6052,7 @@ describe('QueryBuilder', function() { ); }); - it('insert with array with empty object and returning', function() { + it('insert with array with empty object and returning', () => { testsql( qb() .into('users') @@ -6081,7 +6081,7 @@ describe('QueryBuilder', function() { oracledb: { sql: 'insert into "users" ("id") values (default) returning "id" into ?', - bindings: function(bindings) { + bindings: (bindings) => { expect(bindings.length).to.equal(1); expect(bindings[0].toString()).to.equal( '[object ReturningHelper:id]' @@ -6092,7 +6092,7 @@ describe('QueryBuilder', function() { ); }); - it('update method', function() { + it('update method', () => { testsql( qb() .update({ email: 'foo', name: 'bar' }) @@ -6120,7 +6120,7 @@ describe('QueryBuilder', function() { ); }); - it('update only method', function() { + it('update only method', () => { testsql( qb() .update({ email: 'foo', name: 'bar' }) @@ -6135,7 +6135,7 @@ describe('QueryBuilder', function() { ); }); - it('should not update columns undefined values', function() { + it('should not update columns undefined values', () => { testsql( qb() .update({ email: 'foo', name: undefined }) @@ -6158,7 +6158,7 @@ describe('QueryBuilder', function() { ); }); - it("should allow for 'null' updates", function() { + it("should allow for 'null' updates", () => { testsql( qb() .update({ email: null, name: 'bar' }) @@ -6186,7 +6186,7 @@ describe('QueryBuilder', function() { ); }); - it('order by, limit', function() { + it('order by, limit', () => { // update with limit works only with mysql and derrivates testsql( qb() @@ -6218,7 +6218,7 @@ describe('QueryBuilder', function() { ); }); - it('update method with joins mysql', function() { + it('update method with joins mysql', () => { testsql( qb() .from('users') @@ -6250,7 +6250,7 @@ describe('QueryBuilder', function() { ); }); - it('update method with limit mysql', function() { + it('update method with limit mysql', () => { // limit works only with mysql or derrivates testsql( qb() @@ -6283,7 +6283,7 @@ describe('QueryBuilder', function() { ); }); - it('update method without joins on postgres', function() { + it('update method without joins on postgres', () => { testsql( qb() .from('users') @@ -6311,7 +6311,7 @@ describe('QueryBuilder', function() { ); }); - it('update method with returning on oracle', function() { + it('update method with returning on oracle', () => { testsql( qb() .from('users') @@ -6321,7 +6321,7 @@ describe('QueryBuilder', function() { oracledb: { sql: 'update "users" set "email" = ?, "name" = ? where "id" = ? returning "ROWID" into ?', - bindings: function(bindings) { + bindings: (bindings) => { expect(bindings.length).to.equal(4); expect(bindings[0]).to.equal('foo'); expect(bindings[1]).to.equal('bar'); @@ -6342,7 +6342,7 @@ describe('QueryBuilder', function() { // expect(chain.sql).to.eql(['foo', 'bar', 1]); // }); - it('update method respects raw', function() { + it('update method respects raw', () => { testsql( qb() .from('users') @@ -6370,7 +6370,7 @@ describe('QueryBuilder', function() { ); }); - it('increment method', function() { + it('increment method', () => { testsql( qb() .into('users') @@ -6654,7 +6654,7 @@ describe('QueryBuilder', function() { ); }); - it('increment method with floats', function() { + it('increment method with floats', () => { testsql( qb() .into('users') @@ -6682,7 +6682,7 @@ describe('QueryBuilder', function() { ); }); - it('decrement method', function() { + it('decrement method', () => { testsql( qb() .into('users') @@ -6710,7 +6710,7 @@ describe('QueryBuilder', function() { ); }); - it('decrement method with floats', function() { + it('decrement method with floats', () => { testsql( qb() .into('users') @@ -6738,7 +6738,7 @@ describe('QueryBuilder', function() { ); }); - it('delete method', function() { + it('delete method', () => { testsql( qb() .from('users') @@ -6765,7 +6765,7 @@ describe('QueryBuilder', function() { ); }); - it('delete only method', function() { + it('delete only method', () => { testsql( qb() .from('users', { only: true }) @@ -6780,7 +6780,7 @@ describe('QueryBuilder', function() { ); }); - it('truncate method', function() { + it('truncate method', () => { testsql( qb() .table('users') @@ -6793,7 +6793,7 @@ describe('QueryBuilder', function() { sqlite3: { sql: 'delete from `users`', bindings: [], - output: function(output) { + output: (output) => { expect(typeof output).to.equal('function'); }, }, @@ -6817,7 +6817,7 @@ describe('QueryBuilder', function() { ); }); - it('insert get id', function() { + it('insert get id', () => { testsql( qb() .from('users') @@ -6841,7 +6841,7 @@ describe('QueryBuilder', function() { }, oracledb: { sql: 'insert into "users" ("email") values (?) returning "id" into ?', - bindings: function(bindings) { + bindings: (bindings) => { expect(bindings.length).to.equal(2); expect(bindings[0]).to.equal('foo'); expect(bindings[1].toString()).to.equal( @@ -6853,7 +6853,7 @@ describe('QueryBuilder', function() { ); }); - it('wrapping', function() { + it('wrapping', () => { testsql( qb() .select('*') @@ -6866,7 +6866,7 @@ describe('QueryBuilder', function() { ); }); - it('order by desc', function() { + it('order by desc', () => { testsql( qb() .select('*') @@ -6880,7 +6880,7 @@ describe('QueryBuilder', function() { ); }); - it('providing null or false as second parameter builds correctly', function() { + it('providing null or false as second parameter builds correctly', () => { testsql( qb() .select('*') @@ -6894,7 +6894,7 @@ describe('QueryBuilder', function() { ); }); - it('lock for update', function() { + it('lock for update', () => { testsql( qb() .select('*') @@ -6922,7 +6922,7 @@ describe('QueryBuilder', function() { ); }); - it('lock in share mode', function() { + it('lock in share mode', () => { testsql( qb() .select('*') @@ -6946,7 +6946,7 @@ describe('QueryBuilder', function() { ); }); - it('should allow lock (such as forUpdate) outside of a transaction', function() { + it('should allow lock (such as forUpdate) outside of a transaction', () => { testsql( qb() .select('*') @@ -6970,7 +6970,7 @@ describe('QueryBuilder', function() { ); }); - it('lock only some tables for update', function() { + it('lock only some tables for update', () => { testsql( qb() .select('*') @@ -6998,7 +6998,7 @@ describe('QueryBuilder', function() { ); }); - it('lock for update with skip locked #1937', function() { + it('lock for update with skip locked #1937', () => { testsql( qb() .select('*') @@ -7019,7 +7019,7 @@ describe('QueryBuilder', function() { ); }); - it('lock for update with nowait #1937', function() { + it('lock for update with nowait #1937', () => { testsql( qb() .select('*') @@ -7040,8 +7040,8 @@ describe('QueryBuilder', function() { ); }); - it('noWait and skipLocked require a lock mode to be set', function() { - expect(function() { + it('noWait and skipLocked require a lock mode to be set', () => { + expect(() => { qb() .select('*') .noWait() @@ -7049,7 +7049,7 @@ describe('QueryBuilder', function() { }).to.throw( '.noWait() can only be used after a call to .forShare() or .forUpdate()!' ); - expect(function() { + expect(() => { qb() .select('*') .skipLocked() @@ -7059,8 +7059,8 @@ describe('QueryBuilder', function() { ); }); - it('skipLocked conflicts with noWait and vice-versa', function() { - expect(function() { + it('skipLocked conflicts with noWait and vice-versa', () => { + expect(() => { qb() .select('*') .forUpdate() @@ -7068,7 +7068,7 @@ describe('QueryBuilder', function() { .skipLocked() .toString(); }).to.throw('.skipLocked() cannot be used together with .noWait()!'); - expect(function() { + expect(() => { qb() .select('*') .forUpdate() @@ -7078,7 +7078,7 @@ describe('QueryBuilder', function() { }).to.throw('.noWait() cannot be used together with .skipLocked()!'); }); - it('allows insert values of sub-select, #121', function() { + it('allows insert values of sub-select, #121', () => { testsql( qb() .table('entries') @@ -7114,7 +7114,7 @@ describe('QueryBuilder', function() { ); }); - it('allows left outer join with raw values', function() { + it('allows left outer join with raw values', () => { testsql( qb() .select('*') @@ -7150,7 +7150,7 @@ describe('QueryBuilder', function() { ); }); - it('should not break with null call #182', function() { + it('should not break with null call #182', () => { testsql( qb() .from('test') @@ -7177,7 +7177,7 @@ describe('QueryBuilder', function() { ); }); - it('should clear offset when passing null', function() { + it('should clear offset when passing null', () => { testsql( qb() .from('test') @@ -7204,22 +7204,22 @@ describe('QueryBuilder', function() { ); }); - it('allows passing builder into where clause, #162', function() { - var chain = qb() + it('allows passing builder into where clause, #162', () => { + const chain = qb() .from('chapter') .select('id') .where('book', 1); - var page = qb() + const page = qb() .from('page') .select('id') .whereIn('chapter_id', chain); - var word = qb() + const word = qb() .from('word') .select('id') .whereIn('page_id', page); - var three = chain.clone().del(); - var two = page.clone().del(); - var one = word.clone().del(); + const three = chain.clone().del(); + const two = page.clone().del(); + const one = word.clone().del(); testsql(one, { mysql: { @@ -7287,9 +7287,9 @@ describe('QueryBuilder', function() { }); }); - it('allows specifying the columns and the query for insert, #211', function() { - var id = 1; - var email = 'foo@bar.com'; + it('allows specifying the columns and the query for insert, #211', () => { + const id = 1; + const email = 'foo@bar.com'; testsql( qb() .into(raw('recipients (recipient_id, email)')) @@ -7327,9 +7327,9 @@ describe('QueryBuilder', function() { ); }); - it('does an update with join on mysql, #191', function() { - var setObj = { 'tblPerson.City': 'Boonesville' }; - var query = qb() + it('does an update with join on mysql, #191', () => { + const setObj = { 'tblPerson.City': 'Boonesville' }; + const query = qb() .table('tblPerson') .update(setObj) .join( @@ -7365,15 +7365,15 @@ describe('QueryBuilder', function() { }); }); - it('does crazy advanced inserts with clever raw use, #211', function() { - var q1 = qb() + it('does crazy advanced inserts with clever raw use, #211', () => { + const q1 = qb() .select(raw("'user'"), raw("'user@foo.com'")) .whereNotExists(function() { this.select(1) .from('recipients') .where('recipient_id', 1); }); - var q2 = qb() + const q2 = qb() .table('recipients') .insert(raw('(recipient_id, email) ?', [q1])); @@ -7399,7 +7399,7 @@ describe('QueryBuilder', function() { }); }); - it('supports capitalized operators', function() { + it('supports capitalized operators', () => { testsql( qb() .select('*') @@ -7426,7 +7426,7 @@ describe('QueryBuilder', function() { ); }); - it('supports POSIX regex operators in Postgres', function() { + it('supports POSIX regex operators in Postgres', () => { testsql( qb() .select('*') @@ -7445,7 +7445,7 @@ describe('QueryBuilder', function() { ); }); - it('supports NOT ILIKE operator in Postgres', function() { + it('supports NOT ILIKE operator in Postgres', () => { testsql( qb() .select('*') @@ -7464,8 +7464,8 @@ describe('QueryBuilder', function() { ); }); - it('throws if you try to use an invalid operator', function() { - expect(function() { + it('throws if you try to use an invalid operator', () => { + expect(() => { qb() .select('*') .where('id', 'isnt', 1) @@ -7473,11 +7473,11 @@ describe('QueryBuilder', function() { }).to.throw('The operator "isnt" is not permitted'); }); - it('throws if you try to use an invalid operator in an inserted statement', function() { - var obj = qb() + it('throws if you try to use an invalid operator in an inserted statement', () => { + const obj = qb() .select('*') .where('id', 'isnt', 1); - expect(function() { + expect(() => { qb() .select('*') .from('users') @@ -7486,7 +7486,7 @@ describe('QueryBuilder', function() { }).to.throw('The operator "isnt" is not permitted'); }); - it('#287 - wraps correctly for arrays', function() { + it('#287 - wraps correctly for arrays', () => { // arrays only work for postgres testsql( qb() @@ -7499,11 +7499,6 @@ describe('QueryBuilder', function() { 'select * from `value` inner join `table` on `table`.`array_column[1]` = ?', bindings: [1], }, - mssql: { - sql: - 'select * from [value] inner join [table] on [table].[array_column[1]] = ?', - bindings: [1], - }, pg: { sql: 'select * from "value" inner join "table" on "table"."array_column"[1] = ?', @@ -7518,7 +7513,7 @@ describe('QueryBuilder', function() { ); }); - it('allows wrap on raw to wrap in parens and alias', function() { + it('allows wrap on raw to wrap in parens and alias', () => { testsql( qb() .select( @@ -7562,7 +7557,7 @@ describe('QueryBuilder', function() { ); }); - it('allows select as syntax', function() { + it('allows select as syntax', () => { testsql( qb() .select( @@ -7606,7 +7601,7 @@ describe('QueryBuilder', function() { ); }); - it('allows function for subselect column', function() { + it('allows function for subselect column', () => { testsql( qb() .select('e.lastname', 'e.salary') @@ -7648,7 +7643,7 @@ describe('QueryBuilder', function() { ); }); - it('allows first as syntax', function() { + it('allows first as syntax', () => { testsql( qb() .select( @@ -7688,8 +7683,8 @@ describe('QueryBuilder', function() { ); }); - it('supports arbitrarily nested raws', function() { - var chain = qb() + it('supports arbitrarily nested raws', () => { + const chain = qb() .select('*') .from('places') .where( @@ -7729,7 +7724,7 @@ describe('QueryBuilder', function() { }); }); - it('has joinRaw for arbitrary join clauses', function() { + it('has joinRaw for arbitrary join clauses', () => { testsql( qb() .select('*') @@ -7761,7 +7756,7 @@ describe('QueryBuilder', function() { ); }); - it('allows a raw query in the second param', function() { + it('allows a raw query in the second param', () => { testsql( qb() .select('*') @@ -7793,7 +7788,7 @@ describe('QueryBuilder', function() { ); }); - it('allows join "using"', function() { + it('allows join "using"', () => { testsql( qb() .select('*') @@ -7847,7 +7842,7 @@ describe('QueryBuilder', function() { ); }); - it('allows sub-query function on insert, #427', function() { + it('allows sub-query function on insert, #427', () => { testsql( qb() .into('votes') @@ -7877,7 +7872,7 @@ describe('QueryBuilder', function() { ); }); - it('allows sub-query chain on insert, #427', function() { + it('allows sub-query chain on insert, #427', () => { testsql( qb() .into('votes') @@ -7912,7 +7907,7 @@ describe('QueryBuilder', function() { ); }); - it('allows for raw values in join, #441', function() { + it('allows for raw values in join, #441', () => { testsql( qb() .select('A.nid AS id') @@ -7955,7 +7950,7 @@ describe('QueryBuilder', function() { ); }); - it('allows insert values of sub-select without raw, #627', function() { + it('allows insert values of sub-select without raw, #627', () => { testsql( qb() .table('entries') @@ -7991,8 +7986,8 @@ describe('QueryBuilder', function() { ); }); - it('correctly orders parameters when selecting from subqueries, #704', function() { - var subquery = qb() + it('correctly orders parameters when selecting from subqueries, #704', () => { + const subquery = qb() .select(raw('? as f', ['inner raw select'])) .as('g'); testsql( @@ -8030,7 +8025,7 @@ describe('QueryBuilder', function() { ); }); - it('escapes queries properly, #737', function() { + it('escapes queries properly, #737', () => { testsql( qb() .select('id","name', 'id`name') @@ -8056,7 +8051,7 @@ describe('QueryBuilder', function() { ); }); - it('has a fromJS method for json construction of queries', function() { + it('has a fromJS method for json construction of queries', () => { testsql( qb().fromJS({ select: '*', @@ -8091,10 +8086,10 @@ describe('QueryBuilder', function() { ); }); - it('has a modify method which accepts a function that can modify the query', function() { + it('has a modify method which accepts a function that can modify the query', () => { // arbitrary number of arguments can be passed to `.modify(queryBuilder, ...)`, // builder is bound to `this` - var withBars = function(queryBuilder, table, fk) { + const withBars = function(queryBuilder, table, fk) { if (!this || this !== queryBuilder) { throw 'Expected query builder passed as first argument and bound as `this` context'; } @@ -8127,12 +8122,12 @@ describe('QueryBuilder', function() { ); }); - it('Allows for empty where #749', function() { + it('Allows for empty where #749', () => { testsql( qb() .select('foo') .from('tbl') - .where(function() {}), + .where(() => {}), { mysql: 'select `foo` from `tbl`', mssql: 'select [foo] from [tbl]', @@ -8141,7 +8136,7 @@ describe('QueryBuilder', function() { ); }); - it('escapes single quotes properly', function() { + it('escapes single quotes properly', () => { testquery( qb() .select('*') @@ -8154,7 +8149,7 @@ describe('QueryBuilder', function() { ); }); - it('escapes double quotes property', function() { + it('escapes double quotes property', () => { testquery( qb() .select('*') @@ -8166,7 +8161,7 @@ describe('QueryBuilder', function() { ); }); - it('escapes backslashes properly', function() { + it('escapes backslashes properly', () => { testquery( qb() .select('*') @@ -8178,7 +8173,7 @@ describe('QueryBuilder', function() { ); }); - it('allows join without operator and with value 0 #953', function() { + it('allows join without operator and with value 0 #953', () => { testsql( qb() .select('*') @@ -8201,7 +8196,7 @@ describe('QueryBuilder', function() { ); }); - it('allows join with operator and with value 0 #953', function() { + it('allows join with operator and with value 0 #953', () => { testsql( qb() .select('*') @@ -8224,8 +8219,8 @@ describe('QueryBuilder', function() { ); }); - it('where with date object', function() { - var date = new Date(); + it('where with date object', () => { + const date = new Date(); testsql( qb() .select('*') @@ -8252,8 +8247,8 @@ describe('QueryBuilder', function() { ); }); - it('raw where with date object', function() { - var date = new Date(); + it('raw where with date object', () => { + const date = new Date(); testsql( qb() .select('*') @@ -8280,27 +8275,25 @@ describe('QueryBuilder', function() { ); }); - it('#965 - .raw accepts Array and Non-Array bindings', function() { - var expected = function(fieldName, expectedBindings) { - return { - mysql: { - sql: 'select * from `users` where ' + fieldName + ' = ?', - bindings: expectedBindings, - }, - mssql: { - sql: 'select * from [users] where ' + fieldName + ' = ?', - bindings: expectedBindings, - }, - pg: { - sql: 'select * from "users" where ' + fieldName + ' = ?', - bindings: expectedBindings, - }, - 'pg-redshift': { - sql: 'select * from "users" where ' + fieldName + ' = ?', - bindings: expectedBindings, - }, - }; - }; + it('#965 - .raw accepts Array and Non-Array bindings', () => { + const expected = (fieldName, expectedBindings) => ({ + mysql: { + sql: 'select * from `users` where ' + fieldName + ' = ?', + bindings: expectedBindings, + }, + mssql: { + sql: 'select * from [users] where ' + fieldName + ' = ?', + bindings: expectedBindings, + }, + pg: { + sql: 'select * from "users" where ' + fieldName + ' = ?', + bindings: expectedBindings, + }, + 'pg-redshift': { + sql: 'select * from "users" where ' + fieldName + ' = ?', + bindings: expectedBindings, + }, + }); //String testsql( @@ -8335,8 +8328,8 @@ describe('QueryBuilder', function() { ); //Date - var date = new Date(2016, 0, 5, 10, 19, 30, 599); - var sqlUpdTime = '2016-01-05 10:19:30.599'; + const date = new Date(2016, 0, 5, 10, 19, 30, 599); + const sqlUpdTime = '2016-01-05 10:19:30.599'; testsql( qb() .select('*') @@ -8363,7 +8356,7 @@ describe('QueryBuilder', function() { ); }); - it('#1118 orWhere({..}) generates or (and - and - and)', function() { + it('#1118 orWhere({..}) generates or (and - and - and)', () => { testsql( qb() .select('*') @@ -8398,7 +8391,7 @@ describe('QueryBuilder', function() { ); }); - it('#1228 Named bindings', function() { + it('#1228 Named bindings', () => { testsql( qb() .select('*') @@ -8424,18 +8417,18 @@ describe('QueryBuilder', function() { } ); - var namedBindings = { + const namedBindings = { name: 'users.name', thisGuy: 'Bob', otherGuy: 'Jay', }; //Had to do it this way as the 'raw' statement's .toQuery is called before testsql, meaning mssql and other dialects would always get the output of qb() default client //as MySQL, which means testing the query per dialect won't work. [users].[name] would be `users`.`name` for mssql which is incorrect. - var mssql = clients.mssql; - var mysql = clients.mysql; - var sqlite3 = clients.sqlite3; + const mssql = clients.mssql; + const mysql = clients.mysql; + const sqlite3 = clients.sqlite3; - var mssqlQb = mssql + const mssqlQb = mssql .queryBuilder() .select('*') .from('users') @@ -8443,7 +8436,7 @@ describe('QueryBuilder', function() { mssql.raw(':name: = :thisGuy or :name: = :otherGuy', namedBindings) ) .toSQL(); - var mysqlQb = mysql + const mysqlQb = mysql .queryBuilder() .select('*') .from('users') @@ -8451,7 +8444,7 @@ describe('QueryBuilder', function() { mysql.raw(':name: = :thisGuy or :name: = :otherGuy', namedBindings) ) .toSQL(); - var sqliteQb = sqlite3 + const sqliteQb = sqlite3 .queryBuilder() .select('*') .from('users') @@ -8476,7 +8469,7 @@ describe('QueryBuilder', function() { expect(sqliteQb.bindings).to.deep.equal(['Bob', 'Jay']); }); - it('#1268 - valueForUndefined should be in toSQL(QueryCompiler)', function() { + it('#1268 - valueForUndefined should be in toSQL(QueryCompiler)', () => { testsql( qb() .insert([ @@ -8513,7 +8506,7 @@ describe('QueryBuilder', function() { } ); - expect(function() { + expect(() => { clients.sqlite3 .queryBuilder() .insert([{ id: void 0 }]) @@ -8521,7 +8514,7 @@ describe('QueryBuilder', function() { .toString(); }).to.throw(TypeError); - expect(function() { + expect(() => { clientsWithNullAsDefault.sqlite3 .queryBuilder() .insert([{ id: void 0 }]) @@ -8530,7 +8523,7 @@ describe('QueryBuilder', function() { }).to.not.throw(TypeError); }); - it('#1402 - raw should take "not" into consideration in querybuilder', function() { + it('#1402 - raw should take "not" into consideration in querybuilder', () => { testsql( qb() .from('testtable') @@ -8560,63 +8553,63 @@ describe('QueryBuilder', function() { ); }); - it('Any undefined binding in a SELECT query should throw an error', function() { - var qbuilders = [ + it('Any undefined binding in a SELECT query should throw an error', () => { + const qbuilders = [ { builder: qb() .from('accounts') .where({ Login: void 0 }) .select(), - undefinedColumns: ['Login'] + undefinedColumns: ['Login'], }, { builder: qb() .from('accounts') .where('Login', void 0) .select(), - undefinedColumns: ['Login'] + undefinedColumns: ['Login'], }, { builder: qb() .from('accounts') .where('Login', '>=', void 0) .select(), - undefinedColumns: ['Login'] + undefinedColumns: ['Login'], }, { builder: qb() .from('accounts') .whereIn('Login', ['test', 'val', void 0]) .select(), - undefinedColumns: ['Login'] + undefinedColumns: ['Login'], }, { builder: qb() .from('accounts') .where({ Login: ['1', '2', '3', void 0] }), - undefinedColumns: ['Login'] + undefinedColumns: ['Login'], }, { builder: qb() .from('accounts') .where({ Login: { Test: '123', Value: void 0 } }), - undefinedColumns: ['Login'] + undefinedColumns: ['Login'], }, { builder: qb() .from('accounts') .where({ Login: ['1', ['2', [void 0]]] }), - undefinedColumns: ['Login'] + undefinedColumns: ['Login'], }, { builder: qb() .from('accounts') .update({ test: '1', test2: void 0 }) .where({ abc: 'test', cba: void 0 }), - undefinedColumns: ['cba'] - } + undefinedColumns: ['cba'], + }, ]; - qbuilders.forEach(function({ builder, undefinedColumns}) { + qbuilders.forEach(({ builder, undefinedColumns }) => { try { //Must be present, but makes no difference since it throws. testsql(builder, { @@ -8655,15 +8648,21 @@ describe('QueryBuilder', function() { }); }); - it('Any undefined binding in a RAW query should throw an error', function() { - var raws = [ + it('Any undefined binding in a RAW query should throw an error', () => { + const raws = [ { query: raw('?', [undefined]), undefinedIndices: [0] }, - { query: raw(':col = :value', { col: 'test', value: void 0 }), undefinedIndices: ['value'] }, + { + query: raw(':col = :value', { col: 'test', value: void 0 }), + undefinedIndices: ['value'], + }, { query: raw('? = ?', ['test', void 0]), undefinedIndices: [1] }, - { query: raw('? = ?', ['test', { test: void 0 }]), undefinedIndices: [1] }, + { + query: raw('? = ?', ['test', { test: void 0 }]), + undefinedIndices: [1], + }, { query: raw('?', [['test', void 0]]), undefinedIndices: [0] }, ]; - raws.forEach(function({ query, undefinedIndices }) { + raws.forEach(({ query, undefinedIndices }) => { try { query.toSQL(); expect(true).to.equal( @@ -8671,17 +8670,18 @@ describe('QueryBuilder', function() { 'Expected to throw error in compilation about undefined bindings.' ); } catch (error) { - var expectedErrorMessageContains = - `Undefined binding(s) detected for keys [${undefinedIndices.join(', ')}] when compiling RAW query:`; + const expectedErrorMessageContains = `Undefined binding(s) detected for keys [${undefinedIndices.join( + ', ' + )}] when compiling RAW query:`; expect(error.message).to.contain(expectedErrorMessageContains); //This test is not for asserting correct queries } }); }); - it('Support escaping of named bindings', function() { - var namedBindings = { a: 'foo', b: 'bar', c: 'baz' }; + it('Support escaping of named bindings', () => { + const namedBindings = { a: 'foo', b: 'bar', c: 'baz' }; - var raws = [ + const raws = [ [ raw(':a: = :b OR :c', namedBindings), '"foo" = ? OR ?', @@ -8701,17 +8701,17 @@ describe('QueryBuilder', function() { [raw('\\:a: = \\:b OR \\:c', namedBindings), ':a: = :b OR :c', []], ]; - raws.forEach(function(raw) { - var result = raw[0].toSQL(); + raws.forEach((raw) => { + const result = raw[0].toSQL(); expect(result.sql).to.equal(raw[1]); expect(result.bindings).to.deep.equal(raw[2]); }); }); - it('Respect casting with named bindings', function() { - var namedBindings = { a: 'foo', b: 'bar', c: 'baz' }; + it('Respect casting with named bindings', () => { + const namedBindings = { a: 'foo', b: 'bar', c: 'baz' }; - var raws = [ + const raws = [ [ raw(':a: = :b::TEXT OR :c', namedBindings), '"foo" = ?::TEXT OR ?', @@ -8749,14 +8749,14 @@ describe('QueryBuilder', function() { ], ]; - raws.forEach(function(raw) { - var result = raw[0].toSQL(); + raws.forEach((raw) => { + const result = raw[0].toSQL(); expect(result.sql).to.equal(raw[1]); expect(result.bindings).to.deep.equal(raw[2]); }); }); - it('query \\\\? escaping', function() { + it('query \\\\? escaping', () => { testquery( qb() .select('*') @@ -8772,7 +8772,7 @@ describe('QueryBuilder', function() { ); }); - it('operator transformation', function() { + it('operator transformation', () => { // part of common base code, no need to test on every dialect testsql( qb() @@ -8803,7 +8803,7 @@ describe('QueryBuilder', function() { ); }); - it("wrapped 'with' clause select", function() { + it("wrapped 'with' clause select", () => { testsql( qb() .with('withClause', function() { @@ -8826,7 +8826,7 @@ describe('QueryBuilder', function() { ); }); - it("wrapped 'with' clause insert", function() { + it("wrapped 'with' clause insert", () => { testsql( qb() .with('withClause', function() { @@ -8845,7 +8845,7 @@ describe('QueryBuilder', function() { ); }); - it("wrapped 'with' clause multiple insert", function() { + it("wrapped 'with' clause multiple insert", () => { testsql( qb() .with('withClause', function() { @@ -8883,7 +8883,7 @@ describe('QueryBuilder', function() { ); }); - it("wrapped 'with' clause update", function() { + it("wrapped 'with' clause update", () => { testsql( qb() .with('withClause', function() { @@ -8903,7 +8903,7 @@ describe('QueryBuilder', function() { ); }); - it("wrapped 'with' clause delete", function() { + it("wrapped 'with' clause delete", () => { testsql( qb() .with('withClause', function() { @@ -8923,7 +8923,7 @@ describe('QueryBuilder', function() { ); }); - it("raw 'with' clause", function() { + it("raw 'with' clause", () => { testsql( qb() .with('withRawClause', raw('select "foo" as "baz" from "users"')) @@ -8944,7 +8944,7 @@ describe('QueryBuilder', function() { ); }); - it("chained wrapped 'with' clause", function() { + it("chained wrapped 'with' clause", () => { testsql( qb() .with('firstWithClause', function() { @@ -8970,7 +8970,7 @@ describe('QueryBuilder', function() { ); }); - it("nested 'with' clause", function() { + it("nested 'with' clause", () => { testsql( qb() .with('withClause', function() { @@ -8999,7 +8999,7 @@ describe('QueryBuilder', function() { ); }); - it("nested 'with' clause with bindings", function() { + it("nested 'with' clause with bindings", () => { testsql( qb() .with('withClause', function() { @@ -9046,7 +9046,7 @@ describe('QueryBuilder', function() { ); }); - it('should return dialect specific sql and bindings with toSQL().toNative()', function() { + it('should return dialect specific sql and bindings with toSQL().toNative()', () => { testNativeSql( qb() .from('table') @@ -9076,7 +9076,7 @@ describe('QueryBuilder', function() { ); }); - it("nested and chained wrapped 'with' clause", function() { + it("nested and chained wrapped 'with' clause", () => { testsql( qb() .with('firstWithClause', function() { @@ -9114,7 +9114,7 @@ describe('QueryBuilder', function() { ); }); - it("nested and chained wrapped 'withRecursive' clause", function() { + it("nested and chained wrapped 'withRecursive' clause", () => { testsql( qb() .withRecursive('firstWithClause', function() { @@ -9273,7 +9273,7 @@ describe('QueryBuilder', function() { }); }); - it('#1710, properly escapes arrays in where clauses in postgresql', function() { + it('#1710, properly escapes arrays in where clauses in postgresql', () => { testquery( qb() .select('*') @@ -9305,11 +9305,9 @@ describe('QueryBuilder', function() { ); }); - it('#2003, properly escapes objects with toPostgres specialization', function() { + it('#2003, properly escapes objects with toPostgres specialization', () => { function TestObject() {} - TestObject.prototype.toPostgres = function() { - return 'foobar'; - }; + TestObject.prototype.toPostgres = () => 'foobar'; testquery( qb() .table('sometable') @@ -9320,7 +9318,7 @@ describe('QueryBuilder', function() { ); }); - it('Throws error if .update() results in faulty sql due to no data', function() { + it('Throws error if .update() results in faulty sql due to no data', () => { try { qb() .table('sometable') @@ -9334,7 +9332,7 @@ describe('QueryBuilder', function() { } }); - it('Throws error if .first() is called on update', function() { + it('Throws error if .first() is called on update', () => { try { qb() .table('sometable') @@ -9350,7 +9348,7 @@ describe('QueryBuilder', function() { } }); - it('Throws error if .first() is called on insert', function() { + it('Throws error if .first() is called on insert', () => { try { qb() .table('sometable') @@ -9366,7 +9364,7 @@ describe('QueryBuilder', function() { } }); - it('Throws error if .first() is called on delete', function() { + it('Throws error if .first() is called on delete', () => { try { qb() .table('sometable') @@ -9380,8 +9378,8 @@ describe('QueryBuilder', function() { } }); - describe('knex.ref()', function() { - it('Can be used as parameter in where-clauses', function() { + describe('knex.ref()', () => { + it('Can be used as parameter in where-clauses', () => { testquery( qb() .table('sometable') @@ -9402,7 +9400,7 @@ describe('QueryBuilder', function() { ); }); - it('Can use .as() for alias', function() { + it('Can use .as() for alias', () => { testquery( qb() .table('sometable') @@ -9419,7 +9417,7 @@ describe('QueryBuilder', function() { }); }); - it('Can call knex.select(0)', function() { + it('Can call knex.select(0)', () => { testquery(qb().select(0), { pg: 'select 0', mysql: 'select 0', @@ -9429,10 +9427,10 @@ describe('QueryBuilder', function() { }); }); - it('should warn to user when use `.returning()` function in MySQL', function() { - var loggerConfigForTestingWarnings = { + it('should warn to user when use `.returning()` function in MySQL', () => { + const loggerConfigForTestingWarnings = { log: { - warn: function(message) { + warn: (message) => { if ( message === '.returning() is not supported by mysql and will not have any effect.' @@ -9443,11 +9441,11 @@ describe('QueryBuilder', function() { }, }; - var mysqlClientForWarnings = new MySQL_Client( + const mysqlClientForWarnings = new MySQL_Client( Object.assign({ client: 'mysql' }, loggerConfigForTestingWarnings) ); - expect(function() { + expect(() => { testsql( qb() .into('users') @@ -9466,10 +9464,10 @@ describe('QueryBuilder', function() { }).to.throw(Error); }); - it('should warn to user when use `.returning()` function in SQLite3', function() { - var loggerConfigForTestingWarnings = { + it('should warn to user when use `.returning()` function in SQLite3', () => { + const loggerConfigForTestingWarnings = { log: { - warn: function(message) { + warn: (message) => { if ( message === '.returning() is not supported by sqlite3 and will not have any effect.' @@ -9480,11 +9478,11 @@ describe('QueryBuilder', function() { }, }; - var sqlite3ClientForWarnings = new SQLite3_Client( + const sqlite3ClientForWarnings = new SQLite3_Client( Object.assign({ client: 'sqlite3' }, loggerConfigForTestingWarnings) ); - expect(function() { + expect(() => { testsql( qb() .into('users') @@ -9503,7 +9501,7 @@ describe('QueryBuilder', function() { }).to.throw(Error); }); - it('join with subquery using .withSchema', function() { + it('join with subquery using .withSchema', () => { testsql( qb() .from('departments') diff --git a/test/unit/schema/mssql.js b/test/unit/schema/mssql.js index 9829412e13..51fb4cf7cc 100644 --- a/test/unit/schema/mssql.js +++ b/test/unit/schema/mssql.js @@ -1,7 +1,6 @@ -/*global expect*/ - 'use strict'; +const expect = require('chai').expect; const sinon = require('sinon'); const MSSQL_Client = require('../../../lib/dialects/mssql'); const client = new MSSQL_Client({ client: 'mssql' });