metal-orm 1.0.15 → 1.0.17
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 +64 -61
- package/dist/decorators/index.cjs +490 -175
- package/dist/decorators/index.cjs.map +1 -1
- package/dist/decorators/index.d.cts +1 -5
- package/dist/decorators/index.d.ts +1 -5
- package/dist/decorators/index.js +490 -175
- package/dist/decorators/index.js.map +1 -1
- package/dist/index.cjs +1044 -483
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +67 -15
- package/dist/index.d.ts +67 -15
- package/dist/index.js +1033 -482
- package/dist/index.js.map +1 -1
- package/dist/{select-Bkv8g8u_.d.cts → select-BPCn6MOH.d.cts} +486 -32
- package/dist/{select-Bkv8g8u_.d.ts → select-BPCn6MOH.d.ts} +486 -32
- package/package.json +2 -1
- package/src/codegen/naming-strategy.ts +64 -0
- package/src/codegen/typescript.ts +48 -53
- package/src/core/ast/aggregate-functions.ts +50 -4
- package/src/core/ast/expression-builders.ts +22 -15
- package/src/core/ast/expression-nodes.ts +6 -0
- package/src/core/ddl/introspect/functions/postgres.ts +2 -6
- package/src/core/ddl/schema-generator.ts +3 -2
- package/src/core/ddl/schema-introspect.ts +1 -1
- package/src/core/dialect/abstract.ts +40 -8
- package/src/core/dialect/mssql/functions.ts +24 -15
- package/src/core/dialect/postgres/functions.ts +33 -24
- package/src/core/dialect/sqlite/functions.ts +19 -12
- package/src/core/functions/datetime.ts +2 -1
- package/src/core/functions/numeric.ts +2 -1
- package/src/core/functions/standard-strategy.ts +52 -12
- package/src/core/functions/text.ts +2 -1
- package/src/core/functions/types.ts +8 -8
- package/src/decorators/column.ts +13 -4
- package/src/index.ts +13 -5
- package/src/orm/domain-event-bus.ts +43 -25
- package/src/orm/entity-context.ts +30 -0
- package/src/orm/entity-meta.ts +42 -2
- package/src/orm/entity-metadata.ts +1 -6
- package/src/orm/entity.ts +88 -88
- package/src/orm/execute.ts +42 -25
- package/src/orm/execution-context.ts +18 -0
- package/src/orm/hydration-context.ts +16 -0
- package/src/orm/identity-map.ts +4 -0
- package/src/orm/interceptor-pipeline.ts +29 -0
- package/src/orm/lazy-batch.ts +6 -6
- package/src/orm/orm-session.ts +245 -0
- package/src/orm/orm.ts +58 -0
- package/src/orm/query-logger.ts +15 -0
- package/src/orm/relation-change-processor.ts +5 -1
- 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 -139
- package/src/orm/relations/many-to-many.ts +46 -45
- package/src/orm/runtime-types.ts +60 -2
- package/src/orm/transaction-runner.ts +7 -0
- package/src/orm/unit-of-work.ts +7 -1
- package/src/query-builder/insert-query-state.ts +13 -3
- package/src/query-builder/select-helpers.ts +50 -0
- package/src/query-builder/select.ts +616 -18
- package/src/query-builder/update-query-state.ts +31 -9
- package/src/schema/types.ts +16 -6
- package/src/orm/orm-context.ts +0 -159
package/dist/decorators/index.js
CHANGED
|
@@ -100,11 +100,20 @@ function Entity(options = {}) {
|
|
|
100
100
|
|
|
101
101
|
// src/decorators/column.ts
|
|
102
102
|
var normalizeColumnInput = (input) => {
|
|
103
|
+
const asOptions = input;
|
|
104
|
+
const asDefinition = input;
|
|
103
105
|
const column = {
|
|
104
|
-
type:
|
|
105
|
-
args:
|
|
106
|
-
notNull:
|
|
107
|
-
primary:
|
|
106
|
+
type: asOptions.type ?? asDefinition.type,
|
|
107
|
+
args: asOptions.args ?? asDefinition.args,
|
|
108
|
+
notNull: asOptions.notNull ?? asDefinition.notNull,
|
|
109
|
+
primary: asOptions.primary ?? asDefinition.primary,
|
|
110
|
+
unique: asDefinition.unique,
|
|
111
|
+
default: asDefinition.default,
|
|
112
|
+
autoIncrement: asDefinition.autoIncrement,
|
|
113
|
+
generated: asDefinition.generated,
|
|
114
|
+
check: asDefinition.check,
|
|
115
|
+
references: asDefinition.references,
|
|
116
|
+
comment: asDefinition.comment
|
|
108
117
|
};
|
|
109
118
|
if (!column.type) {
|
|
110
119
|
throw new Error("Column decorator requires a column type");
|
|
@@ -289,6 +298,15 @@ var isWindowFunctionNode = (node) => node?.type === "WindowFunction";
|
|
|
289
298
|
var isExpressionSelectionNode = (node) => isFunctionNode(node) || isCaseExpressionNode(node) || isWindowFunctionNode(node);
|
|
290
299
|
|
|
291
300
|
// src/core/ast/expression-builders.ts
|
|
301
|
+
var valueToOperand = (value) => {
|
|
302
|
+
if (isOperandNode(value)) {
|
|
303
|
+
return value;
|
|
304
|
+
}
|
|
305
|
+
return {
|
|
306
|
+
type: "Literal",
|
|
307
|
+
value
|
|
308
|
+
};
|
|
309
|
+
};
|
|
292
310
|
var toNode = (col) => {
|
|
293
311
|
if (isOperandNode(col)) return col;
|
|
294
312
|
const def = col;
|
|
@@ -298,10 +316,10 @@ var toLiteralNode = (value) => ({
|
|
|
298
316
|
type: "Literal",
|
|
299
317
|
value
|
|
300
318
|
});
|
|
319
|
+
var isLiteralValue = (value) => value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean";
|
|
301
320
|
var toOperand = (val) => {
|
|
302
|
-
if (val
|
|
303
|
-
|
|
304
|
-
return { type: "Literal", value: val };
|
|
321
|
+
if (isLiteralValue(val)) {
|
|
322
|
+
return valueToOperand(val);
|
|
305
323
|
}
|
|
306
324
|
return toNode(val);
|
|
307
325
|
};
|
|
@@ -342,6 +360,24 @@ var notExists = (subquery) => ({
|
|
|
342
360
|
subquery
|
|
343
361
|
});
|
|
344
362
|
|
|
363
|
+
// src/core/sql/sql.ts
|
|
364
|
+
var JOIN_KINDS = {
|
|
365
|
+
/** INNER JOIN type */
|
|
366
|
+
INNER: "INNER",
|
|
367
|
+
/** LEFT JOIN type */
|
|
368
|
+
LEFT: "LEFT",
|
|
369
|
+
/** RIGHT JOIN type */
|
|
370
|
+
RIGHT: "RIGHT",
|
|
371
|
+
/** CROSS JOIN type */
|
|
372
|
+
CROSS: "CROSS"
|
|
373
|
+
};
|
|
374
|
+
var ORDER_DIRECTIONS = {
|
|
375
|
+
/** Ascending order */
|
|
376
|
+
ASC: "ASC",
|
|
377
|
+
/** Descending order */
|
|
378
|
+
DESC: "DESC"
|
|
379
|
+
};
|
|
380
|
+
|
|
345
381
|
// src/core/ast/aggregate-functions.ts
|
|
346
382
|
var buildAggregate = (name) => (col) => ({
|
|
347
383
|
type: "Function",
|
|
@@ -351,14 +387,21 @@ var buildAggregate = (name) => (col) => ({
|
|
|
351
387
|
var count = buildAggregate("COUNT");
|
|
352
388
|
var sum = buildAggregate("SUM");
|
|
353
389
|
var avg = buildAggregate("AVG");
|
|
390
|
+
var min = buildAggregate("MIN");
|
|
391
|
+
var max = buildAggregate("MAX");
|
|
354
392
|
|
|
355
393
|
// src/core/functions/standard-strategy.ts
|
|
356
|
-
var StandardFunctionStrategy = class {
|
|
394
|
+
var StandardFunctionStrategy = class _StandardFunctionStrategy {
|
|
357
395
|
constructor() {
|
|
358
396
|
this.renderers = /* @__PURE__ */ new Map();
|
|
359
397
|
this.registerStandard();
|
|
360
398
|
}
|
|
361
399
|
registerStandard() {
|
|
400
|
+
this.add("COUNT", ({ compiledArgs }) => `COUNT(${compiledArgs.join(", ")})`);
|
|
401
|
+
this.add("SUM", ({ compiledArgs }) => `SUM(${compiledArgs[0]})`);
|
|
402
|
+
this.add("AVG", ({ compiledArgs }) => `AVG(${compiledArgs[0]})`);
|
|
403
|
+
this.add("MIN", ({ compiledArgs }) => `MIN(${compiledArgs[0]})`);
|
|
404
|
+
this.add("MAX", ({ compiledArgs }) => `MAX(${compiledArgs[0]})`);
|
|
362
405
|
this.add("ABS", ({ compiledArgs }) => `ABS(${compiledArgs[0]})`);
|
|
363
406
|
this.add("UPPER", ({ compiledArgs }) => `UPPER(${compiledArgs[0]})`);
|
|
364
407
|
this.add("LOWER", ({ compiledArgs }) => `LOWER(${compiledArgs[0]})`);
|
|
@@ -385,6 +428,7 @@ var StandardFunctionStrategy = class {
|
|
|
385
428
|
this.add("DAY_OF_WEEK", ({ compiledArgs }) => `DAYOFWEEK(${compiledArgs[0]})`);
|
|
386
429
|
this.add("WEEK_OF_YEAR", ({ compiledArgs }) => `WEEKOFYEAR(${compiledArgs[0]})`);
|
|
387
430
|
this.add("DATE_TRUNC", ({ compiledArgs }) => `DATE_TRUNC(${compiledArgs[0]}, ${compiledArgs[1]})`);
|
|
431
|
+
this.add("GROUP_CONCAT", (ctx) => this.renderGroupConcat(ctx));
|
|
388
432
|
}
|
|
389
433
|
add(name, renderer) {
|
|
390
434
|
this.renderers.set(name, renderer);
|
|
@@ -392,10 +436,40 @@ var StandardFunctionStrategy = class {
|
|
|
392
436
|
getRenderer(name) {
|
|
393
437
|
return this.renderers.get(name);
|
|
394
438
|
}
|
|
439
|
+
renderGroupConcat(ctx) {
|
|
440
|
+
const arg = ctx.compiledArgs[0];
|
|
441
|
+
const orderClause = this.buildOrderByExpression(ctx);
|
|
442
|
+
const orderSegment = orderClause ? ` ${orderClause}` : "";
|
|
443
|
+
const separatorClause = this.formatGroupConcatSeparator(ctx);
|
|
444
|
+
return `GROUP_CONCAT(${arg}${orderSegment}${separatorClause})`;
|
|
445
|
+
}
|
|
446
|
+
buildOrderByExpression(ctx) {
|
|
447
|
+
const orderBy = ctx.node.orderBy;
|
|
448
|
+
if (!orderBy || orderBy.length === 0) {
|
|
449
|
+
return "";
|
|
450
|
+
}
|
|
451
|
+
const parts = orderBy.map((order) => `${ctx.compileOperand(order.column)} ${order.direction}`);
|
|
452
|
+
return `ORDER BY ${parts.join(", ")}`;
|
|
453
|
+
}
|
|
454
|
+
formatGroupConcatSeparator(ctx) {
|
|
455
|
+
if (!ctx.node.separator) {
|
|
456
|
+
return "";
|
|
457
|
+
}
|
|
458
|
+
return ` SEPARATOR ${ctx.compileOperand(ctx.node.separator)}`;
|
|
459
|
+
}
|
|
460
|
+
getGroupConcatSeparatorOperand(ctx) {
|
|
461
|
+
return ctx.node.separator ?? _StandardFunctionStrategy.DEFAULT_GROUP_CONCAT_SEPARATOR;
|
|
462
|
+
}
|
|
463
|
+
static {
|
|
464
|
+
this.DEFAULT_GROUP_CONCAT_SEPARATOR = {
|
|
465
|
+
type: "Literal",
|
|
466
|
+
value: ","
|
|
467
|
+
};
|
|
468
|
+
}
|
|
395
469
|
};
|
|
396
470
|
|
|
397
471
|
// src/core/dialect/abstract.ts
|
|
398
|
-
var Dialect = class {
|
|
472
|
+
var Dialect = class _Dialect {
|
|
399
473
|
/**
|
|
400
474
|
* Compiles a SELECT query AST to SQL
|
|
401
475
|
* @param ast - Query AST to compile
|
|
@@ -568,6 +642,35 @@ var Dialect = class {
|
|
|
568
642
|
this.registerDefaultOperandCompilers();
|
|
569
643
|
this.registerDefaultExpressionCompilers();
|
|
570
644
|
}
|
|
645
|
+
/**
|
|
646
|
+
* Creates a new Dialect instance (for testing purposes)
|
|
647
|
+
* @param functionStrategy - Optional function strategy
|
|
648
|
+
* @returns New Dialect instance
|
|
649
|
+
*/
|
|
650
|
+
static create(functionStrategy) {
|
|
651
|
+
class TestDialect extends _Dialect {
|
|
652
|
+
constructor() {
|
|
653
|
+
super(...arguments);
|
|
654
|
+
this.dialect = "sqlite";
|
|
655
|
+
}
|
|
656
|
+
quoteIdentifier(id) {
|
|
657
|
+
return `"${id}"`;
|
|
658
|
+
}
|
|
659
|
+
compileSelectAst() {
|
|
660
|
+
throw new Error("Not implemented");
|
|
661
|
+
}
|
|
662
|
+
compileInsertAst() {
|
|
663
|
+
throw new Error("Not implemented");
|
|
664
|
+
}
|
|
665
|
+
compileUpdateAst() {
|
|
666
|
+
throw new Error("Not implemented");
|
|
667
|
+
}
|
|
668
|
+
compileDeleteAst() {
|
|
669
|
+
throw new Error("Not implemented");
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
return new TestDialect(functionStrategy);
|
|
673
|
+
}
|
|
571
674
|
/**
|
|
572
675
|
* Registers an expression compiler for a specific node type
|
|
573
676
|
* @param type - Expression node type
|
|
@@ -709,7 +812,11 @@ var Dialect = class {
|
|
|
709
812
|
const compiledArgs = fnNode.args.map((arg) => this.compileOperand(arg, ctx));
|
|
710
813
|
const renderer = this.functionStrategy.getRenderer(fnNode.name);
|
|
711
814
|
if (renderer) {
|
|
712
|
-
return renderer({
|
|
815
|
+
return renderer({
|
|
816
|
+
node: fnNode,
|
|
817
|
+
compiledArgs,
|
|
818
|
+
compileOperand: (operand) => this.compileOperand(operand, ctx)
|
|
819
|
+
});
|
|
713
820
|
}
|
|
714
821
|
return `${fnNode.name}(${compiledArgs.join(", ")})`;
|
|
715
822
|
}
|
|
@@ -1132,6 +1239,14 @@ var PostgresFunctionStrategy = class extends StandardFunctionStrategy {
|
|
|
1132
1239
|
const partClean = String(partArg.value).replace(/['"]/g, "").toLowerCase();
|
|
1133
1240
|
return `DATE_TRUNC('${partClean}', ${date})`;
|
|
1134
1241
|
});
|
|
1242
|
+
this.add("GROUP_CONCAT", (ctx) => {
|
|
1243
|
+
const arg = ctx.compiledArgs[0];
|
|
1244
|
+
const orderClause = this.buildOrderByExpression(ctx);
|
|
1245
|
+
const orderSegment = orderClause ? ` ${orderClause}` : "";
|
|
1246
|
+
const separatorOperand = this.getGroupConcatSeparatorOperand(ctx);
|
|
1247
|
+
const separator = ctx.compileOperand(separatorOperand);
|
|
1248
|
+
return `STRING_AGG(${arg}, ${separator}${orderSegment})`;
|
|
1249
|
+
});
|
|
1135
1250
|
}
|
|
1136
1251
|
};
|
|
1137
1252
|
|
|
@@ -1376,6 +1491,12 @@ var SqliteFunctionStrategy = class extends StandardFunctionStrategy {
|
|
|
1376
1491
|
}
|
|
1377
1492
|
return `date(${date}, 'start of ${partClean}')`;
|
|
1378
1493
|
});
|
|
1494
|
+
this.add("GROUP_CONCAT", (ctx) => {
|
|
1495
|
+
const arg = ctx.compiledArgs[0];
|
|
1496
|
+
const separatorOperand = this.getGroupConcatSeparatorOperand(ctx);
|
|
1497
|
+
const separator = ctx.compileOperand(separatorOperand);
|
|
1498
|
+
return `GROUP_CONCAT(${arg}, ${separator})`;
|
|
1499
|
+
});
|
|
1379
1500
|
}
|
|
1380
1501
|
};
|
|
1381
1502
|
|
|
@@ -1492,6 +1613,14 @@ var MssqlFunctionStrategy = class extends StandardFunctionStrategy {
|
|
|
1492
1613
|
const partClean = String(partArg.value).replace(/['"]/g, "").toLowerCase();
|
|
1493
1614
|
return `DATETRUNC(${partClean}, ${date})`;
|
|
1494
1615
|
});
|
|
1616
|
+
this.add("GROUP_CONCAT", (ctx) => {
|
|
1617
|
+
const arg = ctx.compiledArgs[0];
|
|
1618
|
+
const separatorOperand = this.getGroupConcatSeparatorOperand(ctx);
|
|
1619
|
+
const separator = ctx.compileOperand(separatorOperand);
|
|
1620
|
+
const orderClause = this.buildOrderByExpression(ctx);
|
|
1621
|
+
const withinGroup = orderClause ? ` WITHIN GROUP (${orderClause})` : "";
|
|
1622
|
+
return `STRING_AGG(${arg}, ${separator})${withinGroup}`;
|
|
1623
|
+
});
|
|
1495
1624
|
}
|
|
1496
1625
|
};
|
|
1497
1626
|
|
|
@@ -1861,24 +1990,6 @@ var createJoinNode = (kind, tableName, condition, relationName) => ({
|
|
|
1861
1990
|
meta: relationName ? { relationName } : void 0
|
|
1862
1991
|
});
|
|
1863
1992
|
|
|
1864
|
-
// src/core/sql/sql.ts
|
|
1865
|
-
var JOIN_KINDS = {
|
|
1866
|
-
/** INNER JOIN type */
|
|
1867
|
-
INNER: "INNER",
|
|
1868
|
-
/** LEFT JOIN type */
|
|
1869
|
-
LEFT: "LEFT",
|
|
1870
|
-
/** RIGHT JOIN type */
|
|
1871
|
-
RIGHT: "RIGHT",
|
|
1872
|
-
/** CROSS JOIN type */
|
|
1873
|
-
CROSS: "CROSS"
|
|
1874
|
-
};
|
|
1875
|
-
var ORDER_DIRECTIONS = {
|
|
1876
|
-
/** Ascending order */
|
|
1877
|
-
ASC: "ASC",
|
|
1878
|
-
/** Descending order */
|
|
1879
|
-
DESC: "DESC"
|
|
1880
|
-
};
|
|
1881
|
-
|
|
1882
1993
|
// src/query-builder/hydration-manager.ts
|
|
1883
1994
|
var HydrationManager = class _HydrationManager {
|
|
1884
1995
|
/**
|
|
@@ -3903,31 +4014,43 @@ var flattenResults = (results) => {
|
|
|
3903
4014
|
}
|
|
3904
4015
|
return rows;
|
|
3905
4016
|
};
|
|
3906
|
-
async
|
|
4017
|
+
var executeWithEntityContext = async (entityCtx, qb) => {
|
|
3907
4018
|
const ast = qb.getAST();
|
|
3908
|
-
const compiled =
|
|
3909
|
-
const executed = await
|
|
4019
|
+
const compiled = entityCtx.dialect.compileSelect(ast);
|
|
4020
|
+
const executed = await entityCtx.executor.executeSql(compiled.sql, compiled.params);
|
|
3910
4021
|
const rows = flattenResults(executed);
|
|
3911
4022
|
if (ast.setOps && ast.setOps.length > 0) {
|
|
3912
|
-
return rows.map(
|
|
3913
|
-
(row) => createEntityProxy(ctx, qb.getTable(), row, qb.getLazyRelations())
|
|
3914
|
-
);
|
|
4023
|
+
return rows.map((row) => createEntityProxy(entityCtx, qb.getTable(), row, qb.getLazyRelations()));
|
|
3915
4024
|
}
|
|
3916
4025
|
const hydrated = hydrateRows(rows, qb.getHydrationPlan());
|
|
3917
|
-
return hydrated.map(
|
|
3918
|
-
|
|
3919
|
-
|
|
4026
|
+
return hydrated.map((row) => createEntityFromRow(entityCtx, qb.getTable(), row, qb.getLazyRelations()));
|
|
4027
|
+
};
|
|
4028
|
+
async function executeHydrated(session, qb) {
|
|
4029
|
+
return executeWithEntityContext(session, qb);
|
|
4030
|
+
}
|
|
4031
|
+
async function executeHydratedWithContexts(_execCtx, hydCtx, qb) {
|
|
4032
|
+
const entityCtx = hydCtx.entityContext;
|
|
4033
|
+
if (!entityCtx) {
|
|
4034
|
+
throw new Error("Hydration context is missing an EntityContext");
|
|
4035
|
+
}
|
|
4036
|
+
return executeWithEntityContext(entityCtx, qb);
|
|
3920
4037
|
}
|
|
3921
4038
|
|
|
3922
4039
|
// src/query-builder/select.ts
|
|
3923
4040
|
var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
3924
4041
|
/**
|
|
3925
|
-
|
|
3926
|
-
|
|
3927
|
-
|
|
3928
|
-
|
|
3929
|
-
|
|
3930
|
-
|
|
4042
|
+
|
|
4043
|
+
* Creates a new SelectQueryBuilder instance
|
|
4044
|
+
|
|
4045
|
+
* @param table - Table definition to query
|
|
4046
|
+
|
|
4047
|
+
* @param state - Optional initial query state
|
|
4048
|
+
|
|
4049
|
+
* @param hydration - Optional hydration manager
|
|
4050
|
+
|
|
4051
|
+
* @param dependencies - Optional query builder dependencies
|
|
4052
|
+
|
|
4053
|
+
*/
|
|
3931
4054
|
constructor(table, state, hydration, dependencies, lazyRelations) {
|
|
3932
4055
|
const deps = resolveSelectQueryBuilderDependencies(dependencies);
|
|
3933
4056
|
this.env = { table, deps };
|
|
@@ -3964,112 +4087,183 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
3964
4087
|
return this.applyAst(this.context, (service) => service.withSetOperation(operator, subAst));
|
|
3965
4088
|
}
|
|
3966
4089
|
/**
|
|
3967
|
-
|
|
3968
|
-
|
|
3969
|
-
|
|
3970
|
-
|
|
4090
|
+
|
|
4091
|
+
* Selects specific columns for the query
|
|
4092
|
+
|
|
4093
|
+
* @param columns - Record of column definitions, function nodes, case expressions, or window functions
|
|
4094
|
+
|
|
4095
|
+
* @returns New query builder instance with selected columns
|
|
4096
|
+
|
|
4097
|
+
*/
|
|
3971
4098
|
select(columns) {
|
|
3972
4099
|
return this.clone(this.columnSelector.select(this.context, columns));
|
|
3973
4100
|
}
|
|
3974
4101
|
/**
|
|
3975
|
-
* Selects
|
|
3976
|
-
* @param cols - Column
|
|
3977
|
-
* @returns New query builder instance with raw column selections
|
|
4102
|
+
* Selects columns from the root table by name (typed).
|
|
4103
|
+
* @param cols - Column names on the root table
|
|
3978
4104
|
*/
|
|
4105
|
+
selectColumns(...cols) {
|
|
4106
|
+
const selection = {};
|
|
4107
|
+
for (const key of cols) {
|
|
4108
|
+
const col = this.env.table.columns[key];
|
|
4109
|
+
if (!col) {
|
|
4110
|
+
throw new Error(`Column '${key}' not found on table '${this.env.table.name}'`);
|
|
4111
|
+
}
|
|
4112
|
+
selection[key] = col;
|
|
4113
|
+
}
|
|
4114
|
+
return this.select(selection);
|
|
4115
|
+
}
|
|
4116
|
+
/**
|
|
4117
|
+
|
|
4118
|
+
* Selects raw column expressions
|
|
4119
|
+
|
|
4120
|
+
* @param cols - Column expressions as strings
|
|
4121
|
+
|
|
4122
|
+
* @returns New query builder instance with raw column selections
|
|
4123
|
+
|
|
4124
|
+
*/
|
|
3979
4125
|
selectRaw(...cols) {
|
|
3980
4126
|
return this.clone(this.columnSelector.selectRaw(this.context, cols));
|
|
3981
4127
|
}
|
|
3982
4128
|
/**
|
|
3983
|
-
|
|
3984
|
-
|
|
3985
|
-
|
|
3986
|
-
|
|
3987
|
-
|
|
3988
|
-
|
|
4129
|
+
|
|
4130
|
+
* Adds a Common Table Expression (CTE) to the query
|
|
4131
|
+
|
|
4132
|
+
* @param name - Name of the CTE
|
|
4133
|
+
|
|
4134
|
+
* @param query - Query builder or query node for the CTE
|
|
4135
|
+
|
|
4136
|
+
* @param columns - Optional column names for the CTE
|
|
4137
|
+
|
|
4138
|
+
* @returns New query builder instance with the CTE
|
|
4139
|
+
|
|
4140
|
+
*/
|
|
3989
4141
|
with(name, query, columns) {
|
|
3990
4142
|
const subAst = this.resolveQueryNode(query);
|
|
3991
4143
|
const nextContext = this.applyAst(this.context, (service) => service.withCte(name, subAst, columns, false));
|
|
3992
4144
|
return this.clone(nextContext);
|
|
3993
4145
|
}
|
|
3994
4146
|
/**
|
|
3995
|
-
|
|
3996
|
-
|
|
3997
|
-
|
|
3998
|
-
|
|
3999
|
-
|
|
4000
|
-
|
|
4147
|
+
|
|
4148
|
+
* Adds a recursive Common Table Expression (CTE) to the query
|
|
4149
|
+
|
|
4150
|
+
* @param name - Name of the CTE
|
|
4151
|
+
|
|
4152
|
+
* @param query - Query builder or query node for the CTE
|
|
4153
|
+
|
|
4154
|
+
* @param columns - Optional column names for the CTE
|
|
4155
|
+
|
|
4156
|
+
* @returns New query builder instance with the recursive CTE
|
|
4157
|
+
|
|
4158
|
+
*/
|
|
4001
4159
|
withRecursive(name, query, columns) {
|
|
4002
4160
|
const subAst = this.resolveQueryNode(query);
|
|
4003
4161
|
const nextContext = this.applyAst(this.context, (service) => service.withCte(name, subAst, columns, true));
|
|
4004
4162
|
return this.clone(nextContext);
|
|
4005
4163
|
}
|
|
4006
4164
|
/**
|
|
4007
|
-
|
|
4008
|
-
|
|
4009
|
-
|
|
4010
|
-
|
|
4011
|
-
|
|
4165
|
+
|
|
4166
|
+
* Selects a subquery as a column
|
|
4167
|
+
|
|
4168
|
+
* @param alias - Alias for the subquery column
|
|
4169
|
+
|
|
4170
|
+
* @param sub - Query builder or query node for the subquery
|
|
4171
|
+
|
|
4172
|
+
* @returns New query builder instance with the subquery selection
|
|
4173
|
+
|
|
4174
|
+
*/
|
|
4012
4175
|
selectSubquery(alias, sub) {
|
|
4013
4176
|
const query = this.resolveQueryNode(sub);
|
|
4014
4177
|
return this.clone(this.columnSelector.selectSubquery(this.context, alias, query));
|
|
4015
4178
|
}
|
|
4016
4179
|
/**
|
|
4017
|
-
|
|
4018
|
-
|
|
4019
|
-
|
|
4020
|
-
|
|
4021
|
-
|
|
4180
|
+
|
|
4181
|
+
* Adds an INNER JOIN to the query
|
|
4182
|
+
|
|
4183
|
+
* @param table - Table to join
|
|
4184
|
+
|
|
4185
|
+
* @param condition - Join condition expression
|
|
4186
|
+
|
|
4187
|
+
* @returns New query builder instance with the INNER JOIN
|
|
4188
|
+
|
|
4189
|
+
*/
|
|
4022
4190
|
innerJoin(table, condition) {
|
|
4023
4191
|
const nextContext = this.applyJoin(this.context, table, condition, JOIN_KINDS.INNER);
|
|
4024
4192
|
return this.clone(nextContext);
|
|
4025
4193
|
}
|
|
4026
4194
|
/**
|
|
4027
|
-
|
|
4028
|
-
|
|
4029
|
-
|
|
4030
|
-
|
|
4031
|
-
|
|
4195
|
+
|
|
4196
|
+
* Adds a LEFT JOIN to the query
|
|
4197
|
+
|
|
4198
|
+
* @param table - Table to join
|
|
4199
|
+
|
|
4200
|
+
* @param condition - Join condition expression
|
|
4201
|
+
|
|
4202
|
+
* @returns New query builder instance with the LEFT JOIN
|
|
4203
|
+
|
|
4204
|
+
*/
|
|
4032
4205
|
leftJoin(table, condition) {
|
|
4033
4206
|
const nextContext = this.applyJoin(this.context, table, condition, JOIN_KINDS.LEFT);
|
|
4034
4207
|
return this.clone(nextContext);
|
|
4035
4208
|
}
|
|
4036
4209
|
/**
|
|
4037
|
-
|
|
4038
|
-
|
|
4039
|
-
|
|
4040
|
-
|
|
4041
|
-
|
|
4210
|
+
|
|
4211
|
+
* Adds a RIGHT JOIN to the query
|
|
4212
|
+
|
|
4213
|
+
* @param table - Table to join
|
|
4214
|
+
|
|
4215
|
+
* @param condition - Join condition expression
|
|
4216
|
+
|
|
4217
|
+
* @returns New query builder instance with the RIGHT JOIN
|
|
4218
|
+
|
|
4219
|
+
*/
|
|
4042
4220
|
rightJoin(table, condition) {
|
|
4043
4221
|
const nextContext = this.applyJoin(this.context, table, condition, JOIN_KINDS.RIGHT);
|
|
4044
4222
|
return this.clone(nextContext);
|
|
4045
4223
|
}
|
|
4046
4224
|
/**
|
|
4047
|
-
|
|
4048
|
-
|
|
4049
|
-
|
|
4050
|
-
|
|
4051
|
-
|
|
4225
|
+
|
|
4226
|
+
* Matches records based on a relationship
|
|
4227
|
+
|
|
4228
|
+
* @param relationName - Name of the relationship to match
|
|
4229
|
+
|
|
4230
|
+
* @param predicate - Optional predicate expression
|
|
4231
|
+
|
|
4232
|
+
* @returns New query builder instance with the relationship match
|
|
4233
|
+
|
|
4234
|
+
*/
|
|
4052
4235
|
match(relationName, predicate) {
|
|
4053
4236
|
const nextContext = this.relationManager.match(this.context, relationName, predicate);
|
|
4054
4237
|
return this.clone(nextContext);
|
|
4055
4238
|
}
|
|
4056
4239
|
/**
|
|
4057
|
-
|
|
4058
|
-
|
|
4059
|
-
|
|
4060
|
-
|
|
4061
|
-
|
|
4062
|
-
|
|
4240
|
+
|
|
4241
|
+
* Joins a related table
|
|
4242
|
+
|
|
4243
|
+
* @param relationName - Name of the relationship to join
|
|
4244
|
+
|
|
4245
|
+
* @param joinKind - Type of join (defaults to INNER)
|
|
4246
|
+
|
|
4247
|
+
* @param extraCondition - Optional additional join condition
|
|
4248
|
+
|
|
4249
|
+
* @returns New query builder instance with the relationship join
|
|
4250
|
+
|
|
4251
|
+
*/
|
|
4063
4252
|
joinRelation(relationName, joinKind = JOIN_KINDS.INNER, extraCondition) {
|
|
4064
4253
|
const nextContext = this.relationManager.joinRelation(this.context, relationName, joinKind, extraCondition);
|
|
4065
4254
|
return this.clone(nextContext);
|
|
4066
4255
|
}
|
|
4067
4256
|
/**
|
|
4068
|
-
|
|
4069
|
-
|
|
4070
|
-
|
|
4071
|
-
|
|
4072
|
-
|
|
4257
|
+
|
|
4258
|
+
* Includes related data in the query results
|
|
4259
|
+
|
|
4260
|
+
* @param relationName - Name of the relationship to include
|
|
4261
|
+
|
|
4262
|
+
* @param options - Optional include options
|
|
4263
|
+
|
|
4264
|
+
* @returns New query builder instance with the relationship inclusion
|
|
4265
|
+
|
|
4266
|
+
*/
|
|
4073
4267
|
include(relationName, options) {
|
|
4074
4268
|
const nextContext = this.relationManager.include(this.context, relationName, options);
|
|
4075
4269
|
return this.clone(nextContext);
|
|
@@ -4079,6 +4273,47 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
4079
4273
|
nextLazy.add(relationName);
|
|
4080
4274
|
return this.clone(this.context, nextLazy);
|
|
4081
4275
|
}
|
|
4276
|
+
/**
|
|
4277
|
+
* Selects columns for a related table in a single hop.
|
|
4278
|
+
*/
|
|
4279
|
+
selectRelationColumns(relationName, ...cols) {
|
|
4280
|
+
const relation = this.env.table.relations[relationName];
|
|
4281
|
+
if (!relation) {
|
|
4282
|
+
throw new Error(`Relation '${relationName}' not found on table '${this.env.table.name}'`);
|
|
4283
|
+
}
|
|
4284
|
+
const target = relation.target;
|
|
4285
|
+
for (const col of cols) {
|
|
4286
|
+
if (!target.columns[col]) {
|
|
4287
|
+
throw new Error(
|
|
4288
|
+
`Column '${col}' not found on related table '${target.name}' for relation '${relationName}'`
|
|
4289
|
+
);
|
|
4290
|
+
}
|
|
4291
|
+
}
|
|
4292
|
+
return this.include(relationName, { columns: cols });
|
|
4293
|
+
}
|
|
4294
|
+
/**
|
|
4295
|
+
* Convenience alias for selecting specific columns from a relation.
|
|
4296
|
+
*/
|
|
4297
|
+
includePick(relationName, cols) {
|
|
4298
|
+
return this.selectRelationColumns(relationName, ...cols);
|
|
4299
|
+
}
|
|
4300
|
+
/**
|
|
4301
|
+
* Selects columns for the root table and relations from a single config object.
|
|
4302
|
+
*/
|
|
4303
|
+
selectColumnsDeep(config) {
|
|
4304
|
+
let qb = this;
|
|
4305
|
+
if (config.root?.length) {
|
|
4306
|
+
qb = qb.selectColumns(...config.root);
|
|
4307
|
+
}
|
|
4308
|
+
for (const key of Object.keys(config)) {
|
|
4309
|
+
if (key === "root") continue;
|
|
4310
|
+
const relName = key;
|
|
4311
|
+
const cols = config[relName];
|
|
4312
|
+
if (!cols || !cols.length) continue;
|
|
4313
|
+
qb = qb.selectRelationColumns(relName, ...cols);
|
|
4314
|
+
}
|
|
4315
|
+
return qb;
|
|
4316
|
+
}
|
|
4082
4317
|
getLazyRelations() {
|
|
4083
4318
|
return Array.from(this.lazyRelations);
|
|
4084
4319
|
}
|
|
@@ -4088,125 +4323,186 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
4088
4323
|
async execute(ctx) {
|
|
4089
4324
|
return executeHydrated(ctx, this);
|
|
4090
4325
|
}
|
|
4326
|
+
async executeWithContexts(execCtx, hydCtx) {
|
|
4327
|
+
return executeHydratedWithContexts(execCtx, hydCtx, this);
|
|
4328
|
+
}
|
|
4091
4329
|
/**
|
|
4092
|
-
|
|
4093
|
-
|
|
4094
|
-
|
|
4095
|
-
|
|
4330
|
+
|
|
4331
|
+
* Adds a WHERE condition to the query
|
|
4332
|
+
|
|
4333
|
+
* @param expr - Expression for the WHERE clause
|
|
4334
|
+
|
|
4335
|
+
* @returns New query builder instance with the WHERE condition
|
|
4336
|
+
|
|
4337
|
+
*/
|
|
4096
4338
|
where(expr) {
|
|
4097
4339
|
const nextContext = this.applyAst(this.context, (service) => service.withWhere(expr));
|
|
4098
4340
|
return this.clone(nextContext);
|
|
4099
4341
|
}
|
|
4100
4342
|
/**
|
|
4101
|
-
|
|
4102
|
-
|
|
4103
|
-
|
|
4104
|
-
|
|
4343
|
+
|
|
4344
|
+
* Adds a GROUP BY clause to the query
|
|
4345
|
+
|
|
4346
|
+
* @param col - Column definition or column node to group by
|
|
4347
|
+
|
|
4348
|
+
* @returns New query builder instance with the GROUP BY clause
|
|
4349
|
+
|
|
4350
|
+
*/
|
|
4105
4351
|
groupBy(col) {
|
|
4106
4352
|
const nextContext = this.applyAst(this.context, (service) => service.withGroupBy(col));
|
|
4107
4353
|
return this.clone(nextContext);
|
|
4108
4354
|
}
|
|
4109
4355
|
/**
|
|
4110
|
-
|
|
4111
|
-
|
|
4112
|
-
|
|
4113
|
-
|
|
4356
|
+
|
|
4357
|
+
* Adds a HAVING condition to the query
|
|
4358
|
+
|
|
4359
|
+
* @param expr - Expression for the HAVING clause
|
|
4360
|
+
|
|
4361
|
+
* @returns New query builder instance with the HAVING condition
|
|
4362
|
+
|
|
4363
|
+
*/
|
|
4114
4364
|
having(expr) {
|
|
4115
4365
|
const nextContext = this.applyAst(this.context, (service) => service.withHaving(expr));
|
|
4116
4366
|
return this.clone(nextContext);
|
|
4117
4367
|
}
|
|
4118
4368
|
/**
|
|
4119
|
-
|
|
4120
|
-
|
|
4121
|
-
|
|
4122
|
-
|
|
4123
|
-
|
|
4369
|
+
|
|
4370
|
+
* Adds an ORDER BY clause to the query
|
|
4371
|
+
|
|
4372
|
+
* @param col - Column definition or column node to order by
|
|
4373
|
+
|
|
4374
|
+
* @param direction - Order direction (defaults to ASC)
|
|
4375
|
+
|
|
4376
|
+
* @returns New query builder instance with the ORDER BY clause
|
|
4377
|
+
|
|
4378
|
+
*/
|
|
4124
4379
|
orderBy(col, direction = ORDER_DIRECTIONS.ASC) {
|
|
4125
4380
|
const nextContext = this.applyAst(this.context, (service) => service.withOrderBy(col, direction));
|
|
4126
4381
|
return this.clone(nextContext);
|
|
4127
4382
|
}
|
|
4128
4383
|
/**
|
|
4129
|
-
|
|
4130
|
-
|
|
4131
|
-
|
|
4132
|
-
|
|
4384
|
+
|
|
4385
|
+
* Adds a DISTINCT clause to the query
|
|
4386
|
+
|
|
4387
|
+
* @param cols - Columns to make distinct
|
|
4388
|
+
|
|
4389
|
+
* @returns New query builder instance with the DISTINCT clause
|
|
4390
|
+
|
|
4391
|
+
*/
|
|
4133
4392
|
distinct(...cols) {
|
|
4134
4393
|
return this.clone(this.columnSelector.distinct(this.context, cols));
|
|
4135
4394
|
}
|
|
4136
4395
|
/**
|
|
4137
|
-
|
|
4138
|
-
|
|
4139
|
-
|
|
4140
|
-
|
|
4396
|
+
|
|
4397
|
+
* Adds a LIMIT clause to the query
|
|
4398
|
+
|
|
4399
|
+
* @param n - Maximum number of rows to return
|
|
4400
|
+
|
|
4401
|
+
* @returns New query builder instance with the LIMIT clause
|
|
4402
|
+
|
|
4403
|
+
*/
|
|
4141
4404
|
limit(n) {
|
|
4142
4405
|
const nextContext = this.applyAst(this.context, (service) => service.withLimit(n));
|
|
4143
4406
|
return this.clone(nextContext);
|
|
4144
4407
|
}
|
|
4145
4408
|
/**
|
|
4146
|
-
|
|
4147
|
-
|
|
4148
|
-
|
|
4149
|
-
|
|
4409
|
+
|
|
4410
|
+
* Adds an OFFSET clause to the query
|
|
4411
|
+
|
|
4412
|
+
* @param n - Number of rows to skip
|
|
4413
|
+
|
|
4414
|
+
* @returns New query builder instance with the OFFSET clause
|
|
4415
|
+
|
|
4416
|
+
*/
|
|
4150
4417
|
offset(n) {
|
|
4151
4418
|
const nextContext = this.applyAst(this.context, (service) => service.withOffset(n));
|
|
4152
4419
|
return this.clone(nextContext);
|
|
4153
4420
|
}
|
|
4154
4421
|
/**
|
|
4155
|
-
|
|
4156
|
-
|
|
4157
|
-
|
|
4158
|
-
|
|
4422
|
+
|
|
4423
|
+
* Combines this query with another using UNION
|
|
4424
|
+
|
|
4425
|
+
* @param query - Query to union with
|
|
4426
|
+
|
|
4427
|
+
* @returns New query builder instance with the set operation
|
|
4428
|
+
|
|
4429
|
+
*/
|
|
4159
4430
|
union(query) {
|
|
4160
4431
|
return this.clone(this.applySetOperation("UNION", query));
|
|
4161
4432
|
}
|
|
4162
4433
|
/**
|
|
4163
|
-
|
|
4164
|
-
|
|
4165
|
-
|
|
4166
|
-
|
|
4434
|
+
|
|
4435
|
+
* Combines this query with another using UNION ALL
|
|
4436
|
+
|
|
4437
|
+
* @param query - Query to union with
|
|
4438
|
+
|
|
4439
|
+
* @returns New query builder instance with the set operation
|
|
4440
|
+
|
|
4441
|
+
*/
|
|
4167
4442
|
unionAll(query) {
|
|
4168
4443
|
return this.clone(this.applySetOperation("UNION ALL", query));
|
|
4169
4444
|
}
|
|
4170
4445
|
/**
|
|
4171
|
-
|
|
4172
|
-
|
|
4173
|
-
|
|
4174
|
-
|
|
4446
|
+
|
|
4447
|
+
* Combines this query with another using INTERSECT
|
|
4448
|
+
|
|
4449
|
+
* @param query - Query to intersect with
|
|
4450
|
+
|
|
4451
|
+
* @returns New query builder instance with the set operation
|
|
4452
|
+
|
|
4453
|
+
*/
|
|
4175
4454
|
intersect(query) {
|
|
4176
4455
|
return this.clone(this.applySetOperation("INTERSECT", query));
|
|
4177
4456
|
}
|
|
4178
4457
|
/**
|
|
4179
|
-
|
|
4180
|
-
|
|
4181
|
-
|
|
4182
|
-
|
|
4458
|
+
|
|
4459
|
+
* Combines this query with another using EXCEPT
|
|
4460
|
+
|
|
4461
|
+
* @param query - Query to subtract
|
|
4462
|
+
|
|
4463
|
+
* @returns New query builder instance with the set operation
|
|
4464
|
+
|
|
4465
|
+
*/
|
|
4183
4466
|
except(query) {
|
|
4184
4467
|
return this.clone(this.applySetOperation("EXCEPT", query));
|
|
4185
4468
|
}
|
|
4186
4469
|
/**
|
|
4187
|
-
|
|
4188
|
-
|
|
4189
|
-
|
|
4190
|
-
|
|
4470
|
+
|
|
4471
|
+
* Adds a WHERE EXISTS condition to the query
|
|
4472
|
+
|
|
4473
|
+
* @param subquery - Subquery to check for existence
|
|
4474
|
+
|
|
4475
|
+
* @returns New query builder instance with the WHERE EXISTS condition
|
|
4476
|
+
|
|
4477
|
+
*/
|
|
4191
4478
|
whereExists(subquery) {
|
|
4192
4479
|
const subAst = this.resolveQueryNode(subquery);
|
|
4193
4480
|
return this.where(exists(subAst));
|
|
4194
4481
|
}
|
|
4195
4482
|
/**
|
|
4196
|
-
|
|
4197
|
-
|
|
4198
|
-
|
|
4199
|
-
|
|
4483
|
+
|
|
4484
|
+
* Adds a WHERE NOT EXISTS condition to the query
|
|
4485
|
+
|
|
4486
|
+
* @param subquery - Subquery to check for non-existence
|
|
4487
|
+
|
|
4488
|
+
* @returns New query builder instance with the WHERE NOT EXISTS condition
|
|
4489
|
+
|
|
4490
|
+
*/
|
|
4200
4491
|
whereNotExists(subquery) {
|
|
4201
4492
|
const subAst = this.resolveQueryNode(subquery);
|
|
4202
4493
|
return this.where(notExists(subAst));
|
|
4203
4494
|
}
|
|
4204
4495
|
/**
|
|
4205
|
-
|
|
4206
|
-
|
|
4207
|
-
|
|
4208
|
-
|
|
4209
|
-
|
|
4496
|
+
|
|
4497
|
+
* Adds a WHERE EXISTS condition based on a relationship
|
|
4498
|
+
|
|
4499
|
+
* @param relationName - Name of the relationship to check
|
|
4500
|
+
|
|
4501
|
+
* @param callback - Optional callback to modify the relationship query
|
|
4502
|
+
|
|
4503
|
+
* @returns New query builder instance with the relationship existence check
|
|
4504
|
+
|
|
4505
|
+
*/
|
|
4210
4506
|
whereHas(relationName, callback) {
|
|
4211
4507
|
const relation = this.env.table.relations[relationName];
|
|
4212
4508
|
if (!relation) {
|
|
@@ -4221,11 +4517,16 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
4221
4517
|
return this.where(exists(finalSubAst));
|
|
4222
4518
|
}
|
|
4223
4519
|
/**
|
|
4224
|
-
|
|
4225
|
-
|
|
4226
|
-
|
|
4227
|
-
|
|
4228
|
-
|
|
4520
|
+
|
|
4521
|
+
* Adds a WHERE NOT EXISTS condition based on a relationship
|
|
4522
|
+
|
|
4523
|
+
* @param relationName - Name of the relationship to check
|
|
4524
|
+
|
|
4525
|
+
* @param callback - Optional callback to modify the relationship query
|
|
4526
|
+
|
|
4527
|
+
* @returns New query builder instance with the relationship non-existence check
|
|
4528
|
+
|
|
4529
|
+
*/
|
|
4229
4530
|
whereHasNot(relationName, callback) {
|
|
4230
4531
|
const relation = this.env.table.relations[relationName];
|
|
4231
4532
|
if (!relation) {
|
|
@@ -4240,33 +4541,47 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
4240
4541
|
return this.where(notExists(finalSubAst));
|
|
4241
4542
|
}
|
|
4242
4543
|
/**
|
|
4243
|
-
|
|
4244
|
-
|
|
4245
|
-
|
|
4246
|
-
|
|
4544
|
+
|
|
4545
|
+
* Compiles the query to SQL for a specific dialect
|
|
4546
|
+
|
|
4547
|
+
* @param dialect - Database dialect to compile for
|
|
4548
|
+
|
|
4549
|
+
* @returns Compiled query with SQL and parameters
|
|
4550
|
+
|
|
4551
|
+
*/
|
|
4247
4552
|
compile(dialect) {
|
|
4248
4553
|
const resolved = resolveDialectInput(dialect);
|
|
4249
4554
|
return resolved.compileSelect(this.context.state.ast);
|
|
4250
4555
|
}
|
|
4251
4556
|
/**
|
|
4252
|
-
|
|
4253
|
-
|
|
4254
|
-
|
|
4255
|
-
|
|
4557
|
+
|
|
4558
|
+
* Converts the query to SQL string for a specific dialect
|
|
4559
|
+
|
|
4560
|
+
* @param dialect - Database dialect to generate SQL for
|
|
4561
|
+
|
|
4562
|
+
* @returns SQL string representation of the query
|
|
4563
|
+
|
|
4564
|
+
*/
|
|
4256
4565
|
toSql(dialect) {
|
|
4257
4566
|
return this.compile(dialect).sql;
|
|
4258
4567
|
}
|
|
4259
4568
|
/**
|
|
4260
|
-
|
|
4261
|
-
|
|
4262
|
-
|
|
4569
|
+
|
|
4570
|
+
* Gets the hydration plan for the query
|
|
4571
|
+
|
|
4572
|
+
* @returns Hydration plan or undefined if none exists
|
|
4573
|
+
|
|
4574
|
+
*/
|
|
4263
4575
|
getHydrationPlan() {
|
|
4264
4576
|
return this.context.hydration.getPlan();
|
|
4265
4577
|
}
|
|
4266
4578
|
/**
|
|
4267
|
-
|
|
4268
|
-
|
|
4269
|
-
|
|
4579
|
+
|
|
4580
|
+
* Gets the Abstract Syntax Tree (AST) representation of the query
|
|
4581
|
+
|
|
4582
|
+
* @returns Query AST with hydration applied
|
|
4583
|
+
|
|
4584
|
+
*/
|
|
4270
4585
|
getAST() {
|
|
4271
4586
|
return this.context.hydration.applyToAst(this.context.state.ast);
|
|
4272
4587
|
}
|