pqb 0.73.1 → 0.73.2

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/bun.js CHANGED
@@ -126,19 +126,24 @@ const BunAdapter = {
126
126
  releaseBunClient(client);
127
127
  }
128
128
  },
129
- async savepoint(client, _setClient, name, cb) {
129
+ async savepoint(client, _setClient, name, cb, onSavepoint, beforeRelease, onRelease, beforeRollback, onRollback) {
130
130
  const safeName = (0, pqb_internal.quoteIdentifier)(name);
131
131
  try {
132
132
  await queryClient(client, `SAVEPOINT ${safeName}`);
133
+ onSavepoint?.();
133
134
  const res = await cb();
135
+ beforeRelease?.();
134
136
  await queryClient(client, `RELEASE SAVEPOINT ${safeName}`);
137
+ onRelease?.();
135
138
  return res;
136
139
  } catch (err) {
140
+ beforeRollback?.();
137
141
  await queryClient(client, `ROLLBACK TO SAVEPOINT ${safeName}`);
142
+ onRollback?.();
138
143
  throw err;
139
144
  }
140
145
  },
141
- async hackySavepoint(client, _setClient, state, text, values, arraysMode) {
146
+ async hackySavepoint(client, _setClient, state, text, values, arraysMode, onSavepoint, beforeRelease, onRelease, beforeRollback, onRollback) {
142
147
  const safeName = (0, pqb_internal.quoteIdentifier)(state.name);
143
148
  let resolve;
144
149
  let reject;
@@ -155,6 +160,7 @@ const BunAdapter = {
155
160
  const savepointPromise = (async () => {
156
161
  try {
157
162
  await queryClient(client, `SAVEPOINT ${safeName}`);
163
+ onSavepoint?.();
158
164
  try {
159
165
  const res = await queryClient(client, text, values, arraysMode);
160
166
  resultResolve?.(res);
@@ -163,10 +169,14 @@ const BunAdapter = {
163
169
  throw err;
164
170
  }
165
171
  const result = await promise;
172
+ beforeRelease?.();
166
173
  await queryClient(client, `RELEASE SAVEPOINT ${safeName}`);
174
+ onRelease?.();
167
175
  return result;
168
176
  } catch (err) {
177
+ beforeRollback?.();
169
178
  await queryClient(client, `ROLLBACK TO SAVEPOINT ${safeName}`);
179
+ onRollback?.();
170
180
  throw err;
171
181
  }
172
182
  })();
package/dist/bun.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"bun.js","names":["defaultSchemaConfig","createDbWithAdapter","AdapterClass","noop","quoteIdentifier"],"sources":["../src/adapters/driver-adapter-shared.ts","../src/adapters/bun.ts"],"sourcesContent":["export interface PostgresInterval {\n years: number;\n months: number;\n days: number;\n hours: number;\n minutes: number;\n seconds: number;\n milliseconds: number;\n}\n\nconst intervalRegExp =\n /^\\s*(?:([+-]?\\d+)\\s+years?)?\\s*(?:([+-]?\\d+)\\s+mons?)?\\s*(?:([+-]?\\d+)\\s+days?)?\\s*(?:([+-])?(\\d+):(\\d\\d):(\\d\\d(?:\\.\\d{1,6})?))?\\s*$/;\n\nexport const parseInterval = (str: string): PostgresInterval => {\n const [, years, months, days, timeSign, hours, minutes, seconds] =\n intervalRegExp.exec(str) || [];\n const timeMultiplier = timeSign === '-' ? -1 : 1;\n const secondsFloat = Number(seconds) || 0;\n const wholeSeconds = Math.floor(secondsFloat);\n\n return {\n years: years ? Number(years) : 0,\n months: months ? Number(months) : 0,\n days: days ? Number(days) : 0,\n hours: hours ? timeMultiplier * Number(hours) : 0,\n minutes: minutes ? timeMultiplier * Number(minutes) : 0,\n seconds: timeMultiplier * wholeSeconds,\n milliseconds:\n Math.round(timeMultiplier * (secondsFloat - wholeSeconds) * 1000000) /\n 1000,\n };\n};\n","import {\n AdapterClass,\n AdapterConfigBase,\n ColumnSchemaConfig,\n DbOptions,\n DbResult,\n DefaultColumnTypes,\n defaultSchemaConfig,\n DefaultSchemaConfig,\n DriverAdapter,\n noop,\n QueryResult,\n QueryResultRow,\n QuerySchema,\n quoteIdentifier,\n RecordUnknown,\n AdapterSchemaConfigOptions,\n} from 'pqb/internal';\nimport { createDbWithAdapter } from 'pqb';\nimport { HackySavepointState } from './adapter';\nimport { parseInterval } from './driver-adapter-shared';\n\nconst schemaConfig: AdapterSchemaConfigOptions = {\n arrayEncode: (input) => {\n return getBun().sql.array(input);\n },\n intervalParse: parseInterval,\n jsonEncodedByDriver: true,\n dateParsedByDriver: true,\n};\n\nexport const bunSchemaConfig = Object.assign(\n () => defaultSchemaConfig(schemaConfig),\n schemaConfig,\n);\n\nexport interface CreateBunDbOptions<\n SchemaConfig extends ColumnSchemaConfig,\n ColumnTypes,\n>\n extends BunAdapterOptions, DbOptions<SchemaConfig, ColumnTypes> {}\n\nexport const createDb = <\n SchemaConfig extends ColumnSchemaConfig = DefaultSchemaConfig,\n ColumnTypes = DefaultColumnTypes<SchemaConfig>,\n>({\n log,\n ...options\n}: CreateBunDbOptions<SchemaConfig, ColumnTypes>): DbResult<ColumnTypes> => {\n return createDbWithAdapter({\n schemaConfig: bunSchemaConfig as unknown as () => SchemaConfig,\n ...options,\n log,\n adapter: new AdapterClass({\n driverAdapter: BunAdapter,\n config: options,\n }),\n });\n};\n\nexport interface BunOptions {\n hostname?: string;\n port?: number;\n database?: string;\n username?: string;\n password?: string | (() => string | Promise<string>);\n max?: number;\n idleTimeout?: number;\n maxLifetime?: number;\n connectionTimeout?: number;\n prepare?: boolean;\n tls?: unknown;\n}\n\nexport interface BunAdapterOptions extends AdapterConfigBase, BunOptions {\n schema?: QuerySchema;\n searchPath?: string;\n ssl?: unknown;\n}\n\ninterface Bun {\n SQL: BunSqlConstructor;\n sql: {\n array(input: unknown): unknown;\n };\n}\n\ninterface BunSqlConstructor {\n new (options?: BunSqlOptions | string): BunSql;\n PostgresError: ErrorClass;\n}\n\ninterface BunSqlOptions extends BunOptions {\n url?: string;\n ssl?: unknown;\n}\n\ninterface BunSql {\n unsafe<Row extends QueryResultRow = QueryResultRow>(\n text: string,\n values?: unknown[],\n ): BunSqlQuery<Row>;\n reserve(): Promise<BunReservedSql>;\n close(options?: { timeout?: number }): Promise<void>;\n}\n\ninterface BunReservedSql extends BunSql {\n release(): void;\n}\n\ninterface BunSqlQuery<\n Row extends QueryResultRow = QueryResultRow,\n> extends PromiseLike<BunSqlResult<Row>> {\n values(): Promise<BunSqlResult<unknown[]>>;\n}\n\ninterface BunSqlResult<Row = unknown> extends Array<Row> {\n count?: number;\n affectedRows?: number;\n}\n\n// oxlint-disable-next-line typescript/no-explicit-any\ntype ErrorClass = new (...args: any[]) => Error;\n\nconst getBun = (): Bun => {\n const Bun = (globalThis as unknown as { Bun?: Bun }).Bun;\n if (!Bun?.SQL) {\n throw new Error('Bun.SQL is only available when running in Bun');\n }\n\n return Bun;\n};\n\nconst getBunPostgresError = (): ErrorClass => {\n return (\n (globalThis as unknown as { Bun?: { SQL: BunSqlConstructor } }).Bun?.SQL\n .PostgresError ?? (Error as ErrorClass)\n );\n};\n\nconst queryClient = <T = QueryResultRow>(\n client: BunSql,\n text: string,\n values?: unknown[],\n arraysMode?: boolean,\n): Promise<QueryResult<T>> => {\n const runQuery = () => {\n const query = client.unsafe(text, values);\n const resultPromise: PromiseLike<BunSqlResult> = arraysMode\n ? query.values()\n : query;\n\n return Promise.resolve(resultPromise).then((result) => {\n return normalizeResult(result, arraysMode) as QueryResult<T>;\n });\n };\n\n // Keep a single transactional connection ordered when savepoints are active.\n const { __lock } = client as unknown as { __lock?: Promise<unknown> };\n if (__lock) {\n let resolve: (() => void) | undefined;\n (client as unknown as RecordUnknown).__lock = new Promise<void>((res) => {\n resolve = res;\n });\n\n return __lock.then(() => {\n const promise = runQuery();\n promise.then(resolve, resolve);\n return promise;\n });\n }\n\n const promise = runQuery();\n\n (client as unknown as { __lock?: Promise<unknown> }).__lock =\n promise.catch(noop);\n\n return promise;\n};\n\nconst borrowBunClient = (pool: BunSql): Promise<BunReservedSql> => {\n return pool.reserve();\n};\n\nconst releaseBunClient = (client: BunReservedSql): void => {\n client.release();\n};\n\nexport const BunAdapter: DriverAdapter = {\n noFieldsForArrays: true,\n manualPool: true,\n schemaConfig,\n errorClass: getBunPostgresError(),\n errorFields: {\n message: 'message',\n severity: 'severity',\n code: 'errno',\n detail: 'detail',\n schema: 'schema',\n table: 'table',\n column: 'column',\n dataType: 'dataType',\n constraint: 'constraint',\n hint: 'hint',\n position: 'position',\n internalPosition: 'internalPosition',\n internalQuery: 'internalQuery',\n where: 'where',\n file: 'file',\n line: 'line',\n routine: 'routine',\n },\n\n configure(config: BunAdapterOptions): BunSql {\n return new (getBun().SQL)(makeOptions(config));\n },\n\n queryClient,\n\n borrow(pool: BunSql): Promise<BunReservedSql> {\n return borrowBunClient(pool);\n },\n\n release(client: BunReservedSql): void {\n releaseBunClient(client);\n },\n\n async begin<DriverClient, Result>(\n pool: BunSql,\n cb: (adapter: DriverClient) => Promise<Result>,\n options?: string,\n ): Promise<Result> {\n const client = await borrowBunClient(pool);\n\n try {\n await queryClient(client, options ? 'BEGIN ' + options : 'BEGIN');\n\n let result;\n try {\n result = await cb(client as DriverClient);\n } catch (err) {\n await queryClient(client, 'ROLLBACK');\n throw err;\n }\n\n await queryClient(client, 'COMMIT');\n return result as Result;\n } finally {\n releaseBunClient(client);\n }\n },\n\n async savepoint<T>(\n client: BunSql,\n // Bun doesn't need to switch the client in a savepoint.\n _setClient: (client: BunSql) => void,\n name: string,\n cb: () => Promise<T>,\n ): Promise<T> {\n const safeName = quoteIdentifier(name);\n try {\n await queryClient(client, `SAVEPOINT ${safeName}`);\n const res = await cb();\n await queryClient(client, `RELEASE SAVEPOINT ${safeName}`);\n return res;\n } catch (err) {\n await queryClient(client, `ROLLBACK TO SAVEPOINT ${safeName}`);\n throw err;\n }\n },\n\n async hackySavepoint<T extends QueryResultRow>(\n client: BunSql,\n // Bun doesn't need to switch the client in a savepoint.\n _setClient: (client: BunSql) => void,\n state: HackySavepointState,\n text: string,\n values?: unknown[],\n arraysMode?: boolean,\n ): Promise<QueryResult<T>> {\n const safeName = quoteIdentifier(state.name);\n\n let resolve: (() => void) | undefined;\n let reject: ((err: unknown) => void) | undefined;\n const promise = new Promise<void>((res, rej) => {\n resolve = res;\n reject = rej;\n });\n\n let resultResolve: ((res: QueryResult<T>) => void) | undefined;\n let resultReject: ((err: unknown) => void) | undefined;\n const resultPromise = new Promise<QueryResult<T>>((res, rej) => {\n resultResolve = res;\n resultReject = rej;\n });\n\n const savepointPromise = (async () => {\n try {\n await queryClient(client, `SAVEPOINT ${safeName}`);\n\n try {\n const res = await queryClient<T>(client, text, values, arraysMode);\n resultResolve?.(res as QueryResult<T>);\n } catch (err) {\n resultReject?.(err);\n throw err;\n }\n\n const result = await promise;\n await queryClient(client, `RELEASE SAVEPOINT ${safeName}`);\n return result;\n } catch (err) {\n await queryClient(client, `ROLLBACK TO SAVEPOINT ${safeName}`);\n throw err;\n }\n })();\n\n state.activeSavepoint = {\n async release() {\n resolve?.();\n await savepointPromise;\n },\n async rollback(err) {\n reject?.(err);\n await savepointPromise.catch(noop);\n },\n };\n\n return resultPromise;\n },\n\n close(pool: BunSql): Promise<void> {\n return pool.close();\n },\n};\n\nconst makeOptions = (config: BunAdapterOptions): BunSqlOptions => {\n const {\n databaseURL,\n host,\n user,\n password,\n port,\n database,\n max,\n idleTimeout,\n maxLifetime,\n connectionTimeout,\n prepare,\n tls,\n ssl,\n setConfig,\n searchPath,\n } = config;\n\n return {\n url:\n databaseURL && makeUrl(databaseURL, setConfig?.search_path ?? searchPath),\n hostname: host,\n username: user,\n password,\n port,\n database,\n max,\n idleTimeout,\n maxLifetime,\n connectionTimeout,\n prepare,\n tls,\n ssl,\n };\n};\n\nconst makeUrl = (databaseURL: string, searchPath?: string): string => {\n if (!searchPath) return databaseURL;\n\n const url = new URL(databaseURL);\n url.searchParams.set('options', `-c search_path=${searchPath}`);\n return url.toString();\n};\n\nconst normalizeResult = <T>(\n result: BunSqlResult<T>,\n arraysMode?: boolean,\n): QueryResult<T> | QueryResult<T>[] => {\n if (!arraysMode && isMultiResult(result)) {\n return result.map((item) => new BunQueryResult(item, arraysMode));\n }\n\n return new BunQueryResult(result, arraysMode);\n};\n\nclass BunQueryResult<T> implements QueryResult<T> {\n public rowCount: number;\n public rows: T[];\n private _fields?: QueryResult<T>['fields'];\n\n constructor(\n private result: BunSqlResult<T>,\n private isArray?: boolean,\n ) {\n this.rowCount = result.count ?? result.affectedRows ?? result.length;\n\n // creating new Array because BunSqlResult is not a real array - can't do spread on it\n this.rows = Array.from(result) as T[];\n }\n\n get fields(): QueryResult<T>['fields'] {\n if (this.isArray) {\n throw new Error('Bun does not support fields on array result');\n }\n\n return (this._fields ??= getFields(this.result));\n }\n}\n\nconst isMultiResult = <T>(\n result: BunSqlResult<T>,\n): result is BunSqlResult<T>[] & BunSqlResult<T> => {\n return Array.isArray(result[0]);\n};\n\nconst getFields = <T>(rows: T[]): { name: string }[] => {\n const first = rows[0];\n if (!first || Array.isArray(first) || typeof first !== 'object') return [];\n\n return Object.keys(first).map((name) => ({ name }));\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"bun.js","names":["defaultSchemaConfig","createDbWithAdapter","AdapterClass","noop","quoteIdentifier"],"sources":["../src/adapters/driver-adapter-shared.ts","../src/adapters/bun.ts"],"sourcesContent":["export interface PostgresInterval {\n years: number;\n months: number;\n days: number;\n hours: number;\n minutes: number;\n seconds: number;\n milliseconds: number;\n}\n\nconst intervalRegExp =\n /^\\s*(?:([+-]?\\d+)\\s+years?)?\\s*(?:([+-]?\\d+)\\s+mons?)?\\s*(?:([+-]?\\d+)\\s+days?)?\\s*(?:([+-])?(\\d+):(\\d\\d):(\\d\\d(?:\\.\\d{1,6})?))?\\s*$/;\n\nexport const parseInterval = (str: string): PostgresInterval => {\n const [, years, months, days, timeSign, hours, minutes, seconds] =\n intervalRegExp.exec(str) || [];\n const timeMultiplier = timeSign === '-' ? -1 : 1;\n const secondsFloat = Number(seconds) || 0;\n const wholeSeconds = Math.floor(secondsFloat);\n\n return {\n years: years ? Number(years) : 0,\n months: months ? Number(months) : 0,\n days: days ? Number(days) : 0,\n hours: hours ? timeMultiplier * Number(hours) : 0,\n minutes: minutes ? timeMultiplier * Number(minutes) : 0,\n seconds: timeMultiplier * wholeSeconds,\n milliseconds:\n Math.round(timeMultiplier * (secondsFloat - wholeSeconds) * 1000000) /\n 1000,\n };\n};\n","import {\n AdapterClass,\n AdapterConfigBase,\n ColumnSchemaConfig,\n DbOptions,\n DbResult,\n DefaultColumnTypes,\n defaultSchemaConfig,\n DefaultSchemaConfig,\n DriverAdapter,\n noop,\n QueryResult,\n QueryResultRow,\n QuerySchema,\n quoteIdentifier,\n RecordUnknown,\n AdapterSchemaConfigOptions,\n} from 'pqb/internal';\nimport { createDbWithAdapter } from 'pqb';\nimport { HackySavepointState, SavepointCallback } from './adapter';\nimport { parseInterval } from './driver-adapter-shared';\n\nconst schemaConfig: AdapterSchemaConfigOptions = {\n arrayEncode: (input) => {\n return getBun().sql.array(input);\n },\n intervalParse: parseInterval,\n jsonEncodedByDriver: true,\n dateParsedByDriver: true,\n};\n\nexport const bunSchemaConfig = Object.assign(\n () => defaultSchemaConfig(schemaConfig),\n schemaConfig,\n);\n\nexport interface CreateBunDbOptions<\n SchemaConfig extends ColumnSchemaConfig,\n ColumnTypes,\n>\n extends BunAdapterOptions, DbOptions<SchemaConfig, ColumnTypes> {}\n\nexport const createDb = <\n SchemaConfig extends ColumnSchemaConfig = DefaultSchemaConfig,\n ColumnTypes = DefaultColumnTypes<SchemaConfig>,\n>({\n log,\n ...options\n}: CreateBunDbOptions<SchemaConfig, ColumnTypes>): DbResult<ColumnTypes> => {\n return createDbWithAdapter({\n schemaConfig: bunSchemaConfig as unknown as () => SchemaConfig,\n ...options,\n log,\n adapter: new AdapterClass({\n driverAdapter: BunAdapter,\n config: options,\n }),\n });\n};\n\nexport interface BunOptions {\n hostname?: string;\n port?: number;\n database?: string;\n username?: string;\n password?: string | (() => string | Promise<string>);\n max?: number;\n idleTimeout?: number;\n maxLifetime?: number;\n connectionTimeout?: number;\n prepare?: boolean;\n tls?: unknown;\n}\n\nexport interface BunAdapterOptions extends AdapterConfigBase, BunOptions {\n schema?: QuerySchema;\n searchPath?: string;\n ssl?: unknown;\n}\n\ninterface Bun {\n SQL: BunSqlConstructor;\n sql: {\n array(input: unknown): unknown;\n };\n}\n\ninterface BunSqlConstructor {\n new (options?: BunSqlOptions | string): BunSql;\n PostgresError: ErrorClass;\n}\n\ninterface BunSqlOptions extends BunOptions {\n url?: string;\n ssl?: unknown;\n}\n\ninterface BunSql {\n unsafe<Row extends QueryResultRow = QueryResultRow>(\n text: string,\n values?: unknown[],\n ): BunSqlQuery<Row>;\n reserve(): Promise<BunReservedSql>;\n close(options?: { timeout?: number }): Promise<void>;\n}\n\ninterface BunReservedSql extends BunSql {\n release(): void;\n}\n\ninterface BunSqlQuery<\n Row extends QueryResultRow = QueryResultRow,\n> extends PromiseLike<BunSqlResult<Row>> {\n values(): Promise<BunSqlResult<unknown[]>>;\n}\n\ninterface BunSqlResult<Row = unknown> extends Array<Row> {\n count?: number;\n affectedRows?: number;\n}\n\n// oxlint-disable-next-line typescript/no-explicit-any\ntype ErrorClass = new (...args: any[]) => Error;\n\nconst getBun = (): Bun => {\n const Bun = (globalThis as unknown as { Bun?: Bun }).Bun;\n if (!Bun?.SQL) {\n throw new Error('Bun.SQL is only available when running in Bun');\n }\n\n return Bun;\n};\n\nconst getBunPostgresError = (): ErrorClass => {\n return (\n (globalThis as unknown as { Bun?: { SQL: BunSqlConstructor } }).Bun?.SQL\n .PostgresError ?? (Error as ErrorClass)\n );\n};\n\nconst queryClient = <T = QueryResultRow>(\n client: BunSql,\n text: string,\n values?: unknown[],\n arraysMode?: boolean,\n): Promise<QueryResult<T>> => {\n const runQuery = () => {\n const query = client.unsafe(text, values);\n const resultPromise: PromiseLike<BunSqlResult> = arraysMode\n ? query.values()\n : query;\n\n return Promise.resolve(resultPromise).then((result) => {\n return normalizeResult(result, arraysMode) as QueryResult<T>;\n });\n };\n\n // Keep a single transactional connection ordered when savepoints are active.\n const { __lock } = client as unknown as { __lock?: Promise<unknown> };\n if (__lock) {\n let resolve: (() => void) | undefined;\n (client as unknown as RecordUnknown).__lock = new Promise<void>((res) => {\n resolve = res;\n });\n\n return __lock.then(() => {\n const promise = runQuery();\n promise.then(resolve, resolve);\n return promise;\n });\n }\n\n const promise = runQuery();\n\n (client as unknown as { __lock?: Promise<unknown> }).__lock =\n promise.catch(noop);\n\n return promise;\n};\n\nconst borrowBunClient = (pool: BunSql): Promise<BunReservedSql> => {\n return pool.reserve();\n};\n\nconst releaseBunClient = (client: BunReservedSql): void => {\n client.release();\n};\n\nexport const BunAdapter: DriverAdapter = {\n noFieldsForArrays: true,\n manualPool: true,\n schemaConfig,\n errorClass: getBunPostgresError(),\n errorFields: {\n message: 'message',\n severity: 'severity',\n code: 'errno',\n detail: 'detail',\n schema: 'schema',\n table: 'table',\n column: 'column',\n dataType: 'dataType',\n constraint: 'constraint',\n hint: 'hint',\n position: 'position',\n internalPosition: 'internalPosition',\n internalQuery: 'internalQuery',\n where: 'where',\n file: 'file',\n line: 'line',\n routine: 'routine',\n },\n\n configure(config: BunAdapterOptions): BunSql {\n return new (getBun().SQL)(makeOptions(config));\n },\n\n queryClient,\n\n borrow(pool: BunSql): Promise<BunReservedSql> {\n return borrowBunClient(pool);\n },\n\n release(client: BunReservedSql): void {\n releaseBunClient(client);\n },\n\n async begin<DriverClient, Result>(\n pool: BunSql,\n cb: (adapter: DriverClient) => Promise<Result>,\n options?: string,\n ): Promise<Result> {\n const client = await borrowBunClient(pool);\n\n try {\n await queryClient(client, options ? 'BEGIN ' + options : 'BEGIN');\n\n let result;\n try {\n result = await cb(client as DriverClient);\n } catch (err) {\n await queryClient(client, 'ROLLBACK');\n throw err;\n }\n\n await queryClient(client, 'COMMIT');\n return result as Result;\n } finally {\n releaseBunClient(client);\n }\n },\n\n async savepoint<T>(\n client: BunSql,\n // Bun doesn't need to switch the client in a savepoint.\n _setClient: (client: BunSql) => void,\n name: string,\n cb: () => Promise<T>,\n onSavepoint: SavepointCallback | undefined,\n beforeRelease: SavepointCallback | undefined,\n onRelease: SavepointCallback | undefined,\n beforeRollback: SavepointCallback | undefined,\n onRollback: SavepointCallback | undefined,\n ): Promise<T> {\n const safeName = quoteIdentifier(name);\n try {\n await queryClient(client, `SAVEPOINT ${safeName}`);\n onSavepoint?.();\n const res = await cb();\n beforeRelease?.();\n await queryClient(client, `RELEASE SAVEPOINT ${safeName}`);\n onRelease?.();\n return res;\n } catch (err) {\n beforeRollback?.();\n await queryClient(client, `ROLLBACK TO SAVEPOINT ${safeName}`);\n onRollback?.();\n throw err;\n }\n },\n\n async hackySavepoint<T extends QueryResultRow>(\n client: BunSql,\n // Bun doesn't need to switch the client in a savepoint.\n _setClient: (client: BunSql) => void,\n state: HackySavepointState,\n text: string,\n values?: unknown[],\n arraysMode?: boolean,\n onSavepoint?: SavepointCallback,\n beforeRelease?: SavepointCallback,\n onRelease?: SavepointCallback,\n beforeRollback?: SavepointCallback,\n onRollback?: SavepointCallback,\n ): Promise<QueryResult<T>> {\n const safeName = quoteIdentifier(state.name);\n\n let resolve: (() => void) | undefined;\n let reject: ((err: unknown) => void) | undefined;\n const promise = new Promise<void>((res, rej) => {\n resolve = res;\n reject = rej;\n });\n\n let resultResolve: ((res: QueryResult<T>) => void) | undefined;\n let resultReject: ((err: unknown) => void) | undefined;\n const resultPromise = new Promise<QueryResult<T>>((res, rej) => {\n resultResolve = res;\n resultReject = rej;\n });\n\n const savepointPromise = (async () => {\n try {\n await queryClient(client, `SAVEPOINT ${safeName}`);\n onSavepoint?.();\n\n try {\n const res = await queryClient<T>(client, text, values, arraysMode);\n resultResolve?.(res as QueryResult<T>);\n } catch (err) {\n resultReject?.(err);\n throw err;\n }\n\n const result = await promise;\n beforeRelease?.();\n await queryClient(client, `RELEASE SAVEPOINT ${safeName}`);\n onRelease?.();\n return result;\n } catch (err) {\n beforeRollback?.();\n await queryClient(client, `ROLLBACK TO SAVEPOINT ${safeName}`);\n onRollback?.();\n throw err;\n }\n })();\n\n state.activeSavepoint = {\n async release() {\n resolve?.();\n await savepointPromise;\n },\n async rollback(err) {\n reject?.(err);\n await savepointPromise.catch(noop);\n },\n };\n\n return resultPromise;\n },\n\n close(pool: BunSql): Promise<void> {\n return pool.close();\n },\n};\n\nconst makeOptions = (config: BunAdapterOptions): BunSqlOptions => {\n const {\n databaseURL,\n host,\n user,\n password,\n port,\n database,\n max,\n idleTimeout,\n maxLifetime,\n connectionTimeout,\n prepare,\n tls,\n ssl,\n setConfig,\n searchPath,\n } = config;\n\n return {\n url:\n databaseURL && makeUrl(databaseURL, setConfig?.search_path ?? searchPath),\n hostname: host,\n username: user,\n password,\n port,\n database,\n max,\n idleTimeout,\n maxLifetime,\n connectionTimeout,\n prepare,\n tls,\n ssl,\n };\n};\n\nconst makeUrl = (databaseURL: string, searchPath?: string): string => {\n if (!searchPath) return databaseURL;\n\n const url = new URL(databaseURL);\n url.searchParams.set('options', `-c search_path=${searchPath}`);\n return url.toString();\n};\n\nconst normalizeResult = <T>(\n result: BunSqlResult<T>,\n arraysMode?: boolean,\n): QueryResult<T> | QueryResult<T>[] => {\n if (!arraysMode && isMultiResult(result)) {\n return result.map((item) => new BunQueryResult(item, arraysMode));\n }\n\n return new BunQueryResult(result, arraysMode);\n};\n\nclass BunQueryResult<T> implements QueryResult<T> {\n public rowCount: number;\n public rows: T[];\n private _fields?: QueryResult<T>['fields'];\n\n constructor(\n private result: BunSqlResult<T>,\n private isArray?: boolean,\n ) {\n this.rowCount = result.count ?? result.affectedRows ?? result.length;\n\n // creating new Array because BunSqlResult is not a real array - can't do spread on it\n this.rows = Array.from(result) as T[];\n }\n\n get fields(): QueryResult<T>['fields'] {\n if (this.isArray) {\n throw new Error('Bun does not support fields on array result');\n }\n\n return (this._fields ??= getFields(this.result));\n }\n}\n\nconst isMultiResult = <T>(\n result: BunSqlResult<T>,\n): result is BunSqlResult<T>[] & BunSqlResult<T> => {\n return Array.isArray(result[0]);\n};\n\nconst getFields = <T>(rows: T[]): { name: string }[] => {\n const first = rows[0];\n if (!first || Array.isArray(first) || typeof first !== 'object') return [];\n\n return Object.keys(first).map((name) => ({ name }));\n};\n"],"mappings":"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"}
package/dist/bun.mjs CHANGED
@@ -125,19 +125,24 @@ const BunAdapter = {
125
125
  releaseBunClient(client);
126
126
  }
127
127
  },
128
- async savepoint(client, _setClient, name, cb) {
128
+ async savepoint(client, _setClient, name, cb, onSavepoint, beforeRelease, onRelease, beforeRollback, onRollback) {
129
129
  const safeName = quoteIdentifier(name);
130
130
  try {
131
131
  await queryClient(client, `SAVEPOINT ${safeName}`);
132
+ onSavepoint?.();
132
133
  const res = await cb();
134
+ beforeRelease?.();
133
135
  await queryClient(client, `RELEASE SAVEPOINT ${safeName}`);
136
+ onRelease?.();
134
137
  return res;
135
138
  } catch (err) {
139
+ beforeRollback?.();
136
140
  await queryClient(client, `ROLLBACK TO SAVEPOINT ${safeName}`);
141
+ onRollback?.();
137
142
  throw err;
138
143
  }
139
144
  },
140
- async hackySavepoint(client, _setClient, state, text, values, arraysMode) {
145
+ async hackySavepoint(client, _setClient, state, text, values, arraysMode, onSavepoint, beforeRelease, onRelease, beforeRollback, onRollback) {
141
146
  const safeName = quoteIdentifier(state.name);
142
147
  let resolve;
143
148
  let reject;
@@ -154,6 +159,7 @@ const BunAdapter = {
154
159
  const savepointPromise = (async () => {
155
160
  try {
156
161
  await queryClient(client, `SAVEPOINT ${safeName}`);
162
+ onSavepoint?.();
157
163
  try {
158
164
  const res = await queryClient(client, text, values, arraysMode);
159
165
  resultResolve?.(res);
@@ -162,10 +168,14 @@ const BunAdapter = {
162
168
  throw err;
163
169
  }
164
170
  const result = await promise;
171
+ beforeRelease?.();
165
172
  await queryClient(client, `RELEASE SAVEPOINT ${safeName}`);
173
+ onRelease?.();
166
174
  return result;
167
175
  } catch (err) {
176
+ beforeRollback?.();
168
177
  await queryClient(client, `ROLLBACK TO SAVEPOINT ${safeName}`);
178
+ onRollback?.();
169
179
  throw err;
170
180
  }
171
181
  })();
package/dist/bun.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"bun.mjs","names":[],"sources":["../src/adapters/driver-adapter-shared.ts","../src/adapters/bun.ts"],"sourcesContent":["export interface PostgresInterval {\n years: number;\n months: number;\n days: number;\n hours: number;\n minutes: number;\n seconds: number;\n milliseconds: number;\n}\n\nconst intervalRegExp =\n /^\\s*(?:([+-]?\\d+)\\s+years?)?\\s*(?:([+-]?\\d+)\\s+mons?)?\\s*(?:([+-]?\\d+)\\s+days?)?\\s*(?:([+-])?(\\d+):(\\d\\d):(\\d\\d(?:\\.\\d{1,6})?))?\\s*$/;\n\nexport const parseInterval = (str: string): PostgresInterval => {\n const [, years, months, days, timeSign, hours, minutes, seconds] =\n intervalRegExp.exec(str) || [];\n const timeMultiplier = timeSign === '-' ? -1 : 1;\n const secondsFloat = Number(seconds) || 0;\n const wholeSeconds = Math.floor(secondsFloat);\n\n return {\n years: years ? Number(years) : 0,\n months: months ? Number(months) : 0,\n days: days ? Number(days) : 0,\n hours: hours ? timeMultiplier * Number(hours) : 0,\n minutes: minutes ? timeMultiplier * Number(minutes) : 0,\n seconds: timeMultiplier * wholeSeconds,\n milliseconds:\n Math.round(timeMultiplier * (secondsFloat - wholeSeconds) * 1000000) /\n 1000,\n };\n};\n","import {\n AdapterClass,\n AdapterConfigBase,\n ColumnSchemaConfig,\n DbOptions,\n DbResult,\n DefaultColumnTypes,\n defaultSchemaConfig,\n DefaultSchemaConfig,\n DriverAdapter,\n noop,\n QueryResult,\n QueryResultRow,\n QuerySchema,\n quoteIdentifier,\n RecordUnknown,\n AdapterSchemaConfigOptions,\n} from 'pqb/internal';\nimport { createDbWithAdapter } from 'pqb';\nimport { HackySavepointState } from './adapter';\nimport { parseInterval } from './driver-adapter-shared';\n\nconst schemaConfig: AdapterSchemaConfigOptions = {\n arrayEncode: (input) => {\n return getBun().sql.array(input);\n },\n intervalParse: parseInterval,\n jsonEncodedByDriver: true,\n dateParsedByDriver: true,\n};\n\nexport const bunSchemaConfig = Object.assign(\n () => defaultSchemaConfig(schemaConfig),\n schemaConfig,\n);\n\nexport interface CreateBunDbOptions<\n SchemaConfig extends ColumnSchemaConfig,\n ColumnTypes,\n>\n extends BunAdapterOptions, DbOptions<SchemaConfig, ColumnTypes> {}\n\nexport const createDb = <\n SchemaConfig extends ColumnSchemaConfig = DefaultSchemaConfig,\n ColumnTypes = DefaultColumnTypes<SchemaConfig>,\n>({\n log,\n ...options\n}: CreateBunDbOptions<SchemaConfig, ColumnTypes>): DbResult<ColumnTypes> => {\n return createDbWithAdapter({\n schemaConfig: bunSchemaConfig as unknown as () => SchemaConfig,\n ...options,\n log,\n adapter: new AdapterClass({\n driverAdapter: BunAdapter,\n config: options,\n }),\n });\n};\n\nexport interface BunOptions {\n hostname?: string;\n port?: number;\n database?: string;\n username?: string;\n password?: string | (() => string | Promise<string>);\n max?: number;\n idleTimeout?: number;\n maxLifetime?: number;\n connectionTimeout?: number;\n prepare?: boolean;\n tls?: unknown;\n}\n\nexport interface BunAdapterOptions extends AdapterConfigBase, BunOptions {\n schema?: QuerySchema;\n searchPath?: string;\n ssl?: unknown;\n}\n\ninterface Bun {\n SQL: BunSqlConstructor;\n sql: {\n array(input: unknown): unknown;\n };\n}\n\ninterface BunSqlConstructor {\n new (options?: BunSqlOptions | string): BunSql;\n PostgresError: ErrorClass;\n}\n\ninterface BunSqlOptions extends BunOptions {\n url?: string;\n ssl?: unknown;\n}\n\ninterface BunSql {\n unsafe<Row extends QueryResultRow = QueryResultRow>(\n text: string,\n values?: unknown[],\n ): BunSqlQuery<Row>;\n reserve(): Promise<BunReservedSql>;\n close(options?: { timeout?: number }): Promise<void>;\n}\n\ninterface BunReservedSql extends BunSql {\n release(): void;\n}\n\ninterface BunSqlQuery<\n Row extends QueryResultRow = QueryResultRow,\n> extends PromiseLike<BunSqlResult<Row>> {\n values(): Promise<BunSqlResult<unknown[]>>;\n}\n\ninterface BunSqlResult<Row = unknown> extends Array<Row> {\n count?: number;\n affectedRows?: number;\n}\n\n// oxlint-disable-next-line typescript/no-explicit-any\ntype ErrorClass = new (...args: any[]) => Error;\n\nconst getBun = (): Bun => {\n const Bun = (globalThis as unknown as { Bun?: Bun }).Bun;\n if (!Bun?.SQL) {\n throw new Error('Bun.SQL is only available when running in Bun');\n }\n\n return Bun;\n};\n\nconst getBunPostgresError = (): ErrorClass => {\n return (\n (globalThis as unknown as { Bun?: { SQL: BunSqlConstructor } }).Bun?.SQL\n .PostgresError ?? (Error as ErrorClass)\n );\n};\n\nconst queryClient = <T = QueryResultRow>(\n client: BunSql,\n text: string,\n values?: unknown[],\n arraysMode?: boolean,\n): Promise<QueryResult<T>> => {\n const runQuery = () => {\n const query = client.unsafe(text, values);\n const resultPromise: PromiseLike<BunSqlResult> = arraysMode\n ? query.values()\n : query;\n\n return Promise.resolve(resultPromise).then((result) => {\n return normalizeResult(result, arraysMode) as QueryResult<T>;\n });\n };\n\n // Keep a single transactional connection ordered when savepoints are active.\n const { __lock } = client as unknown as { __lock?: Promise<unknown> };\n if (__lock) {\n let resolve: (() => void) | undefined;\n (client as unknown as RecordUnknown).__lock = new Promise<void>((res) => {\n resolve = res;\n });\n\n return __lock.then(() => {\n const promise = runQuery();\n promise.then(resolve, resolve);\n return promise;\n });\n }\n\n const promise = runQuery();\n\n (client as unknown as { __lock?: Promise<unknown> }).__lock =\n promise.catch(noop);\n\n return promise;\n};\n\nconst borrowBunClient = (pool: BunSql): Promise<BunReservedSql> => {\n return pool.reserve();\n};\n\nconst releaseBunClient = (client: BunReservedSql): void => {\n client.release();\n};\n\nexport const BunAdapter: DriverAdapter = {\n noFieldsForArrays: true,\n manualPool: true,\n schemaConfig,\n errorClass: getBunPostgresError(),\n errorFields: {\n message: 'message',\n severity: 'severity',\n code: 'errno',\n detail: 'detail',\n schema: 'schema',\n table: 'table',\n column: 'column',\n dataType: 'dataType',\n constraint: 'constraint',\n hint: 'hint',\n position: 'position',\n internalPosition: 'internalPosition',\n internalQuery: 'internalQuery',\n where: 'where',\n file: 'file',\n line: 'line',\n routine: 'routine',\n },\n\n configure(config: BunAdapterOptions): BunSql {\n return new (getBun().SQL)(makeOptions(config));\n },\n\n queryClient,\n\n borrow(pool: BunSql): Promise<BunReservedSql> {\n return borrowBunClient(pool);\n },\n\n release(client: BunReservedSql): void {\n releaseBunClient(client);\n },\n\n async begin<DriverClient, Result>(\n pool: BunSql,\n cb: (adapter: DriverClient) => Promise<Result>,\n options?: string,\n ): Promise<Result> {\n const client = await borrowBunClient(pool);\n\n try {\n await queryClient(client, options ? 'BEGIN ' + options : 'BEGIN');\n\n let result;\n try {\n result = await cb(client as DriverClient);\n } catch (err) {\n await queryClient(client, 'ROLLBACK');\n throw err;\n }\n\n await queryClient(client, 'COMMIT');\n return result as Result;\n } finally {\n releaseBunClient(client);\n }\n },\n\n async savepoint<T>(\n client: BunSql,\n // Bun doesn't need to switch the client in a savepoint.\n _setClient: (client: BunSql) => void,\n name: string,\n cb: () => Promise<T>,\n ): Promise<T> {\n const safeName = quoteIdentifier(name);\n try {\n await queryClient(client, `SAVEPOINT ${safeName}`);\n const res = await cb();\n await queryClient(client, `RELEASE SAVEPOINT ${safeName}`);\n return res;\n } catch (err) {\n await queryClient(client, `ROLLBACK TO SAVEPOINT ${safeName}`);\n throw err;\n }\n },\n\n async hackySavepoint<T extends QueryResultRow>(\n client: BunSql,\n // Bun doesn't need to switch the client in a savepoint.\n _setClient: (client: BunSql) => void,\n state: HackySavepointState,\n text: string,\n values?: unknown[],\n arraysMode?: boolean,\n ): Promise<QueryResult<T>> {\n const safeName = quoteIdentifier(state.name);\n\n let resolve: (() => void) | undefined;\n let reject: ((err: unknown) => void) | undefined;\n const promise = new Promise<void>((res, rej) => {\n resolve = res;\n reject = rej;\n });\n\n let resultResolve: ((res: QueryResult<T>) => void) | undefined;\n let resultReject: ((err: unknown) => void) | undefined;\n const resultPromise = new Promise<QueryResult<T>>((res, rej) => {\n resultResolve = res;\n resultReject = rej;\n });\n\n const savepointPromise = (async () => {\n try {\n await queryClient(client, `SAVEPOINT ${safeName}`);\n\n try {\n const res = await queryClient<T>(client, text, values, arraysMode);\n resultResolve?.(res as QueryResult<T>);\n } catch (err) {\n resultReject?.(err);\n throw err;\n }\n\n const result = await promise;\n await queryClient(client, `RELEASE SAVEPOINT ${safeName}`);\n return result;\n } catch (err) {\n await queryClient(client, `ROLLBACK TO SAVEPOINT ${safeName}`);\n throw err;\n }\n })();\n\n state.activeSavepoint = {\n async release() {\n resolve?.();\n await savepointPromise;\n },\n async rollback(err) {\n reject?.(err);\n await savepointPromise.catch(noop);\n },\n };\n\n return resultPromise;\n },\n\n close(pool: BunSql): Promise<void> {\n return pool.close();\n },\n};\n\nconst makeOptions = (config: BunAdapterOptions): BunSqlOptions => {\n const {\n databaseURL,\n host,\n user,\n password,\n port,\n database,\n max,\n idleTimeout,\n maxLifetime,\n connectionTimeout,\n prepare,\n tls,\n ssl,\n setConfig,\n searchPath,\n } = config;\n\n return {\n url:\n databaseURL && makeUrl(databaseURL, setConfig?.search_path ?? searchPath),\n hostname: host,\n username: user,\n password,\n port,\n database,\n max,\n idleTimeout,\n maxLifetime,\n connectionTimeout,\n prepare,\n tls,\n ssl,\n };\n};\n\nconst makeUrl = (databaseURL: string, searchPath?: string): string => {\n if (!searchPath) return databaseURL;\n\n const url = new URL(databaseURL);\n url.searchParams.set('options', `-c search_path=${searchPath}`);\n return url.toString();\n};\n\nconst normalizeResult = <T>(\n result: BunSqlResult<T>,\n arraysMode?: boolean,\n): QueryResult<T> | QueryResult<T>[] => {\n if (!arraysMode && isMultiResult(result)) {\n return result.map((item) => new BunQueryResult(item, arraysMode));\n }\n\n return new BunQueryResult(result, arraysMode);\n};\n\nclass BunQueryResult<T> implements QueryResult<T> {\n public rowCount: number;\n public rows: T[];\n private _fields?: QueryResult<T>['fields'];\n\n constructor(\n private result: BunSqlResult<T>,\n private isArray?: boolean,\n ) {\n this.rowCount = result.count ?? result.affectedRows ?? result.length;\n\n // creating new Array because BunSqlResult is not a real array - can't do spread on it\n this.rows = Array.from(result) as T[];\n }\n\n get fields(): QueryResult<T>['fields'] {\n if (this.isArray) {\n throw new Error('Bun does not support fields on array result');\n }\n\n return (this._fields ??= getFields(this.result));\n }\n}\n\nconst isMultiResult = <T>(\n result: BunSqlResult<T>,\n): result is BunSqlResult<T>[] & BunSqlResult<T> => {\n return Array.isArray(result[0]);\n};\n\nconst getFields = <T>(rows: T[]): { name: string }[] => {\n const first = rows[0];\n if (!first || Array.isArray(first) || typeof first !== 'object') return [];\n\n return Object.keys(first).map((name) => ({ name }));\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"bun.mjs","names":[],"sources":["../src/adapters/driver-adapter-shared.ts","../src/adapters/bun.ts"],"sourcesContent":["export interface PostgresInterval {\n years: number;\n months: number;\n days: number;\n hours: number;\n minutes: number;\n seconds: number;\n milliseconds: number;\n}\n\nconst intervalRegExp =\n /^\\s*(?:([+-]?\\d+)\\s+years?)?\\s*(?:([+-]?\\d+)\\s+mons?)?\\s*(?:([+-]?\\d+)\\s+days?)?\\s*(?:([+-])?(\\d+):(\\d\\d):(\\d\\d(?:\\.\\d{1,6})?))?\\s*$/;\n\nexport const parseInterval = (str: string): PostgresInterval => {\n const [, years, months, days, timeSign, hours, minutes, seconds] =\n intervalRegExp.exec(str) || [];\n const timeMultiplier = timeSign === '-' ? -1 : 1;\n const secondsFloat = Number(seconds) || 0;\n const wholeSeconds = Math.floor(secondsFloat);\n\n return {\n years: years ? Number(years) : 0,\n months: months ? Number(months) : 0,\n days: days ? Number(days) : 0,\n hours: hours ? timeMultiplier * Number(hours) : 0,\n minutes: minutes ? timeMultiplier * Number(minutes) : 0,\n seconds: timeMultiplier * wholeSeconds,\n milliseconds:\n Math.round(timeMultiplier * (secondsFloat - wholeSeconds) * 1000000) /\n 1000,\n };\n};\n","import {\n AdapterClass,\n AdapterConfigBase,\n ColumnSchemaConfig,\n DbOptions,\n DbResult,\n DefaultColumnTypes,\n defaultSchemaConfig,\n DefaultSchemaConfig,\n DriverAdapter,\n noop,\n QueryResult,\n QueryResultRow,\n QuerySchema,\n quoteIdentifier,\n RecordUnknown,\n AdapterSchemaConfigOptions,\n} from 'pqb/internal';\nimport { createDbWithAdapter } from 'pqb';\nimport { HackySavepointState, SavepointCallback } from './adapter';\nimport { parseInterval } from './driver-adapter-shared';\n\nconst schemaConfig: AdapterSchemaConfigOptions = {\n arrayEncode: (input) => {\n return getBun().sql.array(input);\n },\n intervalParse: parseInterval,\n jsonEncodedByDriver: true,\n dateParsedByDriver: true,\n};\n\nexport const bunSchemaConfig = Object.assign(\n () => defaultSchemaConfig(schemaConfig),\n schemaConfig,\n);\n\nexport interface CreateBunDbOptions<\n SchemaConfig extends ColumnSchemaConfig,\n ColumnTypes,\n>\n extends BunAdapterOptions, DbOptions<SchemaConfig, ColumnTypes> {}\n\nexport const createDb = <\n SchemaConfig extends ColumnSchemaConfig = DefaultSchemaConfig,\n ColumnTypes = DefaultColumnTypes<SchemaConfig>,\n>({\n log,\n ...options\n}: CreateBunDbOptions<SchemaConfig, ColumnTypes>): DbResult<ColumnTypes> => {\n return createDbWithAdapter({\n schemaConfig: bunSchemaConfig as unknown as () => SchemaConfig,\n ...options,\n log,\n adapter: new AdapterClass({\n driverAdapter: BunAdapter,\n config: options,\n }),\n });\n};\n\nexport interface BunOptions {\n hostname?: string;\n port?: number;\n database?: string;\n username?: string;\n password?: string | (() => string | Promise<string>);\n max?: number;\n idleTimeout?: number;\n maxLifetime?: number;\n connectionTimeout?: number;\n prepare?: boolean;\n tls?: unknown;\n}\n\nexport interface BunAdapterOptions extends AdapterConfigBase, BunOptions {\n schema?: QuerySchema;\n searchPath?: string;\n ssl?: unknown;\n}\n\ninterface Bun {\n SQL: BunSqlConstructor;\n sql: {\n array(input: unknown): unknown;\n };\n}\n\ninterface BunSqlConstructor {\n new (options?: BunSqlOptions | string): BunSql;\n PostgresError: ErrorClass;\n}\n\ninterface BunSqlOptions extends BunOptions {\n url?: string;\n ssl?: unknown;\n}\n\ninterface BunSql {\n unsafe<Row extends QueryResultRow = QueryResultRow>(\n text: string,\n values?: unknown[],\n ): BunSqlQuery<Row>;\n reserve(): Promise<BunReservedSql>;\n close(options?: { timeout?: number }): Promise<void>;\n}\n\ninterface BunReservedSql extends BunSql {\n release(): void;\n}\n\ninterface BunSqlQuery<\n Row extends QueryResultRow = QueryResultRow,\n> extends PromiseLike<BunSqlResult<Row>> {\n values(): Promise<BunSqlResult<unknown[]>>;\n}\n\ninterface BunSqlResult<Row = unknown> extends Array<Row> {\n count?: number;\n affectedRows?: number;\n}\n\n// oxlint-disable-next-line typescript/no-explicit-any\ntype ErrorClass = new (...args: any[]) => Error;\n\nconst getBun = (): Bun => {\n const Bun = (globalThis as unknown as { Bun?: Bun }).Bun;\n if (!Bun?.SQL) {\n throw new Error('Bun.SQL is only available when running in Bun');\n }\n\n return Bun;\n};\n\nconst getBunPostgresError = (): ErrorClass => {\n return (\n (globalThis as unknown as { Bun?: { SQL: BunSqlConstructor } }).Bun?.SQL\n .PostgresError ?? (Error as ErrorClass)\n );\n};\n\nconst queryClient = <T = QueryResultRow>(\n client: BunSql,\n text: string,\n values?: unknown[],\n arraysMode?: boolean,\n): Promise<QueryResult<T>> => {\n const runQuery = () => {\n const query = client.unsafe(text, values);\n const resultPromise: PromiseLike<BunSqlResult> = arraysMode\n ? query.values()\n : query;\n\n return Promise.resolve(resultPromise).then((result) => {\n return normalizeResult(result, arraysMode) as QueryResult<T>;\n });\n };\n\n // Keep a single transactional connection ordered when savepoints are active.\n const { __lock } = client as unknown as { __lock?: Promise<unknown> };\n if (__lock) {\n let resolve: (() => void) | undefined;\n (client as unknown as RecordUnknown).__lock = new Promise<void>((res) => {\n resolve = res;\n });\n\n return __lock.then(() => {\n const promise = runQuery();\n promise.then(resolve, resolve);\n return promise;\n });\n }\n\n const promise = runQuery();\n\n (client as unknown as { __lock?: Promise<unknown> }).__lock =\n promise.catch(noop);\n\n return promise;\n};\n\nconst borrowBunClient = (pool: BunSql): Promise<BunReservedSql> => {\n return pool.reserve();\n};\n\nconst releaseBunClient = (client: BunReservedSql): void => {\n client.release();\n};\n\nexport const BunAdapter: DriverAdapter = {\n noFieldsForArrays: true,\n manualPool: true,\n schemaConfig,\n errorClass: getBunPostgresError(),\n errorFields: {\n message: 'message',\n severity: 'severity',\n code: 'errno',\n detail: 'detail',\n schema: 'schema',\n table: 'table',\n column: 'column',\n dataType: 'dataType',\n constraint: 'constraint',\n hint: 'hint',\n position: 'position',\n internalPosition: 'internalPosition',\n internalQuery: 'internalQuery',\n where: 'where',\n file: 'file',\n line: 'line',\n routine: 'routine',\n },\n\n configure(config: BunAdapterOptions): BunSql {\n return new (getBun().SQL)(makeOptions(config));\n },\n\n queryClient,\n\n borrow(pool: BunSql): Promise<BunReservedSql> {\n return borrowBunClient(pool);\n },\n\n release(client: BunReservedSql): void {\n releaseBunClient(client);\n },\n\n async begin<DriverClient, Result>(\n pool: BunSql,\n cb: (adapter: DriverClient) => Promise<Result>,\n options?: string,\n ): Promise<Result> {\n const client = await borrowBunClient(pool);\n\n try {\n await queryClient(client, options ? 'BEGIN ' + options : 'BEGIN');\n\n let result;\n try {\n result = await cb(client as DriverClient);\n } catch (err) {\n await queryClient(client, 'ROLLBACK');\n throw err;\n }\n\n await queryClient(client, 'COMMIT');\n return result as Result;\n } finally {\n releaseBunClient(client);\n }\n },\n\n async savepoint<T>(\n client: BunSql,\n // Bun doesn't need to switch the client in a savepoint.\n _setClient: (client: BunSql) => void,\n name: string,\n cb: () => Promise<T>,\n onSavepoint: SavepointCallback | undefined,\n beforeRelease: SavepointCallback | undefined,\n onRelease: SavepointCallback | undefined,\n beforeRollback: SavepointCallback | undefined,\n onRollback: SavepointCallback | undefined,\n ): Promise<T> {\n const safeName = quoteIdentifier(name);\n try {\n await queryClient(client, `SAVEPOINT ${safeName}`);\n onSavepoint?.();\n const res = await cb();\n beforeRelease?.();\n await queryClient(client, `RELEASE SAVEPOINT ${safeName}`);\n onRelease?.();\n return res;\n } catch (err) {\n beforeRollback?.();\n await queryClient(client, `ROLLBACK TO SAVEPOINT ${safeName}`);\n onRollback?.();\n throw err;\n }\n },\n\n async hackySavepoint<T extends QueryResultRow>(\n client: BunSql,\n // Bun doesn't need to switch the client in a savepoint.\n _setClient: (client: BunSql) => void,\n state: HackySavepointState,\n text: string,\n values?: unknown[],\n arraysMode?: boolean,\n onSavepoint?: SavepointCallback,\n beforeRelease?: SavepointCallback,\n onRelease?: SavepointCallback,\n beforeRollback?: SavepointCallback,\n onRollback?: SavepointCallback,\n ): Promise<QueryResult<T>> {\n const safeName = quoteIdentifier(state.name);\n\n let resolve: (() => void) | undefined;\n let reject: ((err: unknown) => void) | undefined;\n const promise = new Promise<void>((res, rej) => {\n resolve = res;\n reject = rej;\n });\n\n let resultResolve: ((res: QueryResult<T>) => void) | undefined;\n let resultReject: ((err: unknown) => void) | undefined;\n const resultPromise = new Promise<QueryResult<T>>((res, rej) => {\n resultResolve = res;\n resultReject = rej;\n });\n\n const savepointPromise = (async () => {\n try {\n await queryClient(client, `SAVEPOINT ${safeName}`);\n onSavepoint?.();\n\n try {\n const res = await queryClient<T>(client, text, values, arraysMode);\n resultResolve?.(res as QueryResult<T>);\n } catch (err) {\n resultReject?.(err);\n throw err;\n }\n\n const result = await promise;\n beforeRelease?.();\n await queryClient(client, `RELEASE SAVEPOINT ${safeName}`);\n onRelease?.();\n return result;\n } catch (err) {\n beforeRollback?.();\n await queryClient(client, `ROLLBACK TO SAVEPOINT ${safeName}`);\n onRollback?.();\n throw err;\n }\n })();\n\n state.activeSavepoint = {\n async release() {\n resolve?.();\n await savepointPromise;\n },\n async rollback(err) {\n reject?.(err);\n await savepointPromise.catch(noop);\n },\n };\n\n return resultPromise;\n },\n\n close(pool: BunSql): Promise<void> {\n return pool.close();\n },\n};\n\nconst makeOptions = (config: BunAdapterOptions): BunSqlOptions => {\n const {\n databaseURL,\n host,\n user,\n password,\n port,\n database,\n max,\n idleTimeout,\n maxLifetime,\n connectionTimeout,\n prepare,\n tls,\n ssl,\n setConfig,\n searchPath,\n } = config;\n\n return {\n url:\n databaseURL && makeUrl(databaseURL, setConfig?.search_path ?? searchPath),\n hostname: host,\n username: user,\n password,\n port,\n database,\n max,\n idleTimeout,\n maxLifetime,\n connectionTimeout,\n prepare,\n tls,\n ssl,\n };\n};\n\nconst makeUrl = (databaseURL: string, searchPath?: string): string => {\n if (!searchPath) return databaseURL;\n\n const url = new URL(databaseURL);\n url.searchParams.set('options', `-c search_path=${searchPath}`);\n return url.toString();\n};\n\nconst normalizeResult = <T>(\n result: BunSqlResult<T>,\n arraysMode?: boolean,\n): QueryResult<T> | QueryResult<T>[] => {\n if (!arraysMode && isMultiResult(result)) {\n return result.map((item) => new BunQueryResult(item, arraysMode));\n }\n\n return new BunQueryResult(result, arraysMode);\n};\n\nclass BunQueryResult<T> implements QueryResult<T> {\n public rowCount: number;\n public rows: T[];\n private _fields?: QueryResult<T>['fields'];\n\n constructor(\n private result: BunSqlResult<T>,\n private isArray?: boolean,\n ) {\n this.rowCount = result.count ?? result.affectedRows ?? result.length;\n\n // creating new Array because BunSqlResult is not a real array - can't do spread on it\n this.rows = Array.from(result) as T[];\n }\n\n get fields(): QueryResult<T>['fields'] {\n if (this.isArray) {\n throw new Error('Bun does not support fields on array result');\n }\n\n return (this._fields ??= getFields(this.result));\n }\n}\n\nconst isMultiResult = <T>(\n result: BunSqlResult<T>,\n): result is BunSqlResult<T>[] & BunSqlResult<T> => {\n return Array.isArray(result[0]);\n};\n\nconst getFields = <T>(rows: T[]): { name: string }[] => {\n const first = rows[0];\n if (!first || Array.isArray(first) || typeof first !== 'object') return [];\n\n return Object.keys(first).map((name) => ({ name }));\n};\n"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -490,14 +490,14 @@ interface Adapter {
490
490
  */
491
491
  interface TransactionAdapter extends Adapter {
492
492
  isInTransaction(this: Adapter): this is TransactionAdapter;
493
- savepoint<T>(name: string, cb: () => Promise<T>): Promise<T>;
493
+ savepoint<T>(name: string, log: QueryLogObject | undefined, cb: () => Promise<T>): Promise<T>;
494
494
  /**
495
495
  * This is a workaround for postgres-js savepoint limitations.
496
496
  * Postgres-js dictates this:
497
497
  * - must use its `savepoint` method over manual `SAVEPOINT` because when doing it manually there is no way to prevent transaction from being rolled back when a query in a savepoint fails.
498
498
  * - must use its `sql` client from inside the `savepoint` method for the lifetime of the savepoint because of the reason above.
499
499
  */
500
- hackySavepoint<T extends QueryResultRow = QueryResultRow>(state: HackySavepointState, text: string, values?: unknown[], arraysMode?: boolean): Promise<QueryResult<T>>;
500
+ hackySavepoint<T extends QueryResultRow = QueryResultRow>(state: HackySavepointState, text: string, values?: unknown[], arraysMode?: boolean, log?: QueryLogObject): Promise<QueryResult<T>>;
501
501
  }
502
502
  type Pool = any;
503
503
  type Client = any;
@@ -521,10 +521,11 @@ interface DriverAdapter {
521
521
  release(client: Client): void;
522
522
  queryClient<T = QueryResultRow>(client: Client, text: string, values?: unknown[], arraysMode?: boolean): Promise<QueryResult<T>>;
523
523
  begin<DriverClient, Result>(pool: Pool, cb: (client: DriverClient) => Promise<Result>, options?: string): Promise<Result>;
524
- savepoint<T>(client: Client, setClient: (client: Client) => void, name: string, cb: () => Promise<T>): Promise<T>;
525
- hackySavepoint<T extends QueryResultRow>(client: Client, setClient: (client: Client) => void, state: HackySavepointState, text: string, values?: unknown[], arraysMode?: boolean): Promise<QueryResult<T>>;
524
+ savepoint<T>(client: Client, setClient: (client: Client) => void, name: string, cb: () => Promise<T>, onSavepoint?: SavepointCallback, beforeRelease?: SavepointCallback, onRelease?: SavepointCallback, beforeRollback?: SavepointCallback, onRollback?: SavepointCallback): Promise<T>;
525
+ hackySavepoint<T extends QueryResultRow>(client: Client, setClient: (client: Client) => void, state: HackySavepointState, text: string, values?: unknown[], arraysMode?: boolean, onSavepoint?: SavepointCallback, beforeRelease?: SavepointCallback, onRelease?: SavepointCallback, beforeRollback?: SavepointCallback, onRollback?: SavepointCallback): Promise<QueryResult<T>>;
526
526
  close(pool: Pool): Promise<void>;
527
527
  }
528
+ type SavepointCallback = () => void;
528
529
  /**
529
530
  * Constructor params for the shared runtime adapter orchestrator.
530
531
  */
@@ -589,8 +590,8 @@ declare class TransactionAdapterClass implements TransactionAdapter {
589
590
  getHost(): string;
590
591
  getSchema(): QuerySchema | undefined;
591
592
  transaction<T>(asyncStorage: AsyncLocalStorage<AsyncState> | undefined, options: AdapterTransactionOptions | undefined, cb: (adapter: TransactionAdapter) => Promise<T>): Promise<T>;
592
- savepoint<T>(name: string, cb: () => Promise<T>): Promise<T>;
593
- hackySavepoint<T extends QueryResultRow = QueryResultRow>(state: HackySavepointState, text: string, values?: unknown[], arraysMode?: boolean): Promise<QueryResult<T>>;
593
+ savepoint<T>(name: string, log: QueryLogObject | undefined, cb: () => Promise<T>): Promise<T>;
594
+ hackySavepoint<T extends QueryResultRow = QueryResultRow>(state: HackySavepointState, text: string, values?: unknown[], arraysMode?: boolean, log?: QueryLogObject): Promise<QueryResult<T>>;
594
595
  close(): Promise<void>;
595
596
  assignError(to: QueryError, from: Error): void;
596
597
  }
@@ -11188,4 +11189,4 @@ declare const testTransaction: {
11188
11189
  */
11189
11190
  close(arg: Arg$1): Promise<void>;
11190
11191
  };
11191
- export { type Adapter, AdapterClass, type AdapterConfigBase, type AdapterParams, type AdapterSchemaConfigOptions, type AfterCommitStandaloneHook, type AfterHook, ArrayColumn, type ArrayColumnValue, type ArrayData, type AsyncState, type BaseNumberData, BigIntColumn, BigSerialColumn, BitColumn, BitVaryingColumn, BooleanColumn, BoxColumn, type BrandColumn, type BrandColumnsShape, type Branded, ByteaColumn, CidrColumn, CircleColumn, CitextColumn, type Code, type Codes, Column, type ColumnFromDbParams, type ColumnRefExpression, type ColumnSchemaConfig, type ColumnSchemaGetterColumns, type ColumnSchemaGetterTableClass, type ColumnToCodeCtx, type ColumnTypeSchemaArg, type ColumnsByType, type ColumnsShape, type ComputedColumnsFromOptions, type ComputedOptionsConfig, type ComputedOptionsFactory, type CreateCtx, type CreateData, type CreateManyMethodsNames, type CreateMethodsNames, type CreateSelf, CustomTypeColumn, DateBaseColumn, DateColumn, type DateColumnData, type DateColumnInput, DateTimeBaseClass, DateTimeTzBaseClass, Db, type DbDomainArg, type DbExtension, type DbOptions, type DbResult, type DbSharedOptions, type DbSqlMethod, type DbStructureDomainsMap, type DbTableOptionScopes, type DbTableOptions, DecimalColumn, type DecimalColumnData, type DefaultColumnTypes, type DefaultPrivileges, type DefaultSchemaConfig, type DeleteMethodsNames, DomainColumn, DoublePrecisionColumn, type DriverAdapter, DynamicRawSQL, type EmptyObject, type EmptyTuple, EnumColumn, Expression, type ExpressionData, type FromArg, type FromResult, type GeneratorIgnore, type Grant, type HookSelectValue, InetColumn, IntegerBaseColumn, IntegerColumn, IntervalColumn, type IsQuery, type IsolationLevel, JSONColumn, JSONTextColumn, type JoinedShapes, LimitedTextBaseColumn, LineColumn, LsegColumn, MacAddr8Column, MacAddrColumn, type MapTableScopesOption, type MaybeArray, type MaybePromise, type MergeQuery, MoneyColumn, type NoPrimaryKeyOption, type NonUniqDataItem, NotFoundError, NumberAsStringBaseColumn, NumberBaseColumn, type NumberColumnData, Operators, type OperatorsArray, type OperatorsDate, type OperatorsJson, type OperatorsNumber, type OperatorsOrdinalText, type OperatorsText, OrchidOrmInternalError, type Ord, PathColumn, type PickQueryInputType, type PickQueryInternal, type PickQueryQ, type PickQueryRelations, type PickQuerySelectableRelations, type PickQueryShape, PointColumn, PolygonColumn, PostgisGeographyPointColumn, type Query, type QueryAfterHook, type QueryBeforeActionHook, type QueryBeforeHook, type QueryData, QueryError, type QueryHasWhere, type QueryHelperResult, QueryHookUtils, QueryHooks, type QueryInternal, type QueryLogObject, type QueryLogOptions, type QueryLogger, type QueryManyTake, type QueryManyTakeOptional, type QueryOrExpression, type QueryResult, type QueryResultRow, type QueryReturnType, type QuerySchema, type QueryScopes, RawSql, type RawSqlBase, RealColumn, type RecordKeyTrue, type RecordOptionalString, type RecordString, type RecordStringOrNumber, type RecordUnknown, type RefreshMaterializedViewOptions, type RelationConfigBase, type RelationJoinQuery, type RelationsBase, type Rls, type RlsPolicy, type SchemaConfigFnWithOptions, type SearchWeight, type SelectSqlColumn, type SelectableFromShape, SerialColumn, type SerialColumnData, type ShallowSimplify, type ShapeUniqueColumns, type SingleSql, type SingleSqlItem, SmallIntColumn, SmallSerialColumn, type Sql, type SqlFn, type SqlSessionState, type StaticSQLArgs, type StorageOptions, StringColumn, type StringData, type TableData, type TableDataFn, type TableDataInput, type TableDataItem, type TableDataItemsUniqueColumnTuples, type TableDataItemsUniqueColumns, type TableDataItemsUniqueConstraints, type TableDataMethods, type TemplateLiteralArgs, TextBaseColumn, TextColumn, TimeColumn, TimestampColumn, TimestampTZColumn, type Timestamps, type ToSQLCtx, type ToSqlValues, type TransactionAdapter, TransactionAdapterClass, type TransactionOptions, TsQueryColumn, TsVectorColumn, UUIDColumn, type UniqueConstraints, type UniqueTableDataItem, UnknownColumn, type UpdateData, type UpsertData, type UpsertThis, VarCharColumn, VirtualColumn, type WhereArg, XMLColumn, _appendQuery, _appendQueryOnUpsertCreate, _clone, _createDbSqlMethod, _hookSelectColumns, _initQueryBuilder, _onUpsertUpdate, _orCreate, _prependWith, _prependWithOnUpsertCreate, _queryCreate, _queryCreateMany, _queryCreateManyFrom, _queryDefaults, _queryDelete, _queryFindBy, _queryFindByOptional, _queryHookAfterCreate, _queryHookAfterUpdate, _queryInsert, _queryInsertForEachFrom, _queryInsertMany, _queryJoinOn, _queryRows, _querySelect, _queryTake, _queryTakeOptional, _queryUpdate, _queryUpdateOrThrow, _queryUpsert, _queryWhere, _queryWhereExists, _queryWhereIn, addCode, addTopCte, addTopCteSql, applyMixins, assignDbDataToColumn, backtickQuote, cloneQueryBaseUnscoped, codeToString, colors, columnsShapeToCode, constraintInnerToCode, constraintToCode, consumeColumnName, copyTableData, createDbWithAdapter, deepCompare, defaultSchemaConfig, emptyArray, emptyObject, escapeForMigration, escapeString, excludeInnerToCode, excludeToCode, exhaustive, getCallerFilePath, getClonedQueryData, getColumnBaseType, getColumnInfo, getColumnTypes, getDateAsDateFn, getDateAsNumberFn, getDriverErrorCode, getFreeAlias, getFreeSetAlias, getImportPath, getPrimaryKeys, getQueryAs, getQuerySchema, getShapeFromSelect, getSqlText, getStackTrace, getSupportedDefaultPrivileges, indexInnerToCode, indexToCode, internalSchemaConfig, isExpression, isQueryReturnsAll, isRawSQL, logColors, logParamToLogObject, makeColumnNullable, makeColumnTypes, makeColumnsByType, makeConnectRetryConfig, noop, objectHasValues, omit, parseTableData, parseTableDataInput, pathToLog, pick, pluralize, prepareSubQueryForSql, primaryKeyInnerToCode, pushQueryOnForOuter, pushQueryValueImmutable, pushTableDataCode, queryToSql, quoteIdentifier, quoteObjectKey, quoteTableWithSchema, raw, rawSqlToCode, rawSqlToSql, referencesArgsToCode, refreshMaterializedView, returnArg, setColumnData, setColumnEncode, setColumnParse, setColumnParseNull, setCurrentColumnName, setDataValue, setDefaultLanguage, setFreeAlias, setQueryObjectValueImmutable, singleQuote, sqlToRawSql, tableDataMethods, testTransaction, toArray, toCamelCase, toPascalCase, toSnakeCase, wrapAdapterFnWithConnectRetry };
11192
+ export { type Adapter, AdapterClass, type AdapterConfigBase, type AdapterParams, type AdapterSchemaConfigOptions, type AfterCommitStandaloneHook, type AfterHook, ArrayColumn, type ArrayColumnValue, type ArrayData, type AsyncState, type BaseNumberData, BigIntColumn, BigSerialColumn, BitColumn, BitVaryingColumn, BooleanColumn, BoxColumn, type BrandColumn, type BrandColumnsShape, type Branded, ByteaColumn, CidrColumn, CircleColumn, CitextColumn, type Code, type Codes, Column, type ColumnFromDbParams, type ColumnRefExpression, type ColumnSchemaConfig, type ColumnSchemaGetterColumns, type ColumnSchemaGetterTableClass, type ColumnToCodeCtx, type ColumnTypeSchemaArg, type ColumnsByType, type ColumnsShape, type ComputedColumnsFromOptions, type ComputedOptionsConfig, type ComputedOptionsFactory, type CreateCtx, type CreateData, type CreateManyMethodsNames, type CreateMethodsNames, type CreateSelf, CustomTypeColumn, DateBaseColumn, DateColumn, type DateColumnData, type DateColumnInput, DateTimeBaseClass, DateTimeTzBaseClass, Db, type DbDomainArg, type DbExtension, type DbOptions, type DbResult, type DbSharedOptions, type DbSqlMethod, type DbStructureDomainsMap, type DbTableOptionScopes, type DbTableOptions, DecimalColumn, type DecimalColumnData, type DefaultColumnTypes, type DefaultPrivileges, type DefaultSchemaConfig, type DeleteMethodsNames, DomainColumn, DoublePrecisionColumn, type DriverAdapter, DynamicRawSQL, type EmptyObject, type EmptyTuple, EnumColumn, Expression, type ExpressionData, type FromArg, type FromResult, type GeneratorIgnore, type Grant, type HookSelectValue, InetColumn, IntegerBaseColumn, IntegerColumn, IntervalColumn, type IsQuery, type IsolationLevel, JSONColumn, JSONTextColumn, type JoinedShapes, LimitedTextBaseColumn, LineColumn, LsegColumn, MacAddr8Column, MacAddrColumn, type MapTableScopesOption, type MaybeArray, type MaybePromise, type MergeQuery, MoneyColumn, type NoPrimaryKeyOption, type NonUniqDataItem, NotFoundError, NumberAsStringBaseColumn, NumberBaseColumn, type NumberColumnData, Operators, type OperatorsArray, type OperatorsDate, type OperatorsJson, type OperatorsNumber, type OperatorsOrdinalText, type OperatorsText, OrchidOrmInternalError, type Ord, PathColumn, type PickQueryInputType, type PickQueryInternal, type PickQueryQ, type PickQueryRelations, type PickQuerySelectableRelations, type PickQueryShape, PointColumn, PolygonColumn, PostgisGeographyPointColumn, type Query, type QueryAfterHook, type QueryBeforeActionHook, type QueryBeforeHook, type QueryData, QueryError, type QueryHasWhere, type QueryHelperResult, QueryHookUtils, QueryHooks, type QueryInternal, type QueryLogObject, type QueryLogOptions, type QueryLogger, type QueryManyTake, type QueryManyTakeOptional, type QueryOrExpression, type QueryResult, type QueryResultRow, type QueryReturnType, type QuerySchema, type QueryScopes, type QueryTake, RawSql, type RawSqlBase, RealColumn, type RecordKeyTrue, type RecordOptionalString, type RecordString, type RecordStringOrNumber, type RecordUnknown, type RefreshMaterializedViewOptions, type RelationConfigBase, type RelationJoinQuery, type RelationsBase, type Rls, type RlsPolicy, type SchemaConfigFnWithOptions, type SearchWeight, type SelectAsFnReturnType, type SelectResultObj, type SelectSqlColumn, type SelectableFromShape, SerialColumn, type SerialColumnData, type ShallowSimplify, type ShapeUniqueColumns, type SingleSql, type SingleSqlItem, SmallIntColumn, SmallSerialColumn, type Sql, type SqlFn, type SqlSessionState, type StaticSQLArgs, type StorageOptions, StringColumn, type StringData, type TableData, type TableDataFn, type TableDataInput, type TableDataItem, type TableDataItemsUniqueColumnTuples, type TableDataItemsUniqueColumns, type TableDataItemsUniqueConstraints, type TableDataMethods, type TemplateLiteralArgs, TextBaseColumn, TextColumn, TimeColumn, TimestampColumn, TimestampTZColumn, type Timestamps, type ToSQLCtx, type ToSqlValues, type TransactionAdapter, TransactionAdapterClass, type TransactionOptions, TsQueryColumn, TsVectorColumn, UUIDColumn, type UniqueConstraints, type UniqueTableDataItem, UnknownColumn, type UpdateData, type UpsertData, type UpsertThis, VarCharColumn, VirtualColumn, type WhereArg, XMLColumn, _appendQuery, _appendQueryOnUpsertCreate, _clone, _createDbSqlMethod, _hookSelectColumns, _initQueryBuilder, _onUpsertUpdate, _orCreate, _prependWith, _prependWithOnUpsertCreate, _queryCreate, _queryCreateMany, _queryCreateManyFrom, _queryDefaults, _queryDelete, _queryFindBy, _queryFindByOptional, _queryHookAfterCreate, _queryHookAfterUpdate, _queryInsert, _queryInsertForEachFrom, _queryInsertMany, _queryJoinOn, _queryRows, _querySelect, _queryTake, _queryTakeOptional, _queryUpdate, _queryUpdateOrThrow, _queryUpsert, _queryWhere, _queryWhereExists, _queryWhereIn, addCode, addTopCte, addTopCteSql, applyMixins, assignDbDataToColumn, backtickQuote, cloneQueryBaseUnscoped, codeToString, colors, columnsShapeToCode, constraintInnerToCode, constraintToCode, consumeColumnName, copyTableData, createDbWithAdapter, deepCompare, defaultSchemaConfig, emptyArray, emptyObject, escapeForMigration, escapeString, excludeInnerToCode, excludeToCode, exhaustive, getCallerFilePath, getClonedQueryData, getColumnBaseType, getColumnInfo, getColumnTypes, getDateAsDateFn, getDateAsNumberFn, getDriverErrorCode, getFreeAlias, getFreeSetAlias, getImportPath, getPrimaryKeys, getQueryAs, getQuerySchema, getShapeFromSelect, getSqlText, getStackTrace, getSupportedDefaultPrivileges, indexInnerToCode, indexToCode, internalSchemaConfig, isExpression, isQueryReturnsAll, isRawSQL, logColors, logParamToLogObject, makeColumnNullable, makeColumnTypes, makeColumnsByType, makeConnectRetryConfig, noop, objectHasValues, omit, parseTableData, parseTableDataInput, pathToLog, pick, pluralize, prepareSubQueryForSql, primaryKeyInnerToCode, pushQueryOnForOuter, pushQueryValueImmutable, pushTableDataCode, queryToSql, quoteIdentifier, quoteObjectKey, quoteTableWithSchema, raw, rawSqlToCode, rawSqlToSql, referencesArgsToCode, refreshMaterializedView, returnArg, setColumnData, setColumnEncode, setColumnParse, setColumnParseNull, setCurrentColumnName, setDataValue, setDefaultLanguage, setFreeAlias, setQueryObjectValueImmutable, singleQuote, sqlToRawSql, tableDataMethods, testTransaction, toArray, toCamelCase, toPascalCase, toSnakeCase, wrapAdapterFnWithConnectRetry };
package/dist/index.js CHANGED
@@ -4229,15 +4229,67 @@ var TransactionAdapterClass = class {
4229
4229
  async transaction(asyncStorage, options, cb) {
4230
4230
  return transaction(asyncStorage, this.adapter, this.driverAdapter, this.client, options, cb, this);
4231
4231
  }
4232
- savepoint(name, cb) {
4233
- return this.driverAdapter.savepoint(this.client, (client) => {
4232
+ async savepoint(name, log, cb) {
4233
+ if (!log) return this.driverAdapter.savepoint(this.client, (client) => {
4234
4234
  this.client = client;
4235
4235
  }, name, cb);
4236
+ const savepointSql = { text: `SAVEPOINT "${name}"` };
4237
+ const savepointLogData = log.beforeQuery(savepointSql);
4238
+ let releaseSql;
4239
+ let releaseLogData;
4240
+ let rollbackSql;
4241
+ let rollbackLogData;
4242
+ let error;
4243
+ return this.driverAdapter.savepoint(this.client, (client) => {
4244
+ this.client = client;
4245
+ }, name, async () => {
4246
+ try {
4247
+ return await cb();
4248
+ } catch (err) {
4249
+ error = err;
4250
+ throw err;
4251
+ }
4252
+ }, () => log.afterQuery(savepointSql, savepointLogData), () => {
4253
+ releaseSql = { text: `RELEASE SAVEPOINT "${name}"` };
4254
+ releaseLogData = log.beforeQuery(releaseSql);
4255
+ }, () => log.afterQuery(releaseSql, releaseLogData), () => {
4256
+ rollbackSql = { text: `ROLLBACK TO SAVEPOINT "${name}"` };
4257
+ rollbackLogData = log.beforeQuery(rollbackSql);
4258
+ }, () => {
4259
+ if (error) log.onError(error, rollbackSql, rollbackLogData);
4260
+ });
4236
4261
  }
4237
- hackySavepoint(state, text, values, arraysMode) {
4238
- return this.driverAdapter.hackySavepoint(this.client, (client) => {
4262
+ hackySavepoint(state, text, values, arraysMode, log) {
4263
+ if (!log) return this.driverAdapter.hackySavepoint(this.client, (client) => {
4239
4264
  this.client = client;
4240
4265
  }, state, text, values, arraysMode);
4266
+ const savepointSql = { text: `SAVEPOINT "${state.name}"` };
4267
+ const savepointLogData = log.beforeQuery(savepointSql);
4268
+ let releaseSql;
4269
+ let releaseLogData;
4270
+ let rollbackSql;
4271
+ let rollbackLogData;
4272
+ let error;
4273
+ const result = this.driverAdapter.hackySavepoint(this.client, (client) => {
4274
+ this.client = client;
4275
+ }, state, text, values, arraysMode, () => log.afterQuery(savepointSql, savepointLogData), () => {
4276
+ releaseSql = { text: `RELEASE SAVEPOINT "${state.name}"` };
4277
+ releaseLogData = log.beforeQuery(releaseSql);
4278
+ }, () => log.afterQuery(releaseSql, releaseLogData), () => {
4279
+ rollbackSql = { text: `ROLLBACK TO SAVEPOINT "${state.name}"` };
4280
+ rollbackLogData = log.beforeQuery(rollbackSql);
4281
+ }, () => {
4282
+ if (error) log.onError(error, rollbackSql, rollbackLogData);
4283
+ });
4284
+ const activeSavepoint = state.activeSavepoint;
4285
+ if (activeSavepoint) {
4286
+ const rollback = activeSavepoint.rollback;
4287
+ activeSavepoint.rollback = async (err) => {
4288
+ error = err;
4289
+ return rollback.call(activeSavepoint, err);
4290
+ };
4291
+ }
4292
+ return result;
4241
4293
  }
4242
4294
  close() {
4243
4295
  return this.adapter.close();
@@ -4329,7 +4381,7 @@ const nestedTransaction = async (adapter, driverAdapter, transactionAdapter, cli
4329
4381
  const state = ctx.state;
4330
4382
  const parentRole = state?.transactionRole;
4331
4383
  const parentSetConfig = state?.transactionSetConfig;
4332
- const result = await transactionAdapter.savepoint(`t${transactionId}`, async () => {
4384
+ const result = await transactionAdapter.savepoint(`t${transactionId}`, options?.log, async () => {
4333
4385
  const setRoleSql = getSetRoleSql(parentRole, options);
4334
4386
  if (setRoleSql) driverAdapter.queryClient(client, setRoleSql);
4335
4387
  const setConfigSql = getSetConfigSql(parentSetConfig, options);
@@ -4757,7 +4809,7 @@ const then = async (q, adapter, state, beforeHooks, afterHooks, afterSaveHooks,
4757
4809
  if (query.autoPreparedStatements) sql.name = queriesNames[sql.text] || (queriesNames[sql.text] = (nameI++).toString(36));
4758
4810
  if (log) logData = log.beforeQuery(sql);
4759
4811
  const method = queryMethodByReturnType[tempReturnType];
4760
- queryResult = await execQuery(adapter, method, sql, startingSavepoint, releasingSavepoint, sqlSessionContextGetStateFromAsyncState(state));
4812
+ queryResult = await execQuery(adapter, method, sql, log, startingSavepoint, releasingSavepoint, sqlSessionContextGetStateFromAsyncState(state));
4761
4813
  const { runAfterQuery } = sql;
4762
4814
  if (log) {
4763
4815
  log.afterQuery(sql, logData);
@@ -4786,7 +4838,7 @@ const then = async (q, adapter, state, beforeHooks, afterHooks, afterSaveHooks,
4786
4838
  for (let i = 0; i <= last; i++) {
4787
4839
  sql = batch[i];
4788
4840
  if (log) logData = log.beforeQuery(sql);
4789
- const result = await execQuery(adapter, queryMethod, sql, i === 0 ? startingSavepoint : void 0, i === last ? releasingSavepoint : void 0, sqlSessionContextGetStateFromAsyncState(state));
4841
+ const result = await execQuery(adapter, queryMethod, sql, log, i === 0 ? startingSavepoint : void 0, i === last ? releasingSavepoint : void 0, sqlSessionContextGetStateFromAsyncState(state));
4790
4842
  if (queryResult) {
4791
4843
  queryResult.rowCount += result.rowCount;
4792
4844
  queryResult.rows.push(...result.rows);
@@ -4987,12 +5039,12 @@ const setCatchingSavepoint = (catchTrx) => {
4987
5039
  * it populates the response with empty objects,
4988
5040
  * because user might expect empty objects to be returned for an empty select.
4989
5041
  */
4990
- const execQuery = (adapter, method, sql, startingSavepoint, releasingSavepoint, sqlSessionState) => {
5042
+ const execQuery = (adapter, method, sql, log, startingSavepoint, releasingSavepoint, sqlSessionState) => {
4991
5043
  let promise;
4992
- if (startingSavepoint) if (releasingSavepoint) promise = startingSavepoint.transactionAdapter.savepoint(startingSavepoint.name, () => {
5044
+ if (startingSavepoint) if (releasingSavepoint) promise = startingSavepoint.transactionAdapter.savepoint(startingSavepoint.name, log, () => {
4993
5045
  return promise = adapter[method](sql.text, sql.values, sqlSessionState);
4994
5046
  });
4995
- else promise = startingSavepoint.transactionAdapter.hackySavepoint(startingSavepoint, sql.text, sql.values, method === "arrays");
5047
+ else promise = startingSavepoint.transactionAdapter.hackySavepoint(startingSavepoint, sql.text, sql.values, method === "arrays", log);
4996
5048
  else promise = adapter[method](sql.text, sql.values, sqlSessionState);
4997
5049
  if (!startingSavepoint && releasingSavepoint) promise = promise.then(async (res) => {
4998
5050
  await releasingSavepoint.activeSavepoint?.release();