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

Commit f8f732ea by Mick Hansen

Merge pull request #5688 from sequelize/before-connection-hook

Before connection hook
2 parents 35e68f67 1656c76d
......@@ -243,7 +243,11 @@ ConnectionManager.prototype.releaseConnection = function(connection) {
};
ConnectionManager.prototype.$connect = function(config) {
return this.dialect.connectionManager.connect(config);
return this.sequelize.runHooks('beforeConnect', config).bind(this).then(function () {
return this.dialect.connectionManager.connect(config).then(function (connection) {
return connection;
});
});
};
ConnectionManager.prototype.$disconnect = function(connection) {
return this.dialect.connectionManager.disconnect(connection);
......
......@@ -65,6 +65,7 @@ var hookTypes = {
afterDefine: {params: 1, sync: true},
beforeInit: {params: 2, sync: true},
afterInit: {params: 1, sync: true},
beforeConnect: {params: 1},
beforeSync: {params: 1},
afterSync: {params: 1},
beforeBulkSync: {params: 1},
......@@ -75,7 +76,8 @@ var hookAliases = {
beforeDelete: 'beforeDestroy',
afterDelete: 'afterDestroy',
beforeBulkDelete: 'beforeBulkDestroy',
afterBulkDelete: 'afterBulkDestroy'
afterBulkDelete: 'afterBulkDestroy',
beforeConnection: 'beforeConnect'
};
var Hooks = {
......@@ -421,6 +423,13 @@ Hooks.hasHooks = Hooks.hasHook;
*/
/**
* A hook that is run before a connection is created
* @param {String} name
* @param {Function} fn A callback function that is called with config passed to connection
* @name beforeConnect
*/
/**
* A hook that is run before Model.sync call
* @param {String} name
* @param {Function} fn A callback function that is called with options passed to Model.sync
......
......@@ -15,7 +15,8 @@ var url = require('url')
, Promise = require('./promise')
, Hooks = require('./hooks')
, Instance = require('./instance')
, Association = require('./associations/index');
, Association = require('./associations/index')
, _ = require('lodash');
/**
* This is the main class, the entry point to sequelize. To use it, you just need to import sequelize:
......@@ -58,12 +59,15 @@ var url = require('url')
* @param {String} [username=null] The username which is used to authenticate against the database.
* @param {String} [password=null] The password which is used to authenticate against the database.
* @param {Object} [options={}] An object with options.
* @param {String} [options.host='localhost'] The host of the relational database.
* @param {Integer} [options.port=] The port of the relational database.
* @param {String} [options.username=null] The username which is used to authenticate against the database.
* @param {String} [options.password=null] The password which is used to authenticate against the database.
* @param {String} [options.database=null] The name of the database
* @param {String} [options.dialect='mysql'] The dialect of the database you are connecting to. One of mysql, postgres, sqlite, mariadb and mssql.
* @param {String} [options.dialectModulePath=null] If specified, load the dialect library from this path. For example, if you want to use pg.js instead of pg when connecting to a pg database, you should specify 'pg.js' here
* @param {Object} [options.dialectOptions] An object of additional options, which are passed directly to the connection library
* @param {String} [options.storage] Only used by sqlite. Defaults to ':memory:'
* @param {String} [options.host='localhost'] The host of the relational database.
* @param {Integer} [options.port=] The port of the relational database.
* @param {String} [options.protocol='tcp'] The protocol of the relational database.
* @param {Object} [options.define={}] Default options for model definitions. See sequelize.define for options
* @param {Object} [options.query={}] Default options for sequelize.query
......@@ -97,20 +101,32 @@ var url = require('url')
* @param {String} uri A full database URI
* @param {object} [options={}] See above for possible options
*/
/**
* Instantiate sequelize with an options object
* @name Sequelize
* @constructor
*
* @param {object} [options={}] See above for possible options
*/
var Sequelize = function(database, username, password, options) {
var urlParts;
options = options || {};
var config;
if (arguments.length === 1 && typeof database === 'object') {
// new Sequelize({ ... options })
options = database;
config = _.pick(options, 'host', 'port', 'database', 'username', 'password');
} else if ((arguments.length === 1 && typeof database === 'string') || (arguments.length === 2 && typeof username === 'object')) {
// new Sequelize(URI, { ... options })
if (arguments.length === 1 || (arguments.length === 2 && typeof username === 'object')) {
config = {};
options = username || {};
urlParts = url.parse(arguments[0]);
// reset username and password to null so we don't pass the options as the username
username = null;
password = null;
var urlParts = url.parse(arguments[0]);
// SQLite don't have DB in connection url
if (urlParts.pathname) {
database = urlParts.pathname.replace(/^\//, '');
config.database = urlParts.pathname.replace(/^\//, '');
}
options.dialect = urlParts.protocol.replace(/:$/, '');
......@@ -121,16 +137,16 @@ var Sequelize = function(database, username, password, options) {
}
if (urlParts.auth) {
username = urlParts.auth.split(':')[0];
password = urlParts.auth.split(':')[1];
config.username = urlParts.auth.split(':')[0];
config.password = urlParts.auth.split(':')[1];
}
} else {
// new Sequelize(database, username, password, { ... options })
options = options || {};
config = {database: database, username: username, password: password};
}
var config = {database: database, username: username, password: password};
Sequelize.runHooks('beforeInit', config, options);
database = config.database;
username = config.username;
password = config.password;
this.options = Utils._.extend({
dialect: 'mysql',
......@@ -172,12 +188,16 @@ var Sequelize = function(database, username, password, options) {
this.options.hooks = this.replaceHookAliases(this.options.hooks);
if ((['', null, false].indexOf(config.password) > -1) || (typeof config.password === 'undefined')) {
config.password = null;
}
this.config = {
database: database,
username: username,
password: (((['', null, false].indexOf(password) > -1) || (typeof password === 'undefined')) ? null : password),
host: this.options.host,
port: this.options.port,
database: config.database,
username: config.username,
password: config.password,
host: config.host || this.options.host,
port: config.port || this.options.port,
pool: this.options.pool,
protocol: this.options.protocol,
native: this.options.native,
......
'use strict';
/* jshint -W030 */
var chai = require('chai')
, sinon = require('sinon')
, expect = chai.expect
, Support = require(__dirname + '/support')
, Sequelize = require(__dirname + '/../../index')
, ConnectionManager = require(__dirname + '/../../lib/dialects/abstract/connection-manager')
, Promise = Sequelize.Promise;
describe('connection manager', function () {
describe('$connect', function () {
beforeEach(function () {
this.sinon = sinon.sandbox.create();
this.dialect = {
connectionManager: {
connect: this.sinon.stub().returns(Promise.resolve())
}
};
this.sequelize = Support.createSequelizeInstance();
});
afterEach(function () {
this.sinon.restore();
});
it('should resolve connection on dialect connection manager', function () {
var connection = {};
this.dialect.connectionManager.connect.returns(Promise.resolve(connection));
var connectionManager = new ConnectionManager(this.dialect, this.sequelize);
var config = {};
return expect(connectionManager.$connect(config)).to.eventually.equal(connection).then(function () {
expect(this.dialect.connectionManager.connect).to.have.been.calledWith(config);
}.bind(this));
});
it('should let beforeConnect hook modify config', function () {
var username = Math.random().toString()
, password = Math.random().toString();
this.sequelize.beforeConnect(function (config) {
config.username = username;
config.password = password;
return config;
});
var connectionManager = new ConnectionManager(this.dialect, this.sequelize);
return connectionManager.$connect({}).then(function () {
expect(this.dialect.connectionManager.connect).to.have.been.calledWith({
username: username,
password: password
});
}.bind(this));
});
});
});
'use strict';
/* jshint -W030 */
var chai = require('chai')
, expect = chai.expect
, Sequelize = require(__dirname + '/../../index');
describe('sequelize constructor', function () {
it('should support database, username, password, options', function () {
var database = Math.random().toString()
, username = Math.random().toString()
, password = Math.random().toString()
, host = Math.random().toString()
, port = Math.random().toString();
var sequelize = new Sequelize(database, username, password, {
host: host,
port: port
});
expect(sequelize.config.database).to.equal(database);
expect(sequelize.config.username).to.equal(username);
expect(sequelize.config.password).to.equal(password);
expect(sequelize.config.host).to.equal(host);
expect(sequelize.config.port).to.equal(port);
});
it('should support connection uri, options', function () {
var dialect = 'postgres'
, database = Math.ceil(Math.random() * 9999).toString()
, username = Math.ceil(Math.random() * 9999).toString()
, password = Math.ceil(Math.random() * 9999).toString()
, host = Math.ceil(Math.random() * 9999).toString()
, port = Math.ceil(Math.random() * 9999).toString();
var uri = dialect + '://' + username + ':' + password + '@' + host + ':' + port + '/' + database;
var sequelize = new Sequelize(uri);
expect(sequelize.config.database).to.equal(database);
expect(sequelize.config.username).to.equal(username);
expect(sequelize.config.password).to.equal(password);
expect(sequelize.config.host).to.equal(host);
expect(sequelize.config.port).to.equal(port);
});
it('should support options', function () {
var database = Math.random().toString()
, username = Math.random().toString()
, password = Math.random().toString()
, host = Math.random().toString()
, port = Math.random().toString();
var sequelize = new Sequelize({
host: host,
port: port,
database: database,
username: username,
password: password
});
expect(sequelize.config.database).to.equal(database);
expect(sequelize.config.username).to.equal(username);
expect(sequelize.config.password).to.equal(password);
expect(sequelize.config.host).to.equal(host);
expect(sequelize.config.port).to.equal(port);
});
});
\ No newline at end of file
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!