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.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 = sqlSessionContextNormalizeSetConfig(options.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 ${quoteRoleIdentifier(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 ${quoteRoleIdentifier(captured.previousRole)}`));
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
- let log;
3615
- if (options.log !== void 0 && !query.q.log) log = logParamToLogObject(query.q.logger, options.log);
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
- const sql = { values: emptyArray };
3727
- const opts = processStorageOptions(this, void 0, options);
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 mergeLocals = (locals, options) => options?.locals ? {
13727
- ...locals,
13728
- ...options.locals
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 transactionArgs = {
13742
- cb: void 0,
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 getTransactionArgs = (cbOrOptions, optionalCb) => {
13746
- if (typeof cbOrOptions === "function") {
13747
- transactionArgs.cb = cbOrOptions;
13748
- transactionArgs.options = void 0;
13749
- } else {
13750
- transactionArgs.options = cbOrOptions;
13751
- transactionArgs.cb = optionalCb;
13752
- }
13753
- return transactionArgs;
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(cbOrOptions, optionalCb) {
13807
- const { cb, options } = getTransactionArgs(cbOrOptions, optionalCb);
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 TransactionAdapterClass {
13839
- constructor(adapter, locals, client) {
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(cbOrOptions, optionalCb) {
13876
- const { cb, options } = getTransactionArgs(cbOrOptions, optionalCb);
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 locals = config.locals ? { ...config.locals } : {};
13968
- delete locals.search_path;
13969
- if (state.searchPath && state.searchPath !== "public") locals.search_path = state.searchPath;
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
- locals
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 === 1) Object.assign(db.baseQuery.q.adapter, data[0].adapter);
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
  },