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

Commit 0dd07ac1 by Mick Hansen

Merge pull request #3702 from sequelize/feature/deferrable-constraints

Deferrable constraints for PostgreSQL
2 parents 341b0172 c79e5302
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
- [FIXED] `include.attributes = []` will no longer force the inclusion of the primary key, making it possible to write aggregates with includes. - [FIXED] `include.attributes = []` will no longer force the inclusion of the primary key, making it possible to write aggregates with includes.
- [CHANGED] The `references` property of model attributes has been transformed to an object: `{type: Sequelize.INTEGER, references: { model: SomeModel, key: 'some_key' }}`. The former format (`references` and `referecesKey`) still exists but is deprecated and will be removed in 4.0. - [CHANGED] The `references` property of model attributes has been transformed to an object: `{type: Sequelize.INTEGER, references: { model: SomeModel, key: 'some_key' }}`. The former format (`references` and `referecesKey`) still exists but is deprecated and will be removed in 4.0.
- [ADDED] It is now possible to defer constraints in PostgreSQL by added a property `deferrable` to the `references` object of a field.
# 3.0.0 # 3.0.0
......
<a name="mixin"></a> <a name="mixin"></a>
# Mixin Mixin # Mixin Mixin
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/associations/mixin.js#L95) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/associations/mixin.js#L95)
Creating assocations in sequelize is done by calling one of the belongsTo / hasOne / hasMany functions Creating assocations in sequelize is done by calling one of the belongsTo / hasOne / hasMany functions
on a model (the source), and providing another model as the first argument to the function (the target). on a model (the source), and providing another model as the first argument to the function (the target).
...@@ -89,7 +89,7 @@ you should either disable some constraints, or rethink your associations complet ...@@ -89,7 +89,7 @@ you should either disable some constraints, or rethink your associations complet
<a name="hasone"></a> <a name="hasone"></a>
## `hasOne(target, [options])` ## `hasOne(target, [options])`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/associations/mixin.js#L145) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/associations/mixin.js#L145)
Creates an association between this (the source) and the provided target. The foreign key is added on the target. Creates an association between this (the source) and the provided target. The foreign key is added on the target.
Example: `User.hasOne(Profile)`. This will add userId to the profile table. Example: `User.hasOne(Profile)`. This will add userId to the profile table.
...@@ -121,7 +121,7 @@ All methods return a promise ...@@ -121,7 +121,7 @@ All methods return a promise
<a name="belongsto"></a> <a name="belongsto"></a>
## `belongsTo(target, [options])` ## `belongsTo(target, [options])`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/associations/mixin.js#L170) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/associations/mixin.js#L170)
Creates an association between this (the source) and the provided target. The foreign key is added on the source. Creates an association between this (the source) and the provided target. The foreign key is added on the source.
Example: `Profile.belongsTo(User)`. This will add userId to the profile table. Example: `Profile.belongsTo(User)`. This will add userId to the profile table.
...@@ -153,7 +153,7 @@ All methods return a promise ...@@ -153,7 +153,7 @@ All methods return a promise
<a name="hasmany"></a> <a name="hasmany"></a>
## `hasMany(target, [options])` ## `hasMany(target, [options])`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/associations/mixin.js#L245) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/associations/mixin.js#L245)
Create an association that is either 1:m or n:m. Create an association that is either 1:m or n:m.
```js ```js
...@@ -236,7 +236,7 @@ user.getProjects().success(function (projects) { ...@@ -236,7 +236,7 @@ user.getProjects().success(function (projects) {
<a name="belongstomany"></a> <a name="belongstomany"></a>
## `belongsToMany(target, [options])` ## `belongsToMany(target, [options])`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/associations/mixin.js#L339) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/associations/mixin.js#L339)
Create an N:M association with a join table Create an N:M association with a join table
```js ```js
......
<a name="datatypes"></a> <a name="datatypes"></a>
# Class DataTypes # Class DataTypes
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/data-types.js#L37) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/data-types.js#L37)
A convenience class holding commonly used data types. The datatypes are used when definining a new model using `Sequelize.define`, like this: A convenience class holding commonly used data types. The datatypes are used when definining a new model using `Sequelize.define`, like this:
```js ```js
sequelize.define('model', { sequelize.define('model', {
...@@ -33,7 +33,7 @@ sequelize.define('model', { ...@@ -33,7 +33,7 @@ sequelize.define('model', {
<a name="string"></a> <a name="string"></a>
## `STRING()` ## `STRING()`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/data-types.js#L55) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/data-types.js#L55)
A variable length string. Default length 255 A variable length string. Default length 255
Available properties: `BINARY` Available properties: `BINARY`
...@@ -43,7 +43,7 @@ Available properties: `BINARY` ...@@ -43,7 +43,7 @@ Available properties: `BINARY`
<a name="char"></a> <a name="char"></a>
## `CHAR()` ## `CHAR()`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/data-types.js#L88) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/data-types.js#L88)
A fixed length string. Default length 255 A fixed length string. Default length 255
Available properties: `BINARY` Available properties: `BINARY`
...@@ -53,14 +53,14 @@ Available properties: `BINARY` ...@@ -53,14 +53,14 @@ Available properties: `BINARY`
<a name="text"></a> <a name="text"></a>
## `TEXT()` ## `TEXT()`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/data-types.js#L109) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/data-types.js#L109)
An unlimited length text column An unlimited length text column
*** ***
<a name="integer"></a> <a name="integer"></a>
## `INTEGER()` ## `INTEGER()`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/data-types.js#L169) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/data-types.js#L169)
A 32 bit integer. A 32 bit integer.
Available properties: `UNSIGNED`, `ZEROFILL` Available properties: `UNSIGNED`, `ZEROFILL`
...@@ -70,7 +70,7 @@ Available properties: `UNSIGNED`, `ZEROFILL` ...@@ -70,7 +70,7 @@ Available properties: `UNSIGNED`, `ZEROFILL`
<a name="bigint"></a> <a name="bigint"></a>
## `BIGINT()` ## `BIGINT()`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/data-types.js#L188) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/data-types.js#L188)
A 64 bit integer. A 64 bit integer.
Available properties: `UNSIGNED`, `ZEROFILL` Available properties: `UNSIGNED`, `ZEROFILL`
...@@ -80,7 +80,7 @@ Available properties: `UNSIGNED`, `ZEROFILL` ...@@ -80,7 +80,7 @@ Available properties: `UNSIGNED`, `ZEROFILL`
<a name="float"></a> <a name="float"></a>
## `FLOAT()` ## `FLOAT()`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/data-types.js#L206) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/data-types.js#L206)
Floating point number (4-byte precision). Accepts one or two arguments for precision Floating point number (4-byte precision). Accepts one or two arguments for precision
Available properties: `UNSIGNED`, `ZEROFILL` Available properties: `UNSIGNED`, `ZEROFILL`
...@@ -90,7 +90,7 @@ Available properties: `UNSIGNED`, `ZEROFILL` ...@@ -90,7 +90,7 @@ Available properties: `UNSIGNED`, `ZEROFILL`
<a name="real"></a> <a name="real"></a>
## `REAL()` ## `REAL()`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/data-types.js#L225) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/data-types.js#L225)
Floating point number (4-byte precision). Accepts one or two arguments for precision Floating point number (4-byte precision). Accepts one or two arguments for precision
Available properties: `UNSIGNED`, `ZEROFILL` Available properties: `UNSIGNED`, `ZEROFILL`
...@@ -100,7 +100,7 @@ Available properties: `UNSIGNED`, `ZEROFILL` ...@@ -100,7 +100,7 @@ Available properties: `UNSIGNED`, `ZEROFILL`
<a name="double"></a> <a name="double"></a>
## `DOUBLE()` ## `DOUBLE()`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/data-types.js#L244) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/data-types.js#L244)
Floating point number (8-byte precision). Accepts one or two arguments for precision Floating point number (8-byte precision). Accepts one or two arguments for precision
Available properties: `UNSIGNED`, `ZEROFILL` Available properties: `UNSIGNED`, `ZEROFILL`
...@@ -110,7 +110,7 @@ Available properties: `UNSIGNED`, `ZEROFILL` ...@@ -110,7 +110,7 @@ Available properties: `UNSIGNED`, `ZEROFILL`
<a name="decimal"></a> <a name="decimal"></a>
## `DECIMAL()` ## `DECIMAL()`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/data-types.js#L263) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/data-types.js#L263)
Decimal number. Accepts one or two arguments for precision Decimal number. Accepts one or two arguments for precision
Available properties: `UNSIGNED`, `ZEROFILL` Available properties: `UNSIGNED`, `ZEROFILL`
...@@ -120,63 +120,63 @@ Available properties: `UNSIGNED`, `ZEROFILL` ...@@ -120,63 +120,63 @@ Available properties: `UNSIGNED`, `ZEROFILL`
<a name="boolean"></a> <a name="boolean"></a>
## `BOOLEAN()` ## `BOOLEAN()`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/data-types.js#L286) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/data-types.js#L286)
A boolean / tinyint column, depending on dialect A boolean / tinyint column, depending on dialect
*** ***
<a name="time"></a> <a name="time"></a>
## `TIME()` ## `TIME()`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/data-types.js#L302) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/data-types.js#L302)
A time column A time column
*** ***
<a name="date"></a> <a name="date"></a>
## `DATE()` ## `DATE()`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/data-types.js#L317) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/data-types.js#L317)
A datetime column A datetime column
*** ***
<a name="dateonly"></a> <a name="dateonly"></a>
## `DATEONLY()` ## `DATEONLY()`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/data-types.js#L333) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/data-types.js#L333)
A date only column A date only column
*** ***
<a name="hstore"></a> <a name="hstore"></a>
## `HSTORE()` ## `HSTORE()`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/data-types.js#L349) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/data-types.js#L349)
A key / value column. Only available in postgres. A key / value column. Only available in postgres.
*** ***
<a name="json"></a> <a name="json"></a>
## `JSON()` ## `JSON()`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/data-types.js#L361) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/data-types.js#L361)
A JSON string column. Only available in postgres. A JSON string column. Only available in postgres.
*** ***
<a name="jsonb"></a> <a name="jsonb"></a>
## `JSONB()` ## `JSONB()`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/data-types.js#L373) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/data-types.js#L373)
A pre-processed JSON data column. Only available in postgres. A pre-processed JSON data column. Only available in postgres.
*** ***
<a name="now"></a> <a name="now"></a>
## `NOW()` ## `NOW()`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/data-types.js#L385) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/data-types.js#L385)
A default value of the current timestamp A default value of the current timestamp
*** ***
<a name="blob"></a> <a name="blob"></a>
## `BLOB()` ## `BLOB()`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/data-types.js#L399) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/data-types.js#L399)
Binary storage. Available lengths: `tiny`, `medium`, `long` Binary storage. Available lengths: `tiny`, `medium`, `long`
...@@ -184,7 +184,7 @@ Binary storage. Available lengths: `tiny`, `medium`, `long` ...@@ -184,7 +184,7 @@ Binary storage. Available lengths: `tiny`, `medium`, `long`
<a name="range"></a> <a name="range"></a>
## `RANGE()` ## `RANGE()`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/data-types.js#L429) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/data-types.js#L429)
Range types are data types representing a range of values of some element type (called the range's subtype). Range types are data types representing a range of values of some element type (called the range's subtype).
Only available in postgres. Only available in postgres.
See {@link http://www.postgresql.org/docs/9.4/static/rangetypes.html|Postgres documentation} for more details See {@link http://www.postgresql.org/docs/9.4/static/rangetypes.html|Postgres documentation} for more details
...@@ -193,28 +193,28 @@ See {@link http://www.postgresql.org/docs/9.4/static/rangetypes.html|Postgres do ...@@ -193,28 +193,28 @@ See {@link http://www.postgresql.org/docs/9.4/static/rangetypes.html|Postgres do
<a name="uuid"></a> <a name="uuid"></a>
## `UUID()` ## `UUID()`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/data-types.js#L458) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/data-types.js#L458)
A column storing a unique univeral identifier. Use with `UUIDV1` or `UUIDV4` for default values. A column storing a unique univeral identifier. Use with `UUIDV1` or `UUIDV4` for default values.
*** ***
<a name="uuidv1"></a> <a name="uuidv1"></a>
## `UUIDV1()` ## `UUIDV1()`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/data-types.js#L471) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/data-types.js#L471)
A default unique universal identifier generated following the UUID v1 standard A default unique universal identifier generated following the UUID v1 standard
*** ***
<a name="uuidv4"></a> <a name="uuidv4"></a>
## `UUIDV4()` ## `UUIDV4()`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/data-types.js#L484) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/data-types.js#L484)
A default unique universal identifier generated following the UUID v2 standard A default unique universal identifier generated following the UUID v2 standard
*** ***
<a name="virtual"></a> <a name="virtual"></a>
## `VIRTUAL()` ## `VIRTUAL()`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/data-types.js#L519) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/data-types.js#L519)
A virtual value that is not stored in the DB. This could for example be useful if you want to provide a default value in your model that is returned to the user but not stored in the DB. A virtual value that is not stored in the DB. This could for example be useful if you want to provide a default value in your model that is returned to the user but not stored in the DB.
You could also use it to validate a value before permuting and storing it. Checking password length before hashing it for example: You could also use it to validate a value before permuting and storing it. Checking password length before hashing it for example:
...@@ -244,7 +244,7 @@ __Aliases:__ NONE ...@@ -244,7 +244,7 @@ __Aliases:__ NONE
<a name="enum"></a> <a name="enum"></a>
## `ENUM()` ## `ENUM()`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/data-types.js#L532) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/data-types.js#L532)
An enumeration. `DataTypes.ENUM('value', 'another value')`. An enumeration. `DataTypes.ENUM('value', 'another value')`.
...@@ -252,7 +252,7 @@ An enumeration. `DataTypes.ENUM('value', 'another value')`. ...@@ -252,7 +252,7 @@ An enumeration. `DataTypes.ENUM('value', 'another value')`.
<a name="array"></a> <a name="array"></a>
## `ARRAY()` ## `ARRAY()`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/data-types.js#L549) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/data-types.js#L549)
An array of `type`, e.g. `DataTypes.ARRAY(DataTypes.DECIMAL)`. Only available in postgres. An array of `type`, e.g. `DataTypes.ARRAY(DataTypes.DECIMAL)`. Only available in postgres.
*** ***
......
<a name="deferrable"></a>
## `Deferrable()` -> `object`
[View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/deferrable.js#L39)
A collection of properties related to deferrable constraints. It can be used to
make foreign key constraints deferrable and to set the constaints within a
transaction. This is only supported in PostgreSQL.
The foreign keys can be configured like this. It will create a foreign key
that will check the constraints immediately when the data was inserted.
```js
sequelize.define('Model', {
foreign_id: {
type: Sequelize.INTEGER,
references: {
model: OtherModel,
key: 'id',
deferrable: Sequelize.Deferrable.INITIALLY_IMMEDIATE
}
}
});
```
The constraints can be configured in a transaction like this. It will
trigger a query once the transaction has been started and set the constraints
to be checked at the very end of the transaction.
```js
sequelize.transaction({
deferrable: Sequelize.Deferrable.SET_DEFERRED
});
```
***
<a name="initially_deferred"></a>
## `INITIALLY_DEFERRED()`
[View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/deferrable.js#L59)
A property that will defer constraints checks to the end of transactions.
***
<a name="initially_immediate"></a>
## `INITIALLY_IMMEDIATE()`
[View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/deferrable.js#L76)
A property that will trigger the constraint checks immediately
***
<a name="not"></a>
## `NOT()`
[View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/deferrable.js#L95)
A property that will set the constraints to not deferred. This is
the default in PostgreSQL and it make it impossible to dynamically
defer the constraints within a transaction.
***
<a name="set_deferred"></a>
## `SET_DEFERRED(constraints)`
[View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/deferrable.js#L114)
A property that will trigger an additional query at the beginning of a
transaction which sets the constraints to deferred.
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| constraints | Array | An array of constraint names. Will defer all constraints by default. |
***
<a name="set_immediate"></a>
## `SET_IMMEDIATE(constraints)`
[View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/deferrable.js#L135)
A property that will trigger an additional query at the beginning of a
transaction which sets the constraints to immediately.
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| constraints | Array | An array of constraint names. Will defer all constraints by default. |
***
_This document is automatically generated based on source code comments. Please do not edit it directly, as your changes will be ignored. Please write on <a href="irc://irc.freenode.net/#sequelizejs">IRC</a>, open an issue or a create a pull request if you feel something can be improved. For help on how to write source code documentation see [JSDoc](http://usejsdoc.org) and [dox](https://github.com/tj/dox)_
\ No newline at end of file
<a name="errors"></a> <a name="errors"></a>
# Class Errors # Class Errors
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/errors.js#L11) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/errors.js#L11)
Sequelize provides a host of custom error classes, to allow you to do easier debugging. All of these errors are exposed on the sequelize object and the sequelize constructor. Sequelize provides a host of custom error classes, to allow you to do easier debugging. All of these errors are exposed on the sequelize object and the sequelize constructor.
All sequelize errors inherit from the base JS error object. All sequelize errors inherit from the base JS error object.
...@@ -9,7 +9,7 @@ All sequelize errors inherit from the base JS error object. ...@@ -9,7 +9,7 @@ All sequelize errors inherit from the base JS error object.
<a name="baseerror"></a> <a name="baseerror"></a>
## `new BaseError()` ## `new BaseError()`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/errors.js#L20) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/errors.js#L20)
The Base Error all Sequelize Errors inherit from. The Base Error all Sequelize Errors inherit from.
__Aliases:__ Error __Aliases:__ Error
...@@ -18,7 +18,7 @@ __Aliases:__ Error ...@@ -18,7 +18,7 @@ __Aliases:__ Error
<a name="validationerror"></a> <a name="validationerror"></a>
## `new ValidationError(message, [errors])` ## `new ValidationError(message, [errors])`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/errors.js#L41) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/errors.js#L41)
Validation Error. Thrown when the sequelize validation has failed. The error contains an `errors` property, Validation Error. Thrown when the sequelize validation has failed. The error contains an `errors` property,
which is an array with 1 or more ValidationErrorItems, one for each validation that failed. which is an array with 1 or more ValidationErrorItems, one for each validation that failed.
...@@ -37,14 +37,14 @@ __Extends:__ BaseError ...@@ -37,14 +37,14 @@ __Extends:__ BaseError
<a name="errors"></a> <a name="errors"></a>
## `errors` ## `errors`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/errors.js#L49) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/errors.js#L49)
An array of ValidationErrorItems An array of ValidationErrorItems
*** ***
<a name="get"></a> <a name="get"></a>
## `get(path)` ## `get(path)`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/errors.js#L70) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/errors.js#L70)
Gets all validation error items for the path / field specified. Gets all validation error items for the path / field specified.
...@@ -59,7 +59,7 @@ Gets all validation error items for the path / field specified. ...@@ -59,7 +59,7 @@ Gets all validation error items for the path / field specified.
<a name="databaseerror"></a> <a name="databaseerror"></a>
## `new DatabaseError()` ## `new DatabaseError()`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/errors.js#L84) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/errors.js#L84)
A base class for all database related errors. A base class for all database related errors.
__Extends:__ BaseError __Extends:__ BaseError
...@@ -68,49 +68,49 @@ __Extends:__ BaseError ...@@ -68,49 +68,49 @@ __Extends:__ BaseError
<a name="parent"></a> <a name="parent"></a>
## `parent` ## `parent`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/errors.js#L92) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/errors.js#L92)
The database specific error which triggered this one The database specific error which triggered this one
*** ***
<a name="sql"></a> <a name="sql"></a>
## `sql` ## `sql`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/errors.js#L98) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/errors.js#L98)
The SQL that triggered the error The SQL that triggered the error
*** ***
<a name="message"></a> <a name="message"></a>
## `message()` ## `message()`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/errors.js#L104) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/errors.js#L104)
The message from the DB. The message from the DB.
*** ***
<a name="fields"></a> <a name="fields"></a>
## `fields()` ## `fields()`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/errors.js#L109) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/errors.js#L109)
The fields of the unique constraint The fields of the unique constraint
*** ***
<a name="value"></a> <a name="value"></a>
## `value()` ## `value()`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/errors.js#L114) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/errors.js#L114)
The value(s) which triggered the error The value(s) which triggered the error
*** ***
<a name="index"></a> <a name="index"></a>
## `index()` ## `index()`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/errors.js#L119) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/errors.js#L119)
The name of the index that triggered the error The name of the index that triggered the error
*** ***
<a name="timeouterror"></a> <a name="timeouterror"></a>
## `new TimeoutError()` ## `new TimeoutError()`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/errors.js#L127) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/errors.js#L127)
Thrown when a database query times out because of a deadlock Thrown when a database query times out because of a deadlock
__Extends:__ DatabaseError __Extends:__ DatabaseError
...@@ -119,7 +119,7 @@ __Extends:__ DatabaseError ...@@ -119,7 +119,7 @@ __Extends:__ DatabaseError
<a name="uniqueconstrainterror"></a> <a name="uniqueconstrainterror"></a>
## `new UniqueConstraintError()` ## `new UniqueConstraintError()`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/errors.js#L138) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/errors.js#L138)
Thrown when a unique constraint is violated in the database Thrown when a unique constraint is violated in the database
__Extends:__ DatabaseError __Extends:__ DatabaseError
...@@ -128,7 +128,7 @@ __Extends:__ DatabaseError ...@@ -128,7 +128,7 @@ __Extends:__ DatabaseError
<a name="foreignkeyconstrainterror"></a> <a name="foreignkeyconstrainterror"></a>
## `new ForeignKeyConstraintError()` ## `new ForeignKeyConstraintError()`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/errors.js#L157) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/errors.js#L157)
Thrown when a foreign key constraint is violated in the database Thrown when a foreign key constraint is violated in the database
__Extends:__ DatabaseError __Extends:__ DatabaseError
...@@ -137,7 +137,7 @@ __Extends:__ DatabaseError ...@@ -137,7 +137,7 @@ __Extends:__ DatabaseError
<a name="exclusionconstrainterror"></a> <a name="exclusionconstrainterror"></a>
## `new ExclusionConstraintError()` ## `new ExclusionConstraintError()`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/errors.js#L177) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/errors.js#L177)
Thrown when an exclusion constraint is violated in the database Thrown when an exclusion constraint is violated in the database
__Extends:__ DatabaseError __Extends:__ DatabaseError
...@@ -146,7 +146,7 @@ __Extends:__ DatabaseError ...@@ -146,7 +146,7 @@ __Extends:__ DatabaseError
<a name="validationerroritem"></a> <a name="validationerroritem"></a>
## `new ValidationErrorItem(message, type, path, value)` ## `new ValidationErrorItem(message, type, path, value)`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/errors.js#L201) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/errors.js#L201)
Validation Error Item Validation Error Item
Instances of this class are included in the `ValidationError.errors` property. Instances of this class are included in the `ValidationError.errors` property.
...@@ -165,7 +165,7 @@ Instances of this class are included in the `ValidationError.errors` property. ...@@ -165,7 +165,7 @@ Instances of this class are included in the `ValidationError.errors` property.
<a name="connectionerror"></a> <a name="connectionerror"></a>
## `new ConnectionError()` ## `new ConnectionError()`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/errors.js#L213) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/errors.js#L213)
A base class for all connection related errors. A base class for all connection related errors.
__Extends:__ BaseError __Extends:__ BaseError
...@@ -174,14 +174,14 @@ __Extends:__ BaseError ...@@ -174,14 +174,14 @@ __Extends:__ BaseError
<a name="parent"></a> <a name="parent"></a>
## `parent` ## `parent`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/errors.js#L220) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/errors.js#L220)
The connection specific error which triggered this one The connection specific error which triggered this one
*** ***
<a name="connectionrefusederror"></a> <a name="connectionrefusederror"></a>
## `new ConnectionRefusedError()` ## `new ConnectionRefusedError()`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/errors.js#L230) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/errors.js#L230)
Thrown when a connection to a database is refused Thrown when a connection to a database is refused
__Extends:__ ConnectionError __Extends:__ ConnectionError
...@@ -190,7 +190,7 @@ __Extends:__ ConnectionError ...@@ -190,7 +190,7 @@ __Extends:__ ConnectionError
<a name="accessdeniederror"></a> <a name="accessdeniederror"></a>
## `new AccessDeniedError()` ## `new AccessDeniedError()`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/errors.js#L241) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/errors.js#L241)
Thrown when a connection to a database is refused due to insufficient privileges Thrown when a connection to a database is refused due to insufficient privileges
__Extends:__ ConnectionError __Extends:__ ConnectionError
...@@ -199,7 +199,7 @@ __Extends:__ ConnectionError ...@@ -199,7 +199,7 @@ __Extends:__ ConnectionError
<a name="hostnotfounderror"></a> <a name="hostnotfounderror"></a>
## `new HostNotFoundError()` ## `new HostNotFoundError()`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/errors.js#L252) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/errors.js#L252)
Thrown when a connection to a database has a hostname that was not found Thrown when a connection to a database has a hostname that was not found
__Extends:__ ConnectionError __Extends:__ ConnectionError
...@@ -208,7 +208,7 @@ __Extends:__ ConnectionError ...@@ -208,7 +208,7 @@ __Extends:__ ConnectionError
<a name="hostnotreachableerror"></a> <a name="hostnotreachableerror"></a>
## `new HostNotReachableError()` ## `new HostNotReachableError()`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/errors.js#L263) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/errors.js#L263)
Thrown when a connection to a database has a hostname that was not reachable Thrown when a connection to a database has a hostname that was not reachable
__Extends:__ ConnectionError __Extends:__ ConnectionError
...@@ -217,7 +217,7 @@ __Extends:__ ConnectionError ...@@ -217,7 +217,7 @@ __Extends:__ ConnectionError
<a name="invalidconnectionerror"></a> <a name="invalidconnectionerror"></a>
## `new InvalidConnectionError()` ## `new InvalidConnectionError()`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/errors.js#L274) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/errors.js#L274)
Thrown when a connection to a database has invalid values for any of the connection parameters Thrown when a connection to a database has invalid values for any of the connection parameters
__Extends:__ ConnectionError __Extends:__ ConnectionError
...@@ -226,7 +226,7 @@ __Extends:__ ConnectionError ...@@ -226,7 +226,7 @@ __Extends:__ ConnectionError
<a name="connectiontimedouterror"></a> <a name="connectiontimedouterror"></a>
## `new ConnectionTimedOutError()` ## `new ConnectionTimedOutError()`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/errors.js#L285) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/errors.js#L285)
Thrown when a connection to a database times out Thrown when a connection to a database times out
__Extends:__ ConnectionError __Extends:__ ConnectionError
......
<a name="hooks"></a> <a name="hooks"></a>
# Mixin Hooks # Mixin Hooks
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/hooks.js#L39) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/hooks.js#L39)
Hooks are function that are called before and after (bulk-) creation/updating/deletion and validation. Hooks can be added to you models in three ways: Hooks are function that are called before and after (bulk-) creation/updating/deletion and validation. Hooks can be added to you models in three ways:
1. By specifying them as options in `sequelize.define` 1. By specifying them as options in `sequelize.define`
...@@ -38,7 +38,7 @@ Model.afterBulkUpdate(function () {}) ...@@ -38,7 +38,7 @@ Model.afterBulkUpdate(function () {})
<a name="addhook"></a> <a name="addhook"></a>
## `addHook(hooktype, [name], fn)` ## `addHook(hooktype, [name], fn)`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/hooks.js#L152) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/hooks.js#L152)
Add a hook to the model Add a hook to the model
...@@ -56,7 +56,7 @@ __Aliases:__ hook ...@@ -56,7 +56,7 @@ __Aliases:__ hook
<a name="hashook"></a> <a name="hashook"></a>
## `hasHook(hookType)` ## `hasHook(hookType)`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/hooks.js#L172) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/hooks.js#L172)
Check whether the mode has any hooks of this type Check whether the mode has any hooks of this type
...@@ -72,7 +72,7 @@ __Aliases:__ hasHooks ...@@ -72,7 +72,7 @@ __Aliases:__ hasHooks
<a name="beforevalidate"></a> <a name="beforevalidate"></a>
## `beforeValidate(name, fn)` ## `beforeValidate(name, fn)`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/hooks.js#L185) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/hooks.js#L185)
A hook that is run before validation A hook that is run before validation
**Params:** **Params:**
...@@ -87,7 +87,7 @@ A hook that is run before validation ...@@ -87,7 +87,7 @@ A hook that is run before validation
<a name="aftervalidate"></a> <a name="aftervalidate"></a>
## `afterValidate(name, fn)` ## `afterValidate(name, fn)`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/hooks.js#L192) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/hooks.js#L192)
A hook that is run after validation A hook that is run after validation
**Params:** **Params:**
...@@ -102,7 +102,7 @@ A hook that is run after validation ...@@ -102,7 +102,7 @@ A hook that is run after validation
<a name="beforecreate"></a> <a name="beforecreate"></a>
## `beforeCreate(name, fn)` ## `beforeCreate(name, fn)`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/hooks.js#L199) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/hooks.js#L199)
A hook that is run before creating a single instance A hook that is run before creating a single instance
**Params:** **Params:**
...@@ -117,7 +117,7 @@ A hook that is run before creating a single instance ...@@ -117,7 +117,7 @@ A hook that is run before creating a single instance
<a name="aftercreate"></a> <a name="aftercreate"></a>
## `afterCreate(name, fn)` ## `afterCreate(name, fn)`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/hooks.js#L206) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/hooks.js#L206)
A hook that is run after creating a single instance A hook that is run after creating a single instance
**Params:** **Params:**
...@@ -132,7 +132,7 @@ A hook that is run after creating a single instance ...@@ -132,7 +132,7 @@ A hook that is run after creating a single instance
<a name="beforedestroy"></a> <a name="beforedestroy"></a>
## `beforeDestroy(name, fn)` ## `beforeDestroy(name, fn)`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/hooks.js#L215) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/hooks.js#L215)
A hook that is run before destroying a single instance A hook that is run before destroying a single instance
**Params:** **Params:**
...@@ -148,7 +148,7 @@ __Aliases:__ beforeDelete ...@@ -148,7 +148,7 @@ __Aliases:__ beforeDelete
<a name="afterdestroy"></a> <a name="afterdestroy"></a>
## `afterDestroy(name, fn)` ## `afterDestroy(name, fn)`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/hooks.js#L224) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/hooks.js#L224)
A hook that is run after destroying a single instance A hook that is run after destroying a single instance
**Params:** **Params:**
...@@ -164,7 +164,7 @@ __Aliases:__ afterDelete ...@@ -164,7 +164,7 @@ __Aliases:__ afterDelete
<a name="beforeupdate"></a> <a name="beforeupdate"></a>
## `beforeUpdate(name, fn)` ## `beforeUpdate(name, fn)`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/hooks.js#L231) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/hooks.js#L231)
A hook that is run before updating a single instance A hook that is run before updating a single instance
**Params:** **Params:**
...@@ -179,7 +179,7 @@ A hook that is run before updating a single instance ...@@ -179,7 +179,7 @@ A hook that is run before updating a single instance
<a name="afterupdate"></a> <a name="afterupdate"></a>
## `afterUpdate(name, fn)` ## `afterUpdate(name, fn)`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/hooks.js#L238) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/hooks.js#L238)
A hook that is run after updating a single instance A hook that is run after updating a single instance
**Params:** **Params:**
...@@ -194,7 +194,7 @@ A hook that is run after updating a single instance ...@@ -194,7 +194,7 @@ A hook that is run after updating a single instance
<a name="beforebulkcreate"></a> <a name="beforebulkcreate"></a>
## `beforeBulkCreate(name, fn)` ## `beforeBulkCreate(name, fn)`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/hooks.js#L245) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/hooks.js#L245)
A hook that is run before creating instances in bulk A hook that is run before creating instances in bulk
**Params:** **Params:**
...@@ -209,7 +209,7 @@ A hook that is run before creating instances in bulk ...@@ -209,7 +209,7 @@ A hook that is run before creating instances in bulk
<a name="afterbulkcreate"></a> <a name="afterbulkcreate"></a>
## `afterBulkCreate(name, fn)` ## `afterBulkCreate(name, fn)`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/hooks.js#L252) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/hooks.js#L252)
A hook that is run after creating instances in bulk A hook that is run after creating instances in bulk
**Params:** **Params:**
...@@ -224,7 +224,7 @@ A hook that is run after creating instances in bulk ...@@ -224,7 +224,7 @@ A hook that is run after creating instances in bulk
<a name="beforebulkdestroy"></a> <a name="beforebulkdestroy"></a>
## `beforeBulkDestroy(name, fn)` ## `beforeBulkDestroy(name, fn)`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/hooks.js#L261) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/hooks.js#L261)
A hook that is run before destroying instances in bulk A hook that is run before destroying instances in bulk
**Params:** **Params:**
...@@ -240,7 +240,7 @@ __Aliases:__ beforeBulkDelete ...@@ -240,7 +240,7 @@ __Aliases:__ beforeBulkDelete
<a name="afterbulkdestroy"></a> <a name="afterbulkdestroy"></a>
## `afterBulkDestroy(name, fn)` ## `afterBulkDestroy(name, fn)`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/hooks.js#L270) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/hooks.js#L270)
A hook that is run after destroying instances in bulk A hook that is run after destroying instances in bulk
**Params:** **Params:**
...@@ -256,7 +256,7 @@ __Aliases:__ afterBulkDelete ...@@ -256,7 +256,7 @@ __Aliases:__ afterBulkDelete
<a name="beforebulkupdate"></a> <a name="beforebulkupdate"></a>
## `beforeBulkUpdate(name, fn)` ## `beforeBulkUpdate(name, fn)`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/hooks.js#L277) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/hooks.js#L277)
A hook that is run after updating instances in bulk A hook that is run after updating instances in bulk
**Params:** **Params:**
...@@ -271,7 +271,7 @@ A hook that is run after updating instances in bulk ...@@ -271,7 +271,7 @@ A hook that is run after updating instances in bulk
<a name="afterbulkupdate"></a> <a name="afterbulkupdate"></a>
## `afterBulkUpdate(name, fn)` ## `afterBulkUpdate(name, fn)`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/hooks.js#L284) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/hooks.js#L284)
A hook that is run after updating instances in bulk A hook that is run after updating instances in bulk
**Params:** **Params:**
...@@ -286,7 +286,7 @@ A hook that is run after updating instances in bulk ...@@ -286,7 +286,7 @@ A hook that is run after updating instances in bulk
<a name="beforefind"></a> <a name="beforefind"></a>
## `beforeFind(name, fn)` ## `beforeFind(name, fn)`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/hooks.js#L291) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/hooks.js#L291)
A hook that is run before a find (select) query A hook that is run before a find (select) query
**Params:** **Params:**
...@@ -301,7 +301,7 @@ A hook that is run before a find (select) query ...@@ -301,7 +301,7 @@ A hook that is run before a find (select) query
<a name="beforefindafterexpandincludeall"></a> <a name="beforefindafterexpandincludeall"></a>
## `beforeFindAfterExpandIncludeAll(name, fn)` ## `beforeFindAfterExpandIncludeAll(name, fn)`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/hooks.js#L298) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/hooks.js#L298)
A hook that is run before a find (select) query, after any { include: {all: ...} } options are expanded A hook that is run before a find (select) query, after any { include: {all: ...} } options are expanded
**Params:** **Params:**
...@@ -316,7 +316,7 @@ A hook that is run before a find (select) query, after any { include: {all: ...} ...@@ -316,7 +316,7 @@ A hook that is run before a find (select) query, after any { include: {all: ...}
<a name="beforefindafteroptions"></a> <a name="beforefindafteroptions"></a>
## `beforeFindAfterOptions(name, fn)` ## `beforeFindAfterOptions(name, fn)`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/hooks.js#L305) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/hooks.js#L305)
A hook that is run before a find (select) query, after all option parsing is complete A hook that is run before a find (select) query, after all option parsing is complete
**Params:** **Params:**
...@@ -331,7 +331,7 @@ A hook that is run before a find (select) query, after all option parsing is com ...@@ -331,7 +331,7 @@ A hook that is run before a find (select) query, after all option parsing is com
<a name="afterfind"></a> <a name="afterfind"></a>
## `afterFind(name, fn)` ## `afterFind(name, fn)`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/hooks.js#L312) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/hooks.js#L312)
A hook that is run after a find (select) query A hook that is run after a find (select) query
**Params:** **Params:**
...@@ -346,7 +346,7 @@ A hook that is run after a find (select) query ...@@ -346,7 +346,7 @@ A hook that is run after a find (select) query
<a name="beforedefine"></a> <a name="beforedefine"></a>
## `beforeDefine(name, fn)` ## `beforeDefine(name, fn)`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/hooks.js#L319) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/hooks.js#L319)
A hook that is run before a define call A hook that is run before a define call
**Params:** **Params:**
...@@ -361,7 +361,7 @@ A hook that is run before a define call ...@@ -361,7 +361,7 @@ A hook that is run before a define call
<a name="afterdefine"></a> <a name="afterdefine"></a>
## `afterDefine(name, fn)` ## `afterDefine(name, fn)`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/hooks.js#L326) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/hooks.js#L326)
A hook that is run after a define call A hook that is run after a define call
**Params:** **Params:**
...@@ -376,7 +376,7 @@ A hook that is run after a define call ...@@ -376,7 +376,7 @@ A hook that is run after a define call
<a name="beforeinit"></a> <a name="beforeinit"></a>
## `beforeInit(name, fn)` ## `beforeInit(name, fn)`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/hooks.js#L333) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/hooks.js#L333)
A hook that is run before Sequelize() call A hook that is run before Sequelize() call
**Params:** **Params:**
...@@ -391,7 +391,7 @@ A hook that is run before Sequelize() call ...@@ -391,7 +391,7 @@ A hook that is run before Sequelize() call
<a name="afterinit"></a> <a name="afterinit"></a>
## `afterInit` ## `afterInit`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/hooks.js#L341) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/hooks.js#L341)
A hook that is run after Sequelize() call A hook that is run after Sequelize() call
**Params:** **Params:**
......
<a name="transaction"></a> <a name="transaction"></a>
# Class Transaction # Class Transaction
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/transaction.js#L11) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/transaction.js#L18)
The transaction object is used to identify a running transaction. It is created by calling `Sequelize.transaction()`. The transaction object is used to identify a running transaction. It is created by calling `Sequelize.transaction()`.
To run a query under a transaction, you should pass the transaction in the options object. To run a query under a transaction, you should pass the transaction in the options object.
**Params:**
| Name | Type | Description |
| ---- | ---- | ----------- |
| sequelize | Sequelize | A configured sequelize Instance |
| options | Object | An object with options |
| options.autocommit=true | Boolean | Sets the autocommit property of the transaction. |
| options.isolationLevel=true | String | Sets the isolation level of the transaction. |
| options.deferrable | String | Sets the constraints to be deferred or immediately checked. |
*** ***
<a name="isolation_levels"></a> <a name="isolation_levels"></a>
## `ISOLATION_LEVELS` ## `ISOLATION_LEVELS`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/transaction.js#L46) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/transaction.js#L53)
The possible isolations levels to use when starting a transaction. The possible isolations levels to use when starting a transaction.
Can be set per-transaction by passing `options.isolationLevel` to `sequelize.transaction`. Can be set per-transaction by passing `options.isolationLevel` to `sequelize.transaction`.
Default to `REPEATABLE_READ` but you can override the default isolation level by passing `options.isolationLevel` in `new Sequelize`. Default to `REPEATABLE_READ` but you can override the default isolation level by passing `options.isolationLevel` in `new Sequelize`.
...@@ -28,7 +39,7 @@ Default to `REPEATABLE_READ` but you can override the default isolation level by ...@@ -28,7 +39,7 @@ Default to `REPEATABLE_READ` but you can override the default isolation level by
<a name="lock"></a> <a name="lock"></a>
## `LOCK` ## `LOCK`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/transaction.js#L90) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/transaction.js#L97)
Possible options for row locking. Used in conjuction with `find` calls: Possible options for row locking. Used in conjuction with `find` calls:
```js ```js
...@@ -68,7 +79,7 @@ UserModel will be locked but TaskModel won't! ...@@ -68,7 +79,7 @@ UserModel will be locked but TaskModel won't!
<a name="commit"></a> <a name="commit"></a>
## `commit()` -> `this` ## `commit()` -> `this`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/transaction.js#L102) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/transaction.js#L109)
Commit the transaction Commit the transaction
...@@ -76,7 +87,7 @@ Commit the transaction ...@@ -76,7 +87,7 @@ Commit the transaction
<a name="rollback"></a> <a name="rollback"></a>
## `rollback()` -> `this` ## `rollback()` -> `this`
[View code](https://github.com/sequelize/sequelize/blob/716cb2d2aae3a4cd7fdaace13411cf4161e6deb6/lib/transaction.js#L123) [View code](https://github.com/sequelize/sequelize/blob/2dc7a0f610480e045a412d215d7247912158407d/lib/transaction.js#L130)
Rollback (abort) the transaction Rollback (abort) the transaction
......
...@@ -27,7 +27,8 @@ if (program.file) { ...@@ -27,7 +27,8 @@ if (program.file) {
{file:'lib/associations/mixin.js', output: 'associations'}, {file:'lib/associations/mixin.js', output: 'associations'},
{file:'lib/promise.js', output: 'promise'}, {file:'lib/promise.js', output: 'promise'},
{file:'lib/transaction.js', output: 'transaction'}, {file:'lib/transaction.js', output: 'transaction'},
{file:'lib/data-types.js', output: 'datatypes'} {file:'lib/data-types.js', output: 'datatypes'},
{file:'lib/deferrable.js', output: 'deferrable'}
]; ];
} }
......
...@@ -48,7 +48,23 @@ var Foo = sequelize.define('Foo', { ...@@ -48,7 +48,23 @@ var Foo = sequelize.define('Foo', {
hasComment: { type: Sequelize.INTEGER, comment: "I'm a comment!" }, hasComment: { type: Sequelize.INTEGER, comment: "I'm a comment!" },
// You can specify a custom field name via the "field" attribute: // You can specify a custom field name via the "field" attribute:
fieldWithUnderscores: { type: Sequelize.STRING, field: "field_with_underscores" } fieldWithUnderscores: { type: Sequelize.STRING, field: "field_with_underscores" },
// It is possible to create foreign keys:
bar_id: {
type: Sequelize.INTEGER,
references: {
// This is a reference to another model
model: Bar,
// This is the column name of the referenced model
key: 'id',
// This declares when to check the foreign key constraint. PostgreSQL only.
deferrable: Sequelize.Deferrable.INITIALLY_IMMEDIATE
}
}
}) })
``` ```
...@@ -134,6 +150,25 @@ sequelize.define('model', { ...@@ -134,6 +150,25 @@ sequelize.define('model', {
}) })
``` ```
## Deferrable
When you specify a foreign key column it is optionally possible to declare the deferrable
type in PostgreSQL. The following options are available:
```js
// Defer all foreign key constraint check to the end of a transaction
Sequelize.Deferrable.INITIALLY_DEFERRED
// Immediately check the foreign key constraints
Sequelize.Deferrable.INITIALLY_IMMEDIATE
// Don't defer the checks at all
Sequelize.Deferrable.NOT
```
The last option is the default in PostgreSQL and won't allow you to dynamically change
the rule in a transaction. See [the transaction section](docs/transactions/#options) for further information.
## Getters & setters ## Getters & setters
It is possible to define 'object-property' getters and setter functions on your models, these can be used both for 'protecting' properties that map to database fields and for defining 'pseudo' properties. It is possible to define 'object-property' getters and setter functions on your models, these can be used both for 'protecting' properties that map to database fields and for defining 'pseudo' properties.
......
...@@ -110,7 +110,7 @@ return sequelize.transaction().then(function (t) { ...@@ -110,7 +110,7 @@ return sequelize.transaction().then(function (t) {
return user.addSibling({ return user.addSibling({
firstName: 'Lisa', firstName: 'Lisa',
lastName: 'Simpson' lastName: 'Simpson'
}, {transction: t}); }, {transaction: t});
}).then(function () { }).then(function () {
t.commit(); t.commit();
}).catch(function (err) { }).catch(function (err) {
...@@ -119,7 +119,57 @@ return sequelize.transaction().then(function (t) { ...@@ -119,7 +119,57 @@ return sequelize.transaction().then(function (t) {
}); });
``` ```
# Using transactions with other sequelize methods # Options
The `transaction` method can be called with an options object as the first argument, that
allows the configuration of the transaction.
```js
return sequelize.transaction({ /* options */ });
```
The following options (with it's default values) are available:
```js
{
autocommit: true,
isolationLevel: 'REPEATABLE_READ',
deferrable: 'NOT DEFERRABLE' // implicit default of postgres
}
```
The `isolationLevel` can either be set globally when initializing the Sequelize instance or
locally for every transaction:
```js
// globally
new Sequelize('db', 'user', 'pw', {
isolationLevel: Sequelize.Transaction.ISOLATION_LEVELS.SERIALIZABLE
});
// locally
sequelize.transaction({
isolationLevel: Sequelize.Transaction.ISOLATION_LEVELS.SERIALIZABLE
});
```
The `deferrable` option triggers an additional query after the transaction start
that optionally set the constraint checks to be deferred or immediate. Please note
that this is only supported in PostgreSQL.
```js
sequelize.transaction({
// to defer all constraints:
deferrable: Sequelize.Deferrable.SET_DEFERRED,
// to defer a specific constraint:
deferrable: Sequelize.Deferrable.SET_DEFERRED(['some_constraint']),
// to not defer constraints:
deferrable: Sequelize.Deferrable.SET_IMMEDIATE
})
```
# Usage with other sequelize methods
The `transaction` option goes with most other options, which are usually the first argument of a method. The `transaction` option goes with most other options, which are usually the first argument of a method.
For methods that take values, like `.create`, `.update()`, `.updateAttributes()` etc. `transaction` should be passed to the option in the second argument. For methods that take values, like `.create`, `.update()`, `.updateAttributes()` etc. `transaction` should be passed to the option in the second argument.
......
'use strict';
var util = require('util');
/**
* A collection of properties related to deferrable constraints. It can be used to
* make foreign key constraints deferrable and to set the constaints within a
* transaction. This is only supported in PostgreSQL.
*
* The foreign keys can be configured like this. It will create a foreign key
* that will check the constraints immediately when the data was inserted.
*
* ```js
* sequelize.define('Model', {
* foreign_id: {
* type: Sequelize.INTEGER,
* references: {
* model: OtherModel,
* key: 'id',
* deferrable: Sequelize.Deferrable.INITIALLY_IMMEDIATE
* }
* }
* });
* ```
*
* The constraints can be configured in a transaction like this. It will
* trigger a query once the transaction has been started and set the constraints
* to be checked at the very end of the transaction.
*
* ```js
* sequelize.transaction({
* deferrable: Sequelize.Deferrable.SET_DEFERRED
* });
* ```
*
* @return {object}
*/
var Deferrable = module.exports = {
INITIALLY_DEFERRED: INITIALLY_DEFERRED,
INITIALLY_IMMEDIATE: INITIALLY_IMMEDIATE,
NOT: NOT,
SET_DEFERRED: SET_DEFERRED,
SET_IMMEDIATE: SET_IMMEDIATE
};
function ABSTRACT () {}
ABSTRACT.prototype.toString = function () {
return this.toSql.apply(this, arguments);
};
/**
* A property that will defer constraints checks to the end of transactions.
*
* @property INITIALLY_DEFERRED
*/
function INITIALLY_DEFERRED () {
if (!(this instanceof INITIALLY_DEFERRED)) {
return new INITIALLY_DEFERRED();
}
}
util.inherits(INITIALLY_DEFERRED, ABSTRACT);
INITIALLY_DEFERRED.prototype.toSql = function () {
return 'DEFERRABLE INITIALLY DEFERRED';
};
/**
* A property that will trigger the constraint checks immediately
*
* @property INITIALLY_IMMEDIATE
*/
function INITIALLY_IMMEDIATE () {
if (!(this instanceof INITIALLY_IMMEDIATE)) {
return new INITIALLY_IMMEDIATE();
}
}
util.inherits(INITIALLY_IMMEDIATE, ABSTRACT);
INITIALLY_IMMEDIATE.prototype.toSql = function () {
return 'DEFERRABLE INITIALLY IMMEDIATE';
};
/**
* A property that will set the constraints to not deferred. This is
* the default in PostgreSQL and it make it impossible to dynamically
* defer the constraints within a transaction.
*
* @property NOT
*/
function NOT () {
if (!(this instanceof NOT)) {
return new NOT();
}
}
util.inherits(NOT, ABSTRACT);
NOT.prototype.toSql = function () {
return 'NOT DEFERRABLE';
};
/**
* A property that will trigger an additional query at the beginning of a
* transaction which sets the constraints to deferred.
*
* @param {Array} constraints An array of constraint names. Will defer all constraints by default.
* @property SET_DEFERRED
*/
function SET_DEFERRED (constraints) {
if (!(this instanceof SET_DEFERRED)) {
return new SET_DEFERRED(constraints);
}
this.constraints = constraints;
}
util.inherits(SET_DEFERRED, ABSTRACT);
SET_DEFERRED.prototype.toSql = function (queryGenerator) {
return queryGenerator.setDeferredQuery(this.constraints);
};
/**
* A property that will trigger an additional query at the beginning of a
* transaction which sets the constraints to immediately.
*
* @param {Array} constraints An array of constraint names. Will defer all constraints by default.
* @property SET_IMMEDIATE
*/
function SET_IMMEDIATE (constraints) {
if (!(this instanceof SET_IMMEDIATE)) {
return new SET_IMMEDIATE(constraints);
}
this.constraints = constraints;
}
util.inherits(SET_IMMEDIATE, ABSTRACT);
SET_IMMEDIATE.prototype.toSql = function (queryGenerator) {
return queryGenerator.setImmediateQuery(this.constraints);
};
Object.keys(Deferrable).forEach(function (key) {
var DeferrableType = Deferrable[key];
DeferrableType.toString = function () {
var instance = new DeferrableType();
return instance.toString.apply(instance, arguments);
};
});
...@@ -48,6 +48,7 @@ AbstractDialect.prototype.supports = { ...@@ -48,6 +48,7 @@ AbstractDialect.prototype.supports = {
joinTableDependent: true, joinTableDependent: true,
indexViaAlter: false, indexViaAlter: false,
JSON: false, JSON: false,
deferrableConstraints: false
}; };
module.exports = AbstractDialect; module.exports = AbstractDialect;
...@@ -1476,6 +1476,19 @@ module.exports = (function() { ...@@ -1476,6 +1476,19 @@ module.exports = (function() {
}, },
/** /**
* Returns a query that defers the constraints. Only works for postgres.
*
* @param {Transaction} transaction
* @param {Object} options An object with options.
* @return {String} The generated sql query.
*/
deferConstraintsQuery: function () {},
setConstraintQuery: function () {},
setDeferredQuery: function () {},
setImmediateQuery: function () {},
/**
* Returns a query that commits a transaction. * Returns a query that commits a transaction.
* *
* @param {Object} options An object with options. * @param {Object} options An object with options.
......
...@@ -44,7 +44,8 @@ PostgresDialect.prototype.supports = _.merge(_.cloneDeep(Abstract.prototype.supp ...@@ -44,7 +44,8 @@ PostgresDialect.prototype.supports = _.merge(_.cloneDeep(Abstract.prototype.supp
NUMERIC: true, NUMERIC: true,
ARRAY: true, ARRAY: true,
JSON: true, JSON: true,
JSONB: true JSONB: true,
deferrableConstraints: true
}); });
PostgresDialect.prototype.Query = Query; PostgresDialect.prototype.Query = Query;
......
...@@ -529,11 +529,40 @@ module.exports = (function() { ...@@ -529,11 +529,40 @@ module.exports = (function() {
template += ' ON UPDATE <%= onUpdateAction %>'; template += ' ON UPDATE <%= onUpdateAction %>';
replacements.onUpdateAction = attribute.onUpdate.toUpperCase(); replacements.onUpdateAction = attribute.onUpdate.toUpperCase();
} }
if (attribute.references.deferrable) {
template += ' <%= deferrable %>';
replacements.deferrable = attribute.references.deferrable.toString(this);
}
} }
return Utils._.template(template)(replacements); return Utils._.template(template)(replacements);
}, },
deferConstraintsQuery: function (options) {
return options.deferrable.toString(this);
},
setConstraintQuery: function (columns, type) {
var columnFragment = 'ALL';
if (columns) {
columnFragment = columns.map(function (column) {
return this.quoteIdentifier(column);
}.bind(this)).join(', ');
}
return 'SET CONSTRAINTS ' + columnFragment + ' ' + type;
},
setDeferredQuery: function (columns) {
return this.setConstraintQuery(columns, 'DEFERRED');
},
setImmediateQuery: function (columns) {
return this.setConstraintQuery(columns, 'IMMEDIATE');
},
attributesToSQL: function(attributes, options) { attributesToSQL: function(attributes, options) {
var result = {} var result = {}
, key , key
......
...@@ -880,6 +880,21 @@ module.exports = (function() { ...@@ -880,6 +880,21 @@ module.exports = (function() {
return this.sequelize.query(sql, options); return this.sequelize.query(sql, options);
}; };
QueryInterface.prototype.deferConstraints = function (transaction, options) {
options = Utils._.extend({
transaction: transaction,
parent: options.transaction
}, options || {});
var sql = this.QueryGenerator.deferConstraintsQuery(options);
if (sql) {
return this.sequelize.query(sql, options);
}
return Promise.resolve();
};
QueryInterface.prototype.commitTransaction = function(transaction, options) { QueryInterface.prototype.commitTransaction = function(transaction, options) {
if (!transaction || !(transaction instanceof Transaction)) { if (!transaction || !(transaction instanceof Transaction)) {
throw new Error('Unable to commit a transaction without transaction object!'); throw new Error('Unable to commit a transaction without transaction object!');
......
...@@ -5,6 +5,7 @@ var url = require('url') ...@@ -5,6 +5,7 @@ var url = require('url')
, Utils = require('./utils') , Utils = require('./utils')
, Model = require('./model') , Model = require('./model')
, DataTypes = require('./data-types') , DataTypes = require('./data-types')
, Deferrable = require('./deferrable')
, ModelManager = require('./model-manager') , ModelManager = require('./model-manager')
, QueryInterface = require('./query-interface') , QueryInterface = require('./query-interface')
, Transaction = require('./transaction') , Transaction = require('./transaction')
...@@ -263,6 +264,14 @@ module.exports = (function() { ...@@ -263,6 +264,14 @@ module.exports = (function() {
Sequelize.prototype.Transaction = Sequelize.Transaction = Transaction; Sequelize.prototype.Transaction = Sequelize.Transaction = Transaction;
/** /**
* A reference to the deferrable collection. Use this to access the different deferrable options.
* @property Deferrable
* @see {Deferrable}
* @see {Sequelize#transaction}
*/
Sequelize.prototype.Deferrable = Sequelize.Deferrable = Deferrable;
/**
* A reference to the sequelize instance class. * A reference to the sequelize instance class.
* @property Instance * @property Instance
* @see {Instance} * @see {Instance}
......
...@@ -7,6 +7,13 @@ var Utils = require('./utils'); ...@@ -7,6 +7,13 @@ var Utils = require('./utils');
* *
* To run a query under a transaction, you should pass the transaction in the options object. * To run a query under a transaction, you should pass the transaction in the options object.
* @class Transaction * @class Transaction
* @constructor
*
* @param {Sequelize} sequelize A configured sequelize Instance
* @param {Object} options An object with options
* @param {Boolean} options.autocommit=true Sets the autocommit property of the transaction.
* @param {String} options.isolationLevel=true Sets the isolation level of the transaction.
* @param {String} options.deferrable Sets the constraints to be deferred or immediately checked.
*/ */
var Transaction = module.exports = function(sequelize, options) { var Transaction = module.exports = function(sequelize, options) {
this.sequelize = sequelize; this.sequelize = sequelize;
...@@ -150,6 +157,8 @@ Transaction.prototype.prepareEnvironment = function() { ...@@ -150,6 +157,8 @@ Transaction.prototype.prepareEnvironment = function() {
}).then(function () { }).then(function () {
return self.begin(); return self.begin();
}).then(function () { }).then(function () {
return self.setDeferrable();
}).then(function () {
return self.setIsolationLevel(); return self.setIsolationLevel();
}).then(function () { }).then(function () {
return self.setAutocommit(); return self.setAutocommit();
...@@ -163,6 +172,15 @@ Transaction.prototype.begin = function() { ...@@ -163,6 +172,15 @@ Transaction.prototype.begin = function() {
.startTransaction(this, this.options); .startTransaction(this, this.options);
}; };
Transaction.prototype.setDeferrable = function () {
if (this.options.deferrable) {
return this
.sequelize
.getQueryInterface()
.deferConstraints(this, this.options);
}
};
Transaction.prototype.setAutocommit = function() { Transaction.prototype.setAutocommit = function() {
return this return this
.sequelize .sequelize
......
...@@ -406,8 +406,9 @@ var Utils = module.exports = { ...@@ -406,8 +406,9 @@ var Utils = module.exports = {
formatReferences: function (obj) { formatReferences: function (obj) {
if (!_.isPlainObject(obj.references)) { if (!_.isPlainObject(obj.references)) {
deprecate('Non-object references property found. Support for that will be removed in version 4. Expected { references: { model: "value", key: "key" } } instead of { references: "value", referencesKey: "key" }.'); deprecate('Non-object references property found. Support for that will be removed in version 4. Expected { references: { model: "value", key: "key" } } instead of { references: "value", referencesKey: "key" }.');
obj.references = { model: obj.references, key: obj.referencesKey }; obj.references = { model: obj.references, key: obj.referencesKey, deferrable: obj.referencesDeferrable };
obj.referencesKey = undefined; obj.referencesKey = undefined;
obj.referencesDeferrable = undefined;
} }
return obj; return obj;
......
...@@ -36,8 +36,8 @@ pages: ...@@ -36,8 +36,8 @@ pages:
- ['api/promise.md', 'API', 'Promise'] - ['api/promise.md', 'API', 'Promise']
- ['api/transaction.md', 'API', 'Transaction'] - ['api/transaction.md', 'API', 'Transaction']
- ['api/datatypes.md', 'API', 'Datatypes'] - ['api/datatypes.md', 'API', 'Datatypes']
- ['api/deferrable.md', 'API', 'Deferrable']
- ['api/errors.md', 'API', 'Errors'] - ['api/errors.md', 'API', 'Errors']
- ['changelog.md', 'Misc', 'Changelog'] - ['changelog.md', 'Misc', 'Changelog']
- ['imprint.md', 'Misc', 'Imprint'] - ['imprint.md', 'Misc', 'Imprint']
'use strict';
/* jshint -W030 */
/* jshint -W110 */
var _ = require('lodash')
, chai = require('chai')
, expect = chai.expect
, Support = require(__dirname + '/../support')
, Sequelize = require(__dirname + '/../../../index')
, config = require(__dirname + '/../../config/config')
;
if (!Support.sequelize.dialect.supports.deferrableConstraints) {
return;
}
describe(Support.getTestDialectTeaser('Sequelize'), function() {
beforeEach(function () {
this.run = function (deferrable, options) {
options = options || {};
var taskTableName = options.taskTableName || 'tasks_' + config.rand();
var transactionOptions = _.extend({ deferrable: Sequelize.Deferrable.SET_DEFERRED }, options);
var userTableName = 'users_' + config.rand();
var User = this.sequelize.define(
'User', { name: Sequelize.STRING }, { tableName: userTableName }
);
var Task = this.sequelize.define(
'Task', {
title: Sequelize.STRING,
user_id: {
allowNull: false,
type: Sequelize.INTEGER,
references: {
model: userTableName,
key: 'id',
deferrable: deferrable
}
}
}, {
tableName: taskTableName
}
);
return User.sync({ force: true }).bind(this).then(function () {
return Task.sync({ force: true });
}).then(function () {
return this.sequelize.transaction(transactionOptions, function (t) {
return Task
.create({ title: 'a task', user_id: -1 }, { transaction: t })
.then(function (task) {
return [task, User.create({}, { transaction: t })];
})
.spread(function (task, user) {
task.user_id = user.id;
return task.save({ transaction: t });
});
});
});
};
});
describe('Deferrable', function () {
describe('NOT', function () {
it('does not allow the violation of the foreign key constraint', function () {
return expect(this.run(Sequelize.Deferrable.NOT)).to.eventually.be.rejectedWith(Sequelize.ForeignKeyConstraintError);
});
});
describe('INITIALLY_IMMEDIATE', function () {
it('allows the violation of the foreign key constraint if the transaction is deferred', function () {
return this
.run(Sequelize.Deferrable.INITIALLY_IMMEDIATE)
.then(function (task) {
expect(task.title).to.equal('a task');
expect(task.user_id).to.equal(1);
});
});
it('does not allow the violation of the foreign key constraint if the transaction is not deffered', function () {
return expect(this.run(Sequelize.Deferrable.INITIALLY_IMMEDIATE, {
deferrable: undefined
})).to.eventually.be.rejectedWith(Sequelize.ForeignKeyConstraintError);
});
it('allows the violation of the foreign key constraint if the transaction deferres only the foreign key constraint', function () {
var taskTableName = 'tasks_' + config.rand();
return this
.run(Sequelize.Deferrable.INITIALLY_IMMEDIATE, {
deferrable: Sequelize.Deferrable.SET_DEFERRED([taskTableName + '_user_id_fkey']),
taskTableName: taskTableName
})
.then(function (task) {
expect(task.title).to.equal('a task');
expect(task.user_id).to.equal(1);
});
});
});
describe('INITIALLY_DEFERRED', function () {
it('allows the violation of the foreign key constraint', function () {
return this
.run(Sequelize.Deferrable.INITIALLY_DEFERRED)
.then(function (task) {
expect(task.title).to.equal('a task');
expect(task.user_id).to.equal(1);
});
});
});
});
});
...@@ -10,10 +10,11 @@ var chai = require('chai') ...@@ -10,10 +10,11 @@ var chai = require('chai')
describe(Support.getTestDialectTeaser('Utils'), function() { describe(Support.getTestDialectTeaser('Utils'), function() {
describe('formatReferences', function () { describe('formatReferences', function () {
([ ([
[{referencesKey: 1}, {references: {model: undefined, key: 1}, referencesKey: undefined}], [{referencesKey: 1}, {references: {model: undefined, key: 1, deferrable: undefined}, referencesKey: undefined, referencesDeferrable: undefined}],
[{references: 'a'}, {references: {model: 'a', key: undefined}, referencesKey: undefined}], [{references: 'a'}, {references: {model: 'a', key: undefined, deferrable: undefined}, referencesKey: undefined, referencesDeferrable: undefined}],
[{references: 'a', referencesKey: 1}, {references: {model: 'a', key: 1}, referencesKey: undefined}], [{references: 'a', referencesKey: 1}, {references: {model: 'a', key: 1, deferrable: undefined}, referencesKey: undefined, referencesDeferrable: undefined}],
[{references: {model: 1}}, {references: {model: 1}}] [{references: {model: 1}}, {references: {model: 1}}],
[{references: 1, referencesKey: 2, referencesDeferrable: 3}, {references: {model: 1, key: 2, deferrable: 3}, referencesKey: undefined, referencesDeferrable: undefined}]
]).forEach(function (test) { ]).forEach(function (test) {
var input = test[0]; var input = test[0];
var output = test[1]; var output = test[1];
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!