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

Commit 0b5aa71f by Simon Schick Committed by Sushant

fix(types): allow specifying additional options for db.query and add missing retry (#10512)

1 parent 45648dd0
...@@ -1688,7 +1688,7 @@ export abstract class Model<T = any, T2 = any> extends Hooks { ...@@ -1688,7 +1688,7 @@ export abstract class Model<T = any, T2 = any> extends Hooks {
* where: ..., * where: ...,
* limit: 12, * limit: 12,
* offset: 12 * offset: 12
* }).then(function (result) { * }).then(result => {
* ... * ...
* }) * })
* ``` * ```
...@@ -1776,7 +1776,7 @@ export abstract class Model<T = any, T2 = any> extends Hooks { ...@@ -1776,7 +1776,7 @@ export abstract class Model<T = any, T2 = any> extends Hooks {
/** /**
* Find a row that matches the query, or build (but don't save) the row if none is found. * Find a row that matches the query, or build (but don't save) the row if none is found.
* The successfull result of the promise will be (instance, initialized) - Make sure to use .spread() * The successfull result of the promise will be (instance, initialized) - Make sure to use `.then(([...]))`
*/ */
public static findOrBuild<M extends Model>( public static findOrBuild<M extends Model>(
this: { new (): M } & typeof Model, this: { new (): M } & typeof Model,
...@@ -1785,7 +1785,7 @@ export abstract class Model<T = any, T2 = any> extends Hooks { ...@@ -1785,7 +1785,7 @@ export abstract class Model<T = any, T2 = any> extends Hooks {
/** /**
* Find a row that matches the query, or build and save the row if none is found * Find a row that matches the query, or build and save the row if none is found
* The successful result of the promise will be (instance, created) - Make sure to use .spread() * The successful result of the promise will be (instance, created) - Make sure to use `.then(([...]))`
* *
* If no transaction is passed in the `options` object, a new transaction will be created internally, to * If no transaction is passed in the `options` object, a new transaction will be created internally, to
* prevent the race condition where a matching row is created by another connection after the find but * prevent the race condition where a matching row is created by another connection after the find but
...@@ -2291,7 +2291,7 @@ export abstract class Model<T = any, T2 = any> extends Hooks { ...@@ -2291,7 +2291,7 @@ export abstract class Model<T = any, T2 = any> extends Hooks {
* Similarily, when fetching through a join table with custom attributes, these attributes will be * Similarily, when fetching through a join table with custom attributes, these attributes will be
* available as an object with the name of the through model. * available as an object with the name of the through model.
* ```js * ```js
* user.getProjects().then(function (projects) { * user.getProjects().then(projects => {
* var p1 = projects[0] * var p1 = projects[0]
* p1.userprojects.started // Is this project started yet? * p1.userprojects.started // Is this project started yet?
* }) * })
...@@ -2340,8 +2340,8 @@ export abstract class Model<T = any, T2 = any> extends Hooks { ...@@ -2340,8 +2340,8 @@ export abstract class Model<T = any, T2 = any> extends Hooks {
* Similarily, when fetching through a join table with custom attributes, these attributes will be * Similarily, when fetching through a join table with custom attributes, these attributes will be
* available as an object with the name of the through model. * available as an object with the name of the through model.
* ```js * ```js
* user.getProjects().then(function (projects) { * user.getProjects().then(projects => {
* var p1 = projects[0] * const p1 = projects[0]
* p1.userprojects.started // Is this project started yet? * p1.userprojects.started // Is this project started yet?
* }) * })
* ``` * ```
......
...@@ -2,7 +2,7 @@ import { DataType } from './data-types'; ...@@ -2,7 +2,7 @@ import { DataType } from './data-types';
import { Logging, Model, ModelAttributeColumnOptions, ModelAttributes, Transactionable, WhereOptions, Filterable } from './model'; import { Logging, Model, ModelAttributeColumnOptions, ModelAttributes, Transactionable, WhereOptions, Filterable } from './model';
import { Promise } from './promise'; import { Promise } from './promise';
import QueryTypes = require('./query-types'); import QueryTypes = require('./query-types');
import { Sequelize } from './sequelize'; import { Sequelize, RetryOptions } from './sequelize';
import { Transaction } from './transaction'; import { Transaction } from './transaction';
/** /**
...@@ -55,13 +55,15 @@ export interface QueryOptions extends Logging, Transactionable { ...@@ -55,13 +55,15 @@ export interface QueryOptions extends Logging, Transactionable {
* A sequelize instance used to build the return instance * A sequelize instance used to build the return instance
*/ */
instance?: Model; instance?: Model;
retry?: RetryOptions;
} }
export interface QueryOptionsWithWhere extends QueryOptions, Filterable { export interface QueryOptionsWithWhere extends QueryOptions, Filterable {
} }
export interface QueryOptionsWithModel { export interface QueryOptionsWithModel extends QueryOptions {
/** /**
* A sequelize model used to build the returned model instances (used to be called callee) * A sequelize model used to build the returned model instances (used to be called callee)
*/ */
......
...@@ -143,6 +143,11 @@ export interface Config { ...@@ -143,6 +143,11 @@ export interface Config {
export type Dialect = 'mysql' | 'postgres' | 'sqlite' | 'mariadb' | 'mssql' | 'mariadb'; export type Dialect = 'mysql' | 'postgres' | 'sqlite' | 'mariadb' | 'mssql' | 'mariadb';
export interface RetryOptions {
match?: (RegExp | string | Function)[];
max?: number;
}
/** /**
* Options for the constructor of Sequelize main class * Options for the constructor of Sequelize main class
*/ */
...@@ -307,7 +312,9 @@ export interface Options extends Logging { ...@@ -307,7 +312,9 @@ export interface Options extends Logging {
/** /**
* Sets global permanent hooks. * Sets global permanent hooks.
*/ */
hooks?: Partial<SequelizeHooks> hooks?: Partial<SequelizeHooks>;
retry?: RetryOptions;
} }
export interface QueryOptionsTransactionRequired {} export interface QueryOptionsTransactionRequired {}
...@@ -1034,17 +1041,17 @@ export class Sequelize extends Hooks { ...@@ -1034,17 +1041,17 @@ export class Sequelize extends Hooks {
* Execute a query on the DB, with the posibility to bypass all the sequelize goodness. * Execute a query on the DB, with the posibility to bypass all the sequelize goodness.
* *
* By default, the function will return two arguments: an array of results, and a metadata object, * By default, the function will return two arguments: an array of results, and a metadata object,
* containing number of affected rows etc. Use `.spread` to access the results. * containing number of affected rows etc. Use `.then(([...]))` to access the results.
* *
* If you are running a type of query where you don't need the metadata, for example a `SELECT` query, you * If you are running a type of query where you don't need the metadata, for example a `SELECT` query, you
* can pass in a query type to make sequelize format the results: * can pass in a query type to make sequelize format the results:
* *
* ```js * ```js
* sequelize.query('SELECT...').spread(function (results, metadata) { * sequelize.query('SELECT...').then(([results, metadata]) {
* // Raw query - use spread * // Raw query - use spread
* }); * });
* *
* sequelize.query('SELECT...', { type: sequelize.QueryTypes.SELECT }).then(function (results) { * sequelize.query('SELECT...', { type: sequelize.QueryTypes.SELECT }).then(results => {
* // SELECT query - use then * // SELECT query - use then
* }) * })
* ``` * ```
...@@ -1175,8 +1182,8 @@ export class Sequelize extends Hooks { ...@@ -1175,8 +1182,8 @@ export class Sequelize extends Hooks {
* in order for the query to happen under that transaction * in order for the query to happen under that transaction
* *
* ```js * ```js
* sequelize.transaction().then(function (t) { * sequelize.transaction().then(t => {
* return User.findOne(..., { transaction: t}).then(function (user) { * return User.findOne(..., { transaction: t}).then(user => {
* return user.update(..., { transaction: t}); * return user.update(..., { transaction: t});
* }) * })
* .then(t.commit.bind(t)) * .then(t.commit.bind(t))
...@@ -1188,13 +1195,13 @@ export class Sequelize extends Hooks { ...@@ -1188,13 +1195,13 @@ export class Sequelize extends Hooks {
* supported: * supported:
* *
* ```js * ```js
* sequelize.transaction(function (t) { // Note that we use a callback rather than a promise.then() * sequelize.transaction(t => { // Note that we use a callback rather than a promise.then()
* return User.findOne(..., { transaction: t}).then(function (user) { * return User.findOne(..., { transaction: t}).then(user => {
* return user.update(..., { transaction: t}); * return user.update(..., { transaction: t});
* }); * });
* }).then(function () { * }).then(() => {
* // Commited * // Commited
* }).catch(function (err) { * }).catch(err => {
* // Rolled back * // Rolled back
* console.error(err); * console.error(err);
* }); * });
......
import { QueryTypes, Sequelize, SyncOptions } from 'sequelize'; import { QueryTypes, Sequelize, SyncOptions } from 'sequelize';
import { User } from 'models/User';
export const sequelize = new Sequelize('uri'); export const sequelize = new Sequelize('uri');
sequelize.afterBulkSync((options: SyncOptions) => { sequelize.afterBulkSync((options: SyncOptions) => {
console.log('synced'); console.log('synced');
}); });
sequelize sequelize
.query('SELECT * FROM `test`', { .query('SELECT * FROM `test`', {
type: QueryTypes.SELECT, type: QueryTypes.SELECT,
}) })
.then(rows => { .then(rows => {
rows.forEach(row => { rows.forEach(row => {
console.log(row); console.log(row);
});
}); });
});
sequelize sequelize
.query('INSERT into test set test=1', { .query('INSERT into test set test=1', {
type: QueryTypes.INSERT, type: QueryTypes.INSERT,
}) })
.then(([aiId, affected]) => { .then(([aiId, affected]) => {
console.log(aiId, affected); console.log(aiId, affected);
}); });
sequelize.transaction<void>(async transaction => {
const rows = await sequelize
.query('SELECT * FROM `user`', {
retry: {
max: 123,
},
model: User,
transaction,
logging: true,
})
})
...@@ -5,6 +5,10 @@ export const sequelize = new Sequelize({ ...@@ -5,6 +5,10 @@ export const sequelize = new Sequelize({
afterConnect: (connection, config: Config) => { afterConnect: (connection, config: Config) => {
// noop // noop
} }
},
retry: {
max: 123,
match: ['hurr'],
} }
}); });
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!