kysely 0.19.10 → 0.19.11

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 (62) hide show
  1. package/README.md +51 -3
  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/postgres/postgres-dialect-config.d.ts +29 -0
  6. package/dist/cjs/dialect/postgres/postgres-driver.d.ts +6 -2
  7. package/dist/cjs/dialect/postgres/postgres-driver.js +24 -2
  8. package/dist/cjs/dialect/sqlite/sqlite-driver.js +3 -0
  9. package/dist/cjs/driver/database-connection.d.ts +1 -0
  10. package/dist/cjs/driver/dummy-driver.js +3 -0
  11. package/dist/cjs/index.d.ts +4 -0
  12. package/dist/cjs/index.js +4 -0
  13. package/dist/cjs/operation-node/data-type-node.d.ts +1 -1
  14. package/dist/cjs/operation-node/insert-query-node.d.ts +2 -1
  15. package/dist/cjs/operation-node/insert-query-node.js +2 -1
  16. package/dist/cjs/operation-node/operation-node-transformer.js +1 -0
  17. package/dist/cjs/query-builder/insert-query-builder.d.ts +1 -1
  18. package/dist/cjs/query-builder/select-query-builder.d.ts +27 -0
  19. package/dist/cjs/query-builder/select-query-builder.js +34 -2
  20. package/dist/cjs/query-compiler/default-query-compiler.js +1 -1
  21. package/dist/cjs/query-creator.d.ts +27 -0
  22. package/dist/cjs/query-creator.js +33 -0
  23. package/dist/cjs/query-executor/query-executor-base.d.ts +6 -0
  24. package/dist/cjs/query-executor/query-executor-base.js +19 -0
  25. package/dist/cjs/query-executor/query-executor.d.ts +11 -0
  26. package/dist/cjs/schema/create-table-builder.d.ts +6 -6
  27. package/dist/cjs/schema/create-table-builder.js +6 -6
  28. package/dist/cjs/schema/create-type-builder.d.ts +9 -0
  29. package/dist/cjs/schema/create-type-builder.js +9 -0
  30. package/dist/cjs/util/deferred.d.ts +7 -0
  31. package/dist/cjs/util/deferred.js +28 -0
  32. package/dist/esm/dialect/mysql/mysql-dialect-config.d.ts +10 -0
  33. package/dist/esm/dialect/mysql/mysql-driver.d.ts +1 -0
  34. package/dist/esm/dialect/mysql/mysql-driver.js +25 -0
  35. package/dist/esm/dialect/postgres/postgres-dialect-config.d.ts +29 -0
  36. package/dist/esm/dialect/postgres/postgres-driver.d.ts +6 -2
  37. package/dist/esm/dialect/postgres/postgres-driver.js +24 -2
  38. package/dist/esm/dialect/sqlite/sqlite-driver.js +3 -0
  39. package/dist/esm/driver/database-connection.d.ts +1 -0
  40. package/dist/esm/driver/dummy-driver.js +3 -0
  41. package/dist/esm/index.d.ts +4 -0
  42. package/dist/esm/index.js +4 -0
  43. package/dist/esm/operation-node/data-type-node.d.ts +1 -1
  44. package/dist/esm/operation-node/insert-query-node.d.ts +2 -1
  45. package/dist/esm/operation-node/insert-query-node.js +2 -1
  46. package/dist/esm/operation-node/operation-node-transformer.js +1 -0
  47. package/dist/esm/query-builder/insert-query-builder.d.ts +1 -1
  48. package/dist/esm/query-builder/select-query-builder.d.ts +27 -0
  49. package/dist/esm/query-builder/select-query-builder.js +34 -2
  50. package/dist/esm/query-compiler/default-query-compiler.js +1 -1
  51. package/dist/esm/query-creator.d.ts +27 -0
  52. package/dist/esm/query-creator.js +33 -0
  53. package/dist/esm/query-executor/query-executor-base.d.ts +6 -0
  54. package/dist/esm/query-executor/query-executor-base.js +19 -0
  55. package/dist/esm/query-executor/query-executor.d.ts +11 -0
  56. package/dist/esm/schema/create-table-builder.d.ts +6 -6
  57. package/dist/esm/schema/create-table-builder.js +6 -6
  58. package/dist/esm/schema/create-type-builder.d.ts +9 -0
  59. package/dist/esm/schema/create-type-builder.js +9 -0
  60. package/dist/esm/util/deferred.d.ts +7 -0
  61. package/dist/esm/util/deferred.js +25 -0
  62. package/package.json +5 -2
