kysely 0.28.17 → 0.28.18
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/mysql/mysql-dialect-config.d.ts +10 -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 +10 -0
- package/dist/cjs/dialect/postgres/postgres-driver.js +5 -0
- 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/helpers/mssql.d.ts +3 -1
- package/dist/cjs/helpers/mssql.js +4 -2
- package/dist/cjs/kysely.d.ts +50 -3
- package/dist/cjs/kysely.js +90 -30
- 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/mysql/mysql-dialect-config.d.ts +10 -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 +10 -0
- package/dist/esm/dialect/postgres/postgres-driver.js +5 -0
- 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/helpers/mssql.d.ts +3 -1
- package/dist/esm/helpers/mssql.js +4 -2
- package/dist/esm/kysely.d.ts +50 -3
- package/dist/esm/kysely.js +90 -30
- 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
|
@@ -412,34 +412,37 @@ class Migrator {
|
|
|
412
412
|
lockTableSchema: this.#props.migrationTableSchema,
|
|
413
413
|
});
|
|
414
414
|
const run = async (db) => {
|
|
415
|
+
const state = await this.#getState(db);
|
|
416
|
+
if (state.migrations.length === 0) {
|
|
417
|
+
return { results: [] };
|
|
418
|
+
}
|
|
419
|
+
const { direction, step } = getMigrationDirectionAndStep(state);
|
|
420
|
+
if (step <= 0) {
|
|
421
|
+
return { results: [] };
|
|
422
|
+
}
|
|
423
|
+
if (direction === 'Down') {
|
|
424
|
+
return await this.#migrateDown(db, state, step);
|
|
425
|
+
}
|
|
426
|
+
else if (direction === 'Up') {
|
|
427
|
+
return await this.#migrateUp(db, state, step);
|
|
428
|
+
}
|
|
429
|
+
return { results: [] };
|
|
430
|
+
};
|
|
431
|
+
const runWithLock = async (db, cb) => {
|
|
415
432
|
try {
|
|
416
433
|
await adapter.acquireMigrationLock(db, lockOptions);
|
|
417
|
-
|
|
418
|
-
if (state.migrations.length === 0) {
|
|
419
|
-
return { results: [] };
|
|
420
|
-
}
|
|
421
|
-
const { direction, step } = getMigrationDirectionAndStep(state);
|
|
422
|
-
if (step <= 0) {
|
|
423
|
-
return { results: [] };
|
|
424
|
-
}
|
|
425
|
-
if (direction === 'Down') {
|
|
426
|
-
return await this.#migrateDown(db, state, step);
|
|
427
|
-
}
|
|
428
|
-
else if (direction === 'Up') {
|
|
429
|
-
return await this.#migrateUp(db, state, step);
|
|
430
|
-
}
|
|
431
|
-
return { results: [] };
|
|
434
|
+
return await cb(db);
|
|
432
435
|
}
|
|
433
436
|
finally {
|
|
434
437
|
await adapter.releaseMigrationLock(db, lockOptions);
|
|
435
438
|
}
|
|
436
439
|
};
|
|
437
440
|
if (adapter.supportsTransactionalDdl && !this.#props.disableTransactions) {
|
|
438
|
-
return this.#props.db
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
return this.#props.db.connection().execute(run);
|
|
441
|
+
return this.#props.db
|
|
442
|
+
.connection()
|
|
443
|
+
.execute((db) => runWithLock(db, (db) => db.transaction().execute((trx) => run(trx))));
|
|
442
444
|
}
|
|
445
|
+
return this.#props.db.connection().execute((db) => runWithLock(db, run));
|
|
443
446
|
}
|
|
444
447
|
async #getState(db) {
|
|
445
448
|
const migrations = await this.#resolveMigrations();
|
|
@@ -1039,7 +1039,7 @@ export declare class DeleteQueryBuilder<DB, TB extends keyof DB, O> implements W
|
|
|
1039
1039
|
* delete from `pet` order by `created_at` limit ?
|
|
1040
1040
|
* ```
|
|
1041
1041
|
*/
|
|
1042
|
-
limit
|
|
1042
|
+
limit<VE extends ValueExpression<DB, TB, number>>(limit: VE): DeleteQueryBuilder<DB, TB, O>;
|
|
1043
1043
|
/**
|
|
1044
1044
|
* This can be used to add any additional SQL to the end of the query.
|
|
1045
1045
|
*
|
|
@@ -1122,7 +1122,7 @@ export declare class DeleteQueryBuilder<DB, TB extends keyof DB, O> implements W
|
|
|
1122
1122
|
* }>
|
|
1123
1123
|
* ```
|
|
1124
1124
|
*/
|
|
1125
|
-
$if<O2>(condition: boolean, func: (qb: this) => DeleteQueryBuilder<any, any, O2>): O2 extends DeleteResult ? DeleteQueryBuilder<DB, TB, DeleteResult> : O2 extends O & infer E ? DeleteQueryBuilder<DB, TB, O & Partial<E>> : DeleteQueryBuilder<DB, TB, Partial<O2>>;
|
|
1125
|
+
$if<O2>(condition: boolean, func: (qb: this) => DeleteQueryBuilder<any, any, O2>): unknown extends O2 ? DeleteQueryBuilder<any, any, O2> : O2 extends DeleteResult ? DeleteQueryBuilder<DB, TB, DeleteResult> : O2 extends O & infer E ? DeleteQueryBuilder<DB, TB, O & Partial<E>> : DeleteQueryBuilder<DB, TB, Partial<O2>>;
|
|
1126
1126
|
/**
|
|
1127
1127
|
* Change the output type of the query.
|
|
1128
1128
|
*
|
|
@@ -14,14 +14,14 @@ export declare class JoinBuilder<DB, TB extends keyof DB> implements OperationNo
|
|
|
14
14
|
* See {@link WhereInterface.where} for documentation and examples.
|
|
15
15
|
*/
|
|
16
16
|
on<RE extends ReferenceExpression<DB, TB>>(lhs: RE, op: ComparisonOperatorExpression, rhs: OperandValueExpressionOrList<DB, TB, RE>): JoinBuilder<DB, TB>;
|
|
17
|
-
on
|
|
17
|
+
on<E extends ExpressionOrFactory<DB, TB, SqlBool>>(expression: E): JoinBuilder<DB, TB>;
|
|
18
18
|
/**
|
|
19
19
|
* Just like {@link WhereInterface.whereRef} but adds an item to the join's
|
|
20
20
|
* `on` clause instead.
|
|
21
21
|
*
|
|
22
22
|
* See {@link WhereInterface.whereRef} for documentation and examples.
|
|
23
23
|
*/
|
|
24
|
-
onRef
|
|
24
|
+
onRef<LRE extends ReferenceExpression<DB, TB>, RRE extends ReferenceExpression<DB, TB>>(lhs: LRE, op: ComparisonOperatorExpression, rhs: RRE): JoinBuilder<DB, TB>;
|
|
25
25
|
/**
|
|
26
26
|
* Adds `on true`.
|
|
27
27
|
*/
|
|
@@ -506,7 +506,7 @@ export declare class OnConflictBuilder<DB, TB extends keyof DB> implements Where
|
|
|
506
506
|
* "last_name" = excluded."last_name"
|
|
507
507
|
* ```
|
|
508
508
|
*/
|
|
509
|
-
doUpdateSet(update: UpdateObjectExpression<
|
|
509
|
+
doUpdateSet(update: UpdateObjectExpression<OnConflictUpdateDatabase<DB, TB>, OnConflictTables<TB>, OnConflictTables<TB>>): OnConflictUpdateBuilder<OnConflictDatabase<DB, TB>, OnConflictTables<TB>>;
|
|
510
510
|
/**
|
|
511
511
|
* Simply calls the provided function passing `this` as the only argument. `$call` returns
|
|
512
512
|
* what the provided function returns.
|
|
@@ -516,9 +516,12 @@ export declare class OnConflictBuilder<DB, TB extends keyof DB> implements Where
|
|
|
516
516
|
export interface OnConflictBuilderProps {
|
|
517
517
|
readonly onConflictNode: OnConflictNode;
|
|
518
518
|
}
|
|
519
|
-
export type
|
|
519
|
+
export type OnConflictUpdateDatabase<DB, TB extends keyof DB> = {
|
|
520
520
|
[K in keyof DB | 'excluded']: Updateable<K extends keyof DB ? DB[K] : DB[TB]>;
|
|
521
521
|
};
|
|
522
|
+
export type OnConflictDatabase<DB, TB extends keyof DB> = {
|
|
523
|
+
[K in keyof DB | 'excluded']: K extends keyof DB ? DB[K] : DB[TB];
|
|
524
|
+
};
|
|
522
525
|
export type OnConflictTables<TB> = TB | 'excluded';
|
|
523
526
|
export declare class OnConflictDoNothingBuilder<DB, TB extends keyof DB> implements OperationNodeSource {
|
|
524
527
|
#private;
|
|
@@ -1377,7 +1377,7 @@ export interface SelectQueryBuilder<DB, TB extends keyof DB, O> extends WhereInt
|
|
|
1377
1377
|
* select "first_name" from "person" limit $1 offset $2
|
|
1378
1378
|
* ```
|
|
1379
1379
|
*/
|
|
1380
|
-
limit
|
|
1380
|
+
limit<VE extends ValueExpression<DB, TB, number | bigint | null>>(limit: VE): SelectQueryBuilder<DB, TB, O>;
|
|
1381
1381
|
/**
|
|
1382
1382
|
* Adds an `offset` clause to the query.
|
|
1383
1383
|
*
|
|
@@ -1400,7 +1400,7 @@ export interface SelectQueryBuilder<DB, TB extends keyof DB, O> extends WhereInt
|
|
|
1400
1400
|
* select "first_name" from "person" limit $1 offset $2
|
|
1401
1401
|
* ```
|
|
1402
1402
|
*/
|
|
1403
|
-
offset
|
|
1403
|
+
offset<VE extends ValueExpression<DB, TB, number | bigint>>(offset: VE): SelectQueryBuilder<DB, TB, O>;
|
|
1404
1404
|
/**
|
|
1405
1405
|
* Adds a `fetch` clause to the query.
|
|
1406
1406
|
*
|
|
@@ -2367,22 +2367,44 @@ export interface SelectQueryBuilderProps {
|
|
|
2367
2367
|
export interface AliasedSelectQueryBuilder<O = undefined, A extends string = never> extends AliasedExpression<O, A> {
|
|
2368
2368
|
get isAliasedSelectQueryBuilder(): true;
|
|
2369
2369
|
}
|
|
2370
|
-
|
|
2370
|
+
/**
|
|
2371
|
+
* Guards a join's result type against being computed for an unknown table
|
|
2372
|
+
* expression.
|
|
2373
|
+
*
|
|
2374
|
+
* `TableExpression<DB, TB> extends TE` only holds when `TE` is as wide as its
|
|
2375
|
+
* own constraint, which never happens at a call site - there `TE` is a specific
|
|
2376
|
+
* table name, alias or subquery. It does happen when the compiler asks what a
|
|
2377
|
+
* join returns for an arbitrary table expression, which is what it has to do
|
|
2378
|
+
* whenever it compares two `SelectQueryBuilder` types structurally.
|
|
2379
|
+
*
|
|
2380
|
+
* Without this guard that comparison never terminates on its own: computing the
|
|
2381
|
+
* join result yields a `SelectQueryBuilder` over a wider `DB`, whose own join
|
|
2382
|
+
* methods yield a wider one still, so the compiler only stops when it hits its
|
|
2383
|
+
* internal recursion limit. That limit differs between TypeScript versions - 7.0
|
|
2384
|
+
* searches a level deeper than 5.9 and 6.0 - which made comparing two select
|
|
2385
|
+
* query builders over 6x more expensive there.
|
|
2386
|
+
*
|
|
2387
|
+
* Collapsing to a fixed type makes the recursion converge instead: joining an
|
|
2388
|
+
* unknown table expression again produces the same type, so the compiler
|
|
2389
|
+
* recognises the pair it is already comparing and stops immediately.
|
|
2390
|
+
*/
|
|
2391
|
+
type JoinResultForUnknownTable<O> = SelectQueryBuilder<any, any, O>;
|
|
2392
|
+
export type SelectQueryBuilderWithInnerJoin<DB, TB extends keyof DB, O, TE extends TableExpression<DB, TB>> = TableExpression<DB, TB> extends TE ? JoinResultForUnknownTable<O> : TE extends `${infer T} as ${infer A}` ? T extends keyof DB ? InnerJoinedBuilder<DB, TB, O, A, DB[T]> : never : TE extends keyof DB ? SelectQueryBuilder<DB, TB | TE, O> : TE extends AliasedExpression<infer QO, infer QA> ? InnerJoinedBuilder<DB, TB, O, QA, QO> : TE extends (qb: any) => AliasedExpression<infer QO, infer QA> ? InnerJoinedBuilder<DB, TB, O, QA, QO> : never;
|
|
2371
2393
|
type InnerJoinedBuilder<DB, TB extends keyof DB, O, A extends string, R> = A extends keyof DB ? SelectQueryBuilder<InnerJoinedDB<DB, A, R>, TB | A, O> : SelectQueryBuilder<DB & ShallowRecord<A, R>, TB | A, O>;
|
|
2372
2394
|
type InnerJoinedDB<DB, A extends string, R> = DrainOuterGeneric<{
|
|
2373
2395
|
[C in keyof DB | A]: C extends A ? R : C extends keyof DB ? DB[C] : never;
|
|
2374
2396
|
}>;
|
|
2375
|
-
export type SelectQueryBuilderWithLeftJoin<DB, TB extends keyof DB, O, TE extends TableExpression<DB, TB>> = TE extends `${infer T} as ${infer A}` ? T extends keyof DB ? LeftJoinedBuilder<DB, TB, O, A, DB[T]> : never : TE extends keyof DB ? LeftJoinedBuilder<DB, TB, O, TE, DB[TE]> : TE extends AliasedExpression<infer QO, infer QA> ? LeftJoinedBuilder<DB, TB, O, QA, QO> : TE extends (qb: any) => AliasedExpression<infer QO, infer QA> ? LeftJoinedBuilder<DB, TB, O, QA, QO> : never;
|
|
2397
|
+
export type SelectQueryBuilderWithLeftJoin<DB, TB extends keyof DB, O, TE extends TableExpression<DB, TB>> = TableExpression<DB, TB> extends TE ? JoinResultForUnknownTable<O> : TE extends `${infer T} as ${infer A}` ? T extends keyof DB ? LeftJoinedBuilder<DB, TB, O, A, DB[T]> : never : TE extends keyof DB ? LeftJoinedBuilder<DB, TB, O, TE, DB[TE]> : TE extends AliasedExpression<infer QO, infer QA> ? LeftJoinedBuilder<DB, TB, O, QA, QO> : TE extends (qb: any) => AliasedExpression<infer QO, infer QA> ? LeftJoinedBuilder<DB, TB, O, QA, QO> : never;
|
|
2376
2398
|
type LeftJoinedBuilder<DB, TB extends keyof DB, O, A extends keyof any, R> = A extends keyof DB ? SelectQueryBuilder<LeftJoinedDB<DB, A, R>, TB | A, O> : SelectQueryBuilder<DB & ShallowRecord<A, Nullable<R>>, TB | A, O>;
|
|
2377
2399
|
type LeftJoinedDB<DB, A extends keyof any, R> = DrainOuterGeneric<{
|
|
2378
2400
|
[C in keyof DB | A]: C extends A ? Nullable<R> : C extends keyof DB ? DB[C] : never;
|
|
2379
2401
|
}>;
|
|
2380
|
-
export type SelectQueryBuilderWithRightJoin<DB, TB extends keyof DB, O, TE extends TableExpression<DB, TB>> = TE extends `${infer T} as ${infer A}` ? T extends keyof DB ? RightJoinedBuilder<DB, TB, O, A, DB[T]> : never : TE extends keyof DB ? RightJoinedBuilder<DB, TB, O, TE, DB[TE]> : TE extends AliasedExpression<infer QO, infer QA> ? RightJoinedBuilder<DB, TB, O, QA, QO> : TE extends (qb: any) => AliasedExpression<infer QO, infer QA> ? RightJoinedBuilder<DB, TB, O, QA, QO> : never;
|
|
2402
|
+
export type SelectQueryBuilderWithRightJoin<DB, TB extends keyof DB, O, TE extends TableExpression<DB, TB>> = TableExpression<DB, TB> extends TE ? JoinResultForUnknownTable<O> : TE extends `${infer T} as ${infer A}` ? T extends keyof DB ? RightJoinedBuilder<DB, TB, O, A, DB[T]> : never : TE extends keyof DB ? RightJoinedBuilder<DB, TB, O, TE, DB[TE]> : TE extends AliasedExpression<infer QO, infer QA> ? RightJoinedBuilder<DB, TB, O, QA, QO> : TE extends (qb: any) => AliasedExpression<infer QO, infer QA> ? RightJoinedBuilder<DB, TB, O, QA, QO> : never;
|
|
2381
2403
|
type RightJoinedBuilder<DB, TB extends keyof DB, O, A extends keyof any, R> = SelectQueryBuilder<RightJoinedDB<DB, TB, A, R>, TB | A, O>;
|
|
2382
2404
|
type RightJoinedDB<DB, TB extends keyof DB, A extends keyof any, R> = DrainOuterGeneric<{
|
|
2383
2405
|
[C in keyof DB | A]: C extends A ? R : C extends TB ? Nullable<DB[C]> : C extends keyof DB ? DB[C] : never;
|
|
2384
2406
|
}>;
|
|
2385
|
-
export type SelectQueryBuilderWithFullJoin<DB, TB extends keyof DB, O, TE extends TableExpression<DB, TB>> = TE extends `${infer T} as ${infer A}` ? T extends keyof DB ? OuterJoinedBuilder<DB, TB, O, A, DB[T]> : never : TE extends keyof DB ? OuterJoinedBuilder<DB, TB, O, TE, DB[TE]> : TE extends AliasedExpression<infer QO, infer QA> ? OuterJoinedBuilder<DB, TB, O, QA, QO> : TE extends (qb: any) => AliasedExpression<infer QO, infer QA> ? OuterJoinedBuilder<DB, TB, O, QA, QO> : never;
|
|
2407
|
+
export type SelectQueryBuilderWithFullJoin<DB, TB extends keyof DB, O, TE extends TableExpression<DB, TB>> = TableExpression<DB, TB> extends TE ? JoinResultForUnknownTable<O> : TE extends `${infer T} as ${infer A}` ? T extends keyof DB ? OuterJoinedBuilder<DB, TB, O, A, DB[T]> : never : TE extends keyof DB ? OuterJoinedBuilder<DB, TB, O, TE, DB[TE]> : TE extends AliasedExpression<infer QO, infer QA> ? OuterJoinedBuilder<DB, TB, O, QA, QO> : TE extends (qb: any) => AliasedExpression<infer QO, infer QA> ? OuterJoinedBuilder<DB, TB, O, QA, QO> : never;
|
|
2386
2408
|
type OuterJoinedBuilder<DB, TB extends keyof DB, O, A extends keyof any, R> = SelectQueryBuilder<OuterJoinedBuilderDB<DB, TB, A, R>, TB | A, O>;
|
|
2387
2409
|
type OuterJoinedBuilderDB<DB, TB extends keyof DB, A extends keyof any, R> = DrainOuterGeneric<{
|
|
2388
2410
|
[C in keyof DB | A]: C extends A ? Nullable<R> : C extends TB ? Nullable<DB[C]> : C extends keyof DB ? DB[C] : never;
|
|
@@ -1148,7 +1148,7 @@ export declare class UpdateQueryBuilder<DB, UT extends keyof DB, TB extends keyo
|
|
|
1148
1148
|
* }>
|
|
1149
1149
|
* ```
|
|
1150
1150
|
*/
|
|
1151
|
-
$if<O2>(condition: boolean, func: (qb: this) => UpdateQueryBuilder<any, any, any, O2>): O2 extends UpdateResult ? UpdateQueryBuilder<DB, UT, TB, UpdateResult> : O2 extends O & infer E ? UpdateQueryBuilder<DB, UT, TB, O & Partial<E>> : UpdateQueryBuilder<DB, UT, TB, Partial<O2>>;
|
|
1151
|
+
$if<O2>(condition: boolean, func: (qb: this) => UpdateQueryBuilder<any, any, any, O2>): unknown extends O2 ? UpdateQueryBuilder<any, any, any, O2> : O2 extends UpdateResult ? UpdateQueryBuilder<DB, UT, TB, UpdateResult> : O2 extends O & infer E ? UpdateQueryBuilder<DB, UT, TB, O & Partial<E>> : UpdateQueryBuilder<DB, UT, TB, Partial<O2>>;
|
|
1152
1152
|
/**
|
|
1153
1153
|
* Change the output type of the query.
|
|
1154
1154
|
*
|
|
@@ -262,6 +262,10 @@ class DefaultQueryCompiler extends operation_node_visitor_js_1.OperationNodeVisi
|
|
|
262
262
|
this.append(' ');
|
|
263
263
|
this.visitNode(node.where);
|
|
264
264
|
}
|
|
265
|
+
if (node.returning) {
|
|
266
|
+
this.append(' ');
|
|
267
|
+
this.visitNode(node.returning);
|
|
268
|
+
}
|
|
265
269
|
if (node.orderBy) {
|
|
266
270
|
this.append(' ');
|
|
267
271
|
this.visitNode(node.orderBy);
|
|
@@ -270,10 +274,6 @@ class DefaultQueryCompiler extends operation_node_visitor_js_1.OperationNodeVisi
|
|
|
270
274
|
this.append(' ');
|
|
271
275
|
this.visitNode(node.limit);
|
|
272
276
|
}
|
|
273
|
-
if (node.returning) {
|
|
274
|
-
this.append(' ');
|
|
275
|
-
this.visitNode(node.returning);
|
|
276
|
-
}
|
|
277
277
|
if (wrapInParens) {
|
|
278
278
|
this.append(')');
|
|
279
279
|
}
|
|
@@ -170,7 +170,7 @@ export type Insertable<R> = DrainOuterGeneric<object & {
|
|
|
170
170
|
* ```
|
|
171
171
|
*/
|
|
172
172
|
export type Updateable<R> = DrainOuterGeneric<{
|
|
173
|
-
[K in UpdateKeys<R>]?: UpdateType<R[K]
|
|
173
|
+
[K in UpdateKeys<R>]?: UpdateType<R[K]> | undefined;
|
|
174
174
|
}>;
|
|
175
175
|
/**
|
|
176
176
|
* Wrap your column type to opt-out from dehydration by {@link ShallowDehydrateValue},
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Kysely } from '../../kysely.js';
|
|
2
2
|
import { DialectAdapterBase } from '../dialect-adapter-base.js';
|
|
3
|
+
import type { MigrationLockOptions } from '../dialect-adapter.js';
|
|
3
4
|
export declare class MssqlAdapter extends DialectAdapterBase {
|
|
4
5
|
/**
|
|
5
6
|
* Whether or not this dialect supports `if not exists` in creation of tables/schemas/views/etc.
|
|
@@ -70,7 +71,7 @@ export declare class MssqlAdapter extends DialectAdapterBase {
|
|
|
70
71
|
* `db` is a single connection (session) that will be used to execute the
|
|
71
72
|
* migrations.
|
|
72
73
|
*/
|
|
73
|
-
acquireMigrationLock(db: Kysely<any
|
|
74
|
+
acquireMigrationLock(db: Kysely<any>, _opt: MigrationLockOptions): Promise<void>;
|
|
74
75
|
/**
|
|
75
76
|
* Releases the migration lock. See {@link acquireMigrationLock}.
|
|
76
77
|
*
|
|
@@ -79,5 +80,5 @@ export declare class MssqlAdapter extends DialectAdapterBase {
|
|
|
79
80
|
* is a single connection (session) that was used to execute the migrations
|
|
80
81
|
* and the `acquireMigrationLock` call.
|
|
81
82
|
*/
|
|
82
|
-
releaseMigrationLock(): Promise<void>;
|
|
83
|
+
releaseMigrationLock(db: Kysely<any>, _opt: MigrationLockOptions): Promise<void>;
|
|
83
84
|
}
|
|
@@ -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
|
}
|
|
@@ -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>);
|
|
@@ -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>);
|
|
@@ -19,6 +19,11 @@ export class PostgresDriver {
|
|
|
19
19
|
}
|
|
20
20
|
async acquireConnection() {
|
|
21
21
|
const client = await this.#pool.connect();
|
|
22
|
+
// `destroy` was called while the connection was being acquired.
|
|
23
|
+
if (!this.#pool) {
|
|
24
|
+
client.release();
|
|
25
|
+
throw new Error('driver has already been destroyed');
|
|
26
|
+
}
|
|
22
27
|
let connection = this.#connections.get(client);
|
|
23
28
|
if (!connection) {
|
|
24
29
|
connection = new PostgresConnection(client, {
|
|
@@ -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>);
|
|
@@ -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/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,10 @@ export declare class ControlledTransaction<DB, S extends string[] = []> extends
|
|
|
646
665
|
/**
|
|
647
666
|
* Commits the transaction.
|
|
648
667
|
*
|
|
668
|
+
* Waits for ongoing queries to finish. Streams must be exhausted or closed
|
|
669
|
+
* before awaiting this command. When consuming a stream with `for await`,
|
|
670
|
+
* exit the loop before committing.
|
|
671
|
+
*
|
|
649
672
|
* See {@link rollback}.
|
|
650
673
|
*
|
|
651
674
|
* ### Examples
|
|
@@ -671,6 +694,13 @@ export declare class ControlledTransaction<DB, S extends string[] = []> extends
|
|
|
671
694
|
/**
|
|
672
695
|
* Rolls back the transaction.
|
|
673
696
|
*
|
|
697
|
+
* The connection is released even if the rollback fails, so the transaction
|
|
698
|
+
* cannot be used afterwards in either case.
|
|
699
|
+
*
|
|
700
|
+
* Waits for ongoing queries to finish. Streams must be exhausted or closed
|
|
701
|
+
* before awaiting this command. When consuming a stream with `for await`,
|
|
702
|
+
* exit the loop before rolling back.
|
|
703
|
+
*
|
|
674
704
|
* See {@link commit} and {@link rollbackToSavepoint}.
|
|
675
705
|
*
|
|
676
706
|
* ### Examples
|
|
@@ -696,6 +726,10 @@ export declare class ControlledTransaction<DB, S extends string[] = []> extends
|
|
|
696
726
|
/**
|
|
697
727
|
* Creates a savepoint with a given name.
|
|
698
728
|
*
|
|
729
|
+
* Waits for ongoing queries to finish. Streams must be exhausted or closed
|
|
730
|
+
* before awaiting this command. When consuming a stream with `for await`,
|
|
731
|
+
* exit the loop before creating a savepoint.
|
|
732
|
+
*
|
|
699
733
|
* See {@link rollbackToSavepoint} and {@link releaseSavepoint}.
|
|
700
734
|
*
|
|
701
735
|
* For a type-safe experience, you should use the returned instance from now on.
|
|
@@ -726,6 +760,10 @@ export declare class ControlledTransaction<DB, S extends string[] = []> extends
|
|
|
726
760
|
/**
|
|
727
761
|
* Rolls back to a savepoint with a given name.
|
|
728
762
|
*
|
|
763
|
+
* Waits for ongoing queries to finish. Streams must be exhausted or closed
|
|
764
|
+
* before awaiting this command. When consuming a stream with `for await`,
|
|
765
|
+
* exit the loop before rolling back to a savepoint.
|
|
766
|
+
*
|
|
729
767
|
* See {@link savepoint} and {@link releaseSavepoint}.
|
|
730
768
|
*
|
|
731
769
|
* You must use the same instance returned by {@link savepoint}, or
|
|
@@ -757,6 +795,10 @@ export declare class ControlledTransaction<DB, S extends string[] = []> extends
|
|
|
757
795
|
/**
|
|
758
796
|
* Releases a savepoint with a given name.
|
|
759
797
|
*
|
|
798
|
+
* Waits for ongoing queries to finish. Streams must be exhausted or closed
|
|
799
|
+
* before awaiting this command. When consuming a stream with `for await`,
|
|
800
|
+
* exit the loop before releasing a savepoint.
|
|
801
|
+
*
|
|
760
802
|
* See {@link savepoint} and {@link rollbackToSavepoint}.
|
|
761
803
|
*
|
|
762
804
|
* You must use the same instance returned by {@link savepoint}, or
|
|
@@ -834,8 +876,13 @@ export declare class ControlledTransaction<DB, S extends string[] = []> extends
|
|
|
834
876
|
*/
|
|
835
877
|
withTables<T extends Record<string, Record<string, any>>>(): ControlledTransaction<DrainOuterGeneric<DB & T>, S>;
|
|
836
878
|
}
|
|
879
|
+
interface ControlledTransctionState {
|
|
880
|
+
isCommitted: boolean;
|
|
881
|
+
isRolledBack: boolean;
|
|
882
|
+
}
|
|
837
883
|
interface ControlledTransactionProps extends KyselyProps {
|
|
838
884
|
readonly connection: ControlledConnection;
|
|
885
|
+
readonly state?: ControlledTransctionState;
|
|
839
886
|
}
|
|
840
887
|
export declare class Command<T> {
|
|
841
888
|
#private;
|