metal-orm 1.0.14 → 1.0.16
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 +69 -67
- package/dist/decorators/index.cjs +1983 -224
- package/dist/decorators/index.cjs.map +1 -1
- package/dist/decorators/index.d.cts +6 -6
- package/dist/decorators/index.d.ts +6 -6
- package/dist/decorators/index.js +1982 -224
- package/dist/decorators/index.js.map +1 -1
- package/dist/index.cjs +5284 -3751
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +524 -169
- package/dist/index.d.ts +524 -169
- package/dist/index.js +5197 -3736
- package/dist/index.js.map +1 -1
- package/dist/{select-CCp1oz9p.d.cts → select-BKZrMRCQ.d.cts} +555 -94
- package/dist/{select-CCp1oz9p.d.ts → select-BKZrMRCQ.d.ts} +555 -94
- package/package.json +1 -1
- package/src/codegen/naming-strategy.ts +64 -0
- package/src/codegen/typescript.ts +19 -21
- package/src/core/ast/adapters.ts +21 -0
- package/src/core/ast/aggregate-functions.ts +13 -13
- package/src/core/ast/builders.ts +56 -43
- package/src/core/ast/expression-builders.ts +34 -34
- package/src/core/ast/expression-nodes.ts +18 -16
- package/src/core/ast/expression-visitor.ts +122 -69
- package/src/core/ast/expression.ts +6 -4
- package/src/core/ast/join-metadata.ts +15 -0
- package/src/core/ast/join-node.ts +22 -20
- package/src/core/ast/join.ts +5 -5
- package/src/core/ast/query.ts +52 -88
- package/src/core/ast/types.ts +20 -0
- package/src/core/ast/window-functions.ts +55 -55
- package/src/core/ddl/dialects/base-schema-dialect.ts +20 -6
- package/src/core/ddl/dialects/mssql-schema-dialect.ts +32 -8
- package/src/core/ddl/dialects/mysql-schema-dialect.ts +21 -10
- package/src/core/ddl/dialects/postgres-schema-dialect.ts +52 -7
- package/src/core/ddl/dialects/sqlite-schema-dialect.ts +23 -9
- package/src/core/ddl/introspect/catalogs/index.ts +1 -0
- package/src/core/ddl/introspect/catalogs/postgres.ts +143 -0
- package/src/core/ddl/introspect/context.ts +9 -0
- package/src/core/ddl/introspect/functions/postgres.ts +26 -0
- package/src/core/ddl/introspect/mssql.ts +149 -149
- package/src/core/ddl/introspect/mysql.ts +99 -99
- package/src/core/ddl/introspect/postgres.ts +245 -154
- package/src/core/ddl/introspect/registry.ts +26 -0
- package/src/core/ddl/introspect/run-select.ts +25 -0
- package/src/core/ddl/introspect/sqlite.ts +7 -7
- package/src/core/ddl/introspect/types.ts +23 -19
- package/src/core/ddl/introspect/utils.ts +1 -1
- package/src/core/ddl/naming-strategy.ts +10 -0
- package/src/core/ddl/schema-dialect.ts +41 -0
- package/src/core/ddl/schema-diff.ts +211 -179
- package/src/core/ddl/schema-generator.ts +17 -90
- package/src/core/ddl/schema-introspect.ts +25 -32
- package/src/core/ddl/schema-plan-executor.ts +17 -0
- package/src/core/ddl/schema-types.ts +46 -39
- package/src/core/ddl/sql-writing.ts +170 -0
- package/src/core/dialect/abstract.ts +172 -126
- package/src/core/dialect/base/cte-compiler.ts +33 -0
- package/src/core/dialect/base/function-table-formatter.ts +132 -0
- package/src/core/dialect/base/groupby-compiler.ts +21 -0
- package/src/core/dialect/base/join-compiler.ts +26 -0
- package/src/core/dialect/base/orderby-compiler.ts +21 -0
- package/src/core/dialect/base/pagination-strategy.ts +32 -0
- package/src/core/dialect/base/returning-strategy.ts +56 -0
- package/src/core/dialect/base/sql-dialect.ts +181 -204
- package/src/core/dialect/dialect-factory.ts +91 -0
- package/src/core/dialect/mssql/functions.ts +101 -0
- package/src/core/dialect/mssql/index.ts +128 -126
- package/src/core/dialect/mysql/functions.ts +101 -0
- package/src/core/dialect/mysql/index.ts +20 -18
- package/src/core/dialect/postgres/functions.ts +95 -0
- package/src/core/dialect/postgres/index.ts +30 -28
- package/src/core/dialect/sqlite/functions.ts +115 -0
- package/src/core/dialect/sqlite/index.ts +30 -28
- package/src/core/driver/database-driver.ts +11 -0
- package/src/core/driver/mssql-driver.ts +20 -0
- package/src/core/driver/mysql-driver.ts +20 -0
- package/src/core/driver/postgres-driver.ts +20 -0
- package/src/core/driver/sqlite-driver.ts +20 -0
- package/src/core/execution/db-executor.ts +63 -0
- package/src/core/execution/executors/mssql-executor.ts +39 -0
- package/src/core/execution/executors/mysql-executor.ts +47 -0
- package/src/core/execution/executors/postgres-executor.ts +32 -0
- package/src/core/execution/executors/sqlite-executor.ts +31 -0
- package/src/core/functions/datetime.ts +132 -0
- package/src/core/functions/numeric.ts +179 -0
- package/src/core/functions/standard-strategy.ts +47 -0
- package/src/core/functions/text.ts +147 -0
- package/src/core/functions/types.ts +18 -0
- package/src/core/hydration/types.ts +57 -0
- package/src/decorators/bootstrap.ts +10 -0
- package/src/decorators/column.ts +13 -4
- package/src/decorators/relations.ts +15 -0
- package/src/index.ts +37 -19
- package/src/orm/entity-context.ts +30 -0
- package/src/orm/entity-meta.ts +2 -2
- package/src/orm/entity-metadata.ts +8 -6
- package/src/orm/entity.ts +72 -41
- package/src/orm/execute.ts +42 -25
- package/src/orm/execution-context.ts +12 -0
- package/src/orm/hydration-context.ts +14 -0
- package/src/orm/hydration.ts +25 -17
- package/src/orm/identity-map.ts +4 -0
- package/src/orm/interceptor-pipeline.ts +29 -0
- package/src/orm/lazy-batch.ts +50 -6
- package/src/orm/orm-session.ts +234 -0
- package/src/orm/orm.ts +58 -0
- package/src/orm/query-logger.ts +1 -1
- package/src/orm/relation-change-processor.ts +48 -3
- package/src/orm/relations/belongs-to.ts +45 -44
- package/src/orm/relations/has-many.ts +44 -43
- package/src/orm/relations/has-one.ts +140 -0
- package/src/orm/relations/many-to-many.ts +46 -45
- package/src/orm/transaction-runner.ts +1 -1
- package/src/orm/unit-of-work.ts +66 -61
- package/src/query-builder/delete.ts +22 -5
- package/src/query-builder/hydration-manager.ts +2 -1
- package/src/query-builder/hydration-planner.ts +8 -7
- package/src/query-builder/insert.ts +22 -5
- package/src/query-builder/relation-conditions.ts +9 -8
- package/src/query-builder/relation-service.ts +3 -2
- package/src/query-builder/select.ts +575 -64
- package/src/query-builder/update.ts +22 -5
- package/src/schema/column.ts +246 -246
- package/src/schema/relation.ts +35 -1
- package/src/schema/table.ts +28 -28
- package/src/schema/types.ts +41 -31
- package/src/orm/db-executor.ts +0 -11
- package/src/orm/orm-context.ts +0 -159
|
@@ -1,489 +1,1000 @@
|
|
|
1
1
|
import { TableDef } from '../schema/table.js';
|
|
2
|
+
|
|
2
3
|
import { ColumnDef } from '../schema/column.js';
|
|
3
|
-
|
|
4
|
+
|
|
5
|
+
import { SelectQueryNode, SetOperationKind } from '../core/ast/query.js';
|
|
6
|
+
|
|
7
|
+
import { HydrationPlan } from '../core/hydration/types.js';
|
|
8
|
+
|
|
4
9
|
import {
|
|
10
|
+
|
|
5
11
|
ColumnNode,
|
|
12
|
+
|
|
6
13
|
ExpressionNode,
|
|
14
|
+
|
|
7
15
|
FunctionNode,
|
|
16
|
+
|
|
8
17
|
LiteralNode,
|
|
18
|
+
|
|
9
19
|
BinaryExpressionNode,
|
|
20
|
+
|
|
10
21
|
CaseExpressionNode,
|
|
22
|
+
|
|
11
23
|
WindowFunctionNode,
|
|
24
|
+
|
|
12
25
|
exists,
|
|
26
|
+
|
|
13
27
|
notExists
|
|
28
|
+
|
|
14
29
|
} from '../core/ast/expression.js';
|
|
30
|
+
|
|
15
31
|
import { CompiledQuery, Dialect } from '../core/dialect/abstract.js';
|
|
32
|
+
|
|
33
|
+
import { DialectKey, resolveDialectInput } from '../core/dialect/dialect-factory.js';
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
type SelectDialectInput = Dialect | DialectKey;
|
|
38
|
+
|
|
16
39
|
import { SelectQueryState } from './select-query-state.js';
|
|
40
|
+
|
|
17
41
|
import { HydrationManager } from './hydration-manager.js';
|
|
42
|
+
|
|
18
43
|
import {
|
|
44
|
+
|
|
19
45
|
resolveSelectQueryBuilderDependencies,
|
|
46
|
+
|
|
20
47
|
SelectQueryBuilderContext,
|
|
48
|
+
|
|
21
49
|
SelectQueryBuilderDependencies,
|
|
50
|
+
|
|
22
51
|
SelectQueryBuilderEnvironment
|
|
52
|
+
|
|
23
53
|
} from './select-query-builder-deps.js';
|
|
54
|
+
|
|
24
55
|
import { QueryAstService } from './query-ast-service.js';
|
|
56
|
+
|
|
25
57
|
import { ColumnSelector } from './column-selector.js';
|
|
58
|
+
|
|
26
59
|
import { RelationManager } from './relation-manager.js';
|
|
60
|
+
|
|
27
61
|
import { RelationIncludeOptions } from './relation-types.js';
|
|
62
|
+
|
|
28
63
|
import { JOIN_KINDS, JoinKind, ORDER_DIRECTIONS, OrderDirection } from '../core/sql/sql.js';
|
|
64
|
+
|
|
29
65
|
import { Entity, RelationMap } from '../schema/types.js';
|
|
30
|
-
|
|
31
|
-
import {
|
|
66
|
+
|
|
67
|
+
import { OrmSession } from '../orm/orm-session.ts';
|
|
68
|
+
|
|
69
|
+
import { ExecutionContext } from '../orm/execution-context.js';
|
|
70
|
+
|
|
71
|
+
import { HydrationContext } from '../orm/hydration-context.js';
|
|
72
|
+
|
|
73
|
+
import { executeHydrated, executeHydratedWithContexts } from '../orm/execute.js';
|
|
74
|
+
|
|
32
75
|
import { createJoinNode } from '../core/ast/join-node.js';
|
|
33
76
|
|
|
77
|
+
|
|
78
|
+
|
|
34
79
|
/**
|
|
80
|
+
|
|
35
81
|
* Main query builder class for constructing SQL SELECT queries
|
|
82
|
+
|
|
36
83
|
* @typeParam T - Result type for projections (unused)
|
|
84
|
+
|
|
37
85
|
* @typeParam TTable - Table definition being queried
|
|
86
|
+
|
|
38
87
|
*/
|
|
88
|
+
|
|
39
89
|
export class SelectQueryBuilder<T = any, TTable extends TableDef = TableDef> {
|
|
90
|
+
|
|
40
91
|
private readonly env: SelectQueryBuilderEnvironment;
|
|
92
|
+
|
|
41
93
|
private readonly context: SelectQueryBuilderContext;
|
|
94
|
+
|
|
42
95
|
private readonly columnSelector: ColumnSelector;
|
|
96
|
+
|
|
43
97
|
private readonly relationManager: RelationManager;
|
|
98
|
+
|
|
44
99
|
private readonly lazyRelations: Set<string>;
|
|
45
100
|
|
|
101
|
+
|
|
102
|
+
|
|
46
103
|
/**
|
|
104
|
+
|
|
47
105
|
* Creates a new SelectQueryBuilder instance
|
|
106
|
+
|
|
48
107
|
* @param table - Table definition to query
|
|
108
|
+
|
|
49
109
|
* @param state - Optional initial query state
|
|
110
|
+
|
|
50
111
|
* @param hydration - Optional hydration manager
|
|
112
|
+
|
|
51
113
|
* @param dependencies - Optional query builder dependencies
|
|
114
|
+
|
|
52
115
|
*/
|
|
116
|
+
|
|
53
117
|
constructor(
|
|
118
|
+
|
|
54
119
|
table: TTable,
|
|
120
|
+
|
|
55
121
|
state?: SelectQueryState,
|
|
122
|
+
|
|
56
123
|
hydration?: HydrationManager,
|
|
124
|
+
|
|
57
125
|
dependencies?: Partial<SelectQueryBuilderDependencies>,
|
|
126
|
+
|
|
58
127
|
lazyRelations?: Set<string>
|
|
128
|
+
|
|
59
129
|
) {
|
|
130
|
+
|
|
60
131
|
const deps = resolveSelectQueryBuilderDependencies(dependencies);
|
|
132
|
+
|
|
61
133
|
this.env = { table, deps };
|
|
134
|
+
|
|
62
135
|
const initialState = state ?? deps.createState(table);
|
|
136
|
+
|
|
63
137
|
const initialHydration = hydration ?? deps.createHydration(table);
|
|
138
|
+
|
|
64
139
|
this.context = {
|
|
140
|
+
|
|
65
141
|
state: initialState,
|
|
142
|
+
|
|
66
143
|
hydration: initialHydration
|
|
144
|
+
|
|
67
145
|
};
|
|
146
|
+
|
|
68
147
|
this.lazyRelations = new Set(lazyRelations ?? []);
|
|
148
|
+
|
|
69
149
|
this.columnSelector = new ColumnSelector(this.env);
|
|
150
|
+
|
|
70
151
|
this.relationManager = new RelationManager(this.env);
|
|
152
|
+
|
|
71
153
|
}
|
|
72
154
|
|
|
155
|
+
|
|
156
|
+
|
|
73
157
|
private clone(
|
|
158
|
+
|
|
74
159
|
context: SelectQueryBuilderContext = this.context,
|
|
160
|
+
|
|
75
161
|
lazyRelations = new Set(this.lazyRelations)
|
|
162
|
+
|
|
76
163
|
): SelectQueryBuilder<T, TTable> {
|
|
164
|
+
|
|
77
165
|
return new SelectQueryBuilder(this.env.table as TTable, context.state, context.hydration, this.env.deps, lazyRelations);
|
|
166
|
+
|
|
78
167
|
}
|
|
79
168
|
|
|
169
|
+
|
|
170
|
+
|
|
80
171
|
private resolveQueryNode(query: SelectQueryBuilder<any, TableDef<any>> | SelectQueryNode): SelectQueryNode {
|
|
172
|
+
|
|
81
173
|
return typeof (query as any).getAST === 'function'
|
|
174
|
+
|
|
82
175
|
? (query as SelectQueryBuilder<any, TableDef<any>>).getAST()
|
|
176
|
+
|
|
83
177
|
: (query as SelectQueryNode);
|
|
178
|
+
|
|
84
179
|
}
|
|
85
180
|
|
|
181
|
+
|
|
182
|
+
|
|
86
183
|
private createChildBuilder<R, TChild extends TableDef>(table: TChild): SelectQueryBuilder<R, TChild> {
|
|
184
|
+
|
|
87
185
|
return new SelectQueryBuilder(table, undefined, undefined, this.env.deps);
|
|
186
|
+
|
|
88
187
|
}
|
|
89
188
|
|
|
189
|
+
|
|
190
|
+
|
|
90
191
|
private applyAst(
|
|
192
|
+
|
|
91
193
|
context: SelectQueryBuilderContext,
|
|
194
|
+
|
|
92
195
|
mutator: (service: QueryAstService) => SelectQueryState
|
|
196
|
+
|
|
93
197
|
): SelectQueryBuilderContext {
|
|
198
|
+
|
|
94
199
|
const astService = this.env.deps.createQueryAstService(this.env.table, context.state);
|
|
200
|
+
|
|
95
201
|
const nextState = mutator(astService);
|
|
202
|
+
|
|
96
203
|
return { state: nextState, hydration: context.hydration };
|
|
204
|
+
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
private applyJoin(
|
|
210
|
+
|
|
211
|
+
context: SelectQueryBuilderContext,
|
|
212
|
+
|
|
213
|
+
table: TableDef,
|
|
214
|
+
|
|
215
|
+
condition: BinaryExpressionNode,
|
|
216
|
+
|
|
217
|
+
kind: JoinKind
|
|
218
|
+
|
|
219
|
+
): SelectQueryBuilderContext {
|
|
220
|
+
|
|
221
|
+
const joinNode = createJoinNode(kind, table.name, condition);
|
|
222
|
+
|
|
223
|
+
return this.applyAst(context, service => service.withJoin(joinNode));
|
|
224
|
+
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
private applySetOperation(
|
|
230
|
+
|
|
231
|
+
operator: SetOperationKind,
|
|
232
|
+
|
|
233
|
+
query: SelectQueryBuilder<any, TableDef<any>> | SelectQueryNode
|
|
234
|
+
|
|
235
|
+
): SelectQueryBuilderContext {
|
|
236
|
+
|
|
237
|
+
const subAst = this.resolveQueryNode(query);
|
|
238
|
+
|
|
239
|
+
return this.applyAst(this.context, service => service.withSetOperation(operator, subAst));
|
|
240
|
+
|
|
97
241
|
}
|
|
98
242
|
|
|
99
|
-
|
|
100
|
-
context: SelectQueryBuilderContext,
|
|
101
|
-
table: TableDef,
|
|
102
|
-
condition: BinaryExpressionNode,
|
|
103
|
-
kind: JoinKind
|
|
104
|
-
): SelectQueryBuilderContext {
|
|
105
|
-
const joinNode = createJoinNode(kind, table.name, condition);
|
|
106
|
-
return this.applyAst(context, service => service.withJoin(joinNode));
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
private applySetOperation(
|
|
110
|
-
operator: SetOperationKind,
|
|
111
|
-
query: SelectQueryBuilder<any, TableDef<any>> | SelectQueryNode
|
|
112
|
-
): SelectQueryBuilderContext {
|
|
113
|
-
const subAst = this.resolveQueryNode(query);
|
|
114
|
-
return this.applyAst(this.context, service => service.withSetOperation(operator, subAst));
|
|
115
|
-
}
|
|
243
|
+
|
|
116
244
|
|
|
117
245
|
/**
|
|
246
|
+
|
|
118
247
|
* Selects specific columns for the query
|
|
248
|
+
|
|
119
249
|
* @param columns - Record of column definitions, function nodes, case expressions, or window functions
|
|
250
|
+
|
|
120
251
|
* @returns New query builder instance with selected columns
|
|
252
|
+
|
|
121
253
|
*/
|
|
254
|
+
|
|
122
255
|
select(columns: Record<string, ColumnDef | FunctionNode | CaseExpressionNode | WindowFunctionNode>): SelectQueryBuilder<T, TTable> {
|
|
256
|
+
|
|
123
257
|
return this.clone(this.columnSelector.select(this.context, columns));
|
|
258
|
+
|
|
124
259
|
}
|
|
125
260
|
|
|
261
|
+
|
|
262
|
+
|
|
126
263
|
/**
|
|
264
|
+
|
|
127
265
|
* Selects raw column expressions
|
|
266
|
+
|
|
128
267
|
* @param cols - Column expressions as strings
|
|
268
|
+
|
|
129
269
|
* @returns New query builder instance with raw column selections
|
|
270
|
+
|
|
130
271
|
*/
|
|
272
|
+
|
|
131
273
|
selectRaw(...cols: string[]): SelectQueryBuilder<T, TTable> {
|
|
274
|
+
|
|
132
275
|
return this.clone(this.columnSelector.selectRaw(this.context, cols));
|
|
276
|
+
|
|
133
277
|
}
|
|
134
278
|
|
|
279
|
+
|
|
280
|
+
|
|
135
281
|
/**
|
|
282
|
+
|
|
136
283
|
* Adds a Common Table Expression (CTE) to the query
|
|
284
|
+
|
|
137
285
|
* @param name - Name of the CTE
|
|
286
|
+
|
|
138
287
|
* @param query - Query builder or query node for the CTE
|
|
288
|
+
|
|
139
289
|
* @param columns - Optional column names for the CTE
|
|
290
|
+
|
|
140
291
|
* @returns New query builder instance with the CTE
|
|
292
|
+
|
|
141
293
|
*/
|
|
294
|
+
|
|
142
295
|
with(name: string, query: SelectQueryBuilder<any, TableDef<any>> | SelectQueryNode, columns?: string[]): SelectQueryBuilder<T, TTable> {
|
|
296
|
+
|
|
143
297
|
const subAst = this.resolveQueryNode(query);
|
|
298
|
+
|
|
144
299
|
const nextContext = this.applyAst(this.context, service => service.withCte(name, subAst, columns, false));
|
|
300
|
+
|
|
145
301
|
return this.clone(nextContext);
|
|
302
|
+
|
|
146
303
|
}
|
|
147
304
|
|
|
305
|
+
|
|
306
|
+
|
|
148
307
|
/**
|
|
308
|
+
|
|
149
309
|
* Adds a recursive Common Table Expression (CTE) to the query
|
|
310
|
+
|
|
150
311
|
* @param name - Name of the CTE
|
|
312
|
+
|
|
151
313
|
* @param query - Query builder or query node for the CTE
|
|
314
|
+
|
|
152
315
|
* @param columns - Optional column names for the CTE
|
|
316
|
+
|
|
153
317
|
* @returns New query builder instance with the recursive CTE
|
|
318
|
+
|
|
154
319
|
*/
|
|
320
|
+
|
|
155
321
|
withRecursive(name: string, query: SelectQueryBuilder<any, TableDef<any>> | SelectQueryNode, columns?: string[]): SelectQueryBuilder<T, TTable> {
|
|
322
|
+
|
|
156
323
|
const subAst = this.resolveQueryNode(query);
|
|
324
|
+
|
|
157
325
|
const nextContext = this.applyAst(this.context, service => service.withCte(name, subAst, columns, true));
|
|
326
|
+
|
|
158
327
|
return this.clone(nextContext);
|
|
328
|
+
|
|
159
329
|
}
|
|
160
330
|
|
|
331
|
+
|
|
332
|
+
|
|
161
333
|
/**
|
|
334
|
+
|
|
162
335
|
* Selects a subquery as a column
|
|
336
|
+
|
|
163
337
|
* @param alias - Alias for the subquery column
|
|
338
|
+
|
|
164
339
|
* @param sub - Query builder or query node for the subquery
|
|
340
|
+
|
|
165
341
|
* @returns New query builder instance with the subquery selection
|
|
342
|
+
|
|
166
343
|
*/
|
|
344
|
+
|
|
167
345
|
selectSubquery(alias: string, sub: SelectQueryBuilder<any, TableDef<any>> | SelectQueryNode): SelectQueryBuilder<T, TTable> {
|
|
346
|
+
|
|
168
347
|
const query = this.resolveQueryNode(sub);
|
|
348
|
+
|
|
169
349
|
return this.clone(this.columnSelector.selectSubquery(this.context, alias, query));
|
|
350
|
+
|
|
170
351
|
}
|
|
171
352
|
|
|
353
|
+
|
|
354
|
+
|
|
172
355
|
/**
|
|
356
|
+
|
|
173
357
|
* Adds an INNER JOIN to the query
|
|
358
|
+
|
|
174
359
|
* @param table - Table to join
|
|
360
|
+
|
|
175
361
|
* @param condition - Join condition expression
|
|
362
|
+
|
|
176
363
|
* @returns New query builder instance with the INNER JOIN
|
|
364
|
+
|
|
177
365
|
*/
|
|
366
|
+
|
|
178
367
|
innerJoin(table: TableDef, condition: BinaryExpressionNode): SelectQueryBuilder<T, TTable> {
|
|
368
|
+
|
|
179
369
|
const nextContext = this.applyJoin(this.context, table, condition, JOIN_KINDS.INNER);
|
|
370
|
+
|
|
180
371
|
return this.clone(nextContext);
|
|
372
|
+
|
|
181
373
|
}
|
|
182
374
|
|
|
375
|
+
|
|
376
|
+
|
|
183
377
|
/**
|
|
378
|
+
|
|
184
379
|
* Adds a LEFT JOIN to the query
|
|
380
|
+
|
|
185
381
|
* @param table - Table to join
|
|
382
|
+
|
|
186
383
|
* @param condition - Join condition expression
|
|
384
|
+
|
|
187
385
|
* @returns New query builder instance with the LEFT JOIN
|
|
386
|
+
|
|
188
387
|
*/
|
|
388
|
+
|
|
189
389
|
leftJoin(table: TableDef, condition: BinaryExpressionNode): SelectQueryBuilder<T, TTable> {
|
|
390
|
+
|
|
190
391
|
const nextContext = this.applyJoin(this.context, table, condition, JOIN_KINDS.LEFT);
|
|
392
|
+
|
|
191
393
|
return this.clone(nextContext);
|
|
394
|
+
|
|
192
395
|
}
|
|
193
396
|
|
|
397
|
+
|
|
398
|
+
|
|
194
399
|
/**
|
|
400
|
+
|
|
195
401
|
* Adds a RIGHT JOIN to the query
|
|
402
|
+
|
|
196
403
|
* @param table - Table to join
|
|
404
|
+
|
|
197
405
|
* @param condition - Join condition expression
|
|
406
|
+
|
|
198
407
|
* @returns New query builder instance with the RIGHT JOIN
|
|
408
|
+
|
|
199
409
|
*/
|
|
410
|
+
|
|
200
411
|
rightJoin(table: TableDef, condition: BinaryExpressionNode): SelectQueryBuilder<T, TTable> {
|
|
412
|
+
|
|
201
413
|
const nextContext = this.applyJoin(this.context, table, condition, JOIN_KINDS.RIGHT);
|
|
414
|
+
|
|
202
415
|
return this.clone(nextContext);
|
|
416
|
+
|
|
203
417
|
}
|
|
204
418
|
|
|
419
|
+
|
|
420
|
+
|
|
205
421
|
/**
|
|
422
|
+
|
|
206
423
|
* Matches records based on a relationship
|
|
424
|
+
|
|
207
425
|
* @param relationName - Name of the relationship to match
|
|
426
|
+
|
|
208
427
|
* @param predicate - Optional predicate expression
|
|
428
|
+
|
|
209
429
|
* @returns New query builder instance with the relationship match
|
|
430
|
+
|
|
210
431
|
*/
|
|
432
|
+
|
|
211
433
|
match(relationName: string, predicate?: ExpressionNode): SelectQueryBuilder<T, TTable> {
|
|
434
|
+
|
|
212
435
|
const nextContext = this.relationManager.match(this.context, relationName, predicate);
|
|
436
|
+
|
|
213
437
|
return this.clone(nextContext);
|
|
438
|
+
|
|
214
439
|
}
|
|
215
440
|
|
|
441
|
+
|
|
442
|
+
|
|
216
443
|
/**
|
|
444
|
+
|
|
217
445
|
* Joins a related table
|
|
446
|
+
|
|
218
447
|
* @param relationName - Name of the relationship to join
|
|
448
|
+
|
|
219
449
|
* @param joinKind - Type of join (defaults to INNER)
|
|
450
|
+
|
|
220
451
|
* @param extraCondition - Optional additional join condition
|
|
452
|
+
|
|
221
453
|
* @returns New query builder instance with the relationship join
|
|
454
|
+
|
|
222
455
|
*/
|
|
456
|
+
|
|
223
457
|
joinRelation(
|
|
458
|
+
|
|
224
459
|
relationName: string,
|
|
460
|
+
|
|
225
461
|
joinKind: JoinKind = JOIN_KINDS.INNER,
|
|
462
|
+
|
|
226
463
|
extraCondition?: ExpressionNode
|
|
464
|
+
|
|
227
465
|
): SelectQueryBuilder<T, TTable> {
|
|
466
|
+
|
|
228
467
|
const nextContext = this.relationManager.joinRelation(this.context, relationName, joinKind, extraCondition);
|
|
468
|
+
|
|
229
469
|
return this.clone(nextContext);
|
|
470
|
+
|
|
230
471
|
}
|
|
231
472
|
|
|
473
|
+
|
|
474
|
+
|
|
232
475
|
/**
|
|
476
|
+
|
|
233
477
|
* Includes related data in the query results
|
|
478
|
+
|
|
234
479
|
* @param relationName - Name of the relationship to include
|
|
480
|
+
|
|
235
481
|
* @param options - Optional include options
|
|
482
|
+
|
|
236
483
|
* @returns New query builder instance with the relationship inclusion
|
|
484
|
+
|
|
237
485
|
*/
|
|
486
|
+
|
|
238
487
|
include(relationName: string, options?: RelationIncludeOptions): SelectQueryBuilder<T, TTable> {
|
|
488
|
+
|
|
239
489
|
const nextContext = this.relationManager.include(this.context, relationName, options);
|
|
490
|
+
|
|
240
491
|
return this.clone(nextContext);
|
|
492
|
+
|
|
241
493
|
}
|
|
242
494
|
|
|
495
|
+
|
|
496
|
+
|
|
243
497
|
includeLazy<K extends keyof RelationMap<TTable>>(relationName: K): SelectQueryBuilder<T, TTable> {
|
|
498
|
+
|
|
244
499
|
const nextLazy = new Set(this.lazyRelations);
|
|
500
|
+
|
|
245
501
|
nextLazy.add(relationName as string);
|
|
502
|
+
|
|
246
503
|
return this.clone(this.context, nextLazy);
|
|
504
|
+
|
|
247
505
|
}
|
|
248
506
|
|
|
507
|
+
|
|
508
|
+
|
|
249
509
|
getLazyRelations(): (keyof RelationMap<TTable>)[] {
|
|
510
|
+
|
|
250
511
|
return Array.from(this.lazyRelations) as (keyof RelationMap<TTable>)[];
|
|
512
|
+
|
|
251
513
|
}
|
|
252
514
|
|
|
515
|
+
|
|
516
|
+
|
|
253
517
|
getTable(): TTable {
|
|
518
|
+
|
|
254
519
|
return this.env.table as TTable;
|
|
520
|
+
|
|
255
521
|
}
|
|
256
522
|
|
|
257
|
-
|
|
523
|
+
|
|
524
|
+
|
|
525
|
+
async execute(ctx: OrmSession): Promise<Entity<TTable>[]> {
|
|
526
|
+
|
|
258
527
|
return executeHydrated(ctx, this);
|
|
528
|
+
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
|
|
532
|
+
|
|
533
|
+
async executeWithContexts(execCtx: ExecutionContext, hydCtx: HydrationContext): Promise<Entity<TTable>[]> {
|
|
534
|
+
|
|
535
|
+
return executeHydratedWithContexts(execCtx, hydCtx, this);
|
|
536
|
+
|
|
259
537
|
}
|
|
260
538
|
|
|
539
|
+
|
|
540
|
+
|
|
261
541
|
/**
|
|
542
|
+
|
|
262
543
|
* Adds a WHERE condition to the query
|
|
544
|
+
|
|
263
545
|
* @param expr - Expression for the WHERE clause
|
|
546
|
+
|
|
264
547
|
* @returns New query builder instance with the WHERE condition
|
|
548
|
+
|
|
265
549
|
*/
|
|
550
|
+
|
|
266
551
|
where(expr: ExpressionNode): SelectQueryBuilder<T, TTable> {
|
|
552
|
+
|
|
267
553
|
const nextContext = this.applyAst(this.context, service => service.withWhere(expr));
|
|
554
|
+
|
|
268
555
|
return this.clone(nextContext);
|
|
556
|
+
|
|
269
557
|
}
|
|
270
558
|
|
|
559
|
+
|
|
560
|
+
|
|
271
561
|
/**
|
|
562
|
+
|
|
272
563
|
* Adds a GROUP BY clause to the query
|
|
564
|
+
|
|
273
565
|
* @param col - Column definition or column node to group by
|
|
566
|
+
|
|
274
567
|
* @returns New query builder instance with the GROUP BY clause
|
|
568
|
+
|
|
275
569
|
*/
|
|
570
|
+
|
|
276
571
|
groupBy(col: ColumnDef | ColumnNode): SelectQueryBuilder<T, TTable> {
|
|
572
|
+
|
|
277
573
|
const nextContext = this.applyAst(this.context, service => service.withGroupBy(col));
|
|
574
|
+
|
|
278
575
|
return this.clone(nextContext);
|
|
576
|
+
|
|
279
577
|
}
|
|
280
578
|
|
|
579
|
+
|
|
580
|
+
|
|
281
581
|
/**
|
|
582
|
+
|
|
282
583
|
* Adds a HAVING condition to the query
|
|
584
|
+
|
|
283
585
|
* @param expr - Expression for the HAVING clause
|
|
586
|
+
|
|
284
587
|
* @returns New query builder instance with the HAVING condition
|
|
588
|
+
|
|
285
589
|
*/
|
|
590
|
+
|
|
286
591
|
having(expr: ExpressionNode): SelectQueryBuilder<T, TTable> {
|
|
592
|
+
|
|
287
593
|
const nextContext = this.applyAst(this.context, service => service.withHaving(expr));
|
|
594
|
+
|
|
288
595
|
return this.clone(nextContext);
|
|
596
|
+
|
|
289
597
|
}
|
|
290
598
|
|
|
599
|
+
|
|
600
|
+
|
|
291
601
|
/**
|
|
602
|
+
|
|
292
603
|
* Adds an ORDER BY clause to the query
|
|
604
|
+
|
|
293
605
|
* @param col - Column definition or column node to order by
|
|
606
|
+
|
|
294
607
|
* @param direction - Order direction (defaults to ASC)
|
|
608
|
+
|
|
295
609
|
* @returns New query builder instance with the ORDER BY clause
|
|
610
|
+
|
|
296
611
|
*/
|
|
612
|
+
|
|
297
613
|
orderBy(col: ColumnDef | ColumnNode, direction: OrderDirection = ORDER_DIRECTIONS.ASC): SelectQueryBuilder<T, TTable> {
|
|
614
|
+
|
|
298
615
|
const nextContext = this.applyAst(this.context, service => service.withOrderBy(col, direction));
|
|
616
|
+
|
|
299
617
|
return this.clone(nextContext);
|
|
618
|
+
|
|
300
619
|
}
|
|
301
620
|
|
|
621
|
+
|
|
622
|
+
|
|
302
623
|
/**
|
|
624
|
+
|
|
303
625
|
* Adds a DISTINCT clause to the query
|
|
626
|
+
|
|
304
627
|
* @param cols - Columns to make distinct
|
|
628
|
+
|
|
305
629
|
* @returns New query builder instance with the DISTINCT clause
|
|
630
|
+
|
|
306
631
|
*/
|
|
632
|
+
|
|
307
633
|
distinct(...cols: (ColumnDef | ColumnNode)[]): SelectQueryBuilder<T, TTable> {
|
|
634
|
+
|
|
308
635
|
return this.clone(this.columnSelector.distinct(this.context, cols));
|
|
636
|
+
|
|
309
637
|
}
|
|
310
638
|
|
|
639
|
+
|
|
640
|
+
|
|
311
641
|
/**
|
|
642
|
+
|
|
312
643
|
* Adds a LIMIT clause to the query
|
|
644
|
+
|
|
313
645
|
* @param n - Maximum number of rows to return
|
|
646
|
+
|
|
314
647
|
* @returns New query builder instance with the LIMIT clause
|
|
648
|
+
|
|
315
649
|
*/
|
|
650
|
+
|
|
316
651
|
limit(n: number): SelectQueryBuilder<T, TTable> {
|
|
652
|
+
|
|
317
653
|
const nextContext = this.applyAst(this.context, service => service.withLimit(n));
|
|
654
|
+
|
|
318
655
|
return this.clone(nextContext);
|
|
656
|
+
|
|
319
657
|
}
|
|
320
658
|
|
|
659
|
+
|
|
660
|
+
|
|
321
661
|
/**
|
|
662
|
+
|
|
322
663
|
* Adds an OFFSET clause to the query
|
|
664
|
+
|
|
323
665
|
* @param n - Number of rows to skip
|
|
666
|
+
|
|
324
667
|
* @returns New query builder instance with the OFFSET clause
|
|
668
|
+
|
|
669
|
+
*/
|
|
670
|
+
|
|
671
|
+
offset(n: number): SelectQueryBuilder<T, TTable> {
|
|
672
|
+
|
|
673
|
+
const nextContext = this.applyAst(this.context, service => service.withOffset(n));
|
|
674
|
+
|
|
675
|
+
return this.clone(nextContext);
|
|
676
|
+
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
|
|
680
|
+
|
|
681
|
+
/**
|
|
682
|
+
|
|
683
|
+
* Combines this query with another using UNION
|
|
684
|
+
|
|
685
|
+
* @param query - Query to union with
|
|
686
|
+
|
|
687
|
+
* @returns New query builder instance with the set operation
|
|
688
|
+
|
|
689
|
+
*/
|
|
690
|
+
|
|
691
|
+
union(query: SelectQueryBuilder<any, TableDef<any>> | SelectQueryNode): SelectQueryBuilder<T, TTable> {
|
|
692
|
+
|
|
693
|
+
return this.clone(this.applySetOperation('UNION', query));
|
|
694
|
+
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
|
|
698
|
+
|
|
699
|
+
/**
|
|
700
|
+
|
|
701
|
+
* Combines this query with another using UNION ALL
|
|
702
|
+
|
|
703
|
+
* @param query - Query to union with
|
|
704
|
+
|
|
705
|
+
* @returns New query builder instance with the set operation
|
|
706
|
+
|
|
707
|
+
*/
|
|
708
|
+
|
|
709
|
+
unionAll(query: SelectQueryBuilder<any, TableDef<any>> | SelectQueryNode): SelectQueryBuilder<T, TTable> {
|
|
710
|
+
|
|
711
|
+
return this.clone(this.applySetOperation('UNION ALL', query));
|
|
712
|
+
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
|
|
716
|
+
|
|
717
|
+
/**
|
|
718
|
+
|
|
719
|
+
* Combines this query with another using INTERSECT
|
|
720
|
+
|
|
721
|
+
* @param query - Query to intersect with
|
|
722
|
+
|
|
723
|
+
* @returns New query builder instance with the set operation
|
|
724
|
+
|
|
725
|
+
*/
|
|
726
|
+
|
|
727
|
+
intersect(query: SelectQueryBuilder<any, TableDef<any>> | SelectQueryNode): SelectQueryBuilder<T, TTable> {
|
|
728
|
+
|
|
729
|
+
return this.clone(this.applySetOperation('INTERSECT', query));
|
|
730
|
+
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
|
|
734
|
+
|
|
735
|
+
/**
|
|
736
|
+
|
|
737
|
+
* Combines this query with another using EXCEPT
|
|
738
|
+
|
|
739
|
+
* @param query - Query to subtract
|
|
740
|
+
|
|
741
|
+
* @returns New query builder instance with the set operation
|
|
742
|
+
|
|
325
743
|
*/
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
* @returns New query builder instance with the set operation
|
|
335
|
-
*/
|
|
336
|
-
union(query: SelectQueryBuilder<any, TableDef<any>> | SelectQueryNode): SelectQueryBuilder<T, TTable> {
|
|
337
|
-
return this.clone(this.applySetOperation('UNION', query));
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
/**
|
|
341
|
-
* Combines this query with another using UNION ALL
|
|
342
|
-
* @param query - Query to union with
|
|
343
|
-
* @returns New query builder instance with the set operation
|
|
344
|
-
*/
|
|
345
|
-
unionAll(query: SelectQueryBuilder<any, TableDef<any>> | SelectQueryNode): SelectQueryBuilder<T, TTable> {
|
|
346
|
-
return this.clone(this.applySetOperation('UNION ALL', query));
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
/**
|
|
350
|
-
* Combines this query with another using INTERSECT
|
|
351
|
-
* @param query - Query to intersect with
|
|
352
|
-
* @returns New query builder instance with the set operation
|
|
353
|
-
*/
|
|
354
|
-
intersect(query: SelectQueryBuilder<any, TableDef<any>> | SelectQueryNode): SelectQueryBuilder<T, TTable> {
|
|
355
|
-
return this.clone(this.applySetOperation('INTERSECT', query));
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
/**
|
|
359
|
-
* Combines this query with another using EXCEPT
|
|
360
|
-
* @param query - Query to subtract
|
|
361
|
-
* @returns New query builder instance with the set operation
|
|
362
|
-
*/
|
|
363
|
-
except(query: SelectQueryBuilder<any, TableDef<any>> | SelectQueryNode): SelectQueryBuilder<T, TTable> {
|
|
364
|
-
return this.clone(this.applySetOperation('EXCEPT', query));
|
|
365
|
-
}
|
|
744
|
+
|
|
745
|
+
except(query: SelectQueryBuilder<any, TableDef<any>> | SelectQueryNode): SelectQueryBuilder<T, TTable> {
|
|
746
|
+
|
|
747
|
+
return this.clone(this.applySetOperation('EXCEPT', query));
|
|
748
|
+
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
|
|
366
752
|
|
|
367
753
|
/**
|
|
754
|
+
|
|
368
755
|
* Adds a WHERE EXISTS condition to the query
|
|
756
|
+
|
|
369
757
|
* @param subquery - Subquery to check for existence
|
|
758
|
+
|
|
370
759
|
* @returns New query builder instance with the WHERE EXISTS condition
|
|
760
|
+
|
|
371
761
|
*/
|
|
762
|
+
|
|
372
763
|
whereExists(subquery: SelectQueryBuilder<any, TableDef<any>> | SelectQueryNode): SelectQueryBuilder<T, TTable> {
|
|
764
|
+
|
|
373
765
|
const subAst = this.resolveQueryNode(subquery);
|
|
766
|
+
|
|
374
767
|
return this.where(exists(subAst));
|
|
768
|
+
|
|
375
769
|
}
|
|
376
770
|
|
|
771
|
+
|
|
772
|
+
|
|
377
773
|
/**
|
|
774
|
+
|
|
378
775
|
* Adds a WHERE NOT EXISTS condition to the query
|
|
776
|
+
|
|
379
777
|
* @param subquery - Subquery to check for non-existence
|
|
778
|
+
|
|
380
779
|
* @returns New query builder instance with the WHERE NOT EXISTS condition
|
|
780
|
+
|
|
381
781
|
*/
|
|
782
|
+
|
|
382
783
|
whereNotExists(subquery: SelectQueryBuilder<any, TableDef<any>> | SelectQueryNode): SelectQueryBuilder<T, TTable> {
|
|
784
|
+
|
|
383
785
|
const subAst = this.resolveQueryNode(subquery);
|
|
786
|
+
|
|
384
787
|
return this.where(notExists(subAst));
|
|
788
|
+
|
|
385
789
|
}
|
|
386
790
|
|
|
791
|
+
|
|
792
|
+
|
|
387
793
|
/**
|
|
794
|
+
|
|
388
795
|
* Adds a WHERE EXISTS condition based on a relationship
|
|
796
|
+
|
|
389
797
|
* @param relationName - Name of the relationship to check
|
|
798
|
+
|
|
390
799
|
* @param callback - Optional callback to modify the relationship query
|
|
800
|
+
|
|
391
801
|
* @returns New query builder instance with the relationship existence check
|
|
802
|
+
|
|
392
803
|
*/
|
|
804
|
+
|
|
393
805
|
whereHas(
|
|
806
|
+
|
|
394
807
|
relationName: string,
|
|
808
|
+
|
|
395
809
|
callback?: <TChildTable extends TableDef>(
|
|
810
|
+
|
|
396
811
|
qb: SelectQueryBuilder<any, TChildTable>
|
|
812
|
+
|
|
397
813
|
) => SelectQueryBuilder<any, TChildTable>
|
|
814
|
+
|
|
398
815
|
): SelectQueryBuilder<T, TTable> {
|
|
816
|
+
|
|
399
817
|
const relation = this.env.table.relations[relationName];
|
|
818
|
+
|
|
400
819
|
if (!relation) {
|
|
820
|
+
|
|
401
821
|
throw new Error(`Relation '${relationName}' not found on table '${this.env.table.name}'`);
|
|
822
|
+
|
|
402
823
|
}
|
|
403
824
|
|
|
825
|
+
|
|
826
|
+
|
|
404
827
|
let subQb = this.createChildBuilder<any, typeof relation.target>(relation.target);
|
|
828
|
+
|
|
405
829
|
if (callback) {
|
|
830
|
+
|
|
406
831
|
subQb = callback(subQb);
|
|
832
|
+
|
|
407
833
|
}
|
|
408
834
|
|
|
835
|
+
|
|
836
|
+
|
|
409
837
|
const subAst = subQb.getAST();
|
|
838
|
+
|
|
410
839
|
const finalSubAst = this.relationManager.applyRelationCorrelation(this.context, relationName, subAst);
|
|
840
|
+
|
|
411
841
|
return this.where(exists(finalSubAst));
|
|
842
|
+
|
|
412
843
|
}
|
|
413
844
|
|
|
845
|
+
|
|
846
|
+
|
|
414
847
|
/**
|
|
848
|
+
|
|
415
849
|
* Adds a WHERE NOT EXISTS condition based on a relationship
|
|
850
|
+
|
|
416
851
|
* @param relationName - Name of the relationship to check
|
|
852
|
+
|
|
417
853
|
* @param callback - Optional callback to modify the relationship query
|
|
854
|
+
|
|
418
855
|
* @returns New query builder instance with the relationship non-existence check
|
|
856
|
+
|
|
419
857
|
*/
|
|
858
|
+
|
|
420
859
|
whereHasNot(
|
|
860
|
+
|
|
421
861
|
relationName: string,
|
|
862
|
+
|
|
422
863
|
callback?: <TChildTable extends TableDef>(
|
|
864
|
+
|
|
423
865
|
qb: SelectQueryBuilder<any, TChildTable>
|
|
866
|
+
|
|
424
867
|
) => SelectQueryBuilder<any, TChildTable>
|
|
868
|
+
|
|
425
869
|
): SelectQueryBuilder<T, TTable> {
|
|
870
|
+
|
|
426
871
|
const relation = this.env.table.relations[relationName];
|
|
872
|
+
|
|
427
873
|
if (!relation) {
|
|
874
|
+
|
|
428
875
|
throw new Error(`Relation '${relationName}' not found on table '${this.env.table.name}'`);
|
|
876
|
+
|
|
429
877
|
}
|
|
430
878
|
|
|
879
|
+
|
|
880
|
+
|
|
431
881
|
let subQb = this.createChildBuilder<any, typeof relation.target>(relation.target);
|
|
882
|
+
|
|
432
883
|
if (callback) {
|
|
884
|
+
|
|
433
885
|
subQb = callback(subQb);
|
|
886
|
+
|
|
434
887
|
}
|
|
435
888
|
|
|
889
|
+
|
|
890
|
+
|
|
436
891
|
const subAst = subQb.getAST();
|
|
892
|
+
|
|
437
893
|
const finalSubAst = this.relationManager.applyRelationCorrelation(this.context, relationName, subAst);
|
|
894
|
+
|
|
438
895
|
return this.where(notExists(finalSubAst));
|
|
896
|
+
|
|
439
897
|
}
|
|
440
898
|
|
|
899
|
+
|
|
900
|
+
|
|
441
901
|
/**
|
|
902
|
+
|
|
442
903
|
* Compiles the query to SQL for a specific dialect
|
|
904
|
+
|
|
443
905
|
* @param dialect - Database dialect to compile for
|
|
906
|
+
|
|
444
907
|
* @returns Compiled query with SQL and parameters
|
|
908
|
+
|
|
445
909
|
*/
|
|
446
|
-
|
|
447
|
-
|
|
910
|
+
|
|
911
|
+
compile(dialect: SelectDialectInput): CompiledQuery {
|
|
912
|
+
|
|
913
|
+
const resolved = resolveDialectInput(dialect);
|
|
914
|
+
|
|
915
|
+
return resolved.compileSelect(this.context.state.ast);
|
|
916
|
+
|
|
448
917
|
}
|
|
449
918
|
|
|
919
|
+
|
|
920
|
+
|
|
450
921
|
/**
|
|
922
|
+
|
|
451
923
|
* Converts the query to SQL string for a specific dialect
|
|
924
|
+
|
|
452
925
|
* @param dialect - Database dialect to generate SQL for
|
|
926
|
+
|
|
453
927
|
* @returns SQL string representation of the query
|
|
928
|
+
|
|
454
929
|
*/
|
|
455
|
-
|
|
930
|
+
|
|
931
|
+
toSql(dialect: SelectDialectInput): string {
|
|
932
|
+
|
|
456
933
|
return this.compile(dialect).sql;
|
|
934
|
+
|
|
457
935
|
}
|
|
458
936
|
|
|
937
|
+
|
|
938
|
+
|
|
459
939
|
/**
|
|
940
|
+
|
|
460
941
|
* Gets the hydration plan for the query
|
|
942
|
+
|
|
461
943
|
* @returns Hydration plan or undefined if none exists
|
|
944
|
+
|
|
462
945
|
*/
|
|
946
|
+
|
|
463
947
|
getHydrationPlan(): HydrationPlan | undefined {
|
|
948
|
+
|
|
464
949
|
return this.context.hydration.getPlan();
|
|
950
|
+
|
|
465
951
|
}
|
|
466
952
|
|
|
953
|
+
|
|
954
|
+
|
|
467
955
|
/**
|
|
956
|
+
|
|
468
957
|
* Gets the Abstract Syntax Tree (AST) representation of the query
|
|
958
|
+
|
|
469
959
|
* @returns Query AST with hydration applied
|
|
960
|
+
|
|
470
961
|
*/
|
|
962
|
+
|
|
471
963
|
getAST(): SelectQueryNode {
|
|
964
|
+
|
|
472
965
|
return this.context.hydration.applyToAst(this.context.state.ast);
|
|
966
|
+
|
|
473
967
|
}
|
|
968
|
+
|
|
474
969
|
}
|
|
475
970
|
|
|
971
|
+
|
|
972
|
+
|
|
476
973
|
/**
|
|
974
|
+
|
|
477
975
|
* Creates a column node for use in expressions
|
|
976
|
+
|
|
478
977
|
* @param table - Table name
|
|
978
|
+
|
|
479
979
|
* @param name - Column name
|
|
980
|
+
|
|
480
981
|
* @returns ColumnNode with the specified table and name
|
|
982
|
+
|
|
481
983
|
*/
|
|
984
|
+
|
|
482
985
|
export const createColumn = (table: string, name: string): ColumnNode => ({ type: 'Column', table, name });
|
|
483
986
|
|
|
987
|
+
|
|
988
|
+
|
|
484
989
|
/**
|
|
990
|
+
|
|
485
991
|
* Creates a literal value node for use in expressions
|
|
992
|
+
|
|
486
993
|
* @param val - Literal value (string or number)
|
|
994
|
+
|
|
487
995
|
* @returns LiteralNode with the specified value
|
|
996
|
+
|
|
488
997
|
*/
|
|
998
|
+
|
|
489
999
|
export const createLiteral = (val: string | number): LiteralNode => ({ type: 'Literal', value: val });
|
|
1000
|
+
|