kysely 0.12.1 → 0.12.2
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/dist/cjs/index.d.ts +1 -0
- package/dist/cjs/index.js +1 -0
- package/dist/cjs/kysely.d.ts +151 -0
- package/dist/cjs/kysely.js +37 -0
- package/dist/cjs/operation-node/common-table-expression-name-node.d.ts +15 -0
- package/dist/cjs/operation-node/common-table-expression-name-node.js +23 -0
- package/dist/cjs/operation-node/common-table-expression-node.d.ts +3 -3
- package/dist/cjs/operation-node/operation-node-transformer.d.ts +2 -0
- package/dist/cjs/operation-node/operation-node-transformer.js +9 -0
- package/dist/cjs/operation-node/operation-node-visitor.d.ts +2 -0
- package/dist/cjs/operation-node/operation-node-visitor.js +1 -0
- package/dist/cjs/operation-node/operation-node.d.ts +1 -1
- package/dist/cjs/operation-node/with-node.d.ts +3 -1
- package/dist/cjs/operation-node/with-node.js +2 -1
- package/dist/cjs/parser/with-parser.d.ts +32 -5
- package/dist/cjs/parser/with-parser.js +13 -2
- package/dist/cjs/plugin/with-schema/with-schema-transformer.js +8 -0
- package/dist/cjs/query-compiler/default-query-compiler.d.ts +2 -0
- package/dist/cjs/query-compiler/default-query-compiler.js +11 -0
- package/dist/cjs/query-creator.d.ts +27 -3
- package/dist/cjs/query-creator.js +33 -1
- package/dist/cjs/query-executor/default-query-executor.d.ts +19 -0
- package/dist/cjs/query-executor/noop-query-executor.d.ts +19 -0
- package/dist/cjs/raw-builder/raw-builder.js +1 -1
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/kysely.d.ts +151 -0
- package/dist/esm/kysely.js +37 -0
- package/dist/esm/operation-node/common-table-expression-name-node.d.ts +15 -0
- package/dist/esm/operation-node/common-table-expression-name-node.js +20 -0
- package/dist/esm/operation-node/common-table-expression-node.d.ts +3 -3
- package/dist/esm/operation-node/operation-node-transformer.d.ts +2 -0
- package/dist/esm/operation-node/operation-node-transformer.js +9 -0
- package/dist/esm/operation-node/operation-node-visitor.d.ts +2 -0
- package/dist/esm/operation-node/operation-node-visitor.js +1 -0
- package/dist/esm/operation-node/operation-node.d.ts +1 -1
- package/dist/esm/operation-node/with-node.d.ts +3 -1
- package/dist/esm/operation-node/with-node.js +2 -1
- package/dist/esm/parser/with-parser.d.ts +32 -5
- package/dist/esm/parser/with-parser.js +13 -2
- package/dist/esm/plugin/with-schema/with-schema-transformer.js +8 -0
- package/dist/esm/query-compiler/default-query-compiler.d.ts +2 -0
- package/dist/esm/query-compiler/default-query-compiler.js +11 -0
- package/dist/esm/query-creator.d.ts +27 -3
- package/dist/esm/query-creator.js +33 -1
- package/dist/esm/query-executor/default-query-executor.d.ts +19 -0
- package/dist/esm/query-executor/noop-query-executor.d.ts +19 -0
- package/dist/esm/raw-builder/raw-builder.js +1 -1
- package/package.json +2 -2
|
@@ -136,7 +136,7 @@ class QueryCreator {
|
|
|
136
136
|
});
|
|
137
137
|
}
|
|
138
138
|
/**
|
|
139
|
-
* Creates a `with` query (
|
|
139
|
+
* Creates a `with` query (Common Table Expression).
|
|
140
140
|
*
|
|
141
141
|
* ### Examples
|
|
142
142
|
*
|
|
@@ -157,6 +157,24 @@ class QueryCreator {
|
|
|
157
157
|
* .selectAll()
|
|
158
158
|
* .execute()
|
|
159
159
|
* ```
|
|
160
|
+
*
|
|
161
|
+
* The CTE name can optionally specify column names in addition to
|
|
162
|
+
* a name. In that case Kysely requires the expression to retun
|
|
163
|
+
* rows with the same columns.
|
|
164
|
+
*
|
|
165
|
+
* ```ts
|
|
166
|
+
* await db
|
|
167
|
+
* .with('jennifers(id, age)', (db) => db
|
|
168
|
+
* .selectFrom('person')
|
|
169
|
+
* .where('first_name', '=', 'Jennifer')
|
|
170
|
+
* // This is ok since we return columns with the same
|
|
171
|
+
* // names as specified by `jennifers(id, age)`.
|
|
172
|
+
* .select(['id', 'age'])
|
|
173
|
+
* )
|
|
174
|
+
* .selectFrom('jennifers')
|
|
175
|
+
* .selectAll()
|
|
176
|
+
* .execute()
|
|
177
|
+
* ```
|
|
160
178
|
*/
|
|
161
179
|
with(name, expression) {
|
|
162
180
|
const cte = (0, with_parser_js_1.parseCommonTableExpression)(this.#props.parseContext, name, expression);
|
|
@@ -167,6 +185,20 @@ class QueryCreator {
|
|
|
167
185
|
: with_node_js_1.WithNode.create(cte),
|
|
168
186
|
});
|
|
169
187
|
}
|
|
188
|
+
/**
|
|
189
|
+
* Creates a recursive `with` query (Common Table Expression).
|
|
190
|
+
*
|
|
191
|
+
* See the {@link with} method for examples and more documentation.
|
|
192
|
+
*/
|
|
193
|
+
withRecursive(name, expression) {
|
|
194
|
+
const cte = (0, with_parser_js_1.parseCommonTableExpression)(this.#props.parseContext, name, expression);
|
|
195
|
+
return new QueryCreator({
|
|
196
|
+
...this.#props,
|
|
197
|
+
withNode: this.#props.withNode
|
|
198
|
+
? with_node_js_1.WithNode.cloneWithExpression(this.#props.withNode, cte)
|
|
199
|
+
: with_node_js_1.WithNode.create(cte, { recursive: true }),
|
|
200
|
+
});
|
|
201
|
+
}
|
|
170
202
|
/**
|
|
171
203
|
* Sets the schema to be used for all table references that don't explicitly
|
|
172
204
|
* specify a schema.
|
|
@@ -7,10 +7,29 @@ import { QueryExecutor } from './query-executor.js';
|
|
|
7
7
|
export declare class DefaultQueryExecutor extends QueryExecutor {
|
|
8
8
|
#private;
|
|
9
9
|
constructor(compiler: QueryCompiler, connectionProvider: ConnectionProvider, plugins?: KyselyPlugin[]);
|
|
10
|
+
/**
|
|
11
|
+
* Compiles the transformed query into SQL. You usually want to pass
|
|
12
|
+
* the output of {@link transformQuery} into this method but you can
|
|
13
|
+
* compile any query using this method.
|
|
14
|
+
*/
|
|
10
15
|
compileQuery(node: RootOperationNode): CompiledQuery;
|
|
11
16
|
protected executeQueryImpl<R>(compiledQuery: CompiledQuery): Promise<QueryResult<R>>;
|
|
17
|
+
/**
|
|
18
|
+
* Returns a copy of this executor with a plugin added as the
|
|
19
|
+
* last plugin.
|
|
20
|
+
*/
|
|
12
21
|
withPlugin(plugin: KyselyPlugin): DefaultQueryExecutor;
|
|
22
|
+
/**
|
|
23
|
+
* Returns a copy of this executor with a plugin added as the
|
|
24
|
+
* first plugin.
|
|
25
|
+
*/
|
|
13
26
|
withPluginAtFront(plugin: KyselyPlugin): DefaultQueryExecutor;
|
|
27
|
+
/**
|
|
28
|
+
* Returns a copy of this executor with a new connection provider.
|
|
29
|
+
*/
|
|
14
30
|
withConnectionProvider(connectionProvider: ConnectionProvider): QueryExecutor;
|
|
31
|
+
/**
|
|
32
|
+
* Returns a copy of this executor without any plugins.
|
|
33
|
+
*/
|
|
15
34
|
withoutPlugins(): QueryExecutor;
|
|
16
35
|
}
|
|
@@ -8,10 +8,29 @@ import { KyselyPlugin } from '../plugin/kysely-plugin.js';
|
|
|
8
8
|
* other needed things to actually execute queries.
|
|
9
9
|
*/
|
|
10
10
|
export declare class NoopQueryExecutor extends QueryExecutor {
|
|
11
|
+
/**
|
|
12
|
+
* Compiles the transformed query into SQL. You usually want to pass
|
|
13
|
+
* the output of {@link transformQuery} into this method but you can
|
|
14
|
+
* compile any query using this method.
|
|
15
|
+
*/
|
|
11
16
|
compileQuery(): CompiledQuery;
|
|
12
17
|
protected executeQueryImpl<R>(): Promise<QueryResult<R>>;
|
|
18
|
+
/**
|
|
19
|
+
* Returns a copy of this executor with a new connection provider.
|
|
20
|
+
*/
|
|
13
21
|
withConnectionProvider(): QueryExecutor;
|
|
22
|
+
/**
|
|
23
|
+
* Returns a copy of this executor with a plugin added as the
|
|
24
|
+
* last plugin.
|
|
25
|
+
*/
|
|
14
26
|
withPlugin(plugin: KyselyPlugin): NoopQueryExecutor;
|
|
27
|
+
/**
|
|
28
|
+
* Returns a copy of this executor with a plugin added as the
|
|
29
|
+
* first plugin.
|
|
30
|
+
*/
|
|
15
31
|
withPluginAtFront(plugin: KyselyPlugin): NoopQueryExecutor;
|
|
32
|
+
/**
|
|
33
|
+
* Returns a copy of this executor without any plugins.
|
|
34
|
+
*/
|
|
16
35
|
withoutPlugins(): QueryExecutor;
|
|
17
36
|
}
|
|
@@ -50,7 +50,7 @@ class RawBuilder {
|
|
|
50
50
|
if (match.index > 0 && sql[match.index - 1] === '\\') {
|
|
51
51
|
continue;
|
|
52
52
|
}
|
|
53
|
-
sqlFragments.push(sql.slice(sqlIdx, match.index).
|
|
53
|
+
sqlFragments.push(sql.slice(sqlIdx, match.index).replace(/\\\?/g, '?'));
|
|
54
54
|
argNodes.push(parseRawArg(str, parameters[paramIdx]));
|
|
55
55
|
sqlIdx = match.index + str.length;
|
|
56
56
|
++paramIdx;
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -73,6 +73,7 @@ export * from './operation-node/column-definition-node.js';
|
|
|
73
73
|
export * from './operation-node/column-node.js';
|
|
74
74
|
export * from './operation-node/column-update-node.js';
|
|
75
75
|
export * from './operation-node/common-table-expression-node.js';
|
|
76
|
+
export * from './operation-node/common-table-expression-name-node.js';
|
|
76
77
|
export * from './operation-node/constraint-node.js';
|
|
77
78
|
export * from './operation-node/create-index-node.js';
|
|
78
79
|
export * from './operation-node/create-schema-node.js';
|
package/dist/esm/index.js
CHANGED
|
@@ -73,6 +73,7 @@ export * from './operation-node/column-definition-node.js';
|
|
|
73
73
|
export * from './operation-node/column-node.js';
|
|
74
74
|
export * from './operation-node/column-update-node.js';
|
|
75
75
|
export * from './operation-node/common-table-expression-node.js';
|
|
76
|
+
export * from './operation-node/common-table-expression-name-node.js';
|
|
76
77
|
export * from './operation-node/constraint-node.js';
|
|
77
78
|
export * from './operation-node/create-index-node.js';
|
|
78
79
|
export * from './operation-node/create-schema-node.js';
|
package/dist/esm/kysely.d.ts
CHANGED
|
@@ -207,6 +207,38 @@ export declare class Kysely<DB> extends QueryCreator<DB> {
|
|
|
207
207
|
* Returns a copy of this Kysely instance without any plugins.
|
|
208
208
|
*/
|
|
209
209
|
withoutPlugins(): Kysely<DB>;
|
|
210
|
+
/**
|
|
211
|
+
* Returns a copy of this Kysely instance with tables added to its
|
|
212
|
+
* database type.
|
|
213
|
+
*
|
|
214
|
+
* This method only modifies the types and doesn't affect any of the
|
|
215
|
+
* executed queries in any way.
|
|
216
|
+
*
|
|
217
|
+
* ### Examples
|
|
218
|
+
*
|
|
219
|
+
* The following example adds and uses a temporary table:
|
|
220
|
+
*
|
|
221
|
+
* @example
|
|
222
|
+
* ```ts
|
|
223
|
+
* await db.schema
|
|
224
|
+
* .createTable('temp_table')
|
|
225
|
+
* .temporary()
|
|
226
|
+
* .addColumn('some_column', 'integer')
|
|
227
|
+
* .execute()
|
|
228
|
+
*
|
|
229
|
+
* const tempDb = db.withTables<{
|
|
230
|
+
* temp_table: {
|
|
231
|
+
* some_column: number
|
|
232
|
+
* }
|
|
233
|
+
* }>()
|
|
234
|
+
*
|
|
235
|
+
* await tempDb
|
|
236
|
+
* .insertInto('temp_table')
|
|
237
|
+
* .values({ some_column: 100 })
|
|
238
|
+
* .execute()
|
|
239
|
+
* ```
|
|
240
|
+
*/
|
|
241
|
+
withTables<T extends Record<string, Record<string, any>>>(): Kysely<DB & T>;
|
|
210
242
|
/**
|
|
211
243
|
* Releases all resources and disconnects from the database.
|
|
212
244
|
*
|
|
@@ -223,13 +255,132 @@ export declare class Kysely<DB> extends QueryCreator<DB> {
|
|
|
223
255
|
export declare class Transaction<DB> extends Kysely<DB> {
|
|
224
256
|
#private;
|
|
225
257
|
constructor(props: KyselyProps);
|
|
258
|
+
/**
|
|
259
|
+
* Returns true if this `Kysely` instance is a transaction.
|
|
260
|
+
*
|
|
261
|
+
* You can also use `db instanceof Transaction`.
|
|
262
|
+
*/
|
|
226
263
|
get isTransaction(): true;
|
|
264
|
+
/**
|
|
265
|
+
* Returns the {@link MigrationModule} module for managing and running migrations.
|
|
266
|
+
*/
|
|
227
267
|
get migration(): MigrationModule;
|
|
268
|
+
/**
|
|
269
|
+
* Creates a {@link TransactionBuilder} that can be used to run queries inside a transaction.
|
|
270
|
+
*
|
|
271
|
+
* The returned {@link TransactionBuilder} can be used to configure the transaction. The
|
|
272
|
+
* {@link TransactionBuilder.execute} method can then be called to run the transaction.
|
|
273
|
+
* {@link TransactionBuilder.execute} takes a function that is run inside the
|
|
274
|
+
* transaction. If the function throws, the transaction is rolled back. Otherwise
|
|
275
|
+
* the transaction is committed.
|
|
276
|
+
*
|
|
277
|
+
* The callback function passed to the {@link TransactionBuilder.execute | execute}
|
|
278
|
+
* method gets the transaction object as its only argument. The transaction is
|
|
279
|
+
* of type {@link Transaction} which inherits {@link Kysely}. Any query
|
|
280
|
+
* started through the transaction object is executed inside the transaction.
|
|
281
|
+
*
|
|
282
|
+
* ### Examples
|
|
283
|
+
*
|
|
284
|
+
* ```ts
|
|
285
|
+
* const catto = await db.transaction().execute(async (trx) => {
|
|
286
|
+
* const jennifer = await trx.insertInto('person')
|
|
287
|
+
* .values({
|
|
288
|
+
* id: db.generated,
|
|
289
|
+
* first_name: 'Jennifer',
|
|
290
|
+
* last_name: 'Aniston',
|
|
291
|
+
* })
|
|
292
|
+
* .returning('id')
|
|
293
|
+
* .executeTakeFirstOrThrow()
|
|
294
|
+
*
|
|
295
|
+
* await someFunction(trx, jennifer)
|
|
296
|
+
*
|
|
297
|
+
* return await trx.insertInto('pet')
|
|
298
|
+
* .values({
|
|
299
|
+
* id: db.generated,
|
|
300
|
+
* user_id: jennifer.id,
|
|
301
|
+
* name: 'Catto',
|
|
302
|
+
* species: 'cat'
|
|
303
|
+
* })
|
|
304
|
+
* .returning('*')
|
|
305
|
+
* .executeTakeFirst()
|
|
306
|
+
* })
|
|
307
|
+
* ```
|
|
308
|
+
*
|
|
309
|
+
* Setting the isolation level:
|
|
310
|
+
*
|
|
311
|
+
* ```ts
|
|
312
|
+
* await db
|
|
313
|
+
* .transaction()
|
|
314
|
+
* .setIsolationLevel('serializable')
|
|
315
|
+
* .execute(async (trx) => {
|
|
316
|
+
* await doStuff(trx)
|
|
317
|
+
* })
|
|
318
|
+
* ```
|
|
319
|
+
*/
|
|
228
320
|
transaction(): TransactionBuilder<DB>;
|
|
321
|
+
/**
|
|
322
|
+
* Provides a kysely instance bound to a single database connection.
|
|
323
|
+
*
|
|
324
|
+
* ### Examples
|
|
325
|
+
*
|
|
326
|
+
* ```ts
|
|
327
|
+
* await db
|
|
328
|
+
* .connection()
|
|
329
|
+
* .execute(async (db) => {
|
|
330
|
+
* // `db` is an instance of `Kysely` that's bound to a single
|
|
331
|
+
* // database connection. All queries executed through `db` use
|
|
332
|
+
* // the same connection.
|
|
333
|
+
* await doStuff(db)
|
|
334
|
+
* })
|
|
335
|
+
* ```
|
|
336
|
+
*/
|
|
229
337
|
connection(): ConnectionBuilder<DB>;
|
|
338
|
+
/**
|
|
339
|
+
* Releases all resources and disconnects from the database.
|
|
340
|
+
*
|
|
341
|
+
* You need to call this when you are done using the `Kysely` instance.
|
|
342
|
+
*/
|
|
230
343
|
destroy(): Promise<void>;
|
|
344
|
+
/**
|
|
345
|
+
* Returns a copy of this Kysely instance with the given plugin installed.
|
|
346
|
+
*/
|
|
231
347
|
withPlugin(plugin: KyselyPlugin): Transaction<DB>;
|
|
348
|
+
/**
|
|
349
|
+
* Returns a copy of this Kysely instance without any plugins.
|
|
350
|
+
*/
|
|
232
351
|
withoutPlugins(): Transaction<DB>;
|
|
352
|
+
/**
|
|
353
|
+
* Returns a copy of this Kysely instance with tables added to its
|
|
354
|
+
* database type.
|
|
355
|
+
*
|
|
356
|
+
* This method only modifies the types and doesn't affect any of the
|
|
357
|
+
* executed queries in any way.
|
|
358
|
+
*
|
|
359
|
+
* ### Examples
|
|
360
|
+
*
|
|
361
|
+
* The following example adds and uses a temporary table:
|
|
362
|
+
*
|
|
363
|
+
* @example
|
|
364
|
+
* ```ts
|
|
365
|
+
* await db.schema
|
|
366
|
+
* .createTable('temp_table')
|
|
367
|
+
* .temporary()
|
|
368
|
+
* .addColumn('some_column', 'integer')
|
|
369
|
+
* .execute()
|
|
370
|
+
*
|
|
371
|
+
* const tempDb = db.withTables<{
|
|
372
|
+
* temp_table: {
|
|
373
|
+
* some_column: number
|
|
374
|
+
* }
|
|
375
|
+
* }>()
|
|
376
|
+
*
|
|
377
|
+
* await tempDb
|
|
378
|
+
* .insertInto('temp_table')
|
|
379
|
+
* .values({ some_column: 100 })
|
|
380
|
+
* .execute()
|
|
381
|
+
* ```
|
|
382
|
+
*/
|
|
383
|
+
withTables<T extends Record<string, Record<string, any>>>(): Transaction<DB & T>;
|
|
233
384
|
}
|
|
234
385
|
export interface KyselyProps {
|
|
235
386
|
readonly config: KyselyConfig;
|
package/dist/esm/kysely.js
CHANGED
|
@@ -258,6 +258,40 @@ export class Kysely extends QueryCreator {
|
|
|
258
258
|
executor: this.#props.executor.withoutPlugins(),
|
|
259
259
|
});
|
|
260
260
|
}
|
|
261
|
+
/**
|
|
262
|
+
* Returns a copy of this Kysely instance with tables added to its
|
|
263
|
+
* database type.
|
|
264
|
+
*
|
|
265
|
+
* This method only modifies the types and doesn't affect any of the
|
|
266
|
+
* executed queries in any way.
|
|
267
|
+
*
|
|
268
|
+
* ### Examples
|
|
269
|
+
*
|
|
270
|
+
* The following example adds and uses a temporary table:
|
|
271
|
+
*
|
|
272
|
+
* @example
|
|
273
|
+
* ```ts
|
|
274
|
+
* await db.schema
|
|
275
|
+
* .createTable('temp_table')
|
|
276
|
+
* .temporary()
|
|
277
|
+
* .addColumn('some_column', 'integer')
|
|
278
|
+
* .execute()
|
|
279
|
+
*
|
|
280
|
+
* const tempDb = db.withTables<{
|
|
281
|
+
* temp_table: {
|
|
282
|
+
* some_column: number
|
|
283
|
+
* }
|
|
284
|
+
* }>()
|
|
285
|
+
*
|
|
286
|
+
* await tempDb
|
|
287
|
+
* .insertInto('temp_table')
|
|
288
|
+
* .values({ some_column: 100 })
|
|
289
|
+
* .execute()
|
|
290
|
+
* ```
|
|
291
|
+
*/
|
|
292
|
+
withTables() {
|
|
293
|
+
return new Kysely({ ...this.#props });
|
|
294
|
+
}
|
|
261
295
|
/**
|
|
262
296
|
* Releases all resources and disconnects from the database.
|
|
263
297
|
*
|
|
@@ -311,6 +345,9 @@ export class Transaction extends Kysely {
|
|
|
311
345
|
executor: this.#props.executor.withoutPlugins(),
|
|
312
346
|
});
|
|
313
347
|
}
|
|
348
|
+
withTables() {
|
|
349
|
+
return new Transaction({ ...this.#props });
|
|
350
|
+
}
|
|
314
351
|
}
|
|
315
352
|
export function isKyselyProps(obj) {
|
|
316
353
|
return (isObject(obj) &&
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ColumnNode } from './column-node.js';
|
|
2
|
+
import { OperationNode } from './operation-node.js';
|
|
3
|
+
import { TableNode } from './table-node.js';
|
|
4
|
+
export interface CommonTableExpressionNameNode extends OperationNode {
|
|
5
|
+
readonly kind: 'CommonTableExpressionNameNode';
|
|
6
|
+
readonly table: TableNode;
|
|
7
|
+
readonly columns?: ReadonlyArray<ColumnNode>;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* @internal
|
|
11
|
+
*/
|
|
12
|
+
export declare const CommonTableExpressionNameNode: Readonly<{
|
|
13
|
+
is(node: OperationNode): node is CommonTableExpressionNameNode;
|
|
14
|
+
create(tableName: string, columnNames?: readonly string[] | undefined): CommonTableExpressionNameNode;
|
|
15
|
+
}>;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { freeze } from '../util/object-utils.js';
|
|
2
|
+
import { ColumnNode } from './column-node.js';
|
|
3
|
+
import { TableNode } from './table-node.js';
|
|
4
|
+
/**
|
|
5
|
+
* @internal
|
|
6
|
+
*/
|
|
7
|
+
export const CommonTableExpressionNameNode = freeze({
|
|
8
|
+
is(node) {
|
|
9
|
+
return node.kind === 'CommonTableExpressionNameNode';
|
|
10
|
+
},
|
|
11
|
+
create(tableName, columnNames) {
|
|
12
|
+
return freeze({
|
|
13
|
+
kind: 'CommonTableExpressionNameNode',
|
|
14
|
+
table: TableNode.create(tableName),
|
|
15
|
+
columns: columnNames
|
|
16
|
+
? freeze(columnNames.map(ColumnNode.create))
|
|
17
|
+
: undefined,
|
|
18
|
+
});
|
|
19
|
+
},
|
|
20
|
+
});
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { CommonTableExpressionNameNode } from './common-table-expression-name-node.js';
|
|
2
2
|
import { OperationNode } from './operation-node.js';
|
|
3
3
|
import { QueryNode } from './query-node.js';
|
|
4
4
|
import { RawNode } from './raw-node.js';
|
|
5
5
|
export interface CommonTableExpressionNode extends OperationNode {
|
|
6
6
|
readonly kind: 'CommonTableExpressionNode';
|
|
7
|
-
readonly name:
|
|
7
|
+
readonly name: CommonTableExpressionNameNode;
|
|
8
8
|
readonly expression: QueryNode | RawNode;
|
|
9
9
|
}
|
|
10
10
|
/**
|
|
@@ -12,5 +12,5 @@ export interface CommonTableExpressionNode extends OperationNode {
|
|
|
12
12
|
*/
|
|
13
13
|
export declare const CommonTableExpressionNode: Readonly<{
|
|
14
14
|
is(node: OperationNode): node is CommonTableExpressionNode;
|
|
15
|
-
create(name:
|
|
15
|
+
create(name: CommonTableExpressionNameNode, expression: QueryNode | RawNode): CommonTableExpressionNode;
|
|
16
16
|
}>;
|
|
@@ -44,6 +44,7 @@ import { ReferencesNode } from './references-node.js';
|
|
|
44
44
|
import { CheckConstraintNode } from './check-constraint-node.js';
|
|
45
45
|
import { WithNode } from './with-node.js';
|
|
46
46
|
import { CommonTableExpressionNode } from './common-table-expression-node.js';
|
|
47
|
+
import { CommonTableExpressionNameNode } from './common-table-expression-name-node.js';
|
|
47
48
|
import { HavingNode } from './having-node.js';
|
|
48
49
|
import { CreateSchemaNode } from './create-schema-node.js';
|
|
49
50
|
import { DropSchemaNode } from './drop-schema-node.js';
|
|
@@ -142,6 +143,7 @@ export declare class OperationNodeTransformer {
|
|
|
142
143
|
protected transformCheckConstraint(node: CheckConstraintNode): CheckConstraintNode;
|
|
143
144
|
protected transformWith(node: WithNode): WithNode;
|
|
144
145
|
protected transformCommonTableExpression(node: CommonTableExpressionNode): CommonTableExpressionNode;
|
|
146
|
+
protected transformCommonTableExpressionName(node: CommonTableExpressionNameNode): CommonTableExpressionNameNode;
|
|
145
147
|
protected transformHaving(node: HavingNode): HavingNode;
|
|
146
148
|
protected transformCreateSchema(node: CreateSchemaNode): CreateSchemaNode;
|
|
147
149
|
protected transformDropSchema(node: DropSchemaNode): DropSchemaNode;
|
|
@@ -78,6 +78,7 @@ export class OperationNodeTransformer {
|
|
|
78
78
|
CheckConstraintNode: this.transformCheckConstraint.bind(this),
|
|
79
79
|
WithNode: this.transformWith.bind(this),
|
|
80
80
|
CommonTableExpressionNode: this.transformCommonTableExpression.bind(this),
|
|
81
|
+
CommonTableExpressionNameNode: this.transformCommonTableExpressionName.bind(this),
|
|
81
82
|
HavingNode: this.transformHaving.bind(this),
|
|
82
83
|
CreateSchemaNode: this.transformCreateSchema.bind(this),
|
|
83
84
|
DropSchemaNode: this.transformDropSchema.bind(this),
|
|
@@ -444,6 +445,7 @@ export class OperationNodeTransformer {
|
|
|
444
445
|
return {
|
|
445
446
|
kind: 'WithNode',
|
|
446
447
|
expressions: this.transformNodeList(node.expressions),
|
|
448
|
+
recursive: node.recursive,
|
|
447
449
|
};
|
|
448
450
|
}
|
|
449
451
|
transformCommonTableExpression(node) {
|
|
@@ -453,6 +455,13 @@ export class OperationNodeTransformer {
|
|
|
453
455
|
expression: this.transformNode(node.expression),
|
|
454
456
|
};
|
|
455
457
|
}
|
|
458
|
+
transformCommonTableExpressionName(node) {
|
|
459
|
+
return {
|
|
460
|
+
kind: 'CommonTableExpressionNameNode',
|
|
461
|
+
table: this.transformNode(node.table),
|
|
462
|
+
columns: this.transformNodeList(node.columns),
|
|
463
|
+
};
|
|
464
|
+
}
|
|
456
465
|
transformHaving(node) {
|
|
457
466
|
return {
|
|
458
467
|
kind: 'HavingNode',
|
|
@@ -44,6 +44,7 @@ import { ReferencesNode } from './references-node.js';
|
|
|
44
44
|
import { CheckConstraintNode } from './check-constraint-node.js';
|
|
45
45
|
import { WithNode } from './with-node.js';
|
|
46
46
|
import { CommonTableExpressionNode } from './common-table-expression-node.js';
|
|
47
|
+
import { CommonTableExpressionNameNode } from './common-table-expression-name-node.js';
|
|
47
48
|
import { HavingNode } from './having-node.js';
|
|
48
49
|
import { CreateSchemaNode } from './create-schema-node.js';
|
|
49
50
|
import { DropSchemaNode } from './drop-schema-node.js';
|
|
@@ -110,6 +111,7 @@ export declare abstract class OperationNodeVisitor {
|
|
|
110
111
|
protected abstract visitCheckConstraint(node: CheckConstraintNode): void;
|
|
111
112
|
protected abstract visitWith(node: WithNode): void;
|
|
112
113
|
protected abstract visitCommonTableExpression(node: CommonTableExpressionNode): void;
|
|
114
|
+
protected abstract visitCommonTableExpressionName(node: CommonTableExpressionNameNode): void;
|
|
113
115
|
protected abstract visitHaving(node: HavingNode): void;
|
|
114
116
|
protected abstract visitCreateSchema(node: CreateSchemaNode): void;
|
|
115
117
|
protected abstract visitDropSchema(node: DropSchemaNode): void;
|
|
@@ -52,6 +52,7 @@ export class OperationNodeVisitor {
|
|
|
52
52
|
CheckConstraintNode: this.visitCheckConstraint.bind(this),
|
|
53
53
|
WithNode: this.visitWith.bind(this),
|
|
54
54
|
CommonTableExpressionNode: this.visitCommonTableExpression.bind(this),
|
|
55
|
+
CommonTableExpressionNameNode: this.visitCommonTableExpressionName.bind(this),
|
|
55
56
|
HavingNode: this.visitHaving.bind(this),
|
|
56
57
|
CreateSchemaNode: this.visitCreateSchema.bind(this),
|
|
57
58
|
DropSchemaNode: this.visitDropSchema.bind(this),
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare type OperationNodeKind = 'IdentifierNode' | 'RawNode' | 'SelectQueryNode' | 'SelectionNode' | 'ReferenceNode' | 'ColumnNode' | 'TableNode' | 'AliasNode' | 'FromNode' | 'SelectAllNode' | 'FilterNode' | 'AndNode' | 'OrNode' | 'ParensNode' | 'ValueNode' | 'ValueListNode' | 'PrimitiveValueListNode' | 'JoinNode' | 'OperatorNode' | 'WhereNode' | 'InsertQueryNode' | 'DeleteQueryNode' | 'ReturningNode' | 'CreateTableNode' | 'ColumnDefinitionNode' | 'AddColumnNode' | 'DropTableNode' | 'DataTypeNode' | 'OrderByNode' | 'OrderByItemNode' | 'GroupByNode' | 'GroupByItemNode' | 'UpdateQueryNode' | 'ColumnUpdateNode' | 'LimitNode' | 'OffsetNode' | 'OnConflictNode' | 'OnDuplicateKeyNode' | 'CreateIndexNode' | 'DropIndexNode' | 'ListNode' | 'ReferencesNode' | 'PrimaryKeyConstraintNode' | 'UniqueConstraintNode' | 'CheckConstraintNode' | 'ForeignKeyConstraintNode' | 'WithNode' | 'CommonTableExpressionNode' | 'HavingNode' | 'CreateSchemaNode' | 'DropSchemaNode' | 'AlterTableNode' | 'ModifyColumnNode' | 'DropColumnNode' | 'RenameColumnNode' | 'AlterColumnNode' | 'AddConstraintNode' | 'DropConstraintNode' | 'UnionNode' | 'CreateViewNode' | 'DropViewNode' | 'GeneratedAlwaysAsNode' | 'DefaultValueNode' | 'OnNode' | 'ValuesNode';
|
|
1
|
+
export declare type OperationNodeKind = 'IdentifierNode' | 'RawNode' | 'SelectQueryNode' | 'SelectionNode' | 'ReferenceNode' | 'ColumnNode' | 'TableNode' | 'AliasNode' | 'FromNode' | 'SelectAllNode' | 'FilterNode' | 'AndNode' | 'OrNode' | 'ParensNode' | 'ValueNode' | 'ValueListNode' | 'PrimitiveValueListNode' | 'JoinNode' | 'OperatorNode' | 'WhereNode' | 'InsertQueryNode' | 'DeleteQueryNode' | 'ReturningNode' | 'CreateTableNode' | 'ColumnDefinitionNode' | 'AddColumnNode' | 'DropTableNode' | 'DataTypeNode' | 'OrderByNode' | 'OrderByItemNode' | 'GroupByNode' | 'GroupByItemNode' | 'UpdateQueryNode' | 'ColumnUpdateNode' | 'LimitNode' | 'OffsetNode' | 'OnConflictNode' | 'OnDuplicateKeyNode' | 'CreateIndexNode' | 'DropIndexNode' | 'ListNode' | 'ReferencesNode' | 'PrimaryKeyConstraintNode' | 'UniqueConstraintNode' | 'CheckConstraintNode' | 'ForeignKeyConstraintNode' | 'WithNode' | 'CommonTableExpressionNode' | 'HavingNode' | 'CreateSchemaNode' | 'DropSchemaNode' | 'AlterTableNode' | 'ModifyColumnNode' | 'DropColumnNode' | 'RenameColumnNode' | 'AlterColumnNode' | 'AddConstraintNode' | 'DropConstraintNode' | 'UnionNode' | 'CreateViewNode' | 'DropViewNode' | 'GeneratedAlwaysAsNode' | 'DefaultValueNode' | 'OnNode' | 'ValuesNode' | 'CommonTableExpressionNameNode';
|
|
2
2
|
export interface OperationNode {
|
|
3
3
|
readonly kind: OperationNodeKind;
|
|
4
4
|
}
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import { OperationNode } from './operation-node.js';
|
|
2
2
|
import { CommonTableExpressionNode } from './common-table-expression-node.js';
|
|
3
|
+
export declare type WithNodeParams = Omit<WithNode, 'kind' | 'expressions'>;
|
|
3
4
|
export interface WithNode extends OperationNode {
|
|
4
5
|
readonly kind: 'WithNode';
|
|
5
6
|
readonly expressions: ReadonlyArray<CommonTableExpressionNode>;
|
|
7
|
+
readonly recursive?: boolean;
|
|
6
8
|
}
|
|
7
9
|
/**
|
|
8
10
|
* @internal
|
|
9
11
|
*/
|
|
10
12
|
export declare const WithNode: Readonly<{
|
|
11
13
|
is(node: OperationNode): node is WithNode;
|
|
12
|
-
create(expression: CommonTableExpressionNode): WithNode;
|
|
14
|
+
create(expression: CommonTableExpressionNode, params?: WithNodeParams | undefined): WithNode;
|
|
13
15
|
cloneWithExpression(withNode: WithNode, expression: CommonTableExpressionNode): WithNode;
|
|
14
16
|
}>;
|
|
@@ -6,10 +6,11 @@ export const WithNode = freeze({
|
|
|
6
6
|
is(node) {
|
|
7
7
|
return node.kind === 'WithNode';
|
|
8
8
|
},
|
|
9
|
-
create(expression) {
|
|
9
|
+
create(expression, params) {
|
|
10
10
|
return freeze({
|
|
11
11
|
kind: 'WithNode',
|
|
12
12
|
expressions: freeze([expression]),
|
|
13
|
+
...params,
|
|
13
14
|
});
|
|
14
15
|
},
|
|
15
16
|
cloneWithExpression(withNode, expression) {
|
|
@@ -5,10 +5,37 @@ import { InsertQueryBuilder } from '../query-builder/insert-query-builder.js';
|
|
|
5
5
|
import { CommonTableExpressionNode } from '../operation-node/common-table-expression-node.js';
|
|
6
6
|
import { QueryCreator } from '../query-creator.js';
|
|
7
7
|
import { RawBuilder } from '../raw-builder/raw-builder.js';
|
|
8
|
-
import { AnyRawBuilder } from '../util/type-utils.js';
|
|
9
8
|
import { ParseContext } from './parse-context.js';
|
|
10
|
-
export declare type CommonTableExpression<DB> = (creator: QueryCreator<DB>) =>
|
|
11
|
-
export declare type
|
|
12
|
-
declare type
|
|
13
|
-
|
|
9
|
+
export declare type CommonTableExpression<DB, CN extends string> = (creator: QueryCreator<DB>) => CommonTableExpressionOutput<DB, CN>;
|
|
10
|
+
export declare type RecursiveCommonTableExpression<DB, CN extends string> = (creator: QueryCreator<DB & Record<ExtractTableFromCommonTableExpressionName<CN>, ExtractRowFromCommonTableExpressionName<CN>>>) => CommonTableExpressionOutput<DB, CN>;
|
|
11
|
+
export declare type QueryCreatorWithCommonTableExpression<DB, CN extends string, CTE> = QueryCreator<DB & Record<ExtractTableFromCommonTableExpressionName<CN>, ExtractRowFromCommonTableExpression<CTE>>>;
|
|
12
|
+
declare type CommonTableExpressionOutput<DB, CN extends string> = SelectQueryBuilder<DB, any, ExtractRowFromCommonTableExpressionName<CN>> | InsertQueryBuilder<DB, any, ExtractRowFromCommonTableExpressionName<CN>> | UpdateQueryBuilder<DB, any, ExtractRowFromCommonTableExpressionName<CN>> | DeleteQueryBuilder<DB, any, ExtractRowFromCommonTableExpressionName<CN>> | RawBuilder<ExtractRowFromCommonTableExpressionName<CN>>;
|
|
13
|
+
/**
|
|
14
|
+
* Given a common CommonTableExpression CTE extracts the row type from it.
|
|
15
|
+
*
|
|
16
|
+
* For example a CTE `(db) => db.selectFrom('person').select(['id', 'first_name'])`
|
|
17
|
+
* would result in `Pick<Person, 'id' | 'first_name'>`.
|
|
18
|
+
*/
|
|
19
|
+
declare type ExtractRowFromCommonTableExpression<CTE> = CTE extends (creator: QueryCreator<any>) => infer Q ? Q extends SelectQueryBuilder<any, any, infer QO> ? QO : Q extends InsertQueryBuilder<any, any, infer QO> ? QO : Q extends UpdateQueryBuilder<any, any, infer QO> ? QO : Q extends DeleteQueryBuilder<any, any, infer QO> ? QO : Q extends RawBuilder<infer RO> ? RO : never : never;
|
|
20
|
+
/**
|
|
21
|
+
* Extracts 'person' from a string like 'person(id, first_name)'.
|
|
22
|
+
*/
|
|
23
|
+
declare type ExtractTableFromCommonTableExpressionName<CN extends string> = CN extends `${infer TB}(${string})` ? TB : CN;
|
|
24
|
+
/**
|
|
25
|
+
* Parses a string like 'person(id, first_name)' into a type:
|
|
26
|
+
*
|
|
27
|
+
* {
|
|
28
|
+
* id: any,
|
|
29
|
+
* first_name: any
|
|
30
|
+
* }
|
|
31
|
+
*
|
|
32
|
+
*/
|
|
33
|
+
declare type ExtractRowFromCommonTableExpressionName<CN extends string> = CN extends `${string}(${infer CL})` ? {
|
|
34
|
+
[C in ExtractColumnNamesFromColumnList<CL>]: any;
|
|
35
|
+
} : Record<string, any>;
|
|
36
|
+
/**
|
|
37
|
+
* Parses a string like 'id, first_name' into a type 'id' | 'first_name'
|
|
38
|
+
*/
|
|
39
|
+
declare type ExtractColumnNamesFromColumnList<R extends string> = R extends `${infer C}, ${infer RS}` ? C | ExtractColumnNamesFromColumnList<RS> : R;
|
|
40
|
+
export declare function parseCommonTableExpression(ctx: ParseContext, name: string, expression: CommonTableExpression<any, any>): CommonTableExpressionNode;
|
|
14
41
|
export {};
|
|
@@ -1,6 +1,17 @@
|
|
|
1
|
-
import { IdentifierNode } from '../operation-node/identifier-node.js';
|
|
2
1
|
import { CommonTableExpressionNode } from '../operation-node/common-table-expression-node.js';
|
|
2
|
+
import { CommonTableExpressionNameNode } from '../operation-node/common-table-expression-name-node.js';
|
|
3
3
|
export function parseCommonTableExpression(ctx, name, expression) {
|
|
4
4
|
const builder = expression(ctx.createQueryCreator());
|
|
5
|
-
return CommonTableExpressionNode.create(
|
|
5
|
+
return CommonTableExpressionNode.create(parseCommonTableExpressionName(name), builder.toOperationNode());
|
|
6
|
+
}
|
|
7
|
+
function parseCommonTableExpressionName(name) {
|
|
8
|
+
if (name.includes('(')) {
|
|
9
|
+
const parts = name.split(/[\(\)]/);
|
|
10
|
+
const table = parts[0];
|
|
11
|
+
const columns = parts[1].split(',').map((it) => it.trim());
|
|
12
|
+
return CommonTableExpressionNameNode.create(table, columns);
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
return CommonTableExpressionNameNode.create(name);
|
|
16
|
+
}
|
|
6
17
|
}
|
|
@@ -79,6 +79,9 @@ export class WithSchemaTransformer extends OperationNodeTransformer {
|
|
|
79
79
|
if ('joins' in node && node.joins) {
|
|
80
80
|
this.#collectTablesFromJoins(node.joins, tables);
|
|
81
81
|
}
|
|
82
|
+
if ('with' in node && node.with) {
|
|
83
|
+
this.#removeCommonTableExpressionTables(node.with, tables);
|
|
84
|
+
}
|
|
82
85
|
return tables;
|
|
83
86
|
}
|
|
84
87
|
#collectTablesFromTableExpressionNodes(nodes, tables) {
|
|
@@ -101,4 +104,9 @@ export class WithSchemaTransformer extends OperationNodeTransformer {
|
|
|
101
104
|
tables.add(table.table.identifier);
|
|
102
105
|
}
|
|
103
106
|
}
|
|
107
|
+
#removeCommonTableExpressionTables(node, tables) {
|
|
108
|
+
for (const expr of node.expressions) {
|
|
109
|
+
tables.delete(expr.name.table.table.identifier);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
104
112
|
}
|
|
@@ -68,6 +68,7 @@ import { GeneratedAlwaysAsNode } from '../operation-node/generated-always-as-nod
|
|
|
68
68
|
import { DefaultValueNode } from '../operation-node/default-value-node.js';
|
|
69
69
|
import { OnNode } from '../operation-node/on-node.js';
|
|
70
70
|
import { ValuesNode } from '../operation-node/values-node.js';
|
|
71
|
+
import { CommonTableExpressionNameNode } from '../operation-node/common-table-expression-name-node.js';
|
|
71
72
|
export declare class DefaultQueryCompiler extends OperationNodeVisitor implements QueryCompiler {
|
|
72
73
|
#private;
|
|
73
74
|
protected get numParameters(): number;
|
|
@@ -129,6 +130,7 @@ export declare class DefaultQueryCompiler extends OperationNodeVisitor implement
|
|
|
129
130
|
protected visitList(node: ListNode): void;
|
|
130
131
|
protected visitWith(node: WithNode): void;
|
|
131
132
|
protected visitCommonTableExpression(node: CommonTableExpressionNode): void;
|
|
133
|
+
protected visitCommonTableExpressionName(node: CommonTableExpressionNameNode): void;
|
|
132
134
|
protected visitAlterTable(node: AlterTableNode): void;
|
|
133
135
|
protected visitAddColumn(node: AddColumnNode): void;
|
|
134
136
|
protected visitRenameColumn(node: RenameColumnNode): void;
|