kysely 0.19.12 → 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/cjs/dialect/mysql/mysql-introspector.js +2 -0
- package/dist/cjs/dialect/mysql/mysql-query-compiler.d.ts +5 -0
- package/dist/cjs/dialect/mysql/mysql-query-compiler.js +16 -0
- package/dist/cjs/dialect/postgres/postgres-introspector.js +7 -1
- package/dist/cjs/dialect/postgres/postgres-query-compiler.d.ts +1 -3
- package/dist/cjs/dialect/postgres/postgres-query-compiler.js +3 -8
- package/dist/cjs/dialect/sqlite/sqlite-introspector.js +2 -0
- package/dist/cjs/dialect/sqlite/sqlite-query-compiler.d.ts +3 -0
- package/dist/cjs/dialect/sqlite/sqlite-query-compiler.js +10 -0
- package/dist/cjs/index.d.ts +2 -0
- package/dist/cjs/index.js +2 -0
- package/dist/cjs/operation-node/create-table-node.d.ts +6 -1
- package/dist/cjs/operation-node/create-table-node.js +16 -0
- package/dist/cjs/operation-node/delete-query-node.d.ts +3 -0
- package/dist/cjs/operation-node/delete-query-node.js +6 -0
- package/dist/cjs/operation-node/explain-node.d.ts +16 -0
- package/dist/cjs/operation-node/explain-node.js +19 -0
- package/dist/cjs/operation-node/insert-query-node.d.ts +2 -0
- package/dist/cjs/operation-node/operation-node-transformer.d.ts +2 -0
- package/dist/cjs/operation-node/operation-node-transformer.js +14 -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/select-query-node.d.ts +3 -0
- package/dist/cjs/operation-node/select-query-node.js +6 -0
- package/dist/cjs/operation-node/update-query-node.d.ts +3 -0
- package/dist/cjs/operation-node/update-query-node.js +6 -0
- package/dist/cjs/query-builder/delete-query-builder.d.ts +19 -1
- package/dist/cjs/query-builder/delete-query-builder.js +24 -0
- package/dist/cjs/query-builder/function-builder.d.ts +3 -3
- package/dist/cjs/query-builder/insert-query-builder.d.ts +20 -2
- package/dist/cjs/query-builder/insert-query-builder.js +26 -0
- package/dist/cjs/query-builder/select-query-builder.d.ts +38 -1
- package/dist/cjs/query-builder/select-query-builder.js +45 -2
- package/dist/cjs/query-builder/update-query-builder.d.ts +20 -1
- package/dist/cjs/query-builder/update-query-builder.js +25 -0
- package/dist/cjs/query-compiler/default-query-compiler.d.ts +6 -0
- package/dist/cjs/query-compiler/default-query-compiler.js +58 -3
- package/dist/cjs/raw-builder/sql.d.ts +96 -96
- package/dist/cjs/raw-builder/sql.js +0 -96
- package/dist/cjs/schema/create-table-builder.d.ts +54 -0
- package/dist/cjs/schema/create-table-builder.js +64 -0
- package/dist/cjs/util/explainable.d.ts +5 -0
- package/dist/cjs/util/explainable.js +2 -0
- package/dist/esm/dialect/mysql/mysql-introspector.js +2 -0
- package/dist/esm/dialect/mysql/mysql-query-compiler.d.ts +5 -0
- package/dist/esm/dialect/mysql/mysql-query-compiler.js +16 -0
- package/dist/esm/dialect/postgres/postgres-introspector.js +7 -1
- package/dist/esm/dialect/postgres/postgres-query-compiler.d.ts +1 -3
- package/dist/esm/dialect/postgres/postgres-query-compiler.js +3 -8
- package/dist/esm/dialect/sqlite/sqlite-introspector.js +2 -0
- package/dist/esm/dialect/sqlite/sqlite-query-compiler.d.ts +3 -0
- package/dist/esm/dialect/sqlite/sqlite-query-compiler.js +10 -0
- package/dist/esm/index.d.ts +2 -0
- package/dist/esm/index.js +2 -0
- package/dist/esm/operation-node/create-table-node.d.ts +6 -1
- package/dist/esm/operation-node/create-table-node.js +16 -0
- package/dist/esm/operation-node/delete-query-node.d.ts +3 -0
- package/dist/esm/operation-node/delete-query-node.js +6 -0
- package/dist/esm/operation-node/explain-node.d.ts +16 -0
- package/dist/esm/operation-node/explain-node.js +17 -0
- package/dist/esm/operation-node/insert-query-node.d.ts +2 -0
- package/dist/esm/operation-node/operation-node-transformer.d.ts +2 -0
- package/dist/esm/operation-node/operation-node-transformer.js +14 -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/select-query-node.d.ts +3 -0
- package/dist/esm/operation-node/select-query-node.js +6 -0
- package/dist/esm/operation-node/update-query-node.d.ts +3 -0
- package/dist/esm/operation-node/update-query-node.js +6 -0
- package/dist/esm/query-builder/delete-query-builder.d.ts +19 -1
- package/dist/esm/query-builder/delete-query-builder.js +24 -0
- package/dist/esm/query-builder/function-builder.d.ts +3 -3
- package/dist/esm/query-builder/insert-query-builder.d.ts +20 -2
- package/dist/esm/query-builder/insert-query-builder.js +26 -0
- package/dist/esm/query-builder/select-query-builder.d.ts +38 -1
- package/dist/esm/query-builder/select-query-builder.js +45 -2
- package/dist/esm/query-builder/update-query-builder.d.ts +20 -1
- package/dist/esm/query-builder/update-query-builder.js +25 -0
- package/dist/esm/query-compiler/default-query-compiler.d.ts +6 -0
- package/dist/esm/query-compiler/default-query-compiler.js +58 -3
- package/dist/esm/raw-builder/sql.d.ts +96 -96
- package/dist/esm/raw-builder/sql.js +0 -96
- package/dist/esm/schema/create-table-builder.d.ts +54 -0
- package/dist/esm/schema/create-table-builder.js +64 -0
- package/dist/esm/util/explainable.d.ts +5 -0
- package/dist/esm/util/explainable.js +2 -0
- package/package.json +3 -1
|
@@ -3,7 +3,7 @@ import { CompiledQuery } from '../query-compiler/compiled-query.js';
|
|
|
3
3
|
import { SelectExpression } from '../parser/select-parser.js';
|
|
4
4
|
import { InsertObject } from '../parser/insert-values-parser.js';
|
|
5
5
|
import { InsertQueryNode } from '../operation-node/insert-query-node.js';
|
|
6
|
-
import { MergePartial, SingleResultType } from '../util/type-utils.js';
|
|
6
|
+
import { AnyRawBuilder, MergePartial, SingleResultType } from '../util/type-utils.js';
|
|
7
7
|
import { MutationObject } from '../parser/update-set-parser.js';
|
|
8
8
|
import { Compilable } from '../util/compilable.js';
|
|
9
9
|
import { QueryExecutor } from '../query-executor/query-executor.js';
|
|
@@ -16,7 +16,8 @@ import { ComplexExpression } from '../parser/complex-expression-parser.js';
|
|
|
16
16
|
import { ReturningInterface } from './returning-interface.js';
|
|
17
17
|
import { OnConflictBuilder, OnConflictDoNothingBuilder, OnConflictUpdateBuilder } from './on-conflict-builder.js';
|
|
18
18
|
import { Selectable } from '../util/column-type.js';
|
|
19
|
-
|
|
19
|
+
import { Explainable, ExplainFormat } from '../util/explainable.js';
|
|
20
|
+
export declare class InsertQueryBuilder<DB, TB extends keyof DB, O> implements ReturningInterface<DB, TB, O>, OperationNodeSource, Compilable, Explainable {
|
|
20
21
|
#private;
|
|
21
22
|
constructor(props: InsertQueryBuilderProps);
|
|
22
23
|
/**
|
|
@@ -541,6 +542,23 @@ export declare class InsertQueryBuilder<DB, TB extends keyof DB, O> implements R
|
|
|
541
542
|
* error.
|
|
542
543
|
*/
|
|
543
544
|
executeTakeFirstOrThrow(errorConstructor?: NoResultErrorConstructor): Promise<O>;
|
|
545
|
+
/**
|
|
546
|
+
* Executes query with `explain` statement before `insert` keyword.
|
|
547
|
+
*
|
|
548
|
+
* ```ts
|
|
549
|
+
* const explained = await db
|
|
550
|
+
* .insertInto('person')
|
|
551
|
+
* .values(values)
|
|
552
|
+
* .explain('json')
|
|
553
|
+
* ```
|
|
554
|
+
*
|
|
555
|
+
* The generated SQL (MySQL):
|
|
556
|
+
*
|
|
557
|
+
* ```sql
|
|
558
|
+
* explain format=json insert into `person` (`id`, `first_name`, `last_name`) values (?, ?, ?) (?, ?, ?)
|
|
559
|
+
* ```
|
|
560
|
+
*/
|
|
561
|
+
explain<ER extends Record<string, any> = Record<string, any>>(format?: ExplainFormat, options?: AnyRawBuilder): Promise<ER[]>;
|
|
544
562
|
}
|
|
545
563
|
export interface InsertQueryBuilderProps {
|
|
546
564
|
readonly queryId: QueryId;
|
|
@@ -15,6 +15,7 @@ const complex_expression_parser_js_1 = require("../parser/complex-expression-par
|
|
|
15
15
|
const column_node_js_1 = require("../operation-node/column-node.js");
|
|
16
16
|
const on_conflict_builder_js_1 = require("./on-conflict-builder.js");
|
|
17
17
|
const on_conflict_node_js_1 = require("../operation-node/on-conflict-node.js");
|
|
18
|
+
const explain_node_js_1 = require("../operation-node/explain-node.js");
|
|
18
19
|
class InsertQueryBuilder {
|
|
19
20
|
#props;
|
|
20
21
|
constructor(props) {
|
|
@@ -446,6 +447,31 @@ class InsertQueryBuilder {
|
|
|
446
447
|
}
|
|
447
448
|
return result;
|
|
448
449
|
}
|
|
450
|
+
/**
|
|
451
|
+
* Executes query with `explain` statement before `insert` keyword.
|
|
452
|
+
*
|
|
453
|
+
* ```ts
|
|
454
|
+
* const explained = await db
|
|
455
|
+
* .insertInto('person')
|
|
456
|
+
* .values(values)
|
|
457
|
+
* .explain('json')
|
|
458
|
+
* ```
|
|
459
|
+
*
|
|
460
|
+
* The generated SQL (MySQL):
|
|
461
|
+
*
|
|
462
|
+
* ```sql
|
|
463
|
+
* explain format=json insert into `person` (`id`, `first_name`, `last_name`) values (?, ?, ?) (?, ?, ?)
|
|
464
|
+
* ```
|
|
465
|
+
*/
|
|
466
|
+
async explain(format, options) {
|
|
467
|
+
const builder = new InsertQueryBuilder({
|
|
468
|
+
...this.#props,
|
|
469
|
+
queryNode: insert_query_node_js_1.InsertQueryNode.cloneWith(this.#props.queryNode, {
|
|
470
|
+
explain: explain_node_js_1.ExplainNode.create(format, options),
|
|
471
|
+
}),
|
|
472
|
+
});
|
|
473
|
+
return await builder.execute();
|
|
474
|
+
}
|
|
449
475
|
}
|
|
450
476
|
exports.InsertQueryBuilder = InsertQueryBuilder;
|
|
451
477
|
(0, prevent_await_js_1.preventAwait)(InsertQueryBuilder, "don't await InsertQueryBuilder instances directly. To execute the query you need to call `execute` or `executeTakeFirst`.");
|
|
@@ -18,7 +18,8 @@ import { WhereInterface } from './where-interface.js';
|
|
|
18
18
|
import { NoResultErrorConstructor } from './no-result-error.js';
|
|
19
19
|
import { HavingInterface } from './having-interface.js';
|
|
20
20
|
import { AliasedRawBuilder } from '../raw-builder/raw-builder.js';
|
|
21
|
-
|
|
21
|
+
import { Explainable, ExplainFormat } from '../util/explainable.js';
|
|
22
|
+
export declare class SelectQueryBuilder<DB, TB extends keyof DB, O> implements WhereInterface<DB, TB>, HavingInterface<DB, TB>, OperationNodeSource, Compilable, Explainable {
|
|
22
23
|
#private;
|
|
23
24
|
constructor(props: SelectQueryBuilderProps);
|
|
24
25
|
/**
|
|
@@ -1370,6 +1371,42 @@ export declare class SelectQueryBuilder<DB, TB extends keyof DB, O> implements W
|
|
|
1370
1371
|
* ```
|
|
1371
1372
|
*/
|
|
1372
1373
|
stream(chunkSize?: number): AsyncIterableIterator<O>;
|
|
1374
|
+
/**
|
|
1375
|
+
* Executes query with `explain` statement before `select` keyword.
|
|
1376
|
+
*
|
|
1377
|
+
* ```ts
|
|
1378
|
+
* const explained = await db
|
|
1379
|
+
* .selectFrom('person')
|
|
1380
|
+
* .where('gender', '=', 'female')
|
|
1381
|
+
* .selectAll()
|
|
1382
|
+
* .explain('json')
|
|
1383
|
+
* ```
|
|
1384
|
+
*
|
|
1385
|
+
* The generated SQL (MySQL):
|
|
1386
|
+
*
|
|
1387
|
+
* ```sql
|
|
1388
|
+
* explain format=json select * from `person` where `gender` = ?
|
|
1389
|
+
* ```
|
|
1390
|
+
*
|
|
1391
|
+
* You can also execute `explain analyze` statements.
|
|
1392
|
+
*
|
|
1393
|
+
* ```ts
|
|
1394
|
+
* import { sql } from 'kysely'
|
|
1395
|
+
*
|
|
1396
|
+
* const explained = await db
|
|
1397
|
+
* .selectFrom('person')
|
|
1398
|
+
* .where('gender', '=', 'female')
|
|
1399
|
+
* .selectAll()
|
|
1400
|
+
* .explain('json', sql`analyze`)
|
|
1401
|
+
* ```
|
|
1402
|
+
*
|
|
1403
|
+
* The generated SQL (PostgreSQL):
|
|
1404
|
+
*
|
|
1405
|
+
* ```sql
|
|
1406
|
+
* explain (analyze, format json) select * from "person" where "gender" = $1
|
|
1407
|
+
* ```
|
|
1408
|
+
*/
|
|
1409
|
+
explain<ER extends Record<string, any> = Record<string, any>>(format?: ExplainFormat, options?: AnyRawBuilder): Promise<ER[]>;
|
|
1373
1410
|
}
|
|
1374
1411
|
export interface SelectQueryBuilderProps {
|
|
1375
1412
|
readonly queryId: QueryId;
|
|
@@ -17,6 +17,7 @@ const group_by_parser_js_1 = require("../parser/group-by-parser.js");
|
|
|
17
17
|
const union_parser_js_1 = require("../parser/union-parser.js");
|
|
18
18
|
const no_result_error_js_1 = require("./no-result-error.js");
|
|
19
19
|
const identifier_node_js_1 = require("../operation-node/identifier-node.js");
|
|
20
|
+
const explain_node_js_1 = require("../operation-node/explain-node.js");
|
|
20
21
|
class SelectQueryBuilder {
|
|
21
22
|
#props;
|
|
22
23
|
constructor(props) {
|
|
@@ -629,8 +630,8 @@ class SelectQueryBuilder {
|
|
|
629
630
|
* Also see the {@link executeTakeFirst} and {@link executeTakeFirstOrThrow} methods.
|
|
630
631
|
*/
|
|
631
632
|
async execute() {
|
|
632
|
-
const
|
|
633
|
-
const result = await this.#props.executor.executeQuery(
|
|
633
|
+
const compiledQuery = this.compile();
|
|
634
|
+
const result = await this.#props.executor.executeQuery(compiledQuery, this.#props.queryId);
|
|
634
635
|
return result.rows;
|
|
635
636
|
}
|
|
636
637
|
/**
|
|
@@ -689,6 +690,48 @@ class SelectQueryBuilder {
|
|
|
689
690
|
yield* item.rows;
|
|
690
691
|
}
|
|
691
692
|
}
|
|
693
|
+
/**
|
|
694
|
+
* Executes query with `explain` statement before `select` keyword.
|
|
695
|
+
*
|
|
696
|
+
* ```ts
|
|
697
|
+
* const explained = await db
|
|
698
|
+
* .selectFrom('person')
|
|
699
|
+
* .where('gender', '=', 'female')
|
|
700
|
+
* .selectAll()
|
|
701
|
+
* .explain('json')
|
|
702
|
+
* ```
|
|
703
|
+
*
|
|
704
|
+
* The generated SQL (MySQL):
|
|
705
|
+
*
|
|
706
|
+
* ```sql
|
|
707
|
+
* explain format=json select * from `person` where `gender` = ?
|
|
708
|
+
* ```
|
|
709
|
+
*
|
|
710
|
+
* You can also execute `explain analyze` statements.
|
|
711
|
+
*
|
|
712
|
+
* ```ts
|
|
713
|
+
* import { sql } from 'kysely'
|
|
714
|
+
*
|
|
715
|
+
* const explained = await db
|
|
716
|
+
* .selectFrom('person')
|
|
717
|
+
* .where('gender', '=', 'female')
|
|
718
|
+
* .selectAll()
|
|
719
|
+
* .explain('json', sql`analyze`)
|
|
720
|
+
* ```
|
|
721
|
+
*
|
|
722
|
+
* The generated SQL (PostgreSQL):
|
|
723
|
+
*
|
|
724
|
+
* ```sql
|
|
725
|
+
* explain (analyze, format json) select * from "person" where "gender" = $1
|
|
726
|
+
* ```
|
|
727
|
+
*/
|
|
728
|
+
async explain(format, options) {
|
|
729
|
+
const builder = new SelectQueryBuilder({
|
|
730
|
+
...this.#props,
|
|
731
|
+
queryNode: select_query_node_js_1.SelectQueryNode.cloneWithExplain(this.#props.queryNode, explain_node_js_1.ExplainNode.create(format, options)),
|
|
732
|
+
});
|
|
733
|
+
return await builder.execute();
|
|
734
|
+
}
|
|
692
735
|
}
|
|
693
736
|
exports.SelectQueryBuilder = SelectQueryBuilder;
|
|
694
737
|
(0, prevent_await_js_1.preventAwait)(SelectQueryBuilder, "don't await SelectQueryBuilder instances directly. To execute the query you need to call `execute` or `executeTakeFirst`.");
|
|
@@ -20,7 +20,8 @@ import { NoResultErrorConstructor } from './no-result-error.js';
|
|
|
20
20
|
import { Selectable } from '../util/column-type.js';
|
|
21
21
|
import { AliasedQueryBuilder } from './select-query-builder.js';
|
|
22
22
|
import { AliasedRawBuilder } from '../raw-builder/raw-builder.js';
|
|
23
|
-
|
|
23
|
+
import { Explainable, ExplainFormat } from '../util/explainable.js';
|
|
24
|
+
export declare class UpdateQueryBuilder<DB, UT extends keyof DB, TB extends keyof DB, O> implements WhereInterface<DB, TB>, ReturningInterface<DB, TB, O>, OperationNodeSource, Compilable, Explainable {
|
|
24
25
|
#private;
|
|
25
26
|
constructor(props: UpdateQueryBuilderProps);
|
|
26
27
|
/**
|
|
@@ -809,6 +810,24 @@ export declare class UpdateQueryBuilder<DB, UT extends keyof DB, TB extends keyo
|
|
|
809
810
|
* error.
|
|
810
811
|
*/
|
|
811
812
|
executeTakeFirstOrThrow(errorConstructor?: NoResultErrorConstructor): Promise<O>;
|
|
813
|
+
/**
|
|
814
|
+
* Executes query with `explain` statement before `update` keyword.
|
|
815
|
+
*
|
|
816
|
+
* ```ts
|
|
817
|
+
* const explained = await db
|
|
818
|
+
* .updateTable('person')
|
|
819
|
+
* .set(updates)
|
|
820
|
+
* .where('id', '=', 123)
|
|
821
|
+
* .explain('json')
|
|
822
|
+
* ```
|
|
823
|
+
*
|
|
824
|
+
* The generated SQL (MySQL):
|
|
825
|
+
*
|
|
826
|
+
* ```sql
|
|
827
|
+
* explain format=json update `person` set `first_name` = ?, `last_name` = ? where `id` = ?
|
|
828
|
+
* ```
|
|
829
|
+
*/
|
|
830
|
+
explain<ER extends Record<string, any> = Record<string, any>>(format?: ExplainFormat, options?: AnyRawBuilder): Promise<ER[]>;
|
|
812
831
|
}
|
|
813
832
|
export interface UpdateQueryBuilderProps {
|
|
814
833
|
readonly queryId: QueryId;
|
|
@@ -12,6 +12,7 @@ const prevent_await_js_1 = require("../util/prevent-await.js");
|
|
|
12
12
|
const object_utils_js_1 = require("../util/object-utils.js");
|
|
13
13
|
const update_result_js_1 = require("./update-result.js");
|
|
14
14
|
const no_result_error_js_1 = require("./no-result-error.js");
|
|
15
|
+
const explain_node_js_1 = require("../operation-node/explain-node.js");
|
|
15
16
|
class UpdateQueryBuilder {
|
|
16
17
|
#props;
|
|
17
18
|
constructor(props) {
|
|
@@ -332,6 +333,30 @@ class UpdateQueryBuilder {
|
|
|
332
333
|
}
|
|
333
334
|
return result;
|
|
334
335
|
}
|
|
336
|
+
/**
|
|
337
|
+
* Executes query with `explain` statement before `update` keyword.
|
|
338
|
+
*
|
|
339
|
+
* ```ts
|
|
340
|
+
* const explained = await db
|
|
341
|
+
* .updateTable('person')
|
|
342
|
+
* .set(updates)
|
|
343
|
+
* .where('id', '=', 123)
|
|
344
|
+
* .explain('json')
|
|
345
|
+
* ```
|
|
346
|
+
*
|
|
347
|
+
* The generated SQL (MySQL):
|
|
348
|
+
*
|
|
349
|
+
* ```sql
|
|
350
|
+
* explain format=json update `person` set `first_name` = ?, `last_name` = ? where `id` = ?
|
|
351
|
+
* ```
|
|
352
|
+
*/
|
|
353
|
+
async explain(format, options) {
|
|
354
|
+
const builder = new UpdateQueryBuilder({
|
|
355
|
+
...this.#props,
|
|
356
|
+
queryNode: update_query_node_js_1.UpdateQueryNode.cloneWithExplain(this.#props.queryNode, explain_node_js_1.ExplainNode.create(format, options)),
|
|
357
|
+
});
|
|
358
|
+
return await builder.execute();
|
|
359
|
+
}
|
|
335
360
|
}
|
|
336
361
|
exports.UpdateQueryBuilder = UpdateQueryBuilder;
|
|
337
362
|
(0, prevent_await_js_1.preventAwait)(UpdateQueryBuilder, "don't await UpdateQueryBuilder instances directly. To execute the query you need to call `execute` or `executeTakeFirst`.");
|
|
@@ -71,6 +71,7 @@ import { CommonTableExpressionNameNode } from '../operation-node/common-table-ex
|
|
|
71
71
|
import { SelectModifierNode } from '../operation-node/select-modifier-node.js';
|
|
72
72
|
import { CreateTypeNode } from '../operation-node/create-type-node.js';
|
|
73
73
|
import { DropTypeNode } from '../operation-node/drop-type-node.js';
|
|
74
|
+
import { ExplainNode } from '../operation-node/explain-node.js';
|
|
74
75
|
export declare class DefaultQueryCompiler extends OperationNodeVisitor implements QueryCompiler {
|
|
75
76
|
#private;
|
|
76
77
|
protected get numParameters(): number;
|
|
@@ -149,11 +150,16 @@ export declare class DefaultQueryCompiler extends OperationNodeVisitor implement
|
|
|
149
150
|
protected visitSelectModifier(node: SelectModifierNode): void;
|
|
150
151
|
protected visitCreateType(node: CreateTypeNode): void;
|
|
151
152
|
protected visitDropType(node: DropTypeNode): void;
|
|
153
|
+
protected visitExplain(node: ExplainNode): void;
|
|
152
154
|
protected append(str: string): void;
|
|
153
155
|
protected appendValue(parameter: unknown): void;
|
|
154
156
|
protected getLeftIdentifierWrapper(): string;
|
|
155
157
|
protected getRightIdentifierWrapper(): string;
|
|
156
158
|
protected getCurrentParameterPlaceholder(): string;
|
|
159
|
+
protected getLeftExplainOptionsWrapper(): string;
|
|
160
|
+
protected getExplainOptionAssignment(): string;
|
|
161
|
+
protected getExplainOptionsDelimiter(): string;
|
|
162
|
+
protected getRightExplainOptionsWrapper(): string;
|
|
157
163
|
protected sanitizeIdentifier(identifier: string): string;
|
|
158
164
|
protected addParameter(parameter: unknown): void;
|
|
159
165
|
protected appendImmediateValue(value: unknown): void;
|
|
@@ -32,6 +32,10 @@ class DefaultQueryCompiler extends operation_node_visitor_js_1.OperationNodeVisi
|
|
|
32
32
|
!insert_query_node_js_1.InsertQueryNode.is(this.parentNode) &&
|
|
33
33
|
!create_view_node_js_1.CreateViewNode.is(this.parentNode) &&
|
|
34
34
|
!union_node_js_1.UnionNode.is(this.parentNode);
|
|
35
|
+
if (this.parentNode === undefined && node.explain) {
|
|
36
|
+
this.visitNode(node.explain);
|
|
37
|
+
this.append(' ');
|
|
38
|
+
}
|
|
35
39
|
if (wrapInParens) {
|
|
36
40
|
this.append('(');
|
|
37
41
|
}
|
|
@@ -127,6 +131,10 @@ class DefaultQueryCompiler extends operation_node_visitor_js_1.OperationNodeVisi
|
|
|
127
131
|
}
|
|
128
132
|
visitInsertQuery(node) {
|
|
129
133
|
const isSubQuery = this.nodeStack.find(query_node_js_1.QueryNode.is) !== node;
|
|
134
|
+
if (!isSubQuery && node.explain) {
|
|
135
|
+
this.visitNode(node.explain);
|
|
136
|
+
this.append(' ');
|
|
137
|
+
}
|
|
130
138
|
if (isSubQuery) {
|
|
131
139
|
this.append('(');
|
|
132
140
|
}
|
|
@@ -171,6 +179,10 @@ class DefaultQueryCompiler extends operation_node_visitor_js_1.OperationNodeVisi
|
|
|
171
179
|
}
|
|
172
180
|
visitDeleteQuery(node) {
|
|
173
181
|
const isSubQuery = this.nodeStack.find(query_node_js_1.QueryNode.is) !== node;
|
|
182
|
+
if (!isSubQuery && node.explain) {
|
|
183
|
+
this.visitNode(node.explain);
|
|
184
|
+
this.append(' ');
|
|
185
|
+
}
|
|
174
186
|
if (isSubQuery) {
|
|
175
187
|
this.append('(');
|
|
176
188
|
}
|
|
@@ -227,6 +239,9 @@ class DefaultQueryCompiler extends operation_node_visitor_js_1.OperationNodeVisi
|
|
|
227
239
|
this.append(this.getRightIdentifierWrapper());
|
|
228
240
|
}
|
|
229
241
|
compileUnwrappedIdentifier(node) {
|
|
242
|
+
if (!(0, object_utils_js_1.isString)(node.identifier)) {
|
|
243
|
+
throw new Error('a non-string identifier was passed to compileUnwrappedIdentifier.');
|
|
244
|
+
}
|
|
230
245
|
this.append(this.sanitizeIdentifier(node.identifier));
|
|
231
246
|
}
|
|
232
247
|
visitFilter(node) {
|
|
@@ -311,6 +326,10 @@ class DefaultQueryCompiler extends operation_node_visitor_js_1.OperationNodeVisi
|
|
|
311
326
|
}
|
|
312
327
|
visitCreateTable(node) {
|
|
313
328
|
this.append('create ');
|
|
329
|
+
if (node.frontModifiers) {
|
|
330
|
+
this.compileList(node.frontModifiers, ' ');
|
|
331
|
+
this.append(' ');
|
|
332
|
+
}
|
|
314
333
|
if (node.temporary) {
|
|
315
334
|
this.append('temporary ');
|
|
316
335
|
}
|
|
@@ -326,6 +345,10 @@ class DefaultQueryCompiler extends operation_node_visitor_js_1.OperationNodeVisi
|
|
|
326
345
|
this.append(' on commit ');
|
|
327
346
|
this.append(node.onCommit);
|
|
328
347
|
}
|
|
348
|
+
if (node.endModifiers) {
|
|
349
|
+
this.append(' ');
|
|
350
|
+
this.compileList(node.endModifiers, ' ');
|
|
351
|
+
}
|
|
329
352
|
}
|
|
330
353
|
visitColumnDefinition(node) {
|
|
331
354
|
this.visitNode(node.column);
|
|
@@ -412,6 +435,10 @@ class DefaultQueryCompiler extends operation_node_visitor_js_1.OperationNodeVisi
|
|
|
412
435
|
}
|
|
413
436
|
visitUpdateQuery(node) {
|
|
414
437
|
const isSubQuery = this.nodeStack.find(query_node_js_1.QueryNode.is) !== node;
|
|
438
|
+
if (!isSubQuery && node.explain) {
|
|
439
|
+
this.visitNode(node.explain);
|
|
440
|
+
this.append(' ');
|
|
441
|
+
}
|
|
415
442
|
if (isSubQuery) {
|
|
416
443
|
this.append('(');
|
|
417
444
|
}
|
|
@@ -806,6 +833,25 @@ class DefaultQueryCompiler extends operation_node_visitor_js_1.OperationNodeVisi
|
|
|
806
833
|
}
|
|
807
834
|
this.visitNode(node.name);
|
|
808
835
|
}
|
|
836
|
+
visitExplain(node) {
|
|
837
|
+
this.append('explain');
|
|
838
|
+
if (node.options || node.format) {
|
|
839
|
+
this.append(' ');
|
|
840
|
+
this.append(this.getLeftExplainOptionsWrapper());
|
|
841
|
+
if (node.options) {
|
|
842
|
+
this.visitNode(node.options);
|
|
843
|
+
if (node.format) {
|
|
844
|
+
this.append(this.getExplainOptionsDelimiter());
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
if (node.format) {
|
|
848
|
+
this.append('format');
|
|
849
|
+
this.append(this.getExplainOptionAssignment());
|
|
850
|
+
this.append(node.format);
|
|
851
|
+
}
|
|
852
|
+
this.append(this.getRightExplainOptionsWrapper());
|
|
853
|
+
}
|
|
854
|
+
}
|
|
809
855
|
append(str) {
|
|
810
856
|
this.#sql += str;
|
|
811
857
|
}
|
|
@@ -822,10 +868,19 @@ class DefaultQueryCompiler extends operation_node_visitor_js_1.OperationNodeVisi
|
|
|
822
868
|
getCurrentParameterPlaceholder() {
|
|
823
869
|
return '$' + this.numParameters;
|
|
824
870
|
}
|
|
871
|
+
getLeftExplainOptionsWrapper() {
|
|
872
|
+
return '(';
|
|
873
|
+
}
|
|
874
|
+
getExplainOptionAssignment() {
|
|
875
|
+
return ' ';
|
|
876
|
+
}
|
|
877
|
+
getExplainOptionsDelimiter() {
|
|
878
|
+
return ', ';
|
|
879
|
+
}
|
|
880
|
+
getRightExplainOptionsWrapper() {
|
|
881
|
+
return ')';
|
|
882
|
+
}
|
|
825
883
|
sanitizeIdentifier(identifier) {
|
|
826
|
-
if (!(0, object_utils_js_1.isString)(identifier)) {
|
|
827
|
-
throw new Error('a non-string identifier was passed to sanitizeIdentifier.');
|
|
828
|
-
}
|
|
829
884
|
const leftWrap = this.getLeftIdentifierWrapper();
|
|
830
885
|
const rightWrap = this.getRightIdentifierWrapper();
|
|
831
886
|
let sanitized = '';
|
|
@@ -1,5 +1,101 @@
|
|
|
1
1
|
import { RawBuilder } from './raw-builder.js';
|
|
2
2
|
export interface Sql {
|
|
3
|
+
/**
|
|
4
|
+
* Template tag for creating raw SQL snippets and queries.
|
|
5
|
+
*
|
|
6
|
+
* ```ts
|
|
7
|
+
* import { sql } from 'kysely'
|
|
8
|
+
*
|
|
9
|
+
* const id = 123
|
|
10
|
+
*
|
|
11
|
+
* const snippet = sql<Person[]>`select * from person where id = ${id}`
|
|
12
|
+
* ```
|
|
13
|
+
*
|
|
14
|
+
* Substitutions (the things inside `${}`) are automatically passed to the database
|
|
15
|
+
* as parameters and are NOT interpolated to the SQL string. There's no need to worry
|
|
16
|
+
* about SQL injection vulnerabilities.
|
|
17
|
+
*
|
|
18
|
+
* If you need your substitutions to be interpreted as identifiers, value literals or
|
|
19
|
+
* lists of things, see the {@link Sql.ref}, {@link Sql.table}, {@link Sql.id},
|
|
20
|
+
* {@link Sql.literal}, {@link Sql.raw} and {@link Sql.join} functions.
|
|
21
|
+
*
|
|
22
|
+
* You can pass sql snippets returned by the `sql` tag pretty much anywhere. Whenever
|
|
23
|
+
* something can't be done using the Kysely API, you should be able to drop down to
|
|
24
|
+
* raw SQL using the `sql` tag. Here's an example query that uses raw sql in a bunch
|
|
25
|
+
* of methods:
|
|
26
|
+
*
|
|
27
|
+
* ```ts
|
|
28
|
+
* const persons = await db
|
|
29
|
+
* .selectFrom('person')
|
|
30
|
+
* .select(
|
|
31
|
+
* // If you use `sql` in a select statement, remember to call the `as`
|
|
32
|
+
* // method to give it an alias. Otherwise Kysely is not able to add
|
|
33
|
+
* // the column to the result type.
|
|
34
|
+
* sql<string>`concat(first_name, ' ', last_name)`.as('full_name')
|
|
35
|
+
* )
|
|
36
|
+
* .where(sql`birthdate between ${date1} and ${date2}`)
|
|
37
|
+
* // Here we assume we have list of nicknames for the person
|
|
38
|
+
* // (a list of strings) and we use the PostgreSQL `@>` operator
|
|
39
|
+
* // to test if all of them are valid nicknames for the user.
|
|
40
|
+
* .where('nicknames', '@>', sql`ARRAY[${sql.join(nicknames)}]`)
|
|
41
|
+
* .orderBy(sql`concat(first_name, ' ', last_name)`)
|
|
42
|
+
* .execute()
|
|
43
|
+
* ```
|
|
44
|
+
*
|
|
45
|
+
* The generated SQL (PostgreSQL):
|
|
46
|
+
*
|
|
47
|
+
* ```sql
|
|
48
|
+
* select concat(first_name, ' ', last_name) as "full_name"
|
|
49
|
+
* from "person"
|
|
50
|
+
* where birthdate between $1 and $2
|
|
51
|
+
* and "nicknames" @> ARRAY[$3, $4, $5, $6, $7, $8, $9, $10]
|
|
52
|
+
* order by concat(first_name, ' ', last_name)
|
|
53
|
+
* ```
|
|
54
|
+
*
|
|
55
|
+
* SQL snippets can be executed by calling the `execute` method and passing a `Kysely`
|
|
56
|
+
* instance as the only argument:
|
|
57
|
+
*
|
|
58
|
+
* ```ts
|
|
59
|
+
* const result = await sql<Person[]>`select * from person`.execute(db)
|
|
60
|
+
* ```
|
|
61
|
+
*
|
|
62
|
+
* You can merge other `sql` expressions and queries using substitutions:
|
|
63
|
+
*
|
|
64
|
+
* ```ts
|
|
65
|
+
* const petName = db.selectFrom('pet').select('name').limit(1)
|
|
66
|
+
* const fullName = sql`concat(first_name, ' ', last_name)`
|
|
67
|
+
*
|
|
68
|
+
* sql`
|
|
69
|
+
* select ${fullName} as full_name, ${petName} as pet_name
|
|
70
|
+
* from person
|
|
71
|
+
* `
|
|
72
|
+
* ```
|
|
73
|
+
*
|
|
74
|
+
* Substitutions also handle {@link ExpressionBuilder.ref},
|
|
75
|
+
* {@link DynamicModule.ref} and pretty much anything else you
|
|
76
|
+
* throw at it. Here's an example of calling a function in a
|
|
77
|
+
* type-safe way:
|
|
78
|
+
*
|
|
79
|
+
* ```ts
|
|
80
|
+
* db.selectFrom('person')
|
|
81
|
+
* .select([
|
|
82
|
+
* 'first_name',
|
|
83
|
+
* 'last_name',
|
|
84
|
+
* (eb) => {
|
|
85
|
+
* // The `eb.ref` method is type-safe and only accepts
|
|
86
|
+
* // column references that are possible.
|
|
87
|
+
* const firstName = eb.ref('first_name')
|
|
88
|
+
* const lastName = eb.ref('last_name')
|
|
89
|
+
*
|
|
90
|
+
* const fullName = sql<string>`concat(${firstName}, ' ', ${lastName})`
|
|
91
|
+
* return fullName.as('full_name')
|
|
92
|
+
* }
|
|
93
|
+
* ])
|
|
94
|
+
* ```
|
|
95
|
+
*
|
|
96
|
+
* don't know if that amount of ceremony is worth the small increase in
|
|
97
|
+
* type-safety though... But it's possible.
|
|
98
|
+
*/
|
|
3
99
|
<T = unknown>(sqlFragments: TemplateStringsArray, ...parameters: unknown[]): RawBuilder<T>;
|
|
4
100
|
/**
|
|
5
101
|
* This can be used to add runtime column references to SQL snippets.
|
|
@@ -232,100 +328,4 @@ export interface Sql {
|
|
|
232
328
|
*/
|
|
233
329
|
join(array: unknown[], separator?: RawBuilder<any>): RawBuilder<unknown>;
|
|
234
330
|
}
|
|
235
|
-
/**
|
|
236
|
-
* Template tag for creating raw SQL snippets and queries.
|
|
237
|
-
*
|
|
238
|
-
* ```ts
|
|
239
|
-
* import { sql } from 'kysely'
|
|
240
|
-
*
|
|
241
|
-
* const id = 123
|
|
242
|
-
*
|
|
243
|
-
* const snippet = sql<Person[]>`select * from person where id = ${id}`
|
|
244
|
-
* ```
|
|
245
|
-
*
|
|
246
|
-
* Substitutions (the things inside `${}`) are automatically passed to the database
|
|
247
|
-
* as parameters and are NOT interpolated to the SQL string. There's no need to worry
|
|
248
|
-
* about SQL injection vulnerabilities.
|
|
249
|
-
*
|
|
250
|
-
* If you need your substitutions to be interpreted as identifiers, value literals or
|
|
251
|
-
* lists of things, see the {@link Sql.ref}, {@link Sql.table}, {@link Sql.id},
|
|
252
|
-
* {@link Sql.literal}, {@link Sql.raw} and {@link Sql.join} functions.
|
|
253
|
-
*
|
|
254
|
-
* You can pass sql snippets returned by the `sql` tag pretty much anywhere. Whenever
|
|
255
|
-
* something can't be done using the Kysely API, you should be able to drop down to
|
|
256
|
-
* raw SQL using the `sql` tag. Here's an example query that uses raw sql in a bunch
|
|
257
|
-
* of methods:
|
|
258
|
-
*
|
|
259
|
-
* ```ts
|
|
260
|
-
* const persons = await db
|
|
261
|
-
* .selectFrom('person')
|
|
262
|
-
* .select(
|
|
263
|
-
* // If you use `sql` in a select statement, remember to call the `as`
|
|
264
|
-
* // method to give it an alias. Otherwise Kysely is not able to add
|
|
265
|
-
* // the column to the result type.
|
|
266
|
-
* sql<string>`concat(first_name, ' ', last_name)`.as('full_name')
|
|
267
|
-
* )
|
|
268
|
-
* .where(sql`birthdate between ${date1} and ${date2}`)
|
|
269
|
-
* // Here we assume we have list of nicknames for the person
|
|
270
|
-
* // (a list of strings) and we use the PostgreSQL `@>` operator
|
|
271
|
-
* // to test if all of them are valid nicknames for the user.
|
|
272
|
-
* .where('nicknames', '@>', sql`ARRAY[${sql.join(nicknames)}]`)
|
|
273
|
-
* .orderBy(sql`concat(first_name, ' ', last_name)`)
|
|
274
|
-
* .execute()
|
|
275
|
-
* ```
|
|
276
|
-
*
|
|
277
|
-
* The generated SQL (PostgreSQL):
|
|
278
|
-
*
|
|
279
|
-
* ```sql
|
|
280
|
-
* select concat(first_name, ' ', last_name) as "full_name"
|
|
281
|
-
* from "person"
|
|
282
|
-
* where birthdate between $1 and $2
|
|
283
|
-
* and "nicknames" @> ARRAY[$3, $4, $5, $6, $7, $8, $9, $10]
|
|
284
|
-
* order by concat(first_name, ' ', last_name)
|
|
285
|
-
* ```
|
|
286
|
-
*
|
|
287
|
-
* SQL snippets can be executed by calling the `execute` method and passing a `Kysely`
|
|
288
|
-
* instance as the only argument:
|
|
289
|
-
*
|
|
290
|
-
* ```ts
|
|
291
|
-
* const result = await sql<Person[]>`select * from person`.execute(db)
|
|
292
|
-
* ```
|
|
293
|
-
*
|
|
294
|
-
* You can merge other `sql` expressions and queries using substitutions:
|
|
295
|
-
*
|
|
296
|
-
* ```ts
|
|
297
|
-
* const petName = db.selectFrom('pet').select('name').limit(1)
|
|
298
|
-
* const fullName = sql`concat(first_name, ' ', last_name)`
|
|
299
|
-
*
|
|
300
|
-
* sql`
|
|
301
|
-
* select ${fullName} as full_name, ${petName} as pet_name
|
|
302
|
-
* from person
|
|
303
|
-
* `
|
|
304
|
-
* ```
|
|
305
|
-
*
|
|
306
|
-
* Substitutions also handle {@link ExpressionBuilder.ref},
|
|
307
|
-
* {@link DynamicModule.ref} and pretty much anything else you
|
|
308
|
-
* throw at it. Here's an example of calling a function in a
|
|
309
|
-
* type-safe way:
|
|
310
|
-
*
|
|
311
|
-
* ```ts
|
|
312
|
-
* db.selectFrom('person')
|
|
313
|
-
* .select([
|
|
314
|
-
* 'first_name',
|
|
315
|
-
* 'last_name',
|
|
316
|
-
* (eb) => {
|
|
317
|
-
* // The `eb.ref` method is type-safe and only accepts
|
|
318
|
-
* // column references that are possible.
|
|
319
|
-
* const firstName = eb.ref('first_name')
|
|
320
|
-
* const lastName = eb.ref('last_name')
|
|
321
|
-
*
|
|
322
|
-
* const fullName = sql<string>`concat(${firstName}, ' ', ${lastName})`
|
|
323
|
-
* return fullName.as('full_name')
|
|
324
|
-
* }
|
|
325
|
-
* ])
|
|
326
|
-
* ```
|
|
327
|
-
*
|
|
328
|
-
* don't know if that amount of ceremony is worth the small increase in
|
|
329
|
-
* type-safety though... But it's possible.
|
|
330
|
-
*/
|
|
331
331
|
export declare const sql: Sql;
|