UNPKG

orange-orm

Version:

Object Relational Mapper

97 lines (87 loc) 2.56 kB
const log = require('../table/log'); const replaceParamChar = require('../pg/replaceParamChar'); const tryGetSessionContext = require('../table/tryGetSessionContext'); function wrapQuery(context, connection) { return runQuery; async function runQuery(query, onCompleted) { try { const sql = replaceParamChar(query, query.parameters); let rdb = tryGetSessionContext(context); let transactionHandler = rdb.transactionHandler; log.emitQuery({ sql, parameters: query.parameters }); if (sql.length < 18 && query.parameters.length === 0) { if (sql === 'BEGIN TRANSACTION' || sql === 'BEGIN') { if (transactionHandler) return onCompleted(new Error('Already inside a transaction'), []); beginTransaction(connection).then(_transactionHandler => { rdb.transactionHandler = _transactionHandler; onCompleted(null, []); }, onCompleted); return; } else if (sql === 'COMMIT') { if (!transactionHandler) return onCompleted(new Error('Cannot commit outside transaction'), []); transactionHandler.resolve(); transactionHandler.promise.then(() => onCompleted(null, []), err => onCompleted(err, [])); return; } else if (sql === 'ROLLBACK') { if (!transactionHandler) return onCompleted(new Error('Cannot rollback outside transaction'), []); transactionHandler.reject(new Error('__rollback__')); transactionHandler.promise.then(null, (err) => { if (err.message === '__rollback__') onCompleted(null, []); else onCompleted(err, []); }); return; } } let result; const _connection = transactionHandler?.tx || connection; if (query.parameters.length === 0) result = await _connection.unsafe(sql); else result = await _connection.unsafe(sql, query.parameters); onCompleted(null, result); } catch (e) { onCompleted(e); } } } function beginTransaction(connection) { let beginIsResolved = false; let resolve; let reject; let resolveBegin; let rejectBegin; let sqlPromise = new Promise((res, rej) => { resolve = res; reject = rej; }); let beginPromise = new Promise((res,rej) => { resolveBegin = res; rejectBegin = rej; }); connection.begin(async (tx) => { beginIsResolved = true; resolveBegin({ tx, resolve, reject, promise: sqlPromise, }); return sqlPromise; }).then(null, e => { if (!beginIsResolved) rejectBegin(e); if (e?.message !== '__rollback__') throw e; }); return beginPromise; } module.exports = wrapQuery;