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.
- package/README.md +51 -3
- package/dist/cjs/dialect/mysql/mysql-dialect-config.d.ts +10 -0
- package/dist/cjs/dialect/mysql/mysql-driver.d.ts +1 -0
- package/dist/cjs/dialect/mysql/mysql-driver.js +25 -0
- package/dist/cjs/dialect/postgres/postgres-dialect-config.d.ts +29 -0
- package/dist/cjs/dialect/postgres/postgres-driver.d.ts +6 -2
- package/dist/cjs/dialect/postgres/postgres-driver.js +24 -2
- package/dist/cjs/dialect/sqlite/sqlite-driver.js +3 -0
- package/dist/cjs/driver/database-connection.d.ts +1 -0
- package/dist/cjs/driver/dummy-driver.js +3 -0
- package/dist/cjs/index.d.ts +4 -0
- package/dist/cjs/index.js +4 -0
- package/dist/cjs/operation-node/data-type-node.d.ts +1 -1
- package/dist/cjs/operation-node/insert-query-node.d.ts +2 -1
- package/dist/cjs/operation-node/insert-query-node.js +2 -1
- package/dist/cjs/operation-node/operation-node-transformer.js +1 -0
- package/dist/cjs/query-builder/insert-query-builder.d.ts +1 -1
- package/dist/cjs/query-builder/select-query-builder.d.ts +27 -0
- package/dist/cjs/query-builder/select-query-builder.js +34 -2
- package/dist/cjs/query-compiler/default-query-compiler.js +1 -1
- package/dist/cjs/query-creator.d.ts +27 -0
- package/dist/cjs/query-creator.js +33 -0
- package/dist/cjs/query-executor/query-executor-base.d.ts +6 -0
- package/dist/cjs/query-executor/query-executor-base.js +19 -0
- package/dist/cjs/query-executor/query-executor.d.ts +11 -0
- package/dist/cjs/schema/create-table-builder.d.ts +6 -6
- package/dist/cjs/schema/create-table-builder.js +6 -6
- package/dist/cjs/schema/create-type-builder.d.ts +9 -0
- package/dist/cjs/schema/create-type-builder.js +9 -0
- package/dist/cjs/util/deferred.d.ts +7 -0
- package/dist/cjs/util/deferred.js +28 -0
- package/dist/esm/dialect/mysql/mysql-dialect-config.d.ts +10 -0
- package/dist/esm/dialect/mysql/mysql-driver.d.ts +1 -0
- package/dist/esm/dialect/mysql/mysql-driver.js +25 -0
- package/dist/esm/dialect/postgres/postgres-dialect-config.d.ts +29 -0
- package/dist/esm/dialect/postgres/postgres-driver.d.ts +6 -2
- package/dist/esm/dialect/postgres/postgres-driver.js +24 -2
- package/dist/esm/dialect/sqlite/sqlite-driver.js +3 -0
- package/dist/esm/driver/database-connection.d.ts +1 -0
- package/dist/esm/driver/dummy-driver.js +3 -0
- package/dist/esm/index.d.ts +4 -0
- package/dist/esm/index.js +4 -0
- package/dist/esm/operation-node/data-type-node.d.ts +1 -1
- package/dist/esm/operation-node/insert-query-node.d.ts +2 -1
- package/dist/esm/operation-node/insert-query-node.js +2 -1
- package/dist/esm/operation-node/operation-node-transformer.js +1 -0
- package/dist/esm/query-builder/insert-query-builder.d.ts +1 -1
- package/dist/esm/query-builder/select-query-builder.d.ts +27 -0
- package/dist/esm/query-builder/select-query-builder.js +34 -2
- package/dist/esm/query-compiler/default-query-compiler.js +1 -1
- package/dist/esm/query-creator.d.ts +27 -0
- package/dist/esm/query-creator.js +33 -0
- package/dist/esm/query-executor/query-executor-base.d.ts +6 -0
- package/dist/esm/query-executor/query-executor-base.js +19 -0
- package/dist/esm/query-executor/query-executor.d.ts +11 -0
- package/dist/esm/schema/create-table-builder.d.ts +6 -6
- package/dist/esm/schema/create-table-builder.js +6 -6
- package/dist/esm/schema/create-type-builder.d.ts +9 -0
- package/dist/esm/schema/create-type-builder.js +9 -0
- package/dist/esm/util/deferred.d.ts +7 -0
- package/dist/esm/util/deferred.js +25 -0
- 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
|
-
- [
|
|
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
|
-
- [
|
|
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
|
-
|
|
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
|
}
|
|
@@ -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
|
/**
|
package/dist/cjs/index.d.ts
CHANGED
|
@@ -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) {
|
|
@@ -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
|
*/
|