rittenhop-dev/versions/5.94.2/node_modules/knex/lib/dialects/mssql/transaction.js

177 lines
4.4 KiB
JavaScript
Raw Normal View History

2024-09-23 19:40:12 -04:00
const Transaction = require('../../execution/transaction');
const debug = require('debug')('knex:tx');
class Transaction_MSSQL extends Transaction {
begin(/** @type {import('tedious').Connection} */ conn) {
debug('transaction::begin id=%s', this.txid);
return new Promise((resolve, reject) => {
conn.beginTransaction(
(err) => {
if (err) {
debug(
'transaction::begin error id=%s message=%s',
this.txid,
err.message
);
return reject(err);
}
resolve();
},
this.outerTx ? this.txid : undefined,
nameToIsolationLevelEnum(this.isolationLevel)
);
}).then(this._resolver, this._rejecter);
}
savepoint(conn) {
debug('transaction::savepoint id=%s', this.txid);
return new Promise((resolve, reject) => {
conn.saveTransaction(
(err) => {
if (err) {
debug(
'transaction::savepoint id=%s message=%s',
this.txid,
err.message
);
return reject(err);
}
this.trxClient.emit('query', {
__knexUid: this.trxClient.__knexUid,
__knexTxId: this.trxClient.__knexTxId,
autogenerated: true,
sql: this.outerTx
? `SAVE TRANSACTION [${this.txid}]`
: `SAVE TRANSACTION`,
});
resolve();
},
this.outerTx ? this.txid : undefined
);
});
}
commit(conn, value) {
debug('transaction::commit id=%s', this.txid);
return new Promise((resolve, reject) => {
conn.commitTransaction(
(err) => {
if (err) {
debug(
'transaction::commit error id=%s message=%s',
this.txid,
err.message
);
return reject(err);
}
this._completed = true;
resolve(value);
},
this.outerTx ? this.txid : undefined
);
}).then(() => this._resolver(value), this._rejecter);
}
release(conn, value) {
return this._resolver(value);
}
rollback(conn, error) {
this._completed = true;
debug('transaction::rollback id=%s', this.txid);
return new Promise((_resolve, reject) => {
if (!conn.inTransaction) {
return reject(
error || new Error('Transaction rejected with non-error: undefined')
);
}
if (conn.state.name !== 'LoggedIn') {
return reject(
new Error(
"Can't rollback transaction. There is a request in progress"
)
);
}
conn.rollbackTransaction(
(err) => {
if (err) {
debug(
'transaction::rollback error id=%s message=%s',
this.txid,
err.message
);
}
reject(
err ||
error ||
new Error('Transaction rejected with non-error: undefined')
);
},
this.outerTx ? this.txid : undefined
);
}).catch((err) => {
if (!error && this.doNotRejectOnRollback) {
this._resolver();
return;
}
if (error) {
try {
err.originalError = error;
} catch (_err) {
// This is to handle https://github.com/knex/knex/issues/4128
}
}
this._rejecter(err);
});
}
rollbackTo(conn, error) {
return this.rollback(conn, error).then(
() =>
void this.trxClient.emit('query', {
__knexUid: this.trxClient.__knexUid,
__knexTxId: this.trxClient.__knexTxId,
autogenerated: true,
sql: `ROLLBACK TRANSACTION`,
})
);
}
}
module.exports = Transaction_MSSQL;
function nameToIsolationLevelEnum(level) {
if (!level) return;
level = level.toUpperCase().replace(' ', '_');
const knownEnum = isolationEnum[level];
if (!knownEnum) {
throw new Error(
`Unknown Isolation level, was expecting one of: ${JSON.stringify(
humanReadableKeys
)}`
);
}
return knownEnum;
}
// Based on: https://github.com/tediousjs/node-mssql/blob/master/lib/isolationlevel.js
const isolationEnum = {
READ_UNCOMMITTED: 0x01,
READ_COMMITTED: 0x02,
REPEATABLE_READ: 0x03,
SERIALIZABLE: 0x04,
SNAPSHOT: 0x05,
};
const humanReadableKeys = Object.keys(isolationEnum).map((key) =>
key.toLowerCase().replace('_', ' ')
);