fix: pin postgres transaction clients

This commit is contained in:
ImBenji
2026-08-17 14:02:59 +01:00
parent 4c24b37af9
commit 51649fbf5f
+23 -7
View File
@@ -32,6 +32,16 @@ function querySync(pool, sql, params = []) {
return result; return result;
} }
function connectSync(pool) {
let done = false;
let client;
let error;
pool.connect().then((value) => { client = value; done = true; }).catch((err) => { error = err; done = true; });
deasync.loopWhile(() => !done);
if (error) throw error;
return client;
}
function normalizeParams(params) { function normalizeParams(params) {
if (params.length === 1 && params[0] && typeof params[0] === 'object' && !Array.isArray(params[0]) && !Buffer.isBuffer(params[0])) { if (params.length === 1 && params[0] && typeof params[0] === 'object' && !Array.isArray(params[0]) && !Buffer.isBuffer(params[0])) {
return params[0]; return params[0];
@@ -94,18 +104,19 @@ class PgCompatDb {
prepare(sql) { prepare(sql) {
const db = this; const db = this;
const target = () => db.activeClient || db.pool;
return { return {
get(...rawParams) { get(...rawParams) {
const { sql: text, params } = rewriteSql(sql, normalizeParams(rawParams)); const { sql: text, params } = rewriteSql(sql, normalizeParams(rawParams));
return querySync(db.pool, text, params).rows[0]; return querySync(target(), text, params).rows[0];
}, },
all(...rawParams) { all(...rawParams) {
const { sql: text, params } = rewriteSql(sql, normalizeParams(rawParams)); const { sql: text, params } = rewriteSql(sql, normalizeParams(rawParams));
return querySync(db.pool, text, params).rows; return querySync(target(), text, params).rows;
}, },
run(...rawParams) { run(...rawParams) {
const { sql: text, params } = rewriteSql(sql, normalizeParams(rawParams)); const { sql: text, params } = rewriteSql(sql, normalizeParams(rawParams));
const result = querySync(db.pool, text, params); const result = querySync(target(), text, params);
return { changes: result.rowCount || 0, lastInsertRowid: result.rows?.[0]?.id ?? null }; return { changes: result.rowCount || 0, lastInsertRowid: result.rows?.[0]?.id ?? null };
}, },
}; };
@@ -115,21 +126,26 @@ class PgCompatDb {
const statements = String(sql).split(';').map((statement) => statement.trim()).filter(Boolean); const statements = String(sql).split(';').map((statement) => statement.trim()).filter(Boolean);
for (const statement of statements) { for (const statement of statements) {
const { sql: text, params } = rewriteSql(statement, []); const { sql: text, params } = rewriteSql(statement, []);
querySync(this.pool, text, params); querySync(this.activeClient || this.pool, text, params);
} }
} }
transaction(fn) { transaction(fn) {
const db = this; const db = this;
const run = (...args) => { const run = (...args) => {
querySync(db.pool, 'BEGIN', []); const client = connectSync(db.pool);
try { try {
db.activeClient = client;
querySync(client, 'BEGIN', []);
const result = fn(...args); const result = fn(...args);
querySync(db.pool, 'COMMIT', []); querySync(client, 'COMMIT', []);
return result; return result;
} catch (error) { } catch (error) {
querySync(db.pool, 'ROLLBACK', []); try { querySync(client, 'ROLLBACK', []); } catch (_) {}
throw error; throw error;
} finally {
db.activeClient = null;
client.release();
} }
}; };
run.immediate = run; run.immediate = run;