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

Commit 2a78517d by Sushant Committed by GitHub

Generic Pool Update (#7109)

* generic pool update and other fixes

* connection internally removed

* doc entry

* review changes

* pooling changes
1 parent ee8194e5
......@@ -37,6 +37,7 @@
- [FIXED] Enforce unique association aliases [#7025](https://github.com/sequelize/sequelize/pull/7025)
- [FIXED] Information warnings when findAll is given incorrect inputs [#7047](https://github.com/sequelize/sequelize/pull/7047)
- [FIXED] scope method syntax loses parameters when used multiple times [#7058](https://github.com/sequelize/sequelize/issues/7058)
- [INTERNAL] Updated to `generic-pool@3.1.6` [#7109](https://github.com/sequelize/sequelize/issues/7109)
## BC breaks:
- `DATEONLY` now returns string in `YYYY-MM-DD` format rather than `Date` type
......
......@@ -130,7 +130,7 @@ class ConnectionManager extends AbstractConnectionManager {
const connection = connectionLock.unwrap();
// Dont disconnect a connection that is already disconnected
if (!!connection.closed) {
if (connection.closed) {
return Promise.resolve();
}
......@@ -143,7 +143,6 @@ class ConnectionManager extends AbstractConnectionManager {
validate(connectionLock) {
const connection = connectionLock.unwrap();
return connection && connection.loggedIn;
}
}
......
'use strict';
var _ = require('lodash')
, Abstract = require('../abstract')
, ConnectionManager = require('./connection-manager')
, Query = require('./query')
, QueryGenerator = require('./query-generator')
, DataTypes = require('../../data-types').mssql;
const _ = require('lodash');
const AbstractDialect = require('../abstract');
const ConnectionManager = require('./connection-manager');
const Query = require('./query');
const QueryGenerator = require('./query-generator');
const DataTypes = require('../../data-types').mssql;
var MssqlDialect = function(sequelize) {
this.sequelize = sequelize;
this.connectionManager = new ConnectionManager(this, sequelize);
this.connectionManager.initPools();
this.QueryGenerator = _.extend({}, QueryGenerator, {
options: sequelize.options,
_dialect: this,
sequelize
});
};
class MssqlDialect extends AbstractDialect {
constructor(sequelize) {
super();
this.sequelize = sequelize;
this.connectionManager = new ConnectionManager(this, sequelize);
this.QueryGenerator = _.extend({}, QueryGenerator, {
options: sequelize.options,
_dialect: this,
sequelize
});
}
}
MssqlDialect.prototype.supports = _.merge(_.cloneDeep(Abstract.prototype.supports), {
MssqlDialect.prototype.supports = _.merge(_.cloneDeep(AbstractDialect.prototype.supports), {
'DEFAULT': true,
'DEFAULT VALUES': true,
'LIMIT ON UPDATE': true,
......@@ -51,7 +53,7 @@ MssqlDialect.prototype.supports = _.merge(_.cloneDeep(Abstract.prototype.support
tmpTableTrigger: true
});
MssqlDialect.prototype.defaultVersion = '12.0.2000'; // SQL Server 2014 Express
ConnectionManager.prototype.defaultVersion = '12.0.2000'; // SQL Server 2014 Express
MssqlDialect.prototype.Query = Query;
MssqlDialect.prototype.name = 'mssql';
MssqlDialect.prototype.TICK_CHAR = '"';
......
'use strict';
var _ = require('lodash')
, Abstract = require('../abstract')
, ConnectionManager = require('./connection-manager')
, Query = require('./query')
, QueryGenerator = require('./query-generator')
, DataTypes = require('../../data-types').mysql;
const _ = require('lodash');
const AbstractDialect = require('../abstract');
const ConnectionManager = require('./connection-manager');
const Query = require('./query');
const QueryGenerator = require('./query-generator');
const DataTypes = require('../../data-types').mysql;
var MysqlDialect = function(sequelize) {
this.sequelize = sequelize;
this.connectionManager = new ConnectionManager(this, sequelize);
this.connectionManager.initPools();
this.QueryGenerator = _.extend({}, QueryGenerator, {
options: sequelize.options,
_dialect: this,
sequelize
});
};
class MysqlDialect extends AbstractDialect {
constructor(sequelize) {
super();
this.sequelize = sequelize;
this.connectionManager = new ConnectionManager(this, sequelize);
this.QueryGenerator = _.extend({}, QueryGenerator, {
options: sequelize.options,
_dialect: this,
sequelize
});
}
}
MysqlDialect.prototype.supports = _.merge(_.cloneDeep(Abstract.prototype.supports), {
MysqlDialect.prototype.supports = _.merge(_.cloneDeep(AbstractDialect.prototype.supports), {
'VALUES ()': true,
'LIMIT ON UPDATE': true,
'IGNORE': ' IGNORE',
......
......@@ -45,8 +45,8 @@ class ConnectionManager extends AbstractConnectionManager {
if (dataType.types.postgres.array_oids) {
for (const oid of dataType.types.postgres.array_oids) {
this.lib.types.setTypeParser(oid, value =>
this.lib.types.arrayParser.create(value, value =>
dataType.parse(value, oid, this.lib.types.getTypeParser)
this.lib.types.arrayParser.create(value, (v) =>
dataType.parse(v, oid, this.lib.types.getTypeParser)
).parse()
);
}
......@@ -172,7 +172,7 @@ class ConnectionManager extends AbstractConnectionManager {
});
}
disconnect(connection) {
return new Promise((resolve, reject) => {
return new Promise(resolve => {
connection.end();
resolve();
});
......
......@@ -12,8 +12,6 @@ class PostgresDialect extends AbstractDialect {
super();
this.sequelize = sequelize;
this.connectionManager = new ConnectionManager(this, sequelize);
this.connectionManager.initPools();
this.QueryGenerator = _.extend({}, QueryGenerator, {
options: sequelize.options,
_dialect: this,
......
......@@ -84,7 +84,8 @@ const _ = require('lodash');
* @param {Integer} [options.pool.max] Maximum number of connection in pool. Default is 5
* @param {Integer} [options.pool.min] Minimum number of connection in pool. Default is 0
* @param {Integer} [options.pool.idle] The maximum time, in milliseconds, that a connection can be idle before being released
* @param {Function} [options.pool.validateConnection] A function that validates a connection. Called with client. The default function checks that client is an object, and that its state is not disconnected
* @param {Integer} [options.pool.acquire] The maximum time, in milliseconds, that pool will try to get connection before throwing error
* @param {Function} [options.pool.validate] A function that validates a connection. Called with client. The default function checks that client is an object, and that its state is not disconnected
* @param {Boolean} [options.quoteIdentifiers=true] Set to `false` to make table names and attributes case-insensitive on Postgres and skip double quoting of them.
* @param {String} [options.transactionType='DEFERRED'] Set the default transaction type. See `Sequelize.Transaction.TYPES` for possible options. Sqlite only.
* @param {String} [options.isolationLevel] Set the default transaction isolation level. See `Sequelize.Transaction.ISOLATION_LEVELS` for possible options.
......@@ -265,10 +266,6 @@ class Sequelize {
Sequelize.runHooks('afterInit', this);
}
get connectorManager() {
return this.transactionManager.getConnectorManager();
}
refreshTypes() {
this.connectionManager.refreshTypeParser(DataTypes);
}
......@@ -500,7 +497,7 @@ class Sequelize {
if (options.replacements && options.bind) {
throw new Error('Both `replacements` and `bind` cannot be set at the same time');
}
if (options.replacements) {
if (Array.isArray(options.replacements)) {
sql = Utils.format([sql].concat(options.replacements), this.options.dialect);
......
......@@ -42,7 +42,7 @@
"depd": "^1.1.0",
"dottie": "^2.0.0",
"env-cmd": "^4.0.0",
"generic-pool": "^2.4.4",
"generic-pool": "^3.1.6",
"inflection": "1.10.0",
"lodash": "^4.17.1",
"moment": "^2.13.0",
......
......@@ -46,7 +46,7 @@ describe(Support.getTestDialectTeaser('Multiple Level Filters'), function() {
return Task.findAll({
include: [
{
model: Project,
model: Project,
include: [
{model: User, where: {username: 'leia'}}
],
......@@ -105,7 +105,7 @@ describe(Support.getTestDialectTeaser('Multiple Level Filters'), function() {
return Task.findAll({
include: [
{
model: Project,
model: Project,
include: [
{model: User, where: {
username: 'leia',
......@@ -166,7 +166,7 @@ describe(Support.getTestDialectTeaser('Multiple Level Filters'), function() {
return User.findAll({
include: [
{
model: Project,
model: Project,
include: [
{model: Task, where: {title: 'fight empire'}}
],
......
......@@ -18,7 +18,7 @@ var poolEntry = {
pool: {}
};
describe('Connction Manager', function() {
describe('Connection Manager', function() {
var sandbox;
......@@ -37,7 +37,7 @@ describe('Connction Manager', function() {
var sequelize = Support.createSequelizeInstance(options);
var connectionManager = new ConnectionManager(Support.getTestDialect(), sequelize);
var poolSpy = sandbox.spy(Pooling, 'Pool');
var poolSpy = sandbox.spy(Pooling, 'createPool');
connectionManager.initPools();
expect(poolSpy.calledOnce).to.be.true;
});
......@@ -52,7 +52,7 @@ describe('Connction Manager', function() {
var sequelize = Support.createSequelizeInstance(options);
var connectionManager = new ConnectionManager(Support.getTestDialect(), sequelize);
var poolSpy = sandbox.spy(Pooling, 'Pool');
var poolSpy = sandbox.spy(Pooling, 'createPool');
connectionManager.initPools();
expect(poolSpy.calledTwice).to.be.true;
});
......
......@@ -22,10 +22,8 @@ if (dialect.match(/^mssql/)) {
conn = connection;
// simulate a unexpected end
connection.unwrap().emit('error', {code: 'ECONNRESET'});
})
.then(function() {
return cm.releaseConnection(conn);
// connection removed from pool by MSSQL Conn Manager
conn.unwrap().emit('error', {code: 'ECONNRESET'});
})
.then(function() {
// Get next available connection
......
......@@ -9,7 +9,7 @@ var chai = require('chai')
, DataTypes = require(__dirname + '/../../../../lib/data-types');
if (dialect === 'mysql') {
describe('[MYSQL Specific] Connector Manager', function() {
describe('[MYSQL Specific] Connection Manager', function() {
it('works correctly after being idle', function() {
var User = this.sequelize.define('User', { username: DataTypes.STRING })
, spy = sinon.spy()
......
'use strict';
/* jshint -W030 */
/* jshint -W110 */
const chai = require('chai');
const expect = chai.expect;
const Support = require(__dirname + '/support');
const dialect = Support.getTestDialect();
const sinon = require('sinon');
const Sequelize = Support.Sequelize;
describe(Support.getTestDialectTeaser('Pooling'), function() {
if (dialect === 'sqlite') return;
beforeEach(() => {
this.sinon = sinon.sandbox.create();
});
afterEach(() => {
this.sinon.restore();
});
it('should reject when unable to acquire connection in given time', () => {
this.testInstance = new Sequelize('localhost', 'ffd', 'dfdf', {
dialect,
databaseVersion: '1.2.3',
pool: {
acquire: 1000 //milliseconds
}
});
this.sinon.stub(this.testInstance.connectionManager, '_connect', () => new Sequelize.Promise(() => {}));
return expect(this.testInstance.authenticate())
.to.eventually.be.rejectedWith('TimeoutError: ResourceRequest timed out');
});
});
......@@ -2,16 +2,16 @@
/* jshint -W030 */
/* jshint -W110 */
var chai = require('chai')
, expect = chai.expect
, Support = require(__dirname + '/support')
, DataTypes = require(__dirname + '/../../lib/data-types')
, dialect = Support.getTestDialect();
const chai = require('chai');
const expect = chai.expect;
const Support = require(__dirname + '/support');
const DataTypes = require(__dirname + '/../../lib/data-types');
const dialect = Support.getTestDialect();
describe(Support.getTestDialectTeaser('Replication'), function() {
if (dialect === 'sqlite') return;
beforeEach(function () {
beforeEach(() => {
this.sequelize = Support.getSequelizeInstance(null, null, null, {
replication: {
write: Support.getConnectionOptions(),
......@@ -32,13 +32,13 @@ describe(Support.getTestDialectTeaser('Replication'), function() {
return this.User.sync({force: true});
});
it('should be able to make a write', function () {
it('should be able to make a write', () => {
return this.User.create({
firstName: Math.random().toString()
});
});
it('should be able to make a read', function () {
it('should be able to make a read', () => {
return this.User.findAll();
});
});
\ No newline at end of file
});
'use strict';
/* jshint -W030 */
var chai = require('chai')
, expect = chai.expect
, sinon = require('sinon')
, Support = require(__dirname + '/support')
, Sequelize = Support.Sequelize
, dialect = Support.getTestDialect()
, current = Support.sequelize
, Promise = Sequelize.Promise;
const chai = require('chai');
const expect = chai.expect;
const sinon = require('sinon');
const Support = require(__dirname + '/support');
const Sequelize = Support.Sequelize;
const dialect = Support.getTestDialect();
const current = Support.sequelize;
describe('Transaction', function() {
before(function () {
this.stub = sinon.stub(current, 'query').returns(Promise.resolve({}));
before(() => {
this.stub = sinon.stub(current, 'query').returns(Sequelize.Promise.resolve({}));
this.stubConnection = sinon.stub(current.connectionManager, 'getConnection')
.returns(Promise.resolve({ uuid: 'ssfdjd-434fd-43dfg23-2d', close : function() { }}));
.returns(Sequelize.Promise.resolve({
uuid: 'ssfdjd-434fd-43dfg23-2d',
close(){}
}));
this.stubRelease = sinon.stub(current.connectionManager, 'releaseConnection')
.returns(Sequelize.Promise.resolve());
});
beforeEach(function () {
beforeEach(() => {
this.stub.reset();
this.stubConnection.reset();
this.stubRelease.reset();
});
after(function () {
after(() => {
this.stub.restore();
this.stubConnection.restore();
});
it('should run auto commit query only when needed', function() {
var expectations = {
it('should run auto commit query only when needed', () => {
const expectations = {
all: [
'START TRANSACTION;'
],
......@@ -43,7 +48,7 @@ describe('Transaction', function() {
};
return current.transaction(() => {
expect(this.stub.args.map(arg => arg[0])).to.deep.equal(expectations[dialect] || expectations.all);
return Promise.resolve();
return Sequelize.Promise.resolve();
});
});
});
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!