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

Commit f98bd7ed by Hugo Denizart Committed by GitHub

feat(add-constraint): add deferrable option (#13096)

Co-authored-by: Pedro Augusto de Paula Barbosa <papb1996@gmail.com>
1 parent 48225948
...@@ -684,6 +684,11 @@ class QueryGenerator { ...@@ -684,6 +684,11 @@ class QueryGenerator {
break; break;
default: throw new Error(`${options.type} is invalid.`); default: throw new Error(`${options.type} is invalid.`);
} }
if (options.deferrable && ['UNIQUE', 'PRIMARY KEY', 'FOREIGN KEY'].includes(options.type.toUpperCase())) {
constraintSnippet += ` ${this.deferConstraintsQuery(options)}`;
}
return constraintSnippet; return constraintSnippet;
} }
......
...@@ -703,6 +703,7 @@ class QueryInterface { ...@@ -703,6 +703,7 @@ class QueryInterface {
* @param {string} [options.references.table] Target table name * @param {string} [options.references.table] Target table name
* @param {string} [options.references.field] Target column name * @param {string} [options.references.field] Target column name
* @param {string} [options.references.fields] Target column names for a composite primary key. Must match the order of fields in options.fields. * @param {string} [options.references.fields] Target column names for a composite primary key. Must match the order of fields in options.fields.
* @param {string} [options.deferrable] Sets the constraint to be deferred or immediately checked. See Sequelize.Deferrable. PostgreSQL Only
* *
* @returns {Promise} * @returns {Promise}
*/ */
......
...@@ -13,6 +13,8 @@ if (!Support.sequelize.dialect.supports.deferrableConstraints) { ...@@ -13,6 +13,8 @@ if (!Support.sequelize.dialect.supports.deferrableConstraints) {
describe(Support.getTestDialectTeaser('Sequelize'), () => { describe(Support.getTestDialectTeaser('Sequelize'), () => {
describe('Deferrable', () => { describe('Deferrable', () => {
const describeDeferrableTest = (title, defineModels) => {
describe(title, () => {
beforeEach(function() { beforeEach(function() {
this.run = async function(deferrable, options) { this.run = async function(deferrable, options) {
options = options || {}; options = options || {};
...@@ -21,29 +23,7 @@ describe(Support.getTestDialectTeaser('Sequelize'), () => { ...@@ -21,29 +23,7 @@ describe(Support.getTestDialectTeaser('Sequelize'), () => {
const transactionOptions = { deferrable: Sequelize.Deferrable.SET_DEFERRED, ...options }; const transactionOptions = { deferrable: Sequelize.Deferrable.SET_DEFERRED, ...options };
const userTableName = `users_${config.rand()}`; const userTableName = `users_${config.rand()}`;
const User = this.sequelize.define( const { Task, User } = await defineModels({ sequelize: this.sequelize, userTableName, deferrable, taskTableName });
'User', { name: Sequelize.STRING }, { tableName: userTableName }
);
const Task = this.sequelize.define(
'Task', {
title: Sequelize.STRING,
user_id: {
allowNull: false,
type: Sequelize.INTEGER,
references: {
model: userTableName,
key: 'id',
deferrable
}
}
}, {
tableName: taskTableName
}
);
await User.sync({ force: true });
await Task.sync({ force: true });
return this.sequelize.transaction(transactionOptions, async t => { return this.sequelize.transaction(transactionOptions, async t => {
const task0 = await Task const task0 = await Task
...@@ -101,4 +81,68 @@ describe(Support.getTestDialectTeaser('Sequelize'), () => { ...@@ -101,4 +81,68 @@ describe(Support.getTestDialectTeaser('Sequelize'), () => {
}); });
}); });
}); });
};
describeDeferrableTest('set in define', async ({ sequelize, userTableName, deferrable, taskTableName }) => {
const User = sequelize.define(
'User', { name: Sequelize.STRING }, { tableName: userTableName }
);
const Task = sequelize.define(
'Task', {
title: Sequelize.STRING,
user_id: {
allowNull: false,
type: Sequelize.INTEGER,
references: {
model: userTableName,
key: 'id',
deferrable
}
}
}, {
tableName: taskTableName
}
);
await User.sync({ force: true });
await Task.sync({ force: true });
return { Task, User };
});
describeDeferrableTest('set in addConstraint', async ({ sequelize, userTableName, deferrable, taskTableName }) => {
const User = sequelize.define(
'User', { name: Sequelize.STRING }, { tableName: userTableName }
);
const Task = sequelize.define(
'Task', {
title: Sequelize.STRING,
user_id: {
allowNull: false,
type: Sequelize.INTEGER
}
}, {
tableName: taskTableName
}
);
await User.sync({ force: true });
await Task.sync({ force: true });
await sequelize.getQueryInterface().addConstraint(taskTableName, {
fields: ['user_id'],
type: 'foreign key',
name: `${taskTableName}_user_id_fkey`,
deferrable,
references: {
table: userTableName,
field: 'id'
}
});
return { Task, User };
});
});
}); });
...@@ -15,6 +15,7 @@ import { Sequelize, RetryOptions } from './sequelize'; ...@@ -15,6 +15,7 @@ import { Sequelize, RetryOptions } from './sequelize';
import { Transaction } from './transaction'; import { Transaction } from './transaction';
import { SetRequired } from './../type-helpers/set-required'; import { SetRequired } from './../type-helpers/set-required';
import { Fn, Literal } from './utils'; import { Fn, Literal } from './utils';
import { Deferrable } from './deferrable';
type BindOrReplacements = { [key: string]: unknown } | unknown[]; type BindOrReplacements = { [key: string]: unknown } | unknown[];
type FieldMap = { [key: string]: string }; type FieldMap = { [key: string]: string };
...@@ -216,6 +217,7 @@ export interface BaseConstraintOptions { ...@@ -216,6 +217,7 @@ export interface BaseConstraintOptions {
export interface AddUniqueConstraintOptions extends BaseConstraintOptions { export interface AddUniqueConstraintOptions extends BaseConstraintOptions {
type: 'unique'; type: 'unique';
deferrable?: Deferrable;
} }
export interface AddDefaultConstraintOptions extends BaseConstraintOptions { export interface AddDefaultConstraintOptions extends BaseConstraintOptions {
...@@ -230,6 +232,7 @@ export interface AddCheckConstraintOptions extends BaseConstraintOptions { ...@@ -230,6 +232,7 @@ export interface AddCheckConstraintOptions extends BaseConstraintOptions {
export interface AddPrimaryKeyConstraintOptions extends BaseConstraintOptions { export interface AddPrimaryKeyConstraintOptions extends BaseConstraintOptions {
type: 'primary key'; type: 'primary key';
deferrable?: Deferrable;
} }
export interface AddForeignKeyConstraintOptions extends BaseConstraintOptions { export interface AddForeignKeyConstraintOptions extends BaseConstraintOptions {
...@@ -240,6 +243,7 @@ export interface AddForeignKeyConstraintOptions extends BaseConstraintOptions { ...@@ -240,6 +243,7 @@ export interface AddForeignKeyConstraintOptions extends BaseConstraintOptions {
}; };
onDelete: string; onDelete: string;
onUpdate: string; onUpdate: string;
deferrable?: Deferrable;
} }
export type AddConstraintOptions = export type AddConstraintOptions =
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!