kysely 0.23.2 → 0.23.4
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 +22 -24
- package/dist/cjs/dialect/dialect-adapter-base.d.ts +32 -6
- package/dist/cjs/dialect/dialect-adapter.d.ts +50 -8
- package/dist/cjs/dialect/mysql/mysql-adapter.d.ts +32 -6
- package/dist/cjs/dialect/mysql/mysql-introspector.js +3 -3
- package/dist/cjs/dialect/postgres/postgres-adapter.d.ts +32 -6
- package/dist/cjs/dialect/postgres/postgres-introspector.js +3 -3
- package/dist/cjs/dialect/sqlite/sqlite-adapter.d.ts +32 -6
- package/dist/cjs/dialect/sqlite/sqlite-introspector.js +3 -3
- package/dist/cjs/index.d.ts +2 -1
- package/dist/cjs/index.js +1 -0
- package/dist/cjs/migration/migrator.d.ts +8 -3
- package/dist/cjs/migration/migrator.js +15 -5
- package/dist/cjs/operation-node/create-index-node.d.ts +1 -0
- package/dist/cjs/operation-node/delete-query-node.d.ts +3 -0
- package/dist/cjs/operation-node/delete-query-node.js +9 -0
- package/dist/cjs/operation-node/operation-node-transformer.d.ts +2 -0
- package/dist/cjs/operation-node/operation-node-transformer.js +9 -0
- package/dist/cjs/operation-node/operation-node-visitor.d.ts +2 -0
- package/dist/cjs/operation-node/operation-node-visitor.js +1 -0
- package/dist/cjs/operation-node/operation-node.d.ts +1 -1
- package/dist/cjs/operation-node/operator-node.d.ts +1 -1
- package/dist/cjs/operation-node/operator-node.js +1 -0
- package/dist/cjs/operation-node/using-node.d.ts +13 -0
- package/dist/cjs/operation-node/using-node.js +24 -0
- package/dist/cjs/parser/binary-operation-parser.d.ts +1 -1
- package/dist/cjs/parser/update-set-parser.d.ts +3 -3
- package/dist/cjs/parser/update-set-parser.js +2 -2
- package/dist/cjs/query-builder/delete-query-builder.d.ts +98 -6
- package/dist/cjs/query-builder/delete-query-builder.js +39 -8
- package/dist/cjs/query-builder/insert-query-builder.d.ts +23 -7
- package/dist/cjs/query-builder/insert-query-builder.js +32 -8
- package/dist/cjs/query-builder/on-conflict-builder.d.ts +2 -2
- package/dist/cjs/query-builder/select-query-builder.d.ts +43 -27
- package/dist/cjs/query-builder/select-query-builder.js +53 -29
- package/dist/cjs/query-builder/update-query-builder.d.ts +23 -7
- package/dist/cjs/query-builder/update-query-builder.js +32 -8
- package/dist/cjs/query-compiler/default-query-compiler.d.ts +2 -0
- package/dist/cjs/query-compiler/default-query-compiler.js +11 -0
- package/dist/cjs/raw-builder/raw-builder.d.ts +4 -0
- package/dist/cjs/raw-builder/raw-builder.js +8 -2
- package/dist/cjs/schema/alter-table-builder.d.ts +5 -1
- package/dist/cjs/schema/alter-table-builder.js +8 -2
- package/dist/cjs/schema/create-index-builder.d.ts +6 -0
- package/dist/cjs/schema/create-index-builder.js +13 -0
- package/dist/cjs/schema/create-table-builder.d.ts +6 -2
- package/dist/cjs/schema/create-table-builder.js +9 -3
- package/dist/cjs/util/type-utils.d.ts +18 -0
- package/dist/esm/dialect/dialect-adapter-base.d.ts +32 -6
- package/dist/esm/dialect/dialect-adapter.d.ts +50 -8
- package/dist/esm/dialect/mysql/mysql-adapter.d.ts +32 -6
- package/dist/esm/dialect/mysql/mysql-introspector.js +3 -3
- package/dist/esm/dialect/postgres/postgres-adapter.d.ts +32 -6
- package/dist/esm/dialect/postgres/postgres-introspector.js +3 -3
- package/dist/esm/dialect/sqlite/sqlite-adapter.d.ts +32 -6
- package/dist/esm/dialect/sqlite/sqlite-introspector.js +3 -3
- package/dist/esm/index.d.ts +2 -1
- package/dist/esm/index.js +1 -0
- package/dist/esm/migration/migrator.d.ts +8 -3
- package/dist/esm/migration/migrator.js +15 -5
- package/dist/esm/operation-node/create-index-node.d.ts +1 -0
- package/dist/esm/operation-node/delete-query-node.d.ts +3 -0
- package/dist/esm/operation-node/delete-query-node.js +9 -0
- package/dist/esm/operation-node/operation-node-transformer.d.ts +2 -0
- package/dist/esm/operation-node/operation-node-transformer.js +9 -0
- package/dist/esm/operation-node/operation-node-visitor.d.ts +2 -0
- package/dist/esm/operation-node/operation-node-visitor.js +1 -0
- package/dist/esm/operation-node/operation-node.d.ts +1 -1
- package/dist/esm/operation-node/operator-node.d.ts +1 -1
- package/dist/esm/operation-node/operator-node.js +1 -0
- package/dist/esm/operation-node/using-node.d.ts +13 -0
- package/dist/esm/operation-node/using-node.js +22 -0
- package/dist/esm/parser/binary-operation-parser.d.ts +1 -1
- package/dist/esm/parser/update-set-parser.d.ts +3 -3
- package/dist/esm/parser/update-set-parser.js +2 -2
- package/dist/esm/query-builder/delete-query-builder.d.ts +98 -6
- package/dist/esm/query-builder/delete-query-builder.js +39 -8
- package/dist/esm/query-builder/insert-query-builder.d.ts +23 -7
- package/dist/esm/query-builder/insert-query-builder.js +33 -9
- package/dist/esm/query-builder/on-conflict-builder.d.ts +2 -2
- package/dist/esm/query-builder/select-query-builder.d.ts +43 -27
- package/dist/esm/query-builder/select-query-builder.js +53 -29
- package/dist/esm/query-builder/update-query-builder.d.ts +23 -7
- package/dist/esm/query-builder/update-query-builder.js +33 -9
- package/dist/esm/query-compiler/default-query-compiler.d.ts +2 -0
- package/dist/esm/query-compiler/default-query-compiler.js +11 -0
- package/dist/esm/raw-builder/raw-builder.d.ts +4 -0
- package/dist/esm/raw-builder/raw-builder.js +8 -2
- package/dist/esm/schema/alter-table-builder.d.ts +5 -1
- package/dist/esm/schema/alter-table-builder.js +8 -2
- package/dist/esm/schema/create-index-builder.d.ts +6 -0
- package/dist/esm/schema/create-index-builder.js +13 -0
- package/dist/esm/schema/create-table-builder.d.ts +6 -2
- package/dist/esm/schema/create-table-builder.js +9 -3
- package/dist/esm/util/type-utils.d.ts +18 -0
- package/package.json +1 -1
|
@@ -211,7 +211,7 @@ export declare class CreateTableBuilder<TB extends string, C extends string = ne
|
|
|
211
211
|
* ```ts
|
|
212
212
|
* db.schema
|
|
213
213
|
* .createTable('test')
|
|
214
|
-
*
|
|
214
|
+
* .$call((builder) => builder.addColumn('id', 'integer'))
|
|
215
215
|
* .execute()
|
|
216
216
|
* ```
|
|
217
217
|
*
|
|
@@ -231,10 +231,14 @@ export declare class CreateTableBuilder<TB extends string, C extends string = ne
|
|
|
231
231
|
*
|
|
232
232
|
* db.schema
|
|
233
233
|
* .createTable('test')
|
|
234
|
-
*
|
|
234
|
+
* .$call(addDefaultColumns)
|
|
235
235
|
* .execute()
|
|
236
236
|
* ```
|
|
237
237
|
*/
|
|
238
|
+
$call<T>(func: (qb: this) => T): T;
|
|
239
|
+
/**
|
|
240
|
+
* @deprecated Use `$call` instead
|
|
241
|
+
*/
|
|
238
242
|
call<T>(func: (qb: this) => T): T;
|
|
239
243
|
toOperationNode(): CreateTableNode;
|
|
240
244
|
compile(): CompiledQuery;
|
|
@@ -278,7 +278,7 @@ class CreateTableBuilder {
|
|
|
278
278
|
* ```ts
|
|
279
279
|
* db.schema
|
|
280
280
|
* .createTable('test')
|
|
281
|
-
*
|
|
281
|
+
* .$call((builder) => builder.addColumn('id', 'integer'))
|
|
282
282
|
* .execute()
|
|
283
283
|
* ```
|
|
284
284
|
*
|
|
@@ -298,13 +298,19 @@ class CreateTableBuilder {
|
|
|
298
298
|
*
|
|
299
299
|
* db.schema
|
|
300
300
|
* .createTable('test')
|
|
301
|
-
*
|
|
301
|
+
* .$call(addDefaultColumns)
|
|
302
302
|
* .execute()
|
|
303
303
|
* ```
|
|
304
304
|
*/
|
|
305
|
-
call(func) {
|
|
305
|
+
$call(func) {
|
|
306
306
|
return func(this);
|
|
307
307
|
}
|
|
308
|
+
/**
|
|
309
|
+
* @deprecated Use `$call` instead
|
|
310
|
+
*/
|
|
311
|
+
call(func) {
|
|
312
|
+
return this.$call(func);
|
|
313
|
+
}
|
|
308
314
|
toOperationNode() {
|
|
309
315
|
return this.#props.executor.transformQuery(this.#props.node, this.#props.queryId);
|
|
310
316
|
}
|
|
@@ -96,9 +96,21 @@ export declare type AnyAliasedColumnWithTable<DB, TB extends keyof DB> = {
|
|
|
96
96
|
* Extracts the item type of an array.
|
|
97
97
|
*/
|
|
98
98
|
export declare type ArrayItemType<T> = T extends ReadonlyArray<infer I> ? I : never;
|
|
99
|
+
/**
|
|
100
|
+
* Any select query builder.
|
|
101
|
+
*/
|
|
99
102
|
export declare type AnySelectQueryBuilder = SelectQueryBuilder<any, any, any>;
|
|
103
|
+
/**
|
|
104
|
+
* Given a query output type `O` evaluates to the output type of a `executeTakeFirst` call.
|
|
105
|
+
*/
|
|
100
106
|
export declare type SingleResultType<O> = O extends InsertResult ? O : O extends DeleteResult ? O : O extends UpdateResult ? O : O | undefined;
|
|
107
|
+
/**
|
|
108
|
+
* Represents a database row whose column names and their types are unknown.
|
|
109
|
+
*/
|
|
101
110
|
export declare type UnknownRow = Record<string, unknown>;
|
|
111
|
+
/**
|
|
112
|
+
* Makes all properties of object type `T` nullable.
|
|
113
|
+
*/
|
|
102
114
|
export declare type Nullable<T> = {
|
|
103
115
|
[P in keyof T]: T[P] | null;
|
|
104
116
|
};
|
|
@@ -123,5 +135,11 @@ export declare type Nullable<T> = {
|
|
|
123
135
|
* // { name: string, age: number, species?: 'cat' | 'dog' }
|
|
124
136
|
*/
|
|
125
137
|
export declare type MergePartial<T1, T2> = T1 & Partial<Omit<T2, keyof T1>>;
|
|
138
|
+
/**
|
|
139
|
+
* Evaluates to `true` if `T` is `never`.
|
|
140
|
+
*/
|
|
126
141
|
export declare type IsNever<T> = [T] extends [never] ? true : false;
|
|
142
|
+
/**
|
|
143
|
+
* Evaluates to `true` if the types `T` and `U` are equal.
|
|
144
|
+
*/
|
|
127
145
|
export declare type Equals<T, U> = (<G>() => G extends T ? 1 : 2) extends <G>() => G extends U ? 1 : 2 ? true : false;
|
|
@@ -25,12 +25,38 @@ export declare abstract class DialectAdapterBase implements DialectAdapter {
|
|
|
25
25
|
* Most dialects have explicit locks that can be used, like advisory locks
|
|
26
26
|
* in PostgreSQL and the get_lock function in MySQL.
|
|
27
27
|
*
|
|
28
|
-
* If the dialect doesn't have explicit locks the {@link
|
|
29
|
-
* created by Kysely can be used instead.
|
|
30
|
-
* has two columns `id` and `is_locked` and there's only one row in the
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
28
|
+
* If the dialect doesn't have explicit locks the {@link MigrationLockOptions.lockTable}
|
|
29
|
+
* created by Kysely can be used instead. You can access it through the `options` object.
|
|
30
|
+
* The lock table has two columns `id` and `is_locked` and there's only one row in the table
|
|
31
|
+
* whose id is {@link MigrationLockOptions.lockRowId}. `is_locked` is an integer. Kysely
|
|
32
|
+
* takes care of creating the lock table and inserting the one single row to it before this
|
|
33
|
+
* method is executed. If the dialect supports schemas and the user has specified a custom
|
|
34
|
+
* schema in their migration settings, the options object also contains the schema name in
|
|
35
|
+
* {@link MigrationLockOptions.lockTableSchema}.
|
|
36
|
+
*
|
|
37
|
+
* Here's an example of how you might implement this method for a dialect that doesn't
|
|
38
|
+
* have explicit locks but supports `FOR UPDATE` row locks and transactional DDL:
|
|
39
|
+
*
|
|
40
|
+
* ```ts
|
|
41
|
+
* {
|
|
42
|
+
* async acquireMigrationLock(db, options): Promise<void> {
|
|
43
|
+
* const queryDb = options.lockTableSchema
|
|
44
|
+
* ? db.withSchema(options.lockTableSchema)
|
|
45
|
+
* : db
|
|
46
|
+
*
|
|
47
|
+
* // Since our imaginary dialect supports transactional DDL and has
|
|
48
|
+
* // row locks, we can simply take a row lock here and it will guarantee
|
|
49
|
+
* // all subsequent calls to this method from other transactions will
|
|
50
|
+
* // wait until this transaction finishes.
|
|
51
|
+
* await queryDb
|
|
52
|
+
* .selectFrom(options.lockTable)
|
|
53
|
+
* .selectAll()
|
|
54
|
+
* .where('id', '=', options.lockRowId)
|
|
55
|
+
* .forUpdate()
|
|
56
|
+
* .execute()
|
|
57
|
+
* }
|
|
58
|
+
* }
|
|
59
|
+
* ```
|
|
34
60
|
*
|
|
35
61
|
* If `supportsTransactionalDdl` is `true` then the `db` passed to this method
|
|
36
62
|
* is a transaction inside which the migrations will be executed. Otherwise
|
|
@@ -26,19 +26,45 @@ export interface DialectAdapter {
|
|
|
26
26
|
* Most dialects have explicit locks that can be used, like advisory locks
|
|
27
27
|
* in PostgreSQL and the get_lock function in MySQL.
|
|
28
28
|
*
|
|
29
|
-
* If the dialect doesn't have explicit locks the {@link
|
|
30
|
-
* created by Kysely can be used instead.
|
|
31
|
-
* has two columns `id` and `is_locked` and there's only one row in the
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
29
|
+
* If the dialect doesn't have explicit locks the {@link MigrationLockOptions.lockTable}
|
|
30
|
+
* created by Kysely can be used instead. You can access it through the `options` object.
|
|
31
|
+
* The lock table has two columns `id` and `is_locked` and there's only one row in the table
|
|
32
|
+
* whose id is {@link MigrationLockOptions.lockRowId}. `is_locked` is an integer. Kysely
|
|
33
|
+
* takes care of creating the lock table and inserting the one single row to it before this
|
|
34
|
+
* method is executed. If the dialect supports schemas and the user has specified a custom
|
|
35
|
+
* schema in their migration settings, the options object also contains the schema name in
|
|
36
|
+
* {@link MigrationLockOptions.lockTableSchema}.
|
|
37
|
+
*
|
|
38
|
+
* Here's an example of how you might implement this method for a dialect that doesn't
|
|
39
|
+
* have explicit locks but supports `FOR UPDATE` row locks and transactional DDL:
|
|
40
|
+
*
|
|
41
|
+
* ```ts
|
|
42
|
+
* {
|
|
43
|
+
* async acquireMigrationLock(db, options): Promise<void> {
|
|
44
|
+
* const queryDb = options.lockTableSchema
|
|
45
|
+
* ? db.withSchema(options.lockTableSchema)
|
|
46
|
+
* : db
|
|
47
|
+
*
|
|
48
|
+
* // Since our imaginary dialect supports transactional DDL and has
|
|
49
|
+
* // row locks, we can simply take a row lock here and it will guarantee
|
|
50
|
+
* // all subsequent calls to this method from other transactions will
|
|
51
|
+
* // wait until this transaction finishes.
|
|
52
|
+
* await queryDb
|
|
53
|
+
* .selectFrom(options.lockTable)
|
|
54
|
+
* .selectAll()
|
|
55
|
+
* .where('id', '=', options.lockRowId)
|
|
56
|
+
* .forUpdate()
|
|
57
|
+
* .execute()
|
|
58
|
+
* }
|
|
59
|
+
* }
|
|
60
|
+
* ```
|
|
35
61
|
*
|
|
36
62
|
* If `supportsTransactionalDdl` is `true` then the `db` passed to this method
|
|
37
63
|
* is a transaction inside which the migrations will be executed. Otherwise
|
|
38
64
|
* `db` is a single connection (session) that will be used to execute the
|
|
39
65
|
* migrations.
|
|
40
66
|
*/
|
|
41
|
-
acquireMigrationLock(db: Kysely<any
|
|
67
|
+
acquireMigrationLock(db: Kysely<any>, options: MigrationLockOptions): Promise<void>;
|
|
42
68
|
/**
|
|
43
69
|
* Releases the migration lock. See {@link acquireMigrationLock}.
|
|
44
70
|
*
|
|
@@ -47,5 +73,21 @@ export interface DialectAdapter {
|
|
|
47
73
|
* is a single connection (session) that was used to execute the migrations
|
|
48
74
|
* and the `acquireMigrationLock` call.
|
|
49
75
|
*/
|
|
50
|
-
releaseMigrationLock(db: Kysely<any
|
|
76
|
+
releaseMigrationLock(db: Kysely<any>, options: MigrationLockOptions): Promise<void>;
|
|
77
|
+
}
|
|
78
|
+
export interface MigrationLockOptions {
|
|
79
|
+
/**
|
|
80
|
+
* The name of the migration lock table.
|
|
81
|
+
*/
|
|
82
|
+
readonly lockTable: string;
|
|
83
|
+
/**
|
|
84
|
+
* The id of the only row in the migration lock table.
|
|
85
|
+
*/
|
|
86
|
+
readonly lockRowId: string;
|
|
87
|
+
/**
|
|
88
|
+
* The schema in which the migration lock table lives. This is only
|
|
89
|
+
* defined if the user has specified a custom schema in the migration
|
|
90
|
+
* settings.
|
|
91
|
+
*/
|
|
92
|
+
readonly lockTableSchema?: string;
|
|
51
93
|
}
|
|
@@ -19,12 +19,38 @@ export declare class MysqlAdapter extends DialectAdapterBase {
|
|
|
19
19
|
* Most dialects have explicit locks that can be used, like advisory locks
|
|
20
20
|
* in PostgreSQL and the get_lock function in MySQL.
|
|
21
21
|
*
|
|
22
|
-
* If the dialect doesn't have explicit locks the {@link
|
|
23
|
-
* created by Kysely can be used instead.
|
|
24
|
-
* has two columns `id` and `is_locked` and there's only one row in the
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
22
|
+
* If the dialect doesn't have explicit locks the {@link MigrationLockOptions.lockTable}
|
|
23
|
+
* created by Kysely can be used instead. You can access it through the `options` object.
|
|
24
|
+
* The lock table has two columns `id` and `is_locked` and there's only one row in the table
|
|
25
|
+
* whose id is {@link MigrationLockOptions.lockRowId}. `is_locked` is an integer. Kysely
|
|
26
|
+
* takes care of creating the lock table and inserting the one single row to it before this
|
|
27
|
+
* method is executed. If the dialect supports schemas and the user has specified a custom
|
|
28
|
+
* schema in their migration settings, the options object also contains the schema name in
|
|
29
|
+
* {@link MigrationLockOptions.lockTableSchema}.
|
|
30
|
+
*
|
|
31
|
+
* Here's an example of how you might implement this method for a dialect that doesn't
|
|
32
|
+
* have explicit locks but supports `FOR UPDATE` row locks and transactional DDL:
|
|
33
|
+
*
|
|
34
|
+
* ```ts
|
|
35
|
+
* {
|
|
36
|
+
* async acquireMigrationLock(db, options): Promise<void> {
|
|
37
|
+
* const queryDb = options.lockTableSchema
|
|
38
|
+
* ? db.withSchema(options.lockTableSchema)
|
|
39
|
+
* : db
|
|
40
|
+
*
|
|
41
|
+
* // Since our imaginary dialect supports transactional DDL and has
|
|
42
|
+
* // row locks, we can simply take a row lock here and it will guarantee
|
|
43
|
+
* // all subsequent calls to this method from other transactions will
|
|
44
|
+
* // wait until this transaction finishes.
|
|
45
|
+
* await queryDb
|
|
46
|
+
* .selectFrom(options.lockTable)
|
|
47
|
+
* .selectAll()
|
|
48
|
+
* .where('id', '=', options.lockRowId)
|
|
49
|
+
* .forUpdate()
|
|
50
|
+
* .execute()
|
|
51
|
+
* }
|
|
52
|
+
* }
|
|
53
|
+
* ```
|
|
28
54
|
*
|
|
29
55
|
* If `supportsTransactionalDdl` is `true` then the `db` passed to this method
|
|
30
56
|
* is a transaction inside which the migrations will be executed. Otherwise
|
|
@@ -11,7 +11,7 @@ export class MysqlIntrospector {
|
|
|
11
11
|
let rawSchemas = await this.#db
|
|
12
12
|
.selectFrom('information_schema.schemata')
|
|
13
13
|
.select('schema_name')
|
|
14
|
-
|
|
14
|
+
.$castTo()
|
|
15
15
|
.execute();
|
|
16
16
|
return rawSchemas.map((it) => ({ name: it.SCHEMA_NAME }));
|
|
17
17
|
}
|
|
@@ -29,8 +29,8 @@ export class MysqlIntrospector {
|
|
|
29
29
|
])
|
|
30
30
|
.where('table_schema', '=', sql `database()`)
|
|
31
31
|
.orderBy('table_name')
|
|
32
|
-
.orderBy('
|
|
33
|
-
|
|
32
|
+
.orderBy('ordinal_position')
|
|
33
|
+
.$castTo();
|
|
34
34
|
if (!options.withInternalKyselyTables) {
|
|
35
35
|
query = query
|
|
36
36
|
.where('table_name', '!=', DEFAULT_MIGRATION_TABLE)
|
|
@@ -19,12 +19,38 @@ export declare class PostgresAdapter extends DialectAdapterBase {
|
|
|
19
19
|
* Most dialects have explicit locks that can be used, like advisory locks
|
|
20
20
|
* in PostgreSQL and the get_lock function in MySQL.
|
|
21
21
|
*
|
|
22
|
-
* If the dialect doesn't have explicit locks the {@link
|
|
23
|
-
* created by Kysely can be used instead.
|
|
24
|
-
* has two columns `id` and `is_locked` and there's only one row in the
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
22
|
+
* If the dialect doesn't have explicit locks the {@link MigrationLockOptions.lockTable}
|
|
23
|
+
* created by Kysely can be used instead. You can access it through the `options` object.
|
|
24
|
+
* The lock table has two columns `id` and `is_locked` and there's only one row in the table
|
|
25
|
+
* whose id is {@link MigrationLockOptions.lockRowId}. `is_locked` is an integer. Kysely
|
|
26
|
+
* takes care of creating the lock table and inserting the one single row to it before this
|
|
27
|
+
* method is executed. If the dialect supports schemas and the user has specified a custom
|
|
28
|
+
* schema in their migration settings, the options object also contains the schema name in
|
|
29
|
+
* {@link MigrationLockOptions.lockTableSchema}.
|
|
30
|
+
*
|
|
31
|
+
* Here's an example of how you might implement this method for a dialect that doesn't
|
|
32
|
+
* have explicit locks but supports `FOR UPDATE` row locks and transactional DDL:
|
|
33
|
+
*
|
|
34
|
+
* ```ts
|
|
35
|
+
* {
|
|
36
|
+
* async acquireMigrationLock(db, options): Promise<void> {
|
|
37
|
+
* const queryDb = options.lockTableSchema
|
|
38
|
+
* ? db.withSchema(options.lockTableSchema)
|
|
39
|
+
* : db
|
|
40
|
+
*
|
|
41
|
+
* // Since our imaginary dialect supports transactional DDL and has
|
|
42
|
+
* // row locks, we can simply take a row lock here and it will guarantee
|
|
43
|
+
* // all subsequent calls to this method from other transactions will
|
|
44
|
+
* // wait until this transaction finishes.
|
|
45
|
+
* await queryDb
|
|
46
|
+
* .selectFrom(options.lockTable)
|
|
47
|
+
* .selectAll()
|
|
48
|
+
* .where('id', '=', options.lockRowId)
|
|
49
|
+
* .forUpdate()
|
|
50
|
+
* .execute()
|
|
51
|
+
* }
|
|
52
|
+
* }
|
|
53
|
+
* ```
|
|
28
54
|
*
|
|
29
55
|
* If `supportsTransactionalDdl` is `true` then the `db` passed to this method
|
|
30
56
|
* is a transaction inside which the migrations will be executed. Otherwise
|
|
@@ -11,7 +11,7 @@ export class PostgresIntrospector {
|
|
|
11
11
|
let rawSchemas = await this.#db
|
|
12
12
|
.selectFrom('pg_catalog.pg_namespace')
|
|
13
13
|
.select('nspname')
|
|
14
|
-
|
|
14
|
+
.$castTo()
|
|
15
15
|
.execute();
|
|
16
16
|
return rawSchemas.map((it) => ({ name: it.nspname }));
|
|
17
17
|
}
|
|
@@ -55,8 +55,8 @@ export class PostgresIntrospector {
|
|
|
55
55
|
.where('a.attisdropped', '!=', true)
|
|
56
56
|
.orderBy('ns.nspname')
|
|
57
57
|
.orderBy('c.relname')
|
|
58
|
-
.orderBy('a.
|
|
59
|
-
|
|
58
|
+
.orderBy('a.attnum')
|
|
59
|
+
.$castTo();
|
|
60
60
|
if (!options.withInternalKyselyTables) {
|
|
61
61
|
query = query
|
|
62
62
|
.where('c.relname', '!=', DEFAULT_MIGRATION_TABLE)
|
|
@@ -18,12 +18,38 @@ export declare class SqliteAdapter implements DialectAdapterBase {
|
|
|
18
18
|
* Most dialects have explicit locks that can be used, like advisory locks
|
|
19
19
|
* in PostgreSQL and the get_lock function in MySQL.
|
|
20
20
|
*
|
|
21
|
-
* If the dialect doesn't have explicit locks the {@link
|
|
22
|
-
* created by Kysely can be used instead.
|
|
23
|
-
* has two columns `id` and `is_locked` and there's only one row in the
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
21
|
+
* If the dialect doesn't have explicit locks the {@link MigrationLockOptions.lockTable}
|
|
22
|
+
* created by Kysely can be used instead. You can access it through the `options` object.
|
|
23
|
+
* The lock table has two columns `id` and `is_locked` and there's only one row in the table
|
|
24
|
+
* whose id is {@link MigrationLockOptions.lockRowId}. `is_locked` is an integer. Kysely
|
|
25
|
+
* takes care of creating the lock table and inserting the one single row to it before this
|
|
26
|
+
* method is executed. If the dialect supports schemas and the user has specified a custom
|
|
27
|
+
* schema in their migration settings, the options object also contains the schema name in
|
|
28
|
+
* {@link MigrationLockOptions.lockTableSchema}.
|
|
29
|
+
*
|
|
30
|
+
* Here's an example of how you might implement this method for a dialect that doesn't
|
|
31
|
+
* have explicit locks but supports `FOR UPDATE` row locks and transactional DDL:
|
|
32
|
+
*
|
|
33
|
+
* ```ts
|
|
34
|
+
* {
|
|
35
|
+
* async acquireMigrationLock(db, options): Promise<void> {
|
|
36
|
+
* const queryDb = options.lockTableSchema
|
|
37
|
+
* ? db.withSchema(options.lockTableSchema)
|
|
38
|
+
* : db
|
|
39
|
+
*
|
|
40
|
+
* // Since our imaginary dialect supports transactional DDL and has
|
|
41
|
+
* // row locks, we can simply take a row lock here and it will guarantee
|
|
42
|
+
* // all subsequent calls to this method from other transactions will
|
|
43
|
+
* // wait until this transaction finishes.
|
|
44
|
+
* await queryDb
|
|
45
|
+
* .selectFrom(options.lockTable)
|
|
46
|
+
* .selectAll()
|
|
47
|
+
* .where('id', '=', options.lockRowId)
|
|
48
|
+
* .forUpdate()
|
|
49
|
+
* .execute()
|
|
50
|
+
* }
|
|
51
|
+
* }
|
|
52
|
+
* ```
|
|
27
53
|
*
|
|
28
54
|
* If `supportsTransactionalDdl` is `true` then the `db` passed to this method
|
|
29
55
|
* is a transaction inside which the migrations will be executed. Otherwise
|
|
@@ -17,7 +17,7 @@ export class SqliteIntrospector {
|
|
|
17
17
|
.where('name', 'not like', 'sqlite_%')
|
|
18
18
|
.select('name')
|
|
19
19
|
.orderBy('name')
|
|
20
|
-
|
|
20
|
+
.$castTo();
|
|
21
21
|
if (!options.withInternalKyselyTables) {
|
|
22
22
|
query = query
|
|
23
23
|
.where('name', '!=', DEFAULT_MIGRATION_TABLE)
|
|
@@ -38,7 +38,7 @@ export class SqliteIntrospector {
|
|
|
38
38
|
.selectFrom('sqlite_master')
|
|
39
39
|
.where('name', '=', table)
|
|
40
40
|
.select('sql')
|
|
41
|
-
|
|
41
|
+
.$castTo()
|
|
42
42
|
.execute();
|
|
43
43
|
// Try to find the name of the column that has `autoincrement` 🤦
|
|
44
44
|
const autoIncrementCol = createSql[0]?.sql
|
|
@@ -50,7 +50,7 @@ export class SqliteIntrospector {
|
|
|
50
50
|
const columns = await db
|
|
51
51
|
.selectFrom(sql `pragma_table_info(${table})`.as('table_info'))
|
|
52
52
|
.select(['name', 'type', 'notnull', 'dflt_value'])
|
|
53
|
-
.orderBy('
|
|
53
|
+
.orderBy('cid')
|
|
54
54
|
.execute();
|
|
55
55
|
return {
|
|
56
56
|
name: table,
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -159,6 +159,7 @@ export * from './operation-node/partition-by-item-node.js';
|
|
|
159
159
|
export * from './operation-node/set-operation-node.js';
|
|
160
160
|
export * from './operation-node/binary-operation-node.js';
|
|
161
161
|
export * from './operation-node/unary-operation-node.js';
|
|
162
|
+
export * from './operation-node/using-node.js';
|
|
162
163
|
export * from './util/column-type.js';
|
|
163
164
|
export * from './util/compilable.js';
|
|
164
165
|
export * from './util/explainable.js';
|
|
@@ -172,7 +173,7 @@ export { ValueExpression, ValueExpressionOrList, } from './parser/value-parser.j
|
|
|
172
173
|
export { TableExpression, TableExpressionOrList, } from './parser/table-parser.js';
|
|
173
174
|
export { JoinReferenceExpression, JoinCallbackExpression, } from './parser/join-parser.js';
|
|
174
175
|
export { InsertObject } from './parser/insert-values-parser.js';
|
|
175
|
-
export {
|
|
176
|
+
export { UpdateObject } from './parser/update-set-parser.js';
|
|
176
177
|
export { OrderByExpression, OrderByDirectionExpression, } from './parser/order-by-parser.js';
|
|
177
178
|
export { ComparisonOperatorExpression, OperandValueExpression, OperandValueExpressionOrList, } from './parser/binary-operation-parser.js';
|
|
178
179
|
export { ExistsExpression } from './parser/unary-operation-parser.js';
|
package/dist/esm/index.js
CHANGED
|
@@ -160,6 +160,7 @@ export * from './operation-node/partition-by-item-node.js';
|
|
|
160
160
|
export * from './operation-node/set-operation-node.js';
|
|
161
161
|
export * from './operation-node/binary-operation-node.js';
|
|
162
162
|
export * from './operation-node/unary-operation-node.js';
|
|
163
|
+
export * from './operation-node/using-node.js';
|
|
163
164
|
export * from './util/column-type.js';
|
|
164
165
|
export * from './util/compilable.js';
|
|
165
166
|
export * from './util/explainable.js';
|
|
@@ -24,12 +24,17 @@ export interface Migration {
|
|
|
24
24
|
* other way.
|
|
25
25
|
*
|
|
26
26
|
* ```ts
|
|
27
|
+
* import { promises as fs } from 'fs'
|
|
28
|
+
* import path from 'path'
|
|
29
|
+
*
|
|
27
30
|
* const migrator = new Migrator({
|
|
28
31
|
* db,
|
|
29
|
-
* provider: new FileMigrationProvider(
|
|
32
|
+
* provider: new FileMigrationProvider({
|
|
33
|
+
* fs,
|
|
34
|
+
* path,
|
|
30
35
|
* // Path to the folder that contains all your migrations.
|
|
31
|
-
* 'some/path/to/migrations'
|
|
32
|
-
* )
|
|
36
|
+
* migrationFolder: 'some/path/to/migrations'
|
|
37
|
+
* })
|
|
33
38
|
* })
|
|
34
39
|
* ```
|
|
35
40
|
*/
|
|
@@ -17,12 +17,17 @@ export const NO_MIGRATIONS = freeze({ __noMigrations__: true });
|
|
|
17
17
|
* other way.
|
|
18
18
|
*
|
|
19
19
|
* ```ts
|
|
20
|
+
* import { promises as fs } from 'fs'
|
|
21
|
+
* import path from 'path'
|
|
22
|
+
*
|
|
20
23
|
* const migrator = new Migrator({
|
|
21
24
|
* db,
|
|
22
|
-
* provider: new FileMigrationProvider(
|
|
25
|
+
* provider: new FileMigrationProvider({
|
|
26
|
+
* fs,
|
|
27
|
+
* path,
|
|
23
28
|
* // Path to the folder that contains all your migrations.
|
|
24
|
-
* 'some/path/to/migrations'
|
|
25
|
-
* )
|
|
29
|
+
* migrationFolder: 'some/path/to/migrations'
|
|
30
|
+
* })
|
|
26
31
|
* })
|
|
27
32
|
* ```
|
|
28
33
|
*/
|
|
@@ -316,9 +321,14 @@ export class Migrator {
|
|
|
316
321
|
}
|
|
317
322
|
async #runMigrations(getTargetMigrationIndex) {
|
|
318
323
|
const adapter = this.#props.db.getExecutor().adapter;
|
|
324
|
+
const lockOptions = freeze({
|
|
325
|
+
lockTable: this.#props.migrationLockTableName ?? DEFAULT_MIGRATION_LOCK_TABLE,
|
|
326
|
+
lockRowId: MIGRATION_LOCK_ID,
|
|
327
|
+
lockTableSchema: this.#props.migrationTableSchema,
|
|
328
|
+
});
|
|
319
329
|
const run = async (db) => {
|
|
320
330
|
try {
|
|
321
|
-
await adapter.acquireMigrationLock(db);
|
|
331
|
+
await adapter.acquireMigrationLock(db, lockOptions);
|
|
322
332
|
const state = await this.#getState(db);
|
|
323
333
|
if (state.migrations.length === 0) {
|
|
324
334
|
return { results: [] };
|
|
@@ -336,7 +346,7 @@ export class Migrator {
|
|
|
336
346
|
return { results: [] };
|
|
337
347
|
}
|
|
338
348
|
finally {
|
|
339
|
-
await adapter.releaseMigrationLock(db);
|
|
349
|
+
await adapter.releaseMigrationLock(db, lockOptions);
|
|
340
350
|
}
|
|
341
351
|
};
|
|
342
352
|
if (adapter.supportsTransactionalDdl) {
|
|
@@ -8,9 +8,11 @@ import { LimitNode } from './limit-node.js';
|
|
|
8
8
|
import { OrderByNode } from './order-by-node.js';
|
|
9
9
|
import { OrderByItemNode } from './order-by-item-node.js';
|
|
10
10
|
import { ExplainNode } from './explain-node.js';
|
|
11
|
+
import { UsingNode } from './using-node.js';
|
|
11
12
|
export interface DeleteQueryNode extends OperationNode {
|
|
12
13
|
readonly kind: 'DeleteQueryNode';
|
|
13
14
|
readonly from: FromNode;
|
|
15
|
+
readonly using?: UsingNode;
|
|
14
16
|
readonly joins?: ReadonlyArray<JoinNode>;
|
|
15
17
|
readonly where?: WhereNode;
|
|
16
18
|
readonly returning?: ReturningNode;
|
|
@@ -28,4 +30,5 @@ export declare const DeleteQueryNode: Readonly<{
|
|
|
28
30
|
cloneWithOrderByItem(deleteNode: DeleteQueryNode, item: OrderByItemNode): DeleteQueryNode;
|
|
29
31
|
cloneWithLimit(deleteNode: DeleteQueryNode, limit: LimitNode): DeleteQueryNode;
|
|
30
32
|
cloneWithExplain(deleteNode: DeleteQueryNode, explain: ExplainNode): DeleteQueryNode;
|
|
33
|
+
cloneWithUsing(deleteNode: DeleteQueryNode, tables: OperationNode[]): DeleteQueryNode;
|
|
31
34
|
}>;
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { freeze } from '../util/object-utils.js';
|
|
3
3
|
import { FromNode } from './from-node.js';
|
|
4
4
|
import { OrderByNode } from './order-by-node.js';
|
|
5
|
+
import { UsingNode } from './using-node.js';
|
|
5
6
|
/**
|
|
6
7
|
* @internal
|
|
7
8
|
*/
|
|
@@ -36,4 +37,12 @@ export const DeleteQueryNode = freeze({
|
|
|
36
37
|
explain,
|
|
37
38
|
});
|
|
38
39
|
},
|
|
40
|
+
cloneWithUsing(deleteNode, tables) {
|
|
41
|
+
return freeze({
|
|
42
|
+
...deleteNode,
|
|
43
|
+
using: deleteNode.using !== undefined
|
|
44
|
+
? UsingNode.cloneWithTables(deleteNode.using, tables)
|
|
45
|
+
: UsingNode.create(tables),
|
|
46
|
+
});
|
|
47
|
+
},
|
|
39
48
|
});
|
|
@@ -76,6 +76,7 @@ import { PartitionByItemNode } from './partition-by-item-node.js';
|
|
|
76
76
|
import { SetOperationNode } from './set-operation-node.js';
|
|
77
77
|
import { BinaryOperationNode } from './binary-operation-node.js';
|
|
78
78
|
import { UnaryOperationNode } from './unary-operation-node.js';
|
|
79
|
+
import { UsingNode } from './using-node.js';
|
|
79
80
|
/**
|
|
80
81
|
* Transforms an operation node tree into another one.
|
|
81
82
|
*
|
|
@@ -181,6 +182,7 @@ export declare class OperationNodeTransformer {
|
|
|
181
182
|
protected transformPartitionByItem(node: PartitionByItemNode): PartitionByItemNode;
|
|
182
183
|
protected transformBinaryOperation(node: BinaryOperationNode): BinaryOperationNode;
|
|
183
184
|
protected transformUnaryOperation(node: UnaryOperationNode): UnaryOperationNode;
|
|
185
|
+
protected transformUsing(node: UsingNode): UsingNode;
|
|
184
186
|
protected transformDataType(node: DataTypeNode): DataTypeNode;
|
|
185
187
|
protected transformSelectAll(node: SelectAllNode): SelectAllNode;
|
|
186
188
|
protected transformIdentifier(node: IdentifierNode): IdentifierNode;
|
|
@@ -110,6 +110,7 @@ export class OperationNodeTransformer {
|
|
|
110
110
|
SetOperationNode: this.transformSetOperation.bind(this),
|
|
111
111
|
BinaryOperationNode: this.transformBinaryOperation.bind(this),
|
|
112
112
|
UnaryOperationNode: this.transformUnaryOperation.bind(this),
|
|
113
|
+
UsingNode: this.transformUsing.bind(this),
|
|
113
114
|
});
|
|
114
115
|
transformNode(node) {
|
|
115
116
|
if (!node) {
|
|
@@ -259,6 +260,7 @@ export class OperationNodeTransformer {
|
|
|
259
260
|
return requireAllProps({
|
|
260
261
|
kind: 'DeleteQueryNode',
|
|
261
262
|
from: this.transformNode(node.from),
|
|
263
|
+
using: this.transformNode(node.using),
|
|
262
264
|
joins: this.transformNodeList(node.joins),
|
|
263
265
|
where: this.transformNode(node.where),
|
|
264
266
|
returning: this.transformNode(node.returning),
|
|
@@ -402,6 +404,7 @@ export class OperationNodeTransformer {
|
|
|
402
404
|
expression: this.transformNode(node.expression),
|
|
403
405
|
unique: node.unique,
|
|
404
406
|
using: this.transformNode(node.using),
|
|
407
|
+
ifNotExists: node.ifNotExists,
|
|
405
408
|
});
|
|
406
409
|
}
|
|
407
410
|
transformList(node) {
|
|
@@ -687,6 +690,12 @@ export class OperationNodeTransformer {
|
|
|
687
690
|
operand: this.transformNode(node.operand),
|
|
688
691
|
});
|
|
689
692
|
}
|
|
693
|
+
transformUsing(node) {
|
|
694
|
+
return requireAllProps({
|
|
695
|
+
kind: 'UsingNode',
|
|
696
|
+
tables: node.tables,
|
|
697
|
+
});
|
|
698
|
+
}
|
|
690
699
|
transformDataType(node) {
|
|
691
700
|
// An Object.freezed leaf node. No need to clone.
|
|
692
701
|
return node;
|
|
@@ -76,6 +76,7 @@ import { PartitionByItemNode } from './partition-by-item-node.js';
|
|
|
76
76
|
import { SetOperationNode } from './set-operation-node.js';
|
|
77
77
|
import { BinaryOperationNode } from './binary-operation-node.js';
|
|
78
78
|
import { UnaryOperationNode } from './unary-operation-node.js';
|
|
79
|
+
import { UsingNode } from './using-node.js';
|
|
79
80
|
export declare abstract class OperationNodeVisitor {
|
|
80
81
|
#private;
|
|
81
82
|
protected readonly nodeStack: OperationNode[];
|
|
@@ -158,4 +159,5 @@ export declare abstract class OperationNodeVisitor {
|
|
|
158
159
|
protected abstract visitSetOperation(node: SetOperationNode): void;
|
|
159
160
|
protected abstract visitBinaryOperation(node: BinaryOperationNode): void;
|
|
160
161
|
protected abstract visitUnaryOperation(node: UnaryOperationNode): void;
|
|
162
|
+
protected abstract visitUsing(node: UsingNode): void;
|
|
161
163
|
}
|
|
@@ -83,6 +83,7 @@ export class OperationNodeVisitor {
|
|
|
83
83
|
SetOperationNode: this.visitSetOperation.bind(this),
|
|
84
84
|
BinaryOperationNode: this.visitBinaryOperation.bind(this),
|
|
85
85
|
UnaryOperationNode: this.visitUnaryOperation.bind(this),
|
|
86
|
+
UsingNode: this.visitUsing.bind(this),
|
|
86
87
|
});
|
|
87
88
|
visitNode = (node) => {
|
|
88
89
|
this.nodeStack.push(node);
|