kysely 0.16.6 → 0.16.10

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.
Files changed (93) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +139 -14
  3. package/dist/cjs/dialect/mysql/mysql-dialect.js +2 -1
  4. package/dist/cjs/dialect/mysql/mysql-driver.js +1 -1
  5. package/dist/cjs/dialect/postgres/postgres-dialect.js +2 -1
  6. package/dist/cjs/dialect/postgres/postgres-driver.js +1 -1
  7. package/dist/cjs/dialect/sqlite/sqlite-dialect.js +2 -1
  8. package/dist/cjs/dialect/sqlite/sqlite-driver.js +1 -1
  9. package/dist/cjs/driver/dummy-driver.d.ts +28 -0
  10. package/dist/cjs/driver/dummy-driver.js +31 -3
  11. package/dist/cjs/index-nodeless.d.ts +1 -0
  12. package/dist/cjs/index-nodeless.js +1 -0
  13. package/dist/cjs/kysely.d.ts +8 -6
  14. package/dist/cjs/kysely.js +10 -8
  15. package/dist/cjs/migration/migrator.d.ts +22 -0
  16. package/dist/cjs/migration/migrator.js +23 -1
  17. package/dist/cjs/plugin/deduplicate-joins/deduplicate-joins-plugin.d.ts +48 -0
  18. package/dist/cjs/plugin/deduplicate-joins/deduplicate-joins-plugin.js +19 -0
  19. package/dist/cjs/plugin/deduplicate-joins/deduplicate-joins-transformer.d.ts +9 -0
  20. package/dist/cjs/plugin/deduplicate-joins/deduplicate-joins-transformer.js +42 -0
  21. package/dist/cjs/plugin/{immediate-value.ts → immediate-value}/immediate-value-plugin.d.ts +0 -0
  22. package/dist/cjs/plugin/{immediate-value.ts → immediate-value}/immediate-value-plugin.js +0 -0
  23. package/dist/cjs/plugin/{immediate-value.ts → immediate-value}/immediate-value-transformer.d.ts +0 -0
  24. package/dist/cjs/plugin/{immediate-value.ts → immediate-value}/immediate-value-transformer.js +0 -0
  25. package/dist/cjs/query-builder/delete-query-builder.d.ts +52 -12
  26. package/dist/cjs/query-builder/delete-query-builder.js +56 -8
  27. package/dist/cjs/query-builder/function-builder.d.ts +29 -5
  28. package/dist/cjs/query-builder/function-builder.js +31 -7
  29. package/dist/cjs/query-builder/insert-query-builder.d.ts +54 -14
  30. package/dist/cjs/query-builder/insert-query-builder.js +58 -10
  31. package/dist/cjs/query-builder/returning-interface.d.ts +1 -3
  32. package/dist/cjs/query-builder/select-query-builder.d.ts +65 -24
  33. package/dist/cjs/query-builder/select-query-builder.js +64 -15
  34. package/dist/cjs/query-builder/update-query-builder.d.ts +53 -12
  35. package/dist/cjs/query-builder/update-query-builder.js +57 -8
  36. package/dist/cjs/query-compiler/default-query-compiler.js +8 -7
  37. package/dist/cjs/query-creator.d.ts +2 -2
  38. package/dist/cjs/query-creator.js +2 -2
  39. package/dist/cjs/query-executor/query-executor.js +3 -2
  40. package/dist/cjs/raw-builder/raw-builder.d.ts +2 -2
  41. package/dist/cjs/raw-builder/raw-builder.js +8 -1
  42. package/dist/cjs/schema/alter-table-builder.js +3 -3
  43. package/dist/cjs/schema/create-table-builder.js +2 -2
  44. package/dist/cjs/schema/create-view-builder.js +1 -1
  45. package/dist/cjs/util/object-utils.d.ts +1 -0
  46. package/dist/cjs/util/object-utils.js +50 -1
  47. package/dist/cjs/util/type-utils.d.ts +21 -0
  48. package/dist/esm/dialect/mysql/mysql-dialect.js +2 -1
  49. package/dist/esm/dialect/mysql/mysql-driver.js +2 -2
  50. package/dist/esm/dialect/postgres/postgres-dialect.js +2 -1
  51. package/dist/esm/dialect/postgres/postgres-driver.js +2 -2
  52. package/dist/esm/dialect/sqlite/sqlite-dialect.js +2 -1
  53. package/dist/esm/dialect/sqlite/sqlite-driver.js +2 -2
  54. package/dist/esm/driver/dummy-driver.d.ts +28 -0
  55. package/dist/esm/driver/dummy-driver.js +31 -3
  56. package/dist/esm/index-nodeless.d.ts +1 -0
  57. package/dist/esm/index-nodeless.js +1 -0
  58. package/dist/esm/kysely.d.ts +8 -6
  59. package/dist/esm/kysely.js +10 -8
  60. package/dist/esm/migration/migrator.d.ts +22 -0
  61. package/dist/esm/migration/migrator.js +23 -1
  62. package/dist/esm/plugin/deduplicate-joins/deduplicate-joins-plugin.d.ts +48 -0
  63. package/dist/esm/plugin/deduplicate-joins/deduplicate-joins-plugin.js +16 -0
  64. package/dist/esm/plugin/deduplicate-joins/deduplicate-joins-transformer.d.ts +9 -0
  65. package/dist/esm/plugin/deduplicate-joins/deduplicate-joins-transformer.js +39 -0
  66. package/dist/esm/plugin/{immediate-value.ts → immediate-value}/immediate-value-plugin.d.ts +0 -0
  67. package/dist/esm/plugin/{immediate-value.ts → immediate-value}/immediate-value-plugin.js +0 -0
  68. package/dist/esm/plugin/{immediate-value.ts → immediate-value}/immediate-value-transformer.d.ts +0 -0
  69. package/dist/esm/plugin/{immediate-value.ts → immediate-value}/immediate-value-transformer.js +0 -0
  70. package/dist/esm/query-builder/delete-query-builder.d.ts +52 -12
  71. package/dist/esm/query-builder/delete-query-builder.js +56 -8
  72. package/dist/esm/query-builder/function-builder.d.ts +29 -5
  73. package/dist/esm/query-builder/function-builder.js +31 -7
  74. package/dist/esm/query-builder/insert-query-builder.d.ts +54 -14
  75. package/dist/esm/query-builder/insert-query-builder.js +58 -10
  76. package/dist/esm/query-builder/returning-interface.d.ts +1 -3
  77. package/dist/esm/query-builder/select-query-builder.d.ts +65 -24
  78. package/dist/esm/query-builder/select-query-builder.js +64 -15
  79. package/dist/esm/query-builder/update-query-builder.d.ts +53 -12
  80. package/dist/esm/query-builder/update-query-builder.js +57 -8
  81. package/dist/esm/query-compiler/default-query-compiler.js +8 -7
  82. package/dist/esm/query-creator.d.ts +2 -2
  83. package/dist/esm/query-creator.js +2 -2
  84. package/dist/esm/query-executor/query-executor.js +3 -2
  85. package/dist/esm/raw-builder/raw-builder.d.ts +2 -2
  86. package/dist/esm/raw-builder/raw-builder.js +8 -1
  87. package/dist/esm/schema/alter-table-builder.js +3 -3
  88. package/dist/esm/schema/create-table-builder.js +2 -2
  89. package/dist/esm/schema/create-view-builder.js +1 -1
  90. package/dist/esm/util/object-utils.d.ts +1 -0
  91. package/dist/esm/util/object-utils.js +48 -0
  92. package/dist/esm/util/type-utils.d.ts +21 -0
  93. package/package.json +4 -2
