kysely 0.7.7 → 0.8.1
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 +29 -2
- package/dist/cjs/dialect/dialect-adapter.d.ts +19 -12
- package/dist/cjs/dialect/dialect.d.ts +1 -1
- package/dist/cjs/dialect/mysql/mysql-adapter.js +6 -0
- package/dist/cjs/dialect/mysql/mysql-driver.js +5 -5
- package/dist/cjs/dialect/postgres/postgres-driver.js +5 -5
- package/dist/cjs/driver/database-connection.d.ts +5 -0
- package/dist/cjs/driver/driver.d.ts +3 -5
- package/dist/cjs/index.d.ts +1 -1
- package/dist/cjs/kysely.d.ts +31 -1
- package/dist/cjs/kysely.js +33 -1
- package/dist/cjs/operation-node/operator-node.d.ts +1 -1
- package/dist/cjs/parser/data-type-parser.d.ts +1 -1
- package/dist/cjs/parser/default-value-parser.d.ts +1 -1
- package/dist/cjs/parser/filter-parser.d.ts +1 -1
- package/dist/cjs/parser/insert-values-parser.d.ts +2 -2
- package/dist/cjs/parser/join-parser.d.ts +1 -1
- package/dist/cjs/parser/on-conflict-parser.d.ts +1 -1
- package/dist/cjs/parser/order-by-parser.d.ts +1 -1
- package/dist/cjs/parser/reference-parser.d.ts +3 -2
- package/dist/cjs/parser/returning-parser.d.ts +1 -1
- package/dist/cjs/parser/select-parser.d.ts +1 -1
- package/dist/cjs/parser/table-parser.d.ts +17 -6
- package/dist/cjs/parser/update-set-parser.d.ts +2 -2
- package/dist/cjs/parser/value-parser.d.ts +1 -1
- package/dist/cjs/parser/with-parser.d.ts +1 -1
- package/dist/cjs/plugin/camel-case/camel-case-plugin.d.ts +4 -3
- package/dist/cjs/plugin/kysely-plugin.d.ts +9 -5
- package/dist/cjs/plugin/with-schema/with-schema-plugin.d.ts +3 -2
- package/dist/cjs/query-builder/expression-builder.d.ts +33 -0
- package/dist/cjs/query-builder/expression-builder.js +35 -0
- package/dist/cjs/query-builder/function-builder.d.ts +112 -0
- package/dist/cjs/query-builder/function-builder.js +138 -0
- package/dist/cjs/query-builder/query-builder.d.ts +8 -8
- package/dist/cjs/query-compiler/compiled-query.d.ts +1 -1
- package/dist/cjs/query-compiler/default-query-compiler.d.ts +2 -2
- package/dist/cjs/query-compiler/default-query-compiler.js +9 -9
- package/dist/cjs/query-compiler/query-compiler.d.ts +3 -0
- package/dist/cjs/query-creator.d.ts +9 -9
- package/dist/cjs/query-creator.js +11 -10
- package/dist/cjs/raw-builder/raw-builder.d.ts +14 -5
- package/dist/cjs/raw-builder/raw-builder.js +25 -20
- package/dist/cjs/schema/alter-table-builder.d.ts +1 -1
- package/dist/cjs/schema/column-definition-builder.d.ts +1 -1
- package/dist/cjs/util/generated-placeholder.d.ts +2 -2
- package/dist/cjs/util/generated-placeholder.js +2 -2
- package/dist/cjs/util/random-string.js +3 -3
- package/dist/cjs/{query-builder → util}/type-utils.d.ts +11 -3
- package/dist/cjs/{query-builder → util}/type-utils.js +0 -0
- package/dist/esm/dialect/dialect-adapter.d.ts +19 -12
- package/dist/esm/dialect/dialect.d.ts +1 -1
- package/dist/esm/dialect/mysql/mysql-adapter.js +6 -0
- package/dist/esm/dialect/mysql/mysql-driver.js +5 -5
- package/dist/esm/dialect/postgres/postgres-driver.js +5 -5
- package/dist/esm/driver/database-connection.d.ts +5 -0
- package/dist/esm/driver/driver.d.ts +3 -5
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/kysely.d.ts +31 -1
- package/dist/esm/kysely.js +34 -2
- package/dist/esm/operation-node/operator-node.d.ts +1 -1
- package/dist/esm/parser/data-type-parser.d.ts +1 -1
- package/dist/esm/parser/default-value-parser.d.ts +1 -1
- package/dist/esm/parser/filter-parser.d.ts +1 -1
- package/dist/esm/parser/insert-values-parser.d.ts +2 -2
- package/dist/esm/parser/join-parser.d.ts +1 -1
- package/dist/esm/parser/on-conflict-parser.d.ts +1 -1
- package/dist/esm/parser/order-by-parser.d.ts +1 -1
- package/dist/esm/parser/reference-parser.d.ts +3 -2
- package/dist/esm/parser/returning-parser.d.ts +1 -1
- package/dist/esm/parser/select-parser.d.ts +1 -1
- package/dist/esm/parser/table-parser.d.ts +17 -6
- package/dist/esm/parser/update-set-parser.d.ts +2 -2
- package/dist/esm/parser/value-parser.d.ts +1 -1
- package/dist/esm/parser/with-parser.d.ts +1 -1
- package/dist/esm/plugin/camel-case/camel-case-plugin.d.ts +4 -3
- package/dist/esm/plugin/kysely-plugin.d.ts +9 -5
- package/dist/esm/plugin/with-schema/with-schema-plugin.d.ts +3 -2
- package/dist/esm/query-builder/expression-builder.d.ts +33 -0
- package/dist/esm/query-builder/expression-builder.js +35 -0
- package/dist/esm/query-builder/function-builder.d.ts +112 -0
- package/dist/esm/query-builder/function-builder.js +134 -0
- package/dist/esm/query-builder/query-builder.d.ts +8 -8
- package/dist/esm/query-compiler/compiled-query.d.ts +1 -1
- package/dist/esm/query-compiler/default-query-compiler.d.ts +2 -2
- package/dist/esm/query-compiler/default-query-compiler.js +9 -9
- package/dist/esm/query-compiler/query-compiler.d.ts +3 -0
- package/dist/esm/query-creator.d.ts +9 -9
- package/dist/esm/query-creator.js +11 -10
- package/dist/esm/raw-builder/raw-builder.d.ts +14 -5
- package/dist/esm/raw-builder/raw-builder.js +25 -20
- package/dist/esm/schema/alter-table-builder.d.ts +1 -1
- package/dist/esm/schema/column-definition-builder.d.ts +1 -1
- package/dist/esm/util/generated-placeholder.d.ts +2 -2
- package/dist/esm/util/generated-placeholder.js +1 -1
- package/dist/esm/util/random-string.js +3 -3
- package/dist/esm/{query-builder → util}/type-utils.d.ts +11 -3
- package/dist/esm/{query-builder → util}/type-utils.js +0 -0
- package/package.json +8 -8
|
@@ -2,12 +2,12 @@ import { ColumnUpdateNode } from '../operation-node/column-update-node.js';
|
|
|
2
2
|
import { RawNode } from '../operation-node/raw-node.js';
|
|
3
3
|
import { SelectQueryNode } from '../operation-node/select-query-node.js';
|
|
4
4
|
import { ValueNode } from '../operation-node/value-node.js';
|
|
5
|
-
import { AnyQueryBuilder, AnyRawBuilder, QueryBuilderFactory, RawBuilderFactory } from '../
|
|
5
|
+
import { AnyQueryBuilder, AnyRawBuilder, QueryBuilderFactory, RawBuilderFactory } from '../util/type-utils.js';
|
|
6
6
|
import { PrimitiveValue } from '../util/object-utils.js';
|
|
7
7
|
import { ParseContext } from './parse-context.js';
|
|
8
8
|
export declare type MutationObject<DB, TB extends keyof DB> = {
|
|
9
9
|
[C in keyof DB[TB]]?: MutationValueExpression<DB, TB, DB[TB][C]>;
|
|
10
10
|
};
|
|
11
|
-
export declare type MutationValueExpression<DB, TB extends keyof DB, T
|
|
11
|
+
export declare type MutationValueExpression<DB, TB extends keyof DB, T> = T | AnyQueryBuilder | QueryBuilderFactory<DB, TB> | AnyRawBuilder | RawBuilderFactory<DB, TB>;
|
|
12
12
|
export declare function parseUpdateObject(ctx: ParseContext, row: MutationObject<any, any>): ReadonlyArray<ColumnUpdateNode>;
|
|
13
13
|
export declare function parseMutationValueExpression(ctx: ParseContext, value: MutationValueExpression<any, any, PrimitiveValue>): ValueNode | RawNode | SelectQueryNode;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ValueExpressionNode } from '../operation-node/operation-node-utils.js';
|
|
2
|
-
import { AnyQueryBuilder, AnyRawBuilder, QueryBuilderFactory, RawBuilderFactory } from '../
|
|
2
|
+
import { AnyQueryBuilder, AnyRawBuilder, QueryBuilderFactory, RawBuilderFactory } from '../util/type-utils.js';
|
|
3
3
|
import { ExtractTypeFromReferenceExpression } from './reference-parser.js';
|
|
4
4
|
import { ParseContext } from './parse-context.js';
|
|
5
5
|
export declare type ValueExpression<DB, TB extends keyof DB, RE> = ExtractTypeFromReferenceExpression<DB, TB, RE> | AnyQueryBuilder | QueryBuilderFactory<DB, TB> | AnyRawBuilder | RawBuilderFactory<DB, TB>;
|
|
@@ -2,7 +2,7 @@ import { CommonTableExpressionNode } from '../operation-node/common-table-expres
|
|
|
2
2
|
import { QueryBuilder } from '../query-builder/query-builder.js';
|
|
3
3
|
import { QueryCreator } from '../query-creator.js';
|
|
4
4
|
import { RawBuilder } from '../raw-builder/raw-builder.js';
|
|
5
|
-
import { AnyRawBuilder } from '../
|
|
5
|
+
import { AnyRawBuilder } from '../util/type-utils.js';
|
|
6
6
|
import { ParseContext } from './parse-context.js';
|
|
7
7
|
export declare type CommonTableExpression<DB> = (creator: QueryCreator<DB>) => QueryBuilder<DB, any> | AnyRawBuilder;
|
|
8
8
|
export declare type QueryCreatorWithCommonTableExpression<DB, N extends string, E extends CommonTableExpression<DB>> = QueryCreator<DB & Record<N, ExtractRowTypeFromCommonTableExpression<E>>>;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { QueryResult } from '../../driver/database-connection.js';
|
|
2
2
|
import { RootOperationNode } from '../../query-compiler/query-compiler.js';
|
|
3
|
-
import {
|
|
3
|
+
import { UnknownRow } from '../../util/type-utils.js';
|
|
4
|
+
import { KyselyPlugin, PluginTransformQueryArgs, PluginTransformResultArgs } from '../kysely-plugin.js';
|
|
4
5
|
export interface CamelCasePluginOptions {
|
|
5
6
|
/**
|
|
6
7
|
* If true, camelCase is transformed into upper case SNAKE_CASE.
|
|
@@ -94,8 +95,8 @@ export declare class CamelCasePlugin implements KyselyPlugin {
|
|
|
94
95
|
#private;
|
|
95
96
|
constructor(opt?: CamelCasePluginOptions);
|
|
96
97
|
transformQuery(args: PluginTransformQueryArgs): RootOperationNode;
|
|
97
|
-
transformResult(args: PluginTransformResultArgs): Promise<QueryResult<
|
|
98
|
-
protected mapRow(row:
|
|
98
|
+
transformResult(args: PluginTransformResultArgs): Promise<QueryResult<UnknownRow>>;
|
|
99
|
+
protected mapRow(row: UnknownRow): UnknownRow;
|
|
99
100
|
protected snakeCase(str: string): string;
|
|
100
101
|
protected camelCase(str: string): string;
|
|
101
102
|
}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { QueryResult } from '../driver/database-connection.js';
|
|
2
2
|
import { RootOperationNode } from '../query-compiler/query-compiler.js';
|
|
3
3
|
import { QueryId } from '../util/query-id.js';
|
|
4
|
+
import { UnknownRow } from '../util/type-utils.js';
|
|
4
5
|
export interface KyselyPlugin {
|
|
5
6
|
/**
|
|
6
7
|
* This is called for each query before it is executed. You can modify the query by
|
|
7
8
|
* transforming its {@link OperationNode} tree provided in {@link PluginTransformQueryArgs.node | args.node}
|
|
8
|
-
* and returning the transformed tree. You'd usually
|
|
9
|
+
* and returning the transformed tree. You'd usually want to use an {@link OperationNodeTransformer}
|
|
9
10
|
* for this.
|
|
10
11
|
*
|
|
11
12
|
* If you need to pass some query-related data between this method and `transformResult` you
|
|
@@ -22,10 +23,14 @@ export interface KyselyPlugin {
|
|
|
22
23
|
*
|
|
23
24
|
* transformResult(args: PluginTransformResultArgs): QueryResult<AnyRow> {
|
|
24
25
|
* const data = this.data.get(args.queryId)
|
|
25
|
-
* return
|
|
26
|
+
* return args.result
|
|
26
27
|
* }
|
|
27
28
|
* }
|
|
28
29
|
* ```
|
|
30
|
+
*
|
|
31
|
+
* You should use a `WeakMap` instead of a `Map` or some other strong references because `transformQuery`
|
|
32
|
+
* is not always matched by a call to `transformResult` which would leave orphaned items in the map
|
|
33
|
+
* and cause a memory leak.
|
|
29
34
|
*/
|
|
30
35
|
transformQuery(args: PluginTransformQueryArgs): RootOperationNode;
|
|
31
36
|
/**
|
|
@@ -33,14 +38,13 @@ export interface KyselyPlugin {
|
|
|
33
38
|
* of the query can be accessed through {@link PluginTransformResultArgs.result | args.result}.
|
|
34
39
|
* You can modify the result and return the modifier result.
|
|
35
40
|
*/
|
|
36
|
-
transformResult(args: PluginTransformResultArgs): Promise<QueryResult<
|
|
41
|
+
transformResult(args: PluginTransformResultArgs): Promise<QueryResult<UnknownRow>>;
|
|
37
42
|
}
|
|
38
43
|
export interface PluginTransformQueryArgs {
|
|
39
44
|
readonly queryId: QueryId;
|
|
40
45
|
readonly node: RootOperationNode;
|
|
41
46
|
}
|
|
42
|
-
export declare type AnyRow = Record<string, unknown>;
|
|
43
47
|
export interface PluginTransformResultArgs {
|
|
44
48
|
readonly queryId: QueryId;
|
|
45
|
-
readonly result: QueryResult<
|
|
49
|
+
readonly result: QueryResult<UnknownRow>;
|
|
46
50
|
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { QueryResult } from '../../driver/database-connection.js';
|
|
2
2
|
import { RootOperationNode } from '../../query-compiler/query-compiler.js';
|
|
3
|
-
import {
|
|
3
|
+
import { KyselyPlugin, PluginTransformQueryArgs, PluginTransformResultArgs } from '../kysely-plugin.js';
|
|
4
|
+
import { UnknownRow } from '../../util/type-utils.js';
|
|
4
5
|
export declare class WithSchemaPlugin implements KyselyPlugin {
|
|
5
6
|
#private;
|
|
6
7
|
constructor(schema: string);
|
|
7
8
|
transformQuery(args: PluginTransformQueryArgs): RootOperationNode;
|
|
8
|
-
transformResult(args: PluginTransformResultArgs): Promise<QueryResult<
|
|
9
|
+
transformResult(args: PluginTransformResultArgs): Promise<QueryResult<UnknownRow>>;
|
|
9
10
|
}
|
|
@@ -1,9 +1,42 @@
|
|
|
1
1
|
import { TableExpression, QueryBuilderWithTable } from '../parser/table-parser.js';
|
|
2
2
|
import { NoopQueryExecutor } from '../query-executor/noop-query-executor.js';
|
|
3
3
|
import { ParseContext } from '../parser/parse-context.js';
|
|
4
|
+
import { FunctionBuilder } from './function-builder.js';
|
|
4
5
|
export declare class ExpressionBuilder<DB, TB extends keyof DB> {
|
|
5
6
|
#private;
|
|
6
7
|
constructor(props: ExpressionBuilderProps);
|
|
8
|
+
/**
|
|
9
|
+
* Returns a {@link FunctionBuilder} that can be used to write type safe function
|
|
10
|
+
* calls.
|
|
11
|
+
*
|
|
12
|
+
* The difference between this and {@link Kysely.fn} is that this one is more
|
|
13
|
+
* type safe. You can only refer to columns visible to the part of the query
|
|
14
|
+
* you are building. {@link Kysely.fn} allows you to refer to columns in any
|
|
15
|
+
* table of the database even if it doesn't produce valid SQL.
|
|
16
|
+
*
|
|
17
|
+
* ```ts
|
|
18
|
+
* await db.selectFrom('person')
|
|
19
|
+
* .innerJoin('pet', 'pet.owner_id', 'person.id')
|
|
20
|
+
* .select([
|
|
21
|
+
* 'person.id',
|
|
22
|
+
* (qb) => qb.fn.count('pet.id').as('pet_count')
|
|
23
|
+
* ])
|
|
24
|
+
* .groupBy('person.id')
|
|
25
|
+
* .having(count('pet.id'), '>', 10)
|
|
26
|
+
* .execute()
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* The generated SQL (postgresql):
|
|
30
|
+
*
|
|
31
|
+
* ```sql
|
|
32
|
+
* select "person"."id", count("pet"."id") as "pet_count"
|
|
33
|
+
* from "person"
|
|
34
|
+
* inner join "pet" on "pet"."owner_id" = "person"."id"
|
|
35
|
+
* group by "person"."id"
|
|
36
|
+
* having count("pet"."id") > $1
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
get fn(): FunctionBuilder<DB, TB>;
|
|
7
40
|
/**
|
|
8
41
|
* Creates a subquery.
|
|
9
42
|
*
|
|
@@ -4,11 +4,46 @@ import { parseTableExpressionOrList, } from '../parser/table-parser.js';
|
|
|
4
4
|
import { WithSchemaPlugin } from '../plugin/with-schema/with-schema-plugin.js';
|
|
5
5
|
import { createQueryId } from '../util/query-id.js';
|
|
6
6
|
import { freeze } from '../util/object-utils.js';
|
|
7
|
+
import { FunctionBuilder } from './function-builder.js';
|
|
7
8
|
export class ExpressionBuilder {
|
|
8
9
|
#props;
|
|
9
10
|
constructor(props) {
|
|
10
11
|
this.#props = freeze(props);
|
|
11
12
|
}
|
|
13
|
+
/**
|
|
14
|
+
* Returns a {@link FunctionBuilder} that can be used to write type safe function
|
|
15
|
+
* calls.
|
|
16
|
+
*
|
|
17
|
+
* The difference between this and {@link Kysely.fn} is that this one is more
|
|
18
|
+
* type safe. You can only refer to columns visible to the part of the query
|
|
19
|
+
* you are building. {@link Kysely.fn} allows you to refer to columns in any
|
|
20
|
+
* table of the database even if it doesn't produce valid SQL.
|
|
21
|
+
*
|
|
22
|
+
* ```ts
|
|
23
|
+
* await db.selectFrom('person')
|
|
24
|
+
* .innerJoin('pet', 'pet.owner_id', 'person.id')
|
|
25
|
+
* .select([
|
|
26
|
+
* 'person.id',
|
|
27
|
+
* (qb) => qb.fn.count('pet.id').as('pet_count')
|
|
28
|
+
* ])
|
|
29
|
+
* .groupBy('person.id')
|
|
30
|
+
* .having(count('pet.id'), '>', 10)
|
|
31
|
+
* .execute()
|
|
32
|
+
* ```
|
|
33
|
+
*
|
|
34
|
+
* The generated SQL (postgresql):
|
|
35
|
+
*
|
|
36
|
+
* ```sql
|
|
37
|
+
* select "person"."id", count("pet"."id") as "pet_count"
|
|
38
|
+
* from "person"
|
|
39
|
+
* inner join "pet" on "pet"."owner_id" = "person"."id"
|
|
40
|
+
* group by "person"."id"
|
|
41
|
+
* having count("pet"."id") > $1
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
get fn() {
|
|
45
|
+
return new FunctionBuilder({ executor: this.#props.executor });
|
|
46
|
+
}
|
|
12
47
|
subQuery(table) {
|
|
13
48
|
return new QueryBuilder({
|
|
14
49
|
queryId: createQueryId(),
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { StringReference, ExtractTypeFromReferenceExpression } from '../parser/reference-parser.js';
|
|
2
|
+
import { QueryExecutor } from '../query-executor/query-executor.js';
|
|
3
|
+
import { RawBuilder } from '../raw-builder/raw-builder.js';
|
|
4
|
+
/**
|
|
5
|
+
* Helpers for type safe SQL function calls.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* const { count } = db.fn
|
|
10
|
+
*
|
|
11
|
+
* await db.selectFrom('person')
|
|
12
|
+
* .innerJoin('pet', 'pet.owner_id', 'person.id')
|
|
13
|
+
* .select([
|
|
14
|
+
* 'person.id',
|
|
15
|
+
* count('pet.id').as('pet_count')
|
|
16
|
+
* ])
|
|
17
|
+
* .groupBy('person.id')
|
|
18
|
+
* .having(count('pet.id'), '>', 10)
|
|
19
|
+
* .execute()
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* The generated SQL (postgresql):
|
|
23
|
+
*
|
|
24
|
+
* ```sql
|
|
25
|
+
* select "person"."id", count("pet"."id") as "pet_count"
|
|
26
|
+
* from "person"
|
|
27
|
+
* inner join "pet" on "pet"."owner_id" = "person"."id"
|
|
28
|
+
* group by "person"."id"
|
|
29
|
+
* having count("pet"."id") > $1
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export declare class FunctionBuilder<DB, TB extends keyof DB> {
|
|
33
|
+
#private;
|
|
34
|
+
constructor(props: FunctionBuilderProps);
|
|
35
|
+
/**
|
|
36
|
+
* Calls the `max` function for the column given as the argument.
|
|
37
|
+
*/
|
|
38
|
+
min<C extends StringReference<DB, TB>>(column: C): RawBuilder<ExtractTypeFromReferenceExpression<DB, TB, C>>;
|
|
39
|
+
/**
|
|
40
|
+
* Calls the `min` function for the column given as the argument.
|
|
41
|
+
*/
|
|
42
|
+
max<C extends StringReference<DB, TB>>(column: C): RawBuilder<ExtractTypeFromReferenceExpression<DB, TB, C>>;
|
|
43
|
+
/**
|
|
44
|
+
* Calls the `avg` function for the column given as the argument.
|
|
45
|
+
*
|
|
46
|
+
* If this is used in a `select` statement the type of the selected expression
|
|
47
|
+
* will be `number | string` by default. This is because Kysely can't know the
|
|
48
|
+
* type the db driver outputs. Sometimes the output can be larger than the
|
|
49
|
+
* largest javascript number and a string is returned instead. Most drivers
|
|
50
|
+
* allow you to configure the output type of large numbers and Kysely can't
|
|
51
|
+
* know if you've done so.
|
|
52
|
+
*
|
|
53
|
+
* You can specify the output type of the expression by providing
|
|
54
|
+
* the type as the first type argument:
|
|
55
|
+
*
|
|
56
|
+
* ```ts
|
|
57
|
+
* const { avg } = db.fn
|
|
58
|
+
*
|
|
59
|
+
* db.selectFrom('toy')
|
|
60
|
+
* .select(avg<number>('price'))
|
|
61
|
+
* .execute()
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
avg<O extends number | string, C extends StringReference<DB, TB> = any>(column: C): RawBuilder<O>;
|
|
65
|
+
/**
|
|
66
|
+
* Calls the `sum` function for the column given as the argument.
|
|
67
|
+
*
|
|
68
|
+
* If this is used in a `select` statement the type of the selected expression
|
|
69
|
+
* will be `number | string` by default. This is because Kysely can't know the
|
|
70
|
+
* type the db driver outputs. Sometimes the output can be larger than the
|
|
71
|
+
* largest javascript number and a string is returned instead. Most drivers
|
|
72
|
+
* allow you to configure the output type of large numbers and Kysely can't
|
|
73
|
+
* know if you've done so.
|
|
74
|
+
*
|
|
75
|
+
* You can specify the output type of the expression by providing
|
|
76
|
+
* the type as the first type argument:
|
|
77
|
+
*
|
|
78
|
+
* ```ts
|
|
79
|
+
* const { sum } = db.fn
|
|
80
|
+
*
|
|
81
|
+
* db.selectFrom('toy')
|
|
82
|
+
* .select(sum<number>('price'))
|
|
83
|
+
* .execute()
|
|
84
|
+
* ```
|
|
85
|
+
*/
|
|
86
|
+
sum<O extends number | string | BigInt, C extends StringReference<DB, TB> = any>(column: C): RawBuilder<O>;
|
|
87
|
+
/**
|
|
88
|
+
* Calls the `count` function for the column given as the argument.
|
|
89
|
+
*
|
|
90
|
+
* If this is used in a `select` statement the type of the selected expression
|
|
91
|
+
* will be `number | string` by default. This is because Kysely can't know the
|
|
92
|
+
* type the db driver outputs. Sometimes the output can be larger than the
|
|
93
|
+
* largest javascript number and a string is returned instead. Most drivers
|
|
94
|
+
* allow you to configure the output type of large numbers and Kysely can't
|
|
95
|
+
* know if you've done so.
|
|
96
|
+
*
|
|
97
|
+
* You can specify the output type of the expression by providing
|
|
98
|
+
* the type as the first type argument:
|
|
99
|
+
*
|
|
100
|
+
* ```ts
|
|
101
|
+
* const { count } = db.fn
|
|
102
|
+
*
|
|
103
|
+
* db.selectFrom('toy')
|
|
104
|
+
* .select(count<number>('price'))
|
|
105
|
+
* .execute()
|
|
106
|
+
* ```
|
|
107
|
+
*/
|
|
108
|
+
count<O extends number | string | BigInt, C extends StringReference<DB, TB> = any>(column: C): RawBuilder<O>;
|
|
109
|
+
}
|
|
110
|
+
export interface FunctionBuilderProps {
|
|
111
|
+
readonly executor: QueryExecutor;
|
|
112
|
+
}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { RawBuilder } from '../raw-builder/raw-builder.js';
|
|
2
|
+
import { freeze } from '../util/object-utils.js';
|
|
3
|
+
import { createQueryId } from '../util/query-id.js';
|
|
4
|
+
/**
|
|
5
|
+
* Helpers for type safe SQL function calls.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* const { count } = db.fn
|
|
10
|
+
*
|
|
11
|
+
* await db.selectFrom('person')
|
|
12
|
+
* .innerJoin('pet', 'pet.owner_id', 'person.id')
|
|
13
|
+
* .select([
|
|
14
|
+
* 'person.id',
|
|
15
|
+
* count('pet.id').as('pet_count')
|
|
16
|
+
* ])
|
|
17
|
+
* .groupBy('person.id')
|
|
18
|
+
* .having(count('pet.id'), '>', 10)
|
|
19
|
+
* .execute()
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* The generated SQL (postgresql):
|
|
23
|
+
*
|
|
24
|
+
* ```sql
|
|
25
|
+
* select "person"."id", count("pet"."id") as "pet_count"
|
|
26
|
+
* from "person"
|
|
27
|
+
* inner join "pet" on "pet"."owner_id" = "person"."id"
|
|
28
|
+
* group by "person"."id"
|
|
29
|
+
* having count("pet"."id") > $1
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export class FunctionBuilder {
|
|
33
|
+
#props;
|
|
34
|
+
constructor(props) {
|
|
35
|
+
this.#props = freeze(props);
|
|
36
|
+
this.min = this.min.bind(this);
|
|
37
|
+
this.max = this.max.bind(this);
|
|
38
|
+
this.avg = this.avg.bind(this);
|
|
39
|
+
this.sum = this.sum.bind(this);
|
|
40
|
+
this.count = this.count.bind(this);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Calls the `max` function for the column given as the argument.
|
|
44
|
+
*/
|
|
45
|
+
min(column) {
|
|
46
|
+
return this.#oneArgFunction('min', column);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Calls the `min` function for the column given as the argument.
|
|
50
|
+
*/
|
|
51
|
+
max(column) {
|
|
52
|
+
return this.#oneArgFunction('max', column);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Calls the `avg` function for the column given as the argument.
|
|
56
|
+
*
|
|
57
|
+
* If this is used in a `select` statement the type of the selected expression
|
|
58
|
+
* will be `number | string` by default. This is because Kysely can't know the
|
|
59
|
+
* type the db driver outputs. Sometimes the output can be larger than the
|
|
60
|
+
* largest javascript number and a string is returned instead. Most drivers
|
|
61
|
+
* allow you to configure the output type of large numbers and Kysely can't
|
|
62
|
+
* know if you've done so.
|
|
63
|
+
*
|
|
64
|
+
* You can specify the output type of the expression by providing
|
|
65
|
+
* the type as the first type argument:
|
|
66
|
+
*
|
|
67
|
+
* ```ts
|
|
68
|
+
* const { avg } = db.fn
|
|
69
|
+
*
|
|
70
|
+
* db.selectFrom('toy')
|
|
71
|
+
* .select(avg<number>('price'))
|
|
72
|
+
* .execute()
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
75
|
+
avg(column) {
|
|
76
|
+
return this.#oneArgFunction('avg', column);
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Calls the `sum` function for the column given as the argument.
|
|
80
|
+
*
|
|
81
|
+
* If this is used in a `select` statement the type of the selected expression
|
|
82
|
+
* will be `number | string` by default. This is because Kysely can't know the
|
|
83
|
+
* type the db driver outputs. Sometimes the output can be larger than the
|
|
84
|
+
* largest javascript number and a string is returned instead. Most drivers
|
|
85
|
+
* allow you to configure the output type of large numbers and Kysely can't
|
|
86
|
+
* know if you've done so.
|
|
87
|
+
*
|
|
88
|
+
* You can specify the output type of the expression by providing
|
|
89
|
+
* the type as the first type argument:
|
|
90
|
+
*
|
|
91
|
+
* ```ts
|
|
92
|
+
* const { sum } = db.fn
|
|
93
|
+
*
|
|
94
|
+
* db.selectFrom('toy')
|
|
95
|
+
* .select(sum<number>('price'))
|
|
96
|
+
* .execute()
|
|
97
|
+
* ```
|
|
98
|
+
*/
|
|
99
|
+
sum(column) {
|
|
100
|
+
return this.#oneArgFunction('sum', column);
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Calls the `count` function for the column given as the argument.
|
|
104
|
+
*
|
|
105
|
+
* If this is used in a `select` statement the type of the selected expression
|
|
106
|
+
* will be `number | string` by default. This is because Kysely can't know the
|
|
107
|
+
* type the db driver outputs. Sometimes the output can be larger than the
|
|
108
|
+
* largest javascript number and a string is returned instead. Most drivers
|
|
109
|
+
* allow you to configure the output type of large numbers and Kysely can't
|
|
110
|
+
* know if you've done so.
|
|
111
|
+
*
|
|
112
|
+
* You can specify the output type of the expression by providing
|
|
113
|
+
* the type as the first type argument:
|
|
114
|
+
*
|
|
115
|
+
* ```ts
|
|
116
|
+
* const { count } = db.fn
|
|
117
|
+
*
|
|
118
|
+
* db.selectFrom('toy')
|
|
119
|
+
* .select(count<number>('price'))
|
|
120
|
+
* .execute()
|
|
121
|
+
* ```
|
|
122
|
+
*/
|
|
123
|
+
count(column) {
|
|
124
|
+
return this.#oneArgFunction('count', column);
|
|
125
|
+
}
|
|
126
|
+
#oneArgFunction(fn, column) {
|
|
127
|
+
return new RawBuilder({
|
|
128
|
+
queryId: createQueryId(),
|
|
129
|
+
executor: this.#props.executor,
|
|
130
|
+
sql: `${fn}(??)`,
|
|
131
|
+
parameters: [column],
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
}
|
|
@@ -2,7 +2,7 @@ import { AliasNode } from '../operation-node/alias-node.js';
|
|
|
2
2
|
import { OperationNodeSource } from '../operation-node/operation-node-source.js';
|
|
3
3
|
import { CompiledQuery } from '../query-compiler/compiled-query.js';
|
|
4
4
|
import { JoinCallbackExpression, JoinReferenceExpression } from '../parser/join-parser.js';
|
|
5
|
-
import { TableExpression, QueryBuilderWithTable } from '../parser/table-parser.js';
|
|
5
|
+
import { TableExpression, QueryBuilderWithTable, QueryBuilderWithLeftJoin, QueryBuilderWithRightJoin, QueryBuilderWithFullJoin } from '../parser/table-parser.js';
|
|
6
6
|
import { SelectExpression, QueryBuilderWithSelection, SelectAllQueryBuilder } from '../parser/select-parser.js';
|
|
7
7
|
import { ExistsExpression, FilterOperator } from '../parser/filter-parser.js';
|
|
8
8
|
import { InsertObject } from '../parser/insert-values-parser.js';
|
|
@@ -10,7 +10,7 @@ import { QueryBuilderWithReturning } from '../parser/returning-parser.js';
|
|
|
10
10
|
import { ReferenceExpression } from '../parser/reference-parser.js';
|
|
11
11
|
import { ValueExpressionOrList } from '../parser/value-parser.js';
|
|
12
12
|
import { QueryNode } from '../operation-node/query-node.js';
|
|
13
|
-
import { AnyColumn, ManyResultRowType, NonEmptySingleResultRowType, SingleResultRowType } from '
|
|
13
|
+
import { AnyColumn, ManyResultRowType, NonEmptySingleResultRowType, SingleResultRowType } from '../util/type-utils.js';
|
|
14
14
|
import { OrderByDirectionExpression, OrderByExpression } from '../parser/order-by-parser.js';
|
|
15
15
|
import { MutationObject } from '../parser/update-set-parser.js';
|
|
16
16
|
import { Compilable } from '../util/compilable.js';
|
|
@@ -869,20 +869,20 @@ export declare class QueryBuilder<DB, TB extends keyof DB, O = {}> implements Op
|
|
|
869
869
|
* Just like {@link QueryBuilder.innerJoin | innerJoin} but adds a left join
|
|
870
870
|
* instead of an inner join.
|
|
871
871
|
*/
|
|
872
|
-
leftJoin<TE extends TableExpression<DB, TB>, K1 extends JoinReferenceExpression<DB, TB, TE>, K2 extends JoinReferenceExpression<DB, TB, TE>>(table: TE, k1: K1, k2: K2):
|
|
873
|
-
leftJoin<TE extends TableExpression<DB, TB>, FN extends JoinCallbackExpression<DB, TB, TE>>(table: TE, callback: FN):
|
|
872
|
+
leftJoin<TE extends TableExpression<DB, TB>, K1 extends JoinReferenceExpression<DB, TB, TE>, K2 extends JoinReferenceExpression<DB, TB, TE>>(table: TE, k1: K1, k2: K2): QueryBuilderWithLeftJoin<DB, TB, O, TE>;
|
|
873
|
+
leftJoin<TE extends TableExpression<DB, TB>, FN extends JoinCallbackExpression<DB, TB, TE>>(table: TE, callback: FN): QueryBuilderWithLeftJoin<DB, TB, O, TE>;
|
|
874
874
|
/**
|
|
875
875
|
* Just like {@link QueryBuilder.innerJoin | innerJoin} but adds a right join
|
|
876
876
|
* instead of an inner join.
|
|
877
877
|
*/
|
|
878
|
-
rightJoin<TE extends TableExpression<DB, TB>, K1 extends JoinReferenceExpression<DB, TB, TE>, K2 extends JoinReferenceExpression<DB, TB, TE>>(table: TE, k1: K1, k2: K2):
|
|
879
|
-
rightJoin<TE extends TableExpression<DB, TB>, FN extends JoinCallbackExpression<DB, TB, TE>>(table: TE, callback: FN):
|
|
878
|
+
rightJoin<TE extends TableExpression<DB, TB>, K1 extends JoinReferenceExpression<DB, TB, TE>, K2 extends JoinReferenceExpression<DB, TB, TE>>(table: TE, k1: K1, k2: K2): QueryBuilderWithRightJoin<DB, TB, O, TE>;
|
|
879
|
+
rightJoin<TE extends TableExpression<DB, TB>, FN extends JoinCallbackExpression<DB, TB, TE>>(table: TE, callback: FN): QueryBuilderWithRightJoin<DB, TB, O, TE>;
|
|
880
880
|
/**
|
|
881
881
|
* Just like {@link QueryBuilder.innerJoin | innerJoin} but adds a full join
|
|
882
882
|
* instead of an inner join.
|
|
883
883
|
*/
|
|
884
|
-
fullJoin<TE extends TableExpression<DB, TB>, K1 extends JoinReferenceExpression<DB, TB, TE>, K2 extends JoinReferenceExpression<DB, TB, TE>>(table: TE, k1: K1, k2: K2):
|
|
885
|
-
fullJoin<TE extends TableExpression<DB, TB>, FN extends JoinCallbackExpression<DB, TB, TE>>(table: TE, callback: FN):
|
|
884
|
+
fullJoin<TE extends TableExpression<DB, TB>, K1 extends JoinReferenceExpression<DB, TB, TE>, K2 extends JoinReferenceExpression<DB, TB, TE>>(table: TE, k1: K1, k2: K2): QueryBuilderWithFullJoin<DB, TB, O, TE>;
|
|
885
|
+
fullJoin<TE extends TableExpression<DB, TB>, FN extends JoinCallbackExpression<DB, TB, TE>>(table: TE, callback: FN): QueryBuilderWithFullJoin<DB, TB, O, TE>;
|
|
886
886
|
/**
|
|
887
887
|
* Sets the values to insert for an {@link Kysely.insertInto | insert} query.
|
|
888
888
|
*
|
|
@@ -62,7 +62,7 @@ import { ModifyColumnNode } from '../operation-node/modify-column-node.js';
|
|
|
62
62
|
import { OnDuplicateKeyNode } from '../operation-node/on-duplicate-key-node.js';
|
|
63
63
|
export declare class DefaultQueryCompiler extends OperationNodeVisitor implements QueryCompiler {
|
|
64
64
|
#private;
|
|
65
|
-
protected get
|
|
65
|
+
protected get numParameters(): number;
|
|
66
66
|
compileQuery(node: RootOperationNode): CompiledQuery;
|
|
67
67
|
protected getSql(): string;
|
|
68
68
|
protected visitSelectQuery(node: SelectQueryNode): void;
|
|
@@ -129,6 +129,6 @@ export declare class DefaultQueryCompiler extends OperationNodeVisitor implement
|
|
|
129
129
|
protected getLeftIdentifierWrapper(): string;
|
|
130
130
|
protected getRightIdentifierWrapper(): string;
|
|
131
131
|
protected getCurrentParameterPlaceholder(): string;
|
|
132
|
-
protected
|
|
132
|
+
protected addParameter(parameter: any): void;
|
|
133
133
|
protected appendImmediateValue(value: PrimitiveValue): void;
|
|
134
134
|
}
|
|
@@ -5,17 +5,17 @@ import { RawNode } from '../operation-node/raw-node.js';
|
|
|
5
5
|
import { getLast, freeze, isString, isNumber, isBoolean, isNull, isDate, isBigInt, } from '../util/object-utils.js';
|
|
6
6
|
export class DefaultQueryCompiler extends OperationNodeVisitor {
|
|
7
7
|
#sqlFragments = [];
|
|
8
|
-
#
|
|
9
|
-
get
|
|
10
|
-
return this.#
|
|
8
|
+
#parameters = [];
|
|
9
|
+
get numParameters() {
|
|
10
|
+
return this.#parameters.length;
|
|
11
11
|
}
|
|
12
12
|
compileQuery(node) {
|
|
13
13
|
this.#sqlFragments = [];
|
|
14
|
-
this.#
|
|
14
|
+
this.#parameters = [];
|
|
15
15
|
this.visitNode(node);
|
|
16
16
|
return freeze({
|
|
17
17
|
sql: this.getSql(),
|
|
18
|
-
|
|
18
|
+
parameters: this.#parameters,
|
|
19
19
|
});
|
|
20
20
|
}
|
|
21
21
|
getSql() {
|
|
@@ -637,7 +637,7 @@ export class DefaultQueryCompiler extends OperationNodeVisitor {
|
|
|
637
637
|
this.#sqlFragments.push(str);
|
|
638
638
|
}
|
|
639
639
|
appendValue(value) {
|
|
640
|
-
this.
|
|
640
|
+
this.addParameter(value);
|
|
641
641
|
this.append(this.getCurrentParameterPlaceholder());
|
|
642
642
|
}
|
|
643
643
|
getLeftIdentifierWrapper() {
|
|
@@ -647,10 +647,10 @@ export class DefaultQueryCompiler extends OperationNodeVisitor {
|
|
|
647
647
|
return '"';
|
|
648
648
|
}
|
|
649
649
|
getCurrentParameterPlaceholder() {
|
|
650
|
-
return '$' + this.
|
|
650
|
+
return '$' + this.numParameters;
|
|
651
651
|
}
|
|
652
|
-
|
|
653
|
-
this.#
|
|
652
|
+
addParameter(parameter) {
|
|
653
|
+
this.#parameters.push(parameter);
|
|
654
654
|
}
|
|
655
655
|
appendImmediateValue(value) {
|
|
656
656
|
if (isString(value)) {
|
|
@@ -9,6 +9,9 @@ import { QueryNode } from '../operation-node/query-node.js';
|
|
|
9
9
|
import { RawNode } from '../operation-node/raw-node.js';
|
|
10
10
|
import { CompiledQuery } from './compiled-query.js';
|
|
11
11
|
export declare type RootOperationNode = QueryNode | CreateTableNode | CreateIndexNode | AlterTableNode | DropTableNode | DropIndexNode | CreateSchemaNode | DropSchemaNode | RawNode;
|
|
12
|
+
/**
|
|
13
|
+
* a `QueryCompiler` compiles a query expressed as a tree of `OperationNodes` into SQL.
|
|
14
|
+
*/
|
|
12
15
|
export interface QueryCompiler {
|
|
13
16
|
compileQuery(node: RootOperationNode): CompiledQuery;
|
|
14
17
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { QueryBuilder } from './query-builder/query-builder.js';
|
|
2
2
|
import { QueryBuilderWithTable, TableExpression, TableReference } from './parser/table-parser.js';
|
|
3
|
-
import { InsertResultTypeTag, DeleteResultTypeTag, UpdateResultTypeTag } from './
|
|
3
|
+
import { InsertResultTypeTag, DeleteResultTypeTag, UpdateResultTypeTag } from './util/type-utils.js';
|
|
4
4
|
import { QueryExecutor } from './query-executor/query-executor.js';
|
|
5
5
|
import { RawBuilder } from './raw-builder/raw-builder.js';
|
|
6
6
|
import { CommonTableExpression, QueryCreatorWithCommonTableExpression } from './parser/with-parser.js';
|
|
@@ -276,11 +276,11 @@ export declare class QueryCreator<DB> {
|
|
|
276
276
|
* Raw builder instances can be passed to pretty much anywhere: `select`, `where`,
|
|
277
277
|
* `*Join`, `groupBy`, `orderBy` etc. Just try it. If the method accepts it, it works.
|
|
278
278
|
*
|
|
279
|
-
* @param sql - The raw SQL. Special strings `?` and `??` can be used
|
|
280
|
-
*
|
|
279
|
+
* @param sql - The raw SQL. Special strings `?` and `??` can be used as parameter
|
|
280
|
+
* placeholders. `?` for values and `??` for identifiers such as column names
|
|
281
281
|
* or `column.table` references.
|
|
282
282
|
*
|
|
283
|
-
* @param params - The parameters that will be bound to the `?` and `??`
|
|
283
|
+
* @param params - The parameters that will be bound to the `?` and `??` placeholders in
|
|
284
284
|
* the sql string.
|
|
285
285
|
*
|
|
286
286
|
* @example
|
|
@@ -318,7 +318,7 @@ export declare class QueryCreator<DB> {
|
|
|
318
318
|
* the output type. In this case you need to use the `castTo` method on the query
|
|
319
319
|
* to specify a return type for the query.
|
|
320
320
|
*
|
|
321
|
-
* We could've also used `??`
|
|
321
|
+
* We could've also used a `??` placeholder to provide `first_name` and `last_name` like
|
|
322
322
|
* this:
|
|
323
323
|
*
|
|
324
324
|
* ```ts
|
|
@@ -333,9 +333,9 @@ export declare class QueryCreator<DB> {
|
|
|
333
333
|
*
|
|
334
334
|
* But it's often cleaner to just write the column names in the SQL. Again remember to
|
|
335
335
|
* never concatenate column names or any other untrusted user input to the SQL string or you
|
|
336
|
-
* are going to create an injection vulnerability. All user input should go to the
|
|
336
|
+
* are going to create an injection vulnerability. All user input should go to the parameters
|
|
337
337
|
* array, never to the SQL string directly. But if the column names or values are trusted
|
|
338
|
-
* and known at compile time, there is no reason to use
|
|
338
|
+
* and known at compile time, there is no reason to use parameters.
|
|
339
339
|
*
|
|
340
340
|
* @example
|
|
341
341
|
* Example of using `raw` in `where`:
|
|
@@ -361,7 +361,7 @@ export declare class QueryCreator<DB> {
|
|
|
361
361
|
*
|
|
362
362
|
* The function in the above example returns people that are older than the given number of
|
|
363
363
|
* years. The number of years in this example is an untrusted user input, and therefore we use
|
|
364
|
-
* a `?`
|
|
364
|
+
* a `?` placeholder for it.
|
|
365
365
|
*
|
|
366
366
|
* @example
|
|
367
367
|
* Example of creating a completely raw query from scratch:
|
|
@@ -375,7 +375,7 @@ export declare class QueryCreator<DB> {
|
|
|
375
375
|
* The result of `execute()` method is always an array. In this case the type of
|
|
376
376
|
* the `persons` variable is `Person[]`.
|
|
377
377
|
*/
|
|
378
|
-
raw<T = unknown>(sql: string,
|
|
378
|
+
raw<T = unknown>(sql: string, parameters?: any[]): RawBuilder<T>;
|
|
379
379
|
}
|
|
380
380
|
export interface QueryCreatorProps {
|
|
381
381
|
readonly executor: QueryExecutor;
|