pqb 0.65.1 → 0.65.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +189 -129
- package/dist/index.js +215 -218
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +215 -218
- package/dist/index.mjs.map +1 -1
- package/dist/internal.d.ts +2 -2
- package/dist/node-postgres.js +31 -30
- package/dist/node-postgres.js.map +1 -1
- package/dist/node-postgres.mjs +31 -30
- package/dist/node-postgres.mjs.map +1 -1
- package/dist/postgres-js.js +2 -2
- package/dist/postgres-js.js.map +1 -1
- package/dist/postgres-js.mjs +2 -2
- package/dist/postgres-js.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -282,6 +282,11 @@ const colors = {
|
|
|
282
282
|
greenBold: (s) => `\x1b[1m\x1b[32m${s}\x1b[0m`,
|
|
283
283
|
pale: (s) => `\x1b[2m${s}\x1b[0m`
|
|
284
284
|
};
|
|
285
|
+
const commitSql = { text: "COMMIT" };
|
|
286
|
+
const rollbackSql = { text: "ROLLBACK" };
|
|
287
|
+
const quoteIdentifier = (role) => {
|
|
288
|
+
return `"${role.replace(/"/g, "\"\"")}"`;
|
|
289
|
+
};
|
|
285
290
|
/**
|
|
286
291
|
* Symbol that turns on a snake case column names.
|
|
287
292
|
* It is set on the column types.
|
|
@@ -3514,9 +3519,6 @@ var QueryLog = class {
|
|
|
3514
3519
|
return q;
|
|
3515
3520
|
}
|
|
3516
3521
|
};
|
|
3517
|
-
const quoteRoleIdentifier = (role) => {
|
|
3518
|
-
return `"${role.replace(/"/g, "\"\"")}"`;
|
|
3519
|
-
};
|
|
3520
3522
|
const hasSqlSessionContextOptions = (options) => {
|
|
3521
3523
|
return options.role !== void 0 || options.setConfig !== void 0;
|
|
3522
3524
|
};
|
|
@@ -3524,9 +3526,6 @@ const hasActiveSqlSessionContext = (state) => {
|
|
|
3524
3526
|
if (!state) return false;
|
|
3525
3527
|
return state.role !== void 0 || state.setConfig !== void 0;
|
|
3526
3528
|
};
|
|
3527
|
-
const sqlSessionContextNormalizeSetConfig = (setConfig) => {
|
|
3528
|
-
return Object.fromEntries(Object.entries(setConfig).map(([key, value]) => [key, String(value)]));
|
|
3529
|
-
};
|
|
3530
3529
|
const buildConfigRestoreExpression = (key, value) => {
|
|
3531
3530
|
const escapedKey = key.replace(/'/g, "''");
|
|
3532
3531
|
if (value === null || value === void 0) value = "";
|
|
@@ -3535,7 +3534,7 @@ const buildConfigRestoreExpression = (key, value) => {
|
|
|
3535
3534
|
const sqlSessionContextSetStorageOptions = (query, state, options, result) => {
|
|
3536
3535
|
if (hasSqlSessionContextOptions(options) && hasActiveSqlSessionContext(state)) throw new NestedSqlSessionError(query);
|
|
3537
3536
|
if (options.role !== void 0) result.role = options.role;
|
|
3538
|
-
if (options.setConfig) result.setConfig =
|
|
3537
|
+
if (options.setConfig) result.setConfig = options.setConfig;
|
|
3539
3538
|
};
|
|
3540
3539
|
const sqlSessionContextMergeStorageState = (state, options) => {
|
|
3541
3540
|
if (!options) return state;
|
|
@@ -3557,7 +3556,7 @@ const sqlSessionContextComputeSetup = (desired) => {
|
|
|
3557
3556
|
if (!hasRole && !hasConfig) return void 0;
|
|
3558
3557
|
const result = {};
|
|
3559
3558
|
if (hasRole) {
|
|
3560
|
-
result.roleSetupSql = `SET ROLE ${
|
|
3559
|
+
result.roleSetupSql = `SET ROLE ${quoteIdentifier(role)}`;
|
|
3561
3560
|
result.captureRoleSql = "SELECT current_user";
|
|
3562
3561
|
}
|
|
3563
3562
|
if (hasConfig && setConfig) {
|
|
@@ -3602,7 +3601,7 @@ const sqlSessionContextExecute = async (query, setup, mainQuery) => {
|
|
|
3602
3601
|
return await mainQuery();
|
|
3603
3602
|
} finally {
|
|
3604
3603
|
const cleanupPromises = [];
|
|
3605
|
-
if (roleSetupSql && captured.previousRole !== void 0) cleanupPromises.push(query(`SET ROLE ${
|
|
3604
|
+
if (roleSetupSql && captured.previousRole !== void 0) cleanupPromises.push(query(`SET ROLE ${quoteIdentifier(captured.previousRole)}`));
|
|
3606
3605
|
if (captured.previousConfigs) {
|
|
3607
3606
|
const restoreSql = sqlSessionContextBuildConfigRestoreBatchSql(captured.previousConfigs);
|
|
3608
3607
|
if (restoreSql) cleanupPromises.push(query(restoreSql));
|
|
@@ -3610,14 +3609,12 @@ const sqlSessionContextExecute = async (query, setup, mainQuery) => {
|
|
|
3610
3609
|
await Promise.all(cleanupPromises);
|
|
3611
3610
|
}
|
|
3612
3611
|
};
|
|
3613
|
-
const processStorageOptions = (query, state, options) => {
|
|
3614
|
-
|
|
3615
|
-
|
|
3616
|
-
const result = {};
|
|
3612
|
+
const processStorageOptions = (query, state, { log: enableLog, ...options }) => {
|
|
3613
|
+
const log = enableLog === void 0 ? query.q.log : logParamToLogObject(query.q.logger, enableLog);
|
|
3614
|
+
const result = options;
|
|
3617
3615
|
if (log) result.log = log;
|
|
3618
3616
|
if ("schema" in options) result.schema = options.schema;
|
|
3619
3617
|
sqlSessionContextSetStorageOptions(query, state, options, result);
|
|
3620
|
-
if (result.log === void 0 && result.schema === void 0 && result.role === void 0 && result.setConfig === void 0) return;
|
|
3621
3618
|
return result;
|
|
3622
3619
|
};
|
|
3623
3620
|
let currentDefaultSchema;
|
|
@@ -3639,8 +3636,6 @@ var QueryStorage = class {
|
|
|
3639
3636
|
return !opts ? state ? this.internal.asyncStorage.run(state, cb) : cb() : this.internal.asyncStorage.run(newState, cb);
|
|
3640
3637
|
}
|
|
3641
3638
|
};
|
|
3642
|
-
const commitSql = { text: "COMMIT" };
|
|
3643
|
-
const rollbackSql = { text: "ROLLBACK" };
|
|
3644
3639
|
/**
|
|
3645
3640
|
* `AfterCommitError` is thrown when one of after commit hooks throws.
|
|
3646
3641
|
*
|
|
@@ -3723,81 +3718,8 @@ var QueryTransaction = class QueryTransaction {
|
|
|
3723
3718
|
options = typeof cbOrOptions === "object" ? cbOrOptions : { level: cbOrOptions };
|
|
3724
3719
|
fn = cb;
|
|
3725
3720
|
}
|
|
3726
|
-
|
|
3727
|
-
|
|
3728
|
-
const log = opts?.log || this.q.log;
|
|
3729
|
-
let logData;
|
|
3730
|
-
let state = this.internal.asyncStorage.getStore();
|
|
3731
|
-
const transactionId = state?.transactionId !== void 0 ? state.transactionId + 1 : 0;
|
|
3732
|
-
const callback = (transactionAdapter) => {
|
|
3733
|
-
if (log) log.afterQuery(sql, logData);
|
|
3734
|
-
if (log) logData = log.beforeQuery(commitSql);
|
|
3735
|
-
if (state) {
|
|
3736
|
-
state.transactionId = transactionId;
|
|
3737
|
-
return fn();
|
|
3738
|
-
}
|
|
3739
|
-
state = {
|
|
3740
|
-
...opts,
|
|
3741
|
-
transactionAdapter,
|
|
3742
|
-
transactionId
|
|
3743
|
-
};
|
|
3744
|
-
if (options.log !== void 0) state.log = log;
|
|
3745
|
-
return this.internal.asyncStorage.run(state, fn);
|
|
3746
|
-
};
|
|
3747
|
-
const transactionAdapter = state?.transactionAdapter;
|
|
3748
|
-
if (!state || !transactionAdapter) {
|
|
3749
|
-
let transactionOptions;
|
|
3750
|
-
if (options.level) transactionOptions = { options: `ISOLATION LEVEL ${options.level}` };
|
|
3751
|
-
if (options.readOnly !== void 0) {
|
|
3752
|
-
const add = `READ ${options.readOnly ? "ONLY" : "WRITE"}`;
|
|
3753
|
-
const opts = transactionOptions ??= {};
|
|
3754
|
-
if (opts.options) opts.options += " " + add;
|
|
3755
|
-
else opts.options = add;
|
|
3756
|
-
}
|
|
3757
|
-
if (options.deferrable !== void 0) {
|
|
3758
|
-
const add = `${options.deferrable ? "" : "NOT "}DEFERRABLE`;
|
|
3759
|
-
const opts = transactionOptions ??= {};
|
|
3760
|
-
if (opts.options) opts.options += " " + add;
|
|
3761
|
-
else opts.options = add;
|
|
3762
|
-
}
|
|
3763
|
-
if (log) {
|
|
3764
|
-
sql.text = transactionOptions?.options ? `BEGIN ${transactionOptions.options}` : "BEGIN";
|
|
3765
|
-
logData = log.beforeQuery(sql);
|
|
3766
|
-
}
|
|
3767
|
-
const result = await this.q.adapter.transaction(transactionOptions, callback).catch((err) => {
|
|
3768
|
-
if (log) log.afterQuery(rollbackSql, logData);
|
|
3769
|
-
throw err;
|
|
3770
|
-
});
|
|
3771
|
-
if (log) log.afterQuery(commitSql, logData);
|
|
3772
|
-
runAfterCommit(state.afterCommit, result);
|
|
3773
|
-
return result;
|
|
3774
|
-
} else try {
|
|
3775
|
-
sql.text = `SAVEPOINT "t${transactionId}"`;
|
|
3776
|
-
if (log) logData = log.beforeQuery(sql);
|
|
3777
|
-
await transactionAdapter.arrays(sql.text, sql.values);
|
|
3778
|
-
let result;
|
|
3779
|
-
try {
|
|
3780
|
-
result = await callback(transactionAdapter);
|
|
3781
|
-
} catch (err) {
|
|
3782
|
-
sql.text = `ROLLBACK TO SAVEPOINT "t${transactionId}"`;
|
|
3783
|
-
if (log) logData = log.beforeQuery(sql);
|
|
3784
|
-
await transactionAdapter.arrays(sql.text, sql.values);
|
|
3785
|
-
if (log) log.afterQuery(sql, logData);
|
|
3786
|
-
throw err;
|
|
3787
|
-
}
|
|
3788
|
-
sql.text = `RELEASE SAVEPOINT "t${transactionId}"`;
|
|
3789
|
-
if (log) logData = log.beforeQuery(sql);
|
|
3790
|
-
await transactionAdapter.arrays(sql.text, sql.values);
|
|
3791
|
-
if (log) log.afterQuery(sql, logData);
|
|
3792
|
-
if (transactionId === state.testTransactionCount) {
|
|
3793
|
-
const { afterCommit } = state;
|
|
3794
|
-
state.afterCommit = void 0;
|
|
3795
|
-
runAfterCommit(afterCommit, result);
|
|
3796
|
-
}
|
|
3797
|
-
return result;
|
|
3798
|
-
} finally {
|
|
3799
|
-
state.transactionId = transactionId - 1;
|
|
3800
|
-
}
|
|
3721
|
+
let opts = processStorageOptions(this, void 0, options);
|
|
3722
|
+
return this.q.adapter.transaction(this.internal.asyncStorage, opts, fn);
|
|
3801
3723
|
}
|
|
3802
3724
|
/**
|
|
3803
3725
|
* Use the `$ensureTransaction` when you want to ensure the sequence of queries is running in a transaction, but there is no need for Postgres [savepoints](https://www.postgresql.org/docs/current/sql-savepoint.html).
|
|
@@ -3909,49 +3831,6 @@ var QueryTransaction = class QueryTransaction {
|
|
|
3909
3831
|
return q;
|
|
3910
3832
|
}
|
|
3911
3833
|
};
|
|
3912
|
-
const runAfterCommit = (afterCommit, result) => {
|
|
3913
|
-
queueMicrotask(async () => {
|
|
3914
|
-
if (afterCommit) {
|
|
3915
|
-
const promises = [];
|
|
3916
|
-
let catchAfterCommitErrors;
|
|
3917
|
-
for (let i = 0, len = afterCommit.length; i < len;) {
|
|
3918
|
-
const first = afterCommit[i];
|
|
3919
|
-
if (typeof first === "function") {
|
|
3920
|
-
try {
|
|
3921
|
-
promises.push(first());
|
|
3922
|
-
} catch (err) {
|
|
3923
|
-
promises.push(Promise.reject(err));
|
|
3924
|
-
}
|
|
3925
|
-
i++;
|
|
3926
|
-
} else {
|
|
3927
|
-
const q = afterCommit[i + 1];
|
|
3928
|
-
if (q.q.catchAfterCommitErrors) (catchAfterCommitErrors ??= []).push(...q.q.catchAfterCommitErrors);
|
|
3929
|
-
for (const fn of afterCommit[i + 2]) try {
|
|
3930
|
-
promises.push(fn(first, q));
|
|
3931
|
-
} catch (err) {
|
|
3932
|
-
promises.push(Promise.reject(err));
|
|
3933
|
-
}
|
|
3934
|
-
i += 3;
|
|
3935
|
-
}
|
|
3936
|
-
}
|
|
3937
|
-
const getHookNames = () => {
|
|
3938
|
-
const hookNames = [];
|
|
3939
|
-
for (let i = 0, len = afterCommit.length; i < len;) {
|
|
3940
|
-
const first = afterCommit[i];
|
|
3941
|
-
if (typeof first === "function") {
|
|
3942
|
-
hookNames.push(first.name);
|
|
3943
|
-
i++;
|
|
3944
|
-
} else {
|
|
3945
|
-
for (const fn of afterCommit[i + 2]) hookNames.push(fn.name);
|
|
3946
|
-
i += 3;
|
|
3947
|
-
}
|
|
3948
|
-
}
|
|
3949
|
-
return hookNames;
|
|
3950
|
-
};
|
|
3951
|
-
await _runAfterCommitHooks(result, promises, getHookNames, catchAfterCommitErrors);
|
|
3952
|
-
}
|
|
3953
|
-
});
|
|
3954
|
-
};
|
|
3955
3834
|
/**
|
|
3956
3835
|
* See `transform` query method.
|
|
3957
3836
|
* This helper applies all transform functions to a result.
|
|
@@ -4417,7 +4296,7 @@ const then = async (q, adapter, state, beforeHooks, afterHooks, afterSaveHooks,
|
|
|
4417
4296
|
else {
|
|
4418
4297
|
const { batch } = sql;
|
|
4419
4298
|
if (log) logData = log.beforeQuery(beginSql);
|
|
4420
|
-
await adapter.transaction(async () => {
|
|
4299
|
+
await adapter.transaction(void 0, void 0, async () => {
|
|
4421
4300
|
if (log) log.afterQuery(beginSql, logData);
|
|
4422
4301
|
const res = await queryBatch(batch);
|
|
4423
4302
|
if (log) logData = log.beforeQuery(commitSql);
|
|
@@ -13723,34 +13602,34 @@ const _initQueryBuilder = (adapter, columnTypes, asyncStorage, commonOptions, op
|
|
|
13723
13602
|
qb.internal.managedRolesSql = options.managedRolesSql;
|
|
13724
13603
|
return qb.qb = qb;
|
|
13725
13604
|
};
|
|
13726
|
-
const
|
|
13727
|
-
|
|
13728
|
-
|
|
13729
|
-
} : locals;
|
|
13730
|
-
const getSetLocalsSql = (options) => {
|
|
13731
|
-
if (!options?.locals) return;
|
|
13732
|
-
return Object.entries(options.locals).map(([key, value]) => `SET LOCAL ${key}=${value}`).join("; ");
|
|
13733
|
-
};
|
|
13734
|
-
const getResetLocalsSql = (parentLocals, options) => {
|
|
13735
|
-
if (!options?.locals) return;
|
|
13736
|
-
return Object.entries(options.locals).reduce((acc, [key, value]) => {
|
|
13737
|
-
if (parentLocals[key] !== value) acc.push(`SET LOCAL ${key}=${parentLocals[key]}`);
|
|
13738
|
-
return acc;
|
|
13739
|
-
}, []).join("; ");
|
|
13605
|
+
const getSetRoleSql = (parentRole, options) => {
|
|
13606
|
+
if (!options?.role) return;
|
|
13607
|
+
return parentRole !== options.role ? `SET LOCAL ROLE ${quoteIdentifier(options.role)}` : void 0;
|
|
13740
13608
|
};
|
|
13741
|
-
const
|
|
13742
|
-
|
|
13743
|
-
options: void 0
|
|
13609
|
+
const getResetRoleSql = (parentRole, options) => {
|
|
13610
|
+
if (!options?.role) return;
|
|
13611
|
+
return parentRole !== options.role ? parentRole ? `SET LOCAL ROLE ${quoteIdentifier(parentRole)}` : `RESET ROLE` : void 0;
|
|
13744
13612
|
};
|
|
13745
|
-
const
|
|
13746
|
-
if (
|
|
13747
|
-
|
|
13748
|
-
|
|
13749
|
-
|
|
13750
|
-
|
|
13751
|
-
|
|
13752
|
-
|
|
13753
|
-
|
|
13613
|
+
const getSetConfigSql = (parentSetConfig, options) => {
|
|
13614
|
+
if (!options?.setConfig) return;
|
|
13615
|
+
const expressions = Object.entries(options.setConfig).reduce((acc, [key, value]) => {
|
|
13616
|
+
if (!parentSetConfig || parentSetConfig[key] !== value) acc.push(setConfigSql(key, value));
|
|
13617
|
+
return acc;
|
|
13618
|
+
}, []);
|
|
13619
|
+
return expressions.length ? `SELECT ${expressions.join(", ")}` : void 0;
|
|
13620
|
+
};
|
|
13621
|
+
const getResetSetConfigSql = (parentSetConfig, options) => {
|
|
13622
|
+
if (!options?.setConfig) return;
|
|
13623
|
+
const expressions = Object.entries(options.setConfig).reduce((acc, [key, value]) => {
|
|
13624
|
+
if (parentSetConfig && key in parentSetConfig) {
|
|
13625
|
+
if (parentSetConfig[key] !== value) acc.push(setConfigSql(key, parentSetConfig[key]));
|
|
13626
|
+
} else acc.push(setConfigSql(key, void 0));
|
|
13627
|
+
return acc;
|
|
13628
|
+
}, []);
|
|
13629
|
+
return expressions.length ? `SELECT ${expressions.join(", ")}` : void 0;
|
|
13630
|
+
};
|
|
13631
|
+
const setConfigSql = (key, value) => {
|
|
13632
|
+
return `set_config('${key.replace(/'/g, "''")}', '${typeof value === "string" ? value.replace(/'/g, "''") : value === void 0 ? "" : value}', true)`;
|
|
13754
13633
|
};
|
|
13755
13634
|
/**
|
|
13756
13635
|
* Shared runtime adapter orchestrator over a driver-specific adapter implementation.
|
|
@@ -13758,8 +13637,12 @@ const getTransactionArgs = (cbOrOptions, optionalCb) => {
|
|
|
13758
13637
|
var AdapterClass = class AdapterClass {
|
|
13759
13638
|
constructor(params) {
|
|
13760
13639
|
this.params = params;
|
|
13640
|
+
this.close = async () => {
|
|
13641
|
+
const { pool } = this;
|
|
13642
|
+
this.pool = this.driverAdapter.configure(this.config);
|
|
13643
|
+
await this.driverAdapter.close(pool);
|
|
13644
|
+
};
|
|
13761
13645
|
this.config = { ...params.config };
|
|
13762
|
-
this.locals = this.config.locals || emptyObject;
|
|
13763
13646
|
if (this.config.connectRetry) {
|
|
13764
13647
|
const connectRetryConfig = makeConnectRetryConfig(this.config.connectRetry === true ? emptyObject : this.config.connectRetry);
|
|
13765
13648
|
if (connectRetryConfig) {
|
|
@@ -13803,29 +13686,8 @@ var AdapterClass = class AdapterClass {
|
|
|
13803
13686
|
getSchema() {
|
|
13804
13687
|
return this.connectionState.schema;
|
|
13805
13688
|
}
|
|
13806
|
-
transaction(
|
|
13807
|
-
|
|
13808
|
-
return this.driverAdapter.begin(this.pool, (client) => {
|
|
13809
|
-
let promises;
|
|
13810
|
-
if (options?.sqlSessionState) {
|
|
13811
|
-
const { role, setConfig } = options.sqlSessionState;
|
|
13812
|
-
if (role) (promises ??= []).push(this.driverAdapter.queryClient(client, `SET ROLE ${role}`));
|
|
13813
|
-
if (setConfig && Object.keys(setConfig).length > 0) {
|
|
13814
|
-
const setExpressions = Object.entries(setConfig).map(([key, value]) => `set_config('${key.replace(/'/g, "''")}', '${typeof value === "string" ? value.replace(/'/g, "''") : value}', true)`).join(", ");
|
|
13815
|
-
(promises ??= []).push(this.driverAdapter.queryClient(client, `SELECT ${setExpressions}`));
|
|
13816
|
-
}
|
|
13817
|
-
}
|
|
13818
|
-
const localsSql = getSetLocalsSql(options);
|
|
13819
|
-
if (localsSql) (promises ??= []).push(this.driverAdapter.queryClient(client, localsSql));
|
|
13820
|
-
const locals = mergeLocals(this.locals, options);
|
|
13821
|
-
const transaction = cb(new TransactionAdapterClass(this, locals, client));
|
|
13822
|
-
return promises ? Promise.all(promises).then(() => transaction) : transaction;
|
|
13823
|
-
}, options?.options);
|
|
13824
|
-
}
|
|
13825
|
-
async close() {
|
|
13826
|
-
const { pool } = this;
|
|
13827
|
-
this.pool = this.driverAdapter.configure(this.config);
|
|
13828
|
-
await this.driverAdapter.close(pool);
|
|
13689
|
+
transaction(asyncStorage, options, cb) {
|
|
13690
|
+
return transaction(asyncStorage, this, this.driverAdapter, this.pool, options, cb);
|
|
13829
13691
|
}
|
|
13830
13692
|
assignError(to, from) {
|
|
13831
13693
|
const { errorFields } = this.driverAdapter;
|
|
@@ -13835,10 +13697,9 @@ var AdapterClass = class AdapterClass {
|
|
|
13835
13697
|
/**
|
|
13836
13698
|
* Shared runtime transaction adapter orchestrator over a driver-specific transaction adapter.
|
|
13837
13699
|
*/
|
|
13838
|
-
var TransactionAdapterClass = class
|
|
13839
|
-
constructor(adapter,
|
|
13700
|
+
var TransactionAdapterClass = class {
|
|
13701
|
+
constructor(adapter, client) {
|
|
13840
13702
|
this.adapter = adapter;
|
|
13841
|
-
this.locals = locals;
|
|
13842
13703
|
this.client = client;
|
|
13843
13704
|
this.driverAdapter = adapter.driverAdapter;
|
|
13844
13705
|
this.errorClass = this.adapter.errorClass;
|
|
@@ -13872,31 +13733,8 @@ var TransactionAdapterClass = class TransactionAdapterClass {
|
|
|
13872
13733
|
getSchema() {
|
|
13873
13734
|
return this.adapter.getSchema();
|
|
13874
13735
|
}
|
|
13875
|
-
async transaction(
|
|
13876
|
-
|
|
13877
|
-
let capturedRole;
|
|
13878
|
-
const capturedConfigs = {};
|
|
13879
|
-
const sqlSession = options?.sqlSessionState;
|
|
13880
|
-
if (sqlSession) {
|
|
13881
|
-
if (sqlSession.role) capturedRole = (await this.driverAdapter.queryClient(this.client, "SELECT current_role as role")).rows[0].role;
|
|
13882
|
-
if (sqlSession.setConfig && Object.keys(sqlSession.setConfig).length > 0) for (const key of Object.keys(sqlSession.setConfig)) capturedConfigs[key] = (await this.driverAdapter.queryClient(this.client, `SELECT current_setting('${key.replace(/'/g, "''")}', true) as val`)).rows[0].val;
|
|
13883
|
-
}
|
|
13884
|
-
const localsSql = getSetLocalsSql(options);
|
|
13885
|
-
if (localsSql) this.driverAdapter.queryClient(this.client, localsSql);
|
|
13886
|
-
const locals = mergeLocals(this.locals, options);
|
|
13887
|
-
try {
|
|
13888
|
-
return await cb(new TransactionAdapterClass(this.adapter, locals, this.client));
|
|
13889
|
-
} finally {
|
|
13890
|
-
if (sqlSession) {
|
|
13891
|
-
if (capturedRole !== void 0) await this.driverAdapter.queryClient(this.client, `SET ROLE ${capturedRole}`);
|
|
13892
|
-
for (const [key, value] of Object.entries(capturedConfigs)) {
|
|
13893
|
-
const restoreValue = value === null ? "" : value;
|
|
13894
|
-
await this.driverAdapter.queryClient(this.client, `SELECT set_config('${key.replace(/'/g, "''")}', '${restoreValue.replace(/'/g, "''")}', true)`);
|
|
13895
|
-
}
|
|
13896
|
-
}
|
|
13897
|
-
const resetLocalsSql = getResetLocalsSql(this.locals, options);
|
|
13898
|
-
if (resetLocalsSql) await this.driverAdapter.queryClient(this.client, resetLocalsSql);
|
|
13899
|
-
}
|
|
13736
|
+
async transaction(asyncStorage, options, cb) {
|
|
13737
|
+
return transaction(asyncStorage, this.adapter, this.driverAdapter, this.client, options, cb, this);
|
|
13900
13738
|
}
|
|
13901
13739
|
close() {
|
|
13902
13740
|
return this.adapter.close();
|
|
@@ -13905,6 +13743,165 @@ var TransactionAdapterClass = class TransactionAdapterClass {
|
|
|
13905
13743
|
return this.adapter.assignError(to, from);
|
|
13906
13744
|
}
|
|
13907
13745
|
};
|
|
13746
|
+
const transaction = (asyncStorage, adapter, driverAdapter, poolOrClient, options, cb, transactionAdapter) => {
|
|
13747
|
+
const sql = { values: emptyArray };
|
|
13748
|
+
const log = options?.log;
|
|
13749
|
+
const state = asyncStorage?.getStore();
|
|
13750
|
+
const ctx = {
|
|
13751
|
+
state,
|
|
13752
|
+
logData: void 0
|
|
13753
|
+
};
|
|
13754
|
+
const transactionId = state?.transactionId !== void 0 ? state.transactionId + 1 : 0;
|
|
13755
|
+
const fn = (transactionAdapter) => {
|
|
13756
|
+
if (log) log.afterQuery(sql, ctx.logData);
|
|
13757
|
+
if (log) ctx.logData = log.beforeQuery(commitSql);
|
|
13758
|
+
if (state || !asyncStorage) {
|
|
13759
|
+
const parentTransactionRole = state?.transactionRole;
|
|
13760
|
+
const parentTransactionSetConfig = state?.transactionSetConfig;
|
|
13761
|
+
if (state) {
|
|
13762
|
+
state.transactionId = transactionId;
|
|
13763
|
+
if (options) {
|
|
13764
|
+
if (options.role) state.transactionRole = options.role;
|
|
13765
|
+
if (options.setConfig) state.transactionSetConfig = {
|
|
13766
|
+
...state.transactionSetConfig,
|
|
13767
|
+
...options.setConfig
|
|
13768
|
+
};
|
|
13769
|
+
}
|
|
13770
|
+
}
|
|
13771
|
+
return Promise.resolve(cb(transactionAdapter)).finally(() => {
|
|
13772
|
+
if (state) {
|
|
13773
|
+
state.transactionId = transactionId - 1;
|
|
13774
|
+
state.transactionRole = parentTransactionRole;
|
|
13775
|
+
state.transactionSetConfig = parentTransactionSetConfig;
|
|
13776
|
+
}
|
|
13777
|
+
});
|
|
13778
|
+
}
|
|
13779
|
+
ctx.state = {
|
|
13780
|
+
...options,
|
|
13781
|
+
role: void 0,
|
|
13782
|
+
setConfig: void 0,
|
|
13783
|
+
transactionAdapter,
|
|
13784
|
+
transactionId,
|
|
13785
|
+
transactionRole: options?.role,
|
|
13786
|
+
transactionSetConfig: options?.setConfig
|
|
13787
|
+
};
|
|
13788
|
+
return asyncStorage.run(ctx.state, () => cb(transactionAdapter));
|
|
13789
|
+
};
|
|
13790
|
+
transactionAdapter ??= state?.transactionAdapter;
|
|
13791
|
+
if (transactionAdapter) return nestedTransaction(adapter, driverAdapter, transactionAdapter, poolOrClient, options, fn, ctx, transactionId, sql, log);
|
|
13792
|
+
else return realTransaction(adapter, driverAdapter, poolOrClient, options, fn, ctx, sql, log);
|
|
13793
|
+
};
|
|
13794
|
+
const realTransaction = async (adapter, driverAdapter, pool, options, cb, ctx, sql, log) => {
|
|
13795
|
+
let trxOpts;
|
|
13796
|
+
if (options?.level) trxOpts = `ISOLATION LEVEL ${options.level}`;
|
|
13797
|
+
if (options?.readOnly !== void 0) {
|
|
13798
|
+
const add = `READ ${options.readOnly ? "ONLY" : "WRITE"}`;
|
|
13799
|
+
trxOpts = trxOpts ? trxOpts + " " + add : add;
|
|
13800
|
+
}
|
|
13801
|
+
if (options?.deferrable !== void 0) {
|
|
13802
|
+
const add = `${options.deferrable ? "" : "NOT "}DEFERRABLE`;
|
|
13803
|
+
trxOpts = trxOpts ? trxOpts + " " + add : add;
|
|
13804
|
+
}
|
|
13805
|
+
if (log) {
|
|
13806
|
+
sql.text = trxOpts ? `BEGIN ${trxOpts}` : "BEGIN";
|
|
13807
|
+
ctx.logData = log.beforeQuery(sql);
|
|
13808
|
+
}
|
|
13809
|
+
const result = await driverAdapter.begin(pool, (client) => {
|
|
13810
|
+
let promises;
|
|
13811
|
+
const setRoleSql = getSetRoleSql(void 0, options);
|
|
13812
|
+
if (setRoleSql) (promises ??= []).push(driverAdapter.queryClient(client, setRoleSql));
|
|
13813
|
+
const setConfigSql = getSetConfigSql(void 0, options);
|
|
13814
|
+
if (setConfigSql) (promises ??= []).push(driverAdapter.queryClient(client, setConfigSql));
|
|
13815
|
+
const transaction = cb(new TransactionAdapterClass(adapter, client));
|
|
13816
|
+
return promises ? Promise.all(promises).then(() => transaction) : transaction;
|
|
13817
|
+
}, trxOpts).catch((err) => {
|
|
13818
|
+
if (log) log.afterQuery(rollbackSql, ctx.logData);
|
|
13819
|
+
throw err;
|
|
13820
|
+
});
|
|
13821
|
+
if (log) log.afterQuery(commitSql, ctx.logData);
|
|
13822
|
+
if (ctx.state) runAfterCommit(ctx.state.afterCommit, result);
|
|
13823
|
+
return result;
|
|
13824
|
+
};
|
|
13825
|
+
const nestedTransaction = async (adapter, driverAdapter, transactionAdapter, client, options, cb, ctx, transactionId, sql, log) => {
|
|
13826
|
+
const state = ctx.state;
|
|
13827
|
+
const parentRole = state?.transactionRole;
|
|
13828
|
+
const parentSetConfig = state?.transactionSetConfig;
|
|
13829
|
+
sql.text = `SAVEPOINT "t${transactionId}"`;
|
|
13830
|
+
if (log) ctx.logData = log.beforeQuery(sql);
|
|
13831
|
+
await transactionAdapter.arrays(sql.text, sql.values);
|
|
13832
|
+
const setRoleSql = getSetRoleSql(parentRole, options);
|
|
13833
|
+
if (setRoleSql) driverAdapter.queryClient(client, setRoleSql);
|
|
13834
|
+
const setConfigSql = getSetConfigSql(parentSetConfig, options);
|
|
13835
|
+
if (setConfigSql) driverAdapter.queryClient(client, setConfigSql);
|
|
13836
|
+
let result;
|
|
13837
|
+
try {
|
|
13838
|
+
result = await cb(new TransactionAdapterClass(adapter, client));
|
|
13839
|
+
} catch (err) {
|
|
13840
|
+
sql.text = `ROLLBACK TO SAVEPOINT "t${transactionId}"`;
|
|
13841
|
+
if (log) ctx.logData = log.beforeQuery(sql);
|
|
13842
|
+
await transactionAdapter.arrays(sql.text, sql.values);
|
|
13843
|
+
if (log) log.afterQuery(sql, ctx.logData);
|
|
13844
|
+
throw err;
|
|
13845
|
+
} finally {
|
|
13846
|
+
const resetRoleSql = getResetRoleSql(parentRole, options);
|
|
13847
|
+
if (resetRoleSql) await driverAdapter.queryClient(client, resetRoleSql);
|
|
13848
|
+
}
|
|
13849
|
+
const resetSetConfigSql = getResetSetConfigSql(parentSetConfig, options);
|
|
13850
|
+
if (resetSetConfigSql) driverAdapter.queryClient(client, resetSetConfigSql);
|
|
13851
|
+
sql.text = `RELEASE SAVEPOINT "t${transactionId}"`;
|
|
13852
|
+
if (log) ctx.logData = log.beforeQuery(sql);
|
|
13853
|
+
await transactionAdapter.arrays(sql.text, sql.values);
|
|
13854
|
+
if (log) log.afterQuery(sql, ctx.logData);
|
|
13855
|
+
if (ctx.state && transactionId === ctx.state.testTransactionCount) {
|
|
13856
|
+
const { afterCommit } = ctx.state;
|
|
13857
|
+
ctx.state.afterCommit = void 0;
|
|
13858
|
+
runAfterCommit(afterCommit, result);
|
|
13859
|
+
}
|
|
13860
|
+
return result;
|
|
13861
|
+
};
|
|
13862
|
+
const runAfterCommit = (afterCommit, result) => {
|
|
13863
|
+
queueMicrotask(async () => {
|
|
13864
|
+
if (afterCommit) {
|
|
13865
|
+
const promises = [];
|
|
13866
|
+
let catchAfterCommitErrors;
|
|
13867
|
+
for (let i = 0, len = afterCommit.length; i < len;) {
|
|
13868
|
+
const first = afterCommit[i];
|
|
13869
|
+
if (typeof first === "function") {
|
|
13870
|
+
try {
|
|
13871
|
+
promises.push(first());
|
|
13872
|
+
} catch (err) {
|
|
13873
|
+
promises.push(Promise.reject(err));
|
|
13874
|
+
}
|
|
13875
|
+
i++;
|
|
13876
|
+
} else {
|
|
13877
|
+
const q = afterCommit[i + 1];
|
|
13878
|
+
if (q.q.catchAfterCommitErrors) (catchAfterCommitErrors ??= []).push(...q.q.catchAfterCommitErrors);
|
|
13879
|
+
for (const fn of afterCommit[i + 2]) try {
|
|
13880
|
+
promises.push(fn(first, q));
|
|
13881
|
+
} catch (err) {
|
|
13882
|
+
promises.push(Promise.reject(err));
|
|
13883
|
+
}
|
|
13884
|
+
i += 3;
|
|
13885
|
+
}
|
|
13886
|
+
}
|
|
13887
|
+
const getHookNames = () => {
|
|
13888
|
+
const hookNames = [];
|
|
13889
|
+
for (let i = 0, len = afterCommit.length; i < len;) {
|
|
13890
|
+
const first = afterCommit[i];
|
|
13891
|
+
if (typeof first === "function") {
|
|
13892
|
+
hookNames.push(first.name);
|
|
13893
|
+
i++;
|
|
13894
|
+
} else {
|
|
13895
|
+
for (const fn of afterCommit[i + 2]) hookNames.push(fn.name);
|
|
13896
|
+
i += 3;
|
|
13897
|
+
}
|
|
13898
|
+
}
|
|
13899
|
+
return hookNames;
|
|
13900
|
+
};
|
|
13901
|
+
await _runAfterCommitHooks(result, promises, getHookNames, catchAfterCommitErrors);
|
|
13902
|
+
}
|
|
13903
|
+
});
|
|
13904
|
+
};
|
|
13908
13905
|
const runQueryHandlePool = async (pool, driverAdapter, text, values, startingSavepoint, releasingSavepoint, sqlSessionState, arraysMode, client) => {
|
|
13909
13906
|
const setup = sqlSessionContextComputeSetup(sqlSessionState);
|
|
13910
13907
|
if (client || !driverAdapter.manualPool && !setup) return runQueryHandleSetupAndCleanup(driverAdapter, client || pool, text, values, startingSavepoint, releasingSavepoint, setup, arraysMode);
|
|
@@ -13964,13 +13961,13 @@ const cloneAdapterConfig = (config, params) => {
|
|
|
13964
13961
|
return clonedConfig;
|
|
13965
13962
|
};
|
|
13966
13963
|
const createDriverAdapterConfig = (config, state) => {
|
|
13967
|
-
const
|
|
13968
|
-
delete
|
|
13969
|
-
if (state.searchPath && state.searchPath !== "public")
|
|
13964
|
+
const setConfig = config.setConfig ? { ...config.setConfig } : {};
|
|
13965
|
+
delete setConfig.search_path;
|
|
13966
|
+
if (state.searchPath && state.searchPath !== "public") setConfig.search_path = state.searchPath;
|
|
13970
13967
|
const driverConfig = {
|
|
13971
13968
|
...config,
|
|
13972
13969
|
searchPath: state.searchPath,
|
|
13973
|
-
|
|
13970
|
+
setConfig
|
|
13974
13971
|
};
|
|
13975
13972
|
if (driverConfig.databaseURL) {
|
|
13976
13973
|
const url = new URL(driverConfig.databaseURL);
|
|
@@ -14190,7 +14187,7 @@ const testTransaction = {
|
|
|
14190
14187
|
const data = db.internal[trxForTest];
|
|
14191
14188
|
const last = data?.pop();
|
|
14192
14189
|
if (!last) return;
|
|
14193
|
-
if (data?.length
|
|
14190
|
+
if (!data?.length) Object.assign(db.baseQuery.q.adapter, last.adapter);
|
|
14194
14191
|
last.reject?.(new Rollback());
|
|
14195
14192
|
return last.promise;
|
|
14196
14193
|
},
|