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

Commit a26193a0 by Simon Schick Committed by Sushant

chore: enforce stricter linting (#10532)

1 parent 786b19b9
......@@ -102,11 +102,22 @@
"one-var-declaration-per-line": "error",
"comma-dangle": "error",
"no-shadow": "warn",
"camelcase": "warn",
"camelcase": "error",
"prefer-template": "error",
"no-else-return": ["error", { "allowElseIf": false }],
"no-lonely-if": "error",
"no-this-before-super": "error"
"no-this-before-super": "error",
"no-throw-literal": "error",
"prefer-promise-reject-errors": "error",
"no-invalid-this": "error",
"radix": "error",
"no-with": "error",
"no-useless-concat": "error",
"no-useless-catch": "error",
"no-useless-call": "error",
"no-unused-expressions": "error",
"no-sequences": "error",
"no-self-compare": "error"
},
"parserOptions": {
"ecmaVersion": 6,
......@@ -133,5 +144,5 @@
// "Model": true,
// "QueryInterface": true,
// "QueryType": true
// }
// },
}
......@@ -61,7 +61,7 @@ function mixinMethods(association, obj, methods, aliases) {
const realMethod = aliases[method] || method;
obj[association.accessors[method]] = function() {
return association[realMethod].apply(association, [this, ...Array.from(arguments)]);
return association[realMethod](this, ...Array.from(arguments));
};
}
}
......
......@@ -87,18 +87,19 @@ const Mixin = {
// The logic for hasOne and belongsTo is exactly the same
function singleLinked(Type) {
return function(target, options = {}) {
if (!isModel(target, this.sequelize)) {
throw new Error(`${this.name}.${_.lowerFirst(Type.name)} called with something that's not a subclass of Sequelize.Model`);
// eslint-disable-next-line no-invalid-this
const source = this;
if (!isModel(target, source.sequelize)) {
throw new Error(`${source.name}.${_.lowerFirst(Type.name)} called with something that's not a subclass of Sequelize.Model`);
}
const source = this;
// Since this is a mixin, we'll need a unique letiable name for hooks (since Model will override our hooks option)
options.hooks = options.hooks === undefined ? false : Boolean(options.hooks);
options.useHooks = options.hooks;
if (options.useHooks) {
this.runHooks('beforeAssociate', { source, target, type: Type }, options);
source.runHooks('beforeAssociate', { source, target, type: Type }, options);
}
// the id is in the foreign table
const association = new Type(source, target, Object.assign(options, source.options));
......@@ -108,7 +109,7 @@ function singleLinked(Type) {
association.mixin(source.prototype);
if (options.useHooks) {
this.runHooks('afterAssociate', { source, target, type: Type, association }, options);
source.runHooks('afterAssociate', { source, target, type: Type, association }, options);
}
return association;
......
......@@ -951,7 +951,7 @@ class QueryGenerator {
if (field.type.stringify) {
// Users shouldn't have to worry about these args - just give them a function that takes a single arg
const simpleEscape = _.partialRight(SqlString.escape, this.options.timezone, this.dialect);
const simpleEscape = escVal => SqlString.escape(escVal, this.options.timezone, this.dialect);
value = field.type.stringify(value, { escape: simpleEscape, field, timezone: this.options.timezone, operation: options.operation });
......
......@@ -8,6 +8,20 @@ const Dot = require('dottie');
class AbstractQuery {
constructor(connection, sequelize, options) {
this.connection = connection;
this.instance = options.instance;
this.model = options.model;
this.sequelize = sequelize;
this.options = Object.assign({
logging: console.log,
plain: false,
raw: false
}, options || {});
this.checkLoggingOption();
}
/**
* rewrite query with parameters
*
......
......@@ -15,20 +15,8 @@ const ER_NO_REFERENCED_ROW = 1452;
class Query extends AbstractQuery {
constructor(connection, sequelize, options) {
super();
this.connection = connection;
this.instance = options.instance;
this.model = options.model;
this.sequelize = sequelize;
super(connection, sequelize, Object.assign({ showWarnings: false }, options));
this.uuid = uuidv4();
this.options = Object.assign({
logging: console.log,
plain: false,
raw: false,
showWarnings: false
}, options || {});
this.checkLoggingOption();
}
static formatBindParameters(sql, values, dialect) {
......
......@@ -19,46 +19,46 @@
@private
*/
const removeColumn = function(tableName, attributeName, options) {
const removeColumn = function(qi, tableName, attributeName, options) {
options = Object.assign({ raw: true }, options || {});
const findConstraintSql = this.QueryGenerator.getDefaultConstraintQuery(tableName, attributeName);
return this.sequelize.query(findConstraintSql, options)
const findConstraintSql = qi.QueryGenerator.getDefaultConstraintQuery(tableName, attributeName);
return qi.sequelize.query(findConstraintSql, options)
.then(([results]) => {
if (!results.length) {
// No default constraint found -- we can cleanly remove the column
return;
}
const dropConstraintSql = this.QueryGenerator.dropConstraintQuery(tableName, results[0].name);
return this.sequelize.query(dropConstraintSql, options);
const dropConstraintSql = qi.QueryGenerator.dropConstraintQuery(tableName, results[0].name);
return qi.sequelize.query(dropConstraintSql, options);
})
.then(() => {
const findForeignKeySql = this.QueryGenerator.getForeignKeyQuery(tableName, attributeName);
return this.sequelize.query(findForeignKeySql, options);
const findForeignKeySql = qi.QueryGenerator.getForeignKeyQuery(tableName, attributeName);
return qi.sequelize.query(findForeignKeySql, options);
})
.then(([results]) => {
if (!results.length) {
// No foreign key constraints found, so we can remove the column
return;
}
const dropForeignKeySql = this.QueryGenerator.dropForeignKeyQuery(tableName, results[0].constraint_name);
return this.sequelize.query(dropForeignKeySql, options);
const dropForeignKeySql = qi.QueryGenerator.dropForeignKeyQuery(tableName, results[0].constraint_name);
return qi.sequelize.query(dropForeignKeySql, options);
})
.then(() => {
//Check if the current column is a primaryKey
const primaryKeyConstraintSql = this.QueryGenerator.getPrimaryKeyConstraintQuery(tableName, attributeName);
return this.sequelize.query(primaryKeyConstraintSql, options);
const primaryKeyConstraintSql = qi.QueryGenerator.getPrimaryKeyConstraintQuery(tableName, attributeName);
return qi.sequelize.query(primaryKeyConstraintSql, options);
})
.then(([result]) => {
if (!result.length) {
return;
}
const dropConstraintSql = this.QueryGenerator.dropConstraintQuery(tableName, result[0].constraintName);
return this.sequelize.query(dropConstraintSql, options);
const dropConstraintSql = qi.QueryGenerator.dropConstraintQuery(tableName, result[0].constraintName);
return qi.sequelize.query(dropConstraintSql, options);
})
.then(() => {
const removeSql = this.QueryGenerator.removeColumnQuery(tableName, attributeName);
return this.sequelize.query(removeSql, options);
const removeSql = qi.QueryGenerator.removeColumnQuery(tableName, attributeName);
return qi.sequelize.query(removeSql, options);
});
};
......
......@@ -9,21 +9,6 @@ const _ = require('lodash');
const debug = logger.getLogger().debugContext('sql:mssql');
class Query extends AbstractQuery {
constructor(connection, sequelize, options) {
super();
this.connection = connection;
this.instance = options.instance;
this.model = options.model;
this.sequelize = sequelize;
this.options = Object.assign({
logging: console.log,
plain: false,
raw: false
}, options || {});
this.checkLoggingOption();
}
getInsertIdField() {
return 'id';
}
......
......@@ -20,13 +20,13 @@ const sequelizeErrors = require('../../errors');
@private
*/
function removeColumn(tableName, columnName, options) {
function removeColumn(qi, tableName, columnName, options) {
options = options || {};
return this.sequelize.query(
this.QueryGenerator.getForeignKeyQuery(tableName.tableName ? tableName : {
return qi.sequelize.query(
qi.QueryGenerator.getForeignKeyQuery(tableName.tableName ? tableName : {
tableName,
schema: this.sequelize.config.database
schema: qi.sequelize.config.database
}, columnName),
Object.assign({ raw: true }, options)
)
......@@ -36,26 +36,34 @@ function removeColumn(tableName, columnName, options) {
// No foreign key constraints found, so we can remove the column
return;
}
return Promise.map(results, constraint => this.sequelize.query(
this.QueryGenerator.dropForeignKeyQuery(tableName, constraint.constraint_name),
return Promise.map(results, constraint => qi.sequelize.query(
qi.QueryGenerator.dropForeignKeyQuery(tableName, constraint.constraint_name),
Object.assign({ raw: true }, options)
));
})
.then(() => this.sequelize.query(
this.QueryGenerator.removeColumnQuery(tableName, columnName),
.then(() => qi.sequelize.query(
qi.QueryGenerator.removeColumnQuery(tableName, columnName),
Object.assign({ raw: true }, options)
));
}
function removeConstraint(tableName, constraintName, options) {
const sql = this.QueryGenerator.showConstraintsQuery(
/**
* @param {QueryInterface} qi
* @param {string} tableName
* @param {string} constraintName
* @param {Object} options
*
* @private
*/
function removeConstraint(qi, tableName, constraintName, options) {
const sql = qi.QueryGenerator.showConstraintsQuery(
tableName.tableName ? tableName : {
tableName,
schema: this.sequelize.config.database
schema: qi.sequelize.config.database
}, constraintName);
return this.sequelize.query(sql, Object.assign({}, options,
{ type: this.sequelize.QueryTypes.SHOWCONSTRAINTS }))
return qi.sequelize.query(sql, Object.assign({}, options,
{ type: qi.sequelize.QueryTypes.SHOWCONSTRAINTS }))
.then(constraints => {
const constraint = constraints[0];
let query;
......@@ -69,12 +77,12 @@ function removeConstraint(tableName, constraintName, options) {
}
if (constraint.constraintType === 'FOREIGN KEY') {
query = this.QueryGenerator.dropForeignKeyQuery(tableName, constraintName);
query = qi.QueryGenerator.dropForeignKeyQuery(tableName, constraintName);
} else {
query = this.QueryGenerator.removeIndexQuery(constraint.tableName, constraint.constraintName);
query = qi.QueryGenerator.removeIndexQuery(constraint.tableName, constraint.constraintName);
}
return this.sequelize.query(query, options);
return qi.sequelize.query(query, options);
});
}
......
......@@ -10,20 +10,8 @@ const _ = require('lodash');
class Query extends AbstractQuery {
constructor(connection, sequelize, options) {
super();
this.connection = connection;
this.instance = options.instance;
this.model = options.model;
this.sequelize = sequelize;
super(connection, sequelize, Object.assign({ showWarnings: false }, options));
this.uuid = uuidv4();
this.options = Object.assign({
logging: console.log,
plain: false,
raw: false,
showWarnings: false
}, options || {});
this.checkLoggingOption();
}
static formatBindParameters(sql, values, dialect) {
......
......@@ -25,7 +25,7 @@ const _ = require('lodash');
* @returns {Promise}
* @private
*/
function ensureEnums(tableName, attributes, options, model) {
function ensureEnums(qi, tableName, attributes, options, model) {
const keys = Object.keys(attributes);
const keyLen = keys.length;
......@@ -41,8 +41,8 @@ function ensureEnums(tableName, attributes, options, model) {
type instanceof DataTypes.ENUM ||
type instanceof DataTypes.ARRAY && type.type instanceof DataTypes.ENUM //ARRAY sub type is ENUM
) {
sql = this.QueryGenerator.pgListEnums(tableName, attribute.field || keys[i], options);
promises.push(this.sequelize.query(
sql = qi.QueryGenerator.pgListEnums(tableName, attribute.field || keys[i], options);
promises.push(qi.sequelize.query(
sql,
Object.assign({}, options, { plain: true, raw: true, type: QueryTypes.SELECT })
));
......@@ -64,13 +64,13 @@ function ensureEnums(tableName, attributes, options, model) {
) {
// If the enum type doesn't exist then create it
if (!results[enumIdx]) {
sql = this.QueryGenerator.pgEnum(tableName, attribute.field || keys[i], enumType, options);
promises.push(this.sequelize.query(
sql = qi.QueryGenerator.pgEnum(tableName, attribute.field || keys[i], enumType, options);
promises.push(qi.sequelize.query(
sql,
Object.assign({}, options, { raw: true })
));
} else if (!!results[enumIdx] && !!model) {
const enumVals = this.QueryGenerator.fromArray(results[enumIdx].enum_value);
const enumVals = qi.QueryGenerator.fromArray(results[enumIdx].enum_value);
const vals = enumType.values;
vals.forEach((value, idx) => {
......@@ -87,7 +87,7 @@ function ensureEnums(tableName, attributes, options, model) {
valueOptions.after = vals[idx - 1];
}
valueOptions.supportsSearchPath = false;
promises.push(this.sequelize.query(this.QueryGenerator.pgEnumAdd(tableName, attribute.field || keys[i], value, valueOptions), valueOptions));
promises.push(qi.sequelize.query(qi.QueryGenerator.pgEnumAdd(tableName, attribute.field || keys[i], value, valueOptions), valueOptions));
}
});
enumIdx++;
......@@ -99,7 +99,7 @@ function ensureEnums(tableName, attributes, options, model) {
.tap(() => {
// If ENUM processed, then refresh OIDs
if (promises.length) {
return this.sequelize.dialect.connectionManager._refreshDynamicOIDs();
return qi.sequelize.dialect.connectionManager._refreshDynamicOIDs();
}
});
});
......
......@@ -9,21 +9,6 @@ const sequelizeErrors = require('../../errors');
const _ = require('lodash');
class Query extends AbstractQuery {
constructor(client, sequelize, options) {
super();
this.client = client;
this.sequelize = sequelize;
this.instance = options.instance;
this.model = options.model;
this.options = Object.assign({
logging: console.log,
plain: false,
raw: false
}, options || {});
this.checkLoggingOption();
}
/**
* rewrite query with parameters
* @private
......@@ -54,6 +39,7 @@ class Query extends AbstractQuery {
}
run(sql, parameters) {
const connection = this.connection;
this.sql = sql;
if (!_.isEmpty(this.options.searchPath)) {
......@@ -61,8 +47,8 @@ class Query extends AbstractQuery {
}
const query = parameters && parameters.length
? new Promise((resolve, reject) => this.client.query(this.sql, parameters, (error, result) => error ? reject(error) : resolve(result)))
: new Promise((resolve, reject) => this.client.query(this.sql, (error, result) => error ? reject(error) : resolve(result)));
? new Promise((resolve, reject) => connection.query(this.sql, parameters, (error, result) => error ? reject(error) : resolve(result)))
: new Promise((resolve, reject) => connection.query(this.sql, (error, result) => error ? reject(error) : resolve(result)));
//do we need benchmark for this query execution
const benchmark = this.sequelize.options.benchmark || this.options.benchmark;
......@@ -71,25 +57,25 @@ class Query extends AbstractQuery {
if (benchmark) {
queryBegin = Date.now();
} else {
this.sequelize.log(`Executing (${this.client.uuid || 'default'}): ${this.sql}`, this.options);
this.sequelize.log(`Executing (${connection.uuid || 'default'}): ${this.sql}`, this.options);
}
debug(`executing(${this.client.uuid || 'default'}) : ${this.sql}`);
debug(`executing(${connection.uuid || 'default'}) : ${this.sql}`);
return query.catch(err => {
// set the client so that it will be reaped if the connection resets while executing
if (err.code === 'ECONNRESET') {
this.client._invalid = true;
connection._invalid = true;
}
err.sql = sql;
throw this.formatError(err);
})
.then(queryResult => {
debug(`executed(${this.client.uuid || 'default'}) : ${this.sql}`);
debug(`executed(${connection.uuid || 'default'}) : ${this.sql}`);
if (benchmark) {
this.sequelize.log(`Executed (${this.client.uuid || 'default'}): ${this.sql}`, Date.now() - queryBegin, this.options);
this.sequelize.log(`Executed (${connection.uuid || 'default'}): ${this.sql}`, Date.now() - queryBegin, this.options);
}
return queryResult;
......
......@@ -18,6 +18,7 @@ const QueryTypes = require('../../query-types');
It will create a backup of the table, drop the table afterwards and create a
new table with the same name but without the obsolete column.
@param {QueryInterface} qi
@param {string} tableName The name of the table.
@param {string} attributeName The name of the attribute that we want to remove.
@param {Object} options
......@@ -26,16 +27,16 @@ const QueryTypes = require('../../query-types');
@since 1.6.0
@private
*/
function removeColumn(tableName, attributeName, options) {
function removeColumn(qi, tableName, attributeName, options) {
options = options || {};
return this.describeTable(tableName, options).then(fields => {
return qi.describeTable(tableName, options).then(fields => {
delete fields[attributeName];
const sql = this.QueryGenerator.removeColumnQuery(tableName, fields);
const sql = qi.QueryGenerator.removeColumnQuery(tableName, fields);
const subQueries = sql.split(';').filter(q => q !== '');
return Promise.each(subQueries, subQuery => this.sequelize.query(`${subQuery};`, Object.assign({ raw: true }, options)));
return Promise.each(subQueries, subQuery => qi.sequelize.query(`${subQuery};`, Object.assign({ raw: true }, options)));
});
}
exports.removeColumn = removeColumn;
......@@ -45,6 +46,7 @@ exports.removeColumn = removeColumn;
It will create a backup of the table, drop the table afterwards and create a
new table with the same name but with a modified version of the respective column.
@param {QueryInterface} qi
@param {string} tableName The name of the table.
@param {Object} attributes An object with the attribute's name as key and its options as value object.
@param {Object} options
......@@ -53,17 +55,17 @@ exports.removeColumn = removeColumn;
@since 1.6.0
@private
*/
function changeColumn(tableName, attributes, options) {
function changeColumn(qi, tableName, attributes, options) {
const attributeName = Object.keys(attributes)[0];
options = options || {};
return this.describeTable(tableName, options).then(fields => {
return qi.describeTable(tableName, options).then(fields => {
fields[attributeName] = attributes[attributeName];
const sql = this.QueryGenerator.removeColumnQuery(tableName, fields);
const sql = qi.QueryGenerator.removeColumnQuery(tableName, fields);
const subQueries = sql.split(';').filter(q => q !== '');
return Promise.each(subQueries, subQuery => this.sequelize.query(`${subQuery};`, Object.assign({ raw: true }, options)));
return Promise.each(subQueries, subQuery => qi.sequelize.query(`${subQuery};`, Object.assign({ raw: true }, options)));
});
}
exports.changeColumn = changeColumn;
......@@ -73,6 +75,7 @@ exports.changeColumn = changeColumn;
It will create a backup of the table, drop the table afterwards and create a
new table with the same name but with a renamed version of the respective column.
@param {QueryInterface} qi
@param {string} tableName The name of the table.
@param {string} attrNameBefore The name of the attribute before it was renamed.
@param {string} attrNameAfter The name of the attribute after it was renamed.
......@@ -82,36 +85,40 @@ exports.changeColumn = changeColumn;
@since 1.6.0
@private
*/
function renameColumn(tableName, attrNameBefore, attrNameAfter, options) {
function renameColumn(qi, tableName, attrNameBefore, attrNameAfter, options) {
options = options || {};
return this.describeTable(tableName, options).then(fields => {
return qi.describeTable(tableName, options).then(fields => {
fields[attrNameAfter] = _.clone(fields[attrNameBefore]);
delete fields[attrNameBefore];
const sql = this.QueryGenerator.renameColumnQuery(tableName, attrNameBefore, attrNameAfter, fields);
const sql = qi.QueryGenerator.renameColumnQuery(tableName, attrNameBefore, attrNameAfter, fields);
const subQueries = sql.split(';').filter(q => q !== '');
return Promise.each(subQueries, subQuery => this.sequelize.query(`${subQuery};`, Object.assign({ raw: true }, options)));
return Promise.each(subQueries, subQuery => qi.sequelize.query(`${subQuery};`, Object.assign({ raw: true }, options)));
});
}
exports.renameColumn = renameColumn;
function removeConstraint(tableName, constraintName, options) {
/**
* @param {QueryInterface} qi
* @private
*/
function removeConstraint(qi, tableName, constraintName, options) {
let createTableSql;
return this.showConstraint(tableName, constraintName)
return qi.showConstraint(tableName, constraintName)
.then(constraints => {
const constraint = constraints[0];
if (constraint) {
createTableSql = constraint.sql;
constraint.constraintName = this.QueryGenerator.quoteIdentifier(constraint.constraintName);
constraint.constraintName = qi.QueryGenerator.quoteIdentifier(constraint.constraintName);
let constraintSnippet = `, CONSTRAINT ${constraint.constraintName} ${constraint.constraintType} ${constraint.constraintCondition}`;
if (constraint.constraintType === 'FOREIGN KEY') {
const referenceTableName = this.QueryGenerator.quoteTable(constraint.referenceTableName);
constraint.referenceTableKeys = constraint.referenceTableKeys.map(columnName => this.QueryGenerator.quoteIdentifier(columnName));
const referenceTableName = qi.QueryGenerator.quoteTable(constraint.referenceTableName);
constraint.referenceTableKeys = constraint.referenceTableKeys.map(columnName => qi.QueryGenerator.quoteIdentifier(columnName));
const referenceTableKeys = constraint.referenceTableKeys.join(', ');
constraintSnippet += ` REFERENCES ${referenceTableName} (${referenceTableKeys})`;
constraintSnippet += ` ON UPDATE ${constraint.updateAction}`;
......@@ -121,7 +128,7 @@ function removeConstraint(tableName, constraintName, options) {
createTableSql = createTableSql.replace(constraintSnippet, '');
createTableSql += ';';
return this.describeTable(tableName, options);
return qi.describeTable(tableName, options);
}
throw new sequelizeErrors.UnknownConstraintError({
message: `Constraint ${constraintName} on table ${tableName} does not exist`,
......@@ -130,20 +137,24 @@ function removeConstraint(tableName, constraintName, options) {
});
})
.then(fields => {
const sql = this.QueryGenerator._alterConstraintQuery(tableName, fields, createTableSql);
const sql = qi.QueryGenerator._alterConstraintQuery(tableName, fields, createTableSql);
const subQueries = sql.split(';').filter(q => q !== '');
return Promise.each(subQueries, subQuery => this.sequelize.query(`${subQuery};`, Object.assign({ raw: true }, options)));
return Promise.each(subQueries, subQuery => qi.sequelize.query(`${subQuery};`, Object.assign({ raw: true }, options)));
});
}
exports.removeConstraint = removeConstraint;
function addConstraint(tableName, options) {
const constraintSnippet = this.QueryGenerator.getConstraintSnippet(tableName, options);
const describeCreateTableSql = this.QueryGenerator.describeCreateTableQuery(tableName);
/**
* @param {QueryInterface} qi
* @private
*/
function addConstraint(qi, tableName, options) {
const constraintSnippet = qi.QueryGenerator.getConstraintSnippet(tableName, options);
const describeCreateTableSql = qi.QueryGenerator.describeCreateTableQuery(tableName);
let createTableSql;
return this.sequelize.query(describeCreateTableSql, Object.assign({}, options, { type: QueryTypes.SELECT, raw: true }))
return qi.sequelize.query(describeCreateTableSql, Object.assign({}, options, { type: QueryTypes.SELECT, raw: true }))
.then(constraints => {
const sql = constraints[0].sql;
const index = sql.length - 1;
......@@ -151,29 +162,29 @@ function addConstraint(tableName, options) {
//http://stackoverflow.com/questions/1431094
createTableSql = `${sql.substr(0, index)}, ${constraintSnippet})${sql.substr(index + 1)};`;
return this.describeTable(tableName, options);
return qi.describeTable(tableName, options);
})
.then(fields => {
const sql = this.QueryGenerator._alterConstraintQuery(tableName, fields, createTableSql);
const sql = qi.QueryGenerator._alterConstraintQuery(tableName, fields, createTableSql);
const subQueries = sql.split(';').filter(q => q !== '');
return Promise.each(subQueries, subQuery => this.sequelize.query(`${subQuery};`, Object.assign({ raw: true }, options)));
return Promise.each(subQueries, subQuery => qi.sequelize.query(`${subQuery};`, Object.assign({ raw: true }, options)));
});
}
exports.addConstraint = addConstraint;
/**
*
* @param {QueryInterface} qi
* @param {string} tableName
* @param {Object} options Query Options
*
* @private
* @returns {Promise}
*/
function getForeignKeyReferencesForTable(tableName, options) {
const database = this.sequelize.config.database;
const query = this.QueryGenerator.getForeignKeysQuery(tableName, database);
return this.sequelize.query(query, options)
function getForeignKeyReferencesForTable(qi, tableName, options) {
const database = qi.sequelize.config.database;
const query = qi.QueryGenerator.getForeignKeysQuery(tableName, database);
return qi.sequelize.query(query, options)
.then(result => {
return result.map(row => ({
tableName,
......
......@@ -11,22 +11,6 @@ const sequelizeErrors = require('../../errors');
const parserStore = require('../parserStore')('sqlite');
class Query extends AbstractQuery {
constructor(database, sequelize, options) {
super();
this.database = database;
this.sequelize = sequelize;
this.instance = options.instance;
this.model = options.model;
this.options = Object.assign({
logging: console.log,
plain: false,
raw: false
}, options);
this.checkLoggingOption();
}
getInsertIdField() {
return 'lastID';
}
......@@ -78,10 +62,10 @@ class Query extends AbstractQuery {
}
_handleQueryResponse(metaData, columnTypes, benchmark, queryBegin, err, results) {
debug(`executed(${this.database.uuid || 'default'}) : ${this.sql}`);
debug(`executed(${this.connection.uuid || 'default'}) : ${this.sql}`);
if (benchmark) {
this.sequelize.log(`Executed (${this.database.uuid || 'default'}): ${this.sql}`, Date.now() - queryBegin, this.options);
this.sequelize.log(`Executed (${this.connection.uuid || 'default'}): ${this.sql}`, Date.now() - queryBegin, this.options);
}
if (err) {
......@@ -234,6 +218,7 @@ class Query extends AbstractQuery {
}
run(sql, parameters) {
const conn = this.connection;
this.sql = sql;
const method = this.getDatabaseMethod();
if (method === 'exec') {
......@@ -249,14 +234,14 @@ class Query extends AbstractQuery {
if (benchmark) {
queryBegin = Date.now();
} else {
this.sequelize.log(`Executing (${this.database.uuid || 'default'}): ${this.sql}`, this.options);
this.sequelize.log(`Executing (${conn.uuid || 'default'}): ${this.sql}`, this.options);
}
debug(`executing(${this.database.uuid || 'default'}) : ${this.sql}`);
debug(`executing(${conn.uuid || 'default'}) : ${this.sql}`);
return new Promise(resolve => {
const columnTypes = {};
this.database.serialize(() => {
conn.serialize(() => {
const executeSql = () => {
if (this.sql.startsWith('-- ')) {
return resolve();
......@@ -266,6 +251,8 @@ class Query extends AbstractQuery {
// cannot use arrow function here because the function is bound to the statement
function afterExecute(executionError, results) {
try {
// `this` is passed from sqlite, we have no control over this.
// eslint-disable-next-line no-invalid-this
resolve(query._handleQueryResponse(this, columnTypes, benchmark, queryBegin, executionError, results));
return;
} catch (error) {
......@@ -275,10 +262,10 @@ class Query extends AbstractQuery {
if (method === 'exec') {
// exec does not support bind parameter
this.database[method](this.sql, afterExecute);
conn[method](this.sql, afterExecute);
} else {
if (!parameters) parameters = [];
this.database[method](this.sql, parameters, afterExecute);
conn[method](this.sql, parameters, afterExecute);
}
}));
return null;
......@@ -303,7 +290,7 @@ class Query extends AbstractQuery {
tableName = tableName.replace(/`/g, '');
columnTypes[tableName] = {};
this.database.all(`PRAGMA table_info(\`${tableName}\`)`, (err, results) => {
conn.all(`PRAGMA table_info(\`${tableName}\`)`, (err, results) => {
if (!err) {
for (const result of results) {
columnTypes[tableName][result.name] = result.type;
......
......@@ -63,8 +63,8 @@ const getProxiedHooks = hookType =>
: [hookType]
;
function getHooks(hookType) {
return (this.options.hooks || {})[hookType] || [];
function getHooks(hooked, hookType) {
return (hooked.options.hooks || {})[hookType] || [];
};
const Hooks = {
......@@ -92,10 +92,10 @@ const Hooks = {
if (typeof hooks === 'string') {
hookType = hooks;
hooks = getHooks.call(this, hookType);
hooks = getHooks(this, hookType);
if (this.sequelize) {
hooks = hooks.concat(getHooks.call(this.sequelize, hookType));
hooks = hooks.concat(getHooks(this.sequelize, hookType));
}
}
......@@ -147,9 +147,10 @@ const Hooks = {
// check for proxies, add them too
hookType = getProxiedHooks(hookType);
_.each(hookType, type => {
this.options.hooks[type] = getHooks.call(this, type);
this.options.hooks[type].push(name ? { name, fn } : fn);
hookType.forEach(type => {
const hooks = getHooks(this, type);
hooks.push(name ? { name, fn } : fn);
this.options.hooks[type] = hooks;
});
return this;
......
......@@ -139,7 +139,7 @@ class InstanceValidator {
}
if (this.modelInstance.validators.hasOwnProperty(field)) {
validators.push(this._singleAttrValidate.call(this, value, field, rawAttribute.allowNull).reflect());
validators.push(this._singleAttrValidate(value, field, rawAttribute.allowNull).reflect());
}
});
......@@ -293,7 +293,7 @@ class InstanceValidator {
const validatorArgs = this._extractValidatorArgs(test, validatorType, field);
if (!validator[validatorType].apply(validator, [valueString, ...validatorArgs])) {
if (!validator[validatorType](valueString, ...validatorArgs)) {
throw Object.assign(new Error(test.msg || `Validation ${validatorType} on ${field} failed`), { validatorName: validatorType, validatorArgs });
}
});
......
......@@ -741,7 +741,7 @@ class Model {
includes.splice(index, 1);
index--;
this._expandIncludeAllElement.call(this, includes, include);
this._expandIncludeAllElement(includes, include);
}
}
......@@ -1149,7 +1149,7 @@ class Model {
}
if (definition.hasOwnProperty('defaultValue')) {
this._defaultValues[name] = _.partial(Utils.toDefaultValue, definition.defaultValue, this.sequelize.options.dialect);
this._defaultValues[name] = () => Utils.toDefaultValue(definition.defaultValue, this.sequelize.options.dialect);
}
if (definition.hasOwnProperty('unique') && definition.unique) {
......@@ -2577,11 +2577,15 @@ class Model {
// set createdAt/updatedAt attributes
if (createdAtAttr && !values[createdAtAttr]) {
values[createdAtAttr] = now;
!options.fields.includes(createdAtAttr) && options.fields.push(createdAtAttr);
if (!options.fields.includes(createdAtAttr)) {
options.fields.push(createdAtAttr);
}
}
if (updatedAtAttr && !values[updatedAtAttr]) {
values[updatedAtAttr] = now;
!options.fields.includes(updatedAtAttr) && options.fields.push(updatedAtAttr);
if (!options.fields.includes(updatedAtAttr)) {
options.fields.push(updatedAtAttr);
}
}
instance.dataValues = Utils.mapValueFieldNames(values, options.fields, this);
......@@ -3143,7 +3147,7 @@ class Model {
if (typeof fields === 'string') {
values[fields] = options.by;
} else if (Array.isArray(fields)) {
_.each(fields, field => {
fields.forEach(field => {
values[field] = options.by;
});
} else { // Assume fields is key-value pairs
......
......@@ -215,7 +215,7 @@ class QueryInterface {
// Postgres requires special SQL commands for ENUM/ENUM[]
if (this.sequelize.options.dialect === 'postgres') {
promise = PostgresQueryInterface.ensureEnums.call(this, tableName, attributes, options, model);
promise = PostgresQueryInterface.ensureEnums(this, tableName, attributes, options, model);
} else {
promise = Promise.resolve();
}
......@@ -528,14 +528,14 @@ class QueryInterface {
switch (this.sequelize.options.dialect) {
case 'sqlite':
// sqlite needs some special treatment as it cannot drop a column
return SQLiteQueryInterface.removeColumn.call(this, tableName, attributeName, options);
return SQLiteQueryInterface.removeColumn(this, tableName, attributeName, options);
case 'mssql':
// mssql needs special treatment as it cannot drop a column with a default or foreign key constraint
return MSSSQLQueryInterface.removeColumn.call(this, tableName, attributeName, options);
return MSSSQLQueryInterface.removeColumn(this, tableName, attributeName, options);
case 'mysql':
case 'mariadb':
// mysql/mariadb need special treatment as it cannot drop a column with a foreign key constraint
return MySQLQueryInterface.removeColumn.call(this, tableName, attributeName, options);
return MySQLQueryInterface.removeColumn(this, tableName, attributeName, options);
default:
return this.sequelize.query(this.QueryGenerator.removeColumnQuery(tableName, attributeName), options);
}
......@@ -565,7 +565,7 @@ class QueryInterface {
if (this.sequelize.options.dialect === 'sqlite') {
// sqlite needs some special treatment as it cannot change a column
return SQLiteQueryInterface.changeColumn.call(this, tableName, attributes, options);
return SQLiteQueryInterface.changeColumn(this, tableName, attributes, options);
}
const query = this.QueryGenerator.attributesToSQL(attributes);
const sql = this.QueryGenerator.changeColumnQuery(tableName, query);
......@@ -608,7 +608,7 @@ class QueryInterface {
if (this.sequelize.options.dialect === 'sqlite') {
// sqlite needs some special treatment as it cannot rename a column
return SQLiteQueryInterface.renameColumn.call(this, tableName, attrNameBefore, attrNameAfter, options);
return SQLiteQueryInterface.renameColumn(this, tableName, attrNameBefore, attrNameAfter, options);
}
const sql = this.QueryGenerator.renameColumnQuery(
tableName,
......@@ -718,7 +718,7 @@ class QueryInterface {
switch (this.sequelize.options.dialect) {
case 'sqlite':
// sqlite needs some special treatment.
return SQLiteQueryInterface.getForeignKeyReferencesForTable.call(this, tableName, queryOptions);
return SQLiteQueryInterface.getForeignKeyReferencesForTable(this, tableName, queryOptions);
case 'postgres':
{
// postgres needs some special treatment as those field names returned are all lowercase
......@@ -834,7 +834,7 @@ class QueryInterface {
options.fields = attributes;
if (this.sequelize.dialect.name === 'sqlite') {
return SQLiteQueryInterface.addConstraint.call(this, tableName, options, rawTablename);
return SQLiteQueryInterface.addConstraint(this, tableName, options, rawTablename);
}
const sql = this.QueryGenerator.addConstraintQuery(tableName, options, rawTablename);
return this.sequelize.query(sql, options);
......@@ -860,9 +860,9 @@ class QueryInterface {
case 'mysql':
case 'mariadb':
//does not support DROP CONSTRAINT. Instead DROP PRIMARY, FOREIGN KEY, INDEX should be used
return MySQLQueryInterface.removeConstraint.call(this, tableName, constraintName, options);
return MySQLQueryInterface.removeConstraint(this, tableName, constraintName, options);
case 'sqlite':
return SQLiteQueryInterface.removeConstraint.call(this, tableName, constraintName, options);
return SQLiteQueryInterface.removeConstraint(this, tableName, constraintName, options);
default:
const sql = this.QueryGenerator.removeConstraintQuery(tableName, constraintName);
return this.sequelize.query(sql, options);
......
......@@ -2,7 +2,6 @@
const dataTypes = require('./data-types');
const util = require('util');
const _ = require('lodash');
function arrayToList(array, timeZone, dialect, format) {
return array.reduce((sql, val, i) => {
......@@ -55,7 +54,7 @@ function escape(val, timeZone, dialect, format) {
}
if (Array.isArray(val)) {
const partialEscape = _.partial(escape, _, timeZone, dialect, format);
const partialEscape = escVal => escape(escVal, timeZone, dialect, format);
if (dialect === 'postgres' && !format) {
return dataTypes.ARRAY.prototype.stringify(val, { escape: partialEscape });
}
......
......@@ -28,7 +28,9 @@ class Logger {
}
debug(message) {
this.config.debug && this.debug(message);
if (this.config.debug) {
this.debug(message);
}
}
warn(message) {
......
{
"rules": {
"no-invalid-this": 0,
"no-unused-expressions": 0,
"camelcase": 0
}
}
'use strict';
exports.default = function(sequelize, DataTypes) {
return sequelize.define(`Project${parseInt(Math.random() * 9999999999999999)}`, {
return sequelize.define(`Project${parseInt(Math.random() * 9999999999999999, 10)}`, {
name: DataTypes.STRING
});
};
'use strict';
module.exports = function(sequelize, DataTypes) {
return sequelize.define(`Project${parseInt(Math.random() * 9999999999999999)}`, {
return sequelize.define(`Project${parseInt(Math.random() * 9999999999999999, 10)}`, {
name: DataTypes.STRING
});
};
......@@ -9,8 +9,9 @@ const chai = require('chai'),
fs = require('fs'),
path = require('path');
let sqlite3;
if (dialect === 'sqlite') {
var sqlite3 = require('sqlite3'); // eslint-disable-line
sqlite3 = require('sqlite3'); // eslint-disable-line
}
describe(Support.getTestDialectTeaser('Configuration'), () => {
......
......@@ -103,7 +103,7 @@ describe('model', () => {
});
})
.then(user => {
expect(parseInt(user.getDataValue('firstEmergencyNumber'))).to.equal(42);
expect(parseInt(user.getDataValue('firstEmergencyNumber'), 10)).to.equal(42);
});
});
......@@ -119,7 +119,7 @@ describe('model', () => {
});
})
.then(user => {
expect(parseInt(user.getDataValue('katesNumber'))).to.equal(1337);
expect(parseInt(user.getDataValue('katesNumber'), 10)).to.equal(1337);
});
});
......@@ -141,7 +141,7 @@ describe('model', () => {
attributes: [[Sequelize.json('emergency_contact.kate.phones[1]'), 'katesFirstPhone']]
});
}).then(user => {
expect(parseInt(user.getDataValue('katesFirstPhone'))).to.equal(42);
expect(parseInt(user.getDataValue('katesFirstPhone'), 10)).to.equal(42);
});
});
......
......@@ -87,7 +87,8 @@ describe(Support.getTestDialectTeaser('Model'), () => {
})
)
.then(result => {
expect(parseInt(result[0].count)).to.be.eql(2);
// TODO: `parseInt` should not be needed, see #10533
expect(parseInt(result[0].count, 10)).to.be.eql(2);
return this.User.count({
where: { username: 'fire' }
});
......@@ -119,14 +120,14 @@ describe(Support.getTestDialectTeaser('Model'), () => {
})
)
.then(count => {
expect(parseInt(count)).to.be.eql(3);
expect(count).to.be.eql(3);
return this.User.count({
col: 'age',
distinct: true
});
})
.then(count => {
expect(parseInt(count)).to.be.eql(2);
expect(count).to.be.eql(2);
});
});
......@@ -139,11 +140,11 @@ describe(Support.getTestDialectTeaser('Model'), () => {
}
};
return this.User.count(queryObject).then(count => {
expect(parseInt(count)).to.be.eql(1);
expect(count).to.be.eql(1);
queryObject.where['$Projects.name$'] = 'project2';
return this.User.count(queryObject);
}).then(count => {
expect(parseInt(count)).to.be.eql(0);
expect(count).to.be.eql(0);
});
});
......@@ -161,13 +162,13 @@ describe(Support.getTestDialectTeaser('Model'), () => {
include: [this.Project]
})
).then(count => {
expect(parseInt(count)).to.be.eql(3);
expect(count).to.be.eql(3);
return this.User.count({
col: 'age',
distinct: true,
include: [this.Project]
});
}).then(count => expect(parseInt(count)).to.be.eql(2));
}).then(count => expect(count).to.be.eql(2));
});
});
......
......@@ -1213,7 +1213,7 @@ describe(Support.getTestDialectTeaser('Model'), () => {
expect(continents[0].countries[0].people[0].name).to.equal(params[3]);
});
});
}),
});
it('sorts by 2nd degree association with alias', function() {
return Sequelize.Promise.map([['ASC', 'Europe', 'France', 'Fred'], ['DESC', 'Europe', 'England', 'Kim']], params => {
......@@ -1253,7 +1253,7 @@ describe(Support.getTestDialectTeaser('Model'), () => {
});
});
});
}),
});
describe('ManyToMany', () => {
beforeEach(function() {
......
......@@ -50,8 +50,8 @@ describe(Support.getTestDialectTeaser('Model'), () => {
]
});
}).then(posts => {
expect(parseInt(posts[0].get('comment_count'))).to.be.equal(3);
expect(parseInt(posts[1].get('comment_count'))).to.be.equal(2);
expect(parseInt(posts[0].get('comment_count'), 10)).to.be.equal(3);
expect(parseInt(posts[1].get('comment_count'), 10)).to.be.equal(2);
});
});
......@@ -96,8 +96,8 @@ describe(Support.getTestDialectTeaser('Model'), () => {
}).then(posts => {
expect(posts[0].get().hasOwnProperty('id')).to.equal(false);
expect(posts[1].get().hasOwnProperty('id')).to.equal(false);
expect(parseInt(posts[0].get('comment_count'))).to.be.equal(3);
expect(parseInt(posts[1].get('comment_count'))).to.be.equal(2);
expect(parseInt(posts[0].get('comment_count'), 10)).to.be.equal(3);
expect(parseInt(posts[1].get('comment_count'), 10)).to.be.equal(2);
});
});
});
......
......@@ -1187,7 +1187,7 @@ describe(Support.getTestDialectTeaser('Sequelize'), () => {
it('imports a dao definition from a function', function() {
const Project = this.sequelize.import('Project', (sequelize, DataTypes) => {
return sequelize.define(`Project${parseInt(Math.random() * 9999999999999999)}`, {
return sequelize.define(`Project${parseInt(Math.random() * 9999999999999999, 10)}`, {
name: DataTypes.STRING
});
});
......
......@@ -180,9 +180,10 @@ describe(Support.getTestDialectTeaser('Utils'), () => {
}, type)), 'count-engines-wings']
]
}).then(([airplane]) => {
expect(parseInt(airplane.get('count'))).to.equal(3);
expect(parseInt(airplane.get('count-engines'))).to.equal(1);
expect(parseInt(airplane.get('count-engines-wings'))).to.equal(2);
// TODO: `parseInt` should not be needed, see #10533
expect(parseInt(airplane.get('count'), 10)).to.equal(3);
expect(parseInt(airplane.get('count-engines'), 10)).to.equal(1);
expect(parseInt(airplane.get('count-engines-wings'), 10)).to.equal(2);
});
});
}
......@@ -205,9 +206,10 @@ describe(Support.getTestDialectTeaser('Utils'), () => {
}), 'count-engines-wings']
]
}).then(([airplane]) => {
expect(parseInt(airplane.get('count'))).to.equal(3);
expect(parseInt(airplane.get('count-engines'))).to.equal(1);
expect(parseInt(airplane.get('count-engines-wings'))).to.equal(2);
// TODO: `parseInt` should not be needed, see #10533
expect(airplane.get('count')).to.equal(3);
expect(parseInt(airplane.get('count-engines'), 10)).to.equal(1);
expect(parseInt(airplane.get('count-engines-wings'), 10)).to.equal(2);
});
});
}
......
......@@ -102,7 +102,7 @@ describe(Support.getTestDialectTeaser('InstanceValidator'), () => {
it('should run beforeValidate hook but not afterValidate hook when _validate is unsuccessful', function() {
const failingInstanceValidator = new InstanceValidator(this.User.build());
sinon.stub(failingInstanceValidator, '_validate').callsFake(() => {
return Promise.reject();
return Promise.reject(new Error());
});
const beforeValidate = sinon.spy();
const afterValidate = sinon.spy();
......@@ -127,7 +127,7 @@ describe(Support.getTestDialectTeaser('InstanceValidator'), () => {
it('should call validationFailed hook when validation fails', function() {
const failingInstanceValidator = new InstanceValidator(this.User.build());
sinon.stub(failingInstanceValidator, '_validate').callsFake(() => {
return Promise.reject();
return Promise.reject(new Error());
});
const validationFailedHook = sinon.spy();
this.User.validationFailed(validationFailedHook);
......
......@@ -1516,7 +1516,7 @@ export abstract class Model<T = any, T2 = any> extends Hooks {
/**
* Apply a scope created in `define` to the model. First let's look at how to create scopes:
* ```js
* var Model = sequelize.define('model', attributes, {
* const Model = sequelize.define('model', attributes, {
* defaultScope: {
* where: {
* username: 'dan'
......@@ -2266,7 +2266,7 @@ export abstract class Model<T = any, T2 = any> extends Hooks {
* ways. Consider users and projects from before with a join table that stores whether the project has been
* started yet:
* ```js
* var UserProjects = sequelize.define('userprojects', {
* const UserProjects = sequelize.define('userprojects', {
* started: Sequelize.BOOLEAN
* })
* User.hasMany(Project, { through: UserProjects })
......@@ -2292,7 +2292,7 @@ export abstract class Model<T = any, T2 = any> extends Hooks {
* available as an object with the name of the through model.
* ```js
* user.getProjects().then(projects => {
* var p1 = projects[0]
* const p1 = projects[0]
* p1.userprojects.started // Is this project started yet?
* })
* ```
......@@ -2316,7 +2316,7 @@ export abstract class Model<T = any, T2 = any> extends Hooks {
* associations in two ways. Consider users and projects from before with a join table that stores whether
* the project has been started yet:
* ```js
* var UserProjects = sequelize.define('userprojects', {
* const UserProjects = sequelize.define('userprojects', {
* started: Sequelize.BOOLEAN
* })
* User.belongsToMany(Project, { through: UserProjects })
......
......@@ -324,7 +324,7 @@ export interface QueryOptionsTransactionRequired {}
* import sequelize:
*
* ```js
* var Sequelize = require('sequelize');
* const Sequelize = require('sequelize');
* ```
*
* In addition to sequelize, the connection library for the dialect you want to use
......@@ -676,19 +676,19 @@ export class Sequelize extends Hooks {
*
* ```javascript
* // without password and options
* var sequelize = new Sequelize('database', 'username')
* const sequelize = new Sequelize('database', 'username')
*
* // without options
* var sequelize = new Sequelize('database', 'username', 'password')
* const sequelize = new Sequelize('database', 'username', 'password')
*
* // without password / with blank password
* var sequelize = new Sequelize('database', 'username', null, {})
* const sequelize = new Sequelize('database', 'username', null, {})
*
* // with password and options
* var sequelize = new Sequelize('my_database', 'john', 'doe', {})
* const sequelize = new Sequelize('my_database', 'john', 'doe', {})
*
* // with uri (see below)
* var sequelize = new Sequelize('mysql://localhost:3306/database', {})
* const sequelize = new Sequelize('mysql://localhost:3306/database', {})
* ```
*
* @param database The name of the database
......@@ -1212,9 +1212,9 @@ export class Sequelize extends Hooks {
* project, create a namespace and set it on the sequelize constructor:
*
* ```js
* var cls = require('continuation-local-storage'),
* const cls = require('continuation-local-storage'),
* ns = cls.createNamespace('....');
* var Sequelize = require('sequelize');
* const Sequelize = require('sequelize');
* Sequelize.cls = ns;
* ```
* Note, that CLS is enabled for all sequelize instances, and all instances will share the same namespace
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!