From a2669000d7edba9f2f0186ac52a9698205f3ff79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20Bajto=C5=A1?= Date: Thu, 4 Jul 2019 14:02:10 +0200 Subject: [PATCH 1/4] Update dev-dependencies MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - mocha to ^6.1.4 - should to ^13.2.3 - sinon to ^7.3.2 Signed-off-by: Miroslav Bajtoš --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 2ce935cb..184494b5 100644 --- a/package.json +++ b/package.json @@ -35,10 +35,10 @@ "juggler-v4": "file:./deps/juggler-v4", "lodash": "^4.17.4", "loopback-datasource-juggler": "^3.0.0 || ^4.0.0", - "mocha": "^5.0.0", + "mocha": "^6.1.4", "rc": "^1.0.0", - "should": "^8.0.2", - "sinon": "^1.15.4" + "should": "^13.2.3", + "sinon": "^7.3.2" }, "repository": { "type": "git", From d57001f3d4b4a6ce364291273e9f19e9870dbdfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20Bajto=C5=A1?= Date: Thu, 4 Jul 2019 14:12:40 +0200 Subject: [PATCH 2/4] Update eslint to ^6.0.1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Miroslav Bajtoš --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 184494b5..3941fdeb 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "uuid": "^3.0.1" }, "devDependencies": { - "eslint": "^5.16.0", + "eslint": "^6.0.1", "eslint-config-loopback": "^13.1.0", "juggler-v3": "file:./deps/juggler-v3", "juggler-v4": "file:./deps/juggler-v4", From 97b33433fdd5d99c94a385fa453c583e0231ef22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20Bajto=C5=A1?= Date: Thu, 4 Jul 2019 14:12:56 +0200 Subject: [PATCH 3/4] Auto-fix linting violations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Miroslav Bajtoš --- deps/juggler-v3/test.js | 6 +- deps/juggler-v4/test.js | 6 +- example/app.js | 12 +- example/model.js | 14 +- index.js | 2 +- lib/discovery.js | 52 ++-- lib/migration.js | 308 +++++++++++------------ lib/postgresql.js | 130 +++++----- lib/transaction.js | 30 +-- pretest.js | 10 +- test/init.js | 18 +- test/postgresql.autocreateschema.test.js | 6 +- test/postgresql.autoupdate.test.js | 38 +-- test/postgresql.dbdefaults.test.js | 6 +- test/postgresql.discover.test.js | 28 +-- test/postgresql.filterUndefined.test.js | 12 +- test/postgresql.initialization.test.js | 36 +-- test/postgresql.mapping.test.js | 10 +- test/postgresql.migration.test.js | 12 +- test/postgresql.test.js | 138 +++++----- test/postgresql.timestamp.test.js | 7 +- test/postgresql.transaction.test.js | 26 +- 22 files changed, 456 insertions(+), 451 deletions(-) diff --git a/deps/juggler-v3/test.js b/deps/juggler-v3/test.js index 8cf2cc4a..bac835cd 100644 --- a/deps/juggler-v3/test.js +++ b/deps/juggler-v3/test.js @@ -5,9 +5,9 @@ 'use strict'; -var should = require('../../test/init'); -var juggler = require('loopback-datasource-juggler'); -var name = require('./package.json').name; +const should = require('../../test/init'); +const juggler = require('loopback-datasource-juggler'); +const name = require('./package.json').name; describe(name, function() { before(function() { diff --git a/deps/juggler-v4/test.js b/deps/juggler-v4/test.js index 8cf2cc4a..bac835cd 100644 --- a/deps/juggler-v4/test.js +++ b/deps/juggler-v4/test.js @@ -5,9 +5,9 @@ 'use strict'; -var should = require('../../test/init'); -var juggler = require('loopback-datasource-juggler'); -var name = require('./package.json').name; +const should = require('../../test/init'); +const juggler = require('loopback-datasource-juggler'); +const name = require('./package.json').name; describe(name, function() { before(function() { diff --git a/example/app.js b/example/app.js index b9e704c0..3e9c420b 100644 --- a/example/app.js +++ b/example/app.js @@ -4,11 +4,11 @@ // License text available at https://opensource.org/licenses/Artistic-2.0 'use strict'; -var DataSource = require('loopback-datasource-juggler').DataSource; +const DataSource = require('loopback-datasource-juggler').DataSource; -var config = require('rc')('loopback', {dev: {postgresql: {}}}).dev.postgresql; +const config = require('rc')('loopback', {dev: {postgresql: {}}}).dev.postgresql; -var ds = new DataSource(require('../'), config); +const ds = new DataSource(require('../'), config); function show(err, models) { if (err) { @@ -26,10 +26,10 @@ ds.discoverModelProperties('product', show); // ds.discoverModelProperties('INVENTORY_VIEW', {owner: 'STRONGLOOP'}, show); -ds.discoverPrimaryKeys('inventory', show); -ds.discoverForeignKeys('inventory', show); +ds.discoverPrimaryKeys('inventory', show); +ds.discoverForeignKeys('inventory', show); -ds.discoverExportedForeignKeys('product', show); +ds.discoverExportedForeignKeys('product', show); /* diff --git a/example/model.js b/example/model.js index 166fa2d7..e3d3adb7 100644 --- a/example/model.js +++ b/example/model.js @@ -4,21 +4,21 @@ // License text available at https://opensource.org/licenses/Artistic-2.0 'use strict'; -var SG = require('strong-globalize'); -var g = SG(); +const SG = require('strong-globalize'); +const g = SG(); -var DataSource = require('loopback-datasource-juggler').DataSource; +const DataSource = require('loopback-datasource-juggler').DataSource; -var config = require('rc')('loopback', {dev: {postgresql: {}}}).dev.postgresql; +const config = require('rc')('loopback', {dev: {postgresql: {}}}).dev.postgresql; -var ds = new DataSource(require('../'), config); +const ds = new DataSource(require('../'), config); // Define a account model -var Account = ds.createModel('account', { +const Account = ds.createModel('account', { name: String, emails: [String], age: Number}, - {strict: true}); +{strict: true}); ds.automigrate('account', function(err) { // Create two instances diff --git a/index.js b/index.js index cd8aaf5c..e519aecf 100644 --- a/index.js +++ b/index.js @@ -4,7 +4,7 @@ // License text available at https://opensource.org/licenses/Artistic-2.0 'use strict'; -var SG = require('strong-globalize'); +const SG = require('strong-globalize'); SG.SetRootDir(__dirname); module.exports = require('./lib/postgresql.js'); diff --git a/lib/discovery.js b/lib/discovery.js index b2b62f53..a29343f3 100644 --- a/lib/discovery.js +++ b/lib/discovery.js @@ -4,16 +4,16 @@ // License text available at https://opensource.org/licenses/Artistic-2.0 'use strict'; -var g = require('strong-globalize')(); +const g = require('strong-globalize')(); module.exports = mixinDiscovery; function mixinDiscovery(PostgreSQL) { - var async = require('async'); + const async = require('async'); PostgreSQL.prototype.paginateSQL = function(sql, orderBy, options) { options = options || {}; - var limit = ''; + let limit = ''; if (options.offset || options.skip || options.limit) { limit = ' OFFSET ' + (options.offset || options.skip || 0); // Offset starts from 0 if (options.limit) { @@ -32,8 +32,8 @@ function mixinDiscovery(PostgreSQL) { * @returns {string} The sql statement */ PostgreSQL.prototype.buildQueryTables = function(options) { - var sqlTables = null; - var owner = options.owner || options.schema; + let sqlTables = null; + const owner = options.owner || options.schema; if (options.all && !owner) { sqlTables = this.paginateSQL('SELECT \'table\' AS "type", table_name AS "name", table_schema AS "owner"' @@ -44,7 +44,7 @@ function mixinDiscovery(PostgreSQL) { } else { sqlTables = this.paginateSQL('SELECT \'table\' AS "type", table_name AS "name",' + ' table_schema AS "owner" FROM information_schema.tables WHERE table_schema=current_schema()', - 'table_name', options); + 'table_name', options); } return sqlTables; }; @@ -55,22 +55,22 @@ function mixinDiscovery(PostgreSQL) { * @returns {string} The sql statement */ PostgreSQL.prototype.buildQueryViews = function(options) { - var sqlViews = null; + let sqlViews = null; if (options.views) { - var owner = options.owner || options.schema; + const owner = options.owner || options.schema; if (options.all && !owner) { sqlViews = this.paginateSQL('SELECT \'view\' AS "type", table_name AS "name",' + ' table_schema AS "owner" FROM information_schema.views', - 'table_schema, table_name', options); + 'table_schema, table_name', options); } else if (owner) { sqlViews = this.paginateSQL('SELECT \'view\' AS "type", table_name AS "name",' + ' table_schema AS "owner" FROM information_schema.views WHERE table_schema=\'' + owner + '\'', - 'table_schema, table_name', options); + 'table_schema, table_name', options); } else { sqlViews = this.paginateSQL('SELECT \'view\' AS "type", table_name AS "name",' + ' current_schema() AS "owner" FROM information_schema.views', - 'table_name', options); + 'table_name', options); } } return sqlViews; @@ -117,9 +117,9 @@ function mixinDiscovery(PostgreSQL) { * @param {Function} [cb] The callback function */ PostgreSQL.prototype.discoverModelProperties = function(table, options, cb) { - var self = this; - var args = self.getArgs(table, options, cb); - var schema = args.schema; + const self = this; + const args = self.getArgs(table, options, cb); + let schema = args.schema; table = args.table; options = args.options; @@ -131,8 +131,8 @@ function mixinDiscovery(PostgreSQL) { self.setDefaultOptions(options); cb = args.cb; - var sql = self.buildQueryColumns(schema, table); - var callback = function(err, results) { + const sql = self.buildQueryColumns(schema, table); + const callback = function(err, results) { if (err) { cb(err, results); } else { @@ -164,7 +164,7 @@ function mixinDiscovery(PostgreSQL) { * @returns {String} The sql statement */ PostgreSQL.prototype.buildQueryColumns = function(owner, table) { - var sql = null; + let sql = null; if (owner) { sql = this.paginateSQL('SELECT table_schema AS "owner", table_name AS "tableName", column_name AS "columnName",' + 'data_type AS "dataType", character_maximum_length AS "dataLength", numeric_precision AS "dataPrecision",' @@ -172,7 +172,7 @@ function mixinDiscovery(PostgreSQL) { + ' FROM information_schema.columns' + ' WHERE table_schema=\'' + owner + '\'' + (table ? ' AND table_name=\'' + table + '\'' : ''), - 'table_name, ordinal_position', {}); + 'table_name, ordinal_position', {}); } else { sql = this.paginateSQL('SELECT current_schema() AS "owner", table_name AS "tableName",' + ' column_name AS "columnName",' @@ -180,7 +180,7 @@ function mixinDiscovery(PostgreSQL) { + ' numeric_scale AS "dataScale", is_nullable AS "nullable"' + ' FROM information_schema.columns' + (table ? ' WHERE table_name=\'' + table + '\'' : ''), - 'table_name, ordinal_position', {}); + 'table_name, ordinal_position', {}); } return sql; }; @@ -193,7 +193,7 @@ function mixinDiscovery(PostgreSQL) { * */ -// http://docs.oracle.com/javase/6/docs/api/java/sql/DatabaseMetaData.html#getPrimaryKeys(java.lang.String, java.lang.String, java.lang.String) + // http://docs.oracle.com/javase/6/docs/api/java/sql/DatabaseMetaData.html#getPrimaryKeys(java.lang.String, java.lang.String, java.lang.String) /* SELECT kc.table_schema AS "owner", kc.table_name AS "tableName", @@ -212,7 +212,7 @@ function mixinDiscovery(PostgreSQL) { * @returns {string} */ PostgreSQL.prototype.buildQueryPrimaryKeys = function(owner, table) { - var sql = 'SELECT kc.table_schema AS "owner", ' + let sql = 'SELECT kc.table_schema AS "owner", ' + 'kc.table_name AS "tableName", kc.column_name AS "columnName",' + ' kc.ordinal_position AS "keySeq",' + ' kc.constraint_name AS "pkName" FROM' @@ -260,7 +260,7 @@ function mixinDiscovery(PostgreSQL) { * @returns {string} */ PostgreSQL.prototype.buildQueryForeignKeys = function(owner, table) { - var sql = + let sql = 'SELECT tc.table_schema AS "fkOwner", tc.constraint_name AS "fkName", tc.table_name AS "fkTableName",' + ' kcu.column_name AS "fkColumnName", kcu.ordinal_position AS "keySeq",' + ' ccu.table_schema AS "pkOwner",' @@ -298,7 +298,7 @@ function mixinDiscovery(PostgreSQL) { * @returns {string} */ PostgreSQL.prototype.buildQueryExportedForeignKeys = function(owner, table) { - var sql = 'SELECT kcu.constraint_name AS "fkName", kcu.table_schema AS "fkOwner", kcu.table_name AS "fkTableName",' + let sql = 'SELECT kcu.constraint_name AS "fkName", kcu.table_schema AS "fkOwner", kcu.table_name AS "fkTableName",' + ' kcu.column_name AS "fkColumnName", kcu.ordinal_position AS "keySeq",' + ' (SELECT constraint_name' + ' FROM information_schema.table_constraints tc2' @@ -328,8 +328,8 @@ function mixinDiscovery(PostgreSQL) { */ PostgreSQL.prototype.buildPropertyType = function(columnDefinition, dataLength) { - var mysqlType = columnDefinition.dataType; - var type = mysqlType.toUpperCase(); + const mysqlType = columnDefinition.dataType; + const type = mysqlType.toUpperCase(); switch (type) { case 'BOOLEAN': return 'Boolean'; @@ -369,7 +369,7 @@ function mixinDiscovery(PostgreSQL) { */ PostgreSQL.prototype.discoverModelIndexes = function(model, cb) { this.getTableStatus(model, function(err, fields, indexes) { - var indexData = {}; + const indexData = {}; indexes.forEach(function(index) { indexData[index.name] = index; delete index.name; diff --git a/lib/migration.js b/lib/migration.js index f9dc163f..03e521e8 100644 --- a/lib/migration.js +++ b/lib/migration.js @@ -4,10 +4,10 @@ // License text available at https://opensource.org/licenses/Artistic-2.0 'use strict'; -var SG = require('strong-globalize'); -var g = SG(); -var async = require('async'); -var debug = require('debug')('loopback:connector:postgresql:migration'); +const SG = require('strong-globalize'); +const g = SG(); +const async = require('async'); +const debug = require('debug')('loopback:connector:postgresql:migration'); module.exports = mixinMigration; @@ -19,7 +19,7 @@ function mixinMigration(PostgreSQL) { }; PostgreSQL.prototype.showFields = function(model, cb) { - var sql = 'SELECT column_name AS "column", data_type AS "type", ' + + const sql = 'SELECT column_name AS "column", data_type AS "type", ' + 'datetime_precision AS time_precision, ' + 'is_nullable AS "nullable", character_maximum_length as "length"' // , data_default AS "Default"' + ' FROM "information_schema"."columns" WHERE table_name=\'' + @@ -38,7 +38,7 @@ function mixinMigration(PostgreSQL) { }; PostgreSQL.prototype.showIndexes = function(model, cb) { - var sql = 'SELECT t.relname AS "table", i.relname AS "name", ' + + const sql = 'SELECT t.relname AS "table", i.relname AS "name", ' + 'am.amname AS "type", ix.indisprimary AS "primary", ' + 'ix.indisunique AS "unique", ' + 'ARRAY(SELECT pg_get_indexdef(ix.indexrelid, k + 1, true) ' + @@ -74,18 +74,18 @@ function mixinMigration(PostgreSQL) { * @param {Function} [cb] The callback function */ PostgreSQL.prototype.alterTable = function(model, actualFields, actualIndexes, cb) { - var self = this; - var m = this._models[model]; - var propNames = Object.keys(m.properties).filter(function(name) { + const self = this; + const m = this._models[model]; + const propNames = Object.keys(m.properties).filter(function(name) { return !!m.properties; }); - 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]; }) : []; var applyPending = function(actions, cb, err, result) { - var action = actions.shift(); - var pendingChanges = action && action() || []; + const action = actions.shift(); + const pendingChanges = action && action() || []; if (pendingChanges.length) { self.applySqlChanges(model, pendingChanges, function(err, result) { if (!err) { @@ -123,7 +123,7 @@ function mixinMigration(PostgreSQL) { // actualFks is a list of EXISTING fkeys here, // so you don't need to recreate them again // prepare fkSQL for new foreign keys - var fkSQL = self.getForeignKeySQL(model, + const fkSQL = self.getForeignKeySQL(model, self.getModelDefinition(model).settings.foreignKeys, actualFks); @@ -136,10 +136,10 @@ function mixinMigration(PostgreSQL) { }; PostgreSQL.prototype.getAddModifyColumns = function(model, actualFields) { - var sql = []; - var self = this; + let sql = []; + const self = this; sql = sql.concat(self.getColumnsToAdd(model, actualFields)); - var drops = self.getPropertiesToModify(model, actualFields); + const drops = self.getPropertiesToModify(model, actualFields); if (drops.length > 0) { if (sql.length > 0) { sql = sql.concat(', '); @@ -150,14 +150,15 @@ function mixinMigration(PostgreSQL) { }; PostgreSQL.prototype.getColumnsToAdd = function(model, actualFields) { - var self = this; - var m = self._models[model]; - var propNames = Object.keys(m.properties); - var sql = []; + const self = this; + const m = self._models[model]; + const propNames = Object.keys(m.properties); + let sql = []; propNames.forEach(function(propName) { if (self.id(model, propName)) return; - var found = self.searchForPropertyInActual( - model, self.column(model, propName), actualFields); + const found = self.searchForPropertyInActual( + model, self.column(model, propName), actualFields + ); if (!found && self.propertyHasNotBeenDeleted(model, propName)) { sql.push('ADD COLUMN ' + self.addPropertyToActual(model, propName)); } @@ -169,11 +170,11 @@ function mixinMigration(PostgreSQL) { }; PostgreSQL.prototype.getPropertiesToModify = function(model, actualFields) { - var self = this; - var sql = []; - var m = self._models[model]; - var propNames = Object.keys(m.properties); - var found; + const self = this; + let sql = []; + const m = self._models[model]; + const propNames = Object.keys(m.properties); + let found; propNames.forEach(function(propName) { if (self.id(model, propName)) { return; @@ -196,7 +197,7 @@ function mixinMigration(PostgreSQL) { return sql; function datatypeChanged(propName, oldSettings) { - var newSettings = m.properties[propName]; + const newSettings = m.properties[propName]; if (!newSettings) { return false; } @@ -204,11 +205,11 @@ function mixinMigration(PostgreSQL) { } function nullabilityChanged(propName, oldSettings) { - var newSettings = m.properties[propName]; + const newSettings = m.properties[propName]; if (!newSettings) { return false; } - var changed = false; + let changed = false; if (oldSettings.nullable === 'YES' && !self.isNullable(newSettings)) { changed = true; } @@ -220,8 +221,8 @@ function mixinMigration(PostgreSQL) { }; PostgreSQL.prototype.modifyDatatypeInActual = function(model, propName) { - var self = this; - var sqlCommand = self.columnEscaped(model, propName) + ' TYPE ' + + const self = this; + const sqlCommand = self.columnEscaped(model, propName) + ' TYPE ' + self.columnDataType(model, propName) + ' USING ' + self.columnEscaped(model, propName) + '::' + self.columnDataType(model, propName); @@ -229,9 +230,9 @@ function mixinMigration(PostgreSQL) { }; PostgreSQL.prototype.modifyNullabilityInActual = function(model, propName) { - var self = this; - var prop = this.getPropertyDefinition(model, propName); - var sqlCommand = self.columnEscaped(model, propName) + ' '; + const self = this; + const prop = this.getPropertyDefinition(model, propName); + let sqlCommand = self.columnEscaped(model, propName) + ' '; if (self.isNullable(prop)) { sqlCommand = sqlCommand + 'DROP '; } else { @@ -242,8 +243,8 @@ function mixinMigration(PostgreSQL) { }; PostgreSQL.prototype.getColumnsToDrop = function(model, actualFields) { - var self = this; - var sql = []; + const self = this; + let sql = []; actualFields.forEach(function(actualField) { if (self.idColumn(model) === actualField.column) { return; @@ -269,13 +270,13 @@ function mixinMigration(PostgreSQL) { */ PostgreSQL.prototype.buildColumnDefinitions = PostgreSQL.prototype.propertiesSQL = function(model) { - var self = this; - var sql = []; - var pks = this.idNames(model).map(function(i) { + const self = this; + const sql = []; + const pks = this.idNames(model).map(function(i) { return self.columnEscaped(model, i); }); Object.keys(this.getModelDefinition(model).properties).forEach(function(prop) { - var colName = self.columnEscaped(model, prop); + const colName = self.columnEscaped(model, prop); sql.push(colName + ' ' + self.buildColumnDefinition(model, prop)); }); if (pks.length > 0) { @@ -291,13 +292,13 @@ function mixinMigration(PostgreSQL) { * @returns {*|string} */ PostgreSQL.prototype.buildColumnDefinition = function(model, propName) { - var self = this; - var modelDef = this.getModelDefinition(model); - var prop = modelDef.properties[propName]; + const self = this; + const modelDef = this.getModelDefinition(model); + const prop = modelDef.properties[propName]; if (prop.generated) { return 'SERIAL'; } - var result = self.columnDataType(model, propName); + let result = self.columnDataType(model, propName); if (!self.isNullable(prop)) result = result + ' NOT NULL'; result += self.columnDbDefault(model, propName); @@ -310,52 +311,51 @@ function mixinMigration(PostgreSQL) { * @param {Function} [cb] The callback function */ PostgreSQL.prototype.createTable = function(model, cb) { - var self = this; - var name = self.tableEscaped(model); + const self = this; + const name = self.tableEscaped(model); // Please note IF NOT EXISTS is introduced in postgresql v9.3 self.execute('CREATE SCHEMA ' + self.escapeName(self.schema(model)), - function(err) { - if (err && err.code !== '42P06') { - return cb && cb(err); - } - self.execute('CREATE TABLE ' + name + ' (\n ' + + function(err) { + if (err && err.code !== '42P06') { + return cb && cb(err); + } + self.execute('CREATE TABLE ' + name + ' (\n ' + self.propertiesSQL(model) + '\n)', - function(err, info) { - if (err) { - return cb(err, info); - } - self.addIndexes(model, undefined, function(err) { - if (err) { - return cb(err); - } - var fkSQL = self.getForeignKeySQL(model, - self.getModelDefinition(model).settings.foreignKeys); - self.addForeignKeys(model, fkSQL, function(err, result) { - cb(err); - }); - }); + function(err, info) { + if (err) { + return cb(err, info); + } + self.addIndexes(model, undefined, function(err) { + if (err) { + return cb(err); } - ); + const fkSQL = self.getForeignKeySQL(model, + self.getModelDefinition(model).settings.foreignKeys); + self.addForeignKeys(model, fkSQL, function(err, result) { + cb(err); + }); + }); }); + }); }; PostgreSQL.prototype.buildIndex = function(model, property) { - var prop = this.getModelDefinition(model).properties[property]; - var i = prop && prop.index; + const prop = this.getModelDefinition(model).properties[property]; + const i = prop && prop.index; if (!i) { return ''; } - var type = ''; - var kind = ''; + let type = ''; + let kind = ''; if (i.type) { type = 'USING ' + i.type; } if (i.kind) { kind = i.kind; } - var columnName = this.columnEscaped(model, property); + const columnName = this.columnEscaped(model, property); if (kind && type) { return (kind + ' INDEX ' + columnName + ' (' + columnName + ') ' + type); } else { @@ -365,29 +365,29 @@ function mixinMigration(PostgreSQL) { }; PostgreSQL.prototype.buildIndexes = function(model) { - var self = this; - var indexClauses = []; - var definition = this.getModelDefinition(model); - var indexes = definition.settings.indexes || {}; + const self = this; + const indexClauses = []; + const definition = this.getModelDefinition(model); + const indexes = definition.settings.indexes || {}; // Build model level indexes - for (var index in indexes) { - var i = indexes[index]; - var type = ''; - var kind = ''; + for (const index in indexes) { + const i = indexes[index]; + let type = ''; + let kind = ''; if (i.type) { type = 'USING ' + i.type; } if (i.kind) { kind = i.kind; } - var indexedColumns = []; - var indexName = this.escapeName(index); + let indexedColumns = []; + const indexName = this.escapeName(index); if (Array.isArray(i.keys)) { indexedColumns = i.keys.map(function(key) { return self.columnEscaped(model, key); }); } - var columns = indexedColumns.join(',') || i.columns; + const columns = indexedColumns.join(',') || i.columns; if (kind && type) { indexClauses.push(kind + ' INDEX ' + indexName + ' (' + columns + ') ' + type); } else { @@ -396,8 +396,8 @@ function mixinMigration(PostgreSQL) { } // Define index for each of the properties - for (var p in definition.properties) { - var propIndex = self.buildIndex(model, p); + for (const p in definition.properties) { + const propIndex = self.buildIndex(model, p); if (propIndex) { indexClauses.push(propIndex); } @@ -414,10 +414,10 @@ function mixinMigration(PostgreSQL) { * @returns {String} The column default value */ PostgreSQL.prototype.columnDbDefault = function(model, property) { - var columnMetadata = this.columnMetadata(model, property); - var colDefault = columnMetadata && columnMetadata.dbDefault; + const columnMetadata = this.columnMetadata(model, property); + let colDefault = columnMetadata && columnMetadata.dbDefault; if (!colDefault) { - var prop = this.getModelDefinition(model).properties[property]; + const prop = this.getModelDefinition(model).properties[property]; if (prop.hasOwnProperty('default')) { colDefault = String(this.escapeValue(prop.default)); } @@ -429,27 +429,27 @@ function mixinMigration(PostgreSQL) { // override this function from base connector to allow postgres connector to // accept dataPrecision and dataScale as column specific properties PostgreSQL.prototype.columnDataType = function(model, property) { - var columnMetadata = this.columnMetadata(model, property); - var colType = columnMetadata && columnMetadata.dataType; + const columnMetadata = this.columnMetadata(model, property); + let colType = columnMetadata && columnMetadata.dataType; if (colType) { colType = colType.toUpperCase(); } - var prop = this.getModelDefinition(model).properties[property]; + const prop = this.getModelDefinition(model).properties[property]; if (!prop) { return null; } - var colLength = columnMetadata && columnMetadata.dataLength || prop.length || prop.limit; - var colPrecision = columnMetadata && columnMetadata.dataPrecision; - var colScale = columnMetadata && columnMetadata.dataScale; + const colLength = columnMetadata && columnMetadata.dataLength || prop.length || prop.limit; + const colPrecision = columnMetadata && columnMetadata.dataPrecision; + const colScale = columnMetadata && columnMetadata.dataScale; // info on setting column specific properties // i.e dataLength, dataPrecision, dataScale // https://loopback.io/doc/en/lb3/Model-definition-JSON-file.html if (colType) { - if (colType === 'CHARACTER VARYING') return 'VARCHAR(' + colLength + ')'; + if (colType === 'CHARACTER VARYING') return 'VARCHAR(' + colLength + ')'; if (colLength) return colType + '(' + colLength + ')'; if (colPrecision && colScale) return colType + '(' + colPrecision + ',' + colScale + ')'; if (colType.startsWith('TIME')) { - var strPrecision = ''; + let strPrecision = ''; if (colPrecision < 6) { // default is 6 strPrecision = '(' + colPrecision + ') '; } @@ -476,7 +476,7 @@ function mixinMigration(PostgreSQL) { }; PostgreSQL.prototype.buildColumnType = function buildColumnType(propertyDefinition) { - var p = propertyDefinition; + const p = propertyDefinition; switch (p.type.name) { default: case 'String': @@ -499,7 +499,7 @@ function mixinMigration(PostgreSQL) { }; PostgreSQL.prototype.addForeignKeys = function(model, fkSQL, cb) { - var self = this; + const self = this; if (fkSQL && fkSQL.length) { self.applySqlChanges(model, [fkSQL.toString()], function(err, result) { @@ -511,24 +511,24 @@ function mixinMigration(PostgreSQL) { }; PostgreSQL.prototype.getDropForeignKeys = function(model, actualFks) { - var self = this; - var m = this.getModelDefinition(model); + const self = this; + const m = this.getModelDefinition(model); - var fks = actualFks; - var sql = []; - var correctFks = m.settings.foreignKeys || {}; + const fks = actualFks; + let sql = []; + const correctFks = m.settings.foreignKeys || {}; // drop foreign keys for removed fields if (fks && fks.length) { - var removedFks = []; + const removedFks = []; fks.forEach(function(fk) { - var needsToDrop = false; - var newFk = correctFks[fk.fkName]; + let needsToDrop = false; + const newFk = correctFks[fk.fkName]; if (newFk) { - var fkCol = newFk.foreignKey; - var fkRefKey = newFk.entityKey; - var fkEntityName = (typeof newFk.entity === 'object') ? newFk.entity.name : newFk.entity; - var fkRefTable = self.table(fkEntityName); + const fkCol = newFk.foreignKey; + const fkRefKey = newFk.entityKey; + const fkEntityName = (typeof newFk.entity === 'object') ? newFk.entity.name : newFk.entity; + const fkRefTable = self.table(fkEntityName); needsToDrop = !isCaseInsensitiveEqual(fkCol, fk.fkColumnName) || !isCaseInsensitiveEqual(fkRefKey, fk.pkColumnName) || !isCaseInsensitiveEqual(fkRefTable, fk.pkTableName); @@ -552,7 +552,7 @@ function mixinMigration(PostgreSQL) { // update out list of existing keys by removing dropped keys removedFks.forEach(function(k) { - var index = actualFks.indexOf(k); + const index = actualFks.indexOf(k); if (index !== -1) actualFks.splice(index, 1); }); } @@ -560,19 +560,19 @@ function mixinMigration(PostgreSQL) { }; PostgreSQL.prototype.getForeignKeySQL = function getForeignKeySQL(model, actualFks, existingFks) { - var self = this; - var addFksSql = []; + const self = this; + const addFksSql = []; existingFks = existingFks || []; if (actualFks) { - var keys = Object.keys(actualFks); + const keys = Object.keys(actualFks); for (var i = 0; i < keys.length; i++) { // all existing fks are already checked in PostgreSQL.prototype.dropForeignKeys // so we need check only names - skip if found if (existingFks.filter(function(fk) { return fk.fkName === keys[i]; }).length > 0) continue; - var constraint = self.buildForeignKeyDefinition(model, keys[i]); + const constraint = self.buildForeignKeyDefinition(model, keys[i]); if (constraint) { addFksSql.push('ADD ' + constraint); @@ -583,12 +583,12 @@ function mixinMigration(PostgreSQL) { }; PostgreSQL.prototype.buildForeignKeyDefinition = function buildForeignKeyDefinition(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) { // 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 if (this._models[fkEntityName]) { @@ -630,7 +630,7 @@ function mixinMigration(PostgreSQL) { * @returns {String} */ function postgresqlDataTypeToJSONType(postgresqlType, dataLength) { - var type = postgresqlType.toUpperCase(); + const type = postgresqlType.toUpperCase(); switch (type) { case 'BOOLEAN': return 'Boolean'; @@ -697,8 +697,8 @@ function mixinMigration(PostgreSQL) { } function mapPostgreSQLDatatypes(typeName, typeLength, typeTimePrecision) { - var type = typeName.toUpperCase(); - var strPrecision = ''; + const type = typeName.toUpperCase(); + let strPrecision = ''; if (typeTimePrecision < 6) { // default is 6 strPrecision = '(' + typeTimePrecision + ') '; } @@ -720,34 +720,34 @@ function mixinMigration(PostgreSQL) { } PostgreSQL.prototype.addIndexes = function(model, actualIndexes, cb) { - var self = this; - var m = self._models[model]; - var propNames = Object.keys(m.properties).filter(function(name) { + const self = this; + const m = self._models[model]; + const propNames = Object.keys(m.properties).filter(function(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]; }) || []; - var sql = []; - var ai = {}; - var propNameRegEx = new RegExp('^' + self.table(model) + '_([^_]+)_idx'); + const sql = []; + const ai = {}; + const propNameRegEx = new RegExp('^' + self.table(model) + '_([^_]+)_idx'); if (actualIndexes) { actualIndexes.forEach(function(i) { - var name = i.name; + const name = i.name; if (!ai[name]) { ai[name] = i; } }); } - var aiNames = Object.keys(ai); + const aiNames = Object.keys(ai); // remove indexes aiNames.forEach(function(indexName) { - var schema = self.escapeName(self.schema(model) || 'public'); - var i = ai[indexName]; - var propName = propNameRegEx.exec(indexName); - var si; // index definition from model schema + const schema = self.escapeName(self.schema(model) || 'public'); + const i = ai[indexName]; + let propName = propNameRegEx.exec(indexName); + let si; // index definition from model schema if (i.primary || (m.properties[indexName] && self.id(model, indexName))) return; @@ -774,12 +774,12 @@ function mixinMigration(PostgreSQL) { // second: check other indexes si = normalizeIndexDefinition(m.settings.indexes[indexName]); - var identical = + let identical = (!si.type || si.type === i.type) && // compare type ((si.options && !!si.options.unique) === i.unique); // compare unique // if this is a multi-column query, verify that the order matches - var siKeys = Object.keys(si.keys); + const siKeys = Object.keys(si.keys); if (identical && siKeys.length > 1) { if (siKeys.length !== i.keys.length) { // lengths differ, obviously non-matching @@ -801,20 +801,20 @@ function mixinMigration(PostgreSQL) { // add single-column indexes propNames.forEach(function(propName) { - var i = m.properties[propName].index; + const i = m.properties[propName].index; if (!i) { return; } // The index name used should match the default naming scheme // by postgres: __idx - var iName = [self.table(model), self.column(model, propName), 'idx'].join('_'); + const iName = [self.table(model), self.column(model, propName), 'idx'].join('_'); - var found = ai[iName]; // && ai[iName].info; + const found = ai[iName]; // && ai[iName].info; if (!found) { - var pName = self.escapeName(self.column(model, propName)); - var type = ''; - var kind = ''; + const pName = self.escapeName(self.column(model, propName)); + let type = ''; + let kind = ''; if (i.type) { type = ' USING ' + i.type; } @@ -833,17 +833,17 @@ function mixinMigration(PostgreSQL) { // add multi-column indexes indexNames.forEach(function(indexName) { - var i = m.settings.indexes[indexName]; - var found = ai[indexName]; + let i = m.settings.indexes[indexName]; + const found = ai[indexName]; if (!found) { i = normalizeIndexDefinition(i); - var iName = self.escapeName(indexName); - var columns = i.keys.map(function(key) { + const iName = self.escapeName(indexName); + const columns = i.keys.map(function(key) { return self.escapeName(self.column(model, key[0])) + (key[1] ? ' ' + key[1] : ''); }).join(', '); - var type = ''; - var kind = ''; + let type = ''; + let kind = ''; if (i.type) { type = ' USING ' + i.type; } @@ -860,7 +860,7 @@ function mixinMigration(PostgreSQL) { } }); - //console.log(sql.join('\n\n')); + // console.log(sql.join('\n\n')); this.query(sql.join(';\n'), cb); }; @@ -876,10 +876,10 @@ function mixinMigration(PostgreSQL) { // ['column1', 'column2'] // to: // [['column1', 'ASC'], ['column2', 'ASC']] - var column; - var attribs; - var parts; - var result; + let column; + let attribs; + let parts; + let result; // Default is ASC if (typeof keys === 'string') { @@ -917,7 +917,7 @@ function mixinMigration(PostgreSQL) { } function normalizeIndexDefinition(index) { - if (typeof index === 'object' && index.keys) { + if (typeof index === 'object' && index.keys) { // Full form index.options = index.options || {}; index.keys = normalizeIndexKeyDefinition(index.keys); diff --git a/lib/postgresql.js b/lib/postgresql.js index d1e5236b..6601824f 100644 --- a/lib/postgresql.js +++ b/lib/postgresql.js @@ -7,15 +7,15 @@ * PostgreSQL connector for LoopBack */ 'use strict'; -var SG = require('strong-globalize'); -var g = SG(); -var postgresql = require('pg'); -var SqlConnector = require('loopback-connector').SqlConnector; -var ParameterizedSQL = SqlConnector.ParameterizedSQL; -var util = require('util'); -var debug = require('debug')('loopback:connector:postgresql'); -var debugData = require('debug')('loopback:connector:postgresql:data'); -var Promise = require('bluebird'); +const SG = require('strong-globalize'); +const g = SG(); +const postgresql = require('pg'); +const SqlConnector = require('loopback-connector').SqlConnector; +const ParameterizedSQL = SqlConnector.ParameterizedSQL; +const util = require('util'); +const debug = require('debug')('loopback:connector:postgresql'); +const debugData = require('debug')('loopback:connector:postgresql:data'); +const Promise = require('bluebird'); /** * @@ -31,7 +31,7 @@ exports.initialize = function initializeDataSource(dataSource, callback) { return; } - var dbSettings = dataSource.settings || {}; + const dbSettings = dataSource.settings || {}; dbSettings.host = dbSettings.host || dbSettings.hostname || 'localhost'; dbSettings.user = dbSettings.user || dbSettings.username; @@ -96,7 +96,7 @@ PostgreSQL.prototype.getDefaultSchemaName = function() { * @callback {Function} [callback] The callback after the connection is established */ PostgreSQL.prototype.connect = function(callback) { - var self = this; + const self = this; self.pg.connect(function(err, client, done) { self.client = client; process.nextTick(done); @@ -115,7 +115,7 @@ PostgreSQL.prototype.connect = function(callback) { * @param {Object[]) data The result from the SQL */ PostgreSQL.prototype.executeSQL = function(sql, params, options, callback) { - var self = this; + const self = this; if (params && params.length > 0) { debug('SQL: %s\nParameters: %j', sql, params); @@ -134,7 +134,7 @@ PostgreSQL.prototype.executeSQL = function(sql, params, options, callback) { done(err); }); } - var result = null; + let result = null; if (data) { switch (data.command) { case 'DELETE': @@ -153,7 +153,7 @@ PostgreSQL.prototype.executeSQL = function(sql, params, options, callback) { }); } - var transaction = options.transaction; + const transaction = options.transaction; if (transaction && transaction.connector === this) { if (!transaction.connection) { return process.nextTick(function() { @@ -177,9 +177,9 @@ PostgreSQL.prototype.executeSQL = function(sql, params, options, callback) { }; PostgreSQL.prototype.buildInsertReturning = function(model, data, options) { - var idColumnNames = []; - var idNames = this.idNames(model); - for (var i = 0, n = idNames.length; i < n; i++) { + const idColumnNames = []; + const idNames = this.idNames(model); + for (let i = 0, n = idNames.length; i < n; i++) { idColumnNames.push(this.columnEscaped(model, idNames[i])); } return 'RETURNING ' + idColumnNames.join(','); @@ -247,7 +247,7 @@ PostgreSQL.prototype.fromColumnValue = function(prop, val) { if (val == null) { return val; } - var type = prop.type && prop.type.name; + const type = prop.type && prop.type.name; if (prop && type === 'Boolean') { if (typeof val === 'boolean') { return val; @@ -258,7 +258,7 @@ PostgreSQL.prototype.fromColumnValue = function(prop, val) { } else if (prop && type === 'GeoPoint' || type === 'Point') { if (typeof val === 'string') { // The point format is (x,y) - var point = val.split(/[\(\)\s,]+/).filter(Boolean); + const point = val.split(/[\(\)\s,]+/).filter(Boolean); return { lat: +point[0], lng: +point[1], @@ -291,9 +291,9 @@ PostgreSQL.prototype.dbName = function(name) { }; function escapeIdentifier(str) { - var escaped = '"'; - for (var i = 0; i < str.length; i++) { - var c = str[i]; + let escaped = '"'; + for (let i = 0; i < str.length; i++) { + const c = str[i]; if (c === '"') { escaped += c + c; } else { @@ -305,10 +305,10 @@ function escapeIdentifier(str) { } function escapeLiteral(str) { - var hasBackslash = false; - var escaped = '\''; - for (var i = 0; i < str.length; i++) { - var c = str[i]; + let hasBackslash = false; + let escaped = '\''; + for (let i = 0; i < str.length; i++) { + const c = str[i]; if (c === '\'') { escaped += c + c; } else if (c === '\\') { @@ -344,7 +344,7 @@ function isNested(property) { PostgreSQL.prototype.columnEscaped = function(model, property) { if (isNested(property)) { // Convert column to PostgreSQL json style query: "model"->>'val' - var self = this; + const self = this; return property .split('.') .map(function(val, idx) { return (idx === 0 ? self.columnEscaped(model, val) : escapeLiteral(val)); }) @@ -383,13 +383,13 @@ PostgreSQL.prototype.escapeValue = function(value) { }; PostgreSQL.prototype.tableEscaped = function(model) { - var schema = this.schema(model) || 'public'; + const schema = this.schema(model) || 'public'; return this.escapeName(schema) + '.' + this.escapeName(this.table(model)); }; function buildLimit(limit, offset) { - var clause = []; + const clause = []; if (isNaN(limit)) { limit = 0; } @@ -409,25 +409,25 @@ function buildLimit(limit, offset) { } PostgreSQL.prototype.applyPagination = function(model, stmt, filter) { - var limitClause = buildLimit(filter.limit, filter.offset || filter.skip); + const limitClause = buildLimit(filter.limit, filter.offset || filter.skip); return stmt.merge(limitClause); }; PostgreSQL.prototype.buildExpression = function(columnName, operator, - operatorValue, propertyDefinition) { + operatorValue, propertyDefinition) { switch (operator) { case 'like': return new ParameterizedSQL(columnName + "::TEXT LIKE ? ESCAPE E'\\\\'", - [operatorValue]); + [operatorValue]); case 'ilike': return new ParameterizedSQL(columnName + "::TEXT ILIKE ? ESCAPE E'\\\\'", - [operatorValue]); + [operatorValue]); case 'nlike': return new ParameterizedSQL(columnName + "::TEXT NOT LIKE ? ESCAPE E'\\\\'", - [operatorValue]); + [operatorValue]); case 'nilike': return new ParameterizedSQL(columnName + "::TEXT NOT ILIKE ? ESCAPE E'\\\\'", - [operatorValue]); + [operatorValue]); case 'regexp': if (operatorValue.global) g.warn('{{PostgreSQL}} regex syntax does not respect the {{`g`}} flag'); @@ -437,11 +437,11 @@ PostgreSQL.prototype.buildExpression = function(columnName, operator, var regexOperator = operatorValue.ignoreCase ? ' ~* ?' : ' ~ ?'; return new ParameterizedSQL(columnName + regexOperator, - [operatorValue.source]); + [operatorValue.source]); default: // invoke the base implementation of `buildExpression` return this.invokeSuper('buildExpression', columnName, operator, - operatorValue, propertyDefinition); + operatorValue, propertyDefinition); } }; @@ -452,9 +452,9 @@ PostgreSQL.prototype.buildExpression = function(columnName, operator, PostgreSQL.prototype.disconnect = function disconnect(cb) { if (this.pg) { debug('Disconnecting from ' + this.settings.hostname); - var pg = this.pg; + const pg = this.pg; this.pg = null; - pg.end(); // This is sync + pg.end(); // This is sync } if (cb) { @@ -467,8 +467,8 @@ PostgreSQL.prototype.ping = function(cb) { }; PostgreSQL.prototype.getInsertedId = function(model, info) { - var idColName = this.idColumn(model); - var idValue; + const idColName = this.idColumn(model); + let idValue; if (info && info[0]) { idValue = info[0][idColName]; } @@ -482,7 +482,7 @@ PostgreSQL.prototype.getInsertedId = function(model, info) { * @returns {ParameterizedSQL} The SQL WHERE clause */ PostgreSQL.prototype.buildWhere = function(model, where) { - var whereClause = this._buildWhere(model, where); + const whereClause = this._buildWhere(model, where); if (whereClause.sql) { whereClause.sql = 'WHERE ' + whereClause.sql; } @@ -496,7 +496,7 @@ PostgreSQL.prototype.buildWhere = function(model, where) { * @returns {ParameterizedSQL} */ PostgreSQL.prototype._buildWhere = function(model, where) { - var columnValue, sqlExp; + let columnValue, sqlExp; if (!where) { return new ParameterizedSQL(''); } @@ -504,20 +504,20 @@ PostgreSQL.prototype._buildWhere = function(model, where) { debug('Invalid value for where: %j', where); return new ParameterizedSQL(''); } - var self = this; - var props = self.getModelDefinition(model).properties; + const self = this; + const props = self.getModelDefinition(model).properties; - var whereStmts = []; - for (var key in where) { - var stmt = new ParameterizedSQL('', []); + const whereStmts = []; + for (const key in where) { + const stmt = new ParameterizedSQL('', []); // Handle and/or operators if (key === 'and' || key === 'or') { - var branches = []; - var branchParams = []; - var clauses = where[key]; + const branches = []; + let branchParams = []; + const clauses = where[key]; if (Array.isArray(clauses)) { - for (var i = 0, n = clauses.length; i < n; i++) { - var stmtForClause = self._buildWhere(model, clauses[i]); + for (let i = 0, n = clauses.length; i < n; i++) { + const stmtForClause = self._buildWhere(model, clauses[i]); if (stmtForClause.sql) { stmtForClause.sql = '(' + stmtForClause.sql + ')'; branchParams = branchParams.concat(stmtForClause.params); @@ -533,7 +533,7 @@ PostgreSQL.prototype._buildWhere = function(model, where) { } // The value is not an array, fall back to regular fields } - var p = props[key]; + let p = props[key]; if (p == null && isNested(key)) { // See if we are querying nested json @@ -546,20 +546,20 @@ PostgreSQL.prototype._buildWhere = function(model, where) { continue; } // eslint-disable one-var - var expression = where[key]; - var columnName = self.columnEscaped(model, key); + let expression = where[key]; + const columnName = self.columnEscaped(model, key); // eslint-enable one-var if (expression === null || expression === undefined) { stmt.merge(columnName + ' IS NULL'); } else if (expression && expression.constructor === Object) { - var operator = Object.keys(expression)[0]; + const operator = Object.keys(expression)[0]; // Get the expression without the operator expression = expression[operator]; if (operator === 'inq' || operator === 'nin' || operator === 'between') { columnValue = []; if (Array.isArray(expression)) { // Column value is a list - for (var j = 0, m = expression.length; j < m; j++) { + for (let j = 0, m = expression.length; j < m; j++) { columnValue.push(this.toColumnValue(p, expression[j])); } } else { @@ -567,8 +567,8 @@ PostgreSQL.prototype._buildWhere = function(model, where) { } if (operator === 'between') { // BETWEEN v1 AND v2 - var v1 = columnValue[0] === undefined ? null : columnValue[0]; - var v2 = columnValue[1] === undefined ? null : columnValue[1]; + const v1 = columnValue[0] === undefined ? null : columnValue[0]; + const v2 = columnValue[1] === undefined ? null : columnValue[1]; columnValue = [v1, v2]; } else { // IN (v1,v2,v3) or NOT IN (v1,v2,v3) @@ -610,13 +610,13 @@ PostgreSQL.prototype._buildWhere = function(model, where) { } whereStmts.push(stmt); } - var params = []; - var sqls = []; - for (var k = 0, s = whereStmts.length; k < s; k++) { + let params = []; + const sqls = []; + for (let k = 0, s = whereStmts.length; k < s; k++) { sqls.push(whereStmts[k].sql); params = params.concat(whereStmts[k].params); } - var whereStmt = new ParameterizedSQL({ + const whereStmt = new ParameterizedSQL({ sql: sqls.join(' AND '), params: params, }); @@ -654,7 +654,7 @@ PostgreSQL.prototype.toColumnValue = function(prop, val) { if (!val.toISOString) { val = new Date(val); } - var iso = val.toISOString(); + const iso = val.toISOString(); // Pass in date as UTC and make sure Postgresql stores using UTC timezone return new ParameterizedSQL({ diff --git a/lib/transaction.js b/lib/transaction.js index 74485a22..f676c908 100644 --- a/lib/transaction.js +++ b/lib/transaction.js @@ -4,9 +4,9 @@ // License text available at https://opensource.org/licenses/Artistic-2.0 'use strict'; -var debug = require('debug')('loopback:connector:postgresql:transaction'); -var uuid = require('uuid'); -var Transaction = require('loopback-connector').Transaction; +const debug = require('debug')('loopback:connector:postgresql:transaction'); +const uuid = require('uuid'); +const Transaction = require('loopback-connector').Transaction; module.exports = mixinTransaction; @@ -20,7 +20,7 @@ function mixinTransaction(PostgreSQL) { * @param cb */ PostgreSQL.prototype.beginTransaction = function(isolationLevel, cb) { - var connector = this; + const connector = this; debug('Begin a transaction with isolation level: %s', isolationLevel); this.pg.connect(function(err, connection, done) { if (err) return cb(err); @@ -28,7 +28,7 @@ function mixinTransaction(PostgreSQL) { connection.query('BEGIN TRANSACTION ISOLATION LEVEL ' + isolationLevel, function(err) { if (err) return cb(err); - var tx = new Transaction(connector, connection); + const tx = new Transaction(connector, connection); tx.txId = uuid.v1(); connection.txId = tx.txId; cb(null, tx); @@ -43,7 +43,7 @@ function mixinTransaction(PostgreSQL) { */ PostgreSQL.prototype.commit = function(connection, cb) { debug('Commit a transaction'); - var self = this; + const self = this; connection.query('COMMIT', function(err) { self.releaseConnection(connection, err); cb(err); @@ -57,19 +57,19 @@ function mixinTransaction(PostgreSQL) { */ PostgreSQL.prototype.rollback = function(connection, cb) { debug('Rollback a transaction'); - var self = this; + const self = this; connection.query('ROLLBACK', function(err) { - //if there was a problem rolling back the query - //something is seriously messed up. Return the error - //to the done function to close & remove this client from - //the pool. If you leave a client in the pool with an unaborted - //transaction weird, hard to diagnose problems might happen. + // if there was a problem rolling back the query + // something is seriously messed up. Return the error + // to the done function to close & remove this client from + // the pool. If you leave a client in the pool with an unaborted + // transaction weird, hard to diagnose problems might happen. self.releaseConnection(connection, err); cb(err); }); - //If we don't set txId to null and wait for the callback - //of ROLLBACK query to execute, another query can be executed in the - //same transaction because the callback will be called asynchronously + // If we don't set txId to null and wait for the callback + // of ROLLBACK query to execute, another query can be executed in the + // same transaction because the callback will be called asynchronously if (typeof connection.autorelease === 'function') { connection.txId = null; } diff --git a/pretest.js b/pretest.js index 0b0e086d..a8445fdf 100644 --- a/pretest.js +++ b/pretest.js @@ -8,11 +8,11 @@ if (!process.env.CI) { return console.log('not seeding DB with test db'); } -var fs = require('fs'); -var cp = require('child_process'); +const fs = require('fs'); +const cp = require('child_process'); -var sql = fs.createReadStream(require.resolve('./test/schema.sql')); -var stdio = ['pipe', process.stdout, process.stderr]; +const sql = fs.createReadStream(require.resolve('./test/schema.sql')); +const stdio = ['pipe', process.stdout, process.stderr]; process.env.PGHOST = process.env.TEST_POSTGRESQL_HOST || process.env.POSTGRESQL_HOST || process.env.PGHOST || 'localhost'; process.env.PGPORT = process.env.TEST_POSTGRESQL_PORT || @@ -23,7 +23,7 @@ process.env.PGPASSWORD = process.env.TEST_POSTGRESQL_PASSWORD || process.env.POSTGRESQL_PASSWORD || process.env.PGPASSWORD || 'test'; console.log('seeding DB with test db...'); -var psql = cp.spawn('psql', {stdio: stdio}); +const psql = cp.spawn('psql', {stdio: stdio}); sql.pipe(psql.stdin); psql.on('exit', function(code) { console.log('done seeding DB'); diff --git a/test/init.js b/test/init.js index 53ba8a92..f0babb6a 100644 --- a/test/init.js +++ b/test/init.js @@ -4,10 +4,10 @@ // License text available at https://opensource.org/licenses/Artistic-2.0 'use strict'; -var juggler = require('loopback-datasource-juggler'); -var DataSource = juggler.DataSource; +const juggler = require('loopback-datasource-juggler'); +let DataSource = juggler.DataSource; -var config = require('rc')('loopback', {test: {postgresql: {}}}).test.postgresql; +let config = require('rc')('loopback', {test: {postgresql: {}}}).test.postgresql; process.env.PGHOST = process.env.POSTGRESQL_HOST || process.env.PGHOST || @@ -31,24 +31,24 @@ config = { password: process.env.PGPASSWORD, }; -var url = 'postgres://' + (config.username || config.user) + ':' + +const url = 'postgres://' + (config.username || config.user) + ':' + config.password + '@' + (config.host || config.hostname) + ':' + config.port + '/' + config.database; global.getDBConfig = function(useUrl) { - var settings = config; + let settings = config; if (useUrl) { settings = {url: url}; - }; + } return settings; }; -var db; +let db; global.getDataSource = global.getSchema = function(useUrl) { // Return cached data source if possible to avoid too many client error // due to multiple instances of connection pools if (!useUrl && db) return db; - var settings = getDBConfig(useUrl); + const settings = getDBConfig(useUrl); db = new DataSource(require('../'), settings); db.log = function(a) { // console.log(a); @@ -58,7 +58,7 @@ global.getDataSource = global.getSchema = function(useUrl) { global.resetDataSourceClass = function(ctor) { DataSource = ctor || juggler.DataSource; - var promise = db ? db.disconnect() : Promise.resolve(); + const promise = db ? db.disconnect() : Promise.resolve(); db = undefined; return promise; }; diff --git a/test/postgresql.autocreateschema.test.js b/test/postgresql.autocreateschema.test.js index abf7543a..bdcc23fd 100644 --- a/test/postgresql.autocreateschema.test.js +++ b/test/postgresql.autocreateschema.test.js @@ -4,9 +4,9 @@ // License text available at https://opensource.org/licenses/Artistic-2.0 'use strict'; -var should = require('should'), +const should = require('should'), assert = require('assert'); -var Another, Post, db; +let Another, Post, db; describe('Autocreate schema if not exists', function() { before(function() { @@ -44,7 +44,7 @@ describe('Autocreate schema if not exists', function() { }); it('should have new schema in place', function(done) { - var query = 'select table_schema, column_name, data_type,' + + const query = 'select table_schema, column_name, data_type,' + ' character_maximum_length, column_default ' + "from information_schema.columns where table_name = 'postincustomschema'" + " and column_name='created'"; diff --git a/test/postgresql.autoupdate.test.js b/test/postgresql.autoupdate.test.js index a8969668..b8f25e7c 100644 --- a/test/postgresql.autoupdate.test.js +++ b/test/postgresql.autoupdate.test.js @@ -4,9 +4,9 @@ // License text available at https://opensource.org/licenses/Artistic-2.0 'use strict'; -var assert = require('assert'); -var _ = require('lodash'); -var ds, properties, SimpleEmployee, Emp1, Emp2; +const assert = require('assert'); +const _ = require('lodash'); +let ds, properties, SimpleEmployee, Emp1, Emp2; before(function() { ds = getDataSource(); @@ -131,7 +131,7 @@ describe('autoupdate', function() { }); it('should auto migrate/update tables', function(done) { - var schema_v1 = + const schema_v1 = { 'name': 'CustomerTest', 'options': { @@ -168,7 +168,7 @@ describe('autoupdate', function() { }, }; - var schema_v2 = + const schema_v2 = { 'name': 'CustomerTest', 'options': { @@ -216,7 +216,7 @@ describe('autoupdate', function() { ds.automigrate(function() { ds.discoverModelProperties('customer_test', function(err, props) { assert.equal(props.length, 4); - var names = props.map(function(p) { + const names = props.map(function(p) { return p.columnName; }); assert.equal(props[0].nullable, 'NO'); @@ -253,7 +253,7 @@ describe('autoupdate', function() { ds.autoupdate(function(err, result) { ds.discoverModelProperties('customer_test', function(err, props) { assert.equal(props.length, 4); - var names = props.map(function(p) { + const names = props.map(function(p) { return p.columnName; }); assert.equal(names[0], 'id'); @@ -321,7 +321,7 @@ describe('autoupdate', function() { it('should produce valid sql for setting column nullability', function(done) { // Initial schema - var schema_v1 = + const schema_v1 = { 'name': 'NamePersonTest', 'options': { @@ -346,7 +346,7 @@ describe('autoupdate', function() { }; // Change nullability - var schema_v2 = JSON.parse(JSON.stringify(schema_v1)); + const schema_v2 = JSON.parse(JSON.stringify(schema_v1)); schema_v2.properties.name.required = true; // Create initial schema @@ -355,7 +355,7 @@ describe('autoupdate', function() { // Create updated schema ds.createModel(schema_v2.name, schema_v2.properties, schema_v2.options); ds.connector.getTableStatus(schema_v2.name, function(err, actualFields) { - var sql = ds.connector.getPropertiesToModify(schema_v2.name, actualFields)[0]; + const sql = ds.connector.getPropertiesToModify(schema_v2.name, actualFields)[0]; assert.equal(sql, 'ALTER COLUMN "name" SET NOT NULL', 'Check that the SQL is correctly spaced.'); done(); }); @@ -364,7 +364,7 @@ describe('autoupdate', function() { describe('foreign key constraint', function() { it('should create, update, and delete foreign keys', function(done) { - var product_schema = { + const product_schema = { 'name': 'Product', 'options': { 'idInjection': false, @@ -387,7 +387,7 @@ describe('autoupdate', function() { }, }; - var customer2_schema = { + const customer2_schema = { 'name': 'CustomerTest2', 'options': { 'idInjection': false, @@ -419,7 +419,7 @@ describe('autoupdate', function() { }, }; - var customer3_schema = { + const customer3_schema = { 'name': 'CustomerTest3', 'options': { 'idInjection': false, @@ -451,7 +451,7 @@ describe('autoupdate', function() { }, }; - var orderTest_schema_v1 = { + const orderTest_schema_v1 = { 'name': 'OrderTest', 'options': { 'idInjection': false, @@ -489,7 +489,7 @@ describe('autoupdate', function() { }, }; - var orderTest_schema_v2 = { + const orderTest_schema_v2 = { 'name': 'OrderTest', 'options': { 'idInjection': false, @@ -534,7 +534,7 @@ describe('autoupdate', function() { }, }; - var orderTest_schema_v3 = { + const orderTest_schema_v3 = { 'name': 'OrderTest', 'options': { 'idInjection': false, @@ -585,7 +585,7 @@ describe('autoupdate', function() { }, }; - var orderTest_schema_v4 = { + const orderTest_schema_v4 = { 'name': 'OrderTest', 'options': { 'idInjection': false, @@ -731,7 +731,7 @@ describe('autoupdate', function() { }); describe('indexes on table in schema', function() { - var schema = { + const schema = { options: { postgresql: { schema: 'aschema', @@ -745,7 +745,7 @@ describe('autoupdate', function() { }, }; - var changedSchema = Object.assign({}, schema, { + const changedSchema = Object.assign({}, schema, { properties: { something: { type: 'string', diff --git a/test/postgresql.dbdefaults.test.js b/test/postgresql.dbdefaults.test.js index 3bb2bfd7..0e7e61c5 100644 --- a/test/postgresql.dbdefaults.test.js +++ b/test/postgresql.dbdefaults.test.js @@ -4,9 +4,9 @@ // License text available at https://opensource.org/licenses/Artistic-2.0 'use strict'; -var should = require('should'), +const should = require('should'), assert = require('assert'); -var InvalidDefault, Post, db; +let InvalidDefault, Post, db; describe('database default field values', function() { before(function() { @@ -58,7 +58,7 @@ describe('database default field values', function() { it('should have \'now()\' default value in SQL column definition', function(done) { - var query = 'select column_name, data_type, character_maximum_length,' + + const query = 'select column_name, data_type, character_maximum_length,' + ' column_default' + ' from information_schema.columns' + " where table_name = 'postwithdbdefaultvalue'" + diff --git a/test/postgresql.discover.test.js b/test/postgresql.discover.test.js index 976af8ce..971ddb67 100644 --- a/test/postgresql.discover.test.js +++ b/test/postgresql.discover.test.js @@ -7,14 +7,14 @@ process.env.NODE_ENV = 'test'; require('should'); -var assert = require('assert'); -var _ = require('lodash'); +const assert = require('assert'); +const _ = require('lodash'); -var DataSource = require('loopback-datasource-juggler').DataSource; -var db, City; +const DataSource = require('loopback-datasource-juggler').DataSource; +let db, City; before(function() { - var config = getDBConfig(); + const config = getDBConfig(); config.database = 'strongloop'; db = new DataSource(require('../'), config); }); @@ -41,7 +41,7 @@ describe('discoverModels', function() { console.error(err); done(err); } else { - var views = false; + let views = false; models.forEach(function(m) { // console.dir(m); if (m.type === 'view') { @@ -65,7 +65,7 @@ describe('discoverModels', function() { console.error(err); done(err); } else { - var views = false; + let views = false; models.forEach(function(m) { // console.dir(m); if (m.type === 'view') { @@ -91,7 +91,7 @@ describe('Discover models including other users', function() { console.error(err); done(err); } else { - var others = false; + let others = false; models.forEach(function(m) { // console.dir(m); if (m.owner !== 'strongloop') { @@ -131,7 +131,7 @@ describe('Discover model properties', function() { db.discoverModelProperties('city', function(err, properties) { assert(!err); assert(properties); - var dataTypes = _.map(properties, function(prop) { + const dataTypes = _.map(properties, function(prop) { return prop.dataType; }); assert(dataTypes); @@ -145,7 +145,7 @@ describe('Discover model properties', function() { db.discoverModelProperties('city', function(err, properties) { assert(!err); assert(properties); - var prop = _.find(properties, function(prop) { + const prop = _.find(properties, function(prop) { return prop.columnName === 'code'; }); assert(prop); @@ -159,7 +159,7 @@ describe('Discover model properties', function() { db.discoverModelProperties('city', function(err, properties) { assert(!err); assert(properties); - var prop = _.find(properties, function(prop) { + const prop = _.find(properties, function(prop) { return prop.columnName === 'population'; }); assert(prop); @@ -173,7 +173,7 @@ describe('Discover model properties', function() { db.discoverModelProperties('city', function(err, properties) { assert(!err); assert(properties); - var prop = _.find(properties, function(prop) { + const prop = _.find(properties, function(prop) { return prop.columnName === 'currency'; }); assert(prop); @@ -194,11 +194,11 @@ describe('Discover model properties', function() { db.createModel(schema.name, schema.properties, schema.options); db.autoupdate(function(err) { assert(!err); - var sql = db.connector.buildQueryColumns('public', 'city'); + const sql = db.connector.buildQueryColumns('public', 'city'); db.connector.execute(sql, function(err, columns) { assert(!err); assert(columns); - var cols = _.filter(columns, function(col) { + const cols = _.filter(columns, function(col) { return col.dataType === 'real' || col.dataType === 'double precision' || col.dataType === 'integer' || col.dataType === 'bigint' || col.dataType === 'smallint'; diff --git a/test/postgresql.filterUndefined.test.js b/test/postgresql.filterUndefined.test.js index 86f1bf16..f096bc90 100644 --- a/test/postgresql.filterUndefined.test.js +++ b/test/postgresql.filterUndefined.test.js @@ -4,9 +4,9 @@ // License text available at https://opensource.org/licenses/Artistic-2.0 'use strict'; -var should = require('should'), +const should = require('should'), assert = require('assert'); -var Post, db; +let Post, db; describe('filter undefined fields', function() { before(function() { @@ -38,7 +38,7 @@ describe('filter undefined fields', function() { }); it('should insert only default value', function(done) { - var dflPost = new Post(); + const dflPost = new Post(); dflPost.save(function(err, p) { should.not.exist(err); Post.findOne({where: {id: p.id}}, function(err, p) { @@ -53,7 +53,7 @@ describe('filter undefined fields', function() { }); it('should insert default value and \'third\' field', function(done) { - var dflPost = new Post(); + const dflPost = new Post(); dflPost.third = 3; dflPost.save(function(err, p) { should.not.exist(err); @@ -106,7 +106,7 @@ describe('filter undefined fields', function() { }); it('should insert a value into \'defaultInt\' and \'second\'', function(done) { - var dflPost = new Post(); + const dflPost = new Post(); dflPost.second = 2; dflPost.defaultInt = 11; dflPost.save(function(err, p) { @@ -116,7 +116,7 @@ describe('filter undefined fields', function() { p.defaultInt.should.be.equal(11); should.not.exist(p.first); should.not.exist(p.third); - //should.exist(p.third); + // should.exist(p.third); p.second.should.be.equal(2); done(); }); diff --git a/test/postgresql.initialization.test.js b/test/postgresql.initialization.test.js index 04b31735..b6a05ba8 100644 --- a/test/postgresql.initialization.test.js +++ b/test/postgresql.initialization.test.js @@ -5,10 +5,10 @@ 'use strict'; require('./init'); -var Promise = require('bluebird'); -var connector = require('..'); -var DataSource = require('loopback-datasource-juggler').DataSource; -var should = require('should'); +const Promise = require('bluebird'); +const connector = require('..'); +const DataSource = require('loopback-datasource-juggler').DataSource; +const should = require('should'); // simple wrapper that uses JSON.parse(JSON.stringify()) as cheap clone function newConfig(withURL) { @@ -21,7 +21,7 @@ describe('initialization', function() { var pool = dataSource.connector.pg; pool.options.max.should.not.equal(999); - var settings = newConfig(); + const settings = newConfig(); settings.max = 999; // non-default value var dataSource = new DataSource(connector, settings); var pool = dataSource.connector.pg; @@ -29,7 +29,7 @@ describe('initialization', function() { }); it('honours user-defined url settings', function() { - var settings = newConfig(); + let settings = newConfig(); var dataSource = new DataSource(connector, settings); var clientConfig = dataSource.connector.clientConfig; @@ -42,25 +42,25 @@ describe('initialization', function() { }); it('honours multiple user-defined settings', function() { - var urlOnly = {url: newConfig(true).url, max: 999}; + const urlOnly = {url: newConfig(true).url, max: 999}; - var dataSource = new DataSource(connector, urlOnly); - var pool = dataSource.connector.pg; + const dataSource = new DataSource(connector, urlOnly); + const pool = dataSource.connector.pg; pool.options.max.should.equal(999); - var clientConfig = dataSource.connector.clientConfig; + const clientConfig = dataSource.connector.clientConfig; clientConfig.connectionString.should.equal(urlOnly.url); }); }); describe('postgresql connector errors', function() { it('Should complete these 4 queries without dying', function(done) { - var dataSource = getDataSource(); - var db = dataSource.connector; - var pool = db.pg; + const dataSource = getDataSource(); + const db = dataSource.connector; + const pool = db.pg; pool.options.max = 5; - var errors = 0; - var shouldGet = 0; + let errors = 0; + let shouldGet = 0; function runErrorQuery() { shouldGet++; return new Promise(function(resolve, reject) { @@ -73,9 +73,9 @@ describe('postgresql connector errors', function() { } }); }); - }; - var ps = []; - for (var i = 0; i < 12; i++) { + } + const ps = []; + for (let i = 0; i < 12; i++) { ps.push(runErrorQuery()); } Promise.all(ps).then(function() { diff --git a/test/postgresql.mapping.test.js b/test/postgresql.mapping.test.js index f4bcfb30..85ad3e2c 100644 --- a/test/postgresql.mapping.test.js +++ b/test/postgresql.mapping.test.js @@ -7,9 +7,9 @@ process.env.NODE_ENV = 'test'; require('should'); -var async = require('async'); +const async = require('async'); -var db; +let db; before(function() { db = getSchema(); @@ -17,7 +17,7 @@ before(function() { describe('Mapping models', function() { it('should honor the postgresql settings for table/column', function(done) { - var schema = + const schema = { 'name': 'TestInventory', 'options': { @@ -56,9 +56,9 @@ describe('Mapping models', function() { }, }, }; - var models = db.modelBuilder.buildModels(schema); + const models = db.modelBuilder.buildModels(schema); // console.log(models); - var Model = models['TestInventory']; + const Model = models['TestInventory']; Model.attachTo(db); db.automigrate(function(err, data) { diff --git a/test/postgresql.migration.test.js b/test/postgresql.migration.test.js index 495b89ad..55f788e2 100644 --- a/test/postgresql.migration.test.js +++ b/test/postgresql.migration.test.js @@ -4,11 +4,11 @@ // License text available at https://opensource.org/licenses/Artistic-2.0 'use strict'; -var should = require('./init.js'); -var assert = require('assert'); -var Schema = require('loopback-datasource-juggler').Schema; +const should = require('./init.js'); +const assert = require('assert'); +const Schema = require('loopback-datasource-juggler').Schema; -var db; +let db; describe('migrations', function() { before(setup); @@ -80,7 +80,7 @@ function setup(done) { db = getSchema(); - var UserDataWithIndexes = db.define('UserDataWithIndexes', { + const UserDataWithIndexes = db.define('UserDataWithIndexes', { email: {type: String, null: false, index: true}, name: String, bio: Schema.Text, @@ -141,7 +141,7 @@ function getIndexes(model, cb) { 't.relkind=\'r\' AND t.relname=\'' + table(model) + '\'', function(err, data) { - var indexes = {}; + const indexes = {}; if (!err) { // group data by index name data.forEach(function(index) { diff --git a/test/postgresql.test.js b/test/postgresql.test.js index 825a7315..dae716d1 100644 --- a/test/postgresql.test.js +++ b/test/postgresql.test.js @@ -4,26 +4,26 @@ // License text available at https://opensource.org/licenses/Artistic-2.0 'use strict'; -var juggler = require('loopback-datasource-juggler'); -var CreateDS = juggler.DataSource; +const juggler = require('loopback-datasource-juggler'); +const CreateDS = juggler.DataSource; require('./init'); -var async = require('async'); -var should = require('should'); +const async = require('async'); +const should = require('should'); -var Post, Expense, db, created, PostWithDate; +let Post, Expense, db, created, PostWithDate; describe('lazyConnect', function() { it('should skip connect phase (lazyConnect = true)', function(done) { - var dsConfig = { + const dsConfig = { host: '127.0.0.1', port: 4, lazyConnect: true, debug: false, }; - var ds = getDS(dsConfig); + const ds = getDS(dsConfig); - var errTimeout = setTimeout(function() { + const errTimeout = setTimeout(function() { done(); }, 2000); ds.on('error', function(err) { @@ -33,13 +33,13 @@ describe('lazyConnect', function() { }); it('should report connection error (lazyConnect = false)', function(done) { - var dsConfig = { + const dsConfig = { host: '127.0.0.1', port: 4, lazyConnect: false, debug: false, }; - var ds = getDS(dsConfig); + const ds = getDS(dsConfig); ds.on('error', function(err) { err.message.should.containEql('ECONNREFUSED'); @@ -49,7 +49,7 @@ describe('lazyConnect', function() { }); var getDS = function(config) { - var db = new CreateDS(require('../'), config); + const db = new CreateDS(require('../'), config); return db; }; @@ -139,7 +139,7 @@ describe('postgresql connector', function() { }); }); - var post; + let post; it('should support boolean types with true value', function(done) { Post.create( {title: 'T1', content: 'C1', approved: true, created: created}, @@ -152,7 +152,8 @@ describe('postgresql connector', function() { p.created.getTime().should.be.eql(created.getTime()); done(); }); - }); + } + ); }); it('should preserve property `count` after query execution', function(done) { @@ -161,13 +162,14 @@ describe('postgresql connector', function() { function(err, p) { if (err) return done(err); post = p; - var query = "UPDATE PostWithBoolean SET title ='T20' WHERE id=" + post.id; + const query = "UPDATE PostWithBoolean SET title ='T20' WHERE id=" + post.id; db.connector.execute(query, function(err, results) { results.should.have.property('count', 1); results.should.have.property('affectedRows', 1); done(err); }); - }); + } + ); }); it('should support `rows` if RETURNING used after UPDATE', function(done) { @@ -176,14 +178,15 @@ describe('postgresql connector', function() { function(err, p) { if (err) return done(err); post = p; - var query = 'UPDATE PostWithBoolean SET title =\'something else\' WHERE id=' + post.id + ' RETURNING id'; + const query = 'UPDATE PostWithBoolean SET title =\'something else\' WHERE id=' + post.id + ' RETURNING id'; db.connector.execute(query, function(err, results) { results.should.have.property('count', 1); results.should.have.property('affectedRows', 1); results.rows[0].id.should.eql(post.id); done(err); }); - }); + } + ); }); it('should support updating boolean types with false value', function(done) { @@ -208,7 +211,8 @@ describe('postgresql connector', function() { p.should.have.property('approved', false); done(); }); - }); + } + ); }); it('should support date types with eq', function(done) { @@ -298,8 +302,8 @@ describe('postgresql connector', function() { }); context('GeoPoint types', function() { - var GeoPoint = juggler.ModelBuilder.schemaTypes.geopoint; - var loc; + const GeoPoint = juggler.ModelBuilder.schemaTypes.geopoint; + let loc; it('should support GeoPoint types', function(done) { loc = new GeoPoint({lng: 10, lat: 20}); @@ -543,7 +547,7 @@ describe('postgresql connector', function() { beforeEach(function addSpy() { sinon.stub(console, 'warn'); }); - afterEach(function removeSpy() { + afterEach(function removeSpy() { console.warn.restore(); }); @@ -557,20 +561,20 @@ describe('postgresql connector', function() { }); it('should print a warning when the global flag is set', - function(done) { - Post.find({where: {content: {regexp: '^a/g'}}}, function(err, posts) { - console.warn.calledOnce.should.be.ok; - done(); - }); + function(done) { + Post.find({where: {content: {regexp: '^a/g'}}}, function(err, posts) { + console.warn.calledOnce.should.be.ok; + done(); }); + }); it('should print a warning when the multiline flag is set', - function(done) { - Post.find({where: {content: {regexp: '^a/m'}}}, function(err, posts) { - console.warn.calledOnce.should.be.ok; - done(); - }); + function(done) { + Post.find({where: {content: {regexp: '^a/m'}}}, function(err, posts) { + console.warn.calledOnce.should.be.ok; + done(); }); + }); }); }); @@ -590,7 +594,7 @@ describe('postgresql connector', function() { beforeEach(function addSpy() { sinon.stub(console, 'warn'); }); - afterEach(function removeSpy() { + afterEach(function removeSpy() { console.warn.restore(); }); @@ -604,20 +608,20 @@ describe('postgresql connector', function() { }); it('should print a warning when the global flag is set', - function(done) { - Post.find({where: {content: {regexp: /^a/g}}}, function(err, posts) { - console.warn.calledOnce.should.be.ok; - done(); - }); + function(done) { + Post.find({where: {content: {regexp: /^a/g}}}, function(err, posts) { + console.warn.calledOnce.should.be.ok; + done(); }); + }); it('should print a warning when the multiline flag is set', - function(done) { - Post.find({where: {content: {regexp: /^a/m}}}, function(err, posts) { - console.warn.calledOnce.should.be.ok; - done(); - }); + function(done) { + Post.find({where: {content: {regexp: /^a/m}}}, function(err, posts) { + console.warn.calledOnce.should.be.ok; + done(); }); + }); }); }); @@ -625,56 +629,56 @@ describe('postgresql connector', function() { beforeEach(function addSpy() { sinon.stub(console, 'warn'); }); - afterEach(function removeSpy() { + afterEach(function removeSpy() { console.warn.restore(); }); context('using no flags', function() { it('should work', function(done) { Post.find({where: {content: {regexp: new RegExp(/^A/)}}}, - function(err, posts) { - should.not.exist(err); - posts.length.should.equal(1); - posts[0].content.should.equal('AAA'); - done(); - }); + function(err, posts) { + should.not.exist(err); + posts.length.should.equal(1); + posts[0].content.should.equal('AAA'); + done(); + }); }); }); context('using flags', function() { it('should work', function(done) { Post.find({where: {content: {regexp: new RegExp(/^a/i)}}}, - function(err, posts) { - should.not.exist(err); - posts.length.should.equal(1); - posts[0].content.should.equal('AAA'); - done(); - }); + function(err, posts) { + should.not.exist(err); + posts.length.should.equal(1); + posts[0].content.should.equal('AAA'); + done(); + }); }); it('should print a warning when the global flag is set', - function(done) { - Post.find({where: {content: {regexp: new RegExp(/^a/g)}}}, + function(done) { + Post.find({where: {content: {regexp: new RegExp(/^a/g)}}}, function(err, posts) { console.warn.calledOnce.should.be.ok; done(); }); - }); + }); it('should print a warning when the multiline flag is set', - function(done) { - Post.find({where: {content: {regexp: new RegExp(/^a/m)}}}, + function(done) { + Post.find({where: {content: {regexp: new RegExp(/^a/m)}}}, function(err, posts) { console.warn.calledOnce.should.be.ok; done(); }); - }); + }); }); }); }); context('json data type', function() { - var Customer; + let Customer; before(function(done) { db = getDataSource(); @@ -755,14 +759,14 @@ describe('postgresql connector', function() { }); describe('Serial properties', function() { - var db; + let db; before(function() { db = getSchema(); }); it('should allow serial properties', function(done) { - var schema = + const schema = { 'name': 'TestInventory', 'options': { @@ -780,9 +784,9 @@ describe('Serial properties', function() { }, }, }; - var models = db.modelBuilder.buildModels(schema); - var Model = models['TestInventory']; - var count = 0; + const models = db.modelBuilder.buildModels(schema); + const Model = models['TestInventory']; + const count = 0; Model.attachTo(db); db.automigrate(function(err, data) { diff --git a/test/postgresql.timestamp.test.js b/test/postgresql.timestamp.test.js index 70c3057d..e3a905ee 100644 --- a/test/postgresql.timestamp.test.js +++ b/test/postgresql.timestamp.test.js @@ -4,8 +4,8 @@ // License text available at https://opensource.org/licenses/Artistic-2.0 'use strict'; -var should = require('should'); -var db, PostWithTimestamps; +const should = require('should'); +let db, PostWithTimestamps; describe('Timestamps', function() { describe('type and precision', function() { @@ -56,7 +56,8 @@ describe('Timestamps', function() { should.not.exist(err); should.exist(p); done(); - }); + } + ); }); it('isActual() should return true', function(done) { diff --git a/test/postgresql.transaction.test.js b/test/postgresql.transaction.test.js index d91edf1b..a2470477 100644 --- a/test/postgresql.transaction.test.js +++ b/test/postgresql.transaction.test.js @@ -7,9 +7,9 @@ require('./init.js'); require('should'); -var Transaction = require('loopback-connector').Transaction; +const Transaction = require('loopback-connector').Transaction; -var db, Post; +let db, Post; describe('transactions', function() { before(function(done) { @@ -21,7 +21,7 @@ describe('transactions', function() { db.automigrate('PostTX', done); }); - var currentTx; + let currentTx; // Return an async function to start a transaction and create a post function createPostInTx(post) { return function(done) { @@ -45,7 +45,7 @@ describe('transactions', function() { // records to equal to the count function expectToFindPosts(where, count, inTx) { return function(done) { - var options = {}; + const options = {}; if (inTx) { options.transaction = currentTx; } @@ -66,11 +66,11 @@ describe('transactions', function() { describe('bulk', function() { it('should work with bulk transactions', function(done) { - var completed = 0; - var concurrent = 20; - for (var i = 0; i <= concurrent; i++) { + let completed = 0; + const concurrent = 20; + for (let i = 0; i <= concurrent; i++) { var post = {title: 'tb' + i, content: 'cb' + i}; - var create = createPostInTx(post); + const create = createPostInTx(post); Transaction.begin(db.connector, Transaction.SERIALIZABLE, function(err, tx) { if (err) return done(err); @@ -100,7 +100,7 @@ describe('transactions', function() { }); describe('commit', function() { - var post = {title: 't1', content: 'c1'}; + const post = {title: 't1', content: 'c1'}; before(createPostInTx(post)); it('should not see the uncommitted insert', expectToFindPosts(post, 0)); @@ -116,8 +116,8 @@ describe('transactions', function() { }); describe('on the model', function() { - var p1Content = {title: 'p1', content: 'post-a'}; - var p2Content = {title: 'p2', content: 'post-a'}; + const p1Content = {title: 'p1', content: 'post-a'}; + const p2Content = {title: 'p2', content: 'post-a'}; before(function(done) { Post.create(p1Content, function(err, p1) { @@ -143,7 +143,7 @@ describe('transactions', function() { }); describe('rollback', function() { - var post = {title: 't2', content: 'c2'}; + const post = {title: 't2', content: 'c2'}; before(createPostInTx(post)); it('should not see the uncommitted insert', expectToFindPosts(post, 0)); @@ -159,7 +159,7 @@ describe('transactions', function() { }); describe('finished', function() { - var post = {title: 't2', content: 'c2'}; + const post = {title: 't2', content: 'c2'}; beforeEach(createPostInTx(post)); it('should throw an error when creating in a committed transaction', function(done) { From be7e95cf5e450743b155b1e5ac53110969b65589 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20Bajto=C5=A1?= Date: Thu, 4 Jul 2019 14:14:22 +0200 Subject: [PATCH 4/4] Manually fix remaining linting violations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Miroslav Bajtoš --- lib/migration.js | 7 ++++--- lib/postgresql.js | 2 +- test/init.js | 4 +--- test/postgresql.autocreateschema.test.js | 2 +- test/postgresql.autoupdate.test.js | 2 +- test/postgresql.dbdefaults.test.js | 2 +- test/postgresql.discover.test.js | 2 +- test/postgresql.filterUndefined.test.js | 2 +- test/postgresql.initialization.test.js | 20 ++++++++++---------- test/postgresql.mapping.test.js | 2 +- test/postgresql.migration.test.js | 2 +- test/postgresql.test.js | 19 ++++++++++--------- test/postgresql.timestamp.test.js | 2 +- test/postgresql.transaction.test.js | 4 ++-- 14 files changed, 36 insertions(+), 36 deletions(-) diff --git a/lib/migration.js b/lib/migration.js index 03e521e8..1659f9fa 100644 --- a/lib/migration.js +++ b/lib/migration.js @@ -83,7 +83,7 @@ function mixinMigration(PostgreSQL) { return !!m.settings.indexes[name]; }) : []; - var applyPending = function(actions, cb, err, result) { + const applyPending = function(actions, cb, err, result) { const action = actions.shift(); const pendingChanges = action && action() || []; if (pendingChanges.length) { @@ -566,7 +566,7 @@ function mixinMigration(PostgreSQL) { if (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 PostgreSQL.prototype.dropForeignKeys // so we need check only names - skip if found if (existingFks.filter(function(fk) { @@ -783,7 +783,8 @@ function mixinMigration(PostgreSQL) { if (identical && siKeys.length > 1) { if (siKeys.length !== i.keys.length) { // lengths differ, obviously non-matching - orderMatched = false; + // ??? orderMatched is not defined and not used anywhere else + // orderMatched = false; } else { siKeys.forEach(function(propName, iter) { identical = identical && self.column(model, propName) === i.keys[iter]; diff --git a/lib/postgresql.js b/lib/postgresql.js index 6601824f..0d7236bb 100644 --- a/lib/postgresql.js +++ b/lib/postgresql.js @@ -435,7 +435,7 @@ PostgreSQL.prototype.buildExpression = function(columnName, operator, if (operatorValue.multiline) g.warn('{{PostgreSQL}} regex syntax does not respect the {{`m`}} flag'); - var regexOperator = operatorValue.ignoreCase ? ' ~* ?' : ' ~ ?'; + const regexOperator = operatorValue.ignoreCase ? ' ~* ?' : ' ~ ?'; return new ParameterizedSQL(columnName + regexOperator, [operatorValue.source]); default: diff --git a/test/init.js b/test/init.js index f0babb6a..d2fa8feb 100644 --- a/test/init.js +++ b/test/init.js @@ -48,7 +48,7 @@ global.getDataSource = global.getSchema = function(useUrl) { // Return cached data source if possible to avoid too many client error // due to multiple instances of connection pools if (!useUrl && db) return db; - const settings = getDBConfig(useUrl); + const settings = global.getDBConfig(useUrl); db = new DataSource(require('../'), settings); db.log = function(a) { // console.log(a); @@ -70,5 +70,3 @@ global.connectorCapabilities = { // see https://github.com/strongloop/loopback-connector-postgresql/issues/342 supportsArrays: false, }; - -global.sinon = require('sinon'); diff --git a/test/postgresql.autocreateschema.test.js b/test/postgresql.autocreateschema.test.js index bdcc23fd..e4805837 100644 --- a/test/postgresql.autocreateschema.test.js +++ b/test/postgresql.autocreateschema.test.js @@ -10,7 +10,7 @@ let Another, Post, db; describe('Autocreate schema if not exists', function() { before(function() { - db = getDataSource(); + db = global.getDataSource(); Post = db.define('PostInCustomSchema', { created: { diff --git a/test/postgresql.autoupdate.test.js b/test/postgresql.autoupdate.test.js index b8f25e7c..900a0724 100644 --- a/test/postgresql.autoupdate.test.js +++ b/test/postgresql.autoupdate.test.js @@ -9,7 +9,7 @@ const _ = require('lodash'); let ds, properties, SimpleEmployee, Emp1, Emp2; before(function() { - ds = getDataSource(); + ds = global.getDataSource(); }); describe('autoupdate', function() { diff --git a/test/postgresql.dbdefaults.test.js b/test/postgresql.dbdefaults.test.js index 0e7e61c5..dffd0dfa 100644 --- a/test/postgresql.dbdefaults.test.js +++ b/test/postgresql.dbdefaults.test.js @@ -10,7 +10,7 @@ let InvalidDefault, Post, db; describe('database default field values', function() { before(function() { - db = getDataSource(); + db = global.getDataSource(); Post = db.define('PostWithDbDefaultValue', { created: { diff --git a/test/postgresql.discover.test.js b/test/postgresql.discover.test.js index 971ddb67..3bf13237 100644 --- a/test/postgresql.discover.test.js +++ b/test/postgresql.discover.test.js @@ -14,7 +14,7 @@ const DataSource = require('loopback-datasource-juggler').DataSource; let db, City; before(function() { - const config = getDBConfig(); + const config = global.getDBConfig(); config.database = 'strongloop'; db = new DataSource(require('../'), config); }); diff --git a/test/postgresql.filterUndefined.test.js b/test/postgresql.filterUndefined.test.js index f096bc90..5b2b36ec 100644 --- a/test/postgresql.filterUndefined.test.js +++ b/test/postgresql.filterUndefined.test.js @@ -10,7 +10,7 @@ let Post, db; describe('filter undefined fields', function() { before(function() { - db = getDataSource(); + db = global.getDataSource(); Post = db.define('FilterUndefined', { defaultInt: { diff --git a/test/postgresql.initialization.test.js b/test/postgresql.initialization.test.js index b6a05ba8..848e9456 100644 --- a/test/postgresql.initialization.test.js +++ b/test/postgresql.initialization.test.js @@ -12,32 +12,32 @@ const should = require('should'); // simple wrapper that uses JSON.parse(JSON.stringify()) as cheap clone function newConfig(withURL) { - return JSON.parse(JSON.stringify(getDBConfig(withURL))); + return JSON.parse(JSON.stringify(global.getDBConfig(withURL))); } describe('initialization', function() { it('honours user-defined pg-pool settings', function() { - var dataSource = new DataSource(connector, newConfig()); - var pool = dataSource.connector.pg; + let dataSource = new DataSource(connector, newConfig()); + let pool = dataSource.connector.pg; pool.options.max.should.not.equal(999); const settings = newConfig(); settings.max = 999; // non-default value - var dataSource = new DataSource(connector, settings); - var pool = dataSource.connector.pg; + dataSource = new DataSource(connector, settings); + pool = dataSource.connector.pg; pool.options.max.should.equal(999); }); it('honours user-defined url settings', function() { let settings = newConfig(); - var dataSource = new DataSource(connector, settings); - var clientConfig = dataSource.connector.clientConfig; + let dataSource = new DataSource(connector, settings); + let clientConfig = dataSource.connector.clientConfig; should.not.exist(clientConfig.connectionString); settings = newConfig(true); - var dataSource = new DataSource(connector, settings); - var clientConfig = dataSource.connector.clientConfig; + dataSource = new DataSource(connector, settings); + clientConfig = dataSource.connector.clientConfig; clientConfig.connectionString.should.equal(settings.url); }); @@ -55,7 +55,7 @@ describe('initialization', function() { describe('postgresql connector errors', function() { it('Should complete these 4 queries without dying', function(done) { - const dataSource = getDataSource(); + const dataSource = global.getDataSource(); const db = dataSource.connector; const pool = db.pg; pool.options.max = 5; diff --git a/test/postgresql.mapping.test.js b/test/postgresql.mapping.test.js index 85ad3e2c..463a0039 100644 --- a/test/postgresql.mapping.test.js +++ b/test/postgresql.mapping.test.js @@ -12,7 +12,7 @@ const async = require('async'); let db; before(function() { - db = getSchema(); + db = global.getSchema(); }); describe('Mapping models', function() { diff --git a/test/postgresql.migration.test.js b/test/postgresql.migration.test.js index 55f788e2..94f58850 100644 --- a/test/postgresql.migration.test.js +++ b/test/postgresql.migration.test.js @@ -78,7 +78,7 @@ describe('migrations', function() { function setup(done) { require('./init.js'); - db = getSchema(); + db = global.getSchema(); const UserDataWithIndexes = db.define('UserDataWithIndexes', { email: {type: String, null: false, index: true}, diff --git a/test/postgresql.test.js b/test/postgresql.test.js index dae716d1..0120ad40 100644 --- a/test/postgresql.test.js +++ b/test/postgresql.test.js @@ -6,6 +6,7 @@ 'use strict'; const juggler = require('loopback-datasource-juggler'); const CreateDS = juggler.DataSource; +const sinon = require('sinon'); require('./init'); const async = require('async'); @@ -48,14 +49,14 @@ describe('lazyConnect', function() { }); }); -var getDS = function(config) { +function getDS(config) { const db = new CreateDS(require('../'), config); return db; -}; +} describe('postgresql connector', function() { before(function() { - db = getDataSource(); + db = global.getDataSource(); Post = db.define('PostWithBoolean', { title: {type: String, length: 255, index: true}, @@ -73,7 +74,7 @@ describe('postgresql connector', function() { describe('Explicit datatype', function() { before(function(done) { - db = getDataSource(); + db = global.getDataSource(); Expense = db.define('Expense', { id: { @@ -269,7 +270,7 @@ describe('postgresql connector', function() { }); }); - it('should escape number values to defect SQL injection in find', + it('should escape number values to defect SQL injection in find (where)', function(done) { Post.find({where: {id: '(SELECT 1+1)'}}, function(err, p) { should.exists(err); @@ -285,7 +286,7 @@ describe('postgresql connector', function() { }); }); - it('should escape number values to defect SQL injection in find', + it('should escape number values to defect SQL injection in find (limit)', function(done) { Post.find({limit: '(SELECT 1+1)'}, function(err, p) { should.exists(err); @@ -681,7 +682,7 @@ describe('postgresql connector', function() { let Customer; before(function(done) { - db = getDataSource(); + db = global.getDataSource(); Customer = db.define('Customer', { address: { @@ -762,7 +763,7 @@ describe('Serial properties', function() { let db; before(function() { - db = getSchema(); + db = global.getSchema(); }); it('should allow serial properties', function(done) { @@ -819,7 +820,7 @@ describe('Serial properties', function() { }); }); -var data = [ +const data = [ { id: 1, description: 'Expense 1', diff --git a/test/postgresql.timestamp.test.js b/test/postgresql.timestamp.test.js index e3a905ee..7d7ca379 100644 --- a/test/postgresql.timestamp.test.js +++ b/test/postgresql.timestamp.test.js @@ -10,7 +10,7 @@ let db, PostWithTimestamps; describe('Timestamps', function() { describe('type and precision', function() { before(function() { - db = getDataSource(); + db = global.getDataSource(); PostWithTimestamps = db.define('PostWithTimestamps', { timestampDefault: { diff --git a/test/postgresql.transaction.test.js b/test/postgresql.transaction.test.js index a2470477..984b8bcf 100644 --- a/test/postgresql.transaction.test.js +++ b/test/postgresql.transaction.test.js @@ -13,7 +13,7 @@ let db, Post; describe('transactions', function() { before(function(done) { - db = getDataSource(true); + db = global.getDataSource(true); Post = db.define('PostTX', { title: {type: String, length: 255, index: true}, content: {type: String}, @@ -69,7 +69,7 @@ describe('transactions', function() { let completed = 0; const concurrent = 20; for (let i = 0; i <= concurrent; i++) { - var post = {title: 'tb' + i, content: 'cb' + i}; + const post = {title: 'tb' + i, content: 'cb' + i}; const create = createPostInTx(post); Transaction.begin(db.connector, Transaction.SERIALIZABLE, function(err, tx) {