pg-promise
Version:
PostgreSQL via promises
177 lines (156 loc) • 5.12 kB
JavaScript
;
/**
* @enum {Number}
* @alias isolationLevel
* @readonly
* @summary Transaction Isolation Level.
* @description
* The type is available from the {@link txMode} namespace.
*
* @see $[Transaction Isolation]
*/
var isolationLevel = {
/** Isolation level not specified. */
none: 0,
/** ISOLATION LEVEL SERIALIZABLE */
serializable: 1,
/** ISOLATION LEVEL REPEATABLE READ */
repeatableRead: 2,
/** ISOLATION LEVEL READ COMMITTED */
readCommitted: 3
// From the official documentation: http://www.postgresql.org/docs/9.5/static/sql-set-transaction.html
// The SQL standard defines one additional level, READ UNCOMMITTED. In PostgreSQL READ UNCOMMITTED is treated as READ COMMITTED.
// => skipping `READ UNCOMMITTED`.
};
Object.freeze(isolationLevel);
/**
* @constructor TransactionMode
* @description
* **Alternative Syntax:** `TransactionMode({tiLevel, readOnly, deferrable})` ⇒ {@link TransactionMode}
*
* Constructs a complete transaction-opening command, based on the parameters:
* - isolation level
* - access mode
* - deferrable mode
*
* The type is available from the {@link txMode} namespace.
*
* @param {isolationLevel|Object} [tiLevel]
* Transaction Isolation Level, or an object with parameters, if the alternative
* syntax is used.
*
* @param {Boolean} [readOnly]
* Sets transaction access mode based on the read-only flag:
* - `undefined` - access mode not specified (default)
* - `true` - access mode is set to `READ ONLY`
* - `false` - access mode is set to `READ WRITE`
*
* @param {Boolean} [deferrable]
* Sets transaction deferrable mode based on the boolean value:
* - `undefined` - deferrable mode not specified (default)
* - `true` - mode is set to `DEFERRABLE`
* - `false` - mode is set to `NOT DEFERRABLE`
*
* It is used only when `tiLevel`=`isolationLevel.serializable`
* and `readOnly`=`true`, or else it is ignored.
*
* @see $[BEGIN], {@link isolationLevel}
*
* @example
*
* var TransactionMode = pgp.txMode.TransactionMode;
* var isolationLevel = pgp.txMode.isolationLevel;
*
* // Create a reusable transaction mode (serializable + read-only + deferrable):
* var tmSRD = new TransactionMode({
* tiLevel: isolationLevel.serializable,
* readOnly: true,
* deferrable: true
* });
*
* function myTransaction() {
* return this.query("SELECT * FROM table");
* }
*
* myTransaction.txMode = tmSRD; // assign transaction mode;
*
* db.tx(myTransaction)
* .then(function() {
* // success;
* });
*
* // Instead of the default BEGIN, such transaction will initiate with:
*
* // BEGIN ISOLATION LEVEL SERIALIZABLE READ ONLY DEFERRABLE
*
*/
function TransactionMode(tiLevel, readOnly, deferrable) {
if (!(this instanceof TransactionMode)) {
return new TransactionMode(tiLevel, readOnly, deferrable);
}
if (tiLevel && typeof tiLevel === 'object') {
readOnly = tiLevel.readOnly;
deferrable = tiLevel.deferrable;
tiLevel = tiLevel.tiLevel;
}
var level, accessMode, deferrableMode, capBegin, begin = 'begin';
tiLevel = (tiLevel > 0) ? parseInt(tiLevel) : 0;
if (tiLevel > 0 && tiLevel < 4) {
var values = ['serializable', 'repeatable read', 'read committed'];
level = 'isolation level ' + values[tiLevel - 1];
}
if (readOnly) {
accessMode = 'read only';
} else {
if (readOnly !== undefined) {
accessMode = 'read write';
}
}
// From the official documentation: http://www.postgresql.org/docs/9.5/static/sql-set-transaction.html
// The DEFERRABLE transaction property has no effect unless the transaction is also SERIALIZABLE and READ ONLY
if (tiLevel === isolationLevel.serializable && readOnly) {
if (deferrable) {
deferrableMode = 'deferrable';
} else {
if (deferrable !== undefined) {
deferrableMode = 'not deferrable';
}
}
}
if (level) {
begin += ' ' + level;
}
if (accessMode) {
begin += ' ' + accessMode;
}
if (deferrableMode) {
begin += ' ' + deferrableMode;
}
capBegin = begin.toUpperCase();
this.begin = function (cap) {
return cap ? capBegin : begin;
};
}
/**
* @namespace txMode
* @description
* Transaction Mode namespace, available as `pgp.txMode`, before and after initializing the library.
*
* Extends the default `BEGIN` with Transaction Mode parameters:
* - isolation level
* - access mode
* - deferrable mode
*
* @property {TransactionMode} TransactionMode
* Automated Transaction Mode class
*
* @property {isolationLevel} isolationLevel
* Transaction Isolation Level enumerator
*
* @see $[BEGIN]
*/
module.exports = {
isolationLevel: isolationLevel,
TransactionMode: TransactionMode
};
Object.freeze(module.exports);