@@ -7,7 +7,7 @@ import { SelectExpression, QueryBuilderWithSelection, SelectAllQueryBuilder } fr
7
7
  import { ExistsExpression, FilterOperator, FilterValueExpressionOrList, WhereGrouper, HavingGrouper } from '../parser/filter-parser.js';
8
8
  import { ReferenceExpression } from '../parser/reference-parser.js';
9
9
  import { SelectQueryNode } from '../operation-node/select-query-node.js';
10
- import { AnyRawBuilder, SingleResultType } from '../util/type-utils.js';
10
+ import { AnyRawBuilder, MergePartial, SingleResultType } from '../util/type-utils.js';
11
11
  import { OrderByDirectionExpression, OrderByExpression } from '../parser/order-by-parser.js';
12
12
  import { Compilable } from '../util/compilable.js';
13
13
  import { QueryExecutor } from '../query-executor/query-executor.js';
@@ -456,7 +456,10 @@ export declare class SelectQueryBuilder<DB, TB extends keyof DB, O> implements W
456
456
  * same as calling `select(['id', 'first_name']).
457
457
  *
458
458
  * To select all columns of the query or specific tables see the
459
- * {@link SelectQueryBuilder.selectAll | selectAll} method.
459
+ * {@link selectAll} method.
460
+ *
461
+ * See the {@link if} method if you are looking for a way to add selections
462
+ * based on a runtime condition.
460
463
  *
461
464
  * ### Examples
462
465
  *
@@ -971,14 +974,12 @@ export declare class SelectQueryBuilder<DB, TB extends keyof DB, O> implements W
971
974
  * `groupBy` also accepts an array:
972
975
  *
973
976
  * ```ts
974
- * const { raw } = db
975
- *
976
977
  * await db
977
978
  * .selectFrom('person')
978
979
  * .select([
979
980
  * 'first_name',
980
981
  * 'last_name',
981
- * raw('max(id)').as('max_id')
982
+ * db.raw('max(id)').as('max_id')
982
983
  * ])
