kysely 0.19.10 → 0.20.0

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 (148) hide show
  1. package/README.md +52 -4
  2. package/dist/cjs/dialect/mysql/mysql-dialect-config.d.ts +10 -0
  3. package/dist/cjs/dialect/mysql/mysql-driver.d.ts +1 -0
  4. package/dist/cjs/dialect/mysql/mysql-driver.js +25 -0
  5. package/dist/cjs/dialect/mysql/mysql-introspector.js +2 -0
  6. package/dist/cjs/dialect/mysql/mysql-query-compiler.d.ts +5 -0
  7. package/dist/cjs/dialect/mysql/mysql-query-compiler.js +16 -0
  8. package/dist/cjs/dialect/postgres/postgres-dialect-config.d.ts +29 -0
  9. package/dist/cjs/dialect/postgres/postgres-driver.d.ts +6 -2
  10. package/dist/cjs/dialect/postgres/postgres-driver.js +24 -2
  11. package/dist/cjs/dialect/postgres/postgres-introspector.js +7 -1
  12. package/dist/cjs/dialect/postgres/postgres-query-compiler.d.ts +1 -3
  13. package/dist/cjs/dialect/postgres/postgres-query-compiler.js +3 -8
  14. package/dist/cjs/dialect/sqlite/sqlite-driver.js +3 -0
  15. package/dist/cjs/dialect/sqlite/sqlite-introspector.js +2 -0
  16. package/dist/cjs/dialect/sqlite/sqlite-query-compiler.d.ts +3 -0
  17. package/dist/cjs/dialect/sqlite/sqlite-query-compiler.js +10 -0
  18. package/dist/cjs/driver/database-connection.d.ts +1 -0
  19. package/dist/cjs/driver/dummy-driver.js +3 -0
  20. package/dist/cjs/index.d.ts +6 -0
  21. package/dist/cjs/index.js +6 -0
  22. package/dist/cjs/operation-node/create-table-node.d.ts +9 -2
  23. package/dist/cjs/operation-node/create-table-node.js +18 -1
  24. package/dist/cjs/operation-node/data-type-node.d.ts +1 -1
  25. package/dist/cjs/operation-node/delete-query-node.d.ts +3 -0
  26. package/dist/cjs/operation-node/delete-query-node.js +6 -0
  27. package/dist/cjs/operation-node/explain-node.d.ts +16 -0
  28. package/dist/cjs/operation-node/explain-node.js +19 -0
  29. package/dist/cjs/operation-node/foreign-key-constraint-node.d.ts +2 -2
  30. package/dist/cjs/operation-node/insert-query-node.d.ts +4 -1
  31. package/dist/cjs/operation-node/insert-query-node.js +2 -1
  32. package/dist/cjs/operation-node/operation-node-transformer.d.ts +2 -0
  33. package/dist/cjs/operation-node/operation-node-transformer.js +15 -0
  34. package/dist/cjs/operation-node/operation-node-visitor.d.ts +2 -0
  35. package/dist/cjs/operation-node/operation-node-visitor.js +1 -0
  36. package/dist/cjs/operation-node/operation-node.d.ts +1 -1
  37. package/dist/cjs/operation-node/references-node.d.ts +3 -1
  38. package/dist/cjs/operation-node/references-node.js +8 -1
  39. package/dist/cjs/operation-node/select-query-node.d.ts +3 -0
  40. package/dist/cjs/operation-node/select-query-node.js +6 -0
  41. package/dist/cjs/operation-node/update-query-node.d.ts +3 -0
  42. package/dist/cjs/operation-node/update-query-node.js +6 -0
  43. package/dist/cjs/parser/on-commit-action-parse.d.ts +2 -0
  44. package/dist/cjs/parser/on-commit-action-parse.js +11 -0
  45. package/dist/cjs/parser/on-modify-action-parser.d.ts +2 -0
  46. package/dist/cjs/parser/on-modify-action-parser.js +11 -0
  47. package/dist/cjs/query-builder/delete-query-builder.d.ts +19 -1
  48. package/dist/cjs/query-builder/delete-query-builder.js +24 -0
  49. package/dist/cjs/query-builder/function-builder.d.ts +3 -3
  50. package/dist/cjs/query-builder/insert-query-builder.d.ts +21 -3
  51. package/dist/cjs/query-builder/insert-query-builder.js +26 -0
  52. package/dist/cjs/query-builder/select-query-builder.d.ts +65 -1
  53. package/dist/cjs/query-builder/select-query-builder.js +79 -4
  54. package/dist/cjs/query-builder/update-query-builder.d.ts +20 -1
  55. package/dist/cjs/query-builder/update-query-builder.js +25 -0
  56. package/dist/cjs/query-compiler/default-query-compiler.d.ts +7 -0
  57. package/dist/cjs/query-compiler/default-query-compiler.js +75 -2
  58. package/dist/cjs/query-creator.d.ts +27 -0
  59. package/dist/cjs/query-creator.js +33 -0
  60. package/dist/cjs/query-executor/query-executor-base.d.ts +6 -0
  61. package/dist/cjs/query-executor/query-executor-base.js +19 -0
  62. package/dist/cjs/query-executor/query-executor.d.ts +11 -0
  63. package/dist/cjs/raw-builder/sql.d.ts +96 -96
  64. package/dist/cjs/raw-builder/sql.js +0 -96
  65. package/dist/cjs/schema/column-definition-builder.js +3 -2
  66. package/dist/cjs/schema/create-table-builder.d.ts +60 -6
  67. package/dist/cjs/schema/create-table-builder.js +72 -7
  68. package/dist/cjs/schema/create-type-builder.d.ts +9 -0
  69. package/dist/cjs/schema/create-type-builder.js +9 -0
  70. package/dist/cjs/schema/foreign-key-constraint-builder.js +3 -2
  71. package/dist/cjs/util/deferred.d.ts +7 -0
  72. package/dist/cjs/util/deferred.js +28 -0
  73. package/dist/cjs/util/explainable.d.ts +5 -0
  74. package/dist/cjs/util/explainable.js +2 -0
  75. package/dist/esm/dialect/mysql/mysql-dialect-config.d.ts +10 -0
  76. package/dist/esm/dialect/mysql/mysql-driver.d.ts +1 -0
  77. package/dist/esm/dialect/mysql/mysql-driver.js +25 -0
  78. package/dist/esm/dialect/mysql/mysql-introspector.js +2 -0
  79. package/dist/esm/dialect/mysql/mysql-query-compiler.d.ts +5 -0
  80. package/dist/esm/dialect/mysql/mysql-query-compiler.js +16 -0
  81. package/dist/esm/dialect/postgres/postgres-dialect-config.d.ts +29 -0
  82. package/dist/esm/dialect/postgres/postgres-driver.d.ts +6 -2
  83. package/dist/esm/dialect/postgres/postgres-driver.js +24 -2
  84. package/dist/esm/dialect/postgres/postgres-introspector.js +7 -1
  85. package/dist/esm/dialect/postgres/postgres-query-compiler.d.ts +1 -3
  86. package/dist/esm/dialect/postgres/postgres-query-compiler.js +3 -8
  87. package/dist/esm/dialect/sqlite/sqlite-driver.js +3 -0
  88. package/dist/esm/dialect/sqlite/sqlite-introspector.js +2 -0
  89. package/dist/esm/dialect/sqlite/sqlite-query-compiler.d.ts +3 -0
  90. package/dist/esm/dialect/sqlite/sqlite-query-compiler.js +10 -0
  91. package/dist/esm/driver/database-connection.d.ts +1 -0
  92. package/dist/esm/driver/dummy-driver.js +3 -0
  93. package/dist/esm/index.d.ts +6 -0
  94. package/dist/esm/index.js +6 -0
  95. package/dist/esm/operation-node/create-table-node.d.ts +9 -2
  96. package/dist/esm/operation-node/create-table-node.js +17 -0
  97. package/dist/esm/operation-node/data-type-node.d.ts +1 -1
  98. package/dist/esm/operation-node/delete-query-node.d.ts +3 -0
  99. package/dist/esm/operation-node/delete-query-node.js +6 -0
  100. package/dist/esm/operation-node/explain-node.d.ts +16 -0
  101. package/dist/esm/operation-node/explain-node.js +17 -0
  102. package/dist/esm/operation-node/foreign-key-constraint-node.d.ts +2 -2
  103. package/dist/esm/operation-node/insert-query-node.d.ts +4 -1
  104. package/dist/esm/operation-node/insert-query-node.js +2 -1
  105. package/dist/esm/operation-node/operation-node-transformer.d.ts +2 -0
  106. package/dist/esm/operation-node/operation-node-transformer.js +15 -0
  107. package/dist/esm/operation-node/operation-node-visitor.d.ts +2 -0
  108. package/dist/esm/operation-node/operation-node-visitor.js +1 -0
  109. package/dist/esm/operation-node/operation-node.d.ts +1 -1
  110. package/dist/esm/operation-node/references-node.d.ts +3 -1
  111. package/dist/esm/operation-node/references-node.js +7 -0
  112. package/dist/esm/operation-node/select-query-node.d.ts +3 -0
  113. package/dist/esm/operation-node/select-query-node.js +6 -0
  114. package/dist/esm/operation-node/update-query-node.d.ts +3 -0
  115. package/dist/esm/operation-node/update-query-node.js +6 -0
  116. package/dist/esm/parser/on-commit-action-parse.d.ts +2 -0
  117. package/dist/esm/parser/on-commit-action-parse.js +8 -0
  118. package/dist/esm/parser/on-modify-action-parser.d.ts +2 -0
  119. package/dist/esm/parser/on-modify-action-parser.js +8 -0
  120. package/dist/esm/query-builder/delete-query-builder.d.ts +19 -1
  121. package/dist/esm/query-builder/delete-query-builder.js +24 -0
  122. package/dist/esm/query-builder/function-builder.d.ts +3 -3
  123. package/dist/esm/query-builder/insert-query-builder.d.ts +21 -3
  124. package/dist/esm/query-builder/insert-query-builder.js +26 -0
  125. package/dist/esm/query-builder/select-query-builder.d.ts +65 -1
  126. package/dist/esm/query-builder/select-query-builder.js +79 -4
  127. package/dist/esm/query-builder/update-query-builder.d.ts +20 -1
  128. package/dist/esm/query-builder/update-query-builder.js +25 -0
  129. package/dist/esm/query-compiler/default-query-compiler.d.ts +7 -0
  130. package/dist/esm/query-compiler/default-query-compiler.js +75 -2
  131. package/dist/esm/query-creator.d.ts +27 -0
  132. package/dist/esm/query-creator.js +33 -0
  133. package/dist/esm/query-executor/query-executor-base.d.ts +6 -0
  134. package/dist/esm/query-executor/query-executor-base.js +19 -0
  135. package/dist/esm/query-executor/query-executor.d.ts +11 -0
  136. package/dist/esm/raw-builder/sql.d.ts +96 -96
  137. package/dist/esm/raw-builder/sql.js +0 -96
  138. package/dist/esm/schema/column-definition-builder.js +3 -2
  139. package/dist/esm/schema/create-table-builder.d.ts +60 -6
  140. package/dist/esm/schema/create-table-builder.js +72 -7
  141. package/dist/esm/schema/create-type-builder.d.ts +9 -0
  142. package/dist/esm/schema/create-type-builder.js +9 -0
  143. package/dist/esm/schema/foreign-key-constraint-builder.js +3 -2
  144. package/dist/esm/util/deferred.d.ts +7 -0
  145. package/dist/esm/util/deferred.js +25 -0
  146. package/dist/esm/util/explainable.d.ts +5 -0
  147. package/dist/esm/util/explainable.js +2 -0
  148. package/package.json +7 -2
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.AliasedQueryBuilder = exports.SelectQueryBuilder = void 0;
4
4
  const alias_node_js_1 = require("../operation-node/alias-node.js");
