kysely 0.28.17 → 0.28.19
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/README.md +1 -1
- package/dist/cjs/dialect/mssql/mssql-adapter.d.ts +3 -2
- package/dist/cjs/dialect/mssql/mssql-adapter.js +13 -7
- package/dist/cjs/dialect/mssql/mssql-driver.d.ts +3 -0
- package/dist/cjs/dialect/mysql/mysql-dialect-config.d.ts +10 -0
- package/dist/cjs/dialect/mysql/mysql-driver.d.ts +3 -0
- package/dist/cjs/dialect/postgres/postgres-adapter.d.ts +1 -1
- package/dist/cjs/dialect/postgres/postgres-adapter.js +13 -7
- package/dist/cjs/dialect/postgres/postgres-dialect-config.d.ts +12 -2
- package/dist/cjs/dialect/postgres/postgres-driver.d.ts +6 -1
- package/dist/cjs/dialect/postgres/postgres-driver.js +35 -3
- package/dist/cjs/dialect/postgres/postgres-introspector.js +18 -12
- package/dist/cjs/dialect/sqlite/sqlite-dialect-config.d.ts +10 -0
- package/dist/cjs/dialect/sqlite/sqlite-driver.d.ts +3 -0
- package/dist/cjs/driver/aborted-transaction-error.d.ts +11 -0
- package/dist/cjs/driver/aborted-transaction-error.js +20 -0
- package/dist/cjs/driver/driver.d.ts +3 -0
- package/dist/cjs/driver/dummy-driver.d.ts +3 -0
- package/dist/cjs/driver/runtime-driver.d.ts +3 -0
- package/dist/cjs/helpers/mssql.d.ts +3 -1
- package/dist/cjs/helpers/mssql.js +4 -2
- package/dist/cjs/index.d.ts +1 -0
- package/dist/cjs/index.js +1 -0
- package/dist/cjs/kysely.d.ts +55 -3
- package/dist/cjs/kysely.js +136 -54
- package/dist/cjs/migration/migrator.js +22 -19
- package/dist/cjs/query-builder/delete-query-builder.d.ts +2 -2
- package/dist/cjs/query-builder/join-builder.d.ts +2 -2
- package/dist/cjs/query-builder/on-conflict-builder.d.ts +5 -2
- package/dist/cjs/query-builder/select-query-builder.d.ts +28 -6
- package/dist/cjs/query-builder/update-query-builder.d.ts +1 -1
- package/dist/cjs/query-compiler/default-query-compiler.js +4 -4
- package/dist/cjs/schema/create-type-builder.d.ts +1 -1
- package/dist/cjs/schema/create-type-builder.js +1 -1
- package/dist/cjs/util/column-type.d.ts +1 -1
- package/dist/esm/dialect/mssql/mssql-adapter.d.ts +3 -2
- package/dist/esm/dialect/mssql/mssql-adapter.js +13 -7
- package/dist/esm/dialect/mssql/mssql-driver.d.ts +3 -0
- package/dist/esm/dialect/mysql/mysql-dialect-config.d.ts +10 -0
- package/dist/esm/dialect/mysql/mysql-driver.d.ts +3 -0
- package/dist/esm/dialect/postgres/postgres-adapter.d.ts +1 -1
- package/dist/esm/dialect/postgres/postgres-adapter.js +13 -7
- package/dist/esm/dialect/postgres/postgres-dialect-config.d.ts +12 -2
- package/dist/esm/dialect/postgres/postgres-driver.d.ts +6 -1
- package/dist/esm/dialect/postgres/postgres-driver.js +35 -3
- package/dist/esm/dialect/postgres/postgres-introspector.js +18 -12
- package/dist/esm/dialect/sqlite/sqlite-dialect-config.d.ts +10 -0
- package/dist/esm/dialect/sqlite/sqlite-driver.d.ts +3 -0
- package/dist/esm/driver/aborted-transaction-error.d.ts +11 -0
- package/dist/esm/driver/aborted-transaction-error.js +16 -0
- package/dist/esm/driver/driver.d.ts +3 -0
- package/dist/esm/driver/dummy-driver.d.ts +3 -0
- package/dist/esm/driver/runtime-driver.d.ts +3 -0
- package/dist/esm/helpers/mssql.d.ts +3 -1
- package/dist/esm/helpers/mssql.js +4 -2
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/kysely.d.ts +55 -3
- package/dist/esm/kysely.js +136 -54
- package/dist/esm/migration/migrator.js +22 -19
- package/dist/esm/query-builder/delete-query-builder.d.ts +2 -2
- package/dist/esm/query-builder/join-builder.d.ts +2 -2
- package/dist/esm/query-builder/on-conflict-builder.d.ts +5 -2
- package/dist/esm/query-builder/select-query-builder.d.ts +28 -6
- package/dist/esm/query-builder/update-query-builder.d.ts +1 -1
- package/dist/esm/query-compiler/default-query-compiler.js +4 -4
- package/dist/esm/schema/create-type-builder.d.ts +1 -1
- package/dist/esm/schema/create-type-builder.js +1 -1
- package/dist/esm/util/column-type.d.ts +1 -1
- package/package.json +36 -34
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { DEFAULT_MIGRATION_TABLE } from '../../migration/migrator.js';
|
|
3
3
|
import { sql } from '../../raw-builder/sql.js';
|
|
4
4
|
import { DialectAdapterBase } from '../dialect-adapter-base.js';
|
|
5
|
+
const LOCK_PRINCIPAL = 'dbo';
|
|
5
6
|
export class MssqlAdapter extends DialectAdapterBase {
|
|
6
7
|
get supportsCreateIfNotExists() {
|
|
7
8
|
return false;
|
|
@@ -12,14 +13,19 @@ export class MssqlAdapter extends DialectAdapterBase {
|
|
|
12
13
|
get supportsOutput() {
|
|
13
14
|
return true;
|
|
14
15
|
}
|
|
15
|
-
async acquireMigrationLock(db) {
|
|
16
|
-
// Acquire a
|
|
16
|
+
async acquireMigrationLock(db, _opt) {
|
|
17
|
+
// Acquire a session-level exclusive lock on the migrations table. A
|
|
18
|
+
// session-level lock (as opposed to the default transaction-level lock)
|
|
19
|
+
// stays held after the migration transaction commits and until we release
|
|
20
|
+
// it explicitly in `releaseMigrationLock` OR the session ends. This way we
|
|
21
|
+
// know the lock is either released by us after successful or failed
|
|
22
|
+
// migrations OR it's released by SQL Server if the connection dies.
|
|
17
23
|
// https://learn.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-getapplock-transact-sql?view=sql-server-ver16
|
|
18
|
-
await sql `exec sp_getapplock @DbPrincipal = ${sql.lit(
|
|
24
|
+
await sql `exec sp_getapplock @DbPrincipal = ${sql.lit(LOCK_PRINCIPAL)}, @Resource = ${sql.lit(DEFAULT_MIGRATION_TABLE)}, @LockMode = ${sql.lit('Exclusive')}, @LockOwner = ${sql.lit('Session')}`.execute(db);
|
|
19
25
|
}
|
|
20
|
-
async releaseMigrationLock() {
|
|
21
|
-
//
|
|
22
|
-
//
|
|
23
|
-
|
|
26
|
+
async releaseMigrationLock(db, _opt) {
|
|
27
|
+
// Release the session-level lock acquired in `acquireMigrationLock`.
|
|
28
|
+
// https://learn.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-releaseapplock-transact-sql?view=sql-server-ver16
|
|
29
|
+
await sql `exec sp_releaseapplock @DbPrincipal = ${sql.lit(LOCK_PRINCIPAL)}, @Resource = ${sql.lit(DEFAULT_MIGRATION_TABLE)}, @LockOwner = ${sql.lit('Session')}`.execute(db);
|
|
24
30
|
}
|
|
25
31
|
}
|
|
@@ -25,6 +25,9 @@ export declare class MssqlDriver implements Driver {
|
|
|
25
25
|
beginTransaction(connection: MssqlConnection, settings: TransactionSettings): Promise<void>;
|
|
26
26
|
/**
|
|
27
27
|
* Commits a transaction.
|
|
28
|
+
*
|
|
29
|
+
* Throws {@link AbortedTransactionError} if the database confirms that
|
|
30
|
+
* the transaction was rolled back instead of committed.
|
|
28
31
|
*/
|
|
29
32
|
commitTransaction(connection: MssqlConnection): Promise<void>;
|
|
30
33
|
/**
|
|
@@ -10,6 +10,16 @@ export interface MysqlDialectConfig {
|
|
|
10
10
|
*
|
|
11
11
|
* If a function is provided, it's called once when the first query is executed.
|
|
12
12
|
*
|
|
13
|
+
* Once the driver has initialized, {@link Kysely.destroy} calls
|
|
14
|
+
* `pool.end(callback)`, whether the pool is supplied directly or returned by a
|
|
15
|
+
* function. If initialization hasn't started, `db.destroy()` does nothing,
|
|
16
|
+
* even if the supplied pool has been used outside Kysely.
|
|
17
|
+
*
|
|
18
|
+
* If Kysely is not the sole consumer of the pool, or the pool's lifecycle is
|
|
19
|
+
* managed elsewhere, skip `db.destroy()`. Let the application call
|
|
20
|
+
* `pool.end(callback)` once all consumers, including Kysely, have finished. No
|
|
21
|
+
* separate cleanup of the `Kysely` instance is needed.
|
|
22
|
+
*
|
|
13
23
|
* https://github.com/sidorares/node-mysql2#using-connection-pools
|
|
14
24
|
*/
|
|
15
25
|
pool: MysqlPool | (() => Promise<MysqlPool>);
|
|
@@ -24,6 +24,9 @@ export declare class MysqlDriver implements Driver {
|
|
|
24
24
|
beginTransaction(connection: DatabaseConnection, settings: TransactionSettings): Promise<void>;
|
|
25
25
|
/**
|
|
26
26
|
* Commits a transaction.
|
|
27
|
+
*
|
|
28
|
+
* Throws {@link AbortedTransactionError} if the database confirms that
|
|
29
|
+
* the transaction was rolled back instead of committed.
|
|
27
30
|
*/
|
|
28
31
|
commitTransaction(connection: DatabaseConnection): Promise<void>;
|
|
29
32
|
/**
|
|
@@ -76,5 +76,5 @@ export declare class PostgresAdapter extends DialectAdapterBase {
|
|
|
76
76
|
* is a single connection (session) that was used to execute the migrations
|
|
77
77
|
* and the `acquireMigrationLock` call.
|
|
78
78
|
*/
|
|
79
|
-
releaseMigrationLock(
|
|
79
|
+
releaseMigrationLock(db: Kysely<any>, _opt: MigrationLockOptions): Promise<void>;
|
|
80
80
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/// <reference types="./postgres-adapter.d.ts" />
|
|
2
2
|
import { sql } from '../../raw-builder/sql.js';
|
|
3
3
|
import { DialectAdapterBase } from '../dialect-adapter-base.js';
|
|
4
|
-
// Random id for our transaction lock.
|
|
5
4
|
const LOCK_ID = BigInt('3853314791062309107');
|
|
5
|
+
const LOCK_TIMEOUT_MILLISECONDS = 60 * 60 * 1_000;
|
|
6
6
|
export class PostgresAdapter extends DialectAdapterBase {
|
|
7
7
|
get supportsTransactionalDdl() {
|
|
8
8
|
return true;
|
|
@@ -11,12 +11,18 @@ export class PostgresAdapter extends DialectAdapterBase {
|
|
|
11
11
|
return true;
|
|
12
12
|
}
|
|
13
13
|
async acquireMigrationLock(db, _opt) {
|
|
14
|
-
//
|
|
15
|
-
|
|
14
|
+
// in 1 RTT, acquire a session-level advisory lock with a timeout.
|
|
15
|
+
//
|
|
16
|
+
// if ever this runs inside a transaction, niche edge case we support - the
|
|
17
|
+
// user is responsible to set a different timeout value or disable (`0` value).
|
|
18
|
+
await sql `
|
|
19
|
+
with set_timeout as (
|
|
20
|
+
select set_config('lock_timeout', '${sql.lit(LOCK_TIMEOUT_MILLISECONDS)}', true) as config_val
|
|
21
|
+
)
|
|
22
|
+
select pg_advisory_lock(${sql.lit(LOCK_ID)})
|
|
23
|
+
from set_timeout`.execute(db);
|
|
16
24
|
}
|
|
17
|
-
async releaseMigrationLock(
|
|
18
|
-
|
|
19
|
-
// end of the transaction and since `supportsTransactionalDdl` true, we know
|
|
20
|
-
// the `db` instance passed to acquireMigrationLock is actually a transaction.
|
|
25
|
+
async releaseMigrationLock(db, _opt) {
|
|
26
|
+
await sql `select pg_advisory_unlock(${sql.lit(LOCK_ID)})`.execute(db);
|
|
21
27
|
}
|
|
22
28
|
}
|
|
@@ -8,6 +8,16 @@ export interface PostgresDialectConfig {
|
|
|
8
8
|
*
|
|
9
9
|
* If a function is provided, it's called once when the first query is executed.
|
|
10
10
|
*
|
|
11
|
+
* Once the driver has initialized, {@link Kysely.destroy} calls `pool.end()`,
|
|
12
|
+
* whether the pool is supplied directly or returned by a function. If
|
|
13
|
+
* initialization hasn't started, `db.destroy()` does nothing, even if the
|
|
14
|
+
* supplied pool has been used outside Kysely.
|
|
15
|
+
*
|
|
16
|
+
* If Kysely is not the sole consumer of the pool, or the pool's lifecycle is
|
|
17
|
+
* managed elsewhere, skip `db.destroy()`. Let the application call `pool.end()`
|
|
18
|
+
* once all consumers, including Kysely, have finished. No separate cleanup of
|
|
19
|
+
* the `Kysely` instance is needed.
|
|
20
|
+
*
|
|
11
21
|
* https://node-postgres.com/apis/pool
|
|
12
22
|
*/
|
|
13
23
|
pool: PostgresPool | (() => Promise<PostgresPool>);
|
|
@@ -51,7 +61,7 @@ export interface PostgresPool {
|
|
|
51
61
|
export interface PostgresPoolClient {
|
|
52
62
|
query<R>(sql: string, parameters: ReadonlyArray<unknown>): Promise<PostgresQueryResult<R>>;
|
|
53
63
|
query<R>(cursor: PostgresCursor<R>): PostgresCursor<R>;
|
|
54
|
-
release(): void;
|
|
64
|
+
release(destroy?: boolean): void;
|
|
55
65
|
}
|
|
56
66
|
export interface PostgresCursor<T> {
|
|
57
67
|
read(rowsCount: number): Promise<T[]>;
|
|
@@ -59,7 +69,7 @@ export interface PostgresCursor<T> {
|
|
|
59
69
|
}
|
|
60
70
|
export type PostgresCursorConstructor = new <T>(sql: string, parameters: unknown[]) => PostgresCursor<T>;
|
|
61
71
|
export interface PostgresQueryResult<R> {
|
|
62
|
-
command: 'UPDATE' | 'DELETE' | 'INSERT' | 'SELECT' | 'MERGE';
|
|
72
|
+
command: 'UPDATE' | 'DELETE' | 'INSERT' | 'SELECT' | 'MERGE' | 'COMMIT' | 'ROLLBACK';
|
|
63
73
|
rowCount: number;
|
|
64
74
|
rows: R[];
|
|
65
75
|
}
|
|
@@ -4,6 +4,7 @@ import { CompiledQuery } from '../../query-compiler/compiled-query.js';
|
|
|
4
4
|
import type { QueryCompiler } from '../../query-compiler/query-compiler.js';
|
|
5
5
|
import type { PostgresCursorConstructor, PostgresDialectConfig, PostgresPoolClient } from './postgres-dialect-config.js';
|
|
6
6
|
declare const PRIVATE_RELEASE_METHOD: unique symbol;
|
|
7
|
+
declare const PRIVATE_MARK_FOR_DISCARD_METHOD: unique symbol;
|
|
7
8
|
export declare class PostgresDriver implements Driver {
|
|
8
9
|
#private;
|
|
9
10
|
constructor(config: PostgresDialectConfig);
|
|
@@ -24,12 +25,15 @@ export declare class PostgresDriver implements Driver {
|
|
|
24
25
|
beginTransaction(connection: DatabaseConnection, settings: TransactionSettings): Promise<void>;
|
|
25
26
|
/**
|
|
26
27
|
* Commits a transaction.
|
|
28
|
+
*
|
|
29
|
+
* Throws {@link AbortedTransactionError} if the database confirms that
|
|
30
|
+
* the transaction was rolled back instead of committed.
|
|
27
31
|
*/
|
|
28
32
|
commitTransaction(connection: DatabaseConnection): Promise<void>;
|
|
29
33
|
/**
|
|
30
34
|
* Rolls back a transaction.
|
|
31
35
|
*/
|
|
32
|
-
rollbackTransaction(connection:
|
|
36
|
+
rollbackTransaction(connection: PostgresConnection): Promise<void>;
|
|
33
37
|
savepoint(connection: DatabaseConnection, savepointName: string, compileQuery: QueryCompiler['compileQuery']): Promise<void>;
|
|
34
38
|
rollbackToSavepoint(connection: DatabaseConnection, savepointName: string, compileQuery: QueryCompiler['compileQuery']): Promise<void>;
|
|
35
39
|
releaseSavepoint(connection: DatabaseConnection, savepointName: string, compileQuery: QueryCompiler['compileQuery']): Promise<void>;
|
|
@@ -51,5 +55,6 @@ declare class PostgresConnection implements DatabaseConnection {
|
|
|
51
55
|
executeQuery<O>(compiledQuery: CompiledQuery): Promise<QueryResult<O>>;
|
|
52
56
|
streamQuery<O>(compiledQuery: CompiledQuery, chunkSize: number): AsyncIterableIterator<QueryResult<O>>;
|
|
53
57
|
[PRIVATE_RELEASE_METHOD](): void;
|
|
58
|
+
[PRIVATE_MARK_FOR_DISCARD_METHOD](): void;
|
|
54
59
|
}
|
|
55
60
|
export {};
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
/// <reference types="./postgres-driver.d.ts" />
|
|
2
|
+
import { AbortedTransactionError } from '../../driver/aborted-transaction-error.js';
|
|
2
3
|
import { parseSavepointCommand } from '../../parser/savepoint-parser.js';
|
|
3
4
|
import { CompiledQuery } from '../../query-compiler/compiled-query.js';
|
|
4
5
|
import { isFunction, freeze } from '../../util/object-utils.js';
|
|
5
6
|
import { createQueryId } from '../../util/query-id.js';
|
|
6
7
|
import { extendStackTrace } from '../../util/stack-trace-utils.js';
|
|
7
8
|
const PRIVATE_RELEASE_METHOD = Symbol();
|
|
9
|
+
const PRIVATE_MARK_FOR_DISCARD_METHOD = Symbol();
|
|
8
10
|
export class PostgresDriver {
|
|
9
11
|
#config;
|
|
10
12
|
#connections = new WeakMap();
|
|
@@ -19,6 +21,11 @@ export class PostgresDriver {
|
|
|
19
21
|
}
|
|
20
22
|
async acquireConnection() {
|
|
21
23
|
const client = await this.#pool.connect();
|
|
24
|
+
// `destroy` was called while the connection was being acquired.
|
|
25
|
+
if (!this.#pool) {
|
|
26
|
+
client.release();
|
|
27
|
+
throw new Error('driver has already been destroyed');
|
|
28
|
+
}
|
|
22
29
|
let connection = this.#connections.get(client);
|
|
23
30
|
if (!connection) {
|
|
24
31
|
connection = new PostgresConnection(client, {
|
|
@@ -53,10 +60,21 @@ export class PostgresDriver {
|
|
|
53
60
|
}
|
|
54
61
|
}
|
|
55
62
|
async commitTransaction(connection) {
|
|
56
|
-
await connection.executeQuery(CompiledQuery.raw('commit'));
|
|
63
|
+
const { rows } = await connection.executeQuery(CompiledQuery.raw('commit'));
|
|
64
|
+
// PostgreSQL completes COMMIT with a ROLLBACK tag if an earlier
|
|
65
|
+
// statement error left the transaction aborted.
|
|
66
|
+
if (rows[0]?.command === 'ROLLBACK') {
|
|
67
|
+
throw new AbortedTransactionError();
|
|
68
|
+
}
|
|
57
69
|
}
|
|
58
70
|
async rollbackTransaction(connection) {
|
|
59
|
-
|
|
71
|
+
try {
|
|
72
|
+
await connection.executeQuery(CompiledQuery.raw('rollback'));
|
|
73
|
+
}
|
|
74
|
+
catch (err) {
|
|
75
|
+
connection[PRIVATE_MARK_FOR_DISCARD_METHOD]();
|
|
76
|
+
throw err;
|
|
77
|
+
}
|
|
60
78
|
}
|
|
61
79
|
async savepoint(connection, savepointName, compileQuery) {
|
|
62
80
|
await connection.executeQuery(compileQuery(parseSavepointCommand('savepoint', savepointName), createQueryId()));
|
|
@@ -81,13 +99,18 @@ export class PostgresDriver {
|
|
|
81
99
|
class PostgresConnection {
|
|
82
100
|
#client;
|
|
83
101
|
#options;
|
|
102
|
+
#discarded;
|
|
84
103
|
constructor(client, options) {
|
|
85
104
|
this.#client = client;
|
|
86
105
|
this.#options = options;
|
|
87
106
|
}
|
|
88
107
|
async executeQuery(compiledQuery) {
|
|
108
|
+
this.#assertNotDiscarded();
|
|
89
109
|
try {
|
|
90
110
|
const { command, rowCount, rows } = await this.#client.query(compiledQuery.sql, [...compiledQuery.parameters]);
|
|
111
|
+
if (command === 'ROLLBACK' || command === 'COMMIT') {
|
|
112
|
+
return { rows: [{ command }] };
|
|
113
|
+
}
|
|
91
114
|
return {
|
|
92
115
|
numAffectedRows: command === 'INSERT' ||
|
|
93
116
|
command === 'UPDATE' ||
|
|
@@ -109,6 +132,7 @@ class PostgresConnection {
|
|
|
109
132
|
if (!Number.isInteger(chunkSize) || chunkSize <= 0) {
|
|
110
133
|
throw new Error('chunkSize must be a positive integer');
|
|
111
134
|
}
|
|
135
|
+
this.#assertNotDiscarded();
|
|
112
136
|
const cursor = this.#client.query(new this.#options.cursor(compiledQuery.sql, compiledQuery.parameters.slice()));
|
|
113
137
|
try {
|
|
114
138
|
while (true) {
|
|
@@ -126,6 +150,14 @@ class PostgresConnection {
|
|
|
126
150
|
}
|
|
127
151
|
}
|
|
128
152
|
[PRIVATE_RELEASE_METHOD]() {
|
|
129
|
-
this.#client.release();
|
|
153
|
+
this.#client.release(Boolean(this.#discarded));
|
|
154
|
+
}
|
|
155
|
+
[PRIVATE_MARK_FOR_DISCARD_METHOD]() {
|
|
156
|
+
this.#discarded = true;
|
|
157
|
+
}
|
|
158
|
+
#assertNotDiscarded() {
|
|
159
|
+
if (this.#discarded) {
|
|
160
|
+
throw new Error('Postgres connection has been discarded');
|
|
161
|
+
}
|
|
130
162
|
}
|
|
131
163
|
}
|
|
@@ -71,20 +71,26 @@ export class PostgresIntrospector {
|
|
|
71
71
|
};
|
|
72
72
|
}
|
|
73
73
|
#parseTableMetadata(columns) {
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
74
|
+
const tables = [];
|
|
75
|
+
const schemas = new Map();
|
|
76
|
+
for (const column of columns) {
|
|
77
|
+
let schema = schemas.get(column.schema);
|
|
78
|
+
if (!schema) {
|
|
79
|
+
schema = new Map();
|
|
80
|
+
schemas.set(column.schema, schema);
|
|
81
|
+
}
|
|
82
|
+
let table = schema.get(column.table);
|
|
83
|
+
if (!table) {
|
|
84
|
+
table = freeze({
|
|
81
85
|
columns: [],
|
|
82
86
|
isView: column.table_type === 'v',
|
|
83
|
-
name: table,
|
|
84
|
-
schema,
|
|
85
|
-
})
|
|
87
|
+
name: column.table,
|
|
88
|
+
schema: column.schema,
|
|
89
|
+
});
|
|
90
|
+
schema.set(column.table, table);
|
|
91
|
+
tables.push(table);
|
|
86
92
|
}
|
|
87
|
-
|
|
93
|
+
table.columns.push(freeze({
|
|
88
94
|
comment: column.column_description ?? undefined,
|
|
89
95
|
dataType: column.type,
|
|
90
96
|
dataTypeSchema: column.type_schema,
|
|
@@ -94,6 +100,6 @@ export class PostgresIntrospector {
|
|
|
94
100
|
name: column.column,
|
|
95
101
|
}));
|
|
96
102
|
}
|
|
97
|
-
return
|
|
103
|
+
return tables;
|
|
98
104
|
}
|
|
99
105
|
}
|
|
@@ -8,6 +8,16 @@ export interface SqliteDialectConfig {
|
|
|
8
8
|
*
|
|
9
9
|
* If a function is provided, it's called once when the first query is executed.
|
|
10
10
|
*
|
|
11
|
+
* Once the driver has initialized, {@link Kysely.destroy} calls
|
|
12
|
+
* `database.close()`, whether the database is supplied directly or returned by
|
|
13
|
+
* a function. If initialization hasn't started, `db.destroy()` does nothing,
|
|
14
|
+
* even if the supplied database has been used outside Kysely.
|
|
15
|
+
*
|
|
16
|
+
* If Kysely is not the sole consumer of the database, or the database's
|
|
17
|
+
* lifecycle is managed elsewhere, skip `db.destroy()`. Let the application
|
|
18
|
+
* call `database.close()` once all consumers, including Kysely, have finished.
|
|
19
|
+
* No separate cleanup of the `Kysely` instance is needed.
|
|
20
|
+
*
|
|
11
21
|
* https://github.com/JoshuaWise/better-sqlite3/blob/master/docs/api.md#new-databasepath-options
|
|
12
22
|
*/
|
|
13
23
|
database: SqliteDatabase | (() => Promise<SqliteDatabase>);
|
|
@@ -22,6 +22,9 @@ export declare class SqliteDriver implements Driver {
|
|
|
22
22
|
beginTransaction(connection: DatabaseConnection): Promise<void>;
|
|
23
23
|
/**
|
|
24
24
|
* Commits a transaction.
|
|
25
|
+
*
|
|
26
|
+
* Throws {@link AbortedTransactionError} if the database confirms that
|
|
27
|
+
* the transaction was rolled back instead of committed.
|
|
25
28
|
*/
|
|
26
29
|
commitTransaction(connection: DatabaseConnection): Promise<void>;
|
|
27
30
|
/**
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
declare const ABORTED_TRANSACTION_ERROR: unique symbol;
|
|
2
|
+
/**
|
|
3
|
+
* Thrown when the database rolls back a transaction instead of committing it.
|
|
4
|
+
*/
|
|
5
|
+
export declare class AbortedTransactionError extends Error {
|
|
6
|
+
name: string;
|
|
7
|
+
readonly [ABORTED_TRANSACTION_ERROR] = true;
|
|
8
|
+
constructor();
|
|
9
|
+
}
|
|
10
|
+
export declare function isAbortedTransactionError(error: unknown): error is AbortedTransactionError;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/// <reference types="./aborted-transaction-error.d.ts" />
|
|
2
|
+
import { isObject } from '../util/object-utils.js';
|
|
3
|
+
const ABORTED_TRANSACTION_ERROR = Symbol.for('kysely.AbortedTransactionError');
|
|
4
|
+
/**
|
|
5
|
+
* Thrown when the database rolls back a transaction instead of committing it.
|
|
6
|
+
*/
|
|
7
|
+
export class AbortedTransactionError extends Error {
|
|
8
|
+
name = 'AbortedTransactionError';
|
|
9
|
+
[ABORTED_TRANSACTION_ERROR] = true;
|
|
10
|
+
constructor() {
|
|
11
|
+
super('Transaction was rolled back instead of committed');
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export function isAbortedTransactionError(error) {
|
|
15
|
+
return isObject(error) && ABORTED_TRANSACTION_ERROR in error;
|
|
16
|
+
}
|
|
@@ -23,6 +23,9 @@ export interface Driver {
|
|
|
23
23
|
beginTransaction(connection: DatabaseConnection, settings: TransactionSettings): Promise<void>;
|
|
24
24
|
/**
|
|
25
25
|
* Commits a transaction.
|
|
26
|
+
*
|
|
27
|
+
* Throws {@link AbortedTransactionError} if the database confirms that
|
|
28
|
+
* the transaction was rolled back instead of committed.
|
|
26
29
|
*/
|
|
27
30
|
commitTransaction(connection: DatabaseConnection): Promise<void>;
|
|
28
31
|
/**
|
|
@@ -55,6 +55,9 @@ export declare class DummyDriver implements Driver {
|
|
|
55
55
|
beginTransaction(): Promise<void>;
|
|
56
56
|
/**
|
|
57
57
|
* Commits a transaction.
|
|
58
|
+
*
|
|
59
|
+
* Throws {@link AbortedTransactionError} if the database confirms that
|
|
60
|
+
* the transaction was rolled back instead of committed.
|
|
58
61
|
*/
|
|
59
62
|
commitTransaction(): Promise<void>;
|
|
60
63
|
/**
|
|
@@ -31,6 +31,9 @@ export declare class RuntimeDriver implements Driver {
|
|
|
31
31
|
beginTransaction(connection: DatabaseConnection, settings: TransactionSettings): Promise<void>;
|
|
32
32
|
/**
|
|
33
33
|
* Commits a transaction.
|
|
34
|
+
*
|
|
35
|
+
* Throws {@link AbortedTransactionError} if the database confirms that
|
|
36
|
+
* the transaction was rolled back instead of committed.
|
|
34
37
|
*/
|
|
35
38
|
commitTransaction(connection: DatabaseConnection): Promise<void>;
|
|
36
39
|
/**
|
|
@@ -202,7 +202,9 @@ export declare function jsonObjectFrom<O>(expr: Expression<O>): RawBuilder<Simpl
|
|
|
202
202
|
*
|
|
203
203
|
* ```sql
|
|
204
204
|
* select "id", json_query(
|
|
205
|
-
* '{"
|
|
205
|
+
* '{"'+string_escape(N'first', 'json')+'":"'+string_escape("first_name", 'json')+
|
|
206
|
+
* '","'+string_escape(N'last', 'json')+'":"'+string_escape("last_name", 'json')+
|
|
207
|
+
* '","'+string_escape(N'full', 'json')+'":"'+string_escape(concat("first_name", ' ', "last_name"), 'json')+'"}'
|
|
206
208
|
* ) as "name"
|
|
207
209
|
* from "person"
|
|
208
210
|
* ```
|
|
@@ -205,11 +205,13 @@ export function jsonObjectFrom(expr) {
|
|
|
205
205
|
*
|
|
206
206
|
* ```sql
|
|
207
207
|
* select "id", json_query(
|
|
208
|
-
* '{"
|
|
208
|
+
* '{"'+string_escape(N'first', 'json')+'":"'+string_escape("first_name", 'json')+
|
|
209
|
+
* '","'+string_escape(N'last', 'json')+'":"'+string_escape("last_name", 'json')+
|
|
210
|
+
* '","'+string_escape(N'full', 'json')+'":"'+string_escape(concat("first_name", ' ', "last_name"), 'json')+'"}'
|
|
209
211
|
* ) as "name"
|
|
210
212
|
* from "person"
|
|
211
213
|
* ```
|
|
212
214
|
*/
|
|
213
215
|
export function jsonBuildObject(obj) {
|
|
214
|
-
return sql `json_query('{${sql.join(Object.keys(obj).map((k) => sql `"${sql.
|
|
216
|
+
return sql `json_query('{${sql.join(Object.keys(obj).map((k) => sql `"'+string_escape(N${sql.lit(k)}, 'json')+'":"'+string_escape(${obj[k]}, 'json')+'"`), sql `,`)}}')`;
|
|
215
217
|
}
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -57,6 +57,7 @@ export * from './dynamic/dynamic.js';
|
|
|
57
57
|
export * from './dynamic/dynamic-reference-builder.js';
|
|
58
58
|
export * from './dynamic/dynamic-table-builder.js';
|
|
59
59
|
export * from './driver/driver.js';
|
|
60
|
+
export * from './driver/aborted-transaction-error.js';
|
|
60
61
|
export * from './driver/database-connection.js';
|
|
61
62
|
export * from './driver/connection-provider.js';
|
|
62
63
|
export * from './driver/default-connection-provider.js';
|
package/dist/esm/index.js
CHANGED
|
@@ -58,6 +58,7 @@ export * from './dynamic/dynamic.js';
|
|
|
58
58
|
export * from './dynamic/dynamic-reference-builder.js';
|
|
59
59
|
export * from './dynamic/dynamic-table-builder.js';
|
|
60
60
|
export * from './driver/driver.js';
|
|
61
|
+
export * from './driver/aborted-transaction-error.js';
|
|
61
62
|
export * from './driver/database-connection.js';
|
|
62
63
|
export * from './driver/connection-provider.js';
|
|
63
64
|
export * from './driver/default-connection-provider.js';
|
package/dist/esm/kysely.d.ts
CHANGED
|
@@ -29,7 +29,8 @@ declare global {
|
|
|
29
29
|
* The main Kysely class.
|
|
30
30
|
*
|
|
31
31
|
* You should create one instance of `Kysely` per database using the {@link Kysely}
|
|
32
|
-
* constructor.
|
|
32
|
+
* constructor. The dialect manages database connections and may use a shared
|
|
33
|
+
* pool or database instance.
|
|
33
34
|
*
|
|
34
35
|
* ### Examples
|
|
35
36
|
*
|
|
@@ -384,7 +385,16 @@ export declare class Kysely<DB> extends QueryCreator<DB> implements QueryExecuto
|
|
|
384
385
|
/**
|
|
385
386
|
* Releases all resources and disconnects from the database.
|
|
386
387
|
*
|
|
387
|
-
*
|
|
388
|
+
* Call this when you are done using the `Kysely` instance and Kysely is
|
|
389
|
+
* responsible for closing its connections, pool, or database instance.
|
|
390
|
+
*
|
|
391
|
+
* If the pool or database instance is shared with other consumers or its
|
|
392
|
+
* lifecycle is managed elsewhere, skip this call. Let the application close it
|
|
393
|
+
* once all consumers, including Kysely, have finished. No separate cleanup of
|
|
394
|
+
* the `Kysely` instance is needed.
|
|
395
|
+
*
|
|
396
|
+
* The driver is initialized lazily. If initialization hasn't started, this
|
|
397
|
+
* method does nothing.
|
|
388
398
|
*/
|
|
389
399
|
destroy(): Promise<void>;
|
|
390
400
|
/**
|
|
@@ -511,7 +521,16 @@ export declare class Transaction<DB> extends Kysely<DB> {
|
|
|
511
521
|
/**
|
|
512
522
|
* Releases all resources and disconnects from the database.
|
|
513
523
|
*
|
|
514
|
-
*
|
|
524
|
+
* Call this when you are done using the `Kysely` instance and Kysely is
|
|
525
|
+
* responsible for closing its connections, pool, or database instance.
|
|
526
|
+
*
|
|
527
|
+
* If the pool or database instance is shared with other consumers or its
|
|
528
|
+
* lifecycle is managed elsewhere, skip this call. Let the application close it
|
|
529
|
+
* once all consumers, including Kysely, have finished. No separate cleanup of
|
|
530
|
+
* the `Kysely` instance is needed.
|
|
531
|
+
*
|
|
532
|
+
* The driver is initialized lazily. If initialization hasn't started, this
|
|
533
|
+
* method does nothing.
|
|
515
534
|
*/
|
|
516
535
|
destroy(): Promise<void>;
|
|
517
536
|
/**
|
|
@@ -646,6 +665,13 @@ export declare class ControlledTransaction<DB, S extends string[] = []> extends
|
|
|
646
665
|
/**
|
|
647
666
|
* Commits the transaction.
|
|
648
667
|
*
|
|
668
|
+
* If the database rolls back instead of committing, marks the transaction
|
|
669
|
+
* as rolled back, releases the connection and throws {@link AbortedTransactionError}.
|
|
670
|
+
*
|
|
671
|
+
* Waits for ongoing queries to finish. Streams must be exhausted or closed
|
|
672
|
+
* before awaiting this command. When consuming a stream with `for await`,
|
|
673
|
+
* exit the loop before committing.
|
|
674
|
+
*
|
|
649
675
|
* See {@link rollback}.
|
|
650
676
|
*
|
|
651
677
|
* ### Examples
|
|
@@ -671,6 +697,16 @@ export declare class ControlledTransaction<DB, S extends string[] = []> extends
|
|
|
671
697
|
/**
|
|
672
698
|
* Rolls back the transaction.
|
|
673
699
|
*
|
|
700
|
+
* If a commit already reported that the database rolled back the transaction,
|
|
701
|
+
* succeeds without sending another rollback command.
|
|
702
|
+
*
|
|
703
|
+
* The connection is released even if the rollback fails, so the transaction
|
|
704
|
+
* cannot be used afterwards in either case.
|
|
705
|
+
*
|
|
706
|
+
* Waits for ongoing queries to finish. Streams must be exhausted or closed
|
|
707
|
+
* before awaiting this command. When consuming a stream with `for await`,
|
|
708
|
+
* exit the loop before rolling back.
|
|
709
|
+
*
|
|
674
710
|
* See {@link commit} and {@link rollbackToSavepoint}.
|
|
675
711
|
*
|
|
676
712
|
* ### Examples
|
|
@@ -696,6 +732,10 @@ export declare class ControlledTransaction<DB, S extends string[] = []> extends
|
|
|
696
732
|
/**
|
|
697
733
|
* Creates a savepoint with a given name.
|
|
698
734
|
*
|
|
735
|
+
* Waits for ongoing queries to finish. Streams must be exhausted or closed
|
|
736
|
+
* before awaiting this command. When consuming a stream with `for await`,
|
|
737
|
+
* exit the loop before creating a savepoint.
|
|
738
|
+
*
|
|
699
739
|
* See {@link rollbackToSavepoint} and {@link releaseSavepoint}.
|
|
700
740
|
*
|
|
701
741
|
* For a type-safe experience, you should use the returned instance from now on.
|
|
@@ -726,6 +766,10 @@ export declare class ControlledTransaction<DB, S extends string[] = []> extends
|
|
|
726
766
|
/**
|
|
727
767
|
* Rolls back to a savepoint with a given name.
|
|
728
768
|
*
|
|
769
|
+
* Waits for ongoing queries to finish. Streams must be exhausted or closed
|
|
770
|
+
* before awaiting this command. When consuming a stream with `for await`,
|
|
771
|
+
* exit the loop before rolling back to a savepoint.
|
|
772
|
+
*
|
|
729
773
|
* See {@link savepoint} and {@link releaseSavepoint}.
|
|
730
774
|
*
|
|
731
775
|
* You must use the same instance returned by {@link savepoint}, or
|
|
@@ -757,6 +801,10 @@ export declare class ControlledTransaction<DB, S extends string[] = []> extends
|
|
|
757
801
|
/**
|
|
758
802
|
* Releases a savepoint with a given name.
|
|
759
803
|
*
|
|
804
|
+
* Waits for ongoing queries to finish. Streams must be exhausted or closed
|
|
805
|
+
* before awaiting this command. When consuming a stream with `for await`,
|
|
806
|
+
* exit the loop before releasing a savepoint.
|
|
807
|
+
*
|
|
760
808
|
* See {@link savepoint} and {@link rollbackToSavepoint}.
|
|
761
809
|
*
|
|
762
810
|
* You must use the same instance returned by {@link savepoint}, or
|
|
@@ -834,8 +882,12 @@ export declare class ControlledTransaction<DB, S extends string[] = []> extends
|
|
|
834
882
|
*/
|
|
835
883
|
withTables<T extends Record<string, Record<string, any>>>(): ControlledTransaction<DrainOuterGeneric<DB & T>, S>;
|
|
836
884
|
}
|
|
885
|
+
interface ControlledTransactionState {
|
|
886
|
+
status: 'active' | 'committed' | 'rolled back' | 'aborted';
|
|
887
|
+
}
|
|
837
888
|
interface ControlledTransactionProps extends KyselyProps {
|
|
838
889
|
readonly connection: ControlledConnection;
|
|
890
|
+
readonly transactionState?: ControlledTransactionState;
|
|
839
891
|
}
|
|
840
892
|
export declare class Command<T> {
|
|
841
893
|
#private;
|