kysely 0.26.1 → 0.26.3
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 +6 -6
- package/dist/cjs/dialect/dialect-adapter-base.d.ts +3 -3
- package/dist/cjs/dialect/mysql/mysql-adapter.d.ts +3 -2
- package/dist/cjs/dialect/mysql/mysql-adapter.js +2 -2
- package/dist/cjs/dialect/postgres/postgres-adapter.d.ts +3 -2
- package/dist/cjs/dialect/postgres/postgres-adapter.js +2 -2
- package/dist/cjs/dialect/postgres/postgres-dialect-config.d.ts +2 -2
- package/dist/cjs/dialect/sqlite/sqlite-adapter.d.ts +4 -2
- package/dist/cjs/dialect/sqlite/sqlite-adapter.js +2 -2
- package/dist/cjs/driver/runtime-driver.js +17 -2
- package/dist/cjs/expression/expression-builder.d.ts +300 -27
- package/dist/cjs/expression/expression-builder.js +36 -26
- package/dist/cjs/expression/expression-wrapper.d.ts +177 -8
- package/dist/cjs/expression/expression-wrapper.js +4 -4
- package/dist/cjs/expression/expression.d.ts +64 -1
- package/dist/cjs/helpers/mysql.d.ts +14 -11
- package/dist/cjs/helpers/mysql.js +21 -32
- package/dist/cjs/helpers/postgres.d.ts +8 -5
- package/dist/cjs/helpers/postgres.js +8 -5
- package/dist/cjs/helpers/sqlite.d.ts +164 -0
- package/dist/cjs/helpers/sqlite.js +180 -0
- package/dist/cjs/index.d.ts +5 -3
- package/dist/cjs/index.js +1 -0
- package/dist/cjs/kysely.d.ts +4 -3
- package/dist/cjs/kysely.js +1 -1
- package/dist/cjs/operation-node/common-table-expression-node.d.ts +4 -0
- package/dist/cjs/operation-node/common-table-expression-node.js +6 -0
- package/dist/cjs/operation-node/delete-query-node.d.ts +1 -1
- package/dist/cjs/operation-node/delete-query-node.js +3 -3
- package/dist/cjs/operation-node/operation-node-transformer.d.ts +2 -0
- package/dist/cjs/operation-node/operation-node-transformer.js +8 -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/operator-node.d.ts +3 -3
- package/dist/cjs/operation-node/operator-node.js +3 -0
- package/dist/cjs/operation-node/order-by-node.d.ts +2 -2
- package/dist/cjs/operation-node/order-by-node.js +4 -4
- package/dist/cjs/operation-node/over-node.d.ts +1 -1
- package/dist/cjs/operation-node/over-node.js +3 -3
- package/dist/cjs/operation-node/select-query-node.d.ts +5 -4
- package/dist/cjs/operation-node/select-query-node.js +13 -7
- package/dist/cjs/operation-node/tuple-node.d.ts +12 -0
- package/dist/cjs/operation-node/tuple-node.js +18 -0
- package/dist/cjs/parser/binary-operation-parser.d.ts +11 -7
- package/dist/cjs/parser/binary-operation-parser.js +35 -46
- package/dist/cjs/parser/expression-parser.d.ts +10 -5
- package/dist/cjs/parser/join-parser.d.ts +2 -2
- package/dist/cjs/parser/join-parser.js +2 -3
- package/dist/cjs/parser/order-by-parser.d.ts +6 -2
- package/dist/cjs/parser/order-by-parser.js +41 -7
- package/dist/cjs/parser/parse-utils.js +2 -2
- package/dist/cjs/parser/reference-parser.d.ts +2 -2
- package/dist/cjs/parser/reference-parser.js +1 -1
- package/dist/cjs/parser/returning-parser.d.ts +2 -1
- package/dist/cjs/parser/select-parser.d.ts +20 -9
- package/dist/cjs/parser/set-operation-parser.d.ts +3 -1
- package/dist/cjs/parser/set-operation-parser.js +13 -4
- package/dist/cjs/parser/tuple-parser.d.ts +47 -0
- package/dist/cjs/parser/tuple-parser.js +2 -0
- package/dist/cjs/parser/value-parser.d.ts +5 -3
- package/dist/cjs/parser/value-parser.js +12 -1
- package/dist/cjs/parser/with-parser.d.ts +3 -2
- package/dist/cjs/parser/with-parser.js +16 -4
- package/dist/cjs/plugin/camel-case/camel-case-plugin.d.ts +3 -3
- package/dist/cjs/plugin/camel-case/camel-case-plugin.js +4 -8
- package/dist/cjs/plugin/parse-json-results/parse-json-results-plugin.d.ts +13 -0
- package/dist/cjs/plugin/parse-json-results/parse-json-results-plugin.js +50 -14
- package/dist/cjs/query-builder/aggregate-function-builder.d.ts +5 -5
- package/dist/cjs/query-builder/aggregate-function-builder.js +2 -2
- package/dist/cjs/query-builder/case-builder.js +8 -4
- package/dist/cjs/query-builder/cte-builder.d.ts +20 -0
- package/dist/cjs/query-builder/cte-builder.js +39 -0
- package/dist/cjs/query-builder/delete-query-builder.d.ts +39 -10
- package/dist/cjs/query-builder/delete-query-builder.js +3 -3
- package/dist/cjs/query-builder/function-module.d.ts +41 -6
- package/dist/cjs/query-builder/function-module.js +3 -0
- package/dist/cjs/query-builder/having-interface.d.ts +2 -5
- package/dist/cjs/query-builder/insert-query-builder.d.ts +5 -3
- package/dist/cjs/query-builder/join-builder.d.ts +2 -6
- package/dist/cjs/query-builder/join-builder.js +2 -2
- package/dist/cjs/query-builder/json-path-builder.d.ts +59 -3
- package/dist/cjs/query-builder/on-conflict-builder.d.ts +65 -12
- package/dist/cjs/query-builder/on-conflict-builder.js +4 -4
- package/dist/cjs/query-builder/over-builder.js +1 -1
- package/dist/cjs/query-builder/returning-interface.d.ts +3 -2
- package/dist/cjs/query-builder/select-query-builder-expression.d.ts +20 -0
- package/dist/cjs/query-builder/select-query-builder-expression.js +2 -0
- package/dist/cjs/query-builder/select-query-builder.d.ts +206 -67
- package/dist/cjs/query-builder/select-query-builder.js +75 -924
- package/dist/cjs/query-builder/update-query-builder.d.ts +39 -10
- package/dist/cjs/query-builder/update-query-builder.js +2 -2
- package/dist/cjs/query-builder/where-interface.d.ts +32 -8
- package/dist/cjs/query-compiler/default-query-compiler.d.ts +3 -0
- package/dist/cjs/query-compiler/default-query-compiler.js +39 -7
- package/dist/cjs/query-creator.d.ts +76 -2
- package/dist/cjs/query-creator.js +36 -6
- package/dist/cjs/raw-builder/raw-builder.d.ts +87 -51
- package/dist/cjs/raw-builder/raw-builder.js +18 -45
- package/dist/cjs/raw-builder/sql.js +8 -8
- package/dist/cjs/schema/alter-table-builder.d.ts +4 -0
- package/dist/cjs/schema/alter-table-builder.js +12 -0
- package/dist/cjs/schema/create-index-builder.d.ts +1 -1
- package/dist/cjs/schema/create-index-builder.js +1 -1
- package/dist/cjs/schema/create-view-builder.d.ts +2 -2
- package/dist/cjs/util/column-type.d.ts +7 -6
- package/dist/cjs/util/infer-result.d.ts +2 -1
- package/dist/cjs/util/json-object-args.d.ts +3 -0
- package/dist/cjs/util/json-object-args.js +35 -0
- package/dist/cjs/util/object-utils.d.ts +1 -0
- package/dist/cjs/util/object-utils.js +9 -1
- package/dist/cjs/util/type-utils.d.ts +16 -17
- package/dist/esm/dialect/dialect-adapter-base.d.ts +3 -3
- package/dist/esm/dialect/mysql/mysql-adapter.d.ts +3 -2
- package/dist/esm/dialect/mysql/mysql-adapter.js +2 -2
- package/dist/esm/dialect/postgres/postgres-adapter.d.ts +3 -2
- package/dist/esm/dialect/postgres/postgres-adapter.js +2 -2
- package/dist/esm/dialect/postgres/postgres-dialect-config.d.ts +2 -2
- package/dist/esm/dialect/sqlite/sqlite-adapter.d.ts +4 -2
- package/dist/esm/dialect/sqlite/sqlite-adapter.js +2 -2
- package/dist/esm/driver/runtime-driver.js +17 -2
- package/dist/esm/expression/expression-builder.d.ts +300 -27
- package/dist/esm/expression/expression-builder.js +40 -30
- package/dist/esm/expression/expression-wrapper.d.ts +177 -8
- package/dist/esm/expression/expression-wrapper.js +5 -5
- package/dist/esm/expression/expression.d.ts +64 -1
- package/dist/esm/helpers/mysql.d.ts +14 -11
- package/dist/esm/helpers/mysql.js +21 -32
- package/dist/esm/helpers/postgres.d.ts +8 -5
- package/dist/esm/helpers/postgres.js +8 -5
- package/dist/esm/helpers/sqlite.d.ts +164 -0
- package/dist/esm/helpers/sqlite.js +175 -0
- package/dist/esm/index.d.ts +5 -3
- package/dist/esm/index.js +1 -0
- package/dist/esm/kysely.d.ts +4 -3
- package/dist/esm/kysely.js +1 -1
- package/dist/esm/operation-node/common-table-expression-node.d.ts +4 -0
- package/dist/esm/operation-node/common-table-expression-node.js +6 -0
- package/dist/esm/operation-node/delete-query-node.d.ts +1 -1
- package/dist/esm/operation-node/delete-query-node.js +3 -3
- package/dist/esm/operation-node/operation-node-transformer.d.ts +2 -0
- package/dist/esm/operation-node/operation-node-transformer.js +8 -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/operator-node.d.ts +3 -3
- package/dist/esm/operation-node/operator-node.js +3 -0
- package/dist/esm/operation-node/order-by-node.d.ts +2 -2
- package/dist/esm/operation-node/order-by-node.js +4 -4
- package/dist/esm/operation-node/over-node.d.ts +1 -1
- package/dist/esm/operation-node/over-node.js +3 -3
- package/dist/esm/operation-node/select-query-node.d.ts +5 -4
- package/dist/esm/operation-node/select-query-node.js +13 -7
- package/dist/esm/operation-node/tuple-node.d.ts +12 -0
- package/dist/esm/operation-node/tuple-node.js +16 -0
- package/dist/esm/parser/binary-operation-parser.d.ts +11 -7
- package/dist/esm/parser/binary-operation-parser.js +36 -47
- package/dist/esm/parser/expression-parser.d.ts +10 -5
- package/dist/esm/parser/join-parser.d.ts +2 -2
- package/dist/esm/parser/join-parser.js +3 -4
- package/dist/esm/parser/order-by-parser.d.ts +6 -2
- package/dist/esm/parser/order-by-parser.js +40 -7
- package/dist/esm/parser/parse-utils.js +3 -3
- package/dist/esm/parser/reference-parser.d.ts +2 -2
- package/dist/esm/parser/reference-parser.js +1 -1
- package/dist/esm/parser/returning-parser.d.ts +2 -1
- package/dist/esm/parser/select-parser.d.ts +20 -9
- package/dist/esm/parser/set-operation-parser.d.ts +3 -1
- package/dist/esm/parser/set-operation-parser.js +11 -2
- package/dist/esm/parser/tuple-parser.d.ts +47 -0
- package/dist/esm/parser/tuple-parser.js +2 -0
- package/dist/esm/parser/value-parser.d.ts +5 -3
- package/dist/esm/parser/value-parser.js +10 -1
- package/dist/esm/parser/with-parser.d.ts +3 -2
- package/dist/esm/parser/with-parser.js +16 -4
- package/dist/esm/plugin/camel-case/camel-case-plugin.d.ts +3 -3
- package/dist/esm/plugin/camel-case/camel-case-plugin.js +5 -9
- package/dist/esm/plugin/parse-json-results/parse-json-results-plugin.d.ts +13 -0
- package/dist/esm/plugin/parse-json-results/parse-json-results-plugin.js +51 -15
- package/dist/esm/query-builder/aggregate-function-builder.d.ts +5 -5
- package/dist/esm/query-builder/aggregate-function-builder.js +3 -3
- package/dist/esm/query-builder/case-builder.js +10 -6
- package/dist/esm/query-builder/cte-builder.d.ts +20 -0
- package/dist/esm/query-builder/cte-builder.js +36 -0
- package/dist/esm/query-builder/delete-query-builder.d.ts +39 -10
- package/dist/esm/query-builder/delete-query-builder.js +4 -4
- package/dist/esm/query-builder/function-module.d.ts +41 -6
- package/dist/esm/query-builder/function-module.js +3 -0
- package/dist/esm/query-builder/having-interface.d.ts +2 -5
- package/dist/esm/query-builder/insert-query-builder.d.ts +5 -3
- package/dist/esm/query-builder/join-builder.d.ts +2 -6
- package/dist/esm/query-builder/join-builder.js +3 -3
- package/dist/esm/query-builder/json-path-builder.d.ts +59 -3
- package/dist/esm/query-builder/on-conflict-builder.d.ts +65 -12
- package/dist/esm/query-builder/on-conflict-builder.js +5 -5
- package/dist/esm/query-builder/over-builder.js +1 -1
- package/dist/esm/query-builder/returning-interface.d.ts +3 -2
- package/dist/esm/query-builder/select-query-builder-expression.d.ts +20 -0
- package/dist/esm/query-builder/select-query-builder-expression.js +2 -0
- package/dist/esm/query-builder/select-query-builder.d.ts +206 -67
- package/dist/esm/query-builder/select-query-builder.js +75 -923
- package/dist/esm/query-builder/update-query-builder.d.ts +39 -10
- package/dist/esm/query-builder/update-query-builder.js +3 -3
- package/dist/esm/query-builder/where-interface.d.ts +32 -8
- package/dist/esm/query-compiler/default-query-compiler.d.ts +3 -0
- package/dist/esm/query-compiler/default-query-compiler.js +39 -7
- package/dist/esm/query-creator.d.ts +76 -2
- package/dist/esm/query-creator.js +37 -7
- package/dist/esm/raw-builder/raw-builder.d.ts +87 -51
- package/dist/esm/raw-builder/raw-builder.js +17 -42
- package/dist/esm/raw-builder/sql.js +9 -9
- package/dist/esm/schema/alter-table-builder.d.ts +4 -0
- package/dist/esm/schema/alter-table-builder.js +12 -0
- package/dist/esm/schema/create-index-builder.d.ts +1 -1
- package/dist/esm/schema/create-index-builder.js +2 -2
- package/dist/esm/schema/create-view-builder.d.ts +2 -2
- package/dist/esm/util/column-type.d.ts +7 -6
- package/dist/esm/util/infer-result.d.ts +2 -1
- package/dist/esm/util/json-object-args.d.ts +3 -0
- package/dist/esm/util/json-object-args.js +32 -0
- package/dist/esm/util/object-utils.d.ts +1 -0
- package/dist/esm/util/object-utils.js +7 -0
- package/dist/esm/util/type-utils.d.ts +16 -17
- package/helpers/sqlite.d.ts +1 -0
- package/helpers/sqlite.js +1 -0
- package/package.json +7 -4
|
@@ -14,1106 +14,270 @@ import { freeze } from '../util/object-utils.js';
|
|
|
14
14
|
import { parseGroupBy } from '../parser/group-by-parser.js';
|
|
15
15
|
import { isNoResultErrorConstructor, NoResultError, } from './no-result-error.js';
|
|
16
16
|
import { IdentifierNode } from '../operation-node/identifier-node.js';
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
|
|
17
|
+
import { parseSetOperations, } from '../parser/set-operation-parser.js';
|
|
18
|
+
import { parseValueBinaryOperationOrExpression, parseReferentialBinaryOperation, } from '../parser/binary-operation-parser.js';
|
|
19
|
+
import { ExpressionWrapper } from '../expression/expression-wrapper.js';
|
|
20
|
+
class SelectQueryBuilderImpl {
|
|
20
21
|
#props;
|
|
21
22
|
constructor(props) {
|
|
22
23
|
this.#props = freeze(props);
|
|
23
24
|
}
|
|
24
|
-
/** @private */
|
|
25
25
|
get expressionType() {
|
|
26
26
|
return undefined;
|
|
27
27
|
}
|
|
28
|
+
get isSelectQueryBuilder() {
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
28
31
|
where(...args) {
|
|
29
|
-
return new
|
|
32
|
+
return new SelectQueryBuilderImpl({
|
|
30
33
|
...this.#props,
|
|
31
|
-
queryNode: QueryNode.cloneWithWhere(this.#props.queryNode,
|
|
34
|
+
queryNode: QueryNode.cloneWithWhere(this.#props.queryNode, parseValueBinaryOperationOrExpression(args)),
|
|
32
35
|
});
|
|
33
36
|
}
|
|
34
37
|
whereRef(lhs, op, rhs) {
|
|
35
|
-
return new
|
|
38
|
+
return new SelectQueryBuilderImpl({
|
|
36
39
|
...this.#props,
|
|
37
|
-
queryNode: QueryNode.cloneWithWhere(this.#props.queryNode,
|
|
40
|
+
queryNode: QueryNode.cloneWithWhere(this.#props.queryNode, parseReferentialBinaryOperation(lhs, op, rhs)),
|
|
38
41
|
});
|
|
39
42
|
}
|
|
40
43
|
having(...args) {
|
|
41
|
-
return new
|
|
44
|
+
return new SelectQueryBuilderImpl({
|
|
42
45
|
...this.#props,
|
|
43
|
-
queryNode: SelectQueryNode.cloneWithHaving(this.#props.queryNode,
|
|
46
|
+
queryNode: SelectQueryNode.cloneWithHaving(this.#props.queryNode, parseValueBinaryOperationOrExpression(args)),
|
|
44
47
|
});
|
|
45
48
|
}
|
|
46
49
|
havingRef(lhs, op, rhs) {
|
|
47
|
-
return new
|
|
50
|
+
return new SelectQueryBuilderImpl({
|
|
48
51
|
...this.#props,
|
|
49
|
-
queryNode: SelectQueryNode.cloneWithHaving(this.#props.queryNode,
|
|
52
|
+
queryNode: SelectQueryNode.cloneWithHaving(this.#props.queryNode, parseReferentialBinaryOperation(lhs, op, rhs)),
|
|
50
53
|
});
|
|
51
54
|
}
|
|
52
|
-
/**
|
|
53
|
-
* Adds a select statement to the query.
|
|
54
|
-
*
|
|
55
|
-
* When a column (or any expression) is selected, Kysely adds its type to the return
|
|
56
|
-
* type of the query. Kysely is smart enough to parse the selection names and types
|
|
57
|
-
* from aliased columns, subqueries, raw expressions etc.
|
|
58
|
-
*
|
|
59
|
-
* Kysely only allows you to select columns and expressions that exist and would
|
|
60
|
-
* produce valid SQL. However, Kysely is not perfect and there may be cases where
|
|
61
|
-
* the type inference doesn't work and you need to override it. You can always
|
|
62
|
-
* use the {@link Kysely.dynamic | dynamic} module and the {@link sql} tag
|
|
63
|
-
* to override the types.
|
|
64
|
-
*
|
|
65
|
-
* Select calls are additive. Calling `select('id').select('first_name')` is the
|
|
66
|
-
* same as calling `select(['id', 'first_name'])`.
|
|
67
|
-
*
|
|
68
|
-
* To select all columns of the query or specific tables see the
|
|
69
|
-
* {@link selectAll} method.
|
|
70
|
-
*
|
|
71
|
-
* See the {@link $if} method if you are looking for a way to add selections
|
|
72
|
-
* based on a runtime condition.
|
|
73
|
-
*
|
|
74
|
-
* ### Examples
|
|
75
|
-
*
|
|
76
|
-
* <!-- siteExample("select", "A single column", 10) -->
|
|
77
|
-
*
|
|
78
|
-
* Select a single column:
|
|
79
|
-
*
|
|
80
|
-
* ```ts
|
|
81
|
-
* const persons = await db
|
|
82
|
-
* .selectFrom('person')
|
|
83
|
-
* .select('id')
|
|
84
|
-
* .where('first_name', '=', 'Arnold')
|
|
85
|
-
* .execute()
|
|
86
|
-
* ```
|
|
87
|
-
*
|
|
88
|
-
* The generated SQL (PostgreSQL):
|
|
89
|
-
*
|
|
90
|
-
* ```sql
|
|
91
|
-
* select "id" from "person" where "first_name" = $1
|
|
92
|
-
* ```
|
|
93
|
-
*
|
|
94
|
-
* <!-- siteExample("select", "Column with a table", 20) -->
|
|
95
|
-
*
|
|
96
|
-
* Select a single column and specify a table:
|
|
97
|
-
*
|
|
98
|
-
* ```ts
|
|
99
|
-
* const persons = await db
|
|
100
|
-
* .selectFrom(['person', 'pet'])
|
|
101
|
-
* .select('person.id')
|
|
102
|
-
* .execute()
|
|
103
|
-
* ```
|
|
104
|
-
*
|
|
105
|
-
* The generated SQL (PostgreSQL):
|
|
106
|
-
*
|
|
107
|
-
* ```sql
|
|
108
|
-
* select "person"."id" from "person", "pet"
|
|
109
|
-
* ```
|
|
110
|
-
*
|
|
111
|
-
* <!-- siteExample("select", "Multiple columns", 30) -->
|
|
112
|
-
*
|
|
113
|
-
* Select multiple columns:
|
|
114
|
-
*
|
|
115
|
-
* ```ts
|
|
116
|
-
* const persons = await db
|
|
117
|
-
* .selectFrom('person')
|
|
118
|
-
* .select(['person.id', 'first_name'])
|
|
119
|
-
* .execute()
|
|
120
|
-
* ```
|
|
121
|
-
*
|
|
122
|
-
* The generated SQL (PostgreSQL):
|
|
123
|
-
*
|
|
124
|
-
* ```sql
|
|
125
|
-
* select "person"."id", "first_name" from "person"
|
|
126
|
-
* ```
|
|
127
|
-
*
|
|
128
|
-
* <!-- siteExample("select", "Aliases", 40) -->
|
|
129
|
-
*
|
|
130
|
-
* You can provide an alias for the selections by appending `as the_alias` to the selection.
|
|
131
|
-
*
|
|
132
|
-
* ```ts
|
|
133
|
-
* const persons = await db
|
|
134
|
-
* .selectFrom('person')
|
|
135
|
-
* .select([
|
|
136
|
-
* 'first_name as fn',
|
|
137
|
-
* 'person.last_name as ln'
|
|
138
|
-
* ])
|
|
139
|
-
* .execute()
|
|
140
|
-
* ```
|
|
141
|
-
*
|
|
142
|
-
* The generated SQL (PostgreSQL):
|
|
143
|
-
*
|
|
144
|
-
* ```sql
|
|
145
|
-
* select
|
|
146
|
-
* "first_name" as "fn",
|
|
147
|
-
* "person"."last_name" as "ln"
|
|
148
|
-
* from "person"
|
|
149
|
-
* ```
|
|
150
|
-
*
|
|
151
|
-
* <!-- siteExample("select", "Complex selections", 50) -->
|
|
152
|
-
*
|
|
153
|
-
* You can select arbitrary expression including subqueries and raw sql snippets.
|
|
154
|
-
* When you do that, you need to give a name for the selections using the `as` method:
|
|
155
|
-
*
|
|
156
|
-
* ```ts
|
|
157
|
-
* import { sql } from 'kysely'
|
|
158
|
-
*
|
|
159
|
-
* const persons = await db.selectFrom('person')
|
|
160
|
-
* .select(({ eb, selectFrom, or }) => [
|
|
161
|
-
* // Select a correlated subquery
|
|
162
|
-
* selectFrom('pet')
|
|
163
|
-
* .whereRef('person.id', '=', 'pet.owner_id')
|
|
164
|
-
* .select('pet.name')
|
|
165
|
-
* .orderBy('pet.name')
|
|
166
|
-
* .limit(1)
|
|
167
|
-
* .as('first_pet_name'),
|
|
168
|
-
*
|
|
169
|
-
* // Build and select an expression using
|
|
170
|
-
* // the expression builder
|
|
171
|
-
* or([
|
|
172
|
-
* eb('first_name', '=', 'Jennifer'),
|
|
173
|
-
* eb('first_name', '=', 'Arnold')
|
|
174
|
-
* ]).as('is_jennifer_or_arnold'),
|
|
175
|
-
*
|
|
176
|
-
* // Select a raw sql expression
|
|
177
|
-
* sql<string>`concat(first_name, ' ', last_name)`.as('full_name')
|
|
178
|
-
* ])
|
|
179
|
-
* .execute()
|
|
180
|
-
* ```
|
|
181
|
-
*
|
|
182
|
-
* The generated SQL (PostgreSQL):
|
|
183
|
-
*
|
|
184
|
-
* ```sql
|
|
185
|
-
* select
|
|
186
|
-
* (
|
|
187
|
-
* select "pet"."name"
|
|
188
|
-
* from "pet"
|
|
189
|
-
* where "person"."id" = "pet"."owner_id"
|
|
190
|
-
* order by "pet"."name"
|
|
191
|
-
* limit $1
|
|
192
|
-
* ) as "pet_name",
|
|
193
|
-
* ("first_name" = $2 or "first_name" = $3) as "jennifer_or_arnold",
|
|
194
|
-
* concat(first_name, ' ', last_name) as "full_name"
|
|
195
|
-
* from "person"
|
|
196
|
-
* ```
|
|
197
|
-
*
|
|
198
|
-
* In case you use the {@link sql} tag you need to specify the type of the expression
|
|
199
|
-
* (in this example `string`).
|
|
200
|
-
*
|
|
201
|
-
* All the examples above assume you know the column names at compile time.
|
|
202
|
-
* While it's better to build your code like that (that way you also know
|
|
203
|
-
* the types) sometimes it's not possible or you just prefer to write more
|
|
204
|
-
* dynamic code.
|
|
205
|
-
* <br><br>
|
|
206
|
-
* In this example, we use the `dynamic` module's methods to add selections
|
|
207
|
-
* dynamically:
|
|
208
|
-
*
|
|
209
|
-
* ```ts
|
|
210
|
-
* const { ref } = db.dynamic
|
|
211
|
-
*
|
|
212
|
-
* // Some column name provided by the user. Value not known at compile time.
|
|
213
|
-
* const columnFromUserInput = req.query.select;
|
|
214
|
-
*
|
|
215
|
-
* // A type that lists all possible values `columnFromUserInput` can have.
|
|
216
|
-
* // You can use `keyof Person` if any column of an interface is allowed.
|
|
217
|
-
* type PossibleColumns = 'last_name' | 'first_name' | 'birth_date'
|
|
218
|
-
*
|
|
219
|
-
* const spersons = await db
|
|
220
|
-
* .selectFrom('person')
|
|
221
|
-
* .select([
|
|
222
|
-
* ref<PossibleColumns>(columnFromUserInput)
|
|
223
|
-
* 'id'
|
|
224
|
-
* ])
|
|
225
|
-
* .execute()
|
|
226
|
-
*
|
|
227
|
-
* // The resulting type contains all `PossibleColumns` as optional fields
|
|
228
|
-
* // because we cannot know which field was actually selected before
|
|
229
|
-
* // running the code.
|
|
230
|
-
* const lastName: string | undefined = persons[0].last_name
|
|
231
|
-
* const firstName: string | undefined = persons[0].first_name
|
|
232
|
-
* const birthDate: string | undefined = persons[0].birth_date
|
|
233
|
-
*
|
|
234
|
-
* // The result type also contains the compile time selection `id`.
|
|
235
|
-
* persons[0].id
|
|
236
|
-
* ```
|
|
237
|
-
*/
|
|
238
55
|
select(selection) {
|
|
239
|
-
return new
|
|
56
|
+
return new SelectQueryBuilderImpl({
|
|
240
57
|
...this.#props,
|
|
241
58
|
queryNode: SelectQueryNode.cloneWithSelections(this.#props.queryNode, parseSelectArg(selection)),
|
|
242
59
|
});
|
|
243
60
|
}
|
|
244
61
|
distinctOn(selection) {
|
|
245
|
-
return new
|
|
62
|
+
return new SelectQueryBuilderImpl({
|
|
246
63
|
...this.#props,
|
|
247
64
|
queryNode: SelectQueryNode.cloneWithDistinctOn(this.#props.queryNode, parseReferenceExpressionOrList(selection)),
|
|
248
65
|
});
|
|
249
66
|
}
|
|
250
|
-
/**
|
|
251
|
-
* This can be used to add any additional SQL to the front of the query __after__ the `select` keyword.
|
|
252
|
-
*
|
|
253
|
-
* ### Examples
|
|
254
|
-
*
|
|
255
|
-
* ```ts
|
|
256
|
-
* db.selectFrom('person')
|
|
257
|
-
* .modifyFront(sql`sql_no_cache`)
|
|
258
|
-
* .select('first_name')
|
|
259
|
-
* .execute()
|
|
260
|
-
* ```
|
|
261
|
-
*
|
|
262
|
-
* The generated SQL (MySQL):
|
|
263
|
-
*
|
|
264
|
-
* ```sql
|
|
265
|
-
* select sql_no_cache `first_name`
|
|
266
|
-
* from `person`
|
|
267
|
-
* ```
|
|
268
|
-
*/
|
|
269
67
|
modifyFront(modifier) {
|
|
270
|
-
return new
|
|
68
|
+
return new SelectQueryBuilderImpl({
|
|
271
69
|
...this.#props,
|
|
272
70
|
queryNode: SelectQueryNode.cloneWithFrontModifier(this.#props.queryNode, SelectModifierNode.createWithExpression(modifier.toOperationNode())),
|
|
273
71
|
});
|
|
274
72
|
}
|
|
275
|
-
/**
|
|
276
|
-
* This can be used to add any additional SQL to the end of the query.
|
|
277
|
-
*
|
|
278
|
-
* Also see {@link forUpdate}, {@link forShare}, {@link forKeyShare}, {@link forNoKeyUpdate}
|
|
279
|
-
* {@link skipLocked} and {@link noWait}.
|
|
280
|
-
*
|
|
281
|
-
* ### Examples
|
|
282
|
-
*
|
|
283
|
-
* ```ts
|
|
284
|
-
* db.selectFrom('person')
|
|
285
|
-
* .select('first_name')
|
|
286
|
-
* .modifyEnd(sql`for update`)
|
|
287
|
-
* .execute()
|
|
288
|
-
* ```
|
|
289
|
-
*
|
|
290
|
-
* The generated SQL (PostgreSQL):
|
|
291
|
-
*
|
|
292
|
-
* ```sql
|
|
293
|
-
* select "first_name"
|
|
294
|
-
* from "person"
|
|
295
|
-
* for update
|
|
296
|
-
* ```
|
|
297
|
-
*/
|
|
298
73
|
modifyEnd(modifier) {
|
|
299
|
-
return new
|
|
74
|
+
return new SelectQueryBuilderImpl({
|
|
300
75
|
...this.#props,
|
|
301
76
|
queryNode: SelectQueryNode.cloneWithEndModifier(this.#props.queryNode, SelectModifierNode.createWithExpression(modifier.toOperationNode())),
|
|
302
77
|
});
|
|
303
78
|
}
|
|
304
|
-
/**
|
|
305
|
-
* Makes the selection distinct.
|
|
306
|
-
*
|
|
307
|
-
* <!-- siteExample("select", "Distinct", 70) -->
|
|
308
|
-
*
|
|
309
|
-
* ### Examples
|
|
310
|
-
*
|
|
311
|
-
* ```ts
|
|
312
|
-
* const persons = await db.selectFrom('person')
|
|
313
|
-
* .select('first_name')
|
|
314
|
-
* .distinct()
|
|
315
|
-
* .execute()
|
|
316
|
-
* ```
|
|
317
|
-
*
|
|
318
|
-
* The generated SQL (PostgreSQL):
|
|
319
|
-
*
|
|
320
|
-
* ```sql
|
|
321
|
-
* select distinct "first_name" from "person"
|
|
322
|
-
* ```
|
|
323
|
-
*/
|
|
324
79
|
distinct() {
|
|
325
|
-
return new
|
|
80
|
+
return new SelectQueryBuilderImpl({
|
|
326
81
|
...this.#props,
|
|
327
82
|
queryNode: SelectQueryNode.cloneWithFrontModifier(this.#props.queryNode, SelectModifierNode.create('Distinct')),
|
|
328
83
|
});
|
|
329
84
|
}
|
|
330
|
-
/**
|
|
331
|
-
* Adds the `for update` modifier to a select query on supported databases.
|
|
332
|
-
*/
|
|
333
85
|
forUpdate() {
|
|
334
|
-
return new
|
|
86
|
+
return new SelectQueryBuilderImpl({
|
|
335
87
|
...this.#props,
|
|
336
88
|
queryNode: SelectQueryNode.cloneWithEndModifier(this.#props.queryNode, SelectModifierNode.create('ForUpdate')),
|
|
337
89
|
});
|
|
338
90
|
}
|
|
339
|
-
/**
|
|
340
|
-
* Adds the `for share` modifier to a select query on supported databases.
|
|
341
|
-
*/
|
|
342
91
|
forShare() {
|
|
343
|
-
return new
|
|
92
|
+
return new SelectQueryBuilderImpl({
|
|
344
93
|
...this.#props,
|
|
345
94
|
queryNode: SelectQueryNode.cloneWithEndModifier(this.#props.queryNode, SelectModifierNode.create('ForShare')),
|
|
346
95
|
});
|
|
347
96
|
}
|
|
348
|
-
/**
|
|
349
|
-
* Adds the `for key share` modifier to a select query on supported databases.
|
|
350
|
-
*/
|
|
351
97
|
forKeyShare() {
|
|
352
|
-
return new
|
|
98
|
+
return new SelectQueryBuilderImpl({
|
|
353
99
|
...this.#props,
|
|
354
100
|
queryNode: SelectQueryNode.cloneWithEndModifier(this.#props.queryNode, SelectModifierNode.create('ForKeyShare')),
|
|
355
101
|
});
|
|
356
102
|
}
|
|
357
|
-
/**
|
|
358
|
-
* Adds the `for no key update` modifier to a select query on supported databases.
|
|
359
|
-
*/
|
|
360
103
|
forNoKeyUpdate() {
|
|
361
|
-
return new
|
|
104
|
+
return new SelectQueryBuilderImpl({
|
|
362
105
|
...this.#props,
|
|
363
106
|
queryNode: SelectQueryNode.cloneWithEndModifier(this.#props.queryNode, SelectModifierNode.create('ForNoKeyUpdate')),
|
|
364
107
|
});
|
|
365
108
|
}
|
|
366
|
-
/**
|
|
367
|
-
* Adds the `skip locked` modifier to a select query on supported databases.
|
|
368
|
-
*/
|
|
369
109
|
skipLocked() {
|
|
370
|
-
return new
|
|
110
|
+
return new SelectQueryBuilderImpl({
|
|
371
111
|
...this.#props,
|
|
372
112
|
queryNode: SelectQueryNode.cloneWithEndModifier(this.#props.queryNode, SelectModifierNode.create('SkipLocked')),
|
|
373
113
|
});
|
|
374
114
|
}
|
|
375
|
-
/**
|
|
376
|
-
* Adds the `nowait` modifier to a select query on supported databases.
|
|
377
|
-
*/
|
|
378
115
|
noWait() {
|
|
379
|
-
return new
|
|
116
|
+
return new SelectQueryBuilderImpl({
|
|
380
117
|
...this.#props,
|
|
381
118
|
queryNode: SelectQueryNode.cloneWithEndModifier(this.#props.queryNode, SelectModifierNode.create('NoWait')),
|
|
382
119
|
});
|
|
383
120
|
}
|
|
384
121
|
selectAll(table) {
|
|
385
|
-
return new
|
|
122
|
+
return new SelectQueryBuilderImpl({
|
|
386
123
|
...this.#props,
|
|
387
124
|
queryNode: SelectQueryNode.cloneWithSelections(this.#props.queryNode, parseSelectAll(table)),
|
|
388
125
|
});
|
|
389
126
|
}
|
|
390
127
|
innerJoin(...args) {
|
|
391
|
-
return new
|
|
128
|
+
return new SelectQueryBuilderImpl({
|
|
392
129
|
...this.#props,
|
|
393
130
|
queryNode: QueryNode.cloneWithJoin(this.#props.queryNode, parseJoin('InnerJoin', args)),
|
|
394
131
|
});
|
|
395
132
|
}
|
|
396
133
|
leftJoin(...args) {
|
|
397
|
-
return new
|
|
134
|
+
return new SelectQueryBuilderImpl({
|
|
398
135
|
...this.#props,
|
|
399
136
|
queryNode: QueryNode.cloneWithJoin(this.#props.queryNode, parseJoin('LeftJoin', args)),
|
|
400
137
|
});
|
|
401
138
|
}
|
|
402
139
|
rightJoin(...args) {
|
|
403
|
-
return new
|
|
140
|
+
return new SelectQueryBuilderImpl({
|
|
404
141
|
...this.#props,
|
|
405
142
|
queryNode: QueryNode.cloneWithJoin(this.#props.queryNode, parseJoin('RightJoin', args)),
|
|
406
143
|
});
|
|
407
144
|
}
|
|
408
145
|
fullJoin(...args) {
|
|
409
|
-
return new
|
|
146
|
+
return new SelectQueryBuilderImpl({
|
|
410
147
|
...this.#props,
|
|
411
148
|
queryNode: QueryNode.cloneWithJoin(this.#props.queryNode, parseJoin('FullJoin', args)),
|
|
412
149
|
});
|
|
413
150
|
}
|
|
414
151
|
innerJoinLateral(...args) {
|
|
415
|
-
return new
|
|
152
|
+
return new SelectQueryBuilderImpl({
|
|
416
153
|
...this.#props,
|
|
417
154
|
queryNode: QueryNode.cloneWithJoin(this.#props.queryNode, parseJoin('LateralInnerJoin', args)),
|
|
418
155
|
});
|
|
419
156
|
}
|
|
420
157
|
leftJoinLateral(...args) {
|
|
421
|
-
return new
|
|
158
|
+
return new SelectQueryBuilderImpl({
|
|
422
159
|
...this.#props,
|
|
423
160
|
queryNode: QueryNode.cloneWithJoin(this.#props.queryNode, parseJoin('LateralLeftJoin', args)),
|
|
424
161
|
});
|
|
425
162
|
}
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
*
|
|
429
|
-
* `orderBy` calls are additive. To order by multiple columns, call `orderBy`
|
|
430
|
-
* multiple times.
|
|
431
|
-
*
|
|
432
|
-
* The first argument is the expression to order by and the second is the
|
|
433
|
-
* order (`asc` or `desc`).
|
|
434
|
-
*
|
|
435
|
-
* ### Examples
|
|
436
|
-
*
|
|
437
|
-
* ```ts
|
|
438
|
-
* await db
|
|
439
|
-
* .selectFrom('person')
|
|
440
|
-
* .select('person.first_name as fn')
|
|
441
|
-
* .orderBy('id')
|
|
442
|
-
* .orderBy('fn', 'desc')
|
|
443
|
-
* .execute()
|
|
444
|
-
* ```
|
|
445
|
-
*
|
|
446
|
-
* The generated SQL (PostgreSQL):
|
|
447
|
-
*
|
|
448
|
-
* ```sql
|
|
449
|
-
* select "person"."first_name" as "fn"
|
|
450
|
-
* from "person"
|
|
451
|
-
* order by "id" asc, "fn" desc
|
|
452
|
-
* ```
|
|
453
|
-
*
|
|
454
|
-
* The order by expression can also be a raw sql expression or a subquery
|
|
455
|
-
* in addition to column references:
|
|
456
|
-
*
|
|
457
|
-
* ```ts
|
|
458
|
-
* import { sql } from 'kysely'
|
|
459
|
-
*
|
|
460
|
-
* await db
|
|
461
|
-
* .selectFrom('person')
|
|
462
|
-
* .selectAll()
|
|
463
|
-
* .orderBy((eb) => eb.selectFrom('pet')
|
|
464
|
-
* .select('pet.name')
|
|
465
|
-
* .whereRef('pet.owner_id', '=', 'person.id')
|
|
466
|
-
* .limit(1)
|
|
467
|
-
* )
|
|
468
|
-
* .orderBy(
|
|
469
|
-
* sql`concat(first_name, last_name)`
|
|
470
|
-
* )
|
|
471
|
-
* .execute()
|
|
472
|
-
* ```
|
|
473
|
-
*
|
|
474
|
-
* The generated SQL (PostgreSQL):
|
|
475
|
-
*
|
|
476
|
-
* ```sql
|
|
477
|
-
* select *
|
|
478
|
-
* from "person"
|
|
479
|
-
* order by
|
|
480
|
-
* ( select "pet"."name"
|
|
481
|
-
* from "pet"
|
|
482
|
-
* where "pet"."owner_id" = "person"."id"
|
|
483
|
-
* limit 1
|
|
484
|
-
* ) asc,
|
|
485
|
-
* concat(first_name, last_name) asc
|
|
486
|
-
* ```
|
|
487
|
-
*
|
|
488
|
-
* `dynamic.ref` can be used to refer to columns not known at
|
|
489
|
-
* compile time:
|
|
490
|
-
*
|
|
491
|
-
* ```ts
|
|
492
|
-
* async function someQuery(orderBy: string) {
|
|
493
|
-
* const { ref } = db.dynamic
|
|
494
|
-
*
|
|
495
|
-
* return await db
|
|
496
|
-
* .selectFrom('person')
|
|
497
|
-
* .select('person.first_name as fn')
|
|
498
|
-
* .orderBy(ref(orderBy))
|
|
499
|
-
* .execute()
|
|
500
|
-
* }
|
|
501
|
-
*
|
|
502
|
-
* someQuery('fn')
|
|
503
|
-
* ```
|
|
504
|
-
*
|
|
505
|
-
* The generated SQL (PostgreSQL):
|
|
506
|
-
*
|
|
507
|
-
* ```sql
|
|
508
|
-
* select "person"."first_name" as "fn"
|
|
509
|
-
* from "person"
|
|
510
|
-
* order by "fn" asc
|
|
511
|
-
* ```
|
|
512
|
-
*/
|
|
513
|
-
orderBy(orderBy, direction) {
|
|
514
|
-
return new SelectQueryBuilder({
|
|
163
|
+
orderBy(...args) {
|
|
164
|
+
return new SelectQueryBuilderImpl({
|
|
515
165
|
...this.#props,
|
|
516
|
-
queryNode: SelectQueryNode.
|
|
166
|
+
queryNode: SelectQueryNode.cloneWithOrderByItems(this.#props.queryNode, parseOrderBy(args)),
|
|
517
167
|
});
|
|
518
168
|
}
|
|
519
|
-
/**
|
|
520
|
-
* Adds a `group by` clause to the query.
|
|
521
|
-
*
|
|
522
|
-
* ### Examples
|
|
523
|
-
*
|
|
524
|
-
* ```ts
|
|
525
|
-
* import { sql } from 'kysely'
|
|
526
|
-
*
|
|
527
|
-
* await db
|
|
528
|
-
* .selectFrom('person')
|
|
529
|
-
* .select([
|
|
530
|
-
* 'first_name',
|
|
531
|
-
* sql`max(id)`.as('max_id')
|
|
532
|
-
* ])
|
|
533
|
-
* .groupBy('first_name')
|
|
534
|
-
* .execute()
|
|
535
|
-
* ```
|
|
536
|
-
*
|
|
537
|
-
* The generated SQL (PostgreSQL):
|
|
538
|
-
*
|
|
539
|
-
* ```sql
|
|
540
|
-
* select "first_name", max(id)
|
|
541
|
-
* from "person"
|
|
542
|
-
* group by "first_name"
|
|
543
|
-
* ```
|
|
544
|
-
*
|
|
545
|
-
* `groupBy` also accepts an array:
|
|
546
|
-
*
|
|
547
|
-
* ```ts
|
|
548
|
-
* import { sql } from 'kysely'
|
|
549
|
-
*
|
|
550
|
-
* await db
|
|
551
|
-
* .selectFrom('person')
|
|
552
|
-
* .select([
|
|
553
|
-
* 'first_name',
|
|
554
|
-
* 'last_name',
|
|
555
|
-
* sql`max(id)`.as('max_id')
|
|
556
|
-
* ])
|
|
557
|
-
* .groupBy([
|
|
558
|
-
* 'first_name',
|
|
559
|
-
* 'last_name'
|
|
560
|
-
* ])
|
|
561
|
-
* .execute()
|
|
562
|
-
* ```
|
|
563
|
-
*
|
|
564
|
-
* The generated SQL (PostgreSQL):
|
|
565
|
-
*
|
|
566
|
-
* ```sql
|
|
567
|
-
* select "first_name", "last_name", max(id)
|
|
568
|
-
* from "person"
|
|
569
|
-
* group by "first_name", "last_name"
|
|
570
|
-
* ```
|
|
571
|
-
*
|
|
572
|
-
* The group by expressions can also be subqueries or
|
|
573
|
-
* raw sql expressions:
|
|
574
|
-
*
|
|
575
|
-
* ```ts
|
|
576
|
-
* import { sql } from 'kysely'
|
|
577
|
-
*
|
|
578
|
-
* await db
|
|
579
|
-
* .selectFrom('person')
|
|
580
|
-
* .select([
|
|
581
|
-
* 'first_name',
|
|
582
|
-
* 'last_name',
|
|
583
|
-
* sql`max(id)`.as('max_id')
|
|
584
|
-
* ])
|
|
585
|
-
* .groupBy([
|
|
586
|
-
* sql`concat(first_name, last_name)`,
|
|
587
|
-
* (qb) => qb.selectFrom('pet').select('id').limit(1)
|
|
588
|
-
* ])
|
|
589
|
-
* .execute()
|
|
590
|
-
* ```
|
|
591
|
-
*
|
|
592
|
-
* `dynamic.ref` can be used to refer to columns not known at
|
|
593
|
-
* compile time:
|
|
594
|
-
*
|
|
595
|
-
* ```ts
|
|
596
|
-
* async function someQuery(groupBy: string) {
|
|
597
|
-
* const { ref } = db.dynamic
|
|
598
|
-
*
|
|
599
|
-
* return await db
|
|
600
|
-
* .selectFrom('person')
|
|
601
|
-
* .select('first_name')
|
|
602
|
-
* .groupBy(ref(groupBy))
|
|
603
|
-
* .execute()
|
|
604
|
-
* }
|
|
605
|
-
*
|
|
606
|
-
* someQuery('first_name')
|
|
607
|
-
* ```
|
|
608
|
-
*
|
|
609
|
-
* The generated SQL (PostgreSQL):
|
|
610
|
-
*
|
|
611
|
-
* ```sql
|
|
612
|
-
* select "first_name"
|
|
613
|
-
* from "person"
|
|
614
|
-
* group by "first_name"
|
|
615
|
-
* ```
|
|
616
|
-
*/
|
|
617
169
|
groupBy(groupBy) {
|
|
618
|
-
return new
|
|
170
|
+
return new SelectQueryBuilderImpl({
|
|
619
171
|
...this.#props,
|
|
620
172
|
queryNode: SelectQueryNode.cloneWithGroupByItems(this.#props.queryNode, parseGroupBy(groupBy)),
|
|
621
173
|
});
|
|
622
174
|
}
|
|
623
|
-
/**
|
|
624
|
-
* Adds a limit clause to the query.
|
|
625
|
-
*
|
|
626
|
-
* ### Examples
|
|
627
|
-
*
|
|
628
|
-
* Select the first 10 rows of the result:
|
|
629
|
-
*
|
|
630
|
-
* ```ts
|
|
631
|
-
* return await db
|
|
632
|
-
* .selectFrom('person')
|
|
633
|
-
* .select('first_name')
|
|
634
|
-
* .limit(10)
|
|
635
|
-
* ```
|
|
636
|
-
*
|
|
637
|
-
* Select rows from index 10 to index 19 of the result:
|
|
638
|
-
*
|
|
639
|
-
* ```ts
|
|
640
|
-
* return await db
|
|
641
|
-
* .selectFrom('person')
|
|
642
|
-
* .select('first_name')
|
|
643
|
-
* .offset(10)
|
|
644
|
-
* .limit(10)
|
|
645
|
-
* ```
|
|
646
|
-
*/
|
|
647
175
|
limit(limit) {
|
|
648
|
-
return new
|
|
176
|
+
return new SelectQueryBuilderImpl({
|
|
649
177
|
...this.#props,
|
|
650
178
|
queryNode: SelectQueryNode.cloneWithLimit(this.#props.queryNode, LimitNode.create(limit)),
|
|
651
179
|
});
|
|
652
180
|
}
|
|
653
|
-
/**
|
|
654
|
-
* Adds an offset clause to the query.
|
|
655
|
-
*
|
|
656
|
-
* ### Examples
|
|
657
|
-
*
|
|
658
|
-
* Select rows from index 10 to index 19 of the result:
|
|
659
|
-
*
|
|
660
|
-
* ```ts
|
|
661
|
-
* return await db
|
|
662
|
-
* .selectFrom('person')
|
|
663
|
-
* .select('first_name')
|
|
664
|
-
* .offset(10)
|
|
665
|
-
* .limit(10)
|
|
666
|
-
* ```
|
|
667
|
-
*/
|
|
668
181
|
offset(offset) {
|
|
669
|
-
return new
|
|
182
|
+
return new SelectQueryBuilderImpl({
|
|
670
183
|
...this.#props,
|
|
671
184
|
queryNode: SelectQueryNode.cloneWithOffset(this.#props.queryNode, OffsetNode.create(offset)),
|
|
672
185
|
});
|
|
673
186
|
}
|
|
674
|
-
/**
|
|
675
|
-
* Combines another select query or raw expression to this query using `union`.
|
|
676
|
-
*
|
|
677
|
-
* The output row type of the combined query must match `this` query.
|
|
678
|
-
*
|
|
679
|
-
* ### Examples
|
|
680
|
-
*
|
|
681
|
-
* ```ts
|
|
682
|
-
* db.selectFrom('person')
|
|
683
|
-
* .select(['id', 'first_name as name'])
|
|
684
|
-
* .union(db.selectFrom('pet').select(['id', 'name']))
|
|
685
|
-
* .orderBy('name')
|
|
686
|
-
* ```
|
|
687
|
-
*/
|
|
688
187
|
union(expression) {
|
|
689
|
-
return new
|
|
188
|
+
return new SelectQueryBuilderImpl({
|
|
690
189
|
...this.#props,
|
|
691
|
-
queryNode: SelectQueryNode.
|
|
190
|
+
queryNode: SelectQueryNode.cloneWithSetOperations(this.#props.queryNode, parseSetOperations('union', expression, false)),
|
|
692
191
|
});
|
|
693
192
|
}
|
|
694
|
-
/**
|
|
695
|
-
* Combines another select query or raw expression to this query using `union all`.
|
|
696
|
-
*
|
|
697
|
-
* The output row type of the combined query must match `this` query.
|
|
698
|
-
*
|
|
699
|
-
* ### Examples
|
|
700
|
-
*
|
|
701
|
-
* ```ts
|
|
702
|
-
* db.selectFrom('person')
|
|
703
|
-
* .select(['id', 'first_name as name'])
|
|
704
|
-
* .unionAll(db.selectFrom('pet').select(['id', 'name']))
|
|
705
|
-
* .orderBy('name')
|
|
706
|
-
* ```
|
|
707
|
-
*/
|
|
708
193
|
unionAll(expression) {
|
|
709
|
-
return new
|
|
194
|
+
return new SelectQueryBuilderImpl({
|
|
710
195
|
...this.#props,
|
|
711
|
-
queryNode: SelectQueryNode.
|
|
196
|
+
queryNode: SelectQueryNode.cloneWithSetOperations(this.#props.queryNode, parseSetOperations('union', expression, true)),
|
|
712
197
|
});
|
|
713
198
|
}
|
|
714
|
-
/**
|
|
715
|
-
* Combines another select query or raw expression to this query using `intersect`.
|
|
716
|
-
*
|
|
717
|
-
* The output row type of the combined query must match `this` query.
|
|
718
|
-
*
|
|
719
|
-
* ### Examples
|
|
720
|
-
*
|
|
721
|
-
* ```ts
|
|
722
|
-
* db.selectFrom('person')
|
|
723
|
-
* .select(['id', 'first_name as name'])
|
|
724
|
-
* .intersect(db.selectFrom('pet').select(['id', 'name']))
|
|
725
|
-
* .orderBy('name')
|
|
726
|
-
* ```
|
|
727
|
-
*/
|
|
728
199
|
intersect(expression) {
|
|
729
|
-
return new
|
|
200
|
+
return new SelectQueryBuilderImpl({
|
|
730
201
|
...this.#props,
|
|
731
|
-
queryNode: SelectQueryNode.
|
|
202
|
+
queryNode: SelectQueryNode.cloneWithSetOperations(this.#props.queryNode, parseSetOperations('intersect', expression, false)),
|
|
732
203
|
});
|
|
733
204
|
}
|
|
734
|
-
/**
|
|
735
|
-
* Combines another select query or raw expression to this query using `intersect all`.
|
|
736
|
-
*
|
|
737
|
-
* The output row type of the combined query must match `this` query.
|
|
738
|
-
*
|
|
739
|
-
* ### Examples
|
|
740
|
-
*
|
|
741
|
-
* ```ts
|
|
742
|
-
* db.selectFrom('person')
|
|
743
|
-
* .select(['id', 'first_name as name'])
|
|
744
|
-
* .intersectAll(db.selectFrom('pet').select(['id', 'name']))
|
|
745
|
-
* .orderBy('name')
|
|
746
|
-
* ```
|
|
747
|
-
*/
|
|
748
205
|
intersectAll(expression) {
|
|
749
|
-
return new
|
|
206
|
+
return new SelectQueryBuilderImpl({
|
|
750
207
|
...this.#props,
|
|
751
|
-
queryNode: SelectQueryNode.
|
|
208
|
+
queryNode: SelectQueryNode.cloneWithSetOperations(this.#props.queryNode, parseSetOperations('intersect', expression, true)),
|
|
752
209
|
});
|
|
753
210
|
}
|
|
754
|
-
/**
|
|
755
|
-
* Combines another select query or raw expression to this query using `except`.
|
|
756
|
-
*
|
|
757
|
-
* The output row type of the combined query must match `this` query.
|
|
758
|
-
*
|
|
759
|
-
* ### Examples
|
|
760
|
-
*
|
|
761
|
-
* ```ts
|
|
762
|
-
* db.selectFrom('person')
|
|
763
|
-
* .select(['id', 'first_name as name'])
|
|
764
|
-
* .except(db.selectFrom('pet').select(['id', 'name']))
|
|
765
|
-
* .orderBy('name')
|
|
766
|
-
* ```
|
|
767
|
-
*/
|
|
768
211
|
except(expression) {
|
|
769
|
-
return new
|
|
212
|
+
return new SelectQueryBuilderImpl({
|
|
770
213
|
...this.#props,
|
|
771
|
-
queryNode: SelectQueryNode.
|
|
214
|
+
queryNode: SelectQueryNode.cloneWithSetOperations(this.#props.queryNode, parseSetOperations('except', expression, false)),
|
|
772
215
|
});
|
|
773
216
|
}
|
|
774
|
-
/**
|
|
775
|
-
* Combines another select query or raw expression to this query using `except all`.
|
|
776
|
-
*
|
|
777
|
-
* The output row type of the combined query must match `this` query.
|
|
778
|
-
*
|
|
779
|
-
* ### Examples
|
|
780
|
-
*
|
|
781
|
-
* ```ts
|
|
782
|
-
* db.selectFrom('person')
|
|
783
|
-
* .select(['id', 'first_name as name'])
|
|
784
|
-
* .exceptAll(db.selectFrom('pet').select(['id', 'name']))
|
|
785
|
-
* .orderBy('name')
|
|
786
|
-
* ```
|
|
787
|
-
*/
|
|
788
217
|
exceptAll(expression) {
|
|
789
|
-
return new
|
|
218
|
+
return new SelectQueryBuilderImpl({
|
|
790
219
|
...this.#props,
|
|
791
|
-
queryNode: SelectQueryNode.
|
|
220
|
+
queryNode: SelectQueryNode.cloneWithSetOperations(this.#props.queryNode, parseSetOperations('except', expression, true)),
|
|
792
221
|
});
|
|
793
222
|
}
|
|
794
|
-
/**
|
|
795
|
-
* Gives an alias for the query. This method is only useful for sub queries.
|
|
796
|
-
*
|
|
797
|
-
* ### Examples
|
|
798
|
-
*
|
|
799
|
-
* ```ts
|
|
800
|
-
* const pets = await db.selectFrom('pet')
|
|
801
|
-
* .selectAll('pet')
|
|
802
|
-
* .select(
|
|
803
|
-
* (qb) => qb.selectFrom('person')
|
|
804
|
-
* .select('first_name')
|
|
805
|
-
* .whereRef('pet.owner_id', '=', 'person.id')
|
|
806
|
-
* .as('owner_first_name')
|
|
807
|
-
* )
|
|
808
|
-
* .execute()
|
|
809
|
-
*
|
|
810
|
-
* pets[0].owner_first_name
|
|
811
|
-
* ```
|
|
812
|
-
*/
|
|
813
223
|
as(alias) {
|
|
814
|
-
return new
|
|
224
|
+
return new AliasedSelectQueryBuilderImpl(this, alias);
|
|
815
225
|
}
|
|
816
|
-
/**
|
|
817
|
-
* Clears all select clauses from the query.
|
|
818
|
-
*
|
|
819
|
-
* ### Examples
|
|
820
|
-
*
|
|
821
|
-
* ```ts
|
|
822
|
-
* db.selectFrom('person')
|
|
823
|
-
* .select(['id', 'first_name'])
|
|
824
|
-
* .clearSelect()
|
|
825
|
-
* .select(['id', 'gender'])
|
|
826
|
-
* ```
|
|
827
|
-
*
|
|
828
|
-
* The generated SQL(PostgreSQL):
|
|
829
|
-
*
|
|
830
|
-
* ```sql
|
|
831
|
-
* select "id", "gender" from "person"
|
|
832
|
-
* ```
|
|
833
|
-
*/
|
|
834
226
|
clearSelect() {
|
|
835
|
-
return new
|
|
227
|
+
return new SelectQueryBuilderImpl({
|
|
836
228
|
...this.#props,
|
|
837
229
|
queryNode: SelectQueryNode.cloneWithoutSelections(this.#props.queryNode),
|
|
838
230
|
});
|
|
839
231
|
}
|
|
840
232
|
clearWhere() {
|
|
841
|
-
return new
|
|
233
|
+
return new SelectQueryBuilderImpl({
|
|
842
234
|
...this.#props,
|
|
843
235
|
queryNode: QueryNode.cloneWithoutWhere(this.#props.queryNode),
|
|
844
236
|
});
|
|
845
237
|
}
|
|
846
|
-
/**
|
|
847
|
-
* Clears limit clause from the query.
|
|
848
|
-
*
|
|
849
|
-
* ### Examples
|
|
850
|
-
*
|
|
851
|
-
* ```ts
|
|
852
|
-
* db.selectFrom('person')
|
|
853
|
-
* .selectAll()
|
|
854
|
-
* .limit(10)
|
|
855
|
-
* .clearLimit()
|
|
856
|
-
* ```
|
|
857
|
-
*
|
|
858
|
-
* The generated SQL(PostgreSQL):
|
|
859
|
-
*
|
|
860
|
-
* ```sql
|
|
861
|
-
* select * from "person"
|
|
862
|
-
* ```
|
|
863
|
-
*/
|
|
864
238
|
clearLimit() {
|
|
865
|
-
return new
|
|
239
|
+
return new SelectQueryBuilderImpl({
|
|
866
240
|
...this.#props,
|
|
867
241
|
queryNode: SelectQueryNode.cloneWithoutLimit(this.#props.queryNode),
|
|
868
242
|
});
|
|
869
243
|
}
|
|
870
|
-
/**
|
|
871
|
-
* Clears offset clause from the query.
|
|
872
|
-
*
|
|
873
|
-
* ### Examples
|
|
874
|
-
*
|
|
875
|
-
* ```ts
|
|
876
|
-
* db.selectFrom('person')
|
|
877
|
-
* .selectAll()
|
|
878
|
-
* .limit(10)
|
|
879
|
-
* .offset(20)
|
|
880
|
-
* .clearOffset()
|
|
881
|
-
* ```
|
|
882
|
-
*
|
|
883
|
-
* The generated SQL(PostgreSQL):
|
|
884
|
-
*
|
|
885
|
-
* ```sql
|
|
886
|
-
* select * from "person" limit 10
|
|
887
|
-
* ```
|
|
888
|
-
*/
|
|
889
244
|
clearOffset() {
|
|
890
|
-
return new
|
|
245
|
+
return new SelectQueryBuilderImpl({
|
|
891
246
|
...this.#props,
|
|
892
247
|
queryNode: SelectQueryNode.cloneWithoutOffset(this.#props.queryNode),
|
|
893
248
|
});
|
|
894
249
|
}
|
|
895
|
-
/**
|
|
896
|
-
* Clears all `order by` clauses from the query.
|
|
897
|
-
*
|
|
898
|
-
* ### Examples
|
|
899
|
-
*
|
|
900
|
-
* ```ts
|
|
901
|
-
* db.selectFrom('person')
|
|
902
|
-
* .selectAll()
|
|
903
|
-
* .orderBy('id')
|
|
904
|
-
* .clearOrderBy()
|
|
905
|
-
* ```
|
|
906
|
-
*
|
|
907
|
-
* The generated SQL(PostgreSQL):
|
|
908
|
-
*
|
|
909
|
-
* ```sql
|
|
910
|
-
* select * from "person"
|
|
911
|
-
* ```
|
|
912
|
-
*/
|
|
913
250
|
clearOrderBy() {
|
|
914
|
-
return new
|
|
251
|
+
return new SelectQueryBuilderImpl({
|
|
915
252
|
...this.#props,
|
|
916
253
|
queryNode: SelectQueryNode.cloneWithoutOrderBy(this.#props.queryNode),
|
|
917
254
|
});
|
|
918
255
|
}
|
|
919
|
-
/**
|
|
920
|
-
* Simply calls the provided function passing `this` as the only argument. `$call` returns
|
|
921
|
-
* what the provided function returns.
|
|
922
|
-
*
|
|
923
|
-
* If you want to conditionally call a method on `this`, see
|
|
924
|
-
* the {@link $if} method.
|
|
925
|
-
*
|
|
926
|
-
* ### Examples
|
|
927
|
-
*
|
|
928
|
-
* The next example uses a helper function `log` to log a query:
|
|
929
|
-
*
|
|
930
|
-
* ```ts
|
|
931
|
-
* function log<T extends Compilable>(qb: T): T {
|
|
932
|
-
* console.log(qb.compile())
|
|
933
|
-
* return qb
|
|
934
|
-
* }
|
|
935
|
-
*
|
|
936
|
-
* db.selectFrom('person')
|
|
937
|
-
* .selectAll()
|
|
938
|
-
* .$call(log)
|
|
939
|
-
* .execute()
|
|
940
|
-
* ```
|
|
941
|
-
*/
|
|
942
256
|
$call(func) {
|
|
943
257
|
return func(this);
|
|
944
258
|
}
|
|
945
|
-
/**
|
|
946
|
-
* Call `func(this)` if `condition` is true.
|
|
947
|
-
*
|
|
948
|
-
* NOTE: This method has an impact on typescript performance and it should only be used
|
|
949
|
-
* when necessary. Remember that you can call most methods like `where` conditionally
|
|
950
|
-
* like this:
|
|
951
|
-
*
|
|
952
|
-
* ```ts
|
|
953
|
-
* let query = db.selectFrom('person').selectAll()
|
|
954
|
-
*
|
|
955
|
-
* if (firstName) {
|
|
956
|
-
* query = query.where('first_name', '=', firstName)
|
|
957
|
-
* }
|
|
958
|
-
*
|
|
959
|
-
* if (lastName) {
|
|
960
|
-
* query = query.where('last_name', '=', lastName)
|
|
961
|
-
* }
|
|
962
|
-
*
|
|
963
|
-
* const result = await query.execute()
|
|
964
|
-
* ```
|
|
965
|
-
*
|
|
966
|
-
* This method is mainly useful with optional selects. Any `select` or `selectAll`
|
|
967
|
-
* method called inside the callback add optional fields to the result type. This is
|
|
968
|
-
* because we can't know if those selections were actually made before running the code.
|
|
969
|
-
*
|
|
970
|
-
* Also see [this recipe](https://github.com/koskimas/kysely/tree/master/site/docs/recipes/conditional-selects.md)
|
|
971
|
-
*
|
|
972
|
-
* ### Examples
|
|
973
|
-
*
|
|
974
|
-
* ```ts
|
|
975
|
-
* async function getPerson(id: number, withLastName: boolean) {
|
|
976
|
-
* return await db
|
|
977
|
-
* .selectFrom('person')
|
|
978
|
-
* .select(['id', 'first_name'])
|
|
979
|
-
* .$if(withLastName, (qb) => qb.select('last_name'))
|
|
980
|
-
* .where('id', '=', id)
|
|
981
|
-
* .executeTakeFirstOrThrow()
|
|
982
|
-
* }
|
|
983
|
-
* ```
|
|
984
|
-
*
|
|
985
|
-
* Any selections added inside the `if` callback will be added as optional fields to the
|
|
986
|
-
* output type since we can't know if the selections were actually made before running
|
|
987
|
-
* the code. In the example above the return type of the `getPerson` function is:
|
|
988
|
-
*
|
|
989
|
-
* ```ts
|
|
990
|
-
* {
|
|
991
|
-
* id: number
|
|
992
|
-
* first_name: string
|
|
993
|
-
* last_name?: string
|
|
994
|
-
* }
|
|
995
|
-
* ```
|
|
996
|
-
*
|
|
997
|
-
* You can also call any other methods inside the callback:
|
|
998
|
-
*
|
|
999
|
-
* ```ts
|
|
1000
|
-
* db.selectFrom('person')
|
|
1001
|
-
* .select('person.id')
|
|
1002
|
-
* .$if(filterByFirstName, (qb) => qb.where('first_name', '=', firstName))
|
|
1003
|
-
* .$if(filterByPetCount, (qb) => qb
|
|
1004
|
-
* .innerJoin('pet', 'pet.owner_id', 'person.id')
|
|
1005
|
-
* .having((eb) => eb.fn.count('pet.id'), '>', petCountLimit)
|
|
1006
|
-
* .groupBy('person.id')
|
|
1007
|
-
* )
|
|
1008
|
-
* ```
|
|
1009
|
-
*/
|
|
1010
259
|
$if(condition, func) {
|
|
1011
260
|
if (condition) {
|
|
1012
261
|
return func(this);
|
|
1013
262
|
}
|
|
1014
|
-
return new
|
|
263
|
+
return new SelectQueryBuilderImpl({
|
|
1015
264
|
...this.#props,
|
|
1016
265
|
});
|
|
1017
266
|
}
|
|
1018
|
-
/**
|
|
1019
|
-
* Change the output type of the query.
|
|
1020
|
-
*
|
|
1021
|
-
* You should only use this method as the last resort if the types
|
|
1022
|
-
* don't support your use case.
|
|
1023
|
-
*/
|
|
1024
267
|
$castTo() {
|
|
1025
|
-
return new
|
|
268
|
+
return new SelectQueryBuilderImpl(this.#props);
|
|
1026
269
|
}
|
|
1027
|
-
/**
|
|
1028
|
-
* Narrows (parts of) the output type of the query.
|
|
1029
|
-
*
|
|
1030
|
-
* Kysely tries to be as type-safe as possible, but in some cases we have to make
|
|
1031
|
-
* compromises for better maintainability and compilation performance. At present,
|
|
1032
|
-
* Kysely doesn't narrow the output type of the query when using {@link where}, {@link having}
|
|
1033
|
-
* or {@link JoinQueryBuilder.on}.
|
|
1034
|
-
*
|
|
1035
|
-
* This utility method is very useful for these situations, as it removes unncessary
|
|
1036
|
-
* runtime assertion/guard code. Its input type is limited to the output type
|
|
1037
|
-
* of the query, so you can't add a column that doesn't exist, or change a column's
|
|
1038
|
-
* type to something that doesn't exist in its union type.
|
|
1039
|
-
*
|
|
1040
|
-
* ### Examples
|
|
1041
|
-
*
|
|
1042
|
-
* Turn this code:
|
|
1043
|
-
*
|
|
1044
|
-
* ```ts
|
|
1045
|
-
* const person = await db.selectFrom('person')
|
|
1046
|
-
* .where('nullable_column', 'is not', null)
|
|
1047
|
-
* .selectAll()
|
|
1048
|
-
* .executeTakeFirstOrThrow()
|
|
1049
|
-
*
|
|
1050
|
-
* if (person.nullable_column) {
|
|
1051
|
-
* functionThatExpectsPersonWithNonNullValue(person)
|
|
1052
|
-
* }
|
|
1053
|
-
* ```
|
|
1054
|
-
*
|
|
1055
|
-
* Into this:
|
|
1056
|
-
*
|
|
1057
|
-
* ```ts
|
|
1058
|
-
* const person = await db.selectFrom('person')
|
|
1059
|
-
* .where('nullable_column', 'is not', null)
|
|
1060
|
-
* .selectAll()
|
|
1061
|
-
* .$narrowType<{ nullable_column: string }>()
|
|
1062
|
-
* .executeTakeFirstOrThrow()
|
|
1063
|
-
*
|
|
1064
|
-
* functionThatExpectsPersonWithNonNullValue(person)
|
|
1065
|
-
* ```
|
|
1066
|
-
*/
|
|
1067
270
|
$narrowType() {
|
|
1068
|
-
return new
|
|
271
|
+
return new SelectQueryBuilderImpl(this.#props);
|
|
1069
272
|
}
|
|
1070
|
-
/**
|
|
1071
|
-
* Asserts that query's output row type equals the given type `T`.
|
|
1072
|
-
*
|
|
1073
|
-
* This method can be used to simplify excessively complex types to make typescript happy
|
|
1074
|
-
* and much faster.
|
|
1075
|
-
*
|
|
1076
|
-
* Kysely uses complex type magic to achieve its type safety. This complexity is sometimes too much
|
|
1077
|
-
* for typescript and you get errors like this:
|
|
1078
|
-
*
|
|
1079
|
-
* ```
|
|
1080
|
-
* error TS2589: Type instantiation is excessively deep and possibly infinite.
|
|
1081
|
-
* ```
|
|
1082
|
-
*
|
|
1083
|
-
* In these case you can often use this method to help typescript a little bit. When you use this
|
|
1084
|
-
* method to assert the output type of a query, Kysely can drop the complex output type that
|
|
1085
|
-
* consists of multiple nested helper types and replace it with the simple asserted type.
|
|
1086
|
-
*
|
|
1087
|
-
* Using this method doesn't reduce type safety at all. You have to pass in a type that is
|
|
1088
|
-
* structurally equal to the current type.
|
|
1089
|
-
*
|
|
1090
|
-
* ### Examples
|
|
1091
|
-
*
|
|
1092
|
-
* ```ts
|
|
1093
|
-
* const result = await db
|
|
1094
|
-
* .with('first_and_last', (qb) => qb
|
|
1095
|
-
* .selectFrom('person')
|
|
1096
|
-
* .select(['first_name', 'last_name'])
|
|
1097
|
-
* .$assertType<{ first_name: string, last_name: string }>()
|
|
1098
|
-
* )
|
|
1099
|
-
* .with('age', (qb) => qb
|
|
1100
|
-
* .selectFrom('person')
|
|
1101
|
-
* .select('age')
|
|
1102
|
-
* .$assertType<{ age: number }>()
|
|
1103
|
-
* )
|
|
1104
|
-
* .selectFrom(['first_and_last', 'age'])
|
|
1105
|
-
* .selectAll()
|
|
1106
|
-
* .executeTakeFirstOrThrow()
|
|
1107
|
-
* ```
|
|
1108
|
-
*/
|
|
1109
273
|
$assertType() {
|
|
1110
|
-
return new
|
|
274
|
+
return new SelectQueryBuilderImpl(this.#props);
|
|
275
|
+
}
|
|
276
|
+
$asTuple() {
|
|
277
|
+
return new ExpressionWrapper(this.toOperationNode());
|
|
1111
278
|
}
|
|
1112
|
-
/**
|
|
1113
|
-
* Returns a copy of this SelectQueryBuilder instance with the given plugin installed.
|
|
1114
|
-
*/
|
|
1115
279
|
withPlugin(plugin) {
|
|
1116
|
-
return new
|
|
280
|
+
return new SelectQueryBuilderImpl({
|
|
1117
281
|
...this.#props,
|
|
1118
282
|
executor: this.#props.executor.withPlugin(plugin),
|
|
1119
283
|
});
|
|
@@ -1124,32 +288,15 @@ export class SelectQueryBuilder {
|
|
|
1124
288
|
compile() {
|
|
1125
289
|
return this.#props.executor.compileQuery(this.toOperationNode(), this.#props.queryId);
|
|
1126
290
|
}
|
|
1127
|
-
/**
|
|
1128
|
-
* Executes the query and returns an array of rows.
|
|
1129
|
-
*
|
|
1130
|
-
* Also see the {@link executeTakeFirst} and {@link executeTakeFirstOrThrow} methods.
|
|
1131
|
-
*/
|
|
1132
291
|
async execute() {
|
|
1133
292
|
const compiledQuery = this.compile();
|
|
1134
293
|
const result = await this.#props.executor.executeQuery(compiledQuery, this.#props.queryId);
|
|
1135
294
|
return result.rows;
|
|
1136
295
|
}
|
|
1137
|
-
/**
|
|
1138
|
-
* Executes the query and returns the first result or undefined if
|
|
1139
|
-
* the query returned no result.
|
|
1140
|
-
*/
|
|
1141
296
|
async executeTakeFirst() {
|
|
1142
297
|
const [result] = await this.execute();
|
|
1143
298
|
return result;
|
|
1144
299
|
}
|
|
1145
|
-
/**
|
|
1146
|
-
* Executes the query and returns the first result or throws if
|
|
1147
|
-
* the query returned no result.
|
|
1148
|
-
*
|
|
1149
|
-
* By default an instance of {@link NoResultError} is thrown, but you can
|
|
1150
|
-
* provide a custom error class, or callback to throw a different
|
|
1151
|
-
* error.
|
|
1152
|
-
*/
|
|
1153
300
|
async executeTakeFirstOrThrow(errorConstructor = NoResultError) {
|
|
1154
301
|
const result = await this.executeTakeFirst();
|
|
1155
302
|
if (result === undefined) {
|
|
@@ -1168,33 +315,38 @@ export class SelectQueryBuilder {
|
|
|
1168
315
|
}
|
|
1169
316
|
}
|
|
1170
317
|
async explain(format, options) {
|
|
1171
|
-
const builder = new
|
|
318
|
+
const builder = new SelectQueryBuilderImpl({
|
|
1172
319
|
...this.#props,
|
|
1173
320
|
queryNode: QueryNode.cloneWithExplain(this.#props.queryNode, format, options),
|
|
1174
321
|
});
|
|
1175
322
|
return await builder.execute();
|
|
1176
323
|
}
|
|
1177
324
|
}
|
|
1178
|
-
preventAwait(
|
|
325
|
+
preventAwait(SelectQueryBuilderImpl, "don't await SelectQueryBuilder instances directly. To execute the query you need to call `execute` or `executeTakeFirst`.");
|
|
326
|
+
export function createSelectQueryBuilder(props) {
|
|
327
|
+
return new SelectQueryBuilderImpl(props);
|
|
328
|
+
}
|
|
1179
329
|
/**
|
|
1180
330
|
* {@link SelectQueryBuilder} with an alias. The result of calling {@link SelectQueryBuilder.as}.
|
|
1181
331
|
*/
|
|
1182
|
-
|
|
332
|
+
class AliasedSelectQueryBuilderImpl {
|
|
1183
333
|
#queryBuilder;
|
|
1184
334
|
#alias;
|
|
1185
335
|
constructor(queryBuilder, alias) {
|
|
1186
336
|
this.#queryBuilder = queryBuilder;
|
|
1187
337
|
this.#alias = alias;
|
|
1188
338
|
}
|
|
1189
|
-
/** @private */
|
|
1190
339
|
get expression() {
|
|
1191
340
|
return this.#queryBuilder;
|
|
1192
341
|
}
|
|
1193
|
-
/** @private */
|
|
1194
342
|
get alias() {
|
|
1195
343
|
return this.#alias;
|
|
1196
344
|
}
|
|
345
|
+
get isAliasedSelectQueryBuilder() {
|
|
346
|
+
return true;
|
|
347
|
+
}
|
|
1197
348
|
toOperationNode() {
|
|
1198
349
|
return AliasNode.create(this.#queryBuilder.toOperationNode(), IdentifierNode.create(this.#alias));
|
|
1199
350
|
}
|
|
1200
351
|
}
|
|
352
|
+
preventAwait(AliasedSelectQueryBuilderImpl, "don't await AliasedSelectQueryBuilder instances directly. AliasedSelectQueryBuilder should never be executed directly since it's always a part of another query.");
|