5
+ const select_modifier_node_js_1 = require("../operation-node/select-modifier-node.js");
5
6
  const join_parser_js_1 = require("../parser/join-parser.js");
6
7
  const select_parser_js_1 = require("../parser/select-parser.js");
7
8
  const filter_parser_js_1 = require("../parser/filter-parser.js");
@@ -16,7 +17,7 @@ const group_by_parser_js_1 = require("../parser/group-by-parser.js");
16
17
  const union_parser_js_1 = require("../parser/union-parser.js");
17
18
  const no_result_error_js_1 = require("./no-result-error.js");
18
19
  const identifier_node_js_1 = require("../operation-node/identifier-node.js");
19
- const select_modifier_node_js_1 = require("../operation-node/select-modifier-node.js");
20
+ const explain_node_js_1 = require("../operation-node/explain-node.js");
20
21
  class SelectQueryBuilder {
21
22
  #props;
22
23
  constructor(props) {
@@ -629,9 +630,8 @@ class SelectQueryBuilder {
629
630
  * Also see the {@link executeTakeFirst} and {@link executeTakeFirstOrThrow} methods.
630
631
  */
631
632
  async execute() {
632
- const compildQuery = this.compile();
633
- const query = compildQuery.query;
634
- const result = await this.#props.executor.executeQuery(compildQuery, this.#props.queryId);
633
+ const compiledQuery = this.compile();
634
+ const result = await this.#props.executor.executeQuery(compiledQuery, this.#props.queryId);
635
635
  return result.rows;
636
636
  }
637
637
  /**
@@ -657,6 +657,81 @@ class SelectQueryBuilder {
657
657
  }
658
658
  return result;
659
659
  }
660
+ /**
661
+ * Executes the query and streams the rows.
662
+ *
663
+ * The optional argument `chunkSize` defines how many rows to fetch from the database
664
+ * at a time. It only affects some dialects like PostgreSQL that support it.
665
+ *
666
+ * ### Examples
667
+ *
668
+ * ```ts
669
+ * const stream = db.
670
+ * .selectFrom('person')
671
+ * .select(['first_name', 'last_name'])
672
+ * .where('gender', '=', 'other')
673
+ * .stream()
674
+ *
675
+ * for await (const person of stream) {
676
+ * console.log(person.first_name)
677
+ *
678
+ * if (person.last_name === 'Something') {
679
+ * // Breaking or returning before the stream has ended will release
680
+ * // the database connection and invalidate the stream.
681
+ * break
682
+ * }
683
+ * }
684
+ * ```
685
+ */
686
+ async *stream(chunkSize = 100) {
687
+ const compildQuery = this.compile();
688
+ const stream = this.#props.executor.stream(compildQuery, chunkSize, this.#props.queryId);
689
+ for await (const item of stream) {
690
+ yield* item.rows;
691
+ }
692
+ }
693
+ /**
694
+ * Executes query with `explain` statement before `select` keyword.
695
+ *
696
+ * ```ts
697
+ * const explained = await db
698
+ * .selectFrom('person')
699
+ * .where('gender', '=', 'female')
700
+ * .selectAll()
701
+ * .explain('json')
702
+ * ```
703
+ *
704
+ * The generated SQL (MySQL):
705
+ *
706
+ * ```sql
707
+ * explain format=json select * from `person` where `gender` = ?
708
+ * ```
709
+ *
710
+ * You can also execute `explain analyze` statements.
711
+ *
712
+ * ```ts
713
+ * import { sql } from 'kysely'
714
+ *
715
+ * const explained = await db
716
+ * .selectFrom('person')
717
+ * .where('gender', '=', 'female')
718
+ * .selectAll()
719
+ * .explain('json', sql`analyze`)
720
+ * ```
721
+ *
722
+ * The generated SQL (PostgreSQL):
723
+ *
724
+ * ```sql
725
+ * explain (analyze, format json) select * from "person" where "gender" = $1
726
+ * ```
727
+ */
728
+ async explain(format, options) {
729
+ const builder = new SelectQueryBuilder({
730
+ ...this.#props,
731
+ queryNode: select_query_node_js_1.SelectQueryNode.cloneWithExplain(this.#props.queryNode, explain_node_js_1.ExplainNode.create(format, options)),
732
+ });
733
+ return await builder.execute();
734
+ }
660
735
  }
661
736
  exports.SelectQueryBuilder = SelectQueryBuilder;
662
737
  (0, prevent_await_js_1.preventAwait)(SelectQueryBuilder, "don't await SelectQueryBuilder instances directly. To execute the query you need to call `execute` or `executeTakeFirst`.");
@@ -20,7 +20,8 @@ import { NoResultErrorConstructor } from './no-result-error.js';
20
20
  import { Selectable } from '../util/column-type.js';
21
21
  import { AliasedQueryBuilder } from './select-query-builder.js';
22
22
  import { AliasedRawBuilder } from '../raw-builder/raw-builder.js';
23
- export declare class UpdateQueryBuilder<DB, UT extends keyof DB, TB extends keyof DB, O> implements WhereInterface<DB, TB>, ReturningInterface<DB, TB, O>, OperationNodeSource, Compilable {
23
+ import { Explainable, ExplainFormat } from '../util/explainable.js';
24
+ export declare class UpdateQueryBuilder<DB, UT extends keyof DB, TB extends keyof DB, O> implements WhereInterface<DB, TB>, ReturningInterface<DB, TB, O>, OperationNodeSource, Compilable, Explainable {
24
25
  #private;
25
26
  constructor(props: UpdateQueryBuilderProps);
26
27
  /**
@@ -809,6 +810,24 @@ export declare class UpdateQueryBuilder<DB, UT extends keyof DB, TB extends keyo
809
810
  * error.
810
811
  */
811
812
  executeTakeFirstOrThrow(errorConstructor?: NoResultErrorConstructor): Promise<O>;
813
+ /**
814
+ * Executes query with `explain` statement before `update` keyword.
815
+ *
816
+ * ```ts
817
+ * const explained = await db
818
+ * .updateTable('person')
819
+ * .set(updates)
820
+ * .where('id', '=', 123)
821
+ * .explain('json')
822
+ * ```
823
+ *
824
+ * The generated SQL (MySQL):
825
+ *
826
+ * ```sql
827
+ * explain format=json update `person` set `first_name` = ?, `last_name` = ? where `id` = ?
828
+ * ```
829
+ */
830
+ explain<ER extends Record<string, any> = Record<string, any>>(format?: ExplainFormat, options?: AnyRawBuilder): Promise<ER[]>;
812
831
  }
813
832
  export interface UpdateQueryBuilderProps {
814
833
  readonly queryId: QueryId;
@@ -12,6 +12,7 @@ const prevent_await_js_1 = require("../util/prevent-await.js");
12
12
  const object_utils_js_1 = require("../util/object-utils.js");
13
13
  const update_result_js_1 = require("./update-result.js");
14
14
  const no_result_error_js_1 = require("./no-result-error.js");
15
+ const explain_node_js_1 = require("../operation-node/explain-node.js");
15
16
  class UpdateQueryBuilder {
16
17
  #props;
17
18
  constructor(props) {
@@ -332,6 +333,30 @@ class UpdateQueryBuilder {
332
333
  }
333
334
  return result;
334
335
  }
336
+ /**
337
+ * Executes query with `explain` statement before `update` keyword.
338
+ *
339
+ * ```ts
340
+ * const explained = await db
341
+ * .updateTable('person')
342
+ * .set(updates)
343
+ * .where('id', '=', 123)
344
+ * .explain('json')
345
+ * ```
346
+ *
347
+ * The generated SQL (MySQL):
348
+ *
349
+ * ```sql
350
+ * explain format=json update `person` set `first_name` = ?, `last_name` = ? where `id` = ?
351
+ * ```
352
+ */
353
+ async explain(format, options) {
354
+ const builder = new UpdateQueryBuilder({
355
+ ...this.#props,
356
+ queryNode: update_query_node_js_1.UpdateQueryNode.cloneWithExplain(this.#props.queryNode, explain_node_js_1.ExplainNode.create(format, options)),
357
+ });
358
+ return await builder.execute();
359
+ }
335
360
  }
336
361
  exports.UpdateQueryBuilder = UpdateQueryBuilder;
337
362
  (0, prevent_await_js_1.preventAwait)(UpdateQueryBuilder, "don't await UpdateQueryBuilder instances directly. To execute the query you need to call `execute` or `executeTakeFirst`.");
@@ -71,6 +71,7 @@ import { CommonTableExpressionNameNode } from '../operation-node/common-table-ex
71
71
  import { SelectModifierNode } from '../operation-node/select-modifier-node.js';
72
72
  import { CreateTypeNode } from '../operation-node/create-type-node.js';
73
73
  import { DropTypeNode } from '../operation-node/drop-type-node.js';
74
+ import { ExplainNode } from '../operation-node/explain-node.js';
74
75
  export declare class DefaultQueryCompiler extends OperationNodeVisitor implements QueryCompiler {
75
76
  #private;
76
77
  protected get numParameters(): number;
@@ -149,11 +150,17 @@ export declare class DefaultQueryCompiler extends OperationNodeVisitor implement
149
150
  protected visitSelectModifier(node: SelectModifierNode): void;
150
151
  protected visitCreateType(node: CreateTypeNode): void;
151
152
  protected visitDropType(node: DropTypeNode): void;
153
+ protected visitExplain(node: ExplainNode): void;
152
154
  protected append(str: string): void;
153
155
  protected appendValue(parameter: unknown): void;
154
156
  protected getLeftIdentifierWrapper(): string;
155
157
  protected getRightIdentifierWrapper(): string;
156
158
  protected getCurrentParameterPlaceholder(): string;
159
+ protected getLeftExplainOptionsWrapper(): string;
160
+ protected getExplainOptionAssignment(): string;
161
+ protected getExplainOptionsDelimiter(): string;
162
+ protected getRightExplainOptionsWrapper(): string;
163
+ protected sanitizeIdentifier(identifier: string): string;
157
164
  protected addParameter(parameter: unknown): void;
158
165
  protected appendImmediateValue(value: unknown): void;
159
166
  }
@@ -32,6 +32,10 @@ class DefaultQueryCompiler extends operation_node_visitor_js_1.OperationNodeVisi
32
32
  !insert_query_node_js_1.InsertQueryNode.is(this.parentNode) &&
33
33
  !create_view_node_js_1.CreateViewNode.is(this.parentNode) &&
34
34
  !union_node_js_1.UnionNode.is(this.parentNode);
35
+ if (this.parentNode === undefined && node.explain) {
36
+ this.visitNode(node.explain);
37
+ this.append(' ');
38
+ }
35
39
  if (wrapInParens) {
36
40
  this.append('(');
37
41
  }
@@ -127,6 +131,10 @@ class DefaultQueryCompiler extends operation_node_visitor_js_1.OperationNodeVisi
127
131
  }
128
132
  visitInsertQuery(node) {
129
133
  const isSubQuery = this.nodeStack.find(query_node_js_1.QueryNode.is) !== node;
134
+ if (!isSubQuery && node.explain) {
135
+ this.visitNode(node.explain);
136
+ this.append(' ');
137
+ }
130
138
  if (isSubQuery) {
131
139
  this.append('(');
132
140
  }
@@ -134,7 +142,7 @@ class DefaultQueryCompiler extends operation_node_visitor_js_1.OperationNodeVisi
134
142
  this.visitNode(node.with);
135
143
  this.append(' ');
136
144
  }
137
- this.append('insert');
145
+ this.append(node.replace ? 'replace' : 'insert');
138
146
  if (node.ignore) {
139
147
  this.append(' ignore');
140
148
  }
@@ -171,6 +179,10 @@ class DefaultQueryCompiler extends operation_node_visitor_js_1.OperationNodeVisi
171
179
  }
172
180
  visitDeleteQuery(node) {
173
181
  const isSubQuery = this.nodeStack.find(query_node_js_1.QueryNode.is) !== node;
182
+ if (!isSubQuery && node.explain) {
183
+ this.visitNode(node.explain);
184
+ this.append(' ');
185
+ }
174
186
  if (isSubQuery) {
175
187
  this.append('(');
176
188
  }
@@ -227,7 +239,10 @@ class DefaultQueryCompiler extends operation_node_visitor_js_1.OperationNodeVisi
227
239
  this.append(this.getRightIdentifierWrapper());
228
240
  }
229
241
  compileUnwrappedIdentifier(node) {
230
- this.append(node.identifier);
242
+ if (!(0, object_utils_js_1.isString)(node.identifier)) {
243
+ throw new Error('a non-string identifier was passed to compileUnwrappedIdentifier.');
244
+ }
245
+ this.append(this.sanitizeIdentifier(node.identifier));
231
246
  }
232
247
  visitFilter(node) {
233
248
  if (node.left) {
@@ -311,6 +326,10 @@ class DefaultQueryCompiler extends operation_node_visitor_js_1.OperationNodeVisi
311
326
  }
312
327
  visitCreateTable(node) {
313
328
  this.append('create ');
329
+ if (node.frontModifiers) {
330
+ this.compileList(node.frontModifiers, ' ');
331
+ this.append(' ');
332
+ }
314
333
  if (node.temporary) {
315
334
  this.append('temporary ');
316
335
  }
@@ -326,6 +345,10 @@ class DefaultQueryCompiler extends operation_node_visitor_js_1.OperationNodeVisi
326
345
  this.append(' on commit ');
327
346
  this.append(node.onCommit);
328
347
  }
348
+ if (node.endModifiers) {
349
+ this.append(' ');
350
+ this.compileList(node.endModifiers, ' ');
351
+ }
329
352
  }
330
353
  visitColumnDefinition(node) {
331
354
  this.visitNode(node.column);
@@ -412,6 +435,10 @@ class DefaultQueryCompiler extends operation_node_visitor_js_1.OperationNodeVisi
412
435
  }
413
436
  visitUpdateQuery(node) {
414
437
  const isSubQuery = this.nodeStack.find(query_node_js_1.QueryNode.is) !== node;
438
+ if (!isSubQuery && node.explain) {
439
+ this.visitNode(node.explain);
440
+ this.append(' ');
441
+ }
415
442
  if (isSubQuery) {
416
443
  this.append('(');
417
444
  }
@@ -806,6 +833,25 @@ class DefaultQueryCompiler extends operation_node_visitor_js_1.OperationNodeVisi
806
833
  }
807
834
  this.visitNode(node.name);
808
835
  }
836
+ visitExplain(node) {
837
+ this.append('explain');
838
+ if (node.options || node.format) {
839
+ this.append(' ');
840
+ this.append(this.getLeftExplainOptionsWrapper());
841
+ if (node.options) {
842
+ this.visitNode(node.options);
843
+ if (node.format) {
844
+ this.append(this.getExplainOptionsDelimiter());
845
+ }
846
+ }
847
+ if (node.format) {
848
+ this.append('format');
849
+ this.append(this.getExplainOptionAssignment());
850
+ this.append(node.format);
851
+ }
852
+ this.append(this.getRightExplainOptionsWrapper());
853
+ }
854
+ }
809
855
  append(str) {
810
856
  this.#sql += str;
811
857
  }
@@ -822,6 +868,33 @@ class DefaultQueryCompiler extends operation_node_visitor_js_1.OperationNodeVisi
822
868
  getCurrentParameterPlaceholder() {
823
869
  return '$' + this.numParameters;
824
870
  }
871
+ getLeftExplainOptionsWrapper() {
872
+ return '(';
873
+ }
874
+ getExplainOptionAssignment() {
875
+ return ' ';
876
+ }
877
+ getExplainOptionsDelimiter() {
878
+ return ', ';
879
+ }
880
+ getRightExplainOptionsWrapper() {
881
+ return ')';
882
+ }
883
+ sanitizeIdentifier(identifier) {
884
+ const leftWrap = this.getLeftIdentifierWrapper();
885
+ const rightWrap = this.getRightIdentifierWrapper();
886
+ let sanitized = '';
887
+ for (const c of identifier) {
888
+ sanitized += c;
889
+ if (c === leftWrap) {
890
+ sanitized += leftWrap;
891
+ }
892
+ else if (c === rightWrap) {
893
+ sanitized += rightWrap;
894
+ }
895
+ }
896
+ return sanitized;
897
+ }
825
898
  addParameter(parameter) {
826
899
  this.#parameters.push(parameter);
827
900
  }
@@ -161,6 +161,33 @@ export declare class QueryCreator<DB> {
161
161
  * ```
162
162
  */
163
163
  insertInto<T extends keyof DB & string>(table: T): InsertQueryBuilder<DB, T, InsertResult>;
164
+ /**
165
+ * Creates a replace query.
166
+ *
167
+ * A MySQL-only statement similar to {@link InsertQueryBuilder.onDuplicateKeyUpdate}
168
+ * that deletes and inserts values on collision instead of updating existing rows.
169
+ *
170
+ * The return value of this query is an instance of {@link InsertResult}. {@link InsertResult}
171
+ * has the {@link InsertResult.insertId | insertId} field that holds the auto incremented id of
172
+ * the inserted row if the db returned one.
173
+ *
174
+ * See the {@link InsertQueryBuilder.values | values} method for more info and examples.
175
+ *
176
+ * ### Examples
177
+ *
178
+ * ```ts
179
+ * const result = await db
180
+ * .replaceInto('person')
181
+ * .values({
182
+ * first_name: 'Jennifer',
183
+ * last_name: 'Aniston'
184
+ * })
185
+ * .executeTakeFirst()
186
+ *
187
+ * console.log(result.insertId)
188
+ * ```
189
+ */
190
+ replaceInto<T extends keyof DB & string>(table: T): InsertQueryBuilder<DB, T, InsertResult>;
164
191
  /**
165
192
  * Creates a delete query.
166
193
  *
@@ -72,6 +72,39 @@ class QueryCreator {
72
72
  queryNode: insert_query_node_js_1.InsertQueryNode.create((0, table_parser_js_1.parseTable)(table), this.#props.withNode),
73
73
  });
74
74
  }
75
+ /**
76
+ * Creates a replace query.
77
+ *
78
+ * A MySQL-only statement similar to {@link InsertQueryBuilder.onDuplicateKeyUpdate}
79
+ * that deletes and inserts values on collision instead of updating existing rows.
80
+ *
81
+ * The return value of this query is an instance of {@link InsertResult}. {@link InsertResult}
82
+ * has the {@link InsertResult.insertId | insertId} field that holds the auto incremented id of
83
+ * the inserted row if the db returned one.
84
+ *
85
+ * See the {@link InsertQueryBuilder.values | values} method for more info and examples.
86
+ *
87
+ * ### Examples
88
+ *
89
+ * ```ts
90
+ * const result = await db
91
+ * .replaceInto('person')
92
+ * .values({
93
+ * first_name: 'Jennifer',
94
+ * last_name: 'Aniston'
95
+ * })
96
+ * .executeTakeFirst()
97
+ *
98
+ * console.log(result.insertId)
99
+ * ```
100
+ */
101
+ replaceInto(table) {
102
+ return new insert_query_builder_js_1.InsertQueryBuilder({
103
+ queryId: (0, query_id_js_1.createQueryId)(),
104
+ executor: this.#props.executor,
105
+ queryNode: insert_query_node_js_1.InsertQueryNode.create((0, table_parser_js_1.parseTable)(table), this.#props.withNode, true),
106
+ });
107
+ }
75
108
  /**
76
109
  * Creates a delete query.
77
110
  *
@@ -36,6 +36,12 @@ export declare abstract class QueryExecutorBase implements QueryExecutor {
36
36
  * `transformResult` method.
37
37
  */
38
38
  executeQuery<R>(compiledQuery: CompiledQuery, queryId: QueryId): Promise<QueryResult<R>>;
39
+ /**
40
+ * Executes a compiled query and runs the result through all plugins'
41
+ * `transformResult` method. Results are streamead instead of loaded
42
+ * at once.
43
+ */
44
+ stream<R>(compiledQuery: CompiledQuery, chunkSize: number, queryId: QueryId): AsyncIterableIterator<QueryResult<R>>;
39
45
  /**
40
46
  * Returns a copy of this executor with a new connection provider.
41
47
  */
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.QueryExecutorBase = void 0;
4
4
  const object_utils_js_1 = require("../util/object-utils.js");
5
+ const deferred_js_1 = require("../util/deferred.js");
5
6
  const NO_PLUGINS = (0, object_utils_js_1.freeze)([]);
6
7
  class QueryExecutorBase {
7
8
  #plugins;
@@ -36,6 +37,24 @@ class QueryExecutorBase {
36
37
  return this.#transformResult(result, queryId);
37
38
  });
38
39
  }
40
+ async *stream(compiledQuery, chunkSize, queryId) {
41
+ const connectionDefer = new deferred_js_1.Deferred();
42
+ const connectionReleaseDefer = new deferred_js_1.Deferred();
43
+ this.provideConnection(async (connection) => {
44
+ connectionDefer.resolve(connection);
45
+ // Lets wait until we don't need connection before returning here (returning releases connection)
46
+ return await connectionReleaseDefer.promise;
47
+ }).catch((ex) => connectionDefer.reject(ex));
48
+ const connection = await connectionDefer.promise;
49
+ try {
50
+ for await (const result of connection.streamQuery(compiledQuery, chunkSize)) {
51
+ yield await this.#transformResult(result, queryId);
52
+ }
53
+ }
54
+ finally {
55
+ connectionReleaseDefer.resolve();
56
+ }
57
+ }
39
58
  async #transformResult(result, queryId) {
40
59
  for (const plugin of this.#plugins) {
41
60
  result = await plugin.transformResult({ result, queryId });
@@ -37,6 +37,17 @@ export interface QueryExecutor extends ConnectionProvider {
37
37
  * `transformResult` method.
38
38
  */
39
39
  executeQuery<R>(compiledQuery: CompiledQuery, queryId: QueryId): Promise<QueryResult<R>>;
40
+ /**
41
+ * Executes a compiled query and runs the result through all plugins'
42
+ * `transformResult` method. Results are streamead instead of loaded
43
+ * at once.
44
+ */
45
+ stream<R>(compiledQuery: CompiledQuery,
46
+ /**
47
+ * How many rows should be pulled from the database at once. Supported
48
+ * only by the postgres driver.
49
+ */
50
+ chunkSize: number, queryId: QueryId): AsyncIterableIterator<QueryResult<R>>;
40
51
  /**
41
52
  * Returns a copy of this executor with a new connection provider.
42
53
  */