983
984
  * .groupBy([
984
985
  * 'first_name',
@@ -999,17 +1000,15 @@ export declare class SelectQueryBuilder<DB, TB extends keyof DB, O> implements W
999
1000
  * raw expressions:
1000
1001
  *
1001
1002
  * ```ts
1002
- * const { raw } = db
1003
- *
1004
1003
  * await db
1005
1004
  * .selectFrom('person')
1006
1005
  * .select([
1007
1006
  * 'first_name',
1008
1007
  * 'last_name',
1009
- * raw('max(id)').as('max_id')
1008
+ * db.raw('max(id)').as('max_id')
1010
1009
  * ])
1011
1010
  * .groupBy([
1012
- * raw('concat(first_name, last_name)'),
1011
+ * db.raw('concat(first_name, last_name)'),
1013
1012
  * (qb) => qb.selectFrom('pet').select('id').limit(1)
1014
1013
  * ])
1015
1014
  * .execute()
@@ -1116,27 +1115,15 @@ export declare class SelectQueryBuilder<DB, TB extends keyof DB, O> implements W
1116
1115
  /**
1117
1116
  * Simply calls the given function passing `this` as the only argument.
1118
1117
  *
1119
- * This method can be useful when adding optional method calls:
1118
+ * If you want to conditionally call a method on `this`, see
1119
+ * the {@link if} method.
1120
1120
  *
1121
1121
  * ### Examples
1122
1122
  *
1123
- * ```ts
1124
- * db.selectFrom('person')
1125
- * .selectAll()
1126
- * .call((qb) => {
1127
- * if (something) {
1128
- * return qb.where('something', '=', something)
1129
- * } else {
1130
- * return qb.where('somethingElse', '=', somethingElse)
1131
- * }
1132
- * })
1133
- * .execute()
1134
- * ```
1135
- *
1136
1123
  * The next example uses a helper funtion `log` to log a query:
1137
1124
  *
1138
1125
  * ```ts
1139
- * function log<T extends AnyQueryBuilder>(qb: T): T {
1126
+ * function log<T extends Compilable>(qb: T): T {
1140
1127
  * console.log(qb.compile())
1141
1128
  * return qb
1142
1129
  * }
@@ -1148,6 +1135,57 @@ export declare class SelectQueryBuilder<DB, TB extends keyof DB, O> implements W
1148
1135
  * ```
1149
1136
  */
1150
1137
  call<T>(func: (qb: this) => T): T;
1138
+ /**
1139
+ * Call `func(this)` if `condition` is true.
1140
+ *
1141
+ * This method is especially handy with optional selects. Any `select` or `selectAll`
1142
+ * method calls add columns as optional fields to the output type when called inside
1143
+ * the `func` callback. This is because we can't know if those selections were actually
1144
+ * made before running the code.
1145
+ *
1146
+ * Also see [this recipe](https://github.com/koskimas/kysely/tree/master/recipes/conditional-selects.md)
1147
+ *
1148
+ * ### Examples
1149
+ *
1150
+ * ```ts
1151
+ * async function getPerson(id: number, withLastName: boolean) {
1152
+ * return await db
1153
+ * .selectFrom('person')
1154
+ * .select(['id', 'first_name'])
1155
+ * .if(withLastName, (qb) => qb.select('last_name'))
1156
+ * .where('id', '=', id)
1157
+ * .executeTakeFirstOrThrow()
1158
+ * }
1159
+ * ```
1160
+ *
1161
+ * Any selections added inside the `if` callback will be added as optional fields to the
1162
+ * output type since we can't know if the selections were actually made before running
1163
+ * the code. In the example above the return type of the `getPerson` function is:
1164
+ *
1165
+ * ```ts
1166
+ * {
1167
+ * id: number
1168
+ * first_name: string
1169
+ * last_name?: string
1170
+ * }
1171
+ * ```
1172
+ *
1173
+ * You can also call any other methods inside the callback:
1174
+ *
1175
+ * ```ts
1176
+ * const { count } = db.fn
1177
+ *
1178
+ * db.selectFrom('person')
1179
+ * .select('person.id')
1180
+ * .if(filterByFirstName, (qb) => qb.where('first_name', '=', firstName))
1181
+ * .if(filterByPetCount, (qb) => qb
1182
+ * .innerJoin('pet', 'pet.owner_id', 'person.id')
1183
+ * .having(count('pet.id'), '>', petCountLimit)
1184
+ * .groupBy('person.id')
1185
+ * )
1186
+ * ```
1187
+ */
1188
+ if<O2 extends O>(condition: boolean, func: (qb: this) => SelectQueryBuilder<DB, TB, O2>): SelectQueryBuilder<DB, TB, MergePartial<O, O2>>;
1151
1189
  /**
1152
1190
  * Gives an alias for the query. This method is only useful for sub queries.
1153
1191
  *
@@ -1173,6 +1211,9 @@ export declare class SelectQueryBuilder<DB, TB extends keyof DB, O> implements W
1173
1211
  * don't support your use case.
1174
1212
  */
1175
1213
  castTo<T>(): SelectQueryBuilder<DB, TB, T>;
1214
+ /**
1215
+ * Returns a copy of this SelectQueryBuilder instance with the given plugin installed.
1216
+ */
1176
1217
  withPlugin(plugin: KyselyPlugin): SelectQueryBuilder<DB, TB, O>;
1177
1218
  toOperationNode(): SelectQueryNode;
1178
1219
  compile(): CompiledQuery;
@@ -425,27 +425,15 @@ export class SelectQueryBuilder {
425
425
  /**
426
426
  * Simply calls the given function passing `this` as the only argument.
427
427
  *
428
- * This method can be useful when adding optional method calls:
428
+ * If you want to conditionally call a method on `this`, see
429
+ * the {@link if} method.
429
430
  *
430
431
  * ### Examples
431
432
  *
432
- * ```ts
433
- * db.selectFrom('person')
434
- * .selectAll()
435
- * .call((qb) => {
436
- * if (something) {
437
- * return qb.where('something', '=', something)
438
- * } else {
439
- * return qb.where('somethingElse', '=', somethingElse)
440
- * }
441
- * })
442
- * .execute()
443
- * ```
444
- *
445
433
  * The next example uses a helper funtion `log` to log a query:
446
434
  *
447
435
  * ```ts
448
- * function log<T extends AnyQueryBuilder>(qb: T): T {
436
+ * function log<T extends Compilable>(qb: T): T {
449
437
  * console.log(qb.compile())
450
438
  * return qb
451
439
  * }
@@ -459,6 +447,64 @@ export class SelectQueryBuilder {
459
447
  call(func) {
460
448
  return func(this);
461
449
  }
450
+ /**
451
+ * Call `func(this)` if `condition` is true.
452
+ *
453
+ * This method is especially handy with optional selects. Any `select` or `selectAll`
454
+ * method calls add columns as optional fields to the output type when called inside
455
+ * the `func` callback. This is because we can't know if those selections were actually
456
+ * made before running the code.
457
+ *
458
+ * Also see [this recipe](https://github.com/koskimas/kysely/tree/master/recipes/conditional-selects.md)
459
+ *
460
+ * ### Examples
461
+ *
462
+ * ```ts
463
+ * async function getPerson(id: number, withLastName: boolean) {
464
+ * return await db
465
+ * .selectFrom('person')
466
+ * .select(['id', 'first_name'])
467
+ * .if(withLastName, (qb) => qb.select('last_name'))
468
+ * .where('id', '=', id)
469
+ * .executeTakeFirstOrThrow()
470
+ * }
471
+ * ```
472
+ *
473
+ * Any selections added inside the `if` callback will be added as optional fields to the
474
+ * output type since we can't know if the selections were actually made before running
475
+ * the code. In the example above the return type of the `getPerson` function is:
476
+ *
477
+ * ```ts
478
+ * {
479
+ * id: number
480
+ * first_name: string
481
+ * last_name?: string
482
+ * }
483
+ * ```
484
+ *
485
+ * You can also call any other methods inside the callback:
486
+ *
487
+ * ```ts
488
+ * const { count } = db.fn
489
+ *
490
+ * db.selectFrom('person')
491
+ * .select('person.id')
492
+ * .if(filterByFirstName, (qb) => qb.where('first_name', '=', firstName))
493
+ * .if(filterByPetCount, (qb) => qb
494
+ * .innerJoin('pet', 'pet.owner_id', 'person.id')
495
+ * .having(count('pet.id'), '>', petCountLimit)
496
+ * .groupBy('person.id')
497
+ * )
498
+ * ```
499
+ */
500
+ if(condition, func) {
501
+ if (condition) {
502
+ return func(this);
503
+ }
504
+ return new SelectQueryBuilder({
505
+ ...this.#props,
506
+ });
507
+ }
462
508
  /**
463
509
  * Gives an alias for the query. This method is only useful for sub queries.
464
510
  *
@@ -488,6 +534,9 @@ export class SelectQueryBuilder {
488
534
  castTo() {
489
535
  return new SelectQueryBuilder(this.#props);
490
536
  }
537
+ /**
538
+ * Returns a copy of this SelectQueryBuilder instance with the given plugin installed.
539
+ */
491
540
  withPlugin(plugin) {
492
541
  return new SelectQueryBuilder({
493
542
  ...this.#props,
@@ -6,13 +6,14 @@ import { SelectExpression } from '../parser/select-parser.js';
6
6
  import { ExistsExpression, FilterOperator, FilterValueExpressionOrList, WhereGrouper } from '../parser/filter-parser.js';
7
7
  import { ReturningRow } from '../parser/returning-parser.js';
8
8
  import { ReferenceExpression } from '../parser/reference-parser.js';
9
- import { AnyRawBuilder, SingleResultType } from '../util/type-utils.js';
9
+ import { AnyRawBuilder, MergePartial, SingleResultType } from '../util/type-utils.js';
10
10
  import { UpdateQueryNode } from '../operation-node/update-query-node.js';
11
11
  import { MutationObject } from '../parser/update-set-parser.js';
12
12
  import { Compilable } from '../util/compilable.js';
13
13
  import { QueryExecutor } from '../query-executor/query-executor.js';
14
14
  import { QueryId } from '../util/query-id.js';
15
15
  import { ParseContext } from '../parser/parse-context.js';
16
+ import { UpdateResult } from './update-result.js';
16
17
  import { KyselyPlugin } from '../plugin/kysely-plugin.js';
17
18
  import { WhereInterface } from './where-interface.js';
18
19
  import { JoinInterface } from './join-interface.js';
@@ -650,8 +651,6 @@ export declare class UpdateQueryBuilder<DB, TB extends keyof DB, O> implements W
650
651
  * Return arbitrary expressions:
651
652
  *
652
653
  * ```ts
653
- * const { raw } = db
654
- *
655
654
  * const { id, full_name, first_pet_id } = await db
656
655
  * .insertInto('person')
657
656
  * .values({
@@ -660,7 +659,7 @@ export declare class UpdateQueryBuilder<DB, TB extends keyof DB, O> implements W
660
659
  * })
661
660
  * .returning([
662
661
  * 'id as id',
663
- * raw<string>(`concat(first_name, ' ', last_name)`).as('full_name'),
662
+ * db.raw<string>(`concat(first_name, ' ', last_name)`).as('full_name'),
664
663
  * (qb) => qb.selectFrom('pets').select('pet.id').limit(1).as('first_pet_id')
665
664
  * ])
666
665
  * .executeTakeFirst()
@@ -676,24 +675,63 @@ export declare class UpdateQueryBuilder<DB, TB extends keyof DB, O> implements W
676
675
  /**
677
676
  * Simply calls the given function passing `this` as the only argument.
678
677
  *
679
- * This method can be useful when adding optional method calls:
678
+ * If you want to conditionally call a method on `this`, see
679
+ * the {@link if} method.
680
680
  *
681
681
  * ### Examples
682
682
  *
683
+ * The next example uses a helper funtion `log` to log a query:
684
+ *
683
685
  * ```ts
686
+ * function log<T extends Compilable>(qb: T): T {
687
+ * console.log(qb.compile())
688
+ * return qb
689
+ * }
690
+ *
684
691
  * db.updateTable('person')
685
692
  * .set(values)
686
- * .call((qb) => {
687
- * if (something) {
688
- * return qb.where('something', '=', something)
689
- * } else {
690
- * return qb.where('somethingElse', '=', somethingElse)
691
- * }
692
- * })
693
+ * .call(log)
693
694
  * .execute()
694
695
  * ```
695
696
  */
696
697
  call<T>(func: (qb: this) => T): T;
698
+ /**
699
+ * Call `func(this)` if `condition` is true.
700
+ *
701
+ * This method is especially handy with optional selects. Any `returning` or `returningAll`
702
+ * method calls add columns as optional fields to the output type when called inside
703
+ * the `func` callback. This is because we can't know if those selections were actually
704
+ * made before running the code.
705
+ *
706
+ * You can also call any other methods inside the callback.
707
+ *
708
+ * ### Examples
709
+ *
710
+ * ```ts
711
+ * async function updatePerson(id: number, updates: UpdateablePerson, returnLastName: boolean) {
712
+ * return await db
713
+ * .updateTable('person')
714
+ * .set(updates)
715
+ * .where('id', '=', id)
716
+ * .returning(['id', 'first_name'])
717
+ * .if(returnLastName, (qb) => qb.returning('last_name'))
718
+ * .executeTakeFirstOrThrow()
719
+ * }
720
+ * ```
721
+ *
722
+ * Any selections added inside the `if` callback will be added as optional fields to the
723
+ * output type since we can't know if the selections were actually made before running
724
+ * the code. In the example above the return type of the `updatePerson` function is:
725
+ *
726
+ * ```ts
727
+ * {
728
+ * id: number
729
+ * first_name: string
730
+ * last_name?: string
731
+ * }
732
+ * ```
733
+ */
734
+ if<O2>(condition: boolean, func: (qb: this) => UpdateQueryBuilder<DB, TB, O2>): UpdateQueryBuilder<DB, TB, O2 extends UpdateResult ? UpdateResult : O extends UpdateResult ? Partial<O2> : MergePartial<O, O2>>;
697
735
  /**
698
736
  * Change the output type of the query.
699
737
  *
@@ -701,6 +739,9 @@ export declare class UpdateQueryBuilder<DB, TB extends keyof DB, O> implements W
701
739
  * don't support your use case.
702
740
  */
703
741
  castTo<T>(): UpdateQueryBuilder<DB, TB, T>;
742
+ /**
743
+ * Returns a copy of this UpdateQueryBuilder instance with the given plugin installed.
744
+ */
704
745
  withPlugin(plugin: KyselyPlugin): UpdateQueryBuilder<DB, TB, O>;
705
746
  toOperationNode(): UpdateQueryNode;
706
747
  compile(): CompiledQuery;
@@ -192,26 +192,72 @@ export class UpdateQueryBuilder {
192
192
  /**
193
193
  * Simply calls the given function passing `this` as the only argument.
194
194
  *
195
- * This method can be useful when adding optional method calls:
195
+ * If you want to conditionally call a method on `this`, see
196
+ * the {@link if} method.
196
197
  *
197
198
  * ### Examples
198
199
  *
200
+ * The next example uses a helper funtion `log` to log a query:
201
+ *
199
202
  * ```ts
203
+ * function log<T extends Compilable>(qb: T): T {
204
+ * console.log(qb.compile())
205
+ * return qb
206
+ * }
207
+ *
200
208
  * db.updateTable('person')
201
209
  * .set(values)
202
- * .call((qb) => {
203
- * if (something) {
204
- * return qb.where('something', '=', something)
205
- * } else {
206
- * return qb.where('somethingElse', '=', somethingElse)
207
- * }
208
- * })
210
+ * .call(log)
209
211
  * .execute()
210
212
  * ```
211
213
  */
212
214
  call(func) {
213
215
  return func(this);
214
216
  }
217
+ /**
218
+ * Call `func(this)` if `condition` is true.
219
+ *
220
+ * This method is especially handy with optional selects. Any `returning` or `returningAll`
221
+ * method calls add columns as optional fields to the output type when called inside
222
+ * the `func` callback. This is because we can't know if those selections were actually
223
+ * made before running the code.
224
+ *
225
+ * You can also call any other methods inside the callback.
226
+ *
227
+ * ### Examples
228
+ *
229
+ * ```ts
230
+ * async function updatePerson(id: number, updates: UpdateablePerson, returnLastName: boolean) {
231
+ * return await db
232
+ * .updateTable('person')
233
+ * .set(updates)
234
+ * .where('id', '=', id)
235
+ * .returning(['id', 'first_name'])
236
+ * .if(returnLastName, (qb) => qb.returning('last_name'))
237
+ * .executeTakeFirstOrThrow()
238
+ * }
239
+ * ```
240
+ *
241
+ * Any selections added inside the `if` callback will be added as optional fields to the
242
+ * output type since we can't know if the selections were actually made before running
243
+ * the code. In the example above the return type of the `updatePerson` function is:
244
+ *
245
+ * ```ts
246
+ * {
247
+ * id: number
248
+ * first_name: string
249
+ * last_name?: string
250
+ * }
251
+ * ```
252
+ */
253
+ if(condition, func) {
254
+ if (condition) {
255
+ return func(this);
256
+ }
257
+ return new UpdateQueryBuilder({
258
+ ...this.#props,
259
+ });
260
+ }
215
261
  /**
216
262
  * Change the output type of the query.
217
263
  *
@@ -221,6 +267,9 @@ export class UpdateQueryBuilder {
221
267
  castTo() {
222
268
  return new UpdateQueryBuilder(this.#props);
223
269
  }
270
+ /**
271
+ * Returns a copy of this UpdateQueryBuilder instance with the given plugin installed.
272
+ */
224
273
  withPlugin(plugin) {
225
274
  return new UpdateQueryBuilder({
226
275
  ...this.#props,
@@ -27,9 +27,9 @@ export class DefaultQueryCompiler extends OperationNodeVisitor {
27
27
  }
28
28
  visitSelectQuery(node) {
29
29
  const wrapInParens = this.parentNode !== undefined &&
30
+ !InsertQueryNode.is(this.parentNode) &&
30
31
  !CreateViewNode.is(this.parentNode) &&
31
- !UnionNode.is(this.parentNode) &&
32
- !InsertQueryNode.is(this.parentNode);
32
+ !UnionNode.is(this.parentNode);
33
33
  if (wrapInParens) {
34
34
  this.append('(');
35
35
  }
@@ -283,12 +283,13 @@ export class DefaultQueryCompiler extends OperationNodeVisitor {
283
283
  this.visitNode(node.on);
284
284
  }
285
285
  visitRaw(node) {
286
- node.sqlFragments.forEach((sql, i) => {
287
- this.append(sql);
288
- if (node.params.length > i) {
289
- this.visitNode(node.params[i]);
286
+ const { sqlFragments, params } = node;
287
+ for (let i = 0; i < sqlFragments.length; ++i) {
288
+ this.append(sqlFragments[i]);
289
+ if (params.length > i) {
290
+ this.visitNode(params[i]);
290
291
  }
291
- });
292
+ }
292
293
  }
293
294
  visitOperator(node) {
294
295
  this.append(node.operator);
@@ -162,7 +162,7 @@ export declare class QueryCreator<DB> {
162
162
  /**
163
163
  * Creates a delete query.
164
164
  *
165
- * See the {@link WhereInterface.where} method for examples on how to specify
165
+ * See the {@link DeleteQueryBuilder.where} method for examples on how to specify
166
166
  * a where clause for the delete operation.
167
167
  *
168
168
  * The return value of the query is an instance of {@link DeleteResult}.
@@ -182,7 +182,7 @@ export declare class QueryCreator<DB> {
182
182
  /**
183
183
  * Creates an update query.
184
184
  *
185
- * See the {@link WhereInterface.where} method for examples on how to specify
185
+ * See the {@link UpdateQueryBuilder.where} method for examples on how to specify
186
186
  * a where clause for the update operation.
187
187
  *
188
188
  * See the {@link UpdateQueryBuilder.set} method for examples on how to
@@ -76,7 +76,7 @@ export class QueryCreator {
76
76
  /**
77
77
  * Creates a delete query.
78
78
  *
79
- * See the {@link WhereInterface.where} method for examples on how to specify
79
+ * See the {@link DeleteQueryBuilder.where} method for examples on how to specify
80
80
  * a where clause for the delete operation.
81
81
  *
82
82
  * The return value of the query is an instance of {@link DeleteResult}.
@@ -103,7 +103,7 @@ export class QueryCreator {
103
103
  /**
104
104
  * Creates an update query.
105
105
  *
106
- * See the {@link WhereInterface.where} method for examples on how to specify
106
+ * See the {@link UpdateQueryBuilder.where} method for examples on how to specify
107
107
  * a where clause for the update operation.
108
108
  *
109
109
  * See the {@link UpdateQueryBuilder.set} method for examples on how to
@@ -1,5 +1,6 @@
1
1
  /// <reference types="./query-executor.d.ts" />
2
2
  import { freeze } from '../util/object-utils.js';
3
+ const NO_PLUGINS = freeze([]);
3
4
  /**
4
5
  * This class abstracts away the details of how to compile a query into SQL
5
6
  * and execute it. Instead of passing around all those details, {@link SelectQueryBuilder}
@@ -8,8 +9,8 @@ import { freeze } from '../util/object-utils.js';
8
9
  */
9
10
  export class QueryExecutor {
10
11
  #plugins;
11
- constructor(plugins = []) {
12
- this.#plugins = freeze([...plugins]);
12
+ constructor(plugins) {
13
+ this.#plugins = plugins ?? NO_PLUGINS;
13
14
  }
14
15
  get plugins() {
15
16
  return this.#plugins;
@@ -40,8 +40,8 @@ export declare class AliasedRawBuilder<O = unknown, A extends string = never> im
40
40
  constructor(rawBuilder: RawBuilder<O>, alias: A);
41
41
  }
42
42
  export interface RawBuilderProps {
43
- readonly queryId: QueryId;
44
- readonly executor: QueryExecutor;
43
+ readonly queryId?: QueryId;
44
+ readonly executor?: QueryExecutor;
45
45
  readonly sql: string;
46
46
  readonly parameters?: ReadonlyArray<unknown>;
47
47
  }
@@ -5,11 +5,18 @@ import { RawNode } from '../operation-node/raw-node.js';
5
5
  import { ValueNode } from '../operation-node/value-node.js';
6
6
  import { parseStringReference } from '../parser/reference-parser.js';
7
7
  import { preventAwait } from '../util/prevent-await.js';
8
+ import { createQueryId } from '../util/query-id.js';
8
9
  import { freeze } from '../util/object-utils.js';
10
+ import { NoopQueryExecutor } from '../query-executor/noop-query-executor.js';
9
11
  export class RawBuilder {
10
12
  #props;
11
13
  constructor(props) {
12
- this.#props = freeze(props);
14
+ this.#props = freeze({
15
+ queryId: props.queryId ?? createQueryId(),
16
+ executor: props.executor ?? new NoopQueryExecutor(),
17
+ sql: props.sql,
18
+ parameters: props.parameters,
19
+ });
13
20
  }
14
21
  as(alias) {
15
22
  return new AliasedRawBuilder(this, alias);
@@ -7,7 +7,6 @@ import { DataTypeNode, } from '../operation-node/data-type-node.js';
7
7
  import { DropColumnNode } from '../operation-node/drop-column-node.js';
8
8
  import { IdentifierNode } from '../operation-node/identifier-node.js';
9
9
  import { RenameColumnNode } from '../operation-node/rename-column-node.js';
10
- import { TableNode } from '../operation-node/table-node.js';
11
10
  import { freeze } from '../util/object-utils.js';
12
11
  import { preventAwait } from '../util/prevent-await.js';
13
12
  import { ColumnDefinitionBuilder, } from './column-definition-builder.js';
@@ -20,6 +19,7 @@ import { CheckConstraintNode } from '../operation-node/check-constraint-node.js'
20
19
  import { ForeignKeyConstraintNode } from '../operation-node/foreign-key-constraint-node.js';
21
20
  import { ColumnNode } from '../operation-node/column-node.js';
22
21
  import { parseDefaultValueExpression, } from '../parser/default-value-parser.js';
22
+ import { parseTable } from '../parser/table-parser.js';
23
23
  /**
24
24
  * This builder can be used to create a `alter table` query.
25
25
  */
@@ -32,7 +32,7 @@ export class AlterTableBuilder {
32
32
  return new AlterTableExecutor({
33
33
  ...this.#props,
34
34
  alterTableNode: AlterTableNode.cloneWith(this.#props.alterTableNode, {
35
- renameTo: TableNode.create(newTableName),
35
+ renameTo: parseTable(newTableName),
36
36
  }),
37
37
  });
38
38
  }
@@ -102,7 +102,7 @@ export class AlterTableBuilder {
102
102
  addForeignKeyConstraint(constraintName, columns, targetTable, targetColumns) {
103
103
  return new AlterTableAddForeignKeyConstraintBuilder({
104
104
  ...this.#props,
105
- constraintBuilder: new ForeignKeyConstraintBuilder(ForeignKeyConstraintNode.create(columns.map(ColumnNode.create), TableNode.create(targetTable), targetColumns.map(ColumnNode.create), constraintName)),
105
+ constraintBuilder: new ForeignKeyConstraintBuilder(ForeignKeyConstraintNode.create(columns.map(ColumnNode.create), parseTable(targetTable), targetColumns.map(ColumnNode.create), constraintName)),
106
106
  });
107
107
  }
108
108
  }
@@ -6,12 +6,12 @@ import { ColumnDefinitionBuilder } from './column-definition-builder.js';
6
6
  import { freeze, noop } from '../util/object-utils.js';
7
7
  import { ForeignKeyConstraintNode } from '../operation-node/foreign-key-constraint-node.js';
8
8
  import { ColumnNode } from '../operation-node/column-node.js';
9
- import { TableNode } from '../operation-node/table-node.js';
10
9
  import { ForeignKeyConstraintBuilder } from './foreign-key-constraint-builder.js';
11
10
  import { parseDataTypeExpression, } from '../parser/data-type-parser.js';
12
11
  import { PrimaryConstraintNode } from '../operation-node/primary-constraint-node.js';
13
12
  import { UniqueConstraintNode } from '../operation-node/unique-constraint-node.js';
14
13
  import { CheckConstraintNode } from '../operation-node/check-constraint-node.js';
14
+ import { parseTable } from '../parser/table-parser.js';
15
15
  /**
16
16
  * This builder can be used to create a `create table` query.
17
17
  */
@@ -193,7 +193,7 @@ export class CreateTableBuilder {
193
193
  * ```
194
194
  */
195
195
  addForeignKeyConstraint(constraintName, columns, targetTable, targetColumns, build = noop) {
196
- const builder = build(new ForeignKeyConstraintBuilder(ForeignKeyConstraintNode.create(columns.map(ColumnNode.create), TableNode.create(targetTable), targetColumns.map(ColumnNode.create), constraintName)));
196
+ const builder = build(new ForeignKeyConstraintBuilder(ForeignKeyConstraintNode.create(columns.map(ColumnNode.create), parseTable(targetTable), targetColumns.map(ColumnNode.create), constraintName)));
197
197
  return new CreateTableBuilder({
198
198
  ...this.#props,
199
199
  createTableNode: CreateTableNode.cloneWithConstraint(this.#props.createTableNode, builder.toOperationNode()),
@@ -3,7 +3,7 @@ import { preventAwait } from '../util/prevent-await.js';
3
3
  import { freeze } from '../util/object-utils.js';
4
4
  import { CreateViewNode } from '../operation-node/create-view-node.js';
5
5
  import { parseColumnName } from '../parser/reference-parser.js';
6
- import { ImmediateValuePlugin } from '../plugin/immediate-value.ts/immediate-value-plugin.js';
6
+ import { ImmediateValuePlugin } from '../plugin/immediate-value/immediate-value-plugin.js';
7
7
  export class CreateViewBuilder {
8
8
  #props;
9
9
  constructor(props) {
@@ -16,3 +16,4 @@ export declare function asArray<T>(arg: T | T[]): T[];
16
16
  export declare function asReadonlyArray<T>(arg: T | ReadonlyArray<T>): ReadonlyArray<T>;
17
17
  export declare function isReadonlyArray(arg: unknown): arg is ReadonlyArray<unknown>;
18
18
  export declare function noop<T>(obj: T): T;
19
+ export declare function compare(obj1: unknown, obj2: unknown): boolean;