kysely 0.23.3 → 0.23.5
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 +25 -25
- package/dist/cjs/dialect/database-introspector.d.ts +4 -2
- 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.d.ts +1 -1
- package/dist/cjs/dialect/mysql/mysql-introspector.js +21 -15
- package/dist/cjs/dialect/postgres/postgres-adapter.d.ts +32 -6
- package/dist/cjs/dialect/postgres/postgres-introspector.d.ts +1 -1
- package/dist/cjs/dialect/postgres/postgres-introspector.js +5 -3
- package/dist/cjs/dialect/sqlite/sqlite-adapter.d.ts +32 -6
- package/dist/cjs/dialect/sqlite/sqlite-introspector.d.ts +1 -1
- package/dist/cjs/dialect/sqlite/sqlite-introspector.js +8 -7
- package/dist/cjs/index.d.ts +1 -0
- 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/aggregate-function-node.d.ts +3 -2
- package/dist/cjs/operation-node/aggregate-function-node.js +2 -2
- package/dist/cjs/operation-node/create-index-node.d.ts +1 -0
- package/dist/cjs/operation-node/delete-query-node.d.ts +4 -1
- package/dist/cjs/operation-node/delete-query-node.js +11 -2
- package/dist/cjs/operation-node/operation-node-transformer.d.ts +2 -0
- package/dist/cjs/operation-node/operation-node-transformer.js +10 -1
- 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/expression-parser.js +1 -1
- package/dist/cjs/parser/table-parser.d.ts +1 -0
- package/dist/cjs/parser/update-set-parser.d.ts +1 -1
- package/dist/cjs/plugin/camel-case/camel-case-plugin.d.ts +7 -0
- package/dist/cjs/plugin/camel-case/camel-case-plugin.js +10 -4
- package/dist/cjs/query-builder/delete-query-builder.d.ts +103 -11
- package/dist/cjs/query-builder/delete-query-builder.js +40 -9
- package/dist/cjs/query-builder/function-module.d.ts +273 -39
- package/dist/cjs/query-builder/function-module.js +156 -34
- package/dist/cjs/query-builder/insert-query-builder.d.ts +25 -10
- package/dist/cjs/query-builder/insert-query-builder.js +32 -9
- package/dist/cjs/query-builder/select-query-builder.d.ts +51 -34
- package/dist/cjs/query-builder/select-query-builder.js +53 -29
- package/dist/cjs/query-builder/update-query-builder.d.ts +26 -10
- package/dist/cjs/query-builder/update-query-builder.js +33 -9
- package/dist/cjs/query-compiler/default-query-compiler.d.ts +2 -0
- package/dist/cjs/query-compiler/default-query-compiler.js +12 -1
- package/dist/cjs/query-creator.d.ts +29 -0
- package/dist/cjs/query-creator.js +2 -21
- 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 +20 -1
- package/dist/esm/dialect/database-introspector.d.ts +4 -2
- 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.d.ts +1 -1
- package/dist/esm/dialect/mysql/mysql-introspector.js +21 -15
- package/dist/esm/dialect/postgres/postgres-adapter.d.ts +32 -6
- package/dist/esm/dialect/postgres/postgres-introspector.d.ts +1 -1
- package/dist/esm/dialect/postgres/postgres-introspector.js +5 -3
- package/dist/esm/dialect/sqlite/sqlite-adapter.d.ts +32 -6
- package/dist/esm/dialect/sqlite/sqlite-introspector.d.ts +1 -1
- package/dist/esm/dialect/sqlite/sqlite-introspector.js +8 -7
- package/dist/esm/index.d.ts +1 -0
- 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/aggregate-function-node.d.ts +3 -2
- package/dist/esm/operation-node/aggregate-function-node.js +2 -2
- package/dist/esm/operation-node/create-index-node.d.ts +1 -0
- package/dist/esm/operation-node/delete-query-node.d.ts +4 -1
- package/dist/esm/operation-node/delete-query-node.js +11 -2
- package/dist/esm/operation-node/operation-node-transformer.d.ts +2 -0
- package/dist/esm/operation-node/operation-node-transformer.js +10 -1
- 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/expression-parser.js +2 -2
- package/dist/esm/parser/table-parser.d.ts +1 -0
- package/dist/esm/parser/update-set-parser.d.ts +1 -1
- package/dist/esm/plugin/camel-case/camel-case-plugin.d.ts +7 -0
- package/dist/esm/plugin/camel-case/camel-case-plugin.js +10 -4
- package/dist/esm/query-builder/delete-query-builder.d.ts +103 -11
- package/dist/esm/query-builder/delete-query-builder.js +40 -9
- package/dist/esm/query-builder/function-module.d.ts +273 -39
- package/dist/esm/query-builder/function-module.js +156 -34
- package/dist/esm/query-builder/insert-query-builder.d.ts +25 -10
- package/dist/esm/query-builder/insert-query-builder.js +33 -10
- package/dist/esm/query-builder/select-query-builder.d.ts +51 -34
- package/dist/esm/query-builder/select-query-builder.js +53 -29
- package/dist/esm/query-builder/update-query-builder.d.ts +26 -10
- 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 +12 -1
- package/dist/esm/query-creator.d.ts +29 -0
- package/dist/esm/query-creator.js +2 -21
- 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 +20 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -78,6 +78,8 @@ for [3rd party dialects](https://koskimas.github.io/kysely/interfaces/Dialect.ht
|
|
|
78
78
|
- [SingleStore Data API](https://github.com/igalklebanov/kysely-singlestore)
|
|
79
79
|
- [D1](https://github.com/aidenwallis/kysely-d1)
|
|
80
80
|
- [SurrealDB](https://github.com/igalklebanov/kysely-surrealdb)
|
|
81
|
+
- [sqld](https://github.com/libsql/kysely-libsql)
|
|
82
|
+
- [Neon](https://github.com/seveibar/kysely-neon)
|
|
81
83
|
|
|
82
84
|
# Minimal example
|
|
83
85
|
|
|
@@ -183,7 +185,7 @@ type UpdateablePerson = Updateable<PersonTable>
|
|
|
183
185
|
|
|
184
186
|
# Playground
|
|
185
187
|
|
|
186
|
-
[@wirekang](https://github.com/wirekang) has created a [playground for Kysely](https://wirekang.github.io/kysely-playground
|
|
188
|
+
[@wirekang](https://github.com/wirekang) has created a [playground for Kysely](https://wirekang.github.io/kysely-playground/?p=f&i=-NLp3n_P5fyeQKMQda8n). You can use to quickly test stuff out and for creating code examples for your issues, PRs and discord messages.
|
|
187
189
|
|
|
188
190
|
# Generating types
|
|
189
191
|
|
|
@@ -207,37 +209,34 @@ among other places.
|
|
|
207
209
|
import { Pool } from 'pg'
|
|
208
210
|
// or `import * as Cursor from 'pg-cursor'` depending on your tsconfig
|
|
209
211
|
import Cursor from 'pg-cursor'
|
|
210
|
-
import {
|
|
211
|
-
Kysely,
|
|
212
|
-
PostgresDialect,
|
|
213
|
-
} from 'kysely'
|
|
212
|
+
import { Kysely, PostgresDialect } from 'kysely'
|
|
214
213
|
|
|
215
214
|
const db = new Kysely<Database>({
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
}),
|
|
222
|
-
cursor: Cursor
|
|
215
|
+
// PostgresDialect requires the Cursor dependency
|
|
216
|
+
dialect: new PostgresDialect({
|
|
217
|
+
pool: new Pool({
|
|
218
|
+
host: 'localhost',
|
|
219
|
+
database: 'kysely_test'
|
|
223
220
|
}),
|
|
224
|
-
|
|
225
|
-
|
|
221
|
+
cursor: Cursor
|
|
222
|
+
}),
|
|
223
|
+
// MysqlDialect doesn't require any special configuration
|
|
226
224
|
})
|
|
227
225
|
|
|
228
226
|
async function demo() {
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
227
|
+
for await (const adult of db.selectFrom('person')
|
|
228
|
+
.selectAll()
|
|
229
|
+
.where('age', '>', 18)
|
|
230
|
+
.stream()
|
|
231
|
+
) {
|
|
232
|
+
console.log(`Hello ${adult.first_name}!`)
|
|
233
|
+
|
|
234
|
+
if (adult.first_name === 'John') {
|
|
235
|
+
// After this line the db connection is released and no more
|
|
236
|
+
// rows are streamed from the database to the client
|
|
237
|
+
break;
|
|
240
238
|
}
|
|
239
|
+
}
|
|
241
240
|
}
|
|
242
241
|
```
|
|
243
242
|
|
|
@@ -268,6 +267,7 @@ or "recipes" for common use cases.
|
|
|
268
267
|
* [Extending kysely](https://github.com/koskimas/kysely/tree/master/recipes/extending-kysely.md)
|
|
269
268
|
* [Raw SQL](https://github.com/koskimas/kysely/tree/master/recipes/raw-sql.md)
|
|
270
269
|
* [Schemas](https://github.com/koskimas/kysely/tree/master/recipes/schemas.md)
|
|
270
|
+
* [Dealing with the `Type instantiation is excessively deep and possibly infinite` error](https://github.com/koskimas/kysely/tree/master/recipes/excessively-deep-types.md)
|
|
271
271
|
|
|
272
272
|
# Migrations
|
|
273
273
|
|
|
@@ -7,7 +7,7 @@ export interface DatabaseIntrospector {
|
|
|
7
7
|
*/
|
|
8
8
|
getSchemas(): Promise<SchemaMetadata[]>;
|
|
9
9
|
/**
|
|
10
|
-
* Get
|
|
10
|
+
* Get tables and views metadata.
|
|
11
11
|
*/
|
|
12
12
|
getTables(options?: DatabaseMetadataOptions): Promise<TableMetadata[]>;
|
|
13
13
|
/**
|
|
@@ -29,12 +29,14 @@ export interface SchemaMetadata {
|
|
|
29
29
|
}
|
|
30
30
|
export interface DatabaseMetadata {
|
|
31
31
|
/**
|
|
32
|
-
* The tables found in the database.
|
|
32
|
+
* The tables and views found in the database.
|
|
33
|
+
* * The propery isView can be used to tell them apart.
|
|
33
34
|
*/
|
|
34
35
|
readonly tables: TableMetadata[];
|
|
35
36
|
}
|
|
36
37
|
export interface TableMetadata {
|
|
37
38
|
readonly name: string;
|
|
39
|
+
readonly isView: boolean;
|
|
38
40
|
readonly columns: ColumnMetadata[];
|
|
39
41
|
readonly schema?: string;
|
|
40
42
|
}
|
|
@@ -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
|
|
@@ -8,7 +8,7 @@ export declare class MysqlIntrospector implements DatabaseIntrospector {
|
|
|
8
8
|
*/
|
|
9
9
|
getSchemas(): Promise<SchemaMetadata[]>;
|
|
10
10
|
/**
|
|
11
|
-
* Get
|
|
11
|
+
* Get tables and views metadata.
|
|
12
12
|
*/
|
|
13
13
|
getTables(options?: DatabaseMetadataOptions): Promise<TableMetadata[]>;
|
|
14
14
|
/**
|
|
@@ -13,30 +13,35 @@ class MysqlIntrospector {
|
|
|
13
13
|
let rawSchemas = await this.#db
|
|
14
14
|
.selectFrom('information_schema.schemata')
|
|
15
15
|
.select('schema_name')
|
|
16
|
-
|
|
16
|
+
.$castTo()
|
|
17
17
|
.execute();
|
|
18
18
|
return rawSchemas.map((it) => ({ name: it.SCHEMA_NAME }));
|
|
19
19
|
}
|
|
20
20
|
async getTables(options = { withInternalKyselyTables: false }) {
|
|
21
21
|
let query = this.#db
|
|
22
|
-
.selectFrom('information_schema.columns')
|
|
22
|
+
.selectFrom('information_schema.columns as columns')
|
|
23
|
+
.innerJoin('information_schema.tables as tables', (b) => b
|
|
24
|
+
.onRef('columns.TABLE_CATALOG', '=', 'tables.TABLE_CATALOG')
|
|
25
|
+
.onRef('columns.TABLE_SCHEMA', '=', 'tables.TABLE_SCHEMA')
|
|
26
|
+
.onRef('columns.TABLE_NAME', '=', 'tables.TABLE_NAME'))
|
|
23
27
|
.select([
|
|
24
|
-
'COLUMN_NAME',
|
|
25
|
-
'COLUMN_DEFAULT',
|
|
26
|
-
'TABLE_NAME',
|
|
27
|
-
'TABLE_SCHEMA',
|
|
28
|
-
'
|
|
29
|
-
'
|
|
30
|
-
'
|
|
28
|
+
'columns.COLUMN_NAME',
|
|
29
|
+
'columns.COLUMN_DEFAULT',
|
|
30
|
+
'columns.TABLE_NAME',
|
|
31
|
+
'columns.TABLE_SCHEMA',
|
|
32
|
+
'tables.TABLE_TYPE',
|
|
33
|
+
'columns.IS_NULLABLE',
|
|
34
|
+
'columns.DATA_TYPE',
|
|
35
|
+
'columns.EXTRA',
|
|
31
36
|
])
|
|
32
|
-
.where('
|
|
33
|
-
.orderBy('
|
|
34
|
-
.orderBy('
|
|
35
|
-
|
|
37
|
+
.where('columns.TABLE_SCHEMA', '=', (0, sql_js_1.sql) `database()`)
|
|
38
|
+
.orderBy('columns.TABLE_NAME')
|
|
39
|
+
.orderBy('columns.ORDINAL_POSITION')
|
|
40
|
+
.$castTo();
|
|
36
41
|
if (!options.withInternalKyselyTables) {
|
|
37
42
|
query = query
|
|
38
|
-
.where('
|
|
39
|
-
.where('
|
|
43
|
+
.where('columns.TABLE_NAME', '!=', migrator_js_1.DEFAULT_MIGRATION_TABLE)
|
|
44
|
+
.where('columns.TABLE_NAME', '!=', migrator_js_1.DEFAULT_MIGRATION_LOCK_TABLE);
|
|
40
45
|
}
|
|
41
46
|
const rawColumns = await query.execute();
|
|
42
47
|
return this.#parseTableMetadata(rawColumns);
|
|
@@ -52,6 +57,7 @@ class MysqlIntrospector {
|
|
|
52
57
|
if (!table) {
|
|
53
58
|
table = (0, object_utils_js_1.freeze)({
|
|
54
59
|
name: it.TABLE_NAME,
|
|
60
|
+
isView: it.TABLE_TYPE === 'VIEW',
|
|
55
61
|
schema: it.TABLE_SCHEMA,
|
|
56
62
|
columns: [],
|
|
57
63
|
});
|
|
@@ -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
|
|
@@ -8,7 +8,7 @@ export declare class PostgresIntrospector implements DatabaseIntrospector {
|
|
|
8
8
|
*/
|
|
9
9
|
getSchemas(): Promise<SchemaMetadata[]>;
|
|
10
10
|
/**
|
|
11
|
-
* Get
|
|
11
|
+
* Get tables and views metadata.
|
|
12
12
|
*/
|
|
13
13
|
getTables(options?: DatabaseMetadataOptions): Promise<TableMetadata[]>;
|
|
14
14
|
/**
|
|
@@ -13,7 +13,7 @@ class PostgresIntrospector {
|
|
|
13
13
|
let rawSchemas = await this.#db
|
|
14
14
|
.selectFrom('pg_catalog.pg_namespace')
|
|
15
15
|
.select('nspname')
|
|
16
|
-
|
|
16
|
+
.$castTo()
|
|
17
17
|
.execute();
|
|
18
18
|
return rawSchemas.map((it) => ({ name: it.nspname }));
|
|
19
19
|
}
|
|
@@ -34,6 +34,7 @@ class PostgresIntrospector {
|
|
|
34
34
|
'a.attnotnull as not_null',
|
|
35
35
|
'a.atthasdef as has_default',
|
|
36
36
|
'c.relname as table',
|
|
37
|
+
'c.relkind as table_type',
|
|
37
38
|
'ns.nspname as schema',
|
|
38
39
|
'typ.typname as type',
|
|
39
40
|
'dtns.nspname as type_schema',
|
|
@@ -49,7 +50,7 @@ class PostgresIntrospector {
|
|
|
49
50
|
.as('auto_incrementing'),
|
|
50
51
|
])
|
|
51
52
|
// r == normal table
|
|
52
|
-
.where('c.relkind', '
|
|
53
|
+
.where('c.relkind', 'in', ['r', 'v'])
|
|
53
54
|
.where('ns.nspname', '!~', '^pg_')
|
|
54
55
|
.where('ns.nspname', '!=', 'information_schema')
|
|
55
56
|
// No system columns
|
|
@@ -58,7 +59,7 @@ class PostgresIntrospector {
|
|
|
58
59
|
.orderBy('ns.nspname')
|
|
59
60
|
.orderBy('c.relname')
|
|
60
61
|
.orderBy('a.attnum')
|
|
61
|
-
|
|
62
|
+
.$castTo();
|
|
62
63
|
if (!options.withInternalKyselyTables) {
|
|
63
64
|
query = query
|
|
64
65
|
.where('c.relname', '!=', migrator_js_1.DEFAULT_MIGRATION_TABLE)
|
|
@@ -78,6 +79,7 @@ class PostgresIntrospector {
|
|
|
78
79
|
if (!table) {
|
|
79
80
|
table = (0, object_utils_js_1.freeze)({
|
|
80
81
|
name: it.table,
|
|
82
|
+
isView: it.table_type === 'v',
|
|
81
83
|
schema: it.schema,
|
|
82
84
|
columns: [],
|
|
83
85
|
});
|
|
@@ -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
|
|
@@ -8,7 +8,7 @@ export declare class SqliteIntrospector implements DatabaseIntrospector {
|
|
|
8
8
|
*/
|
|
9
9
|
getSchemas(): Promise<SchemaMetadata[]>;
|
|
10
10
|
/**
|
|
11
|
-
* Get
|
|
11
|
+
* Get tables and views metadata.
|
|
12
12
|
*/
|
|
13
13
|
getTables(options?: DatabaseMetadataOptions): Promise<TableMetadata[]>;
|
|
14
14
|
/**
|
|
@@ -15,11 +15,11 @@ class SqliteIntrospector {
|
|
|
15
15
|
async getTables(options = { withInternalKyselyTables: false }) {
|
|
16
16
|
let query = this.#db
|
|
17
17
|
.selectFrom('sqlite_schema')
|
|
18
|
-
.where('type', '
|
|
18
|
+
.where('type', 'in', ['table', 'view'])
|
|
19
19
|
.where('name', 'not like', 'sqlite_%')
|
|
20
20
|
.select('name')
|
|
21
21
|
.orderBy('name')
|
|
22
|
-
|
|
22
|
+
.$castTo();
|
|
23
23
|
if (!options.withInternalKyselyTables) {
|
|
24
24
|
query = query
|
|
25
25
|
.where('name', '!=', migrator_js_1.DEFAULT_MIGRATION_TABLE)
|
|
@@ -36,14 +36,14 @@ class SqliteIntrospector {
|
|
|
36
36
|
async #getTableMetadata(table) {
|
|
37
37
|
const db = this.#db;
|
|
38
38
|
// Get the SQL that was used to create the table.
|
|
39
|
-
const
|
|
39
|
+
const tableDefinition = await db
|
|
40
40
|
.selectFrom('sqlite_master')
|
|
41
41
|
.where('name', '=', table)
|
|
42
|
-
.select('sql')
|
|
43
|
-
|
|
44
|
-
.
|
|
42
|
+
.select(['sql', 'type'])
|
|
43
|
+
.$castTo()
|
|
44
|
+
.executeTakeFirstOrThrow();
|
|
45
45
|
// Try to find the name of the column that has `autoincrement` 🤦
|
|
46
|
-
const autoIncrementCol =
|
|
46
|
+
const autoIncrementCol = tableDefinition.sql
|
|
47
47
|
?.split(/[\(\),]/)
|
|
48
48
|
?.find((it) => it.toLowerCase().includes('autoincrement'))
|
|
49
49
|
?.trimStart()
|
|
@@ -56,6 +56,7 @@ class SqliteIntrospector {
|
|
|
56
56
|
.execute();
|
|
57
57
|
return {
|
|
58
58
|
name: table,
|
|
59
|
+
isView: tableDefinition.type === 'view',
|
|
59
60
|
columns: columns.map((col) => ({
|
|
60
61
|
name: col.name,
|
|
61
62
|
dataType: col.type,
|
package/dist/cjs/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';
|
package/dist/cjs/index.js
CHANGED
|
@@ -176,6 +176,7 @@ __exportStar(require("./operation-node/partition-by-item-node.js"), exports);
|
|
|
176
176
|
__exportStar(require("./operation-node/set-operation-node.js"), exports);
|
|
177
177
|
__exportStar(require("./operation-node/binary-operation-node.js"), exports);
|
|
178
178
|
__exportStar(require("./operation-node/unary-operation-node.js"), exports);
|
|
179
|
+
__exportStar(require("./operation-node/using-node.js"), exports);
|
|
179
180
|
__exportStar(require("./util/column-type.js"), exports);
|
|
180
181
|
__exportStar(require("./util/compilable.js"), exports);
|
|
181
182
|
__exportStar(require("./util/explainable.js"), exports);
|
|
@@ -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
|
*/
|
|
@@ -19,12 +19,17 @@ exports.NO_MIGRATIONS = (0, object_utils_js_1.freeze)({ __noMigrations__: true }
|
|
|
19
19
|
* other way.
|
|
20
20
|
*
|
|
21
21
|
* ```ts
|
|
22
|
+
* import { promises as fs } from 'fs'
|
|
23
|
+
* import path from 'path'
|
|
24
|
+
*
|
|
22
25
|
* const migrator = new Migrator({
|
|
23
26
|
* db,
|
|
24
|
-
* provider: new FileMigrationProvider(
|
|
27
|
+
* provider: new FileMigrationProvider({
|
|
28
|
+
* fs,
|
|
29
|
+
* path,
|
|
25
30
|
* // Path to the folder that contains all your migrations.
|
|
26
|
-
* 'some/path/to/migrations'
|
|
27
|
-
* )
|
|
31
|
+
* migrationFolder: 'some/path/to/migrations'
|
|
32
|
+
* })
|
|
28
33
|
* })
|
|
29
34
|
* ```
|
|
30
35
|
*/
|
|
@@ -318,9 +323,14 @@ class Migrator {
|
|
|
318
323
|
}
|
|
319
324
|
async #runMigrations(getTargetMigrationIndex) {
|
|
320
325
|
const adapter = this.#props.db.getExecutor().adapter;
|
|
326
|
+
const lockOptions = (0, object_utils_js_1.freeze)({
|
|
327
|
+
lockTable: this.#props.migrationLockTableName ?? exports.DEFAULT_MIGRATION_LOCK_TABLE,
|
|
328
|
+
lockRowId: exports.MIGRATION_LOCK_ID,
|
|
329
|
+
lockTableSchema: this.#props.migrationTableSchema,
|
|
330
|
+
});
|
|
321
331
|
const run = async (db) => {
|
|
322
332
|
try {
|
|
323
|
-
await adapter.acquireMigrationLock(db);
|
|
333
|
+
await adapter.acquireMigrationLock(db, lockOptions);
|
|
324
334
|
const state = await this.#getState(db);
|
|
325
335
|
if (state.migrations.length === 0) {
|
|
326
336
|
return { results: [] };
|
|
@@ -338,7 +348,7 @@ class Migrator {
|
|
|
338
348
|
return { results: [] };
|
|
339
349
|
}
|
|
340
350
|
finally {
|
|
341
|
-
await adapter.releaseMigrationLock(db);
|
|
351
|
+
await adapter.releaseMigrationLock(db, lockOptions);
|
|
342
352
|
}
|
|
343
353
|
};
|
|
344
354
|
if (adapter.supportsTransactionalDdl) {
|