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

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';
var AbstractConnectionManager = require('../abstract/connection-manager')
, ConnectionManager
, Utils = require('../../utils')
, Promise = require('../../promise')
, sequelizeErrors = require('../../errors')
, dataTypes = require('../../data-types').mysql
, parserMap = {};
ConnectionManager = function(dialect, sequelize) {
AbstractConnectionManager.call(this, dialect, sequelize);
this.sequelize = sequelize;
this.sequelize.config.port = this.sequelize.config.port || 3306;
try {
if (sequelize.config.dialectModulePath) {
this.lib = require(sequelize.config.dialectModulePath);
} else {
this.lib = require('mysql');
}
} catch (err) {
if (err.code === 'MODULE_NOT_FOUND') {
throw new Error('Please install mysql package manually');
const AbstractConnectionManager = require('../abstract/connection-manager');
const Utils = require('../../utils');
const Promise = require('../../promise');
const sequelizeErrors = require('../../errors');
const dataTypes = require('../../data-types').mysql;
const parserMap = new Map();
class ConnectionManager extends AbstractConnectionManager {
constructor(dialect, sequelize) {
super(dialect, sequelize);
this.sequelize = sequelize;
this.sequelize.config.port = this.sequelize.config.port || 3306;
try {
if (sequelize.config.dialectModulePath) {
this.lib = require(sequelize.config.dialectModulePath);
} else {
this.lib = require('mysql');
}
} catch (err) {
if (err.code === 'MODULE_NOT_FOUND') {
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
ConnectionManager.prototype.$refreshTypeParser = function (dataType) {
dataType.types.mysql.forEach(function (type) {
parserMap[type] = dataType.parse;
});
};
$clearTypeParser() {
parserMap.clear();
}
ConnectionManager.prototype.$clearTypeParser = function () {
parserMap = {};
};
static $typecast(field, next) {
if (parserMap.has(field.type)) {
return parserMap.get(field.type)(field, this.sequelize.options);
}
ConnectionManager.$typecast = function (field, next) {
if (parserMap[field.type]) {
return parserMap[field.type](field, this.sequelize.options);
return next();
}
return next();
};
ConnectionManager.prototype.connect = function(config) {
var self = this;
return new Promise(function (resolve, reject) {
var connectionConfig = {
host: config.host,
port: config.port,
user: config.username,
password: config.password,
database: config.database,
timezone: self.sequelize.options.timezone,
typeCast: ConnectionManager.$typecast.bind(self),
bigNumberStrings: false,
supportBigNumbers: true
};
if (config.dialectOptions) {
Object.keys(config.dialectOptions).forEach(function(key) {
connectionConfig[key] = config.dialectOptions[key];
});
}
connect(config) {
return new Promise((resolve, reject) => {
const connectionConfig = {
host: config.host,
port: config.port,
user: config.username,
password: config.password,
database: config.database,
timezone: this.sequelize.options.timezone,
typeCast: ConnectionManager.$typecast.bind(this),
bigNumberStrings: false,
supportBigNumbers: true
};
if (config.dialectOptions) {
for (const key of Object.keys(config.dialectOptions)) {
connectionConfig[key] = config.dialectOptions[key];
}
}
var connection = self.lib.createConnection(connectionConfig);
connection.connect(function(err) {
if (err) {
if (err.code) {
switch (err.code) {
case 'ECONNREFUSED':
reject(new sequelizeErrors.ConnectionRefusedError(err));
break;
case 'ER_ACCESS_DENIED_ERROR':
reject(new sequelizeErrors.AccessDeniedError(err));
break;
case 'ENOTFOUND':
reject(new sequelizeErrors.HostNotFoundError(err));
break;
case 'EHOSTUNREACH':
reject(new sequelizeErrors.HostNotReachableError(err));
break;
case 'EINVAL':
reject(new sequelizeErrors.InvalidConnectionError(err));
break;
default:
const connection = this.lib.createConnection(connectionConfig);
connection.connect(err => {
if (err) {
if (err.code) {
switch (err.code) {
case 'ECONNREFUSED':
reject(new sequelizeErrors.ConnectionRefusedError(err));
break;
case 'ER_ACCESS_DENIED_ERROR':
reject(new sequelizeErrors.AccessDeniedError(err));
break;
case 'ENOTFOUND':
reject(new sequelizeErrors.HostNotFoundError(err));
break;
case 'EHOSTUNREACH':
reject(new sequelizeErrors.HostNotReachableError(err));
break;
case 'EINVAL':
reject(new sequelizeErrors.InvalidConnectionError(err));
break;
default:
reject(new sequelizeErrors.ConnectionError(err));
break;
}
} else {
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) {
// 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', function (err) {
if (err.code === 'PROTOCOL_CONNECTION_LOST') {
// Remove it from read/write pool
self.pool.destroy(connection);
}
});
}
resolve(connection);
}).tap(connection => {
connection.query("SET time_zone = '" + this.sequelize.options.timezone + "'"); /* jshint ignore: line */
});
}
}).tap(function (connection) {
connection.query("SET time_zone = '" + self.sequelize.options.timezone + "'"); /* jshint ignore: line */
});
};
ConnectionManager.prototype.disconnect = function(connection) {
disconnect(connection) {
// Dont disconnect connections with an ended protocol
// That wil trigger a connection error
if (connection._protocol._ended) {
return Promise.resolve();
}
// Dont disconnect connections with an ended protocol
// That wil trigger a connection error
if (connection._protocol._ended) {
return Promise.resolve();
}
return new Promise(function (resolve, reject) {
connection.end(function(err) {
if (err) return reject(new sequelizeErrors.ConnectionError(err));
resolve();
return new Promise((resolve, reject) => {
connection.end(err => {
if (err) return reject(new sequelizeErrors.ConnectionError(err));
resolve();
});
});
});
};
ConnectionManager.prototype.validate = function(connection) {
return connection && ['disconnected', 'protocol_error'].indexOf(connection.state) === -1;
};
}
validate(connection) {
return connection && ['disconnected', 'protocol_error'].indexOf(connection.state) === -1;
}
}
Utils._.extend(ConnectionManager.prototype, AbstractConnectionManager.prototype);
module.exports = ConnectionManager;
module.exports.ConnectionManager = ConnectionManager;
module.exports.default = ConnectionManager;
......@@ -7,7 +7,7 @@
@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.
......@@ -19,32 +19,27 @@ var _ = require('lodash');
@param {String} columnName The name of the attribute that we want to remove.
@param {Object} options
*/
var removeColumn = function (tableName, columnName, options) {
var self = this;
function removeColumn(tableName, columnName, options) {
options = options || {};
return self.sequelize.query(
self.QueryGenerator.getForeignKeyQuery(tableName, columnName),
/* jshint validthis:true */
return this.sequelize.query(
this.QueryGenerator.getForeignKeyQuery(tableName, columnName),
_.assign({ raw: true }, options)
)
.spread(function (results) {
.spread(results => {
if (!results.length) {
// No foreign key constraints found, so we can remove the column
return;
}
return self.sequelize.query(
self.QueryGenerator.dropForeignKeyQuery(tableName, results[0].constraint_name),
_.assign({ raw: true }, options)
);
return this.sequelize.query(
this.QueryGenerator.dropForeignKeyQuery(tableName, results[0].constraint_name),
_.assign({ raw: true }, options)
);
})
.then(function () {
return self.sequelize.query(
self.QueryGenerator.removeColumnQuery(tableName, columnName),
_.assign({ raw: true }, options)
);
});
};
module.exports = {
removeColumn: removeColumn
};
.then(() => this.sequelize.query(
this.QueryGenerator.removeColumnQuery(tableName, columnName),
_.assign({ raw: true }, options)
));
}
exports.removeColumn = removeColumn;
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!