loopback-connector
Advanced tools
Comparing version 2.3.0 to 2.4.0
@@ -0,1 +1,39 @@ | ||
2016-06-29, Version 2.4.0 | ||
========================= | ||
* update copyright notices and license (Ryan Graham) | ||
* Fix linting errors (Amir Jafarian) | ||
* Auto-update by eslint --fix (Amir Jafarian) | ||
* Add eslint infrastructure (Amir Jafarian) | ||
* fixed build of where statement when filter contains non-existing column (Maor Hayun) | ||
* change replace to replaceById (Amir Jafarian) | ||
* Remove underscore from _buildReplaceFields (Amir Jafarian) | ||
* Change _buildReplace to buildReplace (Amir Jafarian) | ||
* Change _buildUpdate to buildUpdate (Amir Jafarian) | ||
* Apply feedback (Amir Jafarian) | ||
* call execute directly for _replace (Amir Jafarian) | ||
* Implement replaceAttributes (Amir Jafarian) | ||
* Removed filterWhere option (eugene-frb) | ||
* 1. Error logging. 2. Options argument of model's include function to pass filter.where object. (eugene-frb) | ||
* Refer to licenses with a link (Sam Roberts) | ||
* Fixed typo. (Matteo Padovano) | ||
* Use strongloop conventions for licensing (Sam Roberts) | ||
2015-07-29, Version 2.3.0 | ||
@@ -2,0 +40,0 @@ ========================= |
@@ -0,1 +1,6 @@ | ||
// Copyright IBM Corp. 2014,2016. All Rights Reserved. | ||
// Node module: loopback-connector | ||
// This file is licensed under the MIT License. | ||
// License text available at https://opensource.org/licenses/MIT | ||
exports.Connector = require('./lib/connector'); | ||
@@ -2,0 +7,0 @@ // Set up SqlConnector as an alias to SQLConnector |
@@ -0,1 +1,6 @@ | ||
// Copyright IBM Corp. 2014,2016. All Rights Reserved. | ||
// Node module: loopback-connector | ||
// This file is licensed under the MIT License. | ||
// License text available at https://opensource.org/licenses/MIT | ||
var debug = require('debug')('loopback:connector'); | ||
@@ -64,3 +69,3 @@ | ||
isRelational: this.isRelational(), | ||
schemaForSettings: {} | ||
schemaForSettings: {}, | ||
}; | ||
@@ -263,3 +268,3 @@ } | ||
return this[methodOrPropertyName]; | ||
} | ||
}, | ||
}); | ||
@@ -266,0 +271,0 @@ } |
@@ -0,1 +1,6 @@ | ||
// Copyright IBM Corp. 2015,2016. All Rights Reserved. | ||
// Node module: loopback-connector | ||
// This file is licensed under the MIT License. | ||
// License text available at https://opensource.org/licenses/MIT | ||
var assert = require('assert'); | ||
@@ -58,3 +63,3 @@ var PLACEHOLDER = '?'; | ||
sql: this.sql, | ||
params: this.params | ||
params: this.params, | ||
}; | ||
@@ -61,0 +66,0 @@ }; |
224
lib/sql.js
@@ -0,1 +1,6 @@ | ||
// Copyright IBM Corp. 2014,2016. All Rights Reserved. | ||
// Node module: loopback-connector | ||
// This file is licensed under the MIT License. | ||
// License text available at https://opensource.org/licenses/MIT | ||
var util = require('util'); | ||
@@ -11,2 +16,4 @@ var async = require('async'); | ||
function NOOP() {} | ||
/** | ||
@@ -404,8 +411,13 @@ * Base class for connectors that connect to relational databases using SQL | ||
sql: sql, | ||
params: params | ||
params: params, | ||
}, | ||
options: options | ||
options: options, | ||
}; | ||
this.notifyObserversAround('execute', context, function(context, done) { | ||
self.executeSQL(context.req.sql, context.req.params, context.options, function(err, info) { | ||
self.executeSQL(context.req.sql, context.req.params, context.options, | ||
function(err, info) { | ||
if (err) { | ||
debug('Error: %j %j %j', err, context.req.sql, context.req.params); | ||
} | ||
if (!err && info != null) { | ||
@@ -492,3 +504,3 @@ context.res = info; | ||
offset: 0, | ||
order: [idName] | ||
order: [idName], | ||
}); | ||
@@ -556,10 +568,4 @@ selectStmt = this.parameterize(selectStmt); | ||
SQLConnector.prototype.destroyAll = function(model, where, options, cb) { | ||
var self = this; | ||
var stmt = this.buildDelete(model, where, options); | ||
this.execute(stmt.sql, stmt.params, options, function(err, info) { | ||
var affectedRows = self.getCountForAffectedRows(model, info); | ||
if (cb) { | ||
cb(err, {count: affectedRows}); | ||
} | ||
}); | ||
this._executeAlteringQuery(model, stmt.sql, stmt.params, options, cb || NOOP); | ||
}; | ||
@@ -585,5 +591,31 @@ | ||
SQLConnector.prototype.updateAttributes = function(model, id, data, options, cb) { | ||
if (!isIdValuePresent(id, cb)) { | ||
return; | ||
} | ||
if (!isIdValuePresent(id, cb)) return; | ||
var where = this._buildWhereObjById(model, id, data); | ||
this.updateAll(model, where, data, options, cb); | ||
}; | ||
/** | ||
* Replace attributes for a given model instance | ||
* @param {String} model The model name | ||
* @param {*} id The id value | ||
* @param {Object} data The model data instance containing all properties to | ||
* be replaced | ||
* @param {Object} options Options object | ||
* @param {Function} cb The callback function | ||
* @private | ||
*/ | ||
SQLConnector.prototype.replaceById = function(model, id, data, options, cb) { | ||
if (!isIdValuePresent(id, cb)) return; | ||
var where = this._buildWhereObjById(model, id, data); | ||
this._replace(model, where, data, options, cb); | ||
}; | ||
/* | ||
* @param model The model name. | ||
* @param id The instance ID. | ||
* @param {Object} data The data Object. | ||
* @returns {Object} where The where object for a spcific instance. | ||
* @private | ||
*/ | ||
SQLConnector.prototype._buildWhereObjById = function(model, id, data) { | ||
var idName = this.idName(model); | ||
@@ -593,3 +625,3 @@ delete data[idName]; | ||
where[idName] = id; | ||
this.updateAll(model, where, data, options, cb); | ||
return where; | ||
}; | ||
@@ -608,2 +640,27 @@ | ||
var fields = this.buildFieldsForUpdate(model, data); | ||
return this._constructUpdateQuery(model, where, fields); | ||
}; | ||
/** | ||
* Build the UPDATE statement for replacing | ||
* @param {String} model The model name | ||
* @param {Object} where The where object | ||
* @param {Object} data The data to be changed | ||
* @param {Object} options The options object | ||
* @param {Function} cb The callback function | ||
* @returns {ParameterizedSQL} The UPDATE SQL statement for replacing fields | ||
*/ | ||
SQLConnector.prototype.buildReplace = function(model, where, data, options) { | ||
var fields = this.buildFieldsForReplace(model, data); | ||
return this._constructUpdateQuery(model, where, fields); | ||
}; | ||
/* | ||
* @param model The model name. | ||
* @param {} where The where object. | ||
* @param {Object} field The parameterizedSQL fileds. | ||
* @returns {Object} update query Constructed update query. | ||
* @private | ||
*/ | ||
SQLConnector.prototype._constructUpdateQuery = function(model, where, fields) { | ||
var updateClause = new ParameterizedSQL('UPDATE ' + this.tableEscaped(model)); | ||
@@ -625,14 +682,31 @@ var whereClause = this.buildWhere(model, where); | ||
SQLConnector.prototype.update = function(model, where, data, options, cb) { | ||
var stmt = this.buildUpdate(model, where, data, options); | ||
this._executeAlteringQuery(model, stmt.sql, stmt.params, options, cb || NOOP); | ||
}; | ||
/** | ||
* Replace all instances that match the where clause with the given data | ||
* @param {String} model The model name | ||
* @param {Object} where The where object | ||
* @param {Object} data The property/value object representing changes | ||
* to be made | ||
* @param {Object} options The options object | ||
* @param {Function} cb The callback function | ||
*/ | ||
SQLConnector.prototype._replace = function(model, where, data, options, cb) { | ||
var stmt = this.buildReplace(model, where, data, options); | ||
this.execute(stmt.sql, stmt.params, options, cb); | ||
}; | ||
SQLConnector.prototype._executeAlteringQuery = function(model, sql, params, options, cb) { | ||
var self = this; | ||
var stmt = this.buildUpdate(model, where, data, options); | ||
this.execute(stmt.sql, stmt.params, options, function(err, info) { | ||
this.execute(sql, params, options, function(err, info) { | ||
var affectedRows = self.getCountForAffectedRows(model, info); | ||
if (cb) { | ||
cb(err, {count: affectedRows}); | ||
} | ||
cb(err, { count: affectedRows }); | ||
}); | ||
}; | ||
// Alias to `update`. Juggler checks `update` only. | ||
// Alias to `update` and `replace`. Juggler checks `update` and `replace` only. | ||
Connector.defineAliases(SQLConnector.prototype, 'update', ['updateAll']); | ||
Connector.defineAliases(SQLConnector.prototype, 'replace', ['replaceAll']); | ||
@@ -661,3 +735,4 @@ /** | ||
*/ | ||
SQLConnector.prototype.buildExpression = function(columnName, operator, columnValue, propertyValue) { | ||
SQLConnector.prototype.buildExpression = | ||
function(columnName, operator, columnValue, propertyValue) { | ||
function buildClause(columnValue, separator, grouping) { | ||
@@ -762,9 +837,11 @@ var values = []; | ||
var stmtForClause = self._buildWhere(model, clauses[i]); | ||
stmtForClause.sql = '(' + stmtForClause.sql + ')'; | ||
branchParams = branchParams.concat(stmtForClause.params); | ||
branches.push(stmtForClause.sql); | ||
if (stmtForClause.sql) { | ||
stmtForClause.sql = '(' + stmtForClause.sql + ')'; | ||
branchParams = branchParams.concat(stmtForClause.params); | ||
branches.push(stmtForClause.sql); | ||
} | ||
} | ||
stmt.merge({ | ||
sql: branches.join(' ' + key.toUpperCase() + ' '), | ||
params: branchParams | ||
params: branchParams, | ||
}); | ||
@@ -776,2 +853,9 @@ whereStmts.push(stmt); | ||
} | ||
var p = props[key]; | ||
if (p == null) { | ||
// Unknown property, ignore it | ||
debug('Unknown property %s is skipped for model %s', key, model); | ||
continue; | ||
} | ||
/* eslint-disable one-var */ | ||
var columnName = self.columnEscaped(model, key); | ||
@@ -781,2 +865,3 @@ var expression = where[key]; | ||
var sqlExp; | ||
/* eslint-enable one-var */ | ||
if (expression === null || expression === undefined) { | ||
@@ -793,6 +878,6 @@ stmt.merge(columnName + ' IS NULL'); | ||
for (var j = 0, m = expression.length; j < m; j++) { | ||
columnValue.push(this.toColumnValue(props[key], expression[j])); | ||
columnValue.push(this.toColumnValue(p, expression[j])); | ||
} | ||
} else { | ||
columnValue.push(this.toColumnValue(props[key], expression)); | ||
columnValue.push(this.toColumnValue(p, expression)); | ||
} | ||
@@ -819,10 +904,10 @@ if (operator === 'between') { | ||
} else { | ||
columnValue = this.toColumnValue(props[key], expression); | ||
columnValue = this.toColumnValue(p, expression); | ||
} | ||
sqlExp = self.buildExpression( | ||
columnName, operator, columnValue, props[key]); | ||
columnName, operator, columnValue, p); | ||
stmt.merge(sqlExp); | ||
} else { | ||
// The expression is the field value, not a condition | ||
columnValue = self.toColumnValue(props[key], expression); | ||
columnValue = self.toColumnValue(p, expression); | ||
if (columnValue === null) { | ||
@@ -836,3 +921,3 @@ stmt.merge(columnName + ' IS NULL'); | ||
sql: columnName + '=?', | ||
params: [columnValue] | ||
params: [columnValue], | ||
}); | ||
@@ -852,3 +937,3 @@ } | ||
sql: sqls.join(' AND '), | ||
params: params | ||
params: params, | ||
}); | ||
@@ -892,9 +977,33 @@ return whereStmt; | ||
SQLConnector.prototype.buildFields = function(model, data, excludeIds) { | ||
var keys = Object.keys(data); | ||
return this._buildFieldsForKeys(model, data, keys, excludeIds); | ||
}; | ||
/** | ||
* Build an array of fields for the replace database operation | ||
* @param {String} model Model name | ||
* @param {Object} data Model data object | ||
* @param {Boolean} excludeIds Exclude id properties or not, default to false | ||
* @returns {{names: Array, values: Array, properties: Array}} | ||
*/ | ||
SQLConnector.prototype.buildReplaceFields = function(model, data, excludeIds) { | ||
var props = this.getModelDefinition(model).properties; | ||
var keys = Object.keys(props); | ||
return this._buildFieldsForKeys(model, data, keys, excludeIds); | ||
}; | ||
/* | ||
* @param {String} model The model name. | ||
* @returns {Object} data The model data object. | ||
* @returns {Array} keys The key fields for which need to be built. | ||
* @param {Boolean} excludeIds Exclude id properties or not, default to false | ||
* @private | ||
*/ | ||
SQLConnector.prototype._buildFieldsForKeys = function(model, data, keys, excludeIds) { | ||
var props = this.getModelDefinition(model).properties; | ||
var fields = { | ||
names: [], // field names | ||
columnValues: [], // an array of ParameterizedSQL | ||
properties: [] // model properties | ||
properties: [], // model properties | ||
}; | ||
var props = this.getModelDefinition(model).properties; | ||
var keys = Object.keys(data); | ||
for (var i = 0, n = keys.length; i < n; i++) { | ||
@@ -908,6 +1017,6 @@ var key = keys[i]; | ||
} | ||
if (excludeIds && p.id) { | ||
continue; | ||
} | ||
var k = this.columnEscaped(model, key); | ||
@@ -929,7 +1038,7 @@ var v = this.toColumnValue(p, data[key]); | ||
/** | ||
* Build the SET clause for database update | ||
* @param {String} model Model na | ||
* @param {Object} data The model data object | ||
* @param {Boolean} excludeIds Exclude id properties or not, default to true | ||
* @returns {string} The list of fields for update | ||
* Build the SET clause for database update. | ||
* @param {String} model Model name. | ||
* @param {Object} data The model data object. | ||
* @param {Boolean} excludeIds Exclude id properties or not, default to true. | ||
* @returns {string} The list of fields for update query. | ||
*/ | ||
@@ -941,2 +1050,26 @@ SQLConnector.prototype.buildFieldsForUpdate = function(model, data, excludeIds) { | ||
var fields = this.buildFields(model, data, excludeIds); | ||
return this._constructUpdateParameterizedSQL(fields); | ||
}; | ||
/** | ||
* Build the SET clause for database replace through update query. | ||
* @param {String} model Model name. | ||
* @param {Object} data The model data object. | ||
* @param {Boolean} excludeIds Exclude id properties or not, default to true. | ||
* @returns {string} The list of fields for update query. | ||
*/ | ||
SQLConnector.prototype.buildFieldsForReplace = function(model, data, excludeIds) { | ||
if (excludeIds === undefined) { | ||
excludeIds = true; | ||
} | ||
var fields = this.buildReplaceFields(model, data, excludeIds); | ||
return this._constructUpdateParameterizedSQL(fields); | ||
}; | ||
/* | ||
* @param {Object} field The fileds. | ||
* @returns {Object} parameterizedSQL. | ||
* @private | ||
*/ | ||
SQLConnector.prototype._constructUpdateParameterizedSQL = function(fields) { | ||
var columns = new ParameterizedSQL(''); | ||
@@ -1019,3 +1152,2 @@ for (var i = 0, n = fields.names.length; i < n; i++) { | ||
if (filter) { | ||
if (filter.where) { | ||
@@ -1034,3 +1166,2 @@ var whereStmt = this.buildWhere(model, filter.where); | ||
} | ||
} | ||
@@ -1046,3 +1177,4 @@ return this.parameterize(selectStmt); | ||
*/ | ||
SQLConnector.prototype.fromRow = SQLConnector.prototype.fromDatabase = function(model, rowData) { | ||
SQLConnector.prototype.fromRow = SQLConnector.prototype.fromDatabase = | ||
function(model, rowData) { | ||
if (rowData == null) { | ||
@@ -1134,3 +1266,3 @@ return rowData; | ||
var filter = {limit: 1, offset: 0, order: idName, where: where}; | ||
var filter = { limit: 1, offset: 0, order: idName, where: where }; | ||
return this.all(model, filter, options, function(err, results) { | ||
@@ -1137,0 +1269,0 @@ cb(err, (results && results[0]) || null); |
@@ -0,1 +1,6 @@ | ||
// Copyright IBM Corp. 2015,2016. All Rights Reserved. | ||
// Node module: loopback-connector | ||
// This file is licensed under the MIT License. | ||
// License text available at https://opensource.org/licenses/MIT | ||
var assert = require('assert'); | ||
@@ -33,3 +38,3 @@ var util = require('util'); | ||
AFTER_ROLLBACK: 'after rollback', | ||
TIMEOUT: 'timeout' | ||
TIMEOUT: 'timeout', | ||
}; | ||
@@ -62,3 +67,3 @@ | ||
Transaction.begin = function(connector, options, cb) { | ||
if (typeof isolationLevel === 'function' && cb === undefined) { | ||
if (typeof options === 'function' && cb === undefined) { | ||
cb = options; | ||
@@ -68,3 +73,3 @@ options = {}; | ||
if (typeof options === 'string') { | ||
options = {isolationLevel: options}; | ||
options = { isolationLevel: options }; | ||
} | ||
@@ -71,0 +76,0 @@ var isolationLevel = options.isolationLevel || Transaction.READ_COMMITTED; |
{ | ||
"name": "loopback-connector", | ||
"version": "2.3.0", | ||
"version": "2.4.0", | ||
"description": "Building blocks for LoopBack connectors", | ||
@@ -16,9 +16,7 @@ "keywords": [ | ||
"scripts": { | ||
"pretest": "jshint .", | ||
"lint": "eslint .", | ||
"posttest": "npm run lint", | ||
"test": "mocha" | ||
}, | ||
"license": { | ||
"name": "Dual MIT/StrongLoop", | ||
"url": "https://github.com/strongloop/loopback-connector/blob/master/LICENSE" | ||
}, | ||
"license": "MIT", | ||
"dependencies": { | ||
@@ -30,3 +28,4 @@ "async": "^1.0.0", | ||
"chai": "~2.3.0", | ||
"jshint": "^2.7.0", | ||
"eslint": "^2.7.0", | ||
"eslint-config-loopback": "^1.0.0", | ||
"loopback-datasource-juggler": "^2.29.0", | ||
@@ -33,0 +32,0 @@ "mocha": "^2.2.5" |
@@ -0,1 +1,6 @@ | ||
// Copyright IBM Corp. 2014,2016. All Rights Reserved. | ||
// Node module: loopback-connector | ||
// This file is licensed under the MIT License. | ||
// License text available at https://opensource.org/licenses/MIT | ||
var expect = require('chai').expect; | ||
@@ -7,3 +12,3 @@ var testConnector = require('./connectors/test-sql-connector'); | ||
connector: testConnector, | ||
debug: true | ||
debug: true, | ||
}); | ||
@@ -47,3 +52,2 @@ | ||
}); | ||
}); |
@@ -0,1 +1,6 @@ | ||
// Copyright IBM Corp. 2014,2016. All Rights Reserved. | ||
// Node module: loopback-connector | ||
// This file is licensed under the MIT License. | ||
// License text available at https://opensource.org/licenses/MIT | ||
/* | ||
@@ -213,8 +218,7 @@ * A mockup connector that extends SQL connector | ||
transaction.connection.data[model] || []; | ||
transaction.connection.data[model].push({sql: sql, params: params}); | ||
transaction.connection.data[model].push({ sql: sql, params: params }); | ||
debug('INSERT', transaction.connection.data, sql, | ||
transaction.connection.name); | ||
callback(null, 1); | ||
} | ||
else { | ||
} else { | ||
debug('SELECT', transaction.connection.data, sql, | ||
@@ -227,3 +231,3 @@ transaction.connection.name); | ||
this.data[model] = this.data[model] || []; | ||
this.data[model].push({sql: sql, params: params}); | ||
this.data[model].push({ sql: sql, params: params }); | ||
debug('INSERT', this.data, sql); | ||
@@ -230,0 +234,0 @@ callback(null, 1); |
@@ -0,1 +1,6 @@ | ||
// Copyright IBM Corp. 2014,2015. All Rights Reserved. | ||
// Node module: loopback-connector | ||
// This file is licensed under the MIT License. | ||
// License text available at https://opensource.org/licenses/MIT | ||
var assert = require('assert'); | ||
@@ -2,0 +7,0 @@ var connector = require('../'); |
@@ -0,1 +1,6 @@ | ||
// Copyright IBM Corp. 2015,2016. All Rights Reserved. | ||
// Node module: loopback-connector | ||
// This file is licensed under the MIT License. | ||
// License text available at https://opensource.org/licenses/MIT | ||
var expect = require('chai').expect; | ||
@@ -9,6 +14,8 @@ var SQLConnector = require('../lib/sql'); | ||
connector: testConnector, | ||
debug: true | ||
debug: true, | ||
}); | ||
/* eslint-disable one-var */ | ||
var connector; | ||
var Customer; | ||
/* eslint-enable one-var */ | ||
@@ -28,13 +35,13 @@ describe('sql connector', function() { | ||
dataType: 'VARCHAR', | ||
dataLength: 32 | ||
} | ||
dataLength: 32, | ||
}, | ||
}, vip: { | ||
type: Boolean, | ||
testdb: { | ||
column: 'VIP' | ||
} | ||
type: Boolean, | ||
testdb: { | ||
column: 'VIP', | ||
}, | ||
}, | ||
address: String, | ||
}, | ||
address: String | ||
}, | ||
{testdb: {table: 'CUSTOMER'}}); | ||
{ testdb: { table: 'CUSTOMER' }}); | ||
}); | ||
@@ -57,3 +64,3 @@ | ||
dataType: 'VARCHAR', | ||
dataLength: 32 | ||
dataLength: 32, | ||
}); | ||
@@ -93,6 +100,6 @@ }); | ||
it('builds where', function() { | ||
var where = connector.buildWhere('customer', {name: 'John'}); | ||
var where = connector.buildWhere('customer', { name: 'John' }); | ||
expect(where.toJSON()).to.eql({ | ||
sql: 'WHERE `NAME`=?', | ||
params: ['John'] | ||
params: ['John'], | ||
}); | ||
@@ -102,6 +109,6 @@ }); | ||
it('builds where with null', function() { | ||
var where = connector.buildWhere('customer', {name: null}); | ||
var where = connector.buildWhere('customer', { name: null }); | ||
expect(where.toJSON()).to.eql({ | ||
sql: 'WHERE `NAME` IS NULL', | ||
params: [] | ||
params: [], | ||
}); | ||
@@ -111,6 +118,6 @@ }); | ||
it('builds where with inq', function() { | ||
var where = connector.buildWhere('customer', {name: {inq: ['John', 'Mary']}}); | ||
var where = connector.buildWhere('customer', { name: { inq: ['John', 'Mary'] }}); | ||
expect(where.toJSON()).to.eql({ | ||
sql: 'WHERE `NAME` IN (?,?)', | ||
params: ['John', 'Mary'] | ||
params: ['John', 'Mary'], | ||
}); | ||
@@ -121,6 +128,6 @@ }); | ||
var where = connector.buildWhere('customer', | ||
{or: [{name: 'John'}, {name: 'Mary'}]}); | ||
{ or: [{ name: 'John' }, { name: 'Mary' }] }); | ||
expect(where.toJSON()).to.eql({ | ||
sql: 'WHERE (`NAME`=?) OR (`NAME`=?)', | ||
params: ['John', 'Mary'] | ||
params: ['John', 'Mary'], | ||
}); | ||
@@ -131,6 +138,6 @@ }); | ||
var where = connector.buildWhere('customer', | ||
{and: [{name: 'John'}, {vip: true}]}); | ||
{ and: [{ name: 'John' }, { vip: true }] }); | ||
expect(where.toJSON()).to.eql({ | ||
sql: 'WHERE (`NAME`=?) AND (`VIP`=?)', | ||
params: ['John', true] | ||
params: ['John', true], | ||
}); | ||
@@ -142,8 +149,8 @@ }); | ||
name: { | ||
regexp: '^J' | ||
} | ||
regexp: '^J', | ||
}, | ||
}); | ||
expect(where.toJSON()).to.eql({ | ||
sql: 'WHERE `NAME` REGEXP ?', | ||
params: ['^J'] | ||
params: ['^J'], | ||
}); | ||
@@ -155,8 +162,8 @@ }); | ||
name: { | ||
regexp: '^J/i' | ||
} | ||
regexp: '^J/i', | ||
}, | ||
}); | ||
expect(where.toJSON()).to.eql({ | ||
sql: 'WHERE `NAME` REGEXP ?', | ||
params: ['^J/i'] | ||
params: ['^J/i'], | ||
}); | ||
@@ -168,8 +175,8 @@ }); | ||
name: { | ||
regexp: /^J/ | ||
} | ||
regexp: /^J/, | ||
}, | ||
}); | ||
expect(where.toJSON()).to.eql({ | ||
sql: 'WHERE `NAME` REGEXP ?', | ||
params: [/^J/] | ||
params: [/^J/], | ||
}); | ||
@@ -181,8 +188,8 @@ }); | ||
name: { | ||
regexp: /^J/i | ||
} | ||
regexp: /^J/i, | ||
}, | ||
}); | ||
expect(where.toJSON()).to.eql({ | ||
sql: 'WHERE `NAME` REGEXP ?', | ||
params: [/^J/i] | ||
params: [/^J/i], | ||
}); | ||
@@ -194,8 +201,8 @@ }); | ||
name: { | ||
regexp: new RegExp(/^J/) | ||
} | ||
regexp: new RegExp(/^J/), | ||
}, | ||
}); | ||
expect(where.toJSON()).to.eql({ | ||
sql: 'WHERE `NAME` REGEXP ?', | ||
params: [/^J/] | ||
params: [/^J/], | ||
}); | ||
@@ -207,8 +214,8 @@ }); | ||
name: { | ||
regexp: new RegExp(/^J/i) | ||
} | ||
regexp: new RegExp(/^J/i), | ||
}, | ||
}); | ||
expect(where.toJSON()).to.eql({ | ||
sql: 'WHERE `NAME` REGEXP ?', | ||
params: [new RegExp(/^J/i)] | ||
params: [new RegExp(/^J/i)], | ||
}); | ||
@@ -219,6 +226,6 @@ }); | ||
var where = connector.buildWhere('customer', | ||
{and: [{name: 'John'}, {or: [{vip: true}, {address: null}]}]}); | ||
{ and: [{ name: 'John' }, { or: [{ vip: true }, { address: null }] }] }); | ||
expect(where.toJSON()).to.eql({ | ||
sql: 'WHERE (`NAME`=?) AND ((`VIP`=?) OR (`ADDRESS` IS NULL))', | ||
params: ['John', true] | ||
params: ['John', true], | ||
}); | ||
@@ -244,8 +251,8 @@ }); | ||
var fields = connector.buildFields('customer', | ||
{name: 'John', vip: true, unknown: 'Random'}); | ||
{ name: 'John', vip: true, unknown: 'Random' }); | ||
expect(fields.names).to.eql(['`NAME`', '`VIP`']); | ||
expect(fields.columnValues[0].toJSON()).to.eql( | ||
{sql: '?', params: ['John']}); | ||
{ sql: '?', params: ['John'] }); | ||
expect(fields.columnValues[1].toJSON()).to.eql( | ||
{sql: '?', params: [true]}); | ||
{ sql: '?', params: [true] }); | ||
}); | ||
@@ -255,6 +262,6 @@ | ||
var fields = connector.buildFieldsForUpdate('customer', | ||
{name: 'John', vip: true}); | ||
{ name: 'John', vip: true }); | ||
expect(fields.toJSON()).to.eql({ | ||
sql: 'SET `VIP`=?', | ||
params: [true] | ||
params: [true], | ||
}); | ||
@@ -265,6 +272,6 @@ }); | ||
var fields = connector.buildFieldsForUpdate('customer', | ||
{name: 'John', vip: true}, false); | ||
{ name: 'John', vip: true }, false); | ||
expect(fields.toJSON()).to.eql({ | ||
sql: 'SET `NAME`=?,`VIP`=?', | ||
params: ['John', true] | ||
params: ['John', true], | ||
}); | ||
@@ -279,3 +286,3 @@ }); | ||
it('builds column names with true fields filter for SELECT', function() { | ||
var cols = connector.buildColumnNames('customer', {fields: {name: true}}); | ||
var cols = connector.buildColumnNames('customer', { fields: { name: true }}); | ||
expect(cols).to.eql('`NAME`'); | ||
@@ -285,3 +292,3 @@ }); | ||
it('builds column names with false fields filter for SELECT', function() { | ||
var cols = connector.buildColumnNames('customer', {fields: {name: false}}); | ||
var cols = connector.buildColumnNames('customer', { fields: { name: false }}); | ||
expect(cols).to.eql('`VIP`,`ADDRESS`'); | ||
@@ -291,3 +298,3 @@ }); | ||
it('builds column names with array fields filter for SELECT', function() { | ||
var cols = connector.buildColumnNames('customer', {fields: ['name']}); | ||
var cols = connector.buildColumnNames('customer', { fields: ['name'] }); | ||
expect(cols).to.eql('`NAME`'); | ||
@@ -297,6 +304,6 @@ }); | ||
it('builds DELETE', function() { | ||
var sql = connector.buildDelete('customer', {name: 'John'}); | ||
var sql = connector.buildDelete('customer', { name: 'John' }); | ||
expect(sql.toJSON()).to.eql({ | ||
sql: 'DELETE FROM `CUSTOMER` WHERE `NAME`=$1', | ||
params: ['John'] | ||
params: ['John'], | ||
}); | ||
@@ -306,6 +313,6 @@ }); | ||
it('builds UPDATE', function() { | ||
var sql = connector.buildUpdate('customer', {name: 'John'}, {vip: false}); | ||
var sql = connector.buildUpdate('customer', { name: 'John' }, { vip: false }); | ||
expect(sql.toJSON()).to.eql({ | ||
sql: 'UPDATE `CUSTOMER` SET `VIP`=$1 WHERE `NAME`=$2', | ||
params: [false, 'John'] | ||
params: [false, 'John'], | ||
}); | ||
@@ -316,7 +323,7 @@ }); | ||
var sql = connector.buildSelect('customer', | ||
{order: 'name', limit: 5, where: {name: 'John'}}); | ||
{ order: 'name', limit: 5, where: { name: 'John' }}); | ||
expect(sql.toJSON()).to.eql({ | ||
sql: 'SELECT `NAME`,`VIP`,`ADDRESS` FROM `CUSTOMER`' + | ||
' WHERE `NAME`=$1 ORDER BY `NAME` LIMIT 5', | ||
params: ['John'] | ||
params: ['John'], | ||
}); | ||
@@ -326,6 +333,6 @@ }); | ||
it('builds INSERT', function() { | ||
var sql = connector.buildInsert('customer', {name: 'John', vip: true}); | ||
var sql = connector.buildInsert('customer', { name: 'John', vip: true }); | ||
expect(sql.toJSON()).to.eql({ | ||
sql: 'INSERT INTO `CUSTOMER`(`NAME`,`VIP`) VALUES($1,$2)', | ||
params: ['John', true] | ||
params: ['John', true], | ||
}); | ||
@@ -337,9 +344,9 @@ }); | ||
var stmt = new ParameterizedSQL(sql); | ||
expect(stmt.toJSON()).to.eql({sql: sql, params: []}); | ||
expect(stmt.toJSON()).to.eql({ sql: sql, params: [] }); | ||
}); | ||
it('normalizes a SQL statement from object without params', function() { | ||
var sql = {sql: 'SELECT * FROM `CUSTOMER`'}; | ||
var sql = { sql: 'SELECT * FROM `CUSTOMER`' }; | ||
var stmt = new ParameterizedSQL(sql); | ||
expect(stmt.toJSON()).to.eql({sql: sql.sql, params: []}); | ||
expect(stmt.toJSON()).to.eql({ sql: sql.sql, params: [] }); | ||
}); | ||
@@ -349,5 +356,5 @@ | ||
var sql = | ||
{sql: 'SELECT * FROM `CUSTOMER` WHERE `NAME`=?', params: ['John']}; | ||
{ sql: 'SELECT * FROM `CUSTOMER` WHERE `NAME`=?', params: ['John'] }; | ||
var stmt = new ParameterizedSQL(sql); | ||
expect(stmt.toJSON()).to.eql({sql: sql.sql, params: ['John']}); | ||
expect(stmt.toJSON()).to.eql({ sql: sql.sql, params: ['John'] }); | ||
}); | ||
@@ -363,7 +370,7 @@ | ||
it('concats SQL statements', function() { | ||
var stmt1 = {sql: 'SELECT * from `CUSTOMER`'}; | ||
var where = {sql: 'WHERE `NAME`=?', params: ['John']}; | ||
var stmt1 = { sql: 'SELECT * from `CUSTOMER`' }; | ||
var where = { sql: 'WHERE `NAME`=?', params: ['John'] }; | ||
stmt1 = ParameterizedSQL.append(stmt1, where); | ||
expect(stmt1.toJSON()).to.eql( | ||
{sql: 'SELECT * from `CUSTOMER` WHERE `NAME`=?', params: ['John']}); | ||
{ sql: 'SELECT * from `CUSTOMER` WHERE `NAME`=?', params: ['John'] }); | ||
}); | ||
@@ -373,6 +380,6 @@ | ||
var stmt1 = 'SELECT * from `CUSTOMER`'; | ||
var where = {sql: 'WHERE `NAME`=?', params: ['John']}; | ||
var where = { sql: 'WHERE `NAME`=?', params: ['John'] }; | ||
stmt1 = ParameterizedSQL.append(stmt1, where); | ||
expect(stmt1.toJSON()).to.eql( | ||
{sql: 'SELECT * from `CUSTOMER` WHERE `NAME`=?', params: ['John']}); | ||
{ sql: 'SELECT * from `CUSTOMER` WHERE `NAME`=?', params: ['John'] }); | ||
}); | ||
@@ -383,3 +390,3 @@ | ||
var stmt1 = 'SELECT * from `CUSTOMER`'; | ||
var where = {sql: 'WHERE `NAME`=?', params: ['John', 'Mary']}; | ||
var where = { sql: 'WHERE `NAME`=?', params: ['John', 'Mary'] }; | ||
stmt1 = ParameterizedSQL.append(stmt1, where); | ||
@@ -400,3 +407,3 @@ }).to.throw('must match the number of params'); | ||
connector.execute('SELECT * FROM `CUSTOMER` WHERE `NAME`=$1', | ||
['xyz'], {transaction: true}, done); | ||
['xyz'], { transaction: true }, done); | ||
}); | ||
@@ -403,0 +410,0 @@ |
@@ -0,1 +1,6 @@ | ||
// Copyright IBM Corp. 2015,2016. All Rights Reserved. | ||
// Node module: loopback-connector | ||
// This file is licensed under the MIT License. | ||
// License text available at https://opensource.org/licenses/MIT | ||
var Transaction = require('../index').Transaction; | ||
@@ -7,23 +12,19 @@ | ||
var juggler = require('loopback-datasource-juggler'); | ||
var db, Post; | ||
var Review; | ||
var db, Post, Review; | ||
describe('transactions', function() { | ||
before(function(done) { | ||
db = new juggler.DataSource({ | ||
connector: testConnector, | ||
debug: true | ||
debug: true, | ||
}); | ||
db.once('connected', function() { | ||
Post = db.define('PostTX', { | ||
title: {type: String, length: 255, index: true}, | ||
content: {type: String} | ||
title: { type: String, length: 255, index: true }, | ||
content: { type: String }, | ||
}); | ||
Review = db.define('ReviewTX', { | ||
author: String, | ||
content: {type: String} | ||
content: { type: String }, | ||
}); | ||
Post.hasMany(Review, {as: 'reviews', foreignKey: 'postId'}); | ||
Post.hasMany(Review, { as: 'reviews', foreignKey: 'postId' }); | ||
done(); | ||
@@ -40,5 +41,5 @@ }); | ||
Post.beginTransaction({ | ||
isolationLevel: Transaction.READ_COMMITTED, | ||
timeout: timeout | ||
}, | ||
isolationLevel: Transaction.READ_COMMITTED, | ||
timeout: timeout, | ||
}, | ||
function(err, tx) { | ||
@@ -65,3 +66,3 @@ if (err) return done(err); | ||
currentTx = tx; | ||
Post.create(post, {transaction: tx, model: 'Post'}, | ||
Post.create(post, { transaction: tx, model: 'Post' }, | ||
function(err, p) { | ||
@@ -72,5 +73,5 @@ if (err) { | ||
p.reviews.create({ | ||
author: 'John', | ||
content: 'Review for ' + p.title | ||
}, {transaction: tx, model: 'Review'}, | ||
author: 'John', | ||
content: 'Review for ' + p.title, | ||
}, { transaction: tx, model: 'Review' }, | ||
function(err, c) { | ||
@@ -89,7 +90,7 @@ done(err); | ||
return function(done) { | ||
var options = {model: 'Post'}; | ||
var options = { model: 'Post' }; | ||
if (inTx) { | ||
options.transaction = currentTx; | ||
} | ||
Post.find({where: where}, options, | ||
Post.find({ where: where }, options, | ||
function(err, posts) { | ||
@@ -116,4 +117,3 @@ if (err) return done(err); | ||
describe('commit', function() { | ||
var post = {title: 't1', content: 'c1'}; | ||
var post = { title: 't1', content: 'c1' }; | ||
before(createPostInTx(post)); | ||
@@ -144,3 +144,2 @@ | ||
describe('rollback', function() { | ||
before(function() { | ||
@@ -151,3 +150,3 @@ // Reset the collection | ||
var post = {title: 't2', content: 'c2'}; | ||
var post = { title: 't2', content: 'c2' }; | ||
before(createPostInTx(post)); | ||
@@ -178,3 +177,2 @@ | ||
describe('timeout', function() { | ||
before(function() { | ||
@@ -185,3 +183,3 @@ // Reset the collection | ||
var post = {title: 't3', content: 'c3'}; | ||
var post = { title: 't3', content: 'c3' }; | ||
before(createPostInTx(post, 50)); | ||
@@ -191,3 +189,3 @@ | ||
setTimeout(function() { | ||
Post.find({where: {title: 't3'}}, {transaction: currentTx}, | ||
Post.find({ where: { title: 't3' }}, { transaction: currentTx }, | ||
function(err, posts) { | ||
@@ -208,4 +206,3 @@ if (err) return done(err); | ||
}); | ||
}); | ||
}); |
Sorry, the diff of this file is not supported yet
Unidentified License
License(Experimental) Something that seems like a license was found, but its contents could not be matched with a known license.
Found 1 instance in 1 package
0
100
2669
324039
5