update eslint + config to latest

Also fix linting errors, most notably get rid of `var` keyword.

Signed-off-by: Miroslav Bajtoš <mbajtoss@gmail.com>
This commit is contained in:
Miroslav Bajtoš 2020-08-28 08:43:09 +02:00
parent 40ce105e57
commit 7ce66b5b81
No known key found for this signature in database
GPG Key ID: 6F2304BA9361C7E3
21 changed files with 422 additions and 445 deletions

View File

@ -4,11 +4,11 @@
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT
'use strict'; 'use strict';
var DataSource = require('loopback-datasource-juggler').DataSource; const DataSource = require('loopback-datasource-juggler').DataSource;
var config = require('rc')('loopback', {dev: {mysql: {}}}).dev.mysql; const config = require('rc')('loopback', {dev: {mysql: {}}}).dev.mysql;
var ds = new DataSource(require('../'), config); const ds = new DataSource(require('../'), config);
function show(err, models) { function show(err, models) {
if (err) { if (err) {
@ -35,7 +35,7 @@ ds.discoverForeignKeys('inventory', show);
ds.discoverExportedForeignKeys('location', show); ds.discoverExportedForeignKeys('location', show);
ds.discoverAndBuildModels('weapon', {owner: 'strongloop', visited: {}, associations: true}, function(err, models) { ds.discoverAndBuildModels('weapon', {owner: 'strongloop', visited: {}, associations: true}, function(err, models) {
for (var m in models) { for (const m in models) {
models[m].all(show); models[m].all(show);
} }
}); });

View File

@ -4,7 +4,7 @@
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT
'use strict'; 'use strict';
var SG = require('strong-globalize'); const SG = require('strong-globalize');
SG.SetRootDir(__dirname); SG.SetRootDir(__dirname);
module.exports = require('./lib/mysql.js'); module.exports = require('./lib/mysql.js');

View File

@ -4,7 +4,7 @@
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT
'use strict'; 'use strict';
var g = require('strong-globalize')(); const g = require('strong-globalize')();
module.exports = mixinDiscovery; module.exports = mixinDiscovery;
@ -13,20 +13,20 @@ module.exports = mixinDiscovery;
* @param {Object} mysql mysql driver * @param {Object} mysql mysql driver
*/ */
function mixinDiscovery(MySQL, mysql) { function mixinDiscovery(MySQL, mysql) {
var async = require('async'); const async = require('async');
function paginateSQL(sql, orderBy, options) { function paginateSQL(sql, orderBy, options) {
options = options || {}; options = options || {};
var limitClause = ''; let limitClause = '';
if (options.offset || options.skip || options.limit) { if (options.offset || options.skip || options.limit) {
// Offset starts from 0 // Offset starts from 0
var offset = Number(options.offset || options.skip || 0); let offset = Number(options.offset || options.skip || 0);
if (isNaN(offset)) { if (isNaN(offset)) {
offset = 0; offset = 0;
} }
limitClause = ' LIMIT ' + offset; limitClause = ' LIMIT ' + offset;
if (options.limit) { if (options.limit) {
var limit = Number(options.limit); let limit = Number(options.limit);
if (isNaN(limit)) { if (isNaN(limit)) {
limit = 0; limit = 0;
} }
@ -45,7 +45,7 @@ function mixinDiscovery(MySQL, mysql) {
* @returns {String} The SQL statement * @returns {String} The SQL statement
*/ */
MySQL.prototype.buildQuerySchemas = function(options) { MySQL.prototype.buildQuerySchemas = function(options) {
var sql = 'SELECT catalog_name as "catalog",' + const sql = 'SELECT catalog_name as "catalog",' +
' schema_name as "schema"' + ' schema_name as "schema"' +
' FROM information_schema.schemata'; ' FROM information_schema.schemata';
return paginateSQL(sql, 'schema_name', options); return paginateSQL(sql, 'schema_name', options);
@ -57,8 +57,8 @@ function mixinDiscovery(MySQL, mysql) {
* @returns {string} The sql statement * @returns {string} The sql statement
*/ */
MySQL.prototype.buildQueryTables = function(options) { MySQL.prototype.buildQueryTables = function(options) {
var sqlTables = null; let sqlTables = null;
var schema = options.owner || options.schema; const schema = options.owner || options.schema;
if (options.all && !schema) { if (options.all && !schema) {
sqlTables = paginateSQL('SELECT \'table\' AS "type",' + sqlTables = paginateSQL('SELECT \'table\' AS "type",' +
@ -87,9 +87,9 @@ function mixinDiscovery(MySQL, mysql) {
* @returns {string} The sql statement * @returns {string} The sql statement
*/ */
MySQL.prototype.buildQueryViews = function(options) { MySQL.prototype.buildQueryViews = function(options) {
var sqlViews = null; let sqlViews = null;
if (options.views) { if (options.views) {
var schema = options.owner || options.schema; const schema = options.owner || options.schema;
if (options.all && !schema) { if (options.all && !schema) {
sqlViews = paginateSQL('SELECT \'view\' AS "type",' + sqlViews = paginateSQL('SELECT \'view\' AS "type",' +
@ -155,7 +155,7 @@ function mixinDiscovery(MySQL, mysql) {
* @returns {String} The sql statement * @returns {String} The sql statement
*/ */
MySQL.prototype.buildQueryColumns = function(schema, table) { MySQL.prototype.buildQueryColumns = function(schema, table) {
var sql = null; let sql = null;
if (schema) { if (schema) {
sql = paginateSQL('SELECT table_schema AS "owner",' + sql = paginateSQL('SELECT table_schema AS "owner",' +
' table_name AS "tableName",' + ' table_name AS "tableName",' +
@ -206,7 +206,7 @@ function mixinDiscovery(MySQL, mysql) {
// http://docs.oracle.com/javase/6/docs/api/java/sql/DatabaseMetaData.html // http://docs.oracle.com/javase/6/docs/api/java/sql/DatabaseMetaData.html
// #getPrimaryKeys(java.lang.String, java.lang.String, java.lang.String) // #getPrimaryKeys(java.lang.String, java.lang.String, java.lang.String)
MySQL.prototype.buildQueryPrimaryKeys = function(schema, table) { MySQL.prototype.buildQueryPrimaryKeys = function(schema, table) {
var sql = 'SELECT table_schema AS "owner",' + let sql = 'SELECT table_schema AS "owner",' +
' table_name AS "tableName",' + ' table_name AS "tableName",' +
' column_name AS "columnName",' + ' column_name AS "columnName",' +
' ordinal_position AS "keySeq",' + ' ordinal_position AS "keySeq",' +
@ -239,7 +239,7 @@ function mixinDiscovery(MySQL, mysql) {
* @returns {string} * @returns {string}
*/ */
MySQL.prototype.buildQueryForeignKeys = function(schema, table) { MySQL.prototype.buildQueryForeignKeys = function(schema, table) {
var sql = let sql =
'SELECT table_schema AS "fkOwner",' + 'SELECT table_schema AS "fkOwner",' +
' constraint_name AS "fkName",' + ' constraint_name AS "fkName",' +
' table_name AS "fkTableName",' + ' table_name AS "fkTableName",' +
@ -276,7 +276,7 @@ function mixinDiscovery(MySQL, mysql) {
* @returns {string} * @returns {string}
*/ */
MySQL.prototype.buildQueryExportedForeignKeys = function(schema, table) { MySQL.prototype.buildQueryExportedForeignKeys = function(schema, table) {
var sql = 'SELECT a.constraint_name AS "fkName",' + let sql = 'SELECT a.constraint_name AS "fkName",' +
' a.table_schema AS "fkOwner",' + ' a.table_schema AS "fkOwner",' +
' a.table_name AS "fkTableName",' + ' a.table_name AS "fkTableName",' +
' a.column_name AS "fkColumnName",' + ' a.column_name AS "fkColumnName",' +
@ -306,11 +306,11 @@ function mixinDiscovery(MySQL, mysql) {
*/ */
MySQL.prototype.buildPropertyType = function(columnDefinition, options) { MySQL.prototype.buildPropertyType = function(columnDefinition, options) {
var mysqlType = columnDefinition.dataType; const mysqlType = columnDefinition.dataType;
var columnType = columnDefinition.columnType; const columnType = columnDefinition.columnType;
var dataLength = columnDefinition.dataLength; const dataLength = columnDefinition.dataLength;
var type = mysqlType.toUpperCase(); const type = mysqlType.toUpperCase();
switch (type) { switch (type) {
case 'CHAR': case 'CHAR':
if (!options.treatCHAR1AsString && columnType === 'char(1)') { if (!options.treatCHAR1AsString && columnType === 'char(1)') {
@ -379,13 +379,13 @@ function mixinDiscovery(MySQL, mysql) {
// http://dev.mysql.com/doc/refman/5.7/en/numeric-type-overview.html // http://dev.mysql.com/doc/refman/5.7/en/numeric-type-overview.html
// Currently default is the inverse of the recommendation for backward compatibility. // Currently default is the inverse of the recommendation for backward compatibility.
MySQL.prototype.setDefaultOptions = function(options) { MySQL.prototype.setDefaultOptions = function(options) {
var defaultOptions = { const defaultOptions = {
treatCHAR1AsString: false, treatCHAR1AsString: false,
treatBIT1AsBit: true, treatBIT1AsBit: true,
treatTINYINT1AsTinyInt: true, treatTINYINT1AsTinyInt: true,
}; };
for (var opt in defaultOptions) { for (const opt in defaultOptions) {
if (defaultOptions.hasOwnProperty(opt) && !options.hasOwnProperty(opt)) { if (defaultOptions.hasOwnProperty(opt) && !options.hasOwnProperty(opt)) {
options[opt] = defaultOptions[opt]; options[opt] = defaultOptions[opt];
} }

View File

@ -4,11 +4,11 @@
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT
'use strict'; 'use strict';
var g = require('strong-globalize')(); const g = require('strong-globalize')();
var EnumFactory = function() { const EnumFactory = function() {
if (arguments.length > 0) { if (arguments.length > 0) {
var Enum = function Enum(arg) { const Enum = function Enum(arg) {
if (typeof arg === 'number' && arg % 1 == 0) { if (typeof arg === 'number' && arg % 1 == 0) {
return Enum._values[arg]; return Enum._values[arg];
} else if (Enum[arg]) { } else if (Enum[arg]) {
@ -21,11 +21,11 @@ var EnumFactory = function() {
return ''; return '';
} }
}; };
var dxList = []; const dxList = [];
// Want empty value to be at index 0 to match MySQL Enum values and // Want empty value to be at index 0 to match MySQL Enum values and
// MySQL non-strict behavior. // MySQL non-strict behavior.
dxList.push(''); dxList.push('');
for (var arg in arguments) { for (let arg in arguments) {
arg = String(arguments[arg]); arg = String(arguments[arg]);
Object.defineProperty(Enum, arg.toUpperCase(), { Object.defineProperty(Enum, arg.toUpperCase(), {
configurable: false, configurable: false,
@ -55,8 +55,8 @@ var EnumFactory = function() {
}; };
function stringified(anEnum) { function stringified(anEnum) {
var s = []; const s = [];
for (var i in anEnum._values) { for (const i in anEnum._values) {
if (anEnum._values[i] != '') { if (anEnum._values[i] != '') {
s.push("'" + anEnum._values[i] + "'"); s.push("'" + anEnum._values[i] + "'");
} }

View File

@ -4,8 +4,8 @@
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT
'use strict'; 'use strict';
var g = require('strong-globalize')(); const g = require('strong-globalize')();
var async = require('async'); const async = require('async');
module.exports = mixinMigration; module.exports = mixinMigration;
/*! /*!
@ -14,8 +14,8 @@ module.exports = mixinMigration;
*/ */
function mixinMigration(MySQL, mysql) { function mixinMigration(MySQL, mysql) {
MySQL.prototype.showFields = function(model, cb) { MySQL.prototype.showFields = function(model, cb) {
var table = this.tableEscaped(model); const table = this.tableEscaped(model);
var sql = 'SHOW FIELDS FROM ' + table; const sql = 'SHOW FIELDS FROM ' + table;
this.execute(sql, function(err, fields) { this.execute(sql, function(err, fields) {
if (err) { if (err) {
return cb(err); return cb(err);
@ -26,8 +26,8 @@ function mixinMigration(MySQL, mysql) {
}; };
MySQL.prototype.showIndexes = function(model, cb) { MySQL.prototype.showIndexes = function(model, cb) {
var table = this.tableEscaped(model); const table = this.tableEscaped(model);
var sql = 'SHOW INDEXES FROM ' + table; const sql = 'SHOW INDEXES FROM ' + table;
this.execute(sql, function(err, indexes) { this.execute(sql, function(err, indexes) {
if (err) { if (err) {
return cb(err); return cb(err);
@ -38,19 +38,20 @@ function mixinMigration(MySQL, mysql) {
}; };
MySQL.prototype.getConstraintTrigger = function(model, actualFks, cb) { MySQL.prototype.getConstraintTrigger = function(model, actualFks, cb) {
var table = this.tableEscaped(model); const table = this.tableEscaped(model);
var sql = 'SHOW CREATE TABLE ' + table; const sql = 'SHOW CREATE TABLE ' + table;
this.execute(sql, function(err, createTable) { this.execute(sql, function(err, createTable) {
if (err) { if (err) {
return cb(err); return cb(err);
} else { } else {
var matchConstraint = new RegExp('CONSTRAINT `([^`]+)` FOREIGN KEY \\(`([^`]+)`\\)' + const matchConstraint = new RegExp('CONSTRAINT `([^`]+)` FOREIGN KEY \\(`([^`]+)`\\)' +
' REFERENCES `([^`]+)` \\(`([^`]+)`\\)' + ' REFERENCES `([^`]+)` \\(`([^`]+)`\\)' +
'(?: ON DELETE (RESTRICT|CASCADE|SET NULL|NO ACTION|SET DEFAULT))?' + '(?: ON DELETE (RESTRICT|CASCADE|SET NULL|NO ACTION|SET DEFAULT))?' +
'(?: ON UPDATE (RESTRICT|CASCADE|SET NULL|NO ACTION|SET DEFAULT))?', 'g'); '(?: ON UPDATE (RESTRICT|CASCADE|SET NULL|NO ACTION|SET DEFAULT))?', 'g');
var rawConstraints = []; const rawConstraints = [];
let match;
do { do {
var match = matchConstraint.exec(createTable[0]['Create Table']); match = matchConstraint.exec(createTable[0]['Create Table']);
if (match) { if (match) {
actualFks.forEach(function(fk) { actualFks.forEach(function(fk) {
if (fk.fkName === match[1]) { if (fk.fkName === match[1]) {
@ -73,8 +74,8 @@ function mixinMigration(MySQL, mysql) {
* @param {Function} [cb] The callback function * @param {Function} [cb] The callback function
*/ */
MySQL.prototype.autoupdate = function(models, cb) { MySQL.prototype.autoupdate = function(models, cb) {
var self = this; const self = this;
var foreignKeyStatements = []; const foreignKeyStatements = [];
if ((!cb) && ('function' === typeof models)) { if ((!cb) && ('function' === typeof models)) {
cb = models; cb = models;
@ -105,7 +106,7 @@ function mixinMigration(MySQL, mysql) {
if (!err) { if (!err) {
// foreignKeys is a list of EXISTING fkeys here, so you don't need to recreate them again // foreignKeys is a list of EXISTING fkeys here, so you don't need to recreate them again
// prepare fkSQL for new foreign keys // prepare fkSQL for new foreign keys
var fkSQL = self.getForeignKeySQL(model, const fkSQL = self.getForeignKeySQL(model,
self.getModelDefinition(model).settings.foreignKeys, self.getModelDefinition(model).settings.foreignKeys,
foreignKeys); foreignKeys);
self.addForeignKeys(model, fkSQL, function(err, result) { self.addForeignKeys(model, fkSQL, function(err, result) {
@ -141,9 +142,9 @@ function mixinMigration(MySQL, mysql) {
* @param cb * @param cb
*/ */
MySQL.prototype.createTable = function(model, cb) { MySQL.prototype.createTable = function(model, cb) {
var metadata = this.getModelDefinition(model).settings[this.name]; const metadata = this.getModelDefinition(model).settings[this.name];
var engine = metadata && metadata.engine; const engine = metadata && metadata.engine;
var sql = 'CREATE TABLE ' + this.tableEscaped(model) + let sql = 'CREATE TABLE ' + this.tableEscaped(model) +
' (\n ' + this.buildColumnDefinitions(model) + '\n)'; ' (\n ' + this.buildColumnDefinitions(model) + '\n)';
if (engine) { if (engine) {
sql += 'ENGINE=' + engine + '\n'; sql += 'ENGINE=' + engine + '\n';
@ -158,8 +159,8 @@ function mixinMigration(MySQL, mysql) {
* @param {Function} [cb] The callback function * @param {Function} [cb] The callback function
*/ */
MySQL.prototype.isActual = function(models, cb) { MySQL.prototype.isActual = function(models, cb) {
var self = this; const self = this;
var ok = false; let ok = false;
if ((!cb) && ('function' === typeof models)) { if ((!cb) && ('function' === typeof models)) {
cb = models; cb = models;
@ -195,17 +196,17 @@ function mixinMigration(MySQL, mysql) {
}; };
MySQL.prototype.getColumnsToAdd = function(model, actualFields) { MySQL.prototype.getColumnsToAdd = function(model, actualFields) {
var self = this; const self = this;
var m = this.getModelDefinition(model); const m = this.getModelDefinition(model);
var propNames = Object.keys(m.properties).filter(function(name) { const propNames = Object.keys(m.properties).filter(function(name) {
return !!m.properties[name]; return !!m.properties[name];
}); });
var sql = []; const sql = [];
propNames.forEach(function(propName) { propNames.forEach(function(propName) {
if (m.properties[propName] && self.id(model, propName)) return; if (m.properties[propName] && self.id(model, propName)) return;
var found; let found;
var colName = expectedColNameForModel(propName, m); const colName = expectedColNameForModel(propName, m);
if (actualFields) { if (actualFields) {
actualFields.forEach(function(f) { actualFields.forEach(function(f) {
if (f.Field === colName) { if (f.Field === colName) {
@ -222,9 +223,9 @@ function mixinMigration(MySQL, mysql) {
}); });
function actualize(propName, oldSettings) { function actualize(propName, oldSettings) {
var newSettings = m.properties[propName]; const newSettings = m.properties[propName];
if (newSettings && changed(newSettings, oldSettings)) { if (newSettings && changed(newSettings, oldSettings)) {
var pName = self.columnEscaped(model, propName); const pName = self.columnEscaped(model, propName);
sql.push('CHANGE COLUMN ' + pName + ' ' + pName + ' ' + sql.push('CHANGE COLUMN ' + pName + ' ' + pName + ' ' +
self.buildColumnDefinition(model, propName)); self.buildColumnDefinition(model, propName));
} }
@ -254,22 +255,22 @@ function mixinMigration(MySQL, mysql) {
}; };
MySQL.prototype.getColumnsToDrop = function(model, actualFields) { MySQL.prototype.getColumnsToDrop = function(model, actualFields) {
var self = this; const self = this;
var fields = actualFields; const fields = actualFields;
var sql = []; const sql = [];
var m = this.getModelDefinition(model); const m = this.getModelDefinition(model);
var propNames = Object.keys(m.properties).filter(function(name) { const propNames = Object.keys(m.properties).filter(function(name) {
return !!m.properties[name]; return !!m.properties[name];
}); });
// drop columns // drop columns
if (fields) { if (fields) {
fields.forEach(function(f) { fields.forEach(function(f) {
var colNames = propNames.map(function expectedColName(propName) { const colNames = propNames.map(function expectedColName(propName) {
return expectedColNameForModel(propName, m); return expectedColNameForModel(propName, m);
}); });
var index = colNames.indexOf(f.Field); const index = colNames.indexOf(f.Field);
var propName = index >= 0 ? propNames[index] : f.Field; const propName = index >= 0 ? propNames[index] : f.Field;
var notFound = !~index; const notFound = !~index;
if (m.properties[propName] && self.id(model, propName)) return; if (m.properties[propName] && self.id(model, propName)) return;
if (notFound || !m.properties[propName]) { if (notFound || !m.properties[propName]) {
sql.push('DROP COLUMN ' + self.client.escapeId(f.Field)); sql.push('DROP COLUMN ' + self.client.escapeId(f.Field));
@ -280,20 +281,20 @@ function mixinMigration(MySQL, mysql) {
}; };
MySQL.prototype.addIndexes = function(model, actualIndexes) { MySQL.prototype.addIndexes = function(model, actualIndexes) {
var self = this; const self = this;
var m = this.getModelDefinition(model); const m = this.getModelDefinition(model);
var propNames = Object.keys(m.properties).filter(function(name) { const propNames = Object.keys(m.properties).filter(function(name) {
return !!m.properties[name]; return !!m.properties[name];
}); });
var indexNames = m.settings.indexes && Object.keys(m.settings.indexes).filter(function(name) { const indexNames = m.settings.indexes && Object.keys(m.settings.indexes).filter(function(name) {
return !!m.settings.indexes[name]; return !!m.settings.indexes[name];
}) || []; }) || [];
var sql = []; const sql = [];
var ai = {}; const ai = {};
if (actualIndexes) { if (actualIndexes) {
actualIndexes.forEach(function(i) { actualIndexes.forEach(function(i) {
var name = i.Key_name; const name = i.Key_name;
if (!ai[name]) { if (!ai[name]) {
ai[name] = { ai[name] = {
info: i, info: i,
@ -303,7 +304,7 @@ function mixinMigration(MySQL, mysql) {
ai[name].columns[i.Seq_in_index - 1] = i.Column_name; ai[name].columns[i.Seq_in_index - 1] = i.Column_name;
}); });
} }
var aiNames = Object.keys(ai); const aiNames = Object.keys(ai);
// remove indexes // remove indexes
aiNames.forEach(function(indexName) { aiNames.forEach(function(indexName) {
@ -322,19 +323,20 @@ function mixinMigration(MySQL, mysql) {
return; return;
} }
// second: check multiple indexes // second: check multiple indexes
var orderMatched = true; let orderMatched = true;
if (indexNames.indexOf(indexName) !== -1) { if (indexNames.indexOf(indexName) !== -1) {
// check if indexes are configured as "columns" // check if indexes are configured as "columns"
if (m.settings.indexes[indexName].columns) { if (m.settings.indexes[indexName].columns) {
m.settings.indexes[indexName].columns.split(/,\s*/).forEach( m.settings.indexes[indexName].columns.split(/,\s*/).forEach(
function(columnName, i) { function(columnName, i) {
if (ai[indexName].columns[i] !== columnName) orderMatched = false; if (ai[indexName].columns[i] !== columnName) orderMatched = false;
}); },
);
} else if (m.settings.indexes[indexName].keys) { } else if (m.settings.indexes[indexName].keys) {
// if indexes are configured as "keys" // if indexes are configured as "keys"
var index = 0; let index = 0;
for (var key in m.settings.indexes[indexName].keys) { for (const key in m.settings.indexes[indexName].keys) {
var sortOrder = m.settings.indexes[indexName].keys[key]; const sortOrder = m.settings.indexes[indexName].keys[key];
if (ai[indexName].columns[index] !== key) { if (ai[indexName].columns[index] !== key) {
orderMatched = false; orderMatched = false;
break; break;
@ -356,17 +358,17 @@ function mixinMigration(MySQL, mysql) {
// add single-column indexes // add single-column indexes
propNames.forEach(function(propName) { propNames.forEach(function(propName) {
var i = m.properties[propName].index; const i = m.properties[propName].index;
if (!i) { if (!i) {
return; return;
} }
var found = ai[propName] && ai[propName].info; const found = ai[propName] && ai[propName].info;
if (!found) { if (!found) {
var colName = expectedColNameForModel(propName, m); const colName = expectedColNameForModel(propName, m);
var pName = self.client.escapeId(colName); const pName = self.client.escapeId(colName);
var indexName = self.client.escapeId(propName); const indexName = self.client.escapeId(propName);
var type = ''; let type = '';
var kind = ''; let kind = '';
if (i.type) { if (i.type) {
type = 'USING ' + i.type; type = 'USING ' + i.type;
} }
@ -385,12 +387,12 @@ function mixinMigration(MySQL, mysql) {
// add multi-column indexes // add multi-column indexes
indexNames.forEach(function(indexName) { indexNames.forEach(function(indexName) {
var i = m.settings.indexes[indexName]; const i = m.settings.indexes[indexName];
var found = ai[indexName] && ai[indexName].info; const found = ai[indexName] && ai[indexName].info;
if (!found) { if (!found) {
var iName = self.client.escapeId(indexName); const iName = self.client.escapeId(indexName);
var type = ''; let type = '';
var kind = ''; let kind = '';
if (i.type) { if (i.type) {
type = 'USING ' + i.type; type = 'USING ' + i.type;
} }
@ -401,11 +403,11 @@ function mixinMigration(MySQL, mysql) {
kind = 'UNIQUE'; kind = 'UNIQUE';
} }
var indexedColumns = []; const indexedColumns = [];
var columns = ''; let columns = '';
// if indexes are configured as "keys" // if indexes are configured as "keys"
if (i.keys) { if (i.keys) {
for (var key in i.keys) { for (const key in i.keys) {
if (i.keys[key] !== -1) { if (i.keys[key] !== -1) {
indexedColumns.push(key); indexedColumns.push(key);
} else { } else {
@ -432,20 +434,20 @@ function mixinMigration(MySQL, mysql) {
}; };
MySQL.prototype.getForeignKeySQL = function(model, actualFks, existingFks) { MySQL.prototype.getForeignKeySQL = function(model, actualFks, existingFks) {
var self = this; const self = this;
var m = this.getModelDefinition(model); const m = this.getModelDefinition(model);
var addFksSql = []; const addFksSql = [];
existingFks = existingFks || []; existingFks = existingFks || [];
if (actualFks) { if (actualFks) {
var keys = Object.keys(actualFks); const keys = Object.keys(actualFks);
for (var i = 0; i < keys.length; i++) { for (let i = 0; i < keys.length; i++) {
// all existing fks are already checked in MySQL.prototype.dropForeignKeys // all existing fks are already checked in MySQL.prototype.dropForeignKeys
// so we need check only names - skip if found // so we need check only names - skip if found
if (existingFks.filter(function(fk) { if (existingFks.filter(function(fk) {
return fk.fkName === keys[i]; return fk.fkName === keys[i];
}).length > 0) continue; }).length > 0) continue;
var constraint = self.buildForeignKeyDefinition(model, keys[i]); const constraint = self.buildForeignKeyDefinition(model, keys[i]);
if (constraint) { if (constraint) {
addFksSql.push('ADD ' + constraint); addFksSql.push('ADD ' + constraint);
@ -456,8 +458,8 @@ function mixinMigration(MySQL, mysql) {
}; };
MySQL.prototype.addForeignKeys = function(model, fkSQL, cb) { MySQL.prototype.addForeignKeys = function(model, fkSQL, cb) {
var self = this; const self = this;
var m = this.getModelDefinition(model); const m = this.getModelDefinition(model);
if ((!cb) && ('function' === typeof fkSQL)) { if ((!cb) && ('function' === typeof fkSQL)) {
cb = fkSQL; cb = fkSQL;
@ -465,7 +467,7 @@ function mixinMigration(MySQL, mysql) {
} }
if (!fkSQL) { if (!fkSQL) {
var newFks = m.settings.foreignKeys; const newFks = m.settings.foreignKeys;
if (newFks) if (newFks)
fkSQL = self.getForeignKeySQL(model, newFks); fkSQL = self.getForeignKeySQL(model, newFks);
} }
@ -479,25 +481,25 @@ function mixinMigration(MySQL, mysql) {
}; };
MySQL.prototype.dropForeignKeys = function(model, actualFks) { MySQL.prototype.dropForeignKeys = function(model, actualFks) {
var self = this; const self = this;
var m = this.getModelDefinition(model); const m = this.getModelDefinition(model);
var fks = actualFks; const fks = actualFks;
var sql = []; const sql = [];
var correctFks = m.settings.foreignKeys || {}; const correctFks = m.settings.foreignKeys || {};
// drop foreign keys for removed fields // drop foreign keys for removed fields
if (fks && fks.length) { if (fks && fks.length) {
var removedFks = []; const removedFks = [];
fks.forEach(function(fk) { fks.forEach(function(fk) {
var needsToDrop = false; let needsToDrop = false;
var newFk = correctFks[fk.fkName]; const newFk = correctFks[fk.fkName];
if (newFk) { if (newFk) {
var fkCol = expectedColNameForModel(newFk.foreignKey, m); const fkCol = expectedColNameForModel(newFk.foreignKey, m);
var fkEntity = self.getModelDefinition(newFk.entity); const fkEntity = self.getModelDefinition(newFk.entity);
var fkRefKey = expectedColNameForModel(newFk.entityKey, fkEntity); const fkRefKey = expectedColNameForModel(newFk.entityKey, fkEntity);
var fkEntityName = (typeof newFk.entity === 'object') ? newFk.entity.name : newFk.entity; const fkEntityName = (typeof newFk.entity === 'object') ? newFk.entity.name : newFk.entity;
var fkRefTable = self.table(fkEntityName); const fkRefTable = self.table(fkEntityName);
needsToDrop = fkCol != fk.fkColumnName || needsToDrop = fkCol != fk.fkColumnName ||
fkRefKey != fk.pkColumnName || fkRefKey != fk.pkColumnName ||
fkRefTable != fk.pkTableName || fkRefTable != fk.pkTableName ||
@ -515,7 +517,7 @@ function mixinMigration(MySQL, mysql) {
// update out list of existing keys by removing dropped keys // update out list of existing keys by removing dropped keys
removedFks.forEach(function(k) { removedFks.forEach(function(k) {
var index = actualFks.indexOf(k); const index = actualFks.indexOf(k);
if (index !== -1) actualFks.splice(index, 1); if (index !== -1) actualFks.splice(index, 1);
}); });
} }
@ -534,9 +536,9 @@ function mixinMigration(MySQL, mysql) {
checkOnly = done || false; checkOnly = done || false;
done = actualFks; done = actualFks;
} }
var self = this; const self = this;
var statements = []; let statements = [];
async.series([ async.series([
function(cb) { function(cb) {
@ -561,12 +563,12 @@ function mixinMigration(MySQL, mysql) {
// determine if there are column, index, or foreign keys changes (all require update) // determine if there are column, index, or foreign keys changes (all require update)
if (statements.length) { if (statements.length) {
// get the required alter statements // get the required alter statements
var alterStmt = self.getAlterStatement(model, statements); const alterStmt = self.getAlterStatement(model, statements);
var stmtList = [alterStmt]; const stmtList = [alterStmt];
// set up an object to pass back all changes, changes that have been run, // set up an object to pass back all changes, changes that have been run,
// and foreign key statements that haven't been run // and foreign key statements that haven't been run
var retValues = { const retValues = {
statements: stmtList, statements: stmtList,
query: stmtList.join(';'), query: stmtList.join(';'),
}; };
@ -588,16 +590,16 @@ function mixinMigration(MySQL, mysql) {
}; };
MySQL.prototype.buildForeignKeyDefinition = function(model, keyName) { MySQL.prototype.buildForeignKeyDefinition = function(model, keyName) {
var definition = this.getModelDefinition(model); const definition = this.getModelDefinition(model);
var fk = definition.settings.foreignKeys[keyName]; const fk = definition.settings.foreignKeys[keyName];
if (fk) { if (fk) {
// get the definition of the referenced object // get the definition of the referenced object
var fkEntityName = (typeof fk.entity === 'object') ? fk.entity.name : fk.entity; const fkEntityName = (typeof fk.entity === 'object') ? fk.entity.name : fk.entity;
// verify that the other model in the same DB // verify that the other model in the same DB
if (this._models[fkEntityName]) { if (this._models[fkEntityName]) {
var constraint = ' CONSTRAINT ' + this.client.escapeId(fk.name) + let constraint = ' CONSTRAINT ' + this.client.escapeId(fk.name) +
' FOREIGN KEY (`' + expectedColNameForModel(fk.foreignKey, definition) + '`)' + ' FOREIGN KEY (`' + expectedColNameForModel(fk.foreignKey, definition) + '`)' +
' REFERENCES ' + this.tableEscaped(fkEntityName) + ' REFERENCES ' + this.tableEscaped(fkEntityName) +
'(' + this.client.escapeId(fk.entityKey) + ')'; '(' + this.client.escapeId(fk.entityKey) + ')';
@ -615,17 +617,17 @@ function mixinMigration(MySQL, mysql) {
MySQL.prototype.buildColumnDefinitions = MySQL.prototype.buildColumnDefinitions =
MySQL.prototype.propertiesSQL = function(model) { MySQL.prototype.propertiesSQL = function(model) {
var self = this; const self = this;
var pks = this.idNames(model).map(function(i) { const pks = this.idNames(model).map(function(i) {
return self.columnEscaped(model, i); return self.columnEscaped(model, i);
}); });
var definition = this.getModelDefinition(model); const definition = this.getModelDefinition(model);
var sql = []; const sql = [];
if (pks.length === 1) { if (pks.length === 1) {
var idName = this.idName(model); const idName = this.idName(model);
var idProp = this.getModelDefinition(model).properties[idName]; const idProp = this.getModelDefinition(model).properties[idName];
if (idProp.generated) { if (idProp.generated) {
sql.push(self.columnEscaped(model, idName) + ' ' + sql.push(self.columnEscaped(model, idName) + ' ' +
self.buildColumnDefinition(model, idName) + ' AUTO_INCREMENT PRIMARY KEY'); self.buildColumnDefinition(model, idName) + ' AUTO_INCREMENT PRIMARY KEY');
@ -639,14 +641,14 @@ function mixinMigration(MySQL, mysql) {
if (self.id(model, prop) && pks.length === 1) { if (self.id(model, prop) && pks.length === 1) {
return; return;
} }
var colName = self.columnEscaped(model, prop); const colName = self.columnEscaped(model, prop);
sql.push(colName + ' ' + self.buildColumnDefinition(model, prop)); sql.push(colName + ' ' + self.buildColumnDefinition(model, prop));
}); });
if (pks.length > 1) { if (pks.length > 1) {
sql.push('PRIMARY KEY(' + pks.join(',') + ')'); sql.push('PRIMARY KEY(' + pks.join(',') + ')');
} }
var indexes = self.buildIndexes(model); const indexes = self.buildIndexes(model);
indexes.forEach(function(i) { indexes.forEach(function(i) {
sql.push(i); sql.push(i);
}); });
@ -655,20 +657,20 @@ function mixinMigration(MySQL, mysql) {
}; };
MySQL.prototype.buildIndex = function(model, property) { MySQL.prototype.buildIndex = function(model, property) {
var prop = this.getModelDefinition(model).properties[property]; const prop = this.getModelDefinition(model).properties[property];
var i = prop && prop.index; const i = prop && prop.index;
if (!i) { if (!i) {
return ''; return '';
} }
var type = ''; let type = '';
var kind = ''; let kind = '';
if (i.type) { if (i.type) {
type = 'USING ' + i.type; type = 'USING ' + i.type;
} }
if (i.kind) { if (i.kind) {
kind = i.kind; kind = i.kind;
} }
var columnName = this.columnEscaped(model, property); const columnName = this.columnEscaped(model, property);
if (kind && type) { if (kind && type) {
return (kind + ' INDEX ' + columnName + ' (' + columnName + ') ' + type); return (kind + ' INDEX ' + columnName + ' (' + columnName + ') ' + type);
} else { } else {
@ -680,15 +682,15 @@ function mixinMigration(MySQL, mysql) {
}; };
MySQL.prototype.buildIndexes = function(model) { MySQL.prototype.buildIndexes = function(model) {
var self = this; const self = this;
var indexClauses = []; const indexClauses = [];
var definition = this.getModelDefinition(model); const definition = this.getModelDefinition(model);
var indexes = definition.settings.indexes || {}; const indexes = definition.settings.indexes || {};
// Build model level indexes // Build model level indexes
for (var index in indexes) { for (const index in indexes) {
var i = indexes[index]; const i = indexes[index];
var type = ''; let type = '';
var kind = ''; let kind = '';
if (i.type) { if (i.type) {
type = 'USING ' + i.type; type = 'USING ' + i.type;
} }
@ -699,13 +701,13 @@ function mixinMigration(MySQL, mysql) {
// if index unique indicator is configured // if index unique indicator is configured
kind = 'UNIQUE'; kind = 'UNIQUE';
} }
var indexedColumns = []; const indexedColumns = [];
var indexName = this.escapeName(index); const indexName = this.escapeName(index);
var columns = ''; let columns = '';
// if indexes are configured as "keys" // if indexes are configured as "keys"
if (i.keys) { if (i.keys) {
// for each field in "keys" object // for each field in "keys" object
for (var key in i.keys) { for (const key in i.keys) {
if (i.keys[key] !== -1) { if (i.keys[key] !== -1) {
indexedColumns.push(this.escapeName(key)); indexedColumns.push(this.escapeName(key));
} else { } else {
@ -731,8 +733,8 @@ function mixinMigration(MySQL, mysql) {
} }
} }
// Define index for each of the properties // Define index for each of the properties
for (var p in definition.properties) { for (const p in definition.properties) {
var propIndex = self.buildIndex(model, p); const propIndex = self.buildIndex(model, p);
if (propIndex) { if (propIndex) {
indexClauses.push(propIndex); indexClauses.push(propIndex);
} }
@ -741,8 +743,8 @@ function mixinMigration(MySQL, mysql) {
}; };
MySQL.prototype.buildColumnDefinition = function(model, prop) { MySQL.prototype.buildColumnDefinition = function(model, prop) {
var p = this.getModelDefinition(model).properties[prop]; const p = this.getModelDefinition(model).properties[prop];
var line = this.columnDataType(model, prop) + ' ' + const line = this.columnDataType(model, prop) + ' ' +
(this.isNullable(p) ? 'NULL' : 'NOT NULL'); (this.isNullable(p) ? 'NULL' : 'NOT NULL');
return columnDefault(p, line); return columnDefault(p, line);
}; };
@ -750,18 +752,18 @@ function mixinMigration(MySQL, mysql) {
// override this function from base connector to allow mysql connector to // override this function from base connector to allow mysql connector to
// accept dataPrecision and dataScale as column specific properties // accept dataPrecision and dataScale as column specific properties
MySQL.prototype.columnDataType = function(model, property) { MySQL.prototype.columnDataType = function(model, property) {
var columnMetadata = this.columnMetadata(model, property); const columnMetadata = this.columnMetadata(model, property);
var colType = columnMetadata && columnMetadata.dataType; let colType = columnMetadata && columnMetadata.dataType;
if (colType) { if (colType) {
colType = colType.toUpperCase(); colType = colType.toUpperCase();
} }
var prop = this.getModelDefinition(model).properties[property]; const prop = this.getModelDefinition(model).properties[property];
if (!prop) { if (!prop) {
return null; return null;
} }
var colLength = columnMetadata && columnMetadata.dataLength || prop.length || prop.limit; const colLength = columnMetadata && columnMetadata.dataLength || prop.length || prop.limit;
var colPrecision = columnMetadata && columnMetadata.dataPrecision; const colPrecision = columnMetadata && columnMetadata.dataPrecision;
var colScale = columnMetadata && columnMetadata.dataScale; const colScale = columnMetadata && columnMetadata.dataScale;
// info on setting column specific properties // info on setting column specific properties
// i.e dataLength, dataPrecision, dataScale // i.e dataLength, dataPrecision, dataScale
// https://loopback.io/doc/en/lb3/Model-definition-JSON-file.html // https://loopback.io/doc/en/lb3/Model-definition-JSON-file.html
@ -775,8 +777,8 @@ function mixinMigration(MySQL, mysql) {
}; };
MySQL.prototype.buildColumnType = function buildColumnType(propertyDefinition) { MySQL.prototype.buildColumnType = function buildColumnType(propertyDefinition) {
var dt = ''; let dt = '';
var p = propertyDefinition; const p = propertyDefinition;
switch (p.type.name) { switch (p.type.name) {
default: default:
case 'JSON': case 'JSON':
@ -822,7 +824,7 @@ function mixinMigration(MySQL, mysql) {
return line; return line;
} }
if (typeof p.mysql !== 'undefined' && p.mysql.default) { if (typeof p.mysql !== 'undefined' && p.mysql.default) {
var columnDefault = p.mysql.default; const columnDefault = p.mysql.default;
if (typeof columnDefault === 'number') { if (typeof columnDefault === 'number') {
return line + ' DEFAULT ' + columnDefault; return line + ' DEFAULT ' + columnDefault;
} }
@ -836,7 +838,7 @@ function mixinMigration(MySQL, mysql) {
} }
function columnType(p, defaultType) { function columnType(p, defaultType) {
var dt = defaultType; let dt = defaultType;
if (p.mysql && p.mysql.dataType) { if (p.mysql && p.mysql.dataType) {
dt = String(p.mysql.dataType); dt = String(p.mysql.dataType);
} else if (p.dataType) { } else if (p.dataType) {
@ -846,12 +848,13 @@ function mixinMigration(MySQL, mysql) {
} }
function stringOptionsByType(p, columnType) { function stringOptionsByType(p, columnType) {
let len;
switch (columnType.toLowerCase()) { switch (columnType.toLowerCase()) {
default: default:
case 'varchar': case 'varchar':
// The maximum length for an ID column is 1000 bytes // The maximum length for an ID column is 1000 bytes
// The maximum row size is 64K // The maximum row size is 64K
var len = p.length || p.limit || len = p.length || p.limit ||
((p.type !== String) ? 4096 : p.id || p.index ? 255 : 512); ((p.type !== String) ? 4096 : p.id || p.index ? 255 : 512);
columnType += '(' + len + ')'; columnType += '(' + len + ')';
break; break;
@ -908,8 +911,8 @@ function mixinMigration(MySQL, mysql) {
} }
function floatingPointOptions(p, columnType) { function floatingPointOptions(p, columnType) {
var precision = 16; let precision = 16;
var scale = 8; let scale = 8;
if (p.precision) { if (p.precision) {
precision = Number(p.precision); precision = Number(p.precision);
} }
@ -929,8 +932,8 @@ function mixinMigration(MySQL, mysql) {
/* JS. Also, defaulting column to (9,2) and not allowing non-specified 'DECIMAL' */ /* JS. Also, defaulting column to (9,2) and not allowing non-specified 'DECIMAL' */
/* declaration which would default to DECIMAL(10,0). Instead defaulting to (9,2). */ /* declaration which would default to DECIMAL(10,0). Instead defaulting to (9,2). */
function fixedPointOptions(p, columnType) { function fixedPointOptions(p, columnType) {
var precision = 9; let precision = 9;
var scale = 2; let scale = 2;
if (p.precision) { if (p.precision) {
precision = Number(p.precision); precision = Number(p.precision);
} }
@ -942,7 +945,7 @@ function mixinMigration(MySQL, mysql) {
} }
function integerOptions(p, columnType) { function integerOptions(p, columnType) {
var tmp = 0; let tmp = 0;
if (p.display || p.limit) { if (p.display || p.limit) {
tmp = Number(p.display || p.limit); tmp = Number(p.display || p.limit);
} }
@ -1005,7 +1008,7 @@ function mixinMigration(MySQL, mysql) {
} }
function dateOptions(p, columnType) { function dateOptions(p, columnType) {
var precision = 0; let precision = 0;
if (p.precision) { if (p.precision) {
precision = Number(p.precision); precision = Number(p.precision);
@ -1022,11 +1025,11 @@ function mixinMigration(MySQL, mysql) {
return columnType; return columnType;
} }
function expectedColNameForModel(propName, modelToCheck) { function expectedColNameForModel(propName, modelToCheck) {
var mysql = modelToCheck.properties[propName].mysql; const mysql = modelToCheck.properties[propName].mysql;
if (typeof mysql === 'undefined') { if (typeof mysql === 'undefined') {
return propName; return propName;
} }
var colName = mysql.columnName; const colName = mysql.columnName;
if (typeof colName === 'undefined') { if (typeof colName === 'undefined') {
return propName; return propName;
} }

View File

@ -4,19 +4,19 @@
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT
'use strict'; 'use strict';
var g = require('strong-globalize')(); const g = require('strong-globalize')();
/*! /*!
* Module dependencies * Module dependencies
*/ */
var mysql = require('mysql'); const mysql = require('mysql');
var SqlConnector = require('loopback-connector').SqlConnector; const SqlConnector = require('loopback-connector').SqlConnector;
var ParameterizedSQL = SqlConnector.ParameterizedSQL; const ParameterizedSQL = SqlConnector.ParameterizedSQL;
var EnumFactory = require('./enumFactory').EnumFactory; const EnumFactory = require('./enumFactory').EnumFactory;
var debug = require('debug')('loopback:connector:mysql'); const debug = require('debug')('loopback:connector:mysql');
var setHttpCode = require('./set-http-code'); const setHttpCode = require('./set-http-code');
/** /**
* @module loopback-connector-mysql * @module loopback-connector-mysql
@ -49,8 +49,8 @@ exports.initialize = function initializeDataSource(dataSource, callback) {
exports.MySQL = MySQL; exports.MySQL = MySQL;
function defineMySQLTypes(dataSource) { function defineMySQLTypes(dataSource) {
var modelBuilder = dataSource.modelBuilder; const modelBuilder = dataSource.modelBuilder;
var defineType = modelBuilder.defineValueType ? const defineType = modelBuilder.defineValueType ?
// loopback-datasource-juggler 2.x // loopback-datasource-juggler 2.x
modelBuilder.defineValueType.bind(modelBuilder) : modelBuilder.defineValueType.bind(modelBuilder) :
// loopback-datasource-juggler 1.x // loopback-datasource-juggler 1.x
@ -75,9 +75,9 @@ function MySQL(settings) {
require('util').inherits(MySQL, SqlConnector); require('util').inherits(MySQL, SqlConnector);
MySQL.prototype.connect = function(callback) { MySQL.prototype.connect = function(callback) {
var self = this; const self = this;
var options = generateOptions(this.settings); const options = generateOptions(this.settings);
var s = self.settings || {}; const s = self.settings || {};
if (this.client) { if (this.client) {
if (callback) { if (callback) {
@ -88,7 +88,7 @@ MySQL.prototype.connect = function(callback) {
} else { } else {
this.client = mysql.createPool(options); this.client = mysql.createPool(options);
this.client.getConnection(function(err, connection) { this.client.getConnection(function(err, connection) {
var conn = connection; const conn = connection;
if (!err) { if (!err) {
if (self.debug) { if (self.debug) {
debug('MySQL connection is established: ' + self.settings || {}); debug('MySQL connection is established: ' + self.settings || {});
@ -105,7 +105,7 @@ MySQL.prototype.connect = function(callback) {
}; };
function generateOptions(settings) { function generateOptions(settings) {
var s = settings || {}; const s = settings || {};
if (s.collation) { if (s.collation) {
// Charset should be first 'chunk' of collation. // Charset should be first 'chunk' of collation.
s.charset = s.collation.substr(0, s.collation.indexOf('_')); s.charset = s.collation.substr(0, s.collation.indexOf('_'));
@ -121,7 +121,7 @@ function generateOptions(settings) {
s.connectionLimit = 10; s.connectionLimit = 10;
} }
var options; let options;
if (s.url) { if (s.url) {
// use url to override other settings if url provided // use url to override other settings if url provided
options = s.url; options = s.url;
@ -145,7 +145,7 @@ function generateOptions(settings) {
// Take other options for mysql driver // Take other options for mysql driver
// See https://github.com/strongloop/loopback-connector-mysql/issues/46 // See https://github.com/strongloop/loopback-connector-mysql/issues/46
for (var p in s) { for (const p in s) {
if (p === 'database' && s.createDatabase) { if (p === 'database' && s.createDatabase) {
continue; continue;
} }
@ -170,10 +170,10 @@ function generateOptions(settings) {
* @param {Function} [callback] The callback after the SQL statement is executed * @param {Function} [callback] The callback after the SQL statement is executed
*/ */
MySQL.prototype.executeSQL = function(sql, params, options, callback) { MySQL.prototype.executeSQL = function(sql, params, options, callback) {
var self = this; const self = this;
var client = this.client; const client = this.client;
var debugEnabled = debug.enabled; const debugEnabled = debug.enabled;
var db = this.settings.database; const db = this.settings.database;
if (typeof callback !== 'function') { if (typeof callback !== 'function') {
throw new Error(g.f('{{callback}} should be a function')); throw new Error(g.f('{{callback}} should be a function'));
} }
@ -181,7 +181,7 @@ MySQL.prototype.executeSQL = function(sql, params, options, callback) {
debug('SQL: %s, params: %j', sql, params); debug('SQL: %s, params: %j', sql, params);
} }
var transaction = options.transaction; const transaction = options.transaction;
function handleResponse(connection, err, result) { function handleResponse(connection, err, result) {
if (!transaction) { if (!transaction) {
@ -214,9 +214,9 @@ MySQL.prototype.executeSQL = function(sql, params, options, callback) {
connection.query('USE ??', [db], function(err) { connection.query('USE ??', [db], function(err) {
if (err) { if (err) {
if (err && err.message.match(/(^|: )unknown database/i)) { if (err && err.message.match(/(^|: )unknown database/i)) {
var charset = self.settings.charset; const charset = self.settings.charset;
var collation = self.settings.collation; const collation = self.settings.collation;
var q = 'CREATE DATABASE ?? CHARACTER SET ?? COLLATE ??'; const q = 'CREATE DATABASE ?? CHARACTER SET ?? COLLATE ??';
connection.query(q, [db, charset, collation], function(err) { connection.query(q, [db, charset, collation], function(err) {
if (!err) { if (!err) {
connection.query('USE ??', [db], function(err) { connection.query('USE ??', [db], function(err) {
@ -252,12 +252,12 @@ MySQL.prototype.executeSQL = function(sql, params, options, callback) {
}; };
MySQL.prototype._modifyOrCreate = function(model, data, options, fields, cb) { MySQL.prototype._modifyOrCreate = function(model, data, options, fields, cb) {
var sql = new ParameterizedSQL('INSERT INTO ' + this.tableEscaped(model)); const sql = new ParameterizedSQL('INSERT INTO ' + this.tableEscaped(model));
var columnValues = fields.columnValues; const columnValues = fields.columnValues;
var fieldNames = fields.names; const fieldNames = fields.names;
if (fieldNames.length) { if (fieldNames.length) {
sql.merge('(' + fieldNames.join(',') + ')', ''); sql.merge('(' + fieldNames.join(',') + ')', '');
var values = ParameterizedSQL.join(columnValues, ','); const values = ParameterizedSQL.join(columnValues, ',');
values.sql = 'VALUES(' + values.sql + ')'; values.sql = 'VALUES(' + values.sql + ')';
sql.merge(values); sql.merge(values);
} else { } else {
@ -265,8 +265,8 @@ MySQL.prototype._modifyOrCreate = function(model, data, options, fields, cb) {
} }
sql.merge('ON DUPLICATE KEY UPDATE'); sql.merge('ON DUPLICATE KEY UPDATE');
var setValues = []; const setValues = [];
for (var i = 0, n = fields.names.length; i < n; i++) { for (let i = 0, n = fields.names.length; i < n; i++) {
if (!fields.properties[i].id) { if (!fields.properties[i].id) {
setValues.push(new ParameterizedSQL(fields.names[i] + '=' + setValues.push(new ParameterizedSQL(fields.names[i] + '=' +
columnValues[i].sql, columnValues[i].params)); columnValues[i].sql, columnValues[i].params));
@ -279,7 +279,7 @@ MySQL.prototype._modifyOrCreate = function(model, data, options, fields, cb) {
if (!err && info && info.insertId) { if (!err && info && info.insertId) {
data.id = info.insertId; data.id = info.insertId;
} }
var meta = {}; const meta = {};
// When using the INSERT ... ON DUPLICATE KEY UPDATE statement, // When using the INSERT ... ON DUPLICATE KEY UPDATE statement,
// the returned value is as follows: // the returned value is as follows:
// 1 for each successful INSERT. // 1 for each successful INSERT.
@ -300,7 +300,7 @@ MySQL.prototype._modifyOrCreate = function(model, data, options, fields, cb) {
* @param {Function} [cb] The callback function * @param {Function} [cb] The callback function
*/ */
MySQL.prototype.replaceOrCreate = function(model, data, options, cb) { MySQL.prototype.replaceOrCreate = function(model, data, options, cb) {
var fields = this.buildReplaceFields(model, data); const fields = this.buildReplaceFields(model, data);
this._modifyOrCreate(model, data, options, fields, cb); this._modifyOrCreate(model, data, options, fields, cb);
}; };
@ -314,12 +314,12 @@ MySQL.prototype.replaceOrCreate = function(model, data, options, cb) {
*/ */
MySQL.prototype.save = MySQL.prototype.save =
MySQL.prototype.updateOrCreate = function(model, data, options, cb) { MySQL.prototype.updateOrCreate = function(model, data, options, cb) {
var fields = this.buildFields(model, data); const fields = this.buildFields(model, data);
this._modifyOrCreate(model, data, options, fields, cb); this._modifyOrCreate(model, data, options, fields, cb);
}; };
MySQL.prototype.getInsertedId = function(model, info) { MySQL.prototype.getInsertedId = function(model, info) {
var insertedId = info && typeof info.insertId === 'number' ? const insertedId = info && typeof info.insertId === 'number' ?
info.insertId : undefined; info.insertId : undefined;
return insertedId; return insertedId;
}; };
@ -339,7 +339,7 @@ MySQL.prototype.toColumnValue = function(prop, val) {
return val; return val;
} else { } else {
try { try {
var castNull = prop.type(val); const castNull = prop.type(val);
if (prop.type === Object) { if (prop.type === Object) {
return JSON.stringify(castNull); return JSON.stringify(castNull);
} }
@ -395,7 +395,7 @@ MySQL.prototype.toColumnValue = function(prop, val) {
}; };
MySQL.prototype._serializeObject = function(obj) { MySQL.prototype._serializeObject = function(obj) {
var val; let val;
if (obj && typeof obj.toJSON === 'function') { if (obj && typeof obj.toJSON === 'function') {
obj = obj.toJSON(); obj = obj.toJSON();
} }
@ -495,7 +495,7 @@ MySQL.prototype._buildLimit = function(model, limit, offset) {
}; };
MySQL.prototype.applyPagination = function(model, stmt, filter) { MySQL.prototype.applyPagination = function(model, stmt, filter) {
var limitClause = this._buildLimit(model, filter.limit, const limitClause = this._buildLimit(model, filter.limit,
filter.offset || filter.skip); filter.offset || filter.skip);
return stmt.merge(limitClause); return stmt.merge(limitClause);
}; };
@ -519,7 +519,7 @@ MySQL.prototype.getPlaceholderForValue = function(key) {
}; };
MySQL.prototype.getCountForAffectedRows = function(model, info) { MySQL.prototype.getCountForAffectedRows = function(model, info) {
var affectedRows = info && typeof info.affectedRows === 'number' ? const affectedRows = info && typeof info.affectedRows === 'number' ?
info.affectedRows : undefined; info.affectedRows : undefined;
return affectedRows; return affectedRows;
}; };
@ -548,7 +548,7 @@ MySQL.prototype.ping = function(cb) {
MySQL.prototype.buildExpression = function(columnName, operator, operatorValue, MySQL.prototype.buildExpression = function(columnName, operator, operatorValue,
propertyDefinition) { propertyDefinition) {
if (operator === 'regexp') { if (operator === 'regexp') {
var clause = columnName + ' REGEXP ?'; let clause = columnName + ' REGEXP ?';
// By default, MySQL regexp is not case sensitive. (https://dev.mysql.com/doc/refman/5.7/en/regexp.html) // By default, MySQL regexp is not case sensitive. (https://dev.mysql.com/doc/refman/5.7/en/regexp.html)
// To allow case sensitive regexp query, it has to be binded to a `BINARY` type. // To allow case sensitive regexp query, it has to be binded to a `BINARY` type.
// If ignore case is not specified, search it as case sensitive. // If ignore case is not specified, search it as case sensitive.

View File

@ -5,9 +5,9 @@
'use strict'; 'use strict';
var _ = require('lodash'); const _ = require('lodash');
var codes = { const codes = {
'404': [ '404': [
'ER_DB_DROP_EXISTS', 'ER_DB_DROP_EXISTS',
'ER_BAD_TABLE_ERROR', 'ER_BAD_TABLE_ERROR',
@ -32,10 +32,10 @@ module.exports = function(err) {
err = new Error(err); // Sucks that we weren't given an error object... err = new Error(err); // Sucks that we weren't given an error object...
} }
// Find error prefix // Find error prefix
var msg = err.message; const msg = err.message;
var sqlError = msg.substring(0, msg.indexOf(':')); const sqlError = msg.substring(0, msg.indexOf(':'));
for (var code in codes) { for (const code in codes) {
if (_.includes(codes[code], sqlError)) { if (_.includes(codes[code], sqlError)) {
err.statusCode = code; err.statusCode = code;
} }

View File

@ -4,7 +4,7 @@
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT
'use strict'; 'use strict';
var debug = require('debug')('loopback:connector:mysql:transaction'); const debug = require('debug')('loopback:connector:mysql:transaction');
module.exports = mixinTransaction; module.exports = mixinTransaction;
/*! /*!
@ -30,7 +30,8 @@ function mixinTransaction(MySQL, mysql) {
if (err) return cb(err); if (err) return cb(err);
return cb(null, connection); return cb(null, connection);
}); });
}); },
);
} else { } else {
connection.beginTransaction(function(err) { connection.beginTransaction(function(err) {
if (err) return cb(err); if (err) return cb(err);

View File

@ -29,8 +29,8 @@
}, },
"devDependencies": { "devDependencies": {
"bluebird": "~2.9.10", "bluebird": "~2.9.10",
"eslint": "^4.3.0", "eslint": "^7.7.0",
"eslint-config-loopback": "^8.0.0", "eslint-config-loopback": "^13.1.0",
"juggler-v3": "file:./deps/juggler-v3", "juggler-v3": "file:./deps/juggler-v3",
"juggler-v4": "file:./deps/juggler-v4", "juggler-v4": "file:./deps/juggler-v4",
"loopback-datasource-juggler": "^3.0.0 || ^4.0.0", "loopback-datasource-juggler": "^3.0.0 || ^4.0.0",

View File

@ -18,12 +18,12 @@ process.env.MYSQL_USER =
process.env.MYSQL_PASSWORD = process.env.MYSQL_PASSWORD =
process.env.MYSQL_PASSWORD || process.env.MYSQL_PASSWORD || 'test'; process.env.MYSQL_PASSWORD || process.env.MYSQL_PASSWORD || 'test';
var fs = require('fs'); const fs = require('fs');
var cp = require('child_process'); const cp = require('child_process');
var sql = fs.createReadStream(require.resolve('./test/schema.sql')); const sql = fs.createReadStream(require.resolve('./test/schema.sql'));
var stdio = ['pipe', process.stdout, process.stderr]; const stdio = ['pipe', process.stdout, process.stderr];
var args = ['--user=' + process.env.MYSQL_USER]; const args = ['--user=' + process.env.MYSQL_USER];
if (process.env.MYSQL_HOST) { if (process.env.MYSQL_HOST) {
args.push('--host=' + process.env.MYSQL_HOST); args.push('--host=' + process.env.MYSQL_HOST);
@ -36,7 +36,7 @@ if (process.env.MYSQL_PASSWORD) {
} }
console.log('seeding DB with example db...'); console.log('seeding DB with example db...');
var mysql = cp.spawn('mysql', args, {stdio: stdio}); const mysql = cp.spawn('mysql', args, {stdio: stdio});
sql.pipe(mysql.stdin); sql.pipe(mysql.stdin);
mysql.on('exit', function(code) { mysql.on('exit', function(code) {
console.log('done seeding DB'); console.log('done seeding DB');

View File

@ -5,13 +5,13 @@
'use strict'; 'use strict';
require('./init.js'); require('./init.js');
var assert = require('assert'); const assert = require('assert');
var should = require('should'); const should = require('should');
var DataSource = require('loopback-datasource-juggler').DataSource; const DataSource = require('loopback-datasource-juggler').DataSource;
var mysqlConnector = require('../'); const mysqlConnector = require('../');
var url = require('url'); const url = require('url');
var db, DummyModel, odb, config; let db, DummyModel, odb, config;
describe('connections', function() { describe('connections', function() {
before(function() { before(function() {
@ -25,13 +25,13 @@ describe('connections', function() {
}); });
it('should pass with valid settings', function(done) { it('should pass with valid settings', function(done) {
var db = new DataSource(mysqlConnector, config); const db = new DataSource(mysqlConnector, config);
db.ping(done); db.ping(done);
}); });
it('ignores all other settings when url is present', function(done) { it('ignores all other settings when url is present', function(done) {
var formatedUrl = generateURL(config); const formatedUrl = generateURL(config);
var dbConfig = { const dbConfig = {
url: formatedUrl, url: formatedUrl,
host: 'invalid-hostname', host: 'invalid-hostname',
port: 80, port: 80,
@ -40,15 +40,15 @@ describe('connections', function() {
password: 'invalid-password', password: 'invalid-password',
}; };
var db = new DataSource(mysqlConnector, dbConfig); const db = new DataSource(mysqlConnector, dbConfig);
db.ping(done); db.ping(done);
}); });
it('should use utf8 charset', function(done) { it('should use utf8 charset', function(done) {
var test_set = /utf8/; const test_set = /utf8/;
var test_collo = /utf8_general_ci/; const test_collo = /utf8_general_ci/;
var test_set_str = 'utf8'; const test_set_str = 'utf8';
var test_set_collo = 'utf8_general_ci'; const test_set_collo = 'utf8_general_ci';
charsetTest(test_set, test_collo, test_set_str, test_set_collo, done); charsetTest(test_set, test_collo, test_set_str, test_set_collo, done);
}); });
@ -60,8 +60,8 @@ describe('connections', function() {
}); });
it('should disconnect then connect and ORM should work', function() { it('should disconnect then connect and ORM should work', function() {
var ds = new DataSource(mysqlConnector, config); const ds = new DataSource(mysqlConnector, config);
var Student = ds.define('Student', { const Student = ds.define('Student', {
name: {type: String, length: 255}, name: {type: String, length: 255},
age: {type: Number}, age: {type: Number},
}, { }, {
@ -95,10 +95,10 @@ describe('connections', function() {
}); });
it('should use latin1 charset', function(done) { it('should use latin1 charset', function(done) {
var test_set = /latin1/; const test_set = /latin1/;
var test_collo = /latin1_general_ci/; const test_collo = /latin1_general_ci/;
var test_set_str = 'latin1'; const test_set_str = 'latin1';
var test_set_collo = 'latin1_general_ci'; const test_set_collo = 'latin1_general_ci';
charsetTest(test_set, test_collo, test_set_str, test_set_collo, done); charsetTest(test_set, test_collo, test_set_str, test_set_collo, done);
}); });
@ -112,14 +112,14 @@ describe('connections', function() {
describe('lazyConnect', function() { describe('lazyConnect', function() {
it('should skip connect phase (lazyConnect = true)', function(done) { it('should skip connect phase (lazyConnect = true)', function(done) {
var dbConfig = { const dbConfig = {
host: '127.0.0.1', host: '127.0.0.1',
port: 4, port: 4,
lazyConnect: true, lazyConnect: true,
}; };
var ds = new DataSource(mysqlConnector, dbConfig); const ds = new DataSource(mysqlConnector, dbConfig);
var errTimeout = setTimeout(function() { const errTimeout = setTimeout(function() {
done(); done();
}, 2000); }, 2000);
ds.on('error', function(err) { ds.on('error', function(err) {
@ -129,12 +129,12 @@ describe('connections', function() {
}); });
it('should report connection error (lazyConnect = false)', function(done) { it('should report connection error (lazyConnect = false)', function(done) {
var dbConfig = { const dbConfig = {
host: '127.0.0.1', host: '127.0.0.1',
port: 4, port: 4,
lazyConnect: false, lazyConnect: false,
}; };
var ds = new DataSource(mysqlConnector, dbConfig); const ds = new DataSource(mysqlConnector, dbConfig);
ds.on('error', function(err) { ds.on('error', function(err) {
err.message.should.containEql('ECONNREFUSED'); err.message.should.containEql('ECONNREFUSED');
@ -152,7 +152,7 @@ function charsetTest(test_set, test_collo, test_set_str, test_set_collo, done) {
createDatabase: true}); createDatabase: true});
DummyModel = db.define('DummyModel', {string: String}); DummyModel = db.define('DummyModel', {string: String});
db.automigrate(function() { db.automigrate(function() {
var q = 'SELECT DEFAULT_COLLATION_NAME' + const q = 'SELECT DEFAULT_COLLATION_NAME' +
' FROM information_schema.SCHEMATA WHERE SCHEMA_NAME = ' + ' FROM information_schema.SCHEMATA WHERE SCHEMA_NAME = ' +
db.driver.escape(db.settings.database) + ' LIMIT 1'; db.driver.escape(db.settings.database) + ' LIMIT 1';
db.connector.execute(q, function(err, r) { db.connector.execute(q, function(err, r) {
@ -160,8 +160,8 @@ function charsetTest(test_set, test_collo, test_set_str, test_set_collo, done) {
should(r[0].DEFAULT_COLLATION_NAME).match(test_collo); should(r[0].DEFAULT_COLLATION_NAME).match(test_collo);
db.connector.execute('SHOW VARIABLES LIKE "character_set%"', function(err, r) { db.connector.execute('SHOW VARIABLES LIKE "character_set%"', function(err, r) {
assert.ok(!err); assert.ok(!err);
var hit_all = 0; let hit_all = 0;
for (var result in r) { for (const result in r) {
hit_all += matchResult(r[result], 'character_set_connection', test_set); hit_all += matchResult(r[result], 'character_set_connection', test_set);
hit_all += matchResult(r[result], 'character_set_database', test_set); hit_all += matchResult(r[result], 'character_set_database', test_set);
hit_all += matchResult(r[result], 'character_set_results', test_set); hit_all += matchResult(r[result], 'character_set_results', test_set);
@ -171,8 +171,8 @@ function charsetTest(test_set, test_collo, test_set_str, test_set_collo, done) {
}); });
db.connector.execute('SHOW VARIABLES LIKE "collation%"', function(err, r) { db.connector.execute('SHOW VARIABLES LIKE "collation%"', function(err, r) {
assert.ok(!err); assert.ok(!err);
var hit_all = 0; let hit_all = 0;
for (var result in r) { for (const result in r) {
hit_all += matchResult(r[result], 'collation_connection', test_set); hit_all += matchResult(r[result], 'collation_connection', test_set);
hit_all += matchResult(r[result], 'collation_database', test_set); hit_all += matchResult(r[result], 'collation_database', test_set);
} }
@ -193,12 +193,12 @@ function matchResult(result, variable_name, match) {
return 0; return 0;
} }
var query = function(sql, cb) { function query(sql, cb) {
odb.connector.execute(sql, cb); odb.connector.execute(sql, cb);
}; }
function generateURL(config) { function generateURL(config) {
var urlObj = { const urlObj = {
protocol: 'mysql', protocol: 'mysql',
auth: config.username || '', auth: config.username || '',
hostname: config.host, hostname: config.host,
@ -208,6 +208,6 @@ function generateURL(config) {
if (config.password) { if (config.password) {
urlObj.auth += ':' + config.password; urlObj.auth += ':' + config.password;
} }
var formatedUrl = url.format(urlObj); const formatedUrl = url.format(urlObj);
return formatedUrl; return formatedUrl;
} }

View File

@ -5,22 +5,22 @@
'use strict'; 'use strict';
require('./init.js'); require('./init.js');
var assert = require('assert'); const assert = require('assert');
var _ = require('lodash'); const _ = require('lodash');
const GeoPoint = require('loopback-datasource-juggler').GeoPoint; const GeoPoint = require('loopback-datasource-juggler').GeoPoint;
var db, BlobModel, EnumModel, ANIMAL_ENUM, City, Account; let db, BlobModel, EnumModel, ANIMAL_ENUM, City, Account;
var mysqlVersion; let mysqlVersion;
describe('MySQL specific datatypes', function() { describe('MySQL specific datatypes', function() {
before(setup); before(setup);
describe('Support explicit datatypes on a property', function() { describe('Support explicit datatypes on a property', function() {
var dateString1 = '2017-04-01'; const dateString1 = '2017-04-01';
var dateString2 = '2016-01-30'; const dateString2 = '2016-01-30';
var dateForTransactions = [new Date(dateString1).toString(), new Date(dateString2).toString()]; const dateForTransactions = [new Date(dateString1).toString(), new Date(dateString2).toString()];
var data = [ const data = [
{ {
id: 1, id: 1,
type: 'Student - Basic', type: 'Student - Basic',
@ -111,7 +111,7 @@ describe('MySQL specific datatypes', function() {
}); });
it('update an instance', function(done) { it('update an instance', function(done) {
var updatedData = { const updatedData = {
type: 'Student - Basic', type: 'Student - Basic',
amount: 1155.77, amount: 1155.77,
}; };
@ -143,7 +143,7 @@ describe('MySQL specific datatypes', function() {
}); });
it('should create a model instance with Enums', function(done) { it('should create a model instance with Enums', function(done) {
var em = EnumModel.create({animal: ANIMAL_ENUM.CAT, condition: 'sleepy', mood: 'happy'}, function(err, obj) { const em = EnumModel.create({animal: ANIMAL_ENUM.CAT, condition: 'sleepy', mood: 'happy'}, function(err, obj) {
if (err) return done(err); if (err) return done(err);
assert.equal(obj.condition, 'sleepy'); assert.equal(obj.condition, 'sleepy');
EnumModel.findOne({where: {animal: ANIMAL_ENUM.CAT}}, function(err, found) { EnumModel.findOne({where: {animal: ANIMAL_ENUM.CAT}}, function(err, found) {
@ -168,9 +168,9 @@ describe('MySQL specific datatypes', function() {
}); });
it('should create a model instance with object/json types', function(done) { it('should create a model instance with object/json types', function(done) {
var note = {a: 1, b: '2'}; const note = {a: 1, b: '2'};
var extras = {c: 3, d: '4'}; const extras = {c: 3, d: '4'};
var em = EnumModel.create({animal: ANIMAL_ENUM.DOG, condition: 'sleepy', const em = EnumModel.create({animal: ANIMAL_ENUM.DOG, condition: 'sleepy',
mood: 'happy', note: note, extras: extras}, function(err, obj) { mood: 'happy', note: note, extras: extras}, function(err, obj) {
if (err) return done(err); if (err) return done(err);
assert.equal(obj.condition, 'sleepy'); assert.equal(obj.condition, 'sleepy');
@ -185,9 +185,9 @@ describe('MySQL specific datatypes', function() {
}); });
}); });
it('should create a model instance with binary types', function(done) { it('should create a model instance with binary types', function(done) {
var str = 'This is a test'; const str = 'This is a test';
var name = 'bob'; const name = 'bob';
var bob = {name: name, bin: new Buffer.from(str)}; const bob = {name: name, bin: new Buffer.from(str)};
BlobModel.create(bob, function(err, obj) { BlobModel.create(bob, function(err, obj) {
if (err) return done(err); if (err) return done(err);
assert.equal(obj.bin.toString(), str); assert.equal(obj.bin.toString(), str);
@ -199,20 +199,20 @@ describe('MySQL specific datatypes', function() {
}); });
}); });
it('should create a model instance with geopoint type', function(done) { it('should create a model instance with geopoint type', function(done) {
var city1 = { const city1 = {
name: 'North York', name: 'North York',
loc: { loc: {
lat: 43.761539, lat: 43.761539,
lng: -79.411079, lng: -79.411079,
}, },
}; };
var xcor, ycor; let xcor, ycor;
City.create(city1, function(err, res) { City.create(city1, function(err, res) {
if (err) return done(err); if (err) return done(err);
const loc_in_geo_type = new GeoPoint(city1.loc); const loc_in_geo_type = new GeoPoint(city1.loc);
res.loc.should.deepEqual(loc_in_geo_type); res.loc.should.deepEqual(loc_in_geo_type);
res.name.should.equal(city1.name); res.name.should.equal(city1.name);
var sqlStmt = 'select ST_X(loc),ST_Y(loc) from City where id=1'; const sqlStmt = 'select ST_X(loc),ST_Y(loc) from City where id=1';
db.connector.execute(sqlStmt, function(err, res) { db.connector.execute(sqlStmt, function(err, res) {
if (err) return done(err); if (err) return done(err);
xcor = res[0]['ST_X(loc)']; xcor = res[0]['ST_X(loc)'];
@ -262,16 +262,16 @@ function setup(done) {
}); });
} }
var query = function(sql, cb) { function query(sql, cb) {
db.adapter.execute(sql, cb); db.adapter.execute(sql, cb);
}; }
var blankDatabase = function(db, cb) { function blankDatabase(db, cb) {
var dbn = db.settings.database; const dbn = db.settings.database;
var cs = db.settings.charset; const cs = db.settings.charset;
var co = db.settings.collation; const co = db.settings.collation;
query('DROP DATABASE IF EXISTS ' + dbn, function(err) { query('DROP DATABASE IF EXISTS ' + dbn, function(err) {
var q = 'CREATE DATABASE ' + dbn; let q = 'CREATE DATABASE ' + dbn;
if (cs) { if (cs) {
q += ' CHARACTER SET ' + cs; q += ' CHARACTER SET ' + cs;
} }
@ -282,36 +282,4 @@ var blankDatabase = function(db, cb) {
query('USE ' + dbn, cb); query('USE ' + dbn, cb);
}); });
}); });
}; }
var getFields = function(model, cb) {
query('SHOW FIELDS FROM ' + model, function(err, res) {
if (err) {
cb(err);
} else {
var fields = {};
res.forEach(function(field) {
fields[field.Field] = field;
});
cb(err, fields);
}
});
};
var getIndexes = function(model, cb) {
query('SHOW INDEXES FROM ' + model, function(err, res) {
if (err) {
console.log(err);
cb(err);
} else {
var indexes = {};
// Note: this will only show the first key of compound keys
res.forEach(function(index) {
if (parseInt(index.Seq_in_index, 10) == 1) {
indexes[index.Key_name] = index;
}
});
cb(err, indexes);
}
});
};

View File

@ -5,13 +5,13 @@
'use strict'; 'use strict';
var DateString = require('../node_modules/loopback-datasource-juggler/lib/date-string'); const DateString = require('../node_modules/loopback-datasource-juggler/lib/date-string');
var fmt = require('util').format; const fmt = require('util').format;
var should = require('./init.js'); const should = require('./init.js');
var db, Person; let db, Person;
describe('MySQL datetime handling', function() { describe('MySQL datetime handling', function() {
var personDefinition = { const personDefinition = {
name: String, name: String,
gender: String, gender: String,
married: Boolean, married: Boolean,
@ -47,7 +47,7 @@ describe('MySQL datetime handling', function() {
}); });
it('should allow use of DateStrings', () => { it('should allow use of DateStrings', () => {
var d = new DateString('1971-06-22'); const d = new DateString('1971-06-22');
return Person.create({ return Person.create({
name: 'Mr. Pink', name: 'Mr. Pink',
gender: 'M', gender: 'M',
@ -63,7 +63,7 @@ describe('MySQL datetime handling', function() {
}); });
describe('should allow use of alternate timezone settings', function() { describe('should allow use of alternate timezone settings', function() {
var d = new Date('1971-06-22T00:00:00.000Z'); const d = new Date('1971-06-22T00:00:00.000Z');
testDateTime(d, '+04:00', '1971-06-22 04:00:00'); testDateTime(d, '+04:00', '1971-06-22 04:00:00');
testDateTime(d, '-04:00', '1971-06-21 20:00:00'); testDateTime(d, '-04:00', '1971-06-21 20:00:00');
testDateTime(d, '-11:00', '1971-06-21 13:00:00'); testDateTime(d, '-11:00', '1971-06-21 13:00:00');
@ -74,7 +74,7 @@ describe('MySQL datetime handling', function() {
setConnectionTimezones(tz); setConnectionTimezones(tz);
db.settings.legacyUtcDateProcessing = false; db.settings.legacyUtcDateProcessing = false;
db.settings.timezone = tz; db.settings.timezone = tz;
var dt = new Date(date); const dt = new Date(date);
return Person.create({ return Person.create({
name: 'Mr. Pink', name: 'Mr. Pink',
gender: 'M', gender: 'M',
@ -90,7 +90,7 @@ describe('MySQL datetime handling', function() {
}); });
it('should allow use of fractional seconds', function() { it('should allow use of fractional seconds', function() {
var d = new Date('1971-06-22T12:34:56.789Z'); const d = new Date('1971-06-22T12:34:56.789Z');
return Person.create({ return Person.create({
name: 'Mr. Pink', name: 'Mr. Pink',
gender: 'M', gender: 'M',
@ -99,7 +99,7 @@ describe('MySQL datetime handling', function() {
return Person.findById(inst.id); return Person.findById(inst.id);
}).then(function(inst) { }).then(function(inst) {
inst.should.not.eql(null); inst.should.not.eql(null);
var lastLogon = new Date(inst.lastLogon); const lastLogon = new Date(inst.lastLogon);
lastLogon.toJSON().should.eql(d.toJSON()); lastLogon.toJSON().should.eql(d.toJSON());
return; return;
}); });

View File

@ -9,9 +9,9 @@ module.exports = require('should');
const juggler = require('loopback-datasource-juggler'); const juggler = require('loopback-datasource-juggler');
let DataSource = juggler.DataSource; let DataSource = juggler.DataSource;
var config = require('rc')('loopback', {test: {mysql: {}}}).test.mysql; const config = require('rc')('loopback', {test: {mysql: {}}}).test.mysql;
global.getConfig = function(options) { global.getConfig = function(options) {
var dbConf = { const dbConf = {
host: process.env.MYSQL_HOST || config.host || 'localhost', host: process.env.MYSQL_HOST || config.host || 'localhost',
port: process.env.MYSQL_PORT || config.port || 3306, port: process.env.MYSQL_PORT || config.port || 3306,
database: process.env.MYSQL_DATABASE || 'myapp_test', database: process.env.MYSQL_DATABASE || 'myapp_test',
@ -21,7 +21,7 @@ global.getConfig = function(options) {
}; };
if (options) { if (options) {
for (var el in options) { for (const el in options) {
dbConf[el] = options[el]; dbConf[el] = options[el];
} }
} }

View File

@ -4,14 +4,14 @@
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT
'use strict'; 'use strict';
var assert = require('assert'); const assert = require('assert');
var async = require('async'); const async = require('async');
var platform = require('./helpers/platform'); const platform = require('./helpers/platform');
var should = require('./init'); const should = require('./init');
var Schema = require('loopback-datasource-juggler').Schema; const Schema = require('loopback-datasource-juggler').Schema;
var db, UserData, StringData, NumberData, DateData, DefaultData, SimpleEmployee; let db, UserData, StringData, NumberData, DateData, DefaultData, SimpleEmployee;
var mysqlVersion; let mysqlVersion;
describe('migrations', function() { describe('migrations', function() {
before(setup); before(setup);
@ -263,7 +263,7 @@ describe('migrations', function() {
if (platform.isWindows) { if (platform.isWindows) {
return done(); return done();
} }
var userExists = function(cb) { const userExists = function(cb) {
query('SELECT * FROM UserData', function(err, res) { query('SELECT * FROM UserData', function(err, res) {
cb(!err && res[0].email == 'test@example.com'); cb(!err && res[0].email == 'test@example.com');
}); });
@ -338,7 +338,8 @@ describe('migrations', function() {
assert.equal(found.floater, 12345678.123456); assert.equal(found.floater, 12345678.123456);
done(); done();
}); });
}); },
);
}); });
// Reference: http://dev.mysql.com/doc/refman/5.7/en/out-of-range-and-overflow.html // Reference: http://dev.mysql.com/doc/refman/5.7/en/out-of-range-and-overflow.html
@ -377,7 +378,7 @@ describe('migrations', function() {
DefaultData.create({}, function(err, obj) { DefaultData.create({}, function(err, obj) {
assert.ok(!err); assert.ok(!err);
assert.ok(obj); assert.ok(obj);
var now = new Date(); const now = new Date();
DefaultData.findById(obj.id, function(err, found) { DefaultData.findById(obj.id, function(err, found) {
now.setSeconds(0); now.setSeconds(0);
found.dateTime.setSeconds(0); found.dateTime.setSeconds(0);
@ -501,7 +502,7 @@ describe('migrations', function() {
query('INSERT INTO `DateData` ' + query('INSERT INTO `DateData` ' +
'(`dateTime`, `timestamp`) ' + '(`dateTime`, `timestamp`) ' +
'VALUES("0000-00-00 00:00:00", "0000-00-00 00:00:00") ', function(err) { 'VALUES("0000-00-00 00:00:00", "0000-00-00 00:00:00") ', function(err) {
var errMsg = 'ER_TRUNCATED_WRONG_VALUE: Incorrect datetime value: ' + const errMsg = 'ER_TRUNCATED_WRONG_VALUE: Incorrect datetime value: ' +
'\'0000-00-00 00:00:00\' for column \'dateTime\' at row 1'; '\'0000-00-00 00:00:00\' for column \'dateTime\' at row 1';
assert(err); assert(err);
assert.equal(err.message, errMsg); assert.equal(err.message, errMsg);
@ -517,7 +518,7 @@ describe('migrations', function() {
query('INSERT INTO `DateData` ' + query('INSERT INTO `DateData` ' +
'(`dateTime`, `timestamp`) ' + '(`dateTime`, `timestamp`) ' +
'VALUES("1000-01-01 00:00:00", "0000-00-00 00:00:00") ', function(err) { 'VALUES("1000-01-01 00:00:00", "0000-00-00 00:00:00") ', function(err) {
var errMsg = 'ER_TRUNCATED_WRONG_VALUE: Incorrect datetime value: ' + const errMsg = 'ER_TRUNCATED_WRONG_VALUE: Incorrect datetime value: ' +
'\'0000-00-00 00:00:00\' for column \'timestamp\' at row 1'; '\'0000-00-00 00:00:00\' for column \'timestamp\' at row 1';
assert(err); assert(err);
assert.equal(err.message, errMsg); assert.equal(err.message, errMsg);
@ -608,16 +609,16 @@ function setup(done) {
}); });
} }
var query = function(sql, cb) { function query(sql, cb) {
db.adapter.execute(sql, cb); db.adapter.execute(sql, cb);
}; }
var blankDatabase = function(db, cb) { function blankDatabase(db, cb) {
var dbn = db.settings.database; const dbn = db.settings.database;
var cs = db.settings.charset; const cs = db.settings.charset;
var co = db.settings.collation; const co = db.settings.collation;
query('DROP DATABASE IF EXISTS ' + dbn, function(err) { query('DROP DATABASE IF EXISTS ' + dbn, function(err) {
var q = 'CREATE DATABASE ' + dbn; let q = 'CREATE DATABASE ' + dbn;
if (cs) { if (cs) {
q += ' CHARACTER SET ' + cs; q += ' CHARACTER SET ' + cs;
} }
@ -628,14 +629,14 @@ var blankDatabase = function(db, cb) {
query('USE ' + dbn, cb); query('USE ' + dbn, cb);
}); });
}); });
}; }
var getFields = function(model, cb) { function getFields(model, cb) {
query('SHOW FIELDS FROM ' + model, function(err, res) { query('SHOW FIELDS FROM ' + model, function(err, res) {
if (err) { if (err) {
cb(err); cb(err);
} else { } else {
var fields = {}; const fields = {};
res.forEach(function(field) { res.forEach(function(field) {
fields[field.Field] = field; fields[field.Field] = field;
}); });
@ -644,15 +645,15 @@ var getFields = function(model, cb) {
cb(err, JSON.parse(JSON.stringify(fields))); cb(err, JSON.parse(JSON.stringify(fields)));
} }
}); });
}; }
var getIndexes = function(model, cb) { function getIndexes(model, cb) {
query('SHOW INDEXES FROM ' + model, function(err, res) { query('SHOW INDEXES FROM ' + model, function(err, res) {
if (err) { if (err) {
console.log(err); console.log(err);
cb(err); cb(err);
} else { } else {
var indexes = {}; const indexes = {};
// Note: this will only show the first key of compound keys // Note: this will only show the first key of compound keys
res.forEach(function(index) { res.forEach(function(index) {
if (parseInt(index.Seq_in_index, 10) == 1) { if (parseInt(index.Seq_in_index, 10) == 1) {
@ -662,4 +663,4 @@ var getIndexes = function(model, cb) {
cb(err, indexes); cb(err, indexes);
} }
}); });
}; }

View File

@ -4,9 +4,9 @@
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT
'use strict'; 'use strict';
var assert = require('assert'); const assert = require('assert');
require('./init'); require('./init');
var ds; let ds;
before(function() { before(function() {
ds = global.getDataSource(); ds = global.getDataSource();
@ -19,7 +19,7 @@ describe('MySQL connector', function() {
describe('escape index names upon automigrate', function() { describe('escape index names upon automigrate', function() {
before(function(done) { before(function(done) {
var messageSchema = { const messageSchema = {
'name': 'Message', 'name': 'Message',
'options': { 'options': {
'idInjection': false, 'idInjection': false,
@ -68,7 +68,7 @@ describe('MySQL connector', function() {
}); });
it('should auto migrate/update tables', function(done) { it('should auto migrate/update tables', function(done) {
var schema_v1 = { const schema_v1 = {
'name': 'CustomerTest', 'name': 'CustomerTest',
'options': { 'options': {
'idInjection': false, 'idInjection': false,
@ -123,7 +123,7 @@ describe('MySQL connector', function() {
}, },
}; };
var schema_v2 = { const schema_v2 = {
'name': 'CustomerTest', 'name': 'CustomerTest',
'options': { 'options': {
'idInjection': false, 'idInjection': false,
@ -222,7 +222,7 @@ describe('MySQL connector', function() {
assert(isActual, 'isActual should return true after automigrate'); assert(isActual, 'isActual should return true after automigrate');
ds.discoverModelProperties('customer_test', function(err, props) { ds.discoverModelProperties('customer_test', function(err, props) {
assert.equal(props.length, 5); assert.equal(props.length, 5);
var names = props.map(function(p) { const names = props.map(function(p) {
return p.columnName; return p.columnName;
}); });
assert.equal(props[0].nullable, 'N'); assert.equal(props[0].nullable, 'N');
@ -250,7 +250,7 @@ describe('MySQL connector', function() {
ds.discoverModelProperties('customer_test', function(err, props) { ds.discoverModelProperties('customer_test', function(err, props) {
if (err) return done(err); if (err) return done(err);
assert.equal(props.length, 7); assert.equal(props.length, 7);
var names = props.map(function(p) { const names = props.map(function(p) {
return p.columnName; return p.columnName;
}); });
assert.equal(names[0], 'id'); assert.equal(names[0], 'id');
@ -287,7 +287,7 @@ describe('MySQL connector', function() {
}); });
it('should auto migrate/update foreign keys in tables', function(done) { it('should auto migrate/update foreign keys in tables', function(done) {
var customer2_schema = { const customer2_schema = {
'name': 'CustomerTest2', 'name': 'CustomerTest2',
'options': { 'options': {
'idInjection': false, 'idInjection': false,
@ -318,7 +318,7 @@ describe('MySQL connector', function() {
}, },
}, },
}; };
var customer3_schema = { const customer3_schema = {
'name': 'CustomerTest3', 'name': 'CustomerTest3',
'options': { 'options': {
'idInjection': false, 'idInjection': false,
@ -350,7 +350,7 @@ describe('MySQL connector', function() {
}, },
}; };
var schema_v1 = { const schema_v1 = {
'name': 'OrderTest', 'name': 'OrderTest',
'options': { 'options': {
'idInjection': false, 'idInjection': false,
@ -385,7 +385,7 @@ describe('MySQL connector', function() {
}, },
}; };
var schema_v2 = { const schema_v2 = {
'name': 'OrderTest', 'name': 'OrderTest',
'options': { 'options': {
'idInjection': false, 'idInjection': false,
@ -423,7 +423,7 @@ describe('MySQL connector', function() {
}, },
}; };
var schema_v3 = { const schema_v3 = {
'name': 'OrderTest', 'name': 'OrderTest',
'options': { 'options': {
'idInjection': false, 'idInjection': false,
@ -453,7 +453,7 @@ describe('MySQL connector', function() {
}, },
}; };
var foreignKeySelect = const foreignKeySelect =
'SELECT COLUMN_NAME,CONSTRAINT_NAME,REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME ' + 'SELECT COLUMN_NAME,CONSTRAINT_NAME,REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME ' +
'FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE ' + 'FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE ' +
'WHERE REFERENCED_TABLE_SCHEMA = "myapp_test" ' + 'WHERE REFERENCED_TABLE_SCHEMA = "myapp_test" ' +
@ -537,7 +537,7 @@ describe('MySQL connector', function() {
}); });
it('should auto migrate/update foreign keys in tables multiple times without error', function(done) { it('should auto migrate/update foreign keys in tables multiple times without error', function(done) {
var customer3_schema = { const customer3_schema = {
'name': 'CustomerTest3', 'name': 'CustomerTest3',
'options': { 'options': {
'idInjection': false, 'idInjection': false,
@ -569,7 +569,7 @@ describe('MySQL connector', function() {
}, },
}; };
var schema_v1 = { const schema_v1 = {
'name': 'OrderTest', 'name': 'OrderTest',
'options': { 'options': {
'idInjection': false, 'idInjection': false,
@ -621,7 +621,7 @@ describe('MySQL connector', function() {
}); });
it('should auto migrate/update foreign keys with onUpdate and onDelete in tables', function(done) { it('should auto migrate/update foreign keys with onUpdate and onDelete in tables', function(done) {
var customer2_schema = { const customer2_schema = {
'name': 'CustomerTest2', 'name': 'CustomerTest2',
'options': { 'options': {
'idInjection': false, 'idInjection': false,
@ -653,7 +653,7 @@ describe('MySQL connector', function() {
}, },
}; };
var schema_v1 = { const schema_v1 = {
'name': 'OrderTest', 'name': 'OrderTest',
'options': { 'options': {
'idInjection': false, 'idInjection': false,
@ -690,7 +690,7 @@ describe('MySQL connector', function() {
}, },
}; };
var schema_v2 = { const schema_v2 = {
'name': 'OrderTest', 'name': 'OrderTest',
'options': { 'options': {
'idInjection': false, 'idInjection': false,
@ -727,12 +727,12 @@ describe('MySQL connector', function() {
}, },
}; };
var foreignKeySelect = const foreignKeySelect =
'SELECT COLUMN_NAME,CONSTRAINT_NAME,REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME ' + 'SELECT COLUMN_NAME,CONSTRAINT_NAME,REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME ' +
'FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE ' + 'FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE ' +
'WHERE REFERENCED_TABLE_SCHEMA = "myapp_test" ' + 'WHERE REFERENCED_TABLE_SCHEMA = "myapp_test" ' +
'AND TABLE_NAME = "order_test"'; 'AND TABLE_NAME = "order_test"';
var getCreateTable = 'SHOW CREATE TABLE `myapp_test`.`order_test`'; const getCreateTable = 'SHOW CREATE TABLE `myapp_test`.`order_test`';
ds.createModel(customer2_schema.name, customer2_schema.properties, customer2_schema.options); ds.createModel(customer2_schema.name, customer2_schema.properties, customer2_schema.options);
ds.createModel(schema_v1.name, schema_v1.properties, schema_v1.options); ds.createModel(schema_v1.name, schema_v1.properties, schema_v1.options);
@ -789,7 +789,7 @@ describe('MySQL connector', function() {
}); });
function setupAltColNameData() { function setupAltColNameData() {
var schema = { const schema = {
name: 'ColRenameTest', name: 'ColRenameTest',
options: { options: {
idInjection: false, idInjection: false,
@ -845,7 +845,7 @@ describe('MySQL connector', function() {
it('should update the nullable property of "first_name" to false', function(done) { it('should update the nullable property of "first_name" to false', function(done) {
// update the model "required" property // update the model "required" property
var schema = { const schema = {
name: 'ColRenameTest', name: 'ColRenameTest',
options: { options: {
idInjection: false, idInjection: false,

View File

@ -5,11 +5,11 @@
'use strict'; 'use strict';
process.env.NODE_ENV = 'test'; process.env.NODE_ENV = 'test';
var should = require('should'); const should = require('should');
var assert = require('assert'); const assert = require('assert');
var DataSource = require('loopback-datasource-juggler').DataSource; const DataSource = require('loopback-datasource-juggler').DataSource;
var db, config; let db, config;
before(function(done) { before(function(done) {
require('./init'); require('./init');
@ -42,7 +42,7 @@ describe('discoverModels', function() {
console.error(err); console.error(err);
done(err); done(err);
} else { } else {
var views = false; let views = false;
assert(models.length > 0, 'some models returned'); assert(models.length > 0, 'some models returned');
models.forEach(function(m) { models.forEach(function(m) {
if (m.type === 'view') { if (m.type === 'view') {
@ -66,7 +66,7 @@ describe('discoverModels', function() {
console.error(err); console.error(err);
done(err); done(err);
} else { } else {
var views = false; const views = false;
assert(models.length > 0, 'some models returned'); assert(models.length > 0, 'some models returned');
models.forEach(function(m) { models.forEach(function(m) {
assert.equal(m.owner.toLowerCase(), config.database.toLowerCase()); assert.equal(m.owner.toLowerCase(), config.database.toLowerCase());
@ -109,7 +109,7 @@ describe('Discover models including other users', function() {
console.error(err); console.error(err);
done(err); done(err);
} else { } else {
var others = false; let others = false;
assert.equal(3, models.length); assert.equal(3, models.length);
models.forEach(function(m) { models.forEach(function(m) {
assert(m.owner); assert(m.owner);
@ -227,7 +227,7 @@ describe('Discover model generated columns', function() {
}); });
describe('Discover LDL schema from a table', function() { describe('Discover LDL schema from a table', function() {
var schema; let schema;
before(function(done) { before(function(done) {
db.discoverSchema('INVENTORY', {owner: 'STRONGLOOP'}, function(err, schema_) { db.discoverSchema('INVENTORY', {owner: 'STRONGLOOP'}, function(err, schema_) {
schema = schema_; schema = schema_;
@ -235,8 +235,8 @@ describe('Discover LDL schema from a table', function() {
}); });
}); });
it('should return an LDL schema for INVENTORY', function() { it('should return an LDL schema for INVENTORY', function() {
var productId = 'productId' in schema.properties ? 'productId' : 'productid'; const productId = 'productId' in schema.properties ? 'productId' : 'productid';
var locationId = 'locationId' in schema.properties ? 'locationId' : 'locationid'; const locationId = 'locationId' in schema.properties ? 'locationId' : 'locationid';
assert.strictEqual(schema.name, 'Inventory'); assert.strictEqual(schema.name, 'Inventory');
assert.ok(/STRONGLOOP/i.test(schema.options.mysql.schema)); assert.ok(/STRONGLOOP/i.test(schema.options.mysql.schema));
assert.strictEqual(schema.options.mysql.table, 'INVENTORY'); assert.strictEqual(schema.options.mysql.table, 'INVENTORY');
@ -257,7 +257,7 @@ describe('Discover LDL schema from a table', function() {
}); });
describe('Discover and build models', function() { describe('Discover and build models', function() {
var models; let models;
before(function(done) { before(function(done) {
db.discoverAndBuildModels('INVENTORY', {owner: 'STRONGLOOP', visited: {}, associations: true}, db.discoverAndBuildModels('INVENTORY', {owner: 'STRONGLOOP', visited: {}, associations: true},
function(err, models_) { function(err, models_) {
@ -267,9 +267,9 @@ describe('Discover and build models', function() {
}); });
it('should discover and build models', function() { it('should discover and build models', function() {
assert(models.Inventory, 'Inventory model should be discovered and built'); assert(models.Inventory, 'Inventory model should be discovered and built');
var schema = models.Inventory.definition; const schema = models.Inventory.definition;
var productId = 'productId' in schema.properties ? 'productId' : 'productid'; const productId = 'productId' in schema.properties ? 'productId' : 'productid';
var locationId = 'locationId' in schema.properties ? 'locationId' : 'locationid'; const locationId = 'locationId' in schema.properties ? 'locationId' : 'locationid';
assert(/STRONGLOOP/i.test(schema.settings.mysql.schema)); assert(/STRONGLOOP/i.test(schema.settings.mysql.schema));
assert.strictEqual(schema.settings.mysql.table, 'INVENTORY'); assert.strictEqual(schema.settings.mysql.table, 'INVENTORY');
assert(schema.properties[productId]); assert(schema.properties[productId]);
@ -293,7 +293,7 @@ describe('Discover and build models', function() {
describe('discoverModelProperties() flags', function() { describe('discoverModelProperties() flags', function() {
context('with default flags', function() { context('with default flags', function() {
var models, schema; let models, schema;
before(discoverAndBuildModels); before(discoverAndBuildModels);
it('handles CHAR(1) as Boolean', function() { it('handles CHAR(1) as Boolean', function() {
@ -325,7 +325,7 @@ describe('Discover and build models', function() {
}); });
context('with flag treatCHAR1AsString = true', function() { context('with flag treatCHAR1AsString = true', function() {
var models, schema; let models, schema;
before(discoverAndBuildModels); before(discoverAndBuildModels);
it('handles CHAR(1) as String', function() { it('handles CHAR(1) as String', function() {
@ -358,7 +358,7 @@ describe('Discover and build models', function() {
}); });
context('with flag treatBIT1AsBit = false', function() { context('with flag treatBIT1AsBit = false', function() {
var models, schema; let models, schema;
before(discoverAndBuildModels); before(discoverAndBuildModels);
it('handles CHAR(1) as Boolean', function() { it('handles CHAR(1) as Boolean', function() {
@ -391,7 +391,7 @@ describe('Discover and build models', function() {
}); });
context('with flag treatTINYINT1AsTinyInt = false', function() { context('with flag treatTINYINT1AsTinyInt = false', function() {
var models, schema; let models, schema;
before(discoverAndBuildModels); before(discoverAndBuildModels);
it('handles CHAR(1) as Boolean', function() { it('handles CHAR(1) as Boolean', function() {

View File

@ -4,12 +4,12 @@
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT
'use strict'; 'use strict';
var async = require('async'); const async = require('async');
var should = require('./init.js'); const should = require('./init.js');
var sinon = require('sinon'); const sinon = require('sinon');
const List = require('loopback-datasource-juggler/lib/list'); const List = require('loopback-datasource-juggler/lib/list');
var Post, PostWithStringId, PostWithUniqueTitle, PostWithNumId, Student, db; let Post, PostWithStringId, PostWithUniqueTitle, PostWithNumId, Student, db;
// Mock up mongodb ObjectID // Mock up mongodb ObjectID
function ObjectID(id) { function ObjectID(id) {
@ -72,7 +72,8 @@ describe('mysql', function() {
function(err) { function(err) {
should.not.exist(err); should.not.exist(err);
done(err); done(err);
}); },
);
}); });
beforeEach(function() { beforeEach(function() {
@ -98,7 +99,7 @@ describe('mysql', function() {
}); });
it('should allow ObjectID', function(done) { it('should allow ObjectID', function(done) {
var uid = new ObjectID('123'); const uid = new ObjectID('123');
Post.create({title: 'a', content: 'AAA', userId: uid}, Post.create({title: 'a', content: 'AAA', userId: uid},
function(err, post) { function(err, post) {
should.not.exist(err); should.not.exist(err);
@ -155,7 +156,7 @@ describe('mysql', function() {
}); });
it('updateOrCreate should create a new instance if it does not exist', function(done) { it('updateOrCreate should create a new instance if it does not exist', function(done) {
var post = {id: 123, title: 'a', content: 'AAA'}; const post = {id: 123, title: 'a', content: 'AAA'};
Post.updateOrCreate(post, function(err, p) { Post.updateOrCreate(post, function(err, p) {
should.not.exist(err); should.not.exist(err);
p.title.should.be.equal(post.title); p.title.should.be.equal(post.title);
@ -227,7 +228,7 @@ describe('mysql', function() {
}); });
it('should create a new instance if it does not exist', function(done) { it('should create a new instance if it does not exist', function(done) {
var post = {id: 123, title: 'a', content: 'AAA'}; const post = {id: 123, title: 'a', content: 'AAA'};
Post.replaceOrCreate(post, function(err, p) { Post.replaceOrCreate(post, function(err, p) {
if (err) return done(err); if (err) return done(err);
p.id.should.equal(post.id); p.id.should.equal(post.id);
@ -246,10 +247,10 @@ describe('mysql', function() {
}); });
it('isNewInstance should be undefined for after save hook', function(done) { it('isNewInstance should be undefined for after save hook', function(done) {
var student = {name: 'Joe', age: 20}; const student = {name: 'Joe', age: 20};
var newStudent = {}; const newStudent = {};
var isNewInstanceBefore = false; let isNewInstanceBefore = false;
var isNewInstanceAfter = false; let isNewInstanceAfter = false;
Student.create(student, function(err, createdStudent) { Student.create(student, function(err, createdStudent) {
if (err) return done(err); if (err) return done(err);
newStudent.id = createdStudent.id; newStudent.id = createdStudent.id;
@ -314,7 +315,7 @@ describe('mysql', function() {
}); });
it('save should create a new instance if it does not exist', function(done) { it('save should create a new instance if it does not exist', function(done) {
var post = new Post({id: 123, title: 'a', content: 'AAA'}); const post = new Post({id: 123, title: 'a', content: 'AAA'});
post.save(post, function(err, p) { post.save(post, function(err, p) {
should.not.exist(err); should.not.exist(err);
p.title.should.be.equal(post.title); p.title.should.be.equal(post.title);
@ -335,7 +336,7 @@ describe('mysql', function() {
}); });
it('all return should honor filter.fields', function(done) { it('all return should honor filter.fields', function(done) {
var post = new Post({title: 'b', content: 'BBB'}); const post = new Post({title: 'b', content: 'BBB'});
post.save(function(err, post) { post.save(function(err, post) {
Post.all({fields: ['title'], where: {title: 'b'}}, function(err, posts) { Post.all({fields: ['title'], where: {title: 'b'}}, function(err, posts) {
should.not.exist(err); should.not.exist(err);
@ -468,7 +469,7 @@ describe('mysql', function() {
}); });
}); });
context('null vals in different operators', function() { context('null vals in different operators', function() {
var defaultPost = { const defaultPost = {
id: 3, id: 3,
title: 'defTitle', title: 'defTitle',
content: 'defContent', content: 'defContent',
@ -689,7 +690,7 @@ describe('mysql', function() {
}); });
it('should not allow duplicate titles', function(done) { it('should not allow duplicate titles', function(done) {
var data = {title: 'a', content: 'AAA'}; const data = {title: 'a', content: 'AAA'};
PostWithUniqueTitle.create(data, function(err, post) { PostWithUniqueTitle.create(data, function(err, post) {
should.not.exist(err); should.not.exist(err);
PostWithUniqueTitle.create(data, function(err, post) { PostWithUniqueTitle.create(data, function(err, post) {
@ -729,7 +730,7 @@ describe('mysql', function() {
beforeEach(function addSpy() { beforeEach(function addSpy() {
sinon.stub(console, 'warn'); sinon.stub(console, 'warn');
}); });
afterEach(function removeSpy() { afterEach(function removeSpy() {
console.warn.restore(); console.warn.restore();
}); });
@ -793,7 +794,7 @@ describe('mysql', function() {
beforeEach(function addSpy() { beforeEach(function addSpy() {
sinon.stub(console, 'warn'); sinon.stub(console, 'warn');
}); });
afterEach(function removeSpy() { afterEach(function removeSpy() {
console.warn.restore(); console.warn.restore();
}); });
@ -846,7 +847,7 @@ describe('mysql', function() {
beforeEach(function addSpy() { beforeEach(function addSpy() {
sinon.stub(console, 'warn'); sinon.stub(console, 'warn');
}); });
afterEach(function removeSpy() { afterEach(function removeSpy() {
console.warn.restore(); console.warn.restore();
}); });

View File

@ -5,8 +5,8 @@
'use strict'; 'use strict';
var setHttpCode = require('../lib/set-http-code'); const setHttpCode = require('../lib/set-http-code');
var should = require('./init.js'); const should = require('./init.js');
describe('setHttpCode', function() { describe('setHttpCode', function() {
describe('should set statusCode', function() { describe('should set statusCode', function() {
@ -22,7 +22,7 @@ describe('setHttpCode', function() {
function testErrorCode(name, msg, expected) { function testErrorCode(name, msg, expected) {
it(name, function() { it(name, function() {
var err = new Error(msg); let err = new Error(msg);
err = setHttpCode(err); err = setHttpCode(err);
should.exist(err.statusCode); should.exist(err.statusCode);
should.equal(err.statusCode, expected); should.equal(err.statusCode, expected);
@ -34,7 +34,7 @@ describe('setHttpCode', function() {
}); });
it('should convert strings to errors', function() { it('should convert strings to errors', function() {
var err = 'REALLY_BAD: Something truly awful occurred.'; let err = 'REALLY_BAD: Something truly awful occurred.';
err = setHttpCode(err); err = setHttpCode(err);
should.exist(err.statusCode); should.exist(err.statusCode);
should(err instanceof Error); should(err instanceof Error);

View File

@ -7,11 +7,11 @@
if (typeof Promise === 'undefined') { if (typeof Promise === 'undefined') {
global.Promise = require('bluebird'); global.Promise = require('bluebird');
} }
var Transaction = require('loopback-datasource-juggler').Transaction; const Transaction = require('loopback-datasource-juggler').Transaction;
require('./init.js'); require('./init.js');
require('should'); require('should');
var db, Post, Review; let db, Post, Review;
describe('transactions with promise', function() { describe('transactions with promise', function() {
before(function(done) { before(function(done) {
@ -38,13 +38,13 @@ describe('transactions with promise', function() {
done(); done();
}); });
var currentTx; let currentTx;
var hooks = []; let hooks = [];
// Return an async function to start a transaction and create a post // Return an async function to start a transaction and create a post
function createPostInTx(post, timeout) { function createPostInTx(post, timeout) {
return function(done) { return function(done) {
// Transaction.begin(db.connector, Transaction.READ_COMMITTED, // Transaction.begin(db.connector, Transaction.READ_COMMITTED,
var promise = Post.beginTransaction({ const promise = Post.beginTransaction({
isolationLevel: Transaction.READ_COMMITTED, isolationLevel: Transaction.READ_COMMITTED,
timeout: timeout, timeout: timeout,
}); });
@ -77,8 +77,10 @@ describe('transactions with promise', function() {
}, {transaction: currentTx}).then( }, {transaction: currentTx}).then(
function(c) { function(c) {
done(null, c); done(null, c);
}); },
}); );
},
);
}).catch(done); }).catch(done);
}; };
} }
@ -87,7 +89,7 @@ describe('transactions with promise', function() {
// records to equal to the count // records to equal to the count
function expectToFindPosts(where, count, inTx) { function expectToFindPosts(where, count, inTx) {
return function(done) { return function(done) {
var options = {}; const options = {};
if (inTx) { if (inTx) {
options.transaction = currentTx; options.transaction = currentTx;
} }
@ -105,12 +107,13 @@ describe('transactions with promise', function() {
} else { } else {
done(); done();
} }
}).catch(done); },
).catch(done);
}; };
} }
describe('commit', function() { describe('commit', function() {
var post = {title: 't1', content: 'c1'}; const post = {title: 't1', content: 'c1'};
before(createPostInTx(post)); before(createPostInTx(post));
it('should not see the uncommitted insert', expectToFindPosts(post, 0)); it('should not see the uncommitted insert', expectToFindPosts(post, 0));
@ -136,7 +139,7 @@ describe('transactions with promise', function() {
}); });
describe('rollback', function() { describe('rollback', function() {
var post = {title: 't2', content: 'c2'}; const post = {title: 't2', content: 'c2'};
before(createPostInTx(post)); before(createPostInTx(post));
it('should not see the uncommitted insert', expectToFindPosts(post, 0)); it('should not see the uncommitted insert', expectToFindPosts(post, 0));
@ -162,7 +165,7 @@ describe('transactions with promise', function() {
}); });
describe('timeout', function() { describe('timeout', function() {
var post = {title: 't3', content: 'c3'}; const post = {title: 't3', content: 'c3'};
before(createPostInTx(post, 500)); before(createPostInTx(post, 500));
it('should invoke the timeout hook', function(done) { it('should invoke the timeout hook', function(done) {

View File

@ -4,11 +4,11 @@
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT
'use strict'; 'use strict';
var Transaction = require('loopback-datasource-juggler').Transaction; const Transaction = require('loopback-datasource-juggler').Transaction;
require('./init.js'); require('./init.js');
require('should'); require('should');
var db, Post, Review; let db, Post, Review;
describe('transactions', function() { describe('transactions', function() {
before(function(done) { before(function(done) {
@ -28,8 +28,8 @@ describe('transactions', function() {
}); });
}); });
var currentTx; let currentTx;
var hooks = []; let hooks = [];
// Return an async function to start a transaction and create a post // Return an async function to start a transaction and create a post
function createPostInTx(post, timeout) { function createPostInTx(post, timeout) {
return function(done) { return function(done) {
@ -81,7 +81,7 @@ describe('transactions', function() {
// records to equal to the count // records to equal to the count
function expectToFindPosts(where, count, inTx) { function expectToFindPosts(where, count, inTx) {
return function(done) { return function(done) {
var options = {}; const options = {};
if (inTx) { if (inTx) {
options.transaction = currentTx; options.transaction = currentTx;
} }
@ -106,7 +106,7 @@ describe('transactions', function() {
} }
describe('commit', function() { describe('commit', function() {
var post = {title: 't1', content: 'c1'}; const post = {title: 't1', content: 'c1'};
before(createPostInTx(post)); before(createPostInTx(post));
it('should not see the uncommitted insert', expectToFindPosts(post, 0)); it('should not see the uncommitted insert', expectToFindPosts(post, 0));
@ -132,7 +132,7 @@ describe('transactions', function() {
}); });
describe('rollback', function() { describe('rollback', function() {
var post = {title: 't2', content: 'c2'}; const post = {title: 't2', content: 'c2'};
before(createPostInTx(post)); before(createPostInTx(post));
it('should not see the uncommitted insert', expectToFindPosts(post, 0)); it('should not see the uncommitted insert', expectToFindPosts(post, 0));
@ -158,7 +158,7 @@ describe('transactions', function() {
}); });
describe('timeout', function() { describe('timeout', function() {
var post = {title: 't3', content: 'c3'}; const post = {title: 't3', content: 'c3'};
before(createPostInTx(post, 500)); before(createPostInTx(post, 500));
it('should invoke the timeout hook', function(done) { it('should invoke the timeout hook', function(done) {