不要怂,就是干,撸起袖子干!

Commit 3107396d by Felix Becker Committed by Jan Aagaard Meier

ES6 refactor: dialects / PostgreSQL (#6048)

* ES6 refactor of hstore.js

const, export

* ES6 refactor of PostgresDialect

const, classes, property shorthands, export default

* ES6 refactor of postgres ConnectionManager

classes, let, const, arrow functions, for of, export default

* Make postgres Query an ES6 class

* ES6 refactor of postgres Query

let, const, arrow functions, property shorthands, export default

* ES6 refactor of postgres QueryGenerator

let, const, arrow functions, template strings where it was easy to implement

* ES6 refactor of postgres range.js

let, const, arrow functions, export
1 parent 3e911332
'use strict'; 'use strict';
var AbstractConnectionManager = require('../abstract/connection-manager') const AbstractConnectionManager = require('../abstract/connection-manager');
, ConnectionManager const Utils = require('../../utils');
, Utils = require('../../utils') const Promise = require('../../promise');
, Promise = require('../../promise') const sequelizeErrors = require('../../errors');
, sequelizeErrors = require('../../errors') const semver = require('semver');
, semver = require('semver') const dataTypes = require('../../data-types');
, dataTypes = require('../../data-types') const moment = require('moment-timezone');
, moment = require('moment-timezone');
class ConnectionManager extends AbstractConnectionManager {
ConnectionManager = function(dialect, sequelize) { constructor(dialect, sequelize) {
AbstractConnectionManager.call(this, dialect, sequelize); super(dialect, sequelize);
this.sequelize = sequelize; this.sequelize = sequelize;
this.sequelize.config.port = this.sequelize.config.port || 5432; this.sequelize.config.port = this.sequelize.config.port || 5432;
try { try {
var pgLib; let pgLib;
if (sequelize.config.dialectModulePath) { if (sequelize.config.dialectModulePath) {
pgLib = require(sequelize.config.dialectModulePath); pgLib = require(sequelize.config.dialectModulePath);
} else { } else {
...@@ -30,39 +30,32 @@ ConnectionManager = function(dialect, sequelize) { ...@@ -30,39 +30,32 @@ ConnectionManager = function(dialect, sequelize) {
} }
this.refreshTypeParser(dataTypes.postgres); this.refreshTypeParser(dataTypes.postgres);
}; }
Utils._.extend(ConnectionManager.prototype, AbstractConnectionManager.prototype);
// Expose this as a method so that the parsing may be updated when the user has added additional, custom types // Expose this as a method so that the parsing may be updated when the user has added additional, custom types
ConnectionManager.prototype.$refreshTypeParser = function (dataType) { $refreshTypeParser(dataType) {
var self = this;
if (dataType.types.postgres.oids) { if (dataType.types.postgres.oids) {
dataType.types.postgres.oids.forEach(function (oid) { for (const oid of dataType.types.postgres.oids) {
self.lib.types.setTypeParser(oid, function (value) { this.lib.types.setTypeParser(oid, value => dataType.parse(value, oid, this.lib.types.getTypeParser));
return dataType.parse(value, oid, self.lib.types.getTypeParser); }
});
});
} }
if (dataType.types.postgres.array_oids) { if (dataType.types.postgres.array_oids) {
dataType.types.postgres.array_oids.forEach(function (oid) { for (const oid of dataType.types.postgres.array_oids) {
self.lib.types.setTypeParser(oid, function (value) { this.lib.types.setTypeParser(oid, value =>
return self.lib.types.arrayParser.create(value, function (value) { this.lib.types.arrayParser.create(value, value =>
return dataType.parse(value, oid, self.lib.types.getTypeParser); dataType.parse(value, oid, this.lib.types.getTypeParser)
}).parse(); ).parse()
}); );
}); }
}
} }
};
ConnectionManager.prototype.connect = function(config) { connect(config) {
var self = this
, connectionConfig = {};
config.user = config.username; config.user = config.username;
connectionConfig = Utils._.pick(config, [ const connectionConfig = Utils._.pick(config, [
'user', 'password', 'host', 'database', 'port' 'user', 'password', 'host', 'database', 'port'
]); ]);
...@@ -86,11 +79,11 @@ ConnectionManager.prototype.connect = function(config) { ...@@ -86,11 +79,11 @@ ConnectionManager.prototype.connect = function(config) {
])); ]));
} }
return new Promise(function (resolve, reject) { return new Promise((resolve, reject) => {
var connection = new self.lib.Client(connectionConfig) const connection = new this.lib.Client(connectionConfig);
, responded = false; let responded = false;
connection.connect(function(err) { connection.connect(err => {
if (err) { if (err) {
if (err.code) { if (err.code) {
switch (err.code) { switch (err.code) {
...@@ -120,30 +113,30 @@ ConnectionManager.prototype.connect = function(config) { ...@@ -120,30 +113,30 @@ ConnectionManager.prototype.connect = function(config) {
}); });
// If we didn't ever hear from the client.connect() callback the connection timeout, node-postgres does not treat this as an error since no active query was ever emitted // If we didn't ever hear from the client.connect() callback the connection timeout, node-postgres does not treat this as an error since no active query was ever emitted
connection.on('end', function () { connection.on('end', () => {
if (!responded) { if (!responded) {
reject(new sequelizeErrors.ConnectionTimedOutError(new Error('Connection timed out'))); reject(new sequelizeErrors.ConnectionTimedOutError(new Error('Connection timed out')));
} }
}); });
// Don't let a Postgres restart (or error) to take down the whole app // Don't let a Postgres restart (or error) to take down the whole app
connection.on('error', function() { connection.on('error', () => {
connection._invalid = true; connection._invalid = true;
}); });
}).tap(function (connection) { }).tap(connection => {
// Disable escape characters in strings, see https://github.com/sequelize/sequelize/issues/3545 // Disable escape characters in strings, see https://github.com/sequelize/sequelize/issues/3545
var query = ''; let query = '';
if (self.sequelize.options.databaseVersion !== 0 && semver.gte(self.sequelize.options.databaseVersion, '8.2.0')) { if (this.sequelize.options.databaseVersion !== 0 && semver.gte(this.sequelize.options.databaseVersion, '8.2.0')) {
query += 'SET standard_conforming_strings=on;'; query += 'SET standard_conforming_strings=on;';
} }
if (!self.sequelize.config.keepDefaultTimezone) { if (!this.sequelize.config.keepDefaultTimezone) {
var isZone = !!moment.tz.zone(self.sequelize.options.timezone); const isZone = !!moment.tz.zone(this.sequelize.options.timezone);
if (isZone) { if (isZone) {
query += 'SET client_min_messages TO warning; SET TIME ZONE \'' + self.sequelize.options.timezone + '\';'; query += 'SET client_min_messages TO warning; SET TIME ZONE \'' + this.sequelize.options.timezone + '\';';
} else { } else {
query += 'SET client_min_messages TO warning; SET TIME ZONE INTERVAL \'' + self.sequelize.options.timezone + '\' HOUR TO MINUTE;'; query += 'SET client_min_messages TO warning; SET TIME ZONE INTERVAL \'' + this.sequelize.options.timezone + '\' HOUR TO MINUTE;';
} }
} }
...@@ -152,11 +145,11 @@ ConnectionManager.prototype.connect = function(config) { ...@@ -152,11 +145,11 @@ ConnectionManager.prototype.connect = function(config) {
query += 'SELECT typname, oid, typarray FROM pg_type WHERE typtype = \'b\' AND typname IN (\'hstore\', \'geometry\', \'geography\')'; query += 'SELECT typname, oid, typarray FROM pg_type WHERE typtype = \'b\' AND typname IN (\'hstore\', \'geometry\', \'geography\')';
} }
return new Promise(function (resolve, reject) { return new Promise((resolve, reject) => {
connection.query(query).on('error', function (err) { connection.query(query)
reject(err); .on('error', err => reject(err))
}).on('row', function (row) { .on('row', row => {
var type; let type;
if (row.typname === 'geometry') { if (row.typname === 'geometry') {
type = dataTypes.postgres.GEOMETRY; type = dataTypes.postgres.GEOMETRY;
} else if (row.typname === 'hstore') { } else if (row.typname === 'hstore') {
...@@ -168,22 +161,26 @@ ConnectionManager.prototype.connect = function(config) { ...@@ -168,22 +161,26 @@ ConnectionManager.prototype.connect = function(config) {
type.types.postgres.oids.push(row.oid); type.types.postgres.oids.push(row.oid);
type.types.postgres.array_oids.push(row.typarray); type.types.postgres.array_oids.push(row.typarray);
self.$refreshTypeParser(type); this.$refreshTypeParser(type);
}).on('end', function () { })
resolve(); .on('end', () => resolve());
}); });
}); });
}); }
}; disconnect(connection) {
ConnectionManager.prototype.disconnect = function(connection) { return new Promise((resolve, reject) => {
return new Promise(function (resolve, reject) {
connection.end(); connection.end();
resolve(); resolve();
}); });
}; }
ConnectionManager.prototype.validate = function(connection) { validate(connection) {
return connection._invalid === undefined; return connection._invalid === undefined;
}; }
}
Utils._.extend(ConnectionManager.prototype, AbstractConnectionManager.prototype);
module.exports = ConnectionManager; module.exports = ConnectionManager;
module.exports.ConnectionManager = ConnectionManager;
module.exports.default = ConnectionManager;
'use strict'; 'use strict';
var hstore = require('pg-hstore')({sanitize : true}); const hstore = require('pg-hstore')({sanitize : true});
function stringify (data) { function stringify (data) {
if (data === null) return null; if (data === null) return null;
return hstore.stringify(data); return hstore.stringify(data);
} }
exports.stringify = stringify;
function parse (value) { function parse (value) {
if (value === null) return null; if (value === null) return null;
return hstore.parse(value); return hstore.parse(value);
} }
exports.parse = parse;
module.exports = {
stringify: stringify,
parse: parse
};
'use strict'; 'use strict';
var _ = require('lodash') const _ = require('lodash');
, Abstract = require('../abstract') const AbstractDialect = require('../abstract');
, ConnectionManager = require('./connection-manager') const ConnectionManager = require('./connection-manager');
, Query = require('./query') const Query = require('./query');
, QueryGenerator = require('./query-generator') const QueryGenerator = require('./query-generator');
, DataTypes = require('../../data-types').postgres; const DataTypes = require('../../data-types').postgres;
var PostgresDialect = function(sequelize) { class PostgresDialect extends AbstractDialect {
constructor(sequelize) {
super();
this.sequelize = sequelize; this.sequelize = sequelize;
this.connectionManager = new ConnectionManager(this, sequelize); this.connectionManager = new ConnectionManager(this, sequelize);
this.connectionManager.initPools(); this.connectionManager.initPools();
...@@ -15,11 +17,12 @@ var PostgresDialect = function(sequelize) { ...@@ -15,11 +17,12 @@ var PostgresDialect = function(sequelize) {
this.QueryGenerator = _.extend({}, QueryGenerator, { this.QueryGenerator = _.extend({}, QueryGenerator, {
options: sequelize.options, options: sequelize.options,
_dialect: this, _dialect: this,
sequelize: sequelize sequelize
}); });
}; }
}
PostgresDialect.prototype.supports = _.merge(_.cloneDeep(Abstract.prototype.supports), { PostgresDialect.prototype.supports = _.merge(_.cloneDeep(AbstractDialect.prototype.supports), {
'DEFAULT VALUES': true, 'DEFAULT VALUES': true,
'EXCEPTION': true, 'EXCEPTION': true,
'ON DUPLICATE KEY': false, 'ON DUPLICATE KEY': false,
...@@ -59,3 +62,5 @@ PostgresDialect.prototype.TICK_CHAR_LEFT = PostgresDialect.prototype.TICK_CHAR; ...@@ -59,3 +62,5 @@ PostgresDialect.prototype.TICK_CHAR_LEFT = PostgresDialect.prototype.TICK_CHAR;
PostgresDialect.prototype.TICK_CHAR_RIGHT = PostgresDialect.prototype.TICK_CHAR; PostgresDialect.prototype.TICK_CHAR_RIGHT = PostgresDialect.prototype.TICK_CHAR;
module.exports = PostgresDialect; module.exports = PostgresDialect;
module.exports.default = PostgresDialect;
module.exports.PostgresDialect = PostgresDialect;
'use strict'; 'use strict';
var _ = require('lodash'); const _ = require('lodash');
function stringifyRangeBound (bound) { function stringifyRangeBound (bound) {
if (bound === null) { if (bound === null) {
...@@ -39,44 +39,38 @@ function stringify (data) { ...@@ -39,44 +39,38 @@ function stringify (data) {
data.inclusive = [true, false]; data.inclusive = [true, false];
} }
_.each(data, function (value, index) { _.each(data, (value, index) => {
if (_.isObject(value)) { if (_.isObject(value)) {
if (value.hasOwnProperty('inclusive')) data.inclusive[index] = !!value.inclusive; if (value.hasOwnProperty('inclusive')) data.inclusive[index] = !!value.inclusive;
if (value.hasOwnProperty('value')) data[index] = value.value; if (value.hasOwnProperty('value')) data[index] = value.value;
} }
}); });
var lowerBound = stringifyRangeBound(data[0]); const lowerBound = stringifyRangeBound(data[0]);
var upperBound = stringifyRangeBound(data[1]); const upperBound = stringifyRangeBound(data[1]);
return (data.inclusive[0] ? '[' : '(') + lowerBound + ',' + upperBound + (data.inclusive[1] ? ']' : ')'); return (data.inclusive[0] ? '[' : '(') + lowerBound + ',' + upperBound + (data.inclusive[1] ? ']' : ')');
} }
exports.stringify = stringify;
function parse (value, parser) { function parse (value, parser) {
if (value === null) return null; if (value === null) return null;
if (value === 'empty') { if (value === 'empty') {
var empty = []; const empty = [];
empty.inclusive = []; empty.inclusive = [];
return empty; return empty;
} }
var result = value let result = value
.substring(1, value.length - 1) .substring(1, value.length - 1)
.split(',', 2); .split(',', 2);
if (result.length !== 2) return value; if (result.length !== 2) return value;
result = result result = result.map(value => parseRangeBound(value, parser));
.map(function (value) {
return parseRangeBound(value, parser);
});
result.inclusive = [(value[0] === '['), (value[value.length - 1] === ']')]; result.inclusive = [(value[0] === '['), (value[value.length - 1] === ']')];
return result; return result;
} }
exports.parse = parse;
module.exports = {
stringify: stringify,
parse: parse
};
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!