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

Commit 6382078a by Sushant Committed by GitHub

feat(sequelize): dialectModule option (#9972)

1 parent 70910476
...@@ -59,6 +59,37 @@ class ConnectionManager { ...@@ -59,6 +59,37 @@ class ConnectionManager {
} }
/** /**
* Try to load dialect module from various configured options.
* Priority goes like dialectModulePath > dialectModule > require(default)
*
* @param {String} moduleName Name of dialect module to lookup
*
* @private
* @returns {Object}
*/
_loadDialectModule(moduleName) {
try {
if (this.sequelize.config.dialectModulePath) {
return require(this.sequelize.config.dialectModulePath);
} else if (this.sequelize.config.dialectModule) {
return this.sequelize.config.dialectModule;
} else {
return require(moduleName);
}
} catch (err) {
if (err.code === 'MODULE_NOT_FOUND') {
if (this.sequelize.config.dialectModulePath) {
throw new Error(`Unable to find dialect at ${this.sequelize.config.dialectModulePath}`);
} else {
throw new Error(`Please install ${moduleName} package manually`);
}
}
throw err;
}
}
/**
* Handler which executes on process exit or connection manager shutdown * Handler which executes on process exit or connection manager shutdown
* *
* @private * @private
......
...@@ -13,22 +13,8 @@ const debugTedious = logger.getLogger().debugContext('connection:mssql:tedious') ...@@ -13,22 +13,8 @@ const debugTedious = logger.getLogger().debugContext('connection:mssql:tedious')
class ConnectionManager extends AbstractConnectionManager { class ConnectionManager extends AbstractConnectionManager {
constructor(dialect, sequelize) { constructor(dialect, sequelize) {
super(dialect, sequelize); super(dialect, sequelize);
this.sequelize.config.port = this.sequelize.config.port || 1433; this.sequelize.config.port = this.sequelize.config.port || 1433;
this.lib = this._loadDialectModule('tedious');
try {
if (sequelize.config.dialectModulePath) {
this.lib = require(sequelize.config.dialectModulePath);
} else {
this.lib = require('tedious');
}
} catch (err) {
if (err.code === 'MODULE_NOT_FOUND') {
throw new Error('Please install tedious package manually');
}
throw err;
}
this.refreshTypeParser(DataTypes); this.refreshTypeParser(DataTypes);
} }
......
...@@ -24,22 +24,8 @@ const parserStore = require('../parserStore')('mysql'); ...@@ -24,22 +24,8 @@ const parserStore = require('../parserStore')('mysql');
class ConnectionManager extends AbstractConnectionManager { class ConnectionManager extends AbstractConnectionManager {
constructor(dialect, sequelize) { constructor(dialect, sequelize) {
super(dialect, sequelize); super(dialect, sequelize);
this.sequelize.config.port = this.sequelize.config.port || 3306; this.sequelize.config.port = this.sequelize.config.port || 3306;
this.lib = this._loadDialectModule('mysql2');
try {
if (sequelize.config.dialectModulePath) {
this.lib = require(sequelize.config.dialectModulePath);
} else {
this.lib = require('mysql2');
}
} catch (err) {
if (err.code === 'MODULE_NOT_FOUND') {
throw new Error('Please install mysql2 package manually');
}
throw err;
}
this.refreshTypeParser(DataTypes); this.refreshTypeParser(DataTypes);
} }
......
...@@ -13,23 +13,10 @@ const moment = require('moment-timezone'); ...@@ -13,23 +13,10 @@ const moment = require('moment-timezone');
class ConnectionManager extends AbstractConnectionManager { class ConnectionManager extends AbstractConnectionManager {
constructor(dialect, sequelize) { constructor(dialect, sequelize) {
super(dialect, sequelize); super(dialect, sequelize);
this.sequelize.config.port = this.sequelize.config.port || 5432; this.sequelize.config.port = this.sequelize.config.port || 5432;
try { const pgLib = this._loadDialectModule('pg');
let pgLib; this.lib = this.sequelize.config.native ? pgLib.native : pgLib;
if (sequelize.config.dialectModulePath) {
pgLib = require(sequelize.config.dialectModulePath);
} else {
pgLib = require('pg');
}
this.lib = sequelize.config.native ? pgLib.native : pgLib;
} catch (err) {
if (err.code === 'MODULE_NOT_FOUND') {
throw new Error('Please install \'' + (sequelize.config.dialectModulePath || 'pg') + '\' module manually');
}
throw err;
}
this._clearTypeParser(); this._clearTypeParser();
this.refreshTypeParser(dataTypes.postgres); this.refreshTypeParser(dataTypes.postgres);
......
...@@ -12,24 +12,14 @@ class ConnectionManager extends AbstractConnectionManager { ...@@ -12,24 +12,14 @@ class ConnectionManager extends AbstractConnectionManager {
constructor(dialect, sequelize) { constructor(dialect, sequelize) {
super(dialect, sequelize); super(dialect, sequelize);
this.connections = {}; // We attempt to parse file location from a connection uri
// but we shouldn't match sequelize default host.
// We attempt to parse file location from a connection uri but we shouldn't match sequelize default host. if (this.sequelize.options.host === 'localhost') {
if (this.sequelize.options.host === 'localhost') delete this.sequelize.options.host; delete this.sequelize.options.host;
try {
if (sequelize.config.dialectModulePath) {
this.lib = require(sequelize.config.dialectModulePath).verbose();
} else {
this.lib = require('sqlite3').verbose();
}
} catch (err) {
if (err.code === 'MODULE_NOT_FOUND') {
throw new Error('Please install sqlite3 package manually');
}
throw err;
} }
this.connections = {};
this.lib = this._loadDialectModule('sqlite3').verbose();
this.refreshTypeParser(dataTypes); this.refreshTypeParser(dataTypes);
} }
......
...@@ -59,7 +59,8 @@ class Sequelize { ...@@ -59,7 +59,8 @@ class Sequelize {
* @param {string} [options.password=null] The password 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.database=null] The name of the database
* @param {string} [options.dialect] The dialect of the database you are connecting to. One of mysql, postgres, sqlite and mssql. * @param {string} [options.dialect] The dialect of the database you are connecting to. One of mysql, postgres, sqlite 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 {String} [options.dialectModule=null] If specified, use this dialect library. For example, if you want to use pg.js instead of pg when connecting to a pg database, you should specify 'require("pg.js")' here
* @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 '/path/to/pg.js' here
* @param {Object} [options.dialectOptions] An object of additional options, which are passed directly to the connection library * @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.storage] Only used by sqlite. Defaults to ':memory:'
* @param {string} [options.protocol='tcp'] The protocol of the relational database. * @param {string} [options.protocol='tcp'] The protocol of the relational database.
...@@ -140,6 +141,7 @@ class Sequelize { ...@@ -140,6 +141,7 @@ class Sequelize {
this.options = Object.assign({ this.options = Object.assign({
dialect: null, dialect: null,
dialectModule: null,
dialectModulePath: null, dialectModulePath: null,
host: 'localhost', host: 'localhost',
protocol: 'tcp', protocol: 'tcp',
...@@ -198,6 +200,7 @@ class Sequelize { ...@@ -198,6 +200,7 @@ class Sequelize {
native: this.options.native, native: this.options.native,
ssl: this.options.ssl, ssl: this.options.ssl,
replication: this.options.replication, replication: this.options.replication,
dialectModule: this.options.dialectModule,
dialectModulePath: this.options.dialectModulePath, dialectModulePath: this.options.dialectModulePath,
keepDefaultTimezone: this.options.keepDefaultTimezone, keepDefaultTimezone: this.options.keepDefaultTimezone,
dialectOptions: this.options.dialectOptions dialectOptions: this.options.dialectOptions
......
'use strict';
const chai = require('chai'),
expect = chai.expect,
path = require('path'),
Support = require(__dirname + '/support'),
Sequelize = Support.Sequelize,
dialect = Support.getTestDialect();
describe(Support.getTestDialectTeaser('Sequelize'), () => {
describe('dialectModule options', () => {
it('options.dialectModule', () => {
const dialectModule = {
verbose: () => { return dialectModule; }
};
const sequelize = new Sequelize('dbname', 'root', 'pass', {
port: 999,
dialect,
dialectModule
});
expect(sequelize.connectionManager.lib).to.equal(dialectModule);
});
it('options.dialectModulePath', () => {
let dialectPath = path.join(process.cwd(), 'node_modules');
switch (dialect) {
case 'postgres': dialectPath = path.join(dialectPath, 'pg'); break;
case 'mysql': dialectPath = path.join(dialectPath, 'mysql2'); break;
case 'mssql': dialectPath = path.join(dialectPath, 'tedious'); break;
case 'sqlite': dialectPath = path.join(dialectPath, 'sqlite3'); break;
default: throw Error('Unsupported dialect');
}
// this will throw if invalid path is passed
new Sequelize('dbname', 'root', 'pass', {
port: 999,
dialect,
dialectModulePath: dialectPath
});
});
it('options.dialectModulePath fails for invalid path', () => {
expect(() => {
new Sequelize('dbname', 'root', 'pass', {
port: 999,
dialect,
dialectModulePath: '/foo/bar/baz'
});
}).to.throw('Unable to find dialect at /foo/bar/baz');
});
});
});
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!