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.js
CHANGED
|
@@ -305,6 +305,11 @@ const colors = {
|
|
|
305
305
|
greenBold: (s) => `\x1b[1m\x1b[32m${s}\x1b[0m`,
|
|
306
306
|
pale: (s) => `\x1b[2m${s}\x1b[0m`
|
|
307
307
|
};
|
|
308
|
+
const commitSql = { text: "COMMIT" };
|
|
309
|
+
const rollbackSql = { text: "ROLLBACK" };
|
|
310
|
+
const quoteIdentifier = (role) => {
|
|
311
|
+
return `"${role.replace(/"/g, "\"\"")}"`;
|
|
312
|
+
};
|
|
308
313
|
/**
|
|
309
314
|
* Symbol that turns on a snake case column names.
|
|
310
315
|
* It is set on the column types.
|
|
@@ -3537,9 +3542,6 @@ var QueryLog = class {
|
|
|
3537
3542
|
return q;
|
|
3538
3543
|
}
|
|
3539
3544
|
};
|
|
3540
|
-
const quoteRoleIdentifier = (role) => {
|
|
3541
|
-
return `"${role.replace(/"/g, "\"\"")}"`;
|
|
3542
|
-
};
|
|
3543
3545
|
const hasSqlSessionContextOptions = (options) => {
|
|
3544
3546
|
return options.role !== void 0 || options.setConfig !== void 0;
|
|
3545
3547
|
};
|
|
@@ -3547,9 +3549,6 @@ const hasActiveSqlSessionContext = (state) => {
|
|
|
3547
3549
|
if (!state) return false;
|
|
3548
3550
|
return state.role !== void 0 || state.setConfig !== void 0;
|
|
3549
3551
|
};
|
|
3550
|
-
const sqlSessionContextNormalizeSetConfig = (setConfig) => {
|
|
3551
|
-
return Object.fromEntries(Object.entries(setConfig).map(([key, value]) => [key, String(value)]));
|
|
3552
|
-
};
|
|
3553
3552
|
const buildConfigRestoreExpression = (key, value) => {
|
|
3554
3553
|
const escapedKey = key.replace(/'/g, "''");
|
|
3555
3554
|
if (value === null || value === void 0) value = "";
|
|
@@ -3558,7 +3557,7 @@ const buildConfigRestoreExpression = (key, value) => {
|
|
|
3558
3557
|
const sqlSessionContextSetStorageOptions = (query, state, options, result) => {
|
|
3559
3558
|
if (hasSqlSessionContextOptions(options) && hasActiveSqlSessionContext(state)) throw new NestedSqlSessionError(query);
|
|
3560
3559
|
if (options.role !== void 0) result.role = options.role;
|
|
3561
|
-
if (options.setConfig) result.setConfig =
|
|
3560
|
+
if (options.setConfig) result.setConfig = options.setConfig;
|
|
3562
3561
|
};
|
|
3563
3562
|
const sqlSessionContextMergeStorageState = (state, options) => {
|
|
3564
3563
|
if (!options) return state;
|
|
@@ -3580,7 +3579,7 @@ const sqlSessionContextComputeSetup = (desired) => {
|
|
|
3580
3579
|
if (!hasRole && !hasConfig) return void 0;
|
|
3581
3580
|
const result = {};
|
|
3582
3581
|
if (hasRole) {
|
|
3583
|
-
result.roleSetupSql = `SET ROLE ${
|
|
3582
|
+
result.roleSetupSql = `SET ROLE ${quoteIdentifier(role)}`;
|
|
3584
3583
|
result.captureRoleSql = "SELECT current_user";
|
|
3585
3584
|
}
|
|
3586
3585
|
if (hasConfig && setConfig) {
|
|
@@ -3625,7 +3624,7 @@ const sqlSessionContextExecute = async (query, setup, mainQuery) => {
|
|
|
3625
3624
|
return await mainQuery();
|
|
3626
3625
|
} finally {
|
|
3627
3626
|
const cleanupPromises = [];
|
|
3628
|
-
if (roleSetupSql && captured.previousRole !== void 0) cleanupPromises.push(query(`SET ROLE ${
|
|
3627
|
+
if (roleSetupSql && captured.previousRole !== void 0) cleanupPromises.push(query(`SET ROLE ${quoteIdentifier(captured.previousRole)}`));
|
|
3629
3628
|
if (captured.previousConfigs) {
|
|
3630
3629
|
const restoreSql = sqlSessionContextBuildConfigRestoreBatchSql(captured.previousConfigs);
|
|
3631
3630
|
if (restoreSql) cleanupPromises.push(query(restoreSql));
|
|
@@ -3633,14 +3632,12 @@ const sqlSessionContextExecute = async (query, setup, mainQuery) => {
|
|
|
3633
3632
|
await Promise.all(cleanupPromises);
|
|
3634
3633
|
}
|
|
3635
3634
|
};
|
|
3636
|
-
const processStorageOptions = (query, state, options) => {
|
|
3637
|
-
|
|
3638
|
-
|
|
3639
|
-
const result = {};
|
|
3635
|
+
const processStorageOptions = (query, state, { log: enableLog, ...options }) => {
|
|
3636
|
+
const log = enableLog === void 0 ? query.q.log : logParamToLogObject(query.q.logger, enableLog);
|
|
3637
|
+
const result = options;
|
|
3640
3638
|
if (log) result.log = log;
|
|
3641
3639
|
if ("schema" in options) result.schema = options.schema;
|
|
3642
3640
|
sqlSessionContextSetStorageOptions(query, state, options, result);
|
|
3643
|
-
if (result.log === void 0 && result.schema === void 0 && result.role === void 0 && result.setConfig === void 0) return;
|
|
3644
3641
|
return result;
|
|
3645
3642
|
};
|
|
3646
3643
|
let currentDefaultSchema;
|
|
@@ -3662,8 +3659,6 @@ var QueryStorage = class {
|
|
|
3662
3659
|
return !opts ? state ? this.internal.asyncStorage.run(state, cb) : cb() : this.internal.asyncStorage.run(newState, cb);
|
|
3663
3660
|
}
|
|
3664
3661
|
};
|
|
3665
|
-
const commitSql = { text: "COMMIT" };
|
|
3666
|
-
const rollbackSql = { text: "ROLLBACK" };
|
|
3667
3662
|
/**
|
|
3668
3663
|
* `AfterCommitError` is thrown when one of after commit hooks throws.
|
|
3669
3664
|
*
|
|
@@ -3746,81 +3741,8 @@ var QueryTransaction = class QueryTransaction {
|
|
|
3746
3741
|
options = typeof cbOrOptions === "object" ? cbOrOptions : { level: cbOrOptions };
|
|
3747
3742
|
fn = cb;
|
|
3748
3743
|
}
|
|
3749
|
-
|
|
3750
|
-
|
|
3751
|
-
const log = opts?.log || this.q.log;
|
|
3752
|
-
let logData;
|
|
3753
|
-
let state = this.internal.asyncStorage.getStore();
|
|
3754
|
-
const transactionId = state?.transactionId !== void 0 ? state.transactionId + 1 : 0;
|
|
3755
|
-
const callback = (transactionAdapter) => {
|
|
3756
|
-
if (log) log.afterQuery(sql, logData);
|
|
3757
|
-
if (log) logData = log.beforeQuery(commitSql);
|
|
3758
|
-
if (state) {
|
|
3759
|
-
state.transactionId = transactionId;
|
|
3760
|
-
return fn();
|
|
3761
|
-
}
|
|
3762
|
-
state = {
|
|
3763
|
-
...opts,
|
|
3764
|
-
transactionAdapter,
|
|
3765
|
-
transactionId
|
|
3766
|
-
};
|
|
3767
|
-
if (options.log !== void 0) state.log = log;
|
|
3768
|
-
return this.internal.asyncStorage.run(state, fn);
|
|
3769
|
-
};
|
|
3770
|
-
const transactionAdapter = state?.transactionAdapter;
|
|
3771
|
-
if (!state || !transactionAdapter) {
|
|
3772
|
-
let transactionOptions;
|
|
3773
|
-
if (options.level) transactionOptions = { options: `ISOLATION LEVEL ${options.level}` };
|
|
3774
|
-
if (options.readOnly !== void 0) {
|
|
3775
|
-
const add = `READ ${options.readOnly ? "ONLY" : "WRITE"}`;
|
|
3776
|
-
const opts = transactionOptions ??= {};
|
|
3777
|
-
if (opts.options) opts.options += " " + add;
|
|
3778
|
-
else opts.options = add;
|
|
3779
|
-
}
|
|
3780
|
-
if (options.deferrable !== void 0) {
|
|
3781
|
-
const add = `${options.deferrable ? "" : "NOT "}DEFERRABLE`;
|
|
3782
|
-
const opts = transactionOptions ??= {};
|
|
3783
|
-
if (opts.options) opts.options += " " + add;
|
|
3784
|
-
else opts.options = add;
|
|
3785
|
-
}
|
|
3786
|
-
if (log) {
|
|
3787
|
-
sql.text = transactionOptions?.options ? `BEGIN ${transactionOptions.options}` : "BEGIN";
|
|
3788
|
-
logData = log.beforeQuery(sql);
|
|
3789
|
-
}
|
|
3790
|
-
const result = await this.q.adapter.transaction(transactionOptions, callback).catch((err) => {
|
|
3791
|
-
if (log) log.afterQuery(rollbackSql, logData);
|
|
3792
|
-
throw err;
|
|
3793
|
-
});
|
|
3794
|
-
if (log) log.afterQuery(commitSql, logData);
|
|
3795
|
-
runAfterCommit(state.afterCommit, result);
|
|
3796
|
-
return result;
|
|
3797
|
-
} else try {
|
|
3798
|
-
sql.text = `SAVEPOINT "t${transactionId}"`;
|
|
3799
|
-
if (log) logData = log.beforeQuery(sql);
|
|
3800
|
-
await transactionAdapter.arrays(sql.text, sql.values);
|
|
3801
|
-
let result;
|
|
3802
|
-
try {
|
|
3803
|
-
result = await callback(transactionAdapter);
|
|
3804
|
-
} catch (err) {
|
|
3805
|
-
sql.text = `ROLLBACK TO SAVEPOINT "t${transactionId}"`;
|
|
3806
|
-
if (log) logData = log.beforeQuery(sql);
|
|
3807
|
-
await transactionAdapter.arrays(sql.text, sql.values);
|
|
3808
|
-
if (log) log.afterQuery(sql, logData);
|
|
3809
|
-
throw err;
|
|
3810
|
-
}
|
|
3811
|
-
sql.text = `RELEASE SAVEPOINT "t${transactionId}"`;
|
|
3812
|
-
if (log) logData = log.beforeQuery(sql);
|
|
3813
|
-
await transactionAdapter.arrays(sql.text, sql.values);
|
|
3814
|
-
if (log) log.afterQuery(sql, logData);
|
|
3815
|
-
if (transactionId === state.testTransactionCount) {
|
|
3816
|
-
const { afterCommit } = state;
|
|
3817
|
-
state.afterCommit = void 0;
|
|
3818
|
-
runAfterCommit(afterCommit, result);
|
|
3819
|
-
}
|
|
3820
|
-
return result;
|
|
3821
|
-
} finally {
|
|
3822
|
-
state.transactionId = transactionId - 1;
|
|
3823
|
-
}
|
|
3744
|
+
let opts = processStorageOptions(this, void 0, options);
|
|
3745
|
+
return this.q.adapter.transaction(this.internal.asyncStorage, opts, fn);
|
|
3824
3746
|
}
|
|
3825
3747
|
/**
|
|
3826
3748
|
* 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).
|
|
@@ -3932,49 +3854,6 @@ var QueryTransaction = class QueryTransaction {
|
|
|
3932
3854
|
return q;
|
|
3933
3855
|
}
|
|
3934
3856
|
};
|
|
3935
|
-
const runAfterCommit = (afterCommit, result) => {
|
|
3936
|
-
queueMicrotask(async () => {
|
|
3937
|
-
if (afterCommit) {
|
|
3938
|
-
const promises = [];
|
|
3939
|
-
let catchAfterCommitErrors;
|
|
3940
|
-
for (let i = 0, len = afterCommit.length; i < len;) {
|
|
3941
|
-
const first = afterCommit[i];
|
|
3942
|
-
if (typeof first === "function") {
|
|
3943
|
-
try {
|
|
3944
|
-
promises.push(first());
|
|
3945
|
-
} catch (err) {
|
|
3946
|
-
promises.push(Promise.reject(err));
|
|
3947
|
-
}
|
|
3948
|
-
i++;
|
|
3949
|
-
} else {
|
|
3950
|
-
const q = afterCommit[i + 1];
|
|
3951
|
-
if (q.q.catchAfterCommitErrors) (catchAfterCommitErrors ??= []).push(...q.q.catchAfterCommitErrors);
|
|
3952
|
-
for (const fn of afterCommit[i + 2]) try {
|
|
3953
|
-
promises.push(fn(first, q));
|
|
3954
|
-
} catch (err) {
|
|
3955
|
-
promises.push(Promise.reject(err));
|
|
3956
|
-
}
|
|
3957
|
-
i += 3;
|
|
3958
|
-
}
|
|
3959
|
-
}
|
|
3960
|
-
const getHookNames = () => {
|
|
3961
|
-
const hookNames = [];
|
|
3962
|
-
for (let i = 0, len = afterCommit.length; i < len;) {
|
|
3963
|
-
const first = afterCommit[i];
|
|
3964
|
-
if (typeof first === "function") {
|
|
3965
|
-
hookNames.push(first.name);
|
|
3966
|
-
i++;
|
|
3967
|
-
} else {
|
|
3968
|
-
for (const fn of afterCommit[i + 2]) hookNames.push(fn.name);
|
|
3969
|
-
i += 3;
|
|
3970
|
-
}
|
|
3971
|
-
}
|
|
3972
|
-
return hookNames;
|
|
3973
|
-
};
|
|
3974
|
-
await _runAfterCommitHooks(result, promises, getHookNames, catchAfterCommitErrors);
|
|
3975
|
-
}
|
|
3976
|
-
});
|
|
3977
|
-
};
|
|
3978
3857
|
/**
|
|
3979
3858
|
* See `transform` query method.
|
|
3980
3859
|
* This helper applies all transform functions to a result.
|
|
@@ -4440,7 +4319,7 @@ const then = async (q, adapter, state, beforeHooks, afterHooks, afterSaveHooks,
|
|
|
4440
4319
|
else {
|
|
4441
4320
|
const { batch } = sql;
|
|
4442
4321
|
if (log) logData = log.beforeQuery(beginSql);
|
|
4443
|
-
await adapter.transaction(async () => {
|
|
4322
|
+
await adapter.transaction(void 0, void 0, async () => {
|
|
4444
4323
|
if (log) log.afterQuery(beginSql, logData);
|
|
4445
4324
|
const res = await queryBatch(batch);
|
|
4446
4325
|
if (log) logData = log.beforeQuery(commitSql);
|
|
@@ -13746,34 +13625,34 @@ const _initQueryBuilder = (adapter, columnTypes, asyncStorage, commonOptions, op
|
|
|
13746
13625
|
qb.internal.managedRolesSql = options.managedRolesSql;
|
|
13747
13626
|
return qb.qb = qb;
|
|
13748
13627
|
};
|
|
13749
|
-
const
|
|
13750
|
-
|
|
13751
|
-
|
|
13752
|
-
} : locals;
|
|
13753
|
-
const getSetLocalsSql = (options) => {
|
|
13754
|
-
if (!options?.locals) return;
|
|
13755
|
-
return Object.entries(options.locals).map(([key, value]) => `SET LOCAL ${key}=${value}`).join("; ");
|
|
13756
|
-
};
|
|
13757
|
-
const getResetLocalsSql = (parentLocals, options) => {
|
|
13758
|
-
if (!options?.locals) return;
|
|
13759
|
-
return Object.entries(options.locals).reduce((acc, [key, value]) => {
|
|
13760
|
-
if (parentLocals[key] !== value) acc.push(`SET LOCAL ${key}=${parentLocals[key]}`);
|
|
13761
|
-
return acc;
|
|
13762
|
-
}, []).join("; ");
|
|
13628
|
+
const getSetRoleSql = (parentRole, options) => {
|
|
13629
|
+
if (!options?.role) return;
|
|
13630
|
+
return parentRole !== options.role ? `SET LOCAL ROLE ${quoteIdentifier(options.role)}` : void 0;
|
|
13763
13631
|
};
|
|
13764
|
-
const
|
|
13765
|
-
|
|
13766
|
-
options: void 0
|
|
13632
|
+
const getResetRoleSql = (parentRole, options) => {
|
|
13633
|
+
if (!options?.role) return;
|
|
13634
|
+
return parentRole !== options.role ? parentRole ? `SET LOCAL ROLE ${quoteIdentifier(parentRole)}` : `RESET ROLE` : void 0;
|
|
13767
13635
|
};
|
|
13768
|
-
const
|
|
13769
|
-
if (
|
|
13770
|
-
|
|
13771
|
-
|
|
13772
|
-
|
|
13773
|
-
|
|
13774
|
-
|
|
13775
|
-
|
|
13776
|
-
|
|
13636
|
+
const getSetConfigSql = (parentSetConfig, options) => {
|
|
13637
|
+
if (!options?.setConfig) return;
|
|
13638
|
+
const expressions = Object.entries(options.setConfig).reduce((acc, [key, value]) => {
|
|
13639
|
+
if (!parentSetConfig || parentSetConfig[key] !== value) acc.push(setConfigSql(key, value));
|
|
13640
|
+
return acc;
|
|
13641
|
+
}, []);
|
|
13642
|
+
return expressions.length ? `SELECT ${expressions.join(", ")}` : void 0;
|
|
13643
|
+
};
|
|
13644
|
+
const getResetSetConfigSql = (parentSetConfig, options) => {
|
|
13645
|
+
if (!options?.setConfig) return;
|
|
13646
|
+
const expressions = Object.entries(options.setConfig).reduce((acc, [key, value]) => {
|
|
13647
|
+
if (parentSetConfig && key in parentSetConfig) {
|
|
13648
|
+
if (parentSetConfig[key] !== value) acc.push(setConfigSql(key, parentSetConfig[key]));
|
|
13649
|
+
} else acc.push(setConfigSql(key, void 0));
|
|
13650
|
+
return acc;
|
|
13651
|
+
}, []);
|
|
13652
|
+
return expressions.length ? `SELECT ${expressions.join(", ")}` : void 0;
|
|
13653
|
+
};
|
|
13654
|
+
const setConfigSql = (key, value) => {
|
|
13655
|
+
return `set_config('${key.replace(/'/g, "''")}', '${typeof value === "string" ? value.replace(/'/g, "''") : value === void 0 ? "" : value}', true)`;
|
|
13777
13656
|
};
|
|
13778
13657
|
/**
|
|
13779
13658
|
* Shared runtime adapter orchestrator over a driver-specific adapter implementation.
|
|
@@ -13781,8 +13660,12 @@ const getTransactionArgs = (cbOrOptions, optionalCb) => {
|
|
|
13781
13660
|
var AdapterClass = class AdapterClass {
|
|
13782
13661
|
constructor(params) {
|
|
13783
13662
|
this.params = params;
|
|
13663
|
+
this.close = async () => {
|
|
13664
|
+
const { pool } = this;
|
|
13665
|
+
this.pool = this.driverAdapter.configure(this.config);
|
|
13666
|
+
await this.driverAdapter.close(pool);
|
|
13667
|
+
};
|
|
13784
13668
|
this.config = { ...params.config };
|
|
13785
|
-
this.locals = this.config.locals || emptyObject;
|
|
13786
13669
|
if (this.config.connectRetry) {
|
|
13787
13670
|
const connectRetryConfig = makeConnectRetryConfig(this.config.connectRetry === true ? emptyObject : this.config.connectRetry);
|
|
13788
13671
|
if (connectRetryConfig) {
|
|
@@ -13826,29 +13709,8 @@ var AdapterClass = class AdapterClass {
|
|
|
13826
13709
|
getSchema() {
|
|
13827
13710
|
return this.connectionState.schema;
|
|
13828
13711
|
}
|
|
13829
|
-
transaction(
|
|
13830
|
-
|
|
13831
|
-
return this.driverAdapter.begin(this.pool, (client) => {
|
|
13832
|
-
let promises;
|
|
13833
|
-
if (options?.sqlSessionState) {
|
|
13834
|
-
const { role, setConfig } = options.sqlSessionState;
|
|
13835
|
-
if (role) (promises ??= []).push(this.driverAdapter.queryClient(client, `SET ROLE ${role}`));
|
|
13836
|
-
if (setConfig && Object.keys(setConfig).length > 0) {
|
|
13837
|
-
const setExpressions = Object.entries(setConfig).map(([key, value]) => `set_config('${key.replace(/'/g, "''")}', '${typeof value === "string" ? value.replace(/'/g, "''") : value}', true)`).join(", ");
|
|
13838
|
-
(promises ??= []).push(this.driverAdapter.queryClient(client, `SELECT ${setExpressions}`));
|
|
13839
|
-
}
|
|
13840
|
-
}
|
|
13841
|
-
const localsSql = getSetLocalsSql(options);
|
|
13842
|
-
if (localsSql) (promises ??= []).push(this.driverAdapter.queryClient(client, localsSql));
|
|
13843
|
-
const locals = mergeLocals(this.locals, options);
|
|
13844
|
-
const transaction = cb(new TransactionAdapterClass(this, locals, client));
|
|
13845
|
-
return promises ? Promise.all(promises).then(() => transaction) : transaction;
|
|
13846
|
-
}, options?.options);
|
|
13847
|
-
}
|
|
13848
|
-
async close() {
|
|
13849
|
-
const { pool } = this;
|
|
13850
|
-
this.pool = this.driverAdapter.configure(this.config);
|
|
13851
|
-
await this.driverAdapter.close(pool);
|
|
13712
|
+
transaction(asyncStorage, options, cb) {
|
|
13713
|
+
return transaction(asyncStorage, this, this.driverAdapter, this.pool, options, cb);
|
|
13852
13714
|
}
|
|
13853
13715
|
assignError(to, from) {
|
|
13854
13716
|
const { errorFields } = this.driverAdapter;
|
|
@@ -13858,10 +13720,9 @@ var AdapterClass = class AdapterClass {
|
|
|
13858
13720
|
/**
|
|
13859
13721
|
* Shared runtime transaction adapter orchestrator over a driver-specific transaction adapter.
|
|
13860
13722
|
*/
|
|
13861
|
-
var TransactionAdapterClass = class
|
|
13862
|
-
constructor(adapter,
|
|
13723
|
+
var TransactionAdapterClass = class {
|
|
13724
|
+
constructor(adapter, client) {
|
|
13863
13725
|
this.adapter = adapter;
|
|
13864
|
-
this.locals = locals;
|
|
13865
13726
|
this.client = client;
|
|
13866
13727
|
this.driverAdapter = adapter.driverAdapter;
|
|
13867
13728
|
this.errorClass = this.adapter.errorClass;
|
|
@@ -13895,31 +13756,8 @@ var TransactionAdapterClass = class TransactionAdapterClass {
|
|
|
13895
13756
|
getSchema() {
|
|
13896
13757
|
return this.adapter.getSchema();
|
|
13897
13758
|
}
|
|
13898
|
-
async transaction(
|
|
13899
|
-
|
|
13900
|
-
let capturedRole;
|
|
13901
|
-
const capturedConfigs = {};
|
|
13902
|
-
const sqlSession = options?.sqlSessionState;
|
|
13903
|
-
if (sqlSession) {
|
|
13904
|
-
if (sqlSession.role) capturedRole = (await this.driverAdapter.queryClient(this.client, "SELECT current_role as role")).rows[0].role;
|
|
13905
|
-
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;
|
|
13906
|
-
}
|
|
13907
|
-
const localsSql = getSetLocalsSql(options);
|
|
13908
|
-
if (localsSql) this.driverAdapter.queryClient(this.client, localsSql);
|
|
13909
|
-
const locals = mergeLocals(this.locals, options);
|
|
13910
|
-
try {
|
|
13911
|
-
return await cb(new TransactionAdapterClass(this.adapter, locals, this.client));
|
|
13912
|
-
} finally {
|
|
13913
|
-
if (sqlSession) {
|
|
13914
|
-
if (capturedRole !== void 0) await this.driverAdapter.queryClient(this.client, `SET ROLE ${capturedRole}`);
|
|
13915
|
-
for (const [key, value] of Object.entries(capturedConfigs)) {
|
|
13916
|
-
const restoreValue = value === null ? "" : value;
|
|
13917
|
-
await this.driverAdapter.queryClient(this.client, `SELECT set_config('${key.replace(/'/g, "''")}', '${restoreValue.replace(/'/g, "''")}', true)`);
|
|
13918
|
-
}
|
|
13919
|
-
}
|
|
13920
|
-
const resetLocalsSql = getResetLocalsSql(this.locals, options);
|
|
13921
|
-
if (resetLocalsSql) await this.driverAdapter.queryClient(this.client, resetLocalsSql);
|
|
13922
|
-
}
|
|
13759
|
+
async transaction(asyncStorage, options, cb) {
|
|
13760
|
+
return transaction(asyncStorage, this.adapter, this.driverAdapter, this.client, options, cb, this);
|
|
13923
13761
|
}
|
|
13924
13762
|
close() {
|
|
13925
13763
|
return this.adapter.close();
|
|
@@ -13928,6 +13766,165 @@ var TransactionAdapterClass = class TransactionAdapterClass {
|
|
|
13928
13766
|
return this.adapter.assignError(to, from);
|
|
13929
13767
|
}
|
|
13930
13768
|
};
|
|
13769
|
+
const transaction = (asyncStorage, adapter, driverAdapter, poolOrClient, options, cb, transactionAdapter) => {
|
|
13770
|
+
const sql = { values: emptyArray };
|
|
13771
|
+
const log = options?.log;
|
|
13772
|
+
const state = asyncStorage?.getStore();
|
|
13773
|
+
const ctx = {
|
|
13774
|
+
state,
|
|
13775
|
+
logData: void 0
|
|
13776
|
+
};
|
|
13777
|
+
const transactionId = state?.transactionId !== void 0 ? state.transactionId + 1 : 0;
|
|
13778
|
+
const fn = (transactionAdapter) => {
|
|
13779
|
+
if (log) log.afterQuery(sql, ctx.logData);
|
|
13780
|
+
if (log) ctx.logData = log.beforeQuery(commitSql);
|
|
13781
|
+
if (state || !asyncStorage) {
|
|
13782
|
+
const parentTransactionRole = state?.transactionRole;
|
|
13783
|
+
const parentTransactionSetConfig = state?.transactionSetConfig;
|
|
13784
|
+
if (state) {
|
|
13785
|
+
state.transactionId = transactionId;
|
|
13786
|
+
if (options) {
|
|
13787
|
+
if (options.role) state.transactionRole = options.role;
|
|
13788
|
+
if (options.setConfig) state.transactionSetConfig = {
|
|
13789
|
+
...state.transactionSetConfig,
|
|
13790
|
+
...options.setConfig
|
|
13791
|
+
};
|
|
13792
|
+
}
|
|
13793
|
+
}
|
|
13794
|
+
return Promise.resolve(cb(transactionAdapter)).finally(() => {
|
|
13795
|
+
if (state) {
|
|
13796
|
+
state.transactionId = transactionId - 1;
|
|
13797
|
+
state.transactionRole = parentTransactionRole;
|
|
13798
|
+
state.transactionSetConfig = parentTransactionSetConfig;
|
|
13799
|
+
}
|
|
13800
|
+
});
|
|
13801
|
+
}
|
|
13802
|
+
ctx.state = {
|
|
13803
|
+
...options,
|
|
13804
|
+
role: void 0,
|
|
13805
|
+
setConfig: void 0,
|
|
13806
|
+
transactionAdapter,
|
|
13807
|
+
transactionId,
|
|
13808
|
+
transactionRole: options?.role,
|
|
13809
|
+
transactionSetConfig: options?.setConfig
|
|
13810
|
+
};
|
|
13811
|
+
return asyncStorage.run(ctx.state, () => cb(transactionAdapter));
|
|
13812
|
+
};
|
|
13813
|
+
transactionAdapter ??= state?.transactionAdapter;
|
|
13814
|
+
if (transactionAdapter) return nestedTransaction(adapter, driverAdapter, transactionAdapter, poolOrClient, options, fn, ctx, transactionId, sql, log);
|
|
13815
|
+
else return realTransaction(adapter, driverAdapter, poolOrClient, options, fn, ctx, sql, log);
|
|
13816
|
+
};
|
|
13817
|
+
const realTransaction = async (adapter, driverAdapter, pool, options, cb, ctx, sql, log) => {
|
|
13818
|
+
let trxOpts;
|
|
13819
|
+
if (options?.level) trxOpts = `ISOLATION LEVEL ${options.level}`;
|
|
13820
|
+
if (options?.readOnly !== void 0) {
|
|
13821
|
+
const add = `READ ${options.readOnly ? "ONLY" : "WRITE"}`;
|
|
13822
|
+
trxOpts = trxOpts ? trxOpts + " " + add : add;
|
|
13823
|
+
}
|
|
13824
|
+
if (options?.deferrable !== void 0) {
|
|
13825
|
+
const add = `${options.deferrable ? "" : "NOT "}DEFERRABLE`;
|
|
13826
|
+
trxOpts = trxOpts ? trxOpts + " " + add : add;
|
|
13827
|
+
}
|
|
13828
|
+
if (log) {
|
|
13829
|
+
sql.text = trxOpts ? `BEGIN ${trxOpts}` : "BEGIN";
|
|
13830
|
+
ctx.logData = log.beforeQuery(sql);
|
|
13831
|
+
}
|
|
13832
|
+
const result = await driverAdapter.begin(pool, (client) => {
|
|
13833
|
+
let promises;
|
|
13834
|
+
const setRoleSql = getSetRoleSql(void 0, options);
|
|
13835
|
+
if (setRoleSql) (promises ??= []).push(driverAdapter.queryClient(client, setRoleSql));
|
|
13836
|
+
const setConfigSql = getSetConfigSql(void 0, options);
|
|
13837
|
+
if (setConfigSql) (promises ??= []).push(driverAdapter.queryClient(client, setConfigSql));
|
|
13838
|
+
const transaction = cb(new TransactionAdapterClass(adapter, client));
|
|
13839
|
+
return promises ? Promise.all(promises).then(() => transaction) : transaction;
|
|
13840
|
+
}, trxOpts).catch((err) => {
|
|
13841
|
+
if (log) log.afterQuery(rollbackSql, ctx.logData);
|
|
13842
|
+
throw err;
|
|
13843
|
+
});
|
|
13844
|
+
if (log) log.afterQuery(commitSql, ctx.logData);
|
|
13845
|
+
if (ctx.state) runAfterCommit(ctx.state.afterCommit, result);
|
|
13846
|
+
return result;
|
|
13847
|
+
};
|
|
13848
|
+
const nestedTransaction = async (adapter, driverAdapter, transactionAdapter, client, options, cb, ctx, transactionId, sql, log) => {
|
|
13849
|
+
const state = ctx.state;
|
|
13850
|
+
const parentRole = state?.transactionRole;
|
|
13851
|
+
const parentSetConfig = state?.transactionSetConfig;
|
|
13852
|
+
sql.text = `SAVEPOINT "t${transactionId}"`;
|
|
13853
|
+
if (log) ctx.logData = log.beforeQuery(sql);
|
|
13854
|
+
await transactionAdapter.arrays(sql.text, sql.values);
|
|
13855
|
+
const setRoleSql = getSetRoleSql(parentRole, options);
|
|
13856
|
+
if (setRoleSql) driverAdapter.queryClient(client, setRoleSql);
|
|
13857
|
+
const setConfigSql = getSetConfigSql(parentSetConfig, options);
|
|
13858
|
+
if (setConfigSql) driverAdapter.queryClient(client, setConfigSql);
|
|
13859
|
+
let result;
|
|
13860
|
+
try {
|
|
13861
|
+
result = await cb(new TransactionAdapterClass(adapter, client));
|
|
13862
|
+
} catch (err) {
|
|
13863
|
+
sql.text = `ROLLBACK TO SAVEPOINT "t${transactionId}"`;
|
|
13864
|
+
if (log) ctx.logData = log.beforeQuery(sql);
|
|
13865
|
+
await transactionAdapter.arrays(sql.text, sql.values);
|
|
13866
|
+
if (log) log.afterQuery(sql, ctx.logData);
|
|
13867
|
+
throw err;
|
|
13868
|
+
} finally {
|
|
13869
|
+
const resetRoleSql = getResetRoleSql(parentRole, options);
|
|
13870
|
+
if (resetRoleSql) await driverAdapter.queryClient(client, resetRoleSql);
|
|
13871
|
+
}
|
|
13872
|
+
const resetSetConfigSql = getResetSetConfigSql(parentSetConfig, options);
|
|
13873
|
+
if (resetSetConfigSql) driverAdapter.queryClient(client, resetSetConfigSql);
|
|
13874
|
+
sql.text = `RELEASE SAVEPOINT "t${transactionId}"`;
|
|
13875
|
+
if (log) ctx.logData = log.beforeQuery(sql);
|
|
13876
|
+
await transactionAdapter.arrays(sql.text, sql.values);
|
|
13877
|
+
if (log) log.afterQuery(sql, ctx.logData);
|
|
13878
|
+
if (ctx.state && transactionId === ctx.state.testTransactionCount) {
|
|
13879
|
+
const { afterCommit } = ctx.state;
|
|
13880
|
+
ctx.state.afterCommit = void 0;
|
|
13881
|
+
runAfterCommit(afterCommit, result);
|
|
13882
|
+
}
|
|
13883
|
+
return result;
|
|
13884
|
+
};
|
|
13885
|
+
const runAfterCommit = (afterCommit, result) => {
|
|
13886
|
+
queueMicrotask(async () => {
|
|
13887
|
+
if (afterCommit) {
|
|
13888
|
+
const promises = [];
|
|
13889
|
+
let catchAfterCommitErrors;
|
|
13890
|
+
for (let i = 0, len = afterCommit.length; i < len;) {
|
|
13891
|
+
const first = afterCommit[i];
|
|
13892
|
+
if (typeof first === "function") {
|
|
13893
|
+
try {
|
|
13894
|
+
promises.push(first());
|
|
13895
|
+
} catch (err) {
|
|
13896
|
+
promises.push(Promise.reject(err));
|
|
13897
|
+
}
|
|
13898
|
+
i++;
|
|
13899
|
+
} else {
|
|
13900
|
+
const q = afterCommit[i + 1];
|
|
13901
|
+
if (q.q.catchAfterCommitErrors) (catchAfterCommitErrors ??= []).push(...q.q.catchAfterCommitErrors);
|
|
13902
|
+
for (const fn of afterCommit[i + 2]) try {
|
|
13903
|
+
promises.push(fn(first, q));
|
|
13904
|
+
} catch (err) {
|
|
13905
|
+
promises.push(Promise.reject(err));
|
|
13906
|
+
}
|
|
13907
|
+
i += 3;
|
|
13908
|
+
}
|
|
13909
|
+
}
|
|
13910
|
+
const getHookNames = () => {
|
|
13911
|
+
const hookNames = [];
|
|
13912
|
+
for (let i = 0, len = afterCommit.length; i < len;) {
|
|
13913
|
+
const first = afterCommit[i];
|
|
13914
|
+
if (typeof first === "function") {
|
|
13915
|
+
hookNames.push(first.name);
|
|
13916
|
+
i++;
|
|
13917
|
+
} else {
|
|
13918
|
+
for (const fn of afterCommit[i + 2]) hookNames.push(fn.name);
|
|
13919
|
+
i += 3;
|
|
13920
|
+
}
|
|
13921
|
+
}
|
|
13922
|
+
return hookNames;
|
|
13923
|
+
};
|
|
13924
|
+
await _runAfterCommitHooks(result, promises, getHookNames, catchAfterCommitErrors);
|
|
13925
|
+
}
|
|
13926
|
+
});
|
|
13927
|
+
};
|
|
13931
13928
|
const runQueryHandlePool = async (pool, driverAdapter, text, values, startingSavepoint, releasingSavepoint, sqlSessionState, arraysMode, client) => {
|
|
13932
13929
|
const setup = sqlSessionContextComputeSetup(sqlSessionState);
|
|
13933
13930
|
if (client || !driverAdapter.manualPool && !setup) return runQueryHandleSetupAndCleanup(driverAdapter, client || pool, text, values, startingSavepoint, releasingSavepoint, setup, arraysMode);
|
|
@@ -13987,13 +13984,13 @@ const cloneAdapterConfig = (config, params) => {
|
|
|
13987
13984
|
return clonedConfig;
|
|
13988
13985
|
};
|
|
13989
13986
|
const createDriverAdapterConfig = (config, state) => {
|
|
13990
|
-
const
|
|
13991
|
-
delete
|
|
13992
|
-
if (state.searchPath && state.searchPath !== "public")
|
|
13987
|
+
const setConfig = config.setConfig ? { ...config.setConfig } : {};
|
|
13988
|
+
delete setConfig.search_path;
|
|
13989
|
+
if (state.searchPath && state.searchPath !== "public") setConfig.search_path = state.searchPath;
|
|
13993
13990
|
const driverConfig = {
|
|
13994
13991
|
...config,
|
|
13995
13992
|
searchPath: state.searchPath,
|
|
13996
|
-
|
|
13993
|
+
setConfig
|
|
13997
13994
|
};
|
|
13998
13995
|
if (driverConfig.databaseURL) {
|
|
13999
13996
|
const url = new URL(driverConfig.databaseURL);
|
|
@@ -14213,7 +14210,7 @@ const testTransaction = {
|
|
|
14213
14210
|
const data = db.internal[trxForTest];
|
|
14214
14211
|
const last = data?.pop();
|
|
14215
14212
|
if (!last) return;
|
|
14216
|
-
if (data?.length
|
|
14213
|
+
if (!data?.length) Object.assign(db.baseQuery.q.adapter, last.adapter);
|
|
14217
14214
|
last.reject?.(new Rollback());
|
|
14218
14215
|
return last.promise;
|
|
14219
14216
|
},
|