package/README.md CHANGED
@@ -32,15 +32,21 @@ You can find a more thorough introduction [here](https://www.jakso.me/blog/kysel
32
32
  # Table of contents
33
33
 
34
34
  - [Installation](#installation)
35
+ - [3rd party dialects](#3rd-party-dialects)
35
36
  - [Minimal example](#minimal-example)
36
37
  - [Generating types](#generating-types)
37
38
  - [Query examples](#query-examples)
38
- - [Recipes](https://github.com/koskimas/kysely/tree/master/recipes)
39
+ - [Select queries](#select-queries)
40
+ - [Stream select query results](#stream-select-query-results)
41
+ - [Update queries](#update-queries)
42
+ - [Insert queries](#insert-queries)
43
+ - [Delete queries](#delete-queries)
39
44
  - [Migrations](#migrations)
45
+ - [PostgreSQL migration example](#postgresql-migration-example)
46
+ - [MySQL migration example](#mysql-migration-example)
40
47
  - [Deno](#deno)
41
48
  - [Browser](#browser)
42
- - [API reference](https://koskimas.github.io/kysely/index.html)
43
- - [Changelog](https://github.com/koskimas/kysely/releases)
49
+ - [Why not just contribute to knex](#why-not-just-contribute-to-knex)
44
50
 
45
51
  # Installation
46
52
 
@@ -180,6 +186,48 @@ You can find examples of select queries in the documentation of the
180
186
  the [where method](https://koskimas.github.io/kysely/classes/SelectQueryBuilder.html#where)
181
187
  among other places.
182
188
 
189
+ ### Stream select query results
190
+
191
+ *Currently only supported by `postgres` and `mysql` dialects.*
192
+
193
+ ```ts
194
+ import { Pool } from 'pg'
195
+ // or `import * as Cursor from 'pg-cursor'` depending on your tsconfig
196
+ import Cursor from 'pg-cursor'
197
+ import {
198
+ Kysely,
199
+ PostgresDialect,
200
+ } from 'kysely'
201
+
202
+ const db = new Kysely<Database>({
203
+ // PostgresDialect requires the Cursor dependency
204
+ dialect: new PostgresDialect({
205
+ pool: new Pool({
206
+ host: 'localhost',
207
+ database: 'kysely_test'
208
+ }),
209
+ cursor: Cursor
210
+ }),
211
+
212
+ // MysqlDialect doesn't require any special configuration
213
+ })
214
+
215
+ async function demo() {
216
+ for await (const male of db.selectFrom("person")
217
+ .selectAll()
218
+ .where("person.gender", "=", "male")
219
+ .stream()) {
220
+ console.log(`Hello mr. ${male.first_name}!`)
221
+
222
+ if (male.first_name === "John") {
223
+ // After this line the db connection is released and no more
224
+ // rows are streamed from the database to the client
225
+ break;
226
+ }
227
+ }
228
+ }
229
+ ```
230
+
183
231
  ## Update queries
184
232
 
185
233
  See the [set method](https://koskimas.github.io/kysely/classes/UpdateQueryBuilder.html#set) and the
@@ -31,9 +31,19 @@ export interface MysqlPool {
31
31
  end(callback: (error: unknown) => void): void;
32
32
  }
33
33
  export interface MysqlPoolConnection {
34
+ query(sql: string, parameters: ReadonlyArray<unknown>): {
35
+ stream: <T>(options: MysqlStreamOptions) => MysqlStream<T>;
36
+ };
34
37
  query(sql: string, parameters: ReadonlyArray<unknown>, callback: (error: unknown, result: MysqlQueryResult) => void): void;
35
38
  release(): void;
36
39
  }
40
+ export interface MysqlStreamOptions {
41
+ highWaterMark?: number;
42
+ objectMode?: boolean;
43
+ }
44
+ export interface MysqlStream<T> {
45
+ [Symbol.asyncIterator](): AsyncIterableIterator<T>;
46
+ }
37
47
  export interface MysqlOkPacket {
38
48
  affectedRows: number;
39
49
  insertId: number;
@@ -42,6 +42,7 @@ declare class MysqlConnection implements DatabaseConnection {
42
42
  #private;
43
43
  constructor(rawConnection: MysqlPoolConnection);
44
44
  executeQuery<O>(compiledQuery: CompiledQuery): Promise<QueryResult<O>>;
45
+ streamQuery<O>(compiledQuery: CompiledQuery, chunkSize: number): AsyncIterableIterator<QueryResult<O>>;
45
46
  [PRIVATE_RELEASE_METHOD](): void;
46
47
  }
47
48
  export {};
@@ -124,6 +124,31 @@ class MysqlConnection {
124
124
  });
125
125
  });
126
126
  }
127
+ async *streamQuery(compiledQuery, chunkSize) {
128
+ const stream = this.#rawConnection
129
+ .query(compiledQuery.sql, compiledQuery.parameters)
130
+ .stream({
131
+ objectMode: true,
132
+ });
133
+ try {
134
+ for await (const row of stream) {
135
+ yield {
136
+ rows: [row],
137
+ };
138
+ }
139
+ }
140
+ catch (ex) {
141
+ if (ex &&
142
+ typeof ex === 'object' &&
143
+ 'code' in ex &&
144
+ // @ts-ignore
145
+ ex.code === 'ERR_STREAM_PREMATURE_CLOSE') {
146
+ // Most likely because of https://github.com/mysqljs/mysql/blob/master/lib/protocol/sequences/Query.js#L220
147
+ return;
148
+ }
149
+ throw ex;
150
+ }
151
+ }
127
152
  [PRIVATE_RELEASE_METHOD]() {
128
153
  this.#rawConnection.release();
129
154
  }
@@ -1,4 +1,14 @@
1
1
  import { DatabaseConnection } from '../../driver/database-connection.js';
2
+ export declare type PostgresCursorConstructor = new <T>(sql: string, parameters: readonly unknown[]) => PostgresCursor<T>;
3
+ export declare type PostgresCursor<T> = {
4
+ state: 'initialized' | 'idle' | 'submitted' | 'busy';
5
+ read: (rowsCount: number) => Promise<T[]>;
6
+ } | {
7
+ state: 'done';
8
+ } | {
9
+ state: 'error';
10
+ _error: Error;
11
+ };
2
12
  /**
3
13
  * Config for the PostgreSQL dialect.
4
14
  */
@@ -11,6 +21,19 @@ export interface PostgresDialectConfig {
11
21
  * https://node-postgres.com/api/pool
12
22
  */
13
23
  pool: PostgresPool | (() => Promise<PostgresPool>);
24
+ /**
25
+ * https://github.com/brianc/node-postgres/tree/master/packages/pg-cursor
26
+ * ```ts
27
+ * import Cursor from 'pg-cursor'
28
+ * // or
29
+ * import * as Cursor from 'pg-cursor'
30
+ *
31
+ * new PostgresDialect({
32
+ * cursor: Cursor
33
+ * })
34
+ * ```
35
+ */
36
+ cursor?: PostgresCursorConstructor;
14
37
  /**
15
38
  * Called once for each created connection.
16
39
  */
@@ -30,6 +53,7 @@ export interface PostgresPool {
30
53
  }
31
54
  export interface PostgresPoolClient {
32
55
  query<R>(sql: string, parameters: ReadonlyArray<unknown>): Promise<PostgresQueryResult<R>>;
56
+ query<R>(cursor: PostgresCursor<R>): PostgresCursor<R>;
33
57
  release(): void;
34
58
  }
35
59
  export interface PostgresQueryResult<R> {
@@ -37,3 +61,8 @@ export interface PostgresQueryResult<R> {
37
61
  rowCount: number;
38
62
  rows: R[];
39
63
  }
64
+ export interface PostgresStreamOptions {
65
+ }
66
+ export interface PostgresStream<T> {
67
+ [Symbol.asyncIterator](): AsyncIterableIterator<T>;
68
+ }
@@ -1,7 +1,7 @@
1
1
  import { DatabaseConnection, QueryResult } from '../../driver/database-connection.js';
2
2
  import { Driver, TransactionSettings } from '../../driver/driver.js';
3
3
  import { CompiledQuery } from '../../query-compiler/compiled-query.js';
4
- import { PostgresDialectConfig, PostgresPoolClient } from './postgres-dialect-config.js';
4
+ import { PostgresCursorConstructor, PostgresDialectConfig, PostgresPoolClient } from './postgres-dialect-config.js';
5
5
  declare const PRIVATE_RELEASE_METHOD: unique symbol;
6
6
  export declare class PostgresDriver implements Driver {
7
7
  #private;
@@ -38,10 +38,14 @@ export declare class PostgresDriver implements Driver {
38
38
  */
39
39
  destroy(): Promise<void>;
40
40
  }
41
+ interface PostgresConnectionOptions {
42
+ cursor: PostgresCursorConstructor | null;
43
+ }
41
44
  declare class PostgresConnection implements DatabaseConnection {
42
45
  #private;
43
- constructor(client: PostgresPoolClient);
46
+ constructor(client: PostgresPoolClient, options: PostgresConnectionOptions);
44
47
  executeQuery<O>(compiledQuery: CompiledQuery): Promise<QueryResult<O>>;
48
+ streamQuery<O>(compiledQuery: CompiledQuery, chunkSize: number): AsyncIterableIterator<QueryResult<O>>;
45
49
  [PRIVATE_RELEASE_METHOD](): void;
46
50
  }
47
51
  export {};
@@ -21,7 +21,9 @@ class PostgresDriver {
21
21
  const client = await this.#pool.connect();
22
22
  let connection = this.#connections.get(client);
23
23
  if (!connection) {
24
- connection = new PostgresConnection(client);
24
+ connection = new PostgresConnection(client, {
25
+ cursor: this.#config.cursor ?? null,
26
+ });
25
27
  this.#connections.set(client, connection);
26
28
  // The driver must take care of calling `onCreateConnection` when a new
27
29
  // connection is created. The `pg` module doesn't provide an async hook
@@ -60,8 +62,10 @@ class PostgresDriver {
60
62
  exports.PostgresDriver = PostgresDriver;
61
63
  class PostgresConnection {
62
64
  #client;
63
- constructor(client) {
65
+ #options;
66
+ constructor(client, options) {
64
67
  this.#client = client;
68
+ this.#options = options;
65
69
  }
66
70
  async executeQuery(compiledQuery) {
67
71
  try {
@@ -82,6 +86,24 @@ class PostgresConnection {
82
86
  throw (0, stack_trace_utils_js_1.extendStackTrace)(err, new Error());
83
87
  }
84
88
  }
89
+ async *streamQuery(compiledQuery, chunkSize) {
90
+ if (!this.#options.cursor) {
91
+ throw new Error("'cursor' is not present in your postgres dialect config. It's required to make streaming work in postgres.");
92
+ }
93
+ const cursor = this.#client.query(new this.#options.cursor(compiledQuery.sql, compiledQuery.parameters));
94
+ while (true) {
95
+ if (cursor.state === 'done') {
96
+ break;
97
+ }
98
+ if (cursor.state === 'error') {
99
+ throw cursor._error;
100
+ }
101
+ const rows = await cursor.read(chunkSize);
102
+ yield {
103
+ rows,
104
+ };
105
+ }
106
+ }
85
107
  [PRIVATE_RELEASE_METHOD]() {
86
108
  this.#client.release();
87
109
  }
@@ -69,6 +69,9 @@ class SqliteConnection {
69
69
  });
70
70
  }
71
71
  }
72
+ async *streamQuery() {
73
+ throw new Error("Sqlite driver doesn't support streaming");
74
+ }
72
75
  }
73
76
  class ConnectionMutex {
74
77
  #promise;
@@ -6,6 +6,7 @@ import { CompiledQuery } from '../query-compiler/compiled-query.js';
6
6
  */
7
7
  export interface DatabaseConnection {
8
8
  executeQuery<R>(compiledQuery: CompiledQuery): Promise<QueryResult<R>>;
9
+ streamQuery<R>(compiledQuery: CompiledQuery, chunkSize?: number): AsyncIterableIterator<QueryResult<R>>;
9
10
  }
10
11
  export interface QueryResult<O> {
11
12
  /**
@@ -67,4 +67,7 @@ class DummyConnection {
67
67
  rows: [],
68
68
  };
69
69
  }
70
+ async *streamQuery() {
71
+ // Nothing to do here.
72
+ }
70
73
  }
@@ -25,7 +25,9 @@ export * from './query-compiler/default-query-compiler.js';
25
25
  export * from './query-compiler/compiled-query.js';
26
26
  export * from './schema/schema.js';
27
27
  export * from './schema/create-table-builder.js';
28
+ export * from './schema/create-type-builder.js';
28
29
  export * from './schema/drop-table-builder.js';
30
+ export * from './schema/drop-type-builder.js';
29
31
  export * from './schema/create-index-builder.js';
30
32
  export * from './schema/drop-index-builder.js';
31
33
  export * from './schema/create-schema-builder.js';
@@ -87,6 +89,7 @@ export * from './operation-node/constraint-node.js';
87
89
  export * from './operation-node/create-index-node.js';
88
90
  export * from './operation-node/create-schema-node.js';
89
91
  export * from './operation-node/create-table-node.js';
92
+ export * from './operation-node/create-type-node.js';
90
93
  export * from './operation-node/create-view-node.js';
91
94
  export * from './operation-node/data-type-node.js';
92
95
  export * from './operation-node/default-value-node.js';
@@ -96,6 +99,7 @@ export * from './operation-node/drop-constraint-node.js';
96
99
  export * from './operation-node/drop-index-node.js';
97
100
  export * from './operation-node/drop-schema-node.js';
98
101
  export * from './operation-node/drop-table-node.js';
102
+ export * from './operation-node/drop-type-node.js';
99
103
  export * from './operation-node/drop-view-node.js';
100
104
  export * from './operation-node/filter-node.js';
101
105
  export * from './operation-node/foreign-key-constraint-node.js';
package/dist/cjs/index.js CHANGED
@@ -41,7 +41,9 @@ __exportStar(require("./query-compiler/default-query-compiler.js"), exports);
41
41
  __exportStar(require("./query-compiler/compiled-query.js"), exports);
42
42
  __exportStar(require("./schema/schema.js"), exports);
43
43
  __exportStar(require("./schema/create-table-builder.js"), exports);
44
+ __exportStar(require("./schema/create-type-builder.js"), exports);
44
45
  __exportStar(require("./schema/drop-table-builder.js"), exports);
46
+ __exportStar(require("./schema/drop-type-builder.js"), exports);
45
47
  __exportStar(require("./schema/create-index-builder.js"), exports);
46
48
  __exportStar(require("./schema/drop-index-builder.js"), exports);
47
49
  __exportStar(require("./schema/create-schema-builder.js"), exports);
@@ -103,6 +105,7 @@ __exportStar(require("./operation-node/constraint-node.js"), exports);
103
105
  __exportStar(require("./operation-node/create-index-node.js"), exports);
104
106
  __exportStar(require("./operation-node/create-schema-node.js"), exports);
105
107
  __exportStar(require("./operation-node/create-table-node.js"), exports);
108
+ __exportStar(require("./operation-node/create-type-node.js"), exports);
106
109
  __exportStar(require("./operation-node/create-view-node.js"), exports);
107
110
  __exportStar(require("./operation-node/data-type-node.js"), exports);
108
111
  __exportStar(require("./operation-node/default-value-node.js"), exports);
@@ -112,6 +115,7 @@ __exportStar(require("./operation-node/drop-constraint-node.js"), exports);
112
115
  __exportStar(require("./operation-node/drop-index-node.js"), exports);
113
116
  __exportStar(require("./operation-node/drop-schema-node.js"), exports);
114
117
  __exportStar(require("./operation-node/drop-table-node.js"), exports);
118
+ __exportStar(require("./operation-node/drop-type-node.js"), exports);
115
119
  __exportStar(require("./operation-node/drop-view-node.js"), exports);
116
120
  __exportStar(require("./operation-node/filter-node.js"), exports);
117
121
  __exportStar(require("./operation-node/foreign-key-constraint-node.js"), exports);
@@ -1,5 +1,5 @@
1
1
  import { OperationNode } from './operation-node.js';
2
- export declare type ColumnDataType = 'varchar' | `varchar(${number})` | 'text' | 'integer' | 'int2' | 'int4' | 'int8' | 'bigint' | 'boolean' | 'real' | 'double precision' | 'float4' | 'float8' | 'decimal' | `decimal(${number}, ${number})` | 'numeric' | `numeric(${number}, ${number})` | 'binary' | 'date' | 'datetime' | 'time' | 'timetz' | 'timestamp' | 'timestamptz' | 'serial' | 'bigserial' | 'uuid' | 'json' | 'jsonb' | 'blob';
2
+ export declare type ColumnDataType = 'varchar' | `varchar(${number})` | 'text' | 'integer' | 'int2' | 'int4' | 'int8' | 'bigint' | 'boolean' | 'real' | 'double precision' | 'float4' | 'float8' | 'decimal' | `decimal(${number}, ${number})` | 'numeric' | `numeric(${number}, ${number})` | 'binary' | 'date' | 'datetime' | `datetime(${number})` | 'time' | `time(${number})` | 'timetz' | `timetz(${number})` | 'timestamp' | `timestamp(${number})` | 'timestamptz' | `timestamptz(${number})` | 'serial' | 'bigserial' | 'uuid' | 'json' | 'jsonb' | 'blob';
3
3
  export declare type DataTypeParams = Omit<DataTypeNode, 'kind' | 'dataType'>;
4
4
  export interface DataTypeNode extends OperationNode {
5
5
  readonly kind: 'DataTypeNode';
@@ -19,12 +19,13 @@ export interface InsertQueryNode extends OperationNode {
19
19
  readonly onDuplicateKey?: OnDuplicateKeyNode;
20
20
  readonly with?: WithNode;
21
21
  readonly ignore?: boolean;
22
+ readonly replace?: boolean;
22
23
  }
23
24
  /**
24
25
  * @internal
25
26
  */
26
27
  export declare const InsertQueryNode: Readonly<{
27
28
  is(node: OperationNode): node is InsertQueryNode;
28
- create(into: TableNode, withNode?: WithNode): InsertQueryNode;
29
+ create(into: TableNode, withNode?: WithNode, replace?: boolean): InsertQueryNode;
29
30
  cloneWith(insertQuery: InsertQueryNode, props: InsertQueryNodeProps): InsertQueryNode;
30
31
  }>;
@@ -9,11 +9,12 @@ exports.InsertQueryNode = (0, object_utils_js_1.freeze)({
9
9
  is(node) {
10
10
  return node.kind === 'InsertQueryNode';
11
11
  },
12
- create(into, withNode) {
12
+ create(into, withNode, replace) {
13
13
  return (0, object_utils_js_1.freeze)({
14
14
  kind: 'InsertQueryNode',
15
15
  into,
16
16
  ...(withNode && { with: withNode }),
17
+ replace,
17
18
  });
18
19
  },
19
20
  cloneWith(insertQuery, props) {
@@ -244,6 +244,7 @@ class OperationNodeTransformer {
244
244
  onDuplicateKey: this.transformNode(node.onDuplicateKey),
245
245
  with: this.transformNode(node.with),
246
246
  ignore: node.ignore,
247
+ replace: node.replace,
247
248
  });
248
249
  }
249
250
  transformValues(node) {
@@ -43,7 +43,7 @@ export declare class InsertQueryBuilder<DB, TB extends keyof DB, O> implements R
43
43
  *
44
44
  * Insert a row into `person`:
45
45
  * ```ts
46
- * const id = await db
46
+ * const result = await db
47
47
  * .insertInto('person')
48
48
  * .values({
49
49
  * first_name: 'Jennifer',
@@ -1343,6 +1343,33 @@ export declare class SelectQueryBuilder<DB, TB extends keyof DB, O> implements W
1343
1343
  * error.
1344
1344
  */
1345
1345
  executeTakeFirstOrThrow(errorConstructor?: NoResultErrorConstructor): Promise<O>;
1346
+ /**
1347
+ * Executes the query and streams the rows.
1348
+ *
1349
+ * The optional argument `chunkSize` defines how many rows to fetch from the database
1350
+ * at a time. It only affects some dialects like PostgreSQL that support it.
1351
+ *
1352
+ * ### Examples
1353
+ *
1354
+ * ```ts
1355
+ * const stream = db.
1356
+ * .selectFrom('person')
1357
+ * .select(['first_name', 'last_name'])
1358
+ * .where('gender', '=', 'other')
1359
+ * .stream()
1360
+ *
1361
+ * for await (const person of stream) {
1362
+ * console.log(person.first_name)
1363
+ *
1364
+ * if (person.last_name === 'Something') {
1365
+ * // Breaking or returning before the stream has ended will release
1366
+ * // the database connection and invalidate the stream.
1367
+ * break
1368
+ * }
1369
+ * }
1370
+ * ```
1371
+ */
1372
+ stream(chunkSize?: number): AsyncIterableIterator<O>;
1346
1373
  }
1347
1374
  export interface SelectQueryBuilderProps {
1348
1375
  readonly queryId: QueryId;
@@ -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,6 @@ 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
20
  class SelectQueryBuilder {
21
21
  #props;
22
22
  constructor(props) {
@@ -630,7 +630,6 @@ class SelectQueryBuilder {
630
630
  */
631
631
  async execute() {
632
632
  const compildQuery = this.compile();
633
- const query = compildQuery.query;
634
633
  const result = await this.#props.executor.executeQuery(compildQuery, this.#props.queryId);
635
634
  return result.rows;
636
635
  }
@@ -657,6 +656,39 @@ class SelectQueryBuilder {
657
656
  }
658
657
  return result;
659
658
  }
659
+ /**
660
+ * Executes the query and streams the rows.
661
+ *
662
+ * The optional argument `chunkSize` defines how many rows to fetch from the database
663
+ * at a time. It only affects some dialects like PostgreSQL that support it.
664
+ *
665
+ * ### Examples
666
+ *
667
+ * ```ts
668
+ * const stream = db.
669
+ * .selectFrom('person')
670
+ * .select(['first_name', 'last_name'])
671
+ * .where('gender', '=', 'other')
672
+ * .stream()
673
+ *
674
+ * for await (const person of stream) {
675
+ * console.log(person.first_name)
676
+ *
677
+ * if (person.last_name === 'Something') {
678
+ * // Breaking or returning before the stream has ended will release
679
+ * // the database connection and invalidate the stream.
680
+ * break
681
+ * }
682
+ * }
683
+ * ```
684
+ */
685
+ async *stream(chunkSize = 100) {
686
+ const compildQuery = this.compile();
687
+ const stream = this.#props.executor.stream(compildQuery, chunkSize, this.#props.queryId);
688
+ for await (const item of stream) {
689
+ yield* item.rows;
690
+ }
691
+ }
660
692
  }
661
693
  exports.SelectQueryBuilder = SelectQueryBuilder;
662
694
  (0, prevent_await_js_1.preventAwait)(SelectQueryBuilder, "don't await SelectQueryBuilder instances directly. To execute the query you need to call `execute` or `executeTakeFirst`.");
@@ -134,7 +134,7 @@ class DefaultQueryCompiler extends operation_node_visitor_js_1.OperationNodeVisi
134
134
  this.visitNode(node.with);
135
135
  this.append(' ');
136
136
  }
137
- this.append('insert');
137
+ this.append(node.replace ? 'replace' : 'insert');
138
138
  if (node.ignore) {
139
139
  this.append(' ignore');
140
140
  }
@@ -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
  */