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

Commit 2924eba1 by Andy Edwards Committed by GitHub

refactor(sequelize): asyncify methods (#12125)

1 parent f1d08764
...@@ -538,7 +538,7 @@ class Sequelize { ...@@ -538,7 +538,7 @@ class Sequelize {
* @see {@link Model.build} for more information about instance option. * @see {@link Model.build} for more information about instance option.
*/ */
query(sql, options) { async query(sql, options) {
options = Object.assign({}, this.options.query, options); options = Object.assign({}, this.options.query, options);
if (options.instance && !options.model) { if (options.instance && !options.model) {
...@@ -583,80 +583,77 @@ class Sequelize { ...@@ -583,80 +583,77 @@ class Sequelize {
options.searchPath = 'DEFAULT'; options.searchPath = 'DEFAULT';
} }
return Promise.resolve().then(() => { if (typeof sql === 'object') {
if (typeof sql === 'object') { if (sql.values !== undefined) {
if (sql.values !== undefined) { if (options.replacements !== undefined) {
if (options.replacements !== undefined) { throw new Error('Both `sql.values` and `options.replacements` cannot be set at the same time');
throw new Error('Both `sql.values` and `options.replacements` cannot be set at the same time');
}
options.replacements = sql.values;
} }
options.replacements = sql.values;
}
if (sql.bind !== undefined) { if (sql.bind !== undefined) {
if (options.bind !== undefined) { if (options.bind !== undefined) {
throw new Error('Both `sql.bind` and `options.bind` cannot be set at the same time'); throw new Error('Both `sql.bind` and `options.bind` cannot be set at the same time');
}
options.bind = sql.bind;
} }
options.bind = sql.bind;
}
if (sql.query !== undefined) { if (sql.query !== undefined) {
sql = sql.query; sql = sql.query;
}
} }
}
sql = sql.trim(); sql = sql.trim();
if (options.replacements && options.bind) { if (options.replacements && options.bind) {
throw new Error('Both `replacements` and `bind` cannot be set at the same time'); 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);
} else {
sql = Utils.formatNamedParameters(sql, options.replacements, this.options.dialect);
} }
}
if (options.replacements) { let bindParameters;
if (Array.isArray(options.replacements)) {
sql = Utils.format([sql].concat(options.replacements), this.options.dialect); if (options.bind) {
} else { [sql, bindParameters] = this.dialect.Query.formatBindParameters(sql, options.bind, this.options.dialect);
sql = Utils.formatNamedParameters(sql, options.replacements, this.options.dialect); }
}
const checkTransaction = () => {
if (options.transaction && options.transaction.finished && !options.completesTransaction) {
const error = new Error(`${options.transaction.finished} has been called on this transaction(${options.transaction.id}), you can no longer use it. (The rejected query is attached as the 'sql' property of this error)`);
error.sql = sql;
throw error;
} }
};
let bindParameters; const retryOptions = Object.assign({}, this.options.retry, options.retry || {});
if (options.bind) { return retry(async () => {
[sql, bindParameters] = this.dialect.Query.formatBindParameters(sql, options.bind, this.options.dialect); if (options.transaction === undefined && Sequelize._cls) {
options.transaction = Sequelize._cls.get('transaction');
} }
const checkTransaction = () => { checkTransaction();
if (options.transaction && options.transaction.finished && !options.completesTransaction) {
const error = new Error(`${options.transaction.finished} has been called on this transaction(${options.transaction.id}), you can no longer use it. (The rejected query is attached as the 'sql' property of this error)`);
error.sql = sql;
throw error;
}
};
const retryOptions = Object.assign({}, this.options.retry, options.retry || {}); const connection = await (options.transaction ? options.transaction.connection : this.connectionManager.getConnection(options));
const query = new this.dialect.Query(connection, this, options);
return Promise.resolve(retry(() => Promise.resolve().then(() => { try {
if (options.transaction === undefined && Sequelize._cls) { await this.runHooks('beforeQuery', options, query);
options.transaction = Sequelize._cls.get('transaction'); await checkTransaction();
return await query.run(sql, bindParameters);
} finally {
await this.runHooks('afterQuery', options, query);
if (!options.transaction) {
await this.connectionManager.releaseConnection(connection);
} }
}
checkTransaction(); }, retryOptions);
return options.transaction
? options.transaction.connection
: this.connectionManager.getConnection(options);
}).then(connection => {
const query = new this.dialect.Query(connection, this, options);
return this.runHooks('beforeQuery', options, query)
.then(() => checkTransaction())
.then(() => query.run(sql, bindParameters))
.finally(() => this.runHooks('afterQuery', options, query))
.finally(() => {
if (!options.transaction) {
return this.connectionManager.releaseConnection(connection);
}
});
}), retryOptions));
});
} }
/** /**
...@@ -671,7 +668,7 @@ class Sequelize { ...@@ -671,7 +668,7 @@ class Sequelize {
* *
* @returns {Promise} * @returns {Promise}
*/ */
set(variables, options) { async set(variables, options) {
// Prepare options // Prepare options
options = Object.assign({}, this.options.set, typeof options === 'object' && options); options = Object.assign({}, this.options.set, typeof options === 'object' && options);
...@@ -693,7 +690,7 @@ class Sequelize { ...@@ -693,7 +690,7 @@ class Sequelize {
`SET ${ `SET ${
_.map(variables, (v, k) => `@${k} := ${typeof v === 'string' ? `"${v}"` : v}`).join(', ')}`; _.map(variables, (v, k) => `@${k} := ${typeof v === 'string' ? `"${v}"` : v}`).join(', ')}`;
return this.query(query, options); return await this.query(query, options);
} }
/** /**
...@@ -722,8 +719,8 @@ class Sequelize { ...@@ -722,8 +719,8 @@ class Sequelize {
* *
* @returns {Promise} * @returns {Promise}
*/ */
createSchema(schema, options) { async createSchema(schema, options) {
return this.getQueryInterface().createSchema(schema, options); return await this.getQueryInterface().createSchema(schema, options);
} }
/** /**
...@@ -737,8 +734,8 @@ class Sequelize { ...@@ -737,8 +734,8 @@ class Sequelize {
* *
* @returns {Promise} * @returns {Promise}
*/ */
showAllSchemas(options) { async showAllSchemas(options) {
return this.getQueryInterface().showAllSchemas(options); return await this.getQueryInterface().showAllSchemas(options);
} }
/** /**
...@@ -753,8 +750,8 @@ class Sequelize { ...@@ -753,8 +750,8 @@ class Sequelize {
* *
* @returns {Promise} * @returns {Promise}
*/ */
dropSchema(schema, options) { async dropSchema(schema, options) {
return this.getQueryInterface().dropSchema(schema, options); return await this.getQueryInterface().dropSchema(schema, options);
} }
/** /**
...@@ -768,8 +765,8 @@ class Sequelize { ...@@ -768,8 +765,8 @@ class Sequelize {
* *
* @returns {Promise} * @returns {Promise}
*/ */
dropAllSchemas(options) { async dropAllSchemas(options) {
return this.getQueryInterface().dropAllSchemas(options); return await this.getQueryInterface().dropAllSchemas(options);
} }
/** /**
...@@ -886,18 +883,20 @@ class Sequelize { ...@@ -886,18 +883,20 @@ class Sequelize {
* *
* @returns {Promise} * @returns {Promise}
*/ */
authenticate(options) { async authenticate(options) {
options = Object.assign({ options = Object.assign({
raw: true, raw: true,
plain: true, plain: true,
type: QueryTypes.SELECT type: QueryTypes.SELECT
}, options); }, options);
return this.query('SELECT 1+1 AS result', options).then(() => undefined); await this.query('SELECT 1+1 AS result', options);
return;
} }
databaseVersion(options) { async databaseVersion(options) {
return this.getQueryInterface().databaseVersion(options); return await this.getQueryInterface().databaseVersion(options);
} }
/** /**
...@@ -1094,7 +1093,7 @@ class Sequelize { ...@@ -1094,7 +1093,7 @@ class Sequelize {
* *
* @returns {Promise} * @returns {Promise}
*/ */
transaction(options, autoCallback) { async transaction(options, autoCallback) {
if (typeof options === 'function') { if (typeof options === 'function') {
autoCallback = options; autoCallback = options;
options = undefined; options = undefined;
...@@ -1102,20 +1101,28 @@ class Sequelize { ...@@ -1102,20 +1101,28 @@ class Sequelize {
const transaction = new Transaction(this, options); const transaction = new Transaction(this, options);
if (!autoCallback) return transaction.prepareEnvironment(false).then(() => transaction); if (!autoCallback) {
await transaction.prepareEnvironment(false);
return transaction;
}
// autoCallback provided // autoCallback provided
return Sequelize._clsRun(() => { return Sequelize._clsRun(async () => {
return transaction.prepareEnvironment() try {
.then(() => autoCallback(transaction)) await transaction.prepareEnvironment();
.then(result => Promise.resolve(transaction.commit()).then(() => result)) const result = await autoCallback(transaction);
.catch(err => { await transaction.commit();
// Rollback transaction if not already finished (commit, rollback, etc) return await result;
// and reject with original error (ignore any error in rollback) } catch (err) {
return Promise.resolve().then(() => { if (!transaction.finished) {
if (!transaction.finished) return transaction.rollback().catch(() => {}); try {
}).then(() => { throw err; }); await transaction.rollback();
}); } catch (err0) {
// ignore
}
}
throw err;
}
}); });
} }
......
...@@ -880,10 +880,9 @@ describe(Support.getTestDialectTeaser('Sequelize'), () => { ...@@ -880,10 +880,9 @@ describe(Support.getTestDialectTeaser('Sequelize'), () => {
if (dialect === 'mysql') { if (dialect === 'mysql') {
describe('set', () => { describe('set', () => {
it("should return an promised error if transaction isn't defined", function() { it("should return an promised error if transaction isn't defined", async function() {
expect(() => { await expect(this.sequelize.set({ foo: 'bar' }))
this.sequelize.set({ foo: 'bar' }); .to.be.rejectedWith(TypeError, 'options.transaction is required');
}).to.throw(TypeError, 'options.transaction is required');
}); });
it('one value', function() { it('one value', function() {
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!