kysely 0.27.1 → 0.27.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/dist/cjs/dialect/database-introspector.d.ts +1 -0
- package/dist/cjs/dialect/mssql/mssql-introspector.js +13 -2
- package/dist/cjs/dialect/mssql/mssql-query-compiler.d.ts +4 -0
- package/dist/cjs/dialect/mssql/mssql-query-compiler.js +8 -0
- package/dist/cjs/dialect/mysql/mysql-introspector.js +2 -0
- package/dist/cjs/dialect/postgres/postgres-dialect-config.d.ts +1 -1
- package/dist/cjs/dialect/postgres/postgres-driver.js +2 -1
- package/dist/cjs/dialect/postgres/postgres-introspector.js +2 -0
- package/dist/cjs/dialect/sqlite/sqlite-introspector.js +1 -0
- package/dist/cjs/driver/database-connection.d.ts +1 -1
- package/dist/cjs/expression/expression-builder.d.ts +30 -4
- package/dist/cjs/expression/expression-builder.js +5 -0
- package/dist/cjs/index.d.ts +7 -1
- package/dist/cjs/index.js +6 -0
- package/dist/cjs/migration/migrator.d.ts +19 -2
- package/dist/cjs/migration/migrator.js +77 -43
- package/dist/cjs/operation-node/add-index-node.js +1 -1
- package/dist/cjs/operation-node/cast-node.d.ts +13 -0
- package/dist/cjs/operation-node/cast-node.js +19 -0
- package/dist/cjs/operation-node/column-definition-node.d.ts +1 -0
- package/dist/cjs/operation-node/data-type-node.d.ts +5 -1
- package/dist/cjs/operation-node/data-type-node.js +55 -1
- package/dist/cjs/operation-node/delete-query-node.d.ts +4 -0
- package/dist/cjs/operation-node/delete-query-node.js +12 -0
- package/dist/cjs/operation-node/fetch-node.d.ts +15 -0
- package/dist/cjs/operation-node/fetch-node.js +19 -0
- package/dist/cjs/operation-node/insert-query-node.d.ts +4 -1
- package/dist/cjs/operation-node/insert-query-node.js +5 -0
- package/dist/cjs/operation-node/join-node.d.ts +1 -1
- package/dist/cjs/operation-node/matched-node.d.ts +13 -0
- package/dist/cjs/operation-node/matched-node.js +19 -0
- package/dist/cjs/operation-node/merge-query-node.d.ts +25 -0
- package/dist/cjs/operation-node/merge-query-node.js +45 -0
- package/dist/cjs/operation-node/operation-node-transformer.d.ts +10 -0
- package/dist/cjs/operation-node/operation-node-transformer.js +50 -0
- package/dist/cjs/operation-node/operation-node-visitor.d.ts +10 -0
- package/dist/cjs/operation-node/operation-node-visitor.js +5 -0
- package/dist/cjs/operation-node/operation-node.d.ts +1 -1
- package/dist/cjs/operation-node/query-node.d.ts +10 -3
- package/dist/cjs/operation-node/query-node.js +15 -1
- package/dist/cjs/operation-node/select-query-node.d.ts +5 -0
- package/dist/cjs/operation-node/select-query-node.js +6 -0
- package/dist/cjs/operation-node/top-node.d.ts +14 -0
- package/dist/cjs/operation-node/top-node.js +19 -0
- package/dist/cjs/operation-node/update-query-node.d.ts +7 -1
- package/dist/cjs/operation-node/update-query-node.js +11 -0
- package/dist/cjs/parser/binary-operation-parser.d.ts +1 -1
- package/dist/cjs/parser/binary-operation-parser.js +2 -2
- package/dist/cjs/parser/data-type-parser.js +7 -3
- package/dist/cjs/parser/fetch-parser.d.ts +2 -0
- package/dist/cjs/parser/fetch-parser.js +18 -0
- package/dist/cjs/parser/insert-values-parser.d.ts +3 -3
- package/dist/cjs/parser/merge-parser.d.ts +9 -0
- package/dist/cjs/parser/merge-parser.js +32 -0
- package/dist/cjs/parser/table-parser.d.ts +4 -3
- package/dist/cjs/parser/top-parser.d.ts +2 -0
- package/dist/cjs/parser/top-parser.js +20 -0
- package/dist/cjs/plugin/with-schema/with-schema-transformer.js +4 -0
- package/dist/cjs/query-builder/delete-query-builder.d.ts +99 -0
- package/dist/cjs/query-builder/delete-query-builder.js +120 -0
- package/dist/cjs/query-builder/insert-query-builder.d.ts +73 -3
- package/dist/cjs/query-builder/insert-query-builder.js +242 -0
- package/dist/cjs/query-builder/merge-query-builder.d.ts +557 -0
- package/dist/cjs/query-builder/merge-query-builder.js +518 -0
- package/dist/cjs/query-builder/merge-result.d.ts +4 -0
- package/dist/cjs/query-builder/merge-result.js +10 -0
- package/dist/cjs/query-builder/select-query-builder.d.ts +102 -7
- package/dist/cjs/query-builder/select-query-builder.js +14 -0
- package/dist/cjs/query-builder/update-query-builder.d.ts +82 -3
- package/dist/cjs/query-builder/update-query-builder.js +98 -0
- package/dist/cjs/query-compiler/default-query-compiler.d.ts +10 -0
- package/dist/cjs/query-compiler/default-query-compiler.js +94 -10
- package/dist/cjs/query-compiler/query-compiler.d.ts +2 -1
- package/dist/cjs/query-creator.d.ts +40 -2
- package/dist/cjs/query-creator.js +9 -0
- package/dist/cjs/schema/alter-table-add-index-builder.js +6 -2
- package/dist/cjs/schema/column-definition-builder.d.ts +13 -1
- package/dist/cjs/schema/column-definition-builder.js +15 -1
- package/dist/cjs/util/infer-result.d.ts +2 -1
- package/dist/cjs/util/type-utils.d.ts +3 -2
- package/dist/esm/dialect/database-introspector.d.ts +1 -0
- package/dist/esm/dialect/mssql/mssql-introspector.js +13 -2
- package/dist/esm/dialect/mssql/mssql-query-compiler.d.ts +4 -0
- package/dist/esm/dialect/mssql/mssql-query-compiler.js +8 -0
- package/dist/esm/dialect/mysql/mysql-introspector.js +2 -0
- package/dist/esm/dialect/postgres/postgres-dialect-config.d.ts +1 -1
- package/dist/esm/dialect/postgres/postgres-driver.js +2 -1
- package/dist/esm/dialect/postgres/postgres-introspector.js +2 -0
- package/dist/esm/dialect/sqlite/sqlite-introspector.js +1 -0
- package/dist/esm/driver/database-connection.d.ts +1 -1
- package/dist/esm/expression/expression-builder.d.ts +30 -4
- package/dist/esm/expression/expression-builder.js +5 -0
- package/dist/esm/index.d.ts +7 -1
- package/dist/esm/index.js +6 -0
- package/dist/esm/migration/migrator.d.ts +19 -2
- package/dist/esm/migration/migrator.js +76 -42
- package/dist/esm/operation-node/add-index-node.js +1 -1
- package/dist/esm/operation-node/cast-node.d.ts +13 -0
- package/dist/esm/operation-node/cast-node.js +17 -0
- package/dist/esm/operation-node/column-definition-node.d.ts +1 -0
- package/dist/esm/operation-node/data-type-node.d.ts +5 -1
- package/dist/esm/operation-node/data-type-node.js +53 -0
- package/dist/esm/operation-node/delete-query-node.d.ts +4 -0
- package/dist/esm/operation-node/delete-query-node.js +12 -0
- package/dist/esm/operation-node/fetch-node.d.ts +15 -0
- package/dist/esm/operation-node/fetch-node.js +17 -0
- package/dist/esm/operation-node/insert-query-node.d.ts +4 -1
- package/dist/esm/operation-node/insert-query-node.js +5 -0
- package/dist/esm/operation-node/join-node.d.ts +1 -1
- package/dist/esm/operation-node/matched-node.d.ts +13 -0
- package/dist/esm/operation-node/matched-node.js +17 -0
- package/dist/esm/operation-node/merge-query-node.d.ts +25 -0
- package/dist/esm/operation-node/merge-query-node.js +43 -0
- package/dist/esm/operation-node/operation-node-transformer.d.ts +10 -0
- package/dist/esm/operation-node/operation-node-transformer.js +50 -0
- package/dist/esm/operation-node/operation-node-visitor.d.ts +10 -0
- package/dist/esm/operation-node/operation-node-visitor.js +5 -0
- package/dist/esm/operation-node/operation-node.d.ts +1 -1
- package/dist/esm/operation-node/query-node.d.ts +10 -3
- package/dist/esm/operation-node/query-node.js +15 -1
- package/dist/esm/operation-node/select-query-node.d.ts +5 -0
- package/dist/esm/operation-node/select-query-node.js +6 -0
- package/dist/esm/operation-node/top-node.d.ts +14 -0
- package/dist/esm/operation-node/top-node.js +17 -0
- package/dist/esm/operation-node/update-query-node.d.ts +7 -1
- package/dist/esm/operation-node/update-query-node.js +11 -0
- package/dist/esm/parser/binary-operation-parser.d.ts +1 -1
- package/dist/esm/parser/binary-operation-parser.js +2 -2
- package/dist/esm/parser/data-type-parser.js +8 -4
- package/dist/esm/parser/fetch-parser.d.ts +2 -0
- package/dist/esm/parser/fetch-parser.js +15 -0
- package/dist/esm/parser/insert-values-parser.d.ts +3 -3
- package/dist/esm/parser/merge-parser.d.ts +9 -0
- package/dist/esm/parser/merge-parser.js +28 -0
- package/dist/esm/parser/table-parser.d.ts +4 -3
- package/dist/esm/parser/top-parser.d.ts +2 -0
- package/dist/esm/parser/top-parser.js +17 -0
- package/dist/esm/plugin/with-schema/with-schema-transformer.js +4 -0
- package/dist/esm/query-builder/delete-query-builder.d.ts +99 -0
- package/dist/esm/query-builder/delete-query-builder.js +120 -0
- package/dist/esm/query-builder/insert-query-builder.d.ts +73 -3
- package/dist/esm/query-builder/insert-query-builder.js +242 -0
- package/dist/esm/query-builder/merge-query-builder.d.ts +557 -0
- package/dist/esm/query-builder/merge-query-builder.js +512 -0
- package/dist/esm/query-builder/merge-result.d.ts +4 -0
- package/dist/esm/query-builder/merge-result.js +7 -0
- package/dist/esm/query-builder/select-query-builder.d.ts +102 -7
- package/dist/esm/query-builder/select-query-builder.js +14 -0
- package/dist/esm/query-builder/update-query-builder.d.ts +82 -3
- package/dist/esm/query-builder/update-query-builder.js +98 -0
- package/dist/esm/query-compiler/default-query-compiler.d.ts +10 -0
- package/dist/esm/query-compiler/default-query-compiler.js +94 -10
- package/dist/esm/query-compiler/query-compiler.d.ts +2 -1
- package/dist/esm/query-creator.d.ts +40 -2
- package/dist/esm/query-creator.js +10 -1
- package/dist/esm/schema/alter-table-add-index-builder.js +7 -3
- package/dist/esm/schema/column-definition-builder.d.ts +13 -1
- package/dist/esm/schema/column-definition-builder.js +15 -1
- package/dist/esm/util/infer-result.d.ts +2 -1
- package/dist/esm/util/type-utils.d.ts +3 -2
- package/package.json +22 -21
|
@@ -0,0 +1,512 @@
|
|
|
1
|
+
/// <reference types="./merge-query-builder.d.ts" />
|
|
2
|
+
import { InsertQueryNode } from '../operation-node/insert-query-node.js';
|
|
3
|
+
import { MergeQueryNode } from '../operation-node/merge-query-node.js';
|
|
4
|
+
import { QueryNode } from '../operation-node/query-node.js';
|
|
5
|
+
import { UpdateQueryNode } from '../operation-node/update-query-node.js';
|
|
6
|
+
import { parseInsertExpression, } from '../parser/insert-values-parser.js';
|
|
7
|
+
import { parseJoin, } from '../parser/join-parser.js';
|
|
8
|
+
import { parseMergeThen, parseMergeWhen } from '../parser/merge-parser.js';
|
|
9
|
+
import { parseTop } from '../parser/top-parser.js';
|
|
10
|
+
import { NOOP_QUERY_EXECUTOR } from '../query-executor/noop-query-executor.js';
|
|
11
|
+
import { freeze } from '../util/object-utils.js';
|
|
12
|
+
import { preventAwait } from '../util/prevent-await.js';
|
|
13
|
+
import { MergeResult } from './merge-result.js';
|
|
14
|
+
import { NoResultError, isNoResultErrorConstructor, } from './no-result-error.js';
|
|
15
|
+
import { UpdateQueryBuilder } from './update-query-builder.js';
|
|
16
|
+
export class MergeQueryBuilder {
|
|
17
|
+
#props;
|
|
18
|
+
constructor(props) {
|
|
19
|
+
this.#props = freeze(props);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Changes a `merge into` query to an `merge top into` query.
|
|
23
|
+
*
|
|
24
|
+
* `top` clause is only supported by some dialects like MS SQL Server.
|
|
25
|
+
*
|
|
26
|
+
* ### Examples
|
|
27
|
+
*
|
|
28
|
+
* Affect 5 matched rows at most:
|
|
29
|
+
*
|
|
30
|
+
* ```ts
|
|
31
|
+
* await db.mergeInto('person')
|
|
32
|
+
* .top(5)
|
|
33
|
+
* .using('pet', 'person.id', 'pet.owner_id')
|
|
34
|
+
* .whenMatched()
|
|
35
|
+
* .thenDelete()
|
|
36
|
+
* .execute()
|
|
37
|
+
* ```
|
|
38
|
+
*
|
|
39
|
+
* The generated SQL (MS SQL Server):
|
|
40
|
+
*
|
|
41
|
+
* ```sql
|
|
42
|
+
* merge top(5) into "person"
|
|
43
|
+
* using "pet" on "person"."id" = "pet"."owner_id"
|
|
44
|
+
* when matched then
|
|
45
|
+
* delete
|
|
46
|
+
* ```
|
|
47
|
+
*
|
|
48
|
+
* Affect 50% of matched rows:
|
|
49
|
+
*
|
|
50
|
+
* ```ts
|
|
51
|
+
* await db.mergeInto('person')
|
|
52
|
+
* .top(50, 'percent')
|
|
53
|
+
* .using('pet', 'person.id', 'pet.owner_id')
|
|
54
|
+
* .whenMatched()
|
|
55
|
+
* .thenDelete()
|
|
56
|
+
* .execute()
|
|
57
|
+
* ```
|
|
58
|
+
*
|
|
59
|
+
* The generated SQL (MS SQL Server):
|
|
60
|
+
*
|
|
61
|
+
* ```sql
|
|
62
|
+
* merge top(50) percent into "person"
|
|
63
|
+
* using "pet" on "person"."id" = "pet"."owner_id"
|
|
64
|
+
* when matched then
|
|
65
|
+
* delete
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
top(expression, modifiers) {
|
|
69
|
+
return new MergeQueryBuilder({
|
|
70
|
+
...this.#props,
|
|
71
|
+
queryNode: QueryNode.cloneWithTop(this.#props.queryNode, parseTop(expression, modifiers)),
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
using(...args) {
|
|
75
|
+
return new WheneableMergeQueryBuilder({
|
|
76
|
+
...this.#props,
|
|
77
|
+
queryNode: MergeQueryNode.cloneWithUsing(this.#props.queryNode, parseJoin('Using', args)),
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
preventAwait(MergeQueryBuilder, "don't await MergeQueryBuilder instances directly. To execute the query you need to call `execute` when available.");
|
|
82
|
+
export class WheneableMergeQueryBuilder {
|
|
83
|
+
#props;
|
|
84
|
+
constructor(props) {
|
|
85
|
+
this.#props = freeze(props);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* See {@link MergeQueryBuilder.top}.
|
|
89
|
+
*/
|
|
90
|
+
top(expression, modifiers) {
|
|
91
|
+
return new WheneableMergeQueryBuilder({
|
|
92
|
+
...this.#props,
|
|
93
|
+
queryNode: QueryNode.cloneWithTop(this.#props.queryNode, parseTop(expression, modifiers)),
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Adds a simple `when matched` clause to the query.
|
|
98
|
+
*
|
|
99
|
+
* For a `when matched` clause with an `and` condition, see {@link whenMatchedAnd}.
|
|
100
|
+
*
|
|
101
|
+
* For a simple `when not matched` clause, see {@link whenNotMatched}.
|
|
102
|
+
*
|
|
103
|
+
* For a `when not matched` clause with an `and` condition, see {@link whenNotMatchedAnd}.
|
|
104
|
+
*
|
|
105
|
+
* ### Examples
|
|
106
|
+
*
|
|
107
|
+
* ```ts
|
|
108
|
+
* const result = await db.mergeInto('person')
|
|
109
|
+
* .using('pet', 'person.id', 'pet.owner_id')
|
|
110
|
+
* .whenMatched()
|
|
111
|
+
* .thenDelete()
|
|
112
|
+
* .execute()
|
|
113
|
+
* ```
|
|
114
|
+
*
|
|
115
|
+
* The generated SQL (PostgreSQL):
|
|
116
|
+
*
|
|
117
|
+
* ```sql
|
|
118
|
+
* merge into "person"
|
|
119
|
+
* using "pet" on "person"."id" = "pet"."owner_id"
|
|
120
|
+
* when matched then
|
|
121
|
+
* delete
|
|
122
|
+
* ```
|
|
123
|
+
*/
|
|
124
|
+
whenMatched() {
|
|
125
|
+
return this.#whenMatched([]);
|
|
126
|
+
}
|
|
127
|
+
whenMatchedAnd(...args) {
|
|
128
|
+
return this.#whenMatched(args);
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Adds the `when matched` clause to the query with an `and` condition. But unlike
|
|
132
|
+
* {@link whenMatchedAnd}, this method accepts a column reference as the 3rd argument.
|
|
133
|
+
*
|
|
134
|
+
* This method is similar to {@link SelectQueryBuilder.whereRef}, so see the documentation
|
|
135
|
+
* for that method for more examples.
|
|
136
|
+
*/
|
|
137
|
+
whenMatchedAndRef(lhs, op, rhs) {
|
|
138
|
+
return this.#whenMatched([lhs, op, rhs], true);
|
|
139
|
+
}
|
|
140
|
+
#whenMatched(args, refRight) {
|
|
141
|
+
return new MatchedThenableMergeQueryBuilder({
|
|
142
|
+
...this.#props,
|
|
143
|
+
queryNode: MergeQueryNode.cloneWithWhen(this.#props.queryNode, parseMergeWhen({ isMatched: true }, args, refRight)),
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Adds a simple `when not matched` clause to the query.
|
|
148
|
+
*
|
|
149
|
+
* For a `when not matched` clause with an `and` condition, see {@link whenNotMatchedAnd}.
|
|
150
|
+
*
|
|
151
|
+
* For a simple `when matched` clause, see {@link whenMatched}.
|
|
152
|
+
*
|
|
153
|
+
* For a `when matched` clause with an `and` condition, see {@link whenMatchedAnd}.
|
|
154
|
+
*
|
|
155
|
+
* ### Examples
|
|
156
|
+
*
|
|
157
|
+
* ```ts
|
|
158
|
+
* const result = await db.mergeInto('person')
|
|
159
|
+
* .using('pet', 'person.id', 'pet.owner_id')
|
|
160
|
+
* .whenNotMatched()
|
|
161
|
+
* .thenInsertValues({
|
|
162
|
+
* first_name: 'John',
|
|
163
|
+
* last_name: 'Doe',
|
|
164
|
+
* })
|
|
165
|
+
* .execute()
|
|
166
|
+
* ```
|
|
167
|
+
*
|
|
168
|
+
* The generated SQL (PostgreSQL):
|
|
169
|
+
*
|
|
170
|
+
* ```sql
|
|
171
|
+
* merge into "person"
|
|
172
|
+
* using "pet" on "person"."id" = "pet"."owner_id"
|
|
173
|
+
* when not matched then
|
|
174
|
+
* insert ("first_name", "last_name") values ($1, $2)
|
|
175
|
+
* ```
|
|
176
|
+
*/
|
|
177
|
+
whenNotMatched() {
|
|
178
|
+
return this.#whenNotMatched([]);
|
|
179
|
+
}
|
|
180
|
+
whenNotMatchedAnd(...args) {
|
|
181
|
+
return this.#whenNotMatched(args);
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Adds the `when not matched` clause to the query with an `and` condition. But unlike
|
|
185
|
+
* {@link whenNotMatchedAnd}, this method accepts a column reference as the 3rd argument.
|
|
186
|
+
*
|
|
187
|
+
* Unlike {@link whenMatchedAndRef}, you cannot reference columns from the target table.
|
|
188
|
+
*
|
|
189
|
+
* This method is similar to {@link SelectQueryBuilder.whereRef}, so see the documentation
|
|
190
|
+
* for that method for more examples.
|
|
191
|
+
*/
|
|
192
|
+
whenNotMatchedAndRef(lhs, op, rhs) {
|
|
193
|
+
return this.#whenNotMatched([lhs, op, rhs], true);
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Adds a simple `when not matched by source` clause to the query.
|
|
197
|
+
*
|
|
198
|
+
* Supported in MS SQL Server.
|
|
199
|
+
*
|
|
200
|
+
* Similar to {@link whenNotMatched}, but returns a {@link MatchedThenableMergeQueryBuilder}.
|
|
201
|
+
*/
|
|
202
|
+
whenNotMatchedBySource() {
|
|
203
|
+
return this.#whenNotMatched([], false, true);
|
|
204
|
+
}
|
|
205
|
+
whenNotMatchedBySourceAnd(...args) {
|
|
206
|
+
return this.#whenNotMatched(args, false, true);
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Adds the `when not matched by source` clause to the query with an `and` condition.
|
|
210
|
+
*
|
|
211
|
+
* Similar to {@link whenNotMatchedAndRef}, but you can reference columns from
|
|
212
|
+
* the target table, and not from source table and returns a {@link MatchedThenableMergeQueryBuilder}.
|
|
213
|
+
*/
|
|
214
|
+
whenNotMatchedBySourceAndRef(lhs, op, rhs) {
|
|
215
|
+
return this.#whenNotMatched([lhs, op, rhs], true, true);
|
|
216
|
+
}
|
|
217
|
+
#whenNotMatched(args, refRight = false, bySource = false) {
|
|
218
|
+
const props = {
|
|
219
|
+
...this.#props,
|
|
220
|
+
queryNode: MergeQueryNode.cloneWithWhen(this.#props.queryNode, parseMergeWhen({ isMatched: false, bySource }, args, refRight)),
|
|
221
|
+
};
|
|
222
|
+
const Builder = bySource
|
|
223
|
+
? MatchedThenableMergeQueryBuilder
|
|
224
|
+
: NotMatchedThenableMergeQueryBuilder;
|
|
225
|
+
return new Builder(props);
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Simply calls the provided function passing `this` as the only argument. `$call` returns
|
|
229
|
+
* what the provided function returns.
|
|
230
|
+
*
|
|
231
|
+
* If you want to conditionally call a method on `this`, see
|
|
232
|
+
* the {@link $if} method.
|
|
233
|
+
*
|
|
234
|
+
* ### Examples
|
|
235
|
+
*
|
|
236
|
+
* The next example uses a helper function `log` to log a query:
|
|
237
|
+
*
|
|
238
|
+
* ```ts
|
|
239
|
+
* function log<T extends Compilable>(qb: T): T {
|
|
240
|
+
* console.log(qb.compile())
|
|
241
|
+
* return qb
|
|
242
|
+
* }
|
|
243
|
+
*
|
|
244
|
+
* db.updateTable('person')
|
|
245
|
+
* .set(values)
|
|
246
|
+
* .$call(log)
|
|
247
|
+
* .execute()
|
|
248
|
+
* ```
|
|
249
|
+
*/
|
|
250
|
+
$call(func) {
|
|
251
|
+
return func(this);
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Call `func(this)` if `condition` is true.
|
|
255
|
+
*
|
|
256
|
+
* This method is especially handy with optional selects. Any `returning` or `returningAll`
|
|
257
|
+
* method calls add columns as optional fields to the output type when called inside
|
|
258
|
+
* the `func` callback. This is because we can't know if those selections were actually
|
|
259
|
+
* made before running the code.
|
|
260
|
+
*
|
|
261
|
+
* You can also call any other methods inside the callback.
|
|
262
|
+
*
|
|
263
|
+
* ### Examples
|
|
264
|
+
*
|
|
265
|
+
* ```ts
|
|
266
|
+
* async function updatePerson(id: number, updates: UpdateablePerson, returnLastName: boolean) {
|
|
267
|
+
* return await db
|
|
268
|
+
* .updateTable('person')
|
|
269
|
+
* .set(updates)
|
|
270
|
+
* .where('id', '=', id)
|
|
271
|
+
* .returning(['id', 'first_name'])
|
|
272
|
+
* .$if(returnLastName, (qb) => qb.returning('last_name'))
|
|
273
|
+
* .executeTakeFirstOrThrow()
|
|
274
|
+
* }
|
|
275
|
+
* ```
|
|
276
|
+
*
|
|
277
|
+
* Any selections added inside the `if` callback will be added as optional fields to the
|
|
278
|
+
* output type since we can't know if the selections were actually made before running
|
|
279
|
+
* the code. In the example above the return type of the `updatePerson` function is:
|
|
280
|
+
*
|
|
281
|
+
* ```ts
|
|
282
|
+
* {
|
|
283
|
+
* id: number
|
|
284
|
+
* first_name: string
|
|
285
|
+
* last_name?: string
|
|
286
|
+
* }
|
|
287
|
+
* ```
|
|
288
|
+
*/
|
|
289
|
+
$if(condition, func) {
|
|
290
|
+
if (condition) {
|
|
291
|
+
return func(this);
|
|
292
|
+
}
|
|
293
|
+
return new WheneableMergeQueryBuilder({
|
|
294
|
+
...this.#props,
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
toOperationNode() {
|
|
298
|
+
return this.#props.executor.transformQuery(this.#props.queryNode, this.#props.queryId);
|
|
299
|
+
}
|
|
300
|
+
compile() {
|
|
301
|
+
return this.#props.executor.compileQuery(this.#props.queryNode, this.#props.queryId);
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Executes the query and returns an array of rows.
|
|
305
|
+
*
|
|
306
|
+
* Also see the {@link executeTakeFirst} and {@link executeTakeFirstOrThrow} methods.
|
|
307
|
+
*/
|
|
308
|
+
async execute() {
|
|
309
|
+
const compiledQuery = this.compile();
|
|
310
|
+
const result = await this.#props.executor.executeQuery(compiledQuery, this.#props.queryId);
|
|
311
|
+
return [new MergeResult(result.numAffectedRows)];
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Executes the query and returns the first result or undefined if
|
|
315
|
+
* the query returned no result.
|
|
316
|
+
*/
|
|
317
|
+
async executeTakeFirst() {
|
|
318
|
+
const [result] = await this.execute();
|
|
319
|
+
return result;
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Executes the query and returns the first result or throws if
|
|
323
|
+
* the query returned no result.
|
|
324
|
+
*
|
|
325
|
+
* By default an instance of {@link NoResultError} is thrown, but you can
|
|
326
|
+
* provide a custom error class, or callback as the only argument to throw a different
|
|
327
|
+
* error.
|
|
328
|
+
*/
|
|
329
|
+
async executeTakeFirstOrThrow(errorConstructor = NoResultError) {
|
|
330
|
+
const result = await this.executeTakeFirst();
|
|
331
|
+
if (result === undefined) {
|
|
332
|
+
const error = isNoResultErrorConstructor(errorConstructor)
|
|
333
|
+
? new errorConstructor(this.toOperationNode())
|
|
334
|
+
: errorConstructor(this.toOperationNode());
|
|
335
|
+
throw error;
|
|
336
|
+
}
|
|
337
|
+
return result;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
preventAwait(WheneableMergeQueryBuilder, "don't await WheneableMergeQueryBuilder instances directly. To execute the query you need to call `execute`.");
|
|
341
|
+
export class MatchedThenableMergeQueryBuilder {
|
|
342
|
+
#props;
|
|
343
|
+
constructor(props) {
|
|
344
|
+
this.#props = freeze(props);
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Performs the `delete` action.
|
|
348
|
+
*
|
|
349
|
+
* To perform the `do nothing` action, see {@link thenDoNothing}.
|
|
350
|
+
*
|
|
351
|
+
* To perform the `update` action, see {@link thenUpdate} or {@link thenUpdateSet}.
|
|
352
|
+
*
|
|
353
|
+
* ### Examples
|
|
354
|
+
*
|
|
355
|
+
* ```ts
|
|
356
|
+
* const result = await db.mergeInto('person')
|
|
357
|
+
* .using('pet', 'person.id', 'pet.owner_id')
|
|
358
|
+
* .whenMatched()
|
|
359
|
+
* .thenDelete()
|
|
360
|
+
* .execute()
|
|
361
|
+
* ```
|
|
362
|
+
*
|
|
363
|
+
* The generated SQL (PostgreSQL):
|
|
364
|
+
*
|
|
365
|
+
* ```sql
|
|
366
|
+
* merge into "person"
|
|
367
|
+
* using "pet" on "person"."id" = "pet"."owner_id"
|
|
368
|
+
* when matched then
|
|
369
|
+
* delete
|
|
370
|
+
* ```
|
|
371
|
+
*/
|
|
372
|
+
thenDelete() {
|
|
373
|
+
return new WheneableMergeQueryBuilder({
|
|
374
|
+
...this.#props,
|
|
375
|
+
queryNode: MergeQueryNode.cloneWithThen(this.#props.queryNode, parseMergeThen('delete')),
|
|
376
|
+
});
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* Performs the `do nothing` action.
|
|
380
|
+
*
|
|
381
|
+
* This is supported in PostgreSQL.
|
|
382
|
+
*
|
|
383
|
+
* To perform the `delete` action, see {@link thenDelete}.
|
|
384
|
+
*
|
|
385
|
+
* To perform the `update` action, see {@link thenUpdate} or {@link thenUpdateSet}.
|
|
386
|
+
*
|
|
387
|
+
* ### Examples
|
|
388
|
+
*
|
|
389
|
+
* ```ts
|
|
390
|
+
* const result = await db.mergeInto('person')
|
|
391
|
+
* .using('pet', 'person.id', 'pet.owner_id')
|
|
392
|
+
* .whenMatched()
|
|
393
|
+
* .thenDoNothing()
|
|
394
|
+
* .execute()
|
|
395
|
+
* ```
|
|
396
|
+
*
|
|
397
|
+
* The generated SQL (PostgreSQL):
|
|
398
|
+
*
|
|
399
|
+
* ```sql
|
|
400
|
+
* merge into "person"
|
|
401
|
+
* using "pet" on "person"."id" = "pet"."owner_id"
|
|
402
|
+
* when matched then
|
|
403
|
+
* do nothing
|
|
404
|
+
* ```
|
|
405
|
+
*/
|
|
406
|
+
thenDoNothing() {
|
|
407
|
+
return new WheneableMergeQueryBuilder({
|
|
408
|
+
...this.#props,
|
|
409
|
+
queryNode: MergeQueryNode.cloneWithThen(this.#props.queryNode, parseMergeThen('do nothing')),
|
|
410
|
+
});
|
|
411
|
+
}
|
|
412
|
+
/**
|
|
413
|
+
* Perform an `update` operation with a full-fledged {@link UpdateQueryBuilder}.
|
|
414
|
+
* This is handy when multiple `set` invocations are needed.
|
|
415
|
+
*
|
|
416
|
+
* For a shorthand version of this method, see {@link thenUpdateSet}.
|
|
417
|
+
*
|
|
418
|
+
* To perform the `delete` action, see {@link thenDelete}.
|
|
419
|
+
*
|
|
420
|
+
* To perform the `do nothing` action, see {@link thenDoNothing}.
|
|
421
|
+
*
|
|
422
|
+
* ### Examples
|
|
423
|
+
*
|
|
424
|
+
* ```ts
|
|
425
|
+
* import { sql } from 'kysely'
|
|
426
|
+
*
|
|
427
|
+
* const result = await db.mergeInto('person')
|
|
428
|
+
* .using('pet', 'person.id', 'pet.owner_id')
|
|
429
|
+
* .whenMatched()
|
|
430
|
+
* .thenUpdate((ub) => ub
|
|
431
|
+
* .set(sql`metadata['has_pets']`, 'Y')
|
|
432
|
+
* .set({
|
|
433
|
+
* updated_at: Date.now(),
|
|
434
|
+
* })
|
|
435
|
+
* )
|
|
436
|
+
* .execute()
|
|
437
|
+
* ```
|
|
438
|
+
*
|
|
439
|
+
* The generated SQL (PostgreSQL):
|
|
440
|
+
*
|
|
441
|
+
* ```sql
|
|
442
|
+
* merge into "person"
|
|
443
|
+
* using "pet" on "person"."id" = "pet"."owner_id"
|
|
444
|
+
* when matched then
|
|
445
|
+
* update set metadata['has_pets'] = $1, "updated_at" = $2
|
|
446
|
+
* ```
|
|
447
|
+
*/
|
|
448
|
+
thenUpdate(set) {
|
|
449
|
+
return new WheneableMergeQueryBuilder({
|
|
450
|
+
...this.#props,
|
|
451
|
+
queryNode: MergeQueryNode.cloneWithThen(this.#props.queryNode, parseMergeThen(set(new UpdateQueryBuilder({
|
|
452
|
+
queryId: this.#props.queryId,
|
|
453
|
+
executor: NOOP_QUERY_EXECUTOR,
|
|
454
|
+
queryNode: UpdateQueryNode.createWithoutTable(),
|
|
455
|
+
})))),
|
|
456
|
+
});
|
|
457
|
+
}
|
|
458
|
+
thenUpdateSet(...args) {
|
|
459
|
+
// @ts-ignore not sure how to type this so it won't complain about set(...args).
|
|
460
|
+
return this.thenUpdate((ub) => ub.set(...args));
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
preventAwait(MatchedThenableMergeQueryBuilder, "don't await MatchedThenableMergeQueryBuilder instances directly. To execute the query you need to call `execute` when available.");
|
|
464
|
+
export class NotMatchedThenableMergeQueryBuilder {
|
|
465
|
+
#props;
|
|
466
|
+
constructor(props) {
|
|
467
|
+
this.#props = freeze(props);
|
|
468
|
+
}
|
|
469
|
+
/**
|
|
470
|
+
* Performs the `do nothing` action.
|
|
471
|
+
*
|
|
472
|
+
* This is supported in PostgreSQL.
|
|
473
|
+
*
|
|
474
|
+
* To perform the `insert` action, see {@link thenInsertValues}.
|
|
475
|
+
*
|
|
476
|
+
* ### Examples
|
|
477
|
+
*
|
|
478
|
+
* ```ts
|
|
479
|
+
* const result = await db.mergeInto('person')
|
|
480
|
+
* .using('pet', 'person.id', 'pet.owner_id')
|
|
481
|
+
* .whenNotMatched()
|
|
482
|
+
* .thenDoNothing()
|
|
483
|
+
* .execute()
|
|
484
|
+
* ```
|
|
485
|
+
*
|
|
486
|
+
* The generated SQL (PostgreSQL):
|
|
487
|
+
*
|
|
488
|
+
* ```sql
|
|
489
|
+
* merge into "person"
|
|
490
|
+
* using "pet" on "person"."id" = "pet"."owner_id"
|
|
491
|
+
* when not matched then
|
|
492
|
+
* do nothing
|
|
493
|
+
* ```
|
|
494
|
+
*/
|
|
495
|
+
thenDoNothing() {
|
|
496
|
+
return new WheneableMergeQueryBuilder({
|
|
497
|
+
...this.#props,
|
|
498
|
+
queryNode: MergeQueryNode.cloneWithThen(this.#props.queryNode, parseMergeThen('do nothing')),
|
|
499
|
+
});
|
|
500
|
+
}
|
|
501
|
+
thenInsertValues(insert) {
|
|
502
|
+
const [columns, values] = parseInsertExpression(insert);
|
|
503
|
+
return new WheneableMergeQueryBuilder({
|
|
504
|
+
...this.#props,
|
|
505
|
+
queryNode: MergeQueryNode.cloneWithThen(this.#props.queryNode, parseMergeThen(InsertQueryNode.cloneWith(InsertQueryNode.createWithoutInto(), {
|
|
506
|
+
columns,
|
|
507
|
+
values,
|
|
508
|
+
}))),
|
|
509
|
+
});
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
preventAwait(NotMatchedThenableMergeQueryBuilder, "don't await NotMatchedThenableMergeQueryBuilder instances directly. To execute the query you need to call `execute` when available.");
|
|
@@ -26,6 +26,8 @@ import { ExpressionOrFactory } from '../parser/expression-parser.js';
|
|
|
26
26
|
import { ExpressionWrapper } from '../expression/expression-wrapper.js';
|
|
27
27
|
import { SelectQueryBuilderExpression } from './select-query-builder-expression.js';
|
|
28
28
|
import { ValueExpression } from '../parser/value-parser.js';
|
|
29
|
+
import { FetchModifier } from '../operation-node/fetch-node.js';
|
|
30
|
+
import { TopModifier } from '../operation-node/top-node.js';
|
|
29
31
|
export interface SelectQueryBuilder<DB, TB extends keyof DB, O> extends WhereInterface<DB, TB>, HavingInterface<DB, TB>, SelectQueryBuilderExpression<O>, Compilable<O>, Explainable, Streamable<O> {
|
|
30
32
|
/**
|
|
31
33
|
* Adds a `where` expression to the query.
|
|
@@ -809,8 +811,10 @@ export interface SelectQueryBuilder<DB, TB extends keyof DB, O> extends WhereInt
|
|
|
809
811
|
* builder for creating more complex joins. The join builder has a
|
|
810
812
|
* bunch of `on*` methods for building the `on` clause of the join.
|
|
811
813
|
* There's basically an equivalent for every `where` method
|
|
812
|
-
* (`on`, `onRef` etc.).
|
|
813
|
-
*
|
|
814
|
+
* (`on`, `onRef` etc.).
|
|
815
|
+
*
|
|
816
|
+
* You can do all the same things with the
|
|
817
|
+
* `on` method that you can with the corresponding `where` method (like [OR expressions for example](https://kysely.dev/docs/examples/WHERE/or-where)).
|
|
814
818
|
* See the `where` method documentation for more examples.
|
|
815
819
|
*
|
|
816
820
|
* ```ts
|
|
@@ -820,6 +824,7 @@ export interface SelectQueryBuilder<DB, TB extends keyof DB, O> extends WhereInt
|
|
|
820
824
|
* (join) => join
|
|
821
825
|
* .onRef('pet.owner_id', '=', 'person.id')
|
|
822
826
|
* .on('pet.name', '=', 'Doggo')
|
|
827
|
+
* .on((eb) => eb.or([eb("person.age", ">", 18), eb("person.age", "<", 100)]))
|
|
823
828
|
* )
|
|
824
829
|
* .selectAll()
|
|
825
830
|
* .execute()
|
|
@@ -1150,6 +1155,13 @@ export interface SelectQueryBuilder<DB, TB extends keyof DB, O> extends WhereInt
|
|
|
1150
1155
|
* .selectFrom('person')
|
|
1151
1156
|
* .select('first_name')
|
|
1152
1157
|
* .limit(10)
|
|
1158
|
+
* .execute()
|
|
1159
|
+
* ```
|
|
1160
|
+
*
|
|
1161
|
+
* The generated SQL (PostgreSQL):
|
|
1162
|
+
*
|
|
1163
|
+
* ```sql
|
|
1164
|
+
* select "first_name" from "person" limit $1
|
|
1153
1165
|
* ```
|
|
1154
1166
|
*
|
|
1155
1167
|
* Select rows from index 10 to index 19 of the result:
|
|
@@ -1158,13 +1170,20 @@ export interface SelectQueryBuilder<DB, TB extends keyof DB, O> extends WhereInt
|
|
|
1158
1170
|
* return await db
|
|
1159
1171
|
* .selectFrom('person')
|
|
1160
1172
|
* .select('first_name')
|
|
1161
|
-
* .offset(10)
|
|
1162
1173
|
* .limit(10)
|
|
1174
|
+
* .offset(10)
|
|
1175
|
+
* .execute()
|
|
1176
|
+
* ```
|
|
1177
|
+
*
|
|
1178
|
+
* The generated SQL (PostgreSQL):
|
|
1179
|
+
*
|
|
1180
|
+
* ```sql
|
|
1181
|
+
* select "first_name" from "person" limit $1 offset $2
|
|
1163
1182
|
* ```
|
|
1164
1183
|
*/
|
|
1165
|
-
limit(limit: ValueExpression<DB, TB, number>): SelectQueryBuilder<DB, TB, O>;
|
|
1184
|
+
limit(limit: ValueExpression<DB, TB, number | bigint>): SelectQueryBuilder<DB, TB, O>;
|
|
1166
1185
|
/**
|
|
1167
|
-
* Adds an offset clause to the query.
|
|
1186
|
+
* Adds an `offset` clause to the query.
|
|
1168
1187
|
*
|
|
1169
1188
|
* ### Examples
|
|
1170
1189
|
*
|
|
@@ -1174,11 +1193,87 @@ export interface SelectQueryBuilder<DB, TB extends keyof DB, O> extends WhereInt
|
|
|
1174
1193
|
* return await db
|
|
1175
1194
|
* .selectFrom('person')
|
|
1176
1195
|
* .select('first_name')
|
|
1177
|
-
* .offset(10)
|
|
1178
1196
|
* .limit(10)
|
|
1197
|
+
* .offset(10)
|
|
1198
|
+
* .execute()
|
|
1199
|
+
* ```
|
|
1200
|
+
*
|
|
1201
|
+
* The generated SQL (PostgreSQL):
|
|
1202
|
+
*
|
|
1203
|
+
* ```sql
|
|
1204
|
+
* select "first_name" from "person" limit $1 offset $2
|
|
1205
|
+
* ```
|
|
1206
|
+
*/
|
|
1207
|
+
offset(offset: ValueExpression<DB, TB, number | bigint>): SelectQueryBuilder<DB, TB, O>;
|
|
1208
|
+
/**
|
|
1209
|
+
* Adds a `fetch` clause to the query.
|
|
1210
|
+
*
|
|
1211
|
+
* This clause is only supported by some dialects like PostgreSQL or MS SQL Server.
|
|
1212
|
+
*
|
|
1213
|
+
* ### Examples
|
|
1214
|
+
*
|
|
1215
|
+
* ```ts
|
|
1216
|
+
* return await db
|
|
1217
|
+
* .selectFrom('person')
|
|
1218
|
+
* .select('first_name')
|
|
1219
|
+
* .orderBy('first_name')
|
|
1220
|
+
* .offset(0)
|
|
1221
|
+
* .fetch(10)
|
|
1222
|
+
* .execute()
|
|
1223
|
+
* ```
|
|
1224
|
+
*
|
|
1225
|
+
* The generated SQL (MS SQL Server):
|
|
1226
|
+
*
|
|
1227
|
+
* ```sql
|
|
1228
|
+
* select "first_name"
|
|
1229
|
+
* from "person"
|
|
1230
|
+
* order by "first_name"
|
|
1231
|
+
* offset 0 rows
|
|
1232
|
+
* fetch next 10 rows only
|
|
1233
|
+
* ```
|
|
1234
|
+
*/
|
|
1235
|
+
fetch(rowCount: number | bigint, modifier?: FetchModifier): SelectQueryBuilder<DB, TB, O>;
|
|
1236
|
+
/**
|
|
1237
|
+
* Adds a `top` clause to the query.
|
|
1238
|
+
*
|
|
1239
|
+
* This clause is only supported by some dialects like MS SQL Server.
|
|
1240
|
+
*
|
|
1241
|
+
* ### Examples
|
|
1242
|
+
*
|
|
1243
|
+
* Select 10 biggest ages:
|
|
1244
|
+
*
|
|
1245
|
+
* ```ts
|
|
1246
|
+
* return await db
|
|
1247
|
+
* .selectFrom('person')
|
|
1248
|
+
* .select('age')
|
|
1249
|
+
* .top(10)
|
|
1250
|
+
* .orderBy('age desc')
|
|
1251
|
+
* .execute()
|
|
1252
|
+
* ```
|
|
1253
|
+
*
|
|
1254
|
+
* The generated SQL (MS SQL Server):
|
|
1255
|
+
*
|
|
1256
|
+
* ```sql
|
|
1257
|
+
* select top(10) "age" from "person" order by "age" desc
|
|
1258
|
+
* ```
|
|
1259
|
+
*
|
|
1260
|
+
* Select 10% first rows:
|
|
1261
|
+
*
|
|
1262
|
+
* ```ts
|
|
1263
|
+
* return await db
|
|
1264
|
+
* .selectFrom('person')
|
|
1265
|
+
* .selectAll()
|
|
1266
|
+
* .top(10, 'percent')
|
|
1267
|
+
* .execute()
|
|
1268
|
+
* ```
|
|
1269
|
+
*
|
|
1270
|
+
* The generated SQL (MS SQL Server):
|
|
1271
|
+
*
|
|
1272
|
+
* ```sql
|
|
1273
|
+
* select top(10) percent * from "person"
|
|
1179
1274
|
* ```
|
|
1180
1275
|
*/
|
|
1181
|
-
|
|
1276
|
+
top(expression: number | bigint, modifiers?: TopModifier): SelectQueryBuilder<DB, TB, O>;
|
|
1182
1277
|
/**
|
|
1183
1278
|
* Combines another select query or raw expression to this query using `union`.
|
|
1184
1279
|
*
|