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

Commit 2fba6364 by Felix Becker Committed by Mick Hansen

ES6 Refactor: dialects / MySQL (#6047)

* Make Mysql ConnectionManager an ES6 class

* ES6 refactor of MySQL ConnectionManager

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

* Make MySQL Query an ES6 class

* ES6 refactor of MySQL Query

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

* ES6 refactor of MySQL QueryInterface

* ES6 refactor of MySQL QueryGenerator
1 parent c032ec90
'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 dataTypes = require('../../data-types').mysql;
, dataTypes = require('../../data-types').mysql const parserMap = new Map();
, parserMap = {};
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 || 3306; this.sequelize.config.port = this.sequelize.config.port || 3306;
try { try {
if (sequelize.config.dialectModulePath) { if (sequelize.config.dialectModulePath) {
this.lib = require(sequelize.config.dialectModulePath); this.lib = require(sequelize.config.dialectModulePath);
} else { } else {
this.lib = require('mysql'); this.lib = require('mysql');
} }
} catch (err) { } catch (err) {
if (err.code === 'MODULE_NOT_FOUND') { if (err.code === 'MODULE_NOT_FOUND') {
throw new Error('Please install mysql package manually'); throw new Error('Please install mysql package manually');
}
throw err;
} }
throw err;
}
this.refreshTypeParser(dataTypes); this.refreshTypeParser(dataTypes);
}; }
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
$refreshTypeParser(dataType) {
for (const type of dataType.types.mysql) {
parserMap.set(type, dataType.parse);
}
}
// Expose this as a method so that the parsing may be updated when the user has added additional, custom types $clearTypeParser() {
ConnectionManager.prototype.$refreshTypeParser = function (dataType) { parserMap.clear();
dataType.types.mysql.forEach(function (type) { }
parserMap[type] = dataType.parse;
});
};
ConnectionManager.prototype.$clearTypeParser = function () { static $typecast(field, next) {
parserMap = {}; if (parserMap.has(field.type)) {
}; return parserMap.get(field.type)(field, this.sequelize.options);
}
ConnectionManager.$typecast = function (field, next) { return next();
if (parserMap[field.type]) {
return parserMap[field.type](field, this.sequelize.options);
} }
return next(); connect(config) {
}; return new Promise((resolve, reject) => {
const connectionConfig = {
ConnectionManager.prototype.connect = function(config) { host: config.host,
var self = this; port: config.port,
return new Promise(function (resolve, reject) { user: config.username,
var connectionConfig = { password: config.password,
host: config.host, database: config.database,
port: config.port, timezone: this.sequelize.options.timezone,
user: config.username, typeCast: ConnectionManager.$typecast.bind(this),
password: config.password, bigNumberStrings: false,
database: config.database, supportBigNumbers: true
timezone: self.sequelize.options.timezone, };
typeCast: ConnectionManager.$typecast.bind(self),
bigNumberStrings: false, if (config.dialectOptions) {
supportBigNumbers: true for (const key of Object.keys(config.dialectOptions)) {
}; connectionConfig[key] = config.dialectOptions[key];
}
if (config.dialectOptions) { }
Object.keys(config.dialectOptions).forEach(function(key) {
connectionConfig[key] = config.dialectOptions[key];
});
}
var connection = self.lib.createConnection(connectionConfig); const connection = this.lib.createConnection(connectionConfig);
connection.connect(function(err) { connection.connect(err => {
if (err) { if (err) {
if (err.code) { if (err.code) {
switch (err.code) { switch (err.code) {
case 'ECONNREFUSED': case 'ECONNREFUSED':
reject(new sequelizeErrors.ConnectionRefusedError(err)); reject(new sequelizeErrors.ConnectionRefusedError(err));
break; break;
case 'ER_ACCESS_DENIED_ERROR': case 'ER_ACCESS_DENIED_ERROR':
reject(new sequelizeErrors.AccessDeniedError(err)); reject(new sequelizeErrors.AccessDeniedError(err));
break; break;
case 'ENOTFOUND': case 'ENOTFOUND':
reject(new sequelizeErrors.HostNotFoundError(err)); reject(new sequelizeErrors.HostNotFoundError(err));
break; break;
case 'EHOSTUNREACH': case 'EHOSTUNREACH':
reject(new sequelizeErrors.HostNotReachableError(err)); reject(new sequelizeErrors.HostNotReachableError(err));
break; break;
case 'EINVAL': case 'EINVAL':
reject(new sequelizeErrors.InvalidConnectionError(err)); reject(new sequelizeErrors.InvalidConnectionError(err));
break; break;
default: default:
reject(new sequelizeErrors.ConnectionError(err));
break;
}
} else {
reject(new sequelizeErrors.ConnectionError(err)); reject(new sequelizeErrors.ConnectionError(err));
break;
} }
} else {
reject(new sequelizeErrors.ConnectionError(err)); return;
} }
return; if (config.pool.handleDisconnects) {
} // Connection to the MySQL server is usually
// lost due to either server restart, or a
// connnection idle timeout (the wait_timeout
// server variable configures this)
//
// See [stackoverflow answer](http://stackoverflow.com/questions/20210522/nodejs-mysql-error-connection-lost-the-server-closed-the-connection)
connection.on('error', err => {
if (err.code === 'PROTOCOL_CONNECTION_LOST') {
// Remove it from read/write pool
this.pool.destroy(connection);
}
});
}
resolve(connection);
});
if (config.pool.handleDisconnects) { }).tap(connection => {
// Connection to the MySQL server is usually connection.query("SET time_zone = '" + this.sequelize.options.timezone + "'"); /* jshint ignore: line */
// lost due to either server restart, or a
// connnection idle timeout (the wait_timeout
// server variable configures this)
//
// See [stackoverflow answer](http://stackoverflow.com/questions/20210522/nodejs-mysql-error-connection-lost-the-server-closed-the-connection)
connection.on('error', function (err) {
if (err.code === 'PROTOCOL_CONNECTION_LOST') {
// Remove it from read/write pool
self.pool.destroy(connection);
}
});
}
resolve(connection);
}); });
}
}).tap(function (connection) { disconnect(connection) {
connection.query("SET time_zone = '" + self.sequelize.options.timezone + "'"); /* jshint ignore: line */
});
};
ConnectionManager.prototype.disconnect = function(connection) {
// Dont disconnect connections with an ended protocol // Dont disconnect connections with an ended protocol
// That wil trigger a connection error // That wil trigger a connection error
if (connection._protocol._ended) { if (connection._protocol._ended) {
return Promise.resolve(); return Promise.resolve();
} }
return new Promise(function (resolve, reject) { return new Promise((resolve, reject) => {
connection.end(function(err) { connection.end(err => {
if (err) return reject(new sequelizeErrors.ConnectionError(err)); if (err) return reject(new sequelizeErrors.ConnectionError(err));
resolve(); resolve();
});
}); });
}); }
};
ConnectionManager.prototype.validate = function(connection) { validate(connection) {
return connection && ['disconnected', 'protocol_error'].indexOf(connection.state) === -1; return connection && ['disconnected', 'protocol_error'].indexOf(connection.state) === -1;
}; }
}
Utils._.extend(ConnectionManager.prototype, AbstractConnectionManager.prototype);
module.exports = ConnectionManager; module.exports = ConnectionManager;
module.exports.ConnectionManager = ConnectionManager;
module.exports.default = ConnectionManager;
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
@static @static
*/ */
var _ = require('lodash'); const _ = require('lodash');
/** /**
A wrapper that fixes MySQL's inability to cleanly remove columns from existing tables if they have a foreign key constraint. A wrapper that fixes MySQL's inability to cleanly remove columns from existing tables if they have a foreign key constraint.
...@@ -19,32 +19,27 @@ var _ = require('lodash'); ...@@ -19,32 +19,27 @@ var _ = require('lodash');
@param {String} columnName The name of the attribute that we want to remove. @param {String} columnName The name of the attribute that we want to remove.
@param {Object} options @param {Object} options
*/ */
var removeColumn = function (tableName, columnName, options) { function removeColumn(tableName, columnName, options) {
var self = this;
options = options || {}; options = options || {};
return self.sequelize.query( /* jshint validthis:true */
self.QueryGenerator.getForeignKeyQuery(tableName, columnName), return this.sequelize.query(
this.QueryGenerator.getForeignKeyQuery(tableName, columnName),
_.assign({ raw: true }, options) _.assign({ raw: true }, options)
) )
.spread(function (results) { .spread(results => {
if (!results.length) { if (!results.length) {
// No foreign key constraints found, so we can remove the column // No foreign key constraints found, so we can remove the column
return; return;
} }
return self.sequelize.query( return this.sequelize.query(
self.QueryGenerator.dropForeignKeyQuery(tableName, results[0].constraint_name), this.QueryGenerator.dropForeignKeyQuery(tableName, results[0].constraint_name),
_.assign({ raw: true }, options) _.assign({ raw: true }, options)
); );
}) })
.then(function () { .then(() => this.sequelize.query(
return self.sequelize.query( this.QueryGenerator.removeColumnQuery(tableName, columnName),
self.QueryGenerator.removeColumnQuery(tableName, columnName), _.assign({ raw: true }, options)
_.assign({ raw: true }, options) ));
); }
}); exports.removeColumn = removeColumn;
};
module.exports = {
removeColumn: removeColumn
};
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!