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
|
@@ -134,11 +134,20 @@ function Entity(options = {}) {
|
|
|
134
134
|
|
|
135
135
|
// src/decorators/column.ts
|
|
136
136
|
var normalizeColumnInput = (input) => {
|
|
137
|
+
const asOptions = input;
|
|
138
|
+
const asDefinition = input;
|
|
137
139
|
const column = {
|
|
138
|
-
type:
|
|
139
|
-
args:
|
|
140
|
-
notNull:
|
|
141
|
-
primary:
|
|
140
|
+
type: asOptions.type ?? asDefinition.type,
|
|
141
|
+
args: asOptions.args ?? asDefinition.args,
|
|
142
|
+
notNull: asOptions.notNull ?? asDefinition.notNull,
|
|
143
|
+
primary: asOptions.primary ?? asDefinition.primary,
|
|
144
|
+
unique: asDefinition.unique,
|
|
145
|
+
default: asDefinition.default,
|
|
146
|
+
autoIncrement: asDefinition.autoIncrement,
|
|
147
|
+
generated: asDefinition.generated,
|
|
148
|
+
check: asDefinition.check,
|
|
149
|
+
references: asDefinition.references,
|
|
150
|
+
comment: asDefinition.comment
|
|
142
151
|
};
|
|
143
152
|
if (!column.type) {
|
|
144
153
|
throw new Error("Column decorator requires a column type");
|
|
@@ -323,6 +332,15 @@ var isWindowFunctionNode = (node) => node?.type === "WindowFunction";
|
|
|
323
332
|
var isExpressionSelectionNode = (node) => isFunctionNode(node) || isCaseExpressionNode(node) || isWindowFunctionNode(node);
|
|
324
333
|
|
|
325
334
|
// src/core/ast/expression-builders.ts
|
|
335
|
+
var valueToOperand = (value) => {
|
|
336
|
+
if (isOperandNode(value)) {
|
|
337
|
+
return value;
|
|
338
|
+
}
|
|
339
|
+
return {
|
|
340
|
+
type: "Literal",
|
|
341
|
+
value
|
|
342
|
+
};
|
|
343
|
+
};
|
|
326
344
|
var toNode = (col) => {
|
|
327
345
|
if (isOperandNode(col)) return col;
|
|
328
346
|
const def = col;
|
|
@@ -332,10 +350,10 @@ var toLiteralNode = (value) => ({
|
|
|
332
350
|
type: "Literal",
|
|
333
351
|
value
|
|
334
352
|
});
|
|
353
|
+
var isLiteralValue = (value) => value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean";
|
|
335
354
|
var toOperand = (val) => {
|
|
336
|
-
if (val
|
|
337
|
-
|
|
338
|
-
return { type: "Literal", value: val };
|
|
355
|
+
if (isLiteralValue(val)) {
|
|
356
|
+
return valueToOperand(val);
|
|
339
357
|
}
|
|
340
358
|
return toNode(val);
|
|
341
359
|
};
|
|
@@ -376,6 +394,24 @@ var notExists = (subquery) => ({
|
|
|
376
394
|
subquery
|
|
377
395
|
});
|
|
378
396
|
|
|
397
|
+
// src/core/sql/sql.ts
|
|
398
|
+
var JOIN_KINDS = {
|
|
399
|
+
/** INNER JOIN type */
|
|
400
|
+
INNER: "INNER",
|
|
401
|
+
/** LEFT JOIN type */
|
|
402
|
+
LEFT: "LEFT",
|
|
403
|
+
/** RIGHT JOIN type */
|
|
404
|
+
RIGHT: "RIGHT",
|
|
405
|
+
/** CROSS JOIN type */
|
|
406
|
+
CROSS: "CROSS"
|
|
407
|
+
};
|
|
408
|
+
var ORDER_DIRECTIONS = {
|
|
409
|
+
/** Ascending order */
|
|
410
|
+
ASC: "ASC",
|
|
411
|
+
/** Descending order */
|
|
412
|
+
DESC: "DESC"
|
|
413
|
+
};
|
|
414
|
+
|
|
379
415
|
// src/core/ast/aggregate-functions.ts
|
|
380
416
|
var buildAggregate = (name) => (col) => ({
|
|
381
417
|
type: "Function",
|
|
@@ -385,14 +421,21 @@ var buildAggregate = (name) => (col) => ({
|
|
|
385
421
|
var count = buildAggregate("COUNT");
|
|
386
422
|
var sum = buildAggregate("SUM");
|
|
387
423
|
var avg = buildAggregate("AVG");
|
|
424
|
+
var min = buildAggregate("MIN");
|
|
425
|
+
var max = buildAggregate("MAX");
|
|
388
426
|
|
|
389
427
|
// src/core/functions/standard-strategy.ts
|
|
390
|
-
var StandardFunctionStrategy = class {
|
|
428
|
+
var StandardFunctionStrategy = class _StandardFunctionStrategy {
|
|
391
429
|
constructor() {
|
|
392
430
|
this.renderers = /* @__PURE__ */ new Map();
|
|
393
431
|
this.registerStandard();
|
|
394
432
|
}
|
|
395
433
|
registerStandard() {
|
|
434
|
+
this.add("COUNT", ({ compiledArgs }) => `COUNT(${compiledArgs.join(", ")})`);
|
|
435
|
+
this.add("SUM", ({ compiledArgs }) => `SUM(${compiledArgs[0]})`);
|
|
436
|
+
this.add("AVG", ({ compiledArgs }) => `AVG(${compiledArgs[0]})`);
|
|
437
|
+
this.add("MIN", ({ compiledArgs }) => `MIN(${compiledArgs[0]})`);
|
|
438
|
+
this.add("MAX", ({ compiledArgs }) => `MAX(${compiledArgs[0]})`);
|
|
396
439
|
this.add("ABS", ({ compiledArgs }) => `ABS(${compiledArgs[0]})`);
|
|
397
440
|
this.add("UPPER", ({ compiledArgs }) => `UPPER(${compiledArgs[0]})`);
|
|
398
441
|
this.add("LOWER", ({ compiledArgs }) => `LOWER(${compiledArgs[0]})`);
|
|
@@ -419,6 +462,7 @@ var StandardFunctionStrategy = class {
|
|
|
419
462
|
this.add("DAY_OF_WEEK", ({ compiledArgs }) => `DAYOFWEEK(${compiledArgs[0]})`);
|
|
420
463
|
this.add("WEEK_OF_YEAR", ({ compiledArgs }) => `WEEKOFYEAR(${compiledArgs[0]})`);
|
|
421
464
|
this.add("DATE_TRUNC", ({ compiledArgs }) => `DATE_TRUNC(${compiledArgs[0]}, ${compiledArgs[1]})`);
|
|
465
|
+
this.add("GROUP_CONCAT", (ctx) => this.renderGroupConcat(ctx));
|
|
422
466
|
}
|
|
423
467
|
add(name, renderer) {
|
|
424
468
|
this.renderers.set(name, renderer);
|
|
@@ -426,10 +470,40 @@ var StandardFunctionStrategy = class {
|
|
|
426
470
|
getRenderer(name) {
|
|
427
471
|
return this.renderers.get(name);
|
|
428
472
|
}
|
|
473
|
+
renderGroupConcat(ctx) {
|
|
474
|
+
const arg = ctx.compiledArgs[0];
|
|
475
|
+
const orderClause = this.buildOrderByExpression(ctx);
|
|
476
|
+
const orderSegment = orderClause ? ` ${orderClause}` : "";
|
|
477
|
+
const separatorClause = this.formatGroupConcatSeparator(ctx);
|
|
478
|
+
return `GROUP_CONCAT(${arg}${orderSegment}${separatorClause})`;
|
|
479
|
+
}
|
|
480
|
+
buildOrderByExpression(ctx) {
|
|
481
|
+
const orderBy = ctx.node.orderBy;
|
|
482
|
+
if (!orderBy || orderBy.length === 0) {
|
|
483
|
+
return "";
|
|
484
|
+
}
|
|
485
|
+
const parts = orderBy.map((order) => `${ctx.compileOperand(order.column)} ${order.direction}`);
|
|
486
|
+
return `ORDER BY ${parts.join(", ")}`;
|
|
487
|
+
}
|
|
488
|
+
formatGroupConcatSeparator(ctx) {
|
|
489
|
+
if (!ctx.node.separator) {
|
|
490
|
+
return "";
|
|
491
|
+
}
|
|
492
|
+
return ` SEPARATOR ${ctx.compileOperand(ctx.node.separator)}`;
|
|
493
|
+
}
|
|
494
|
+
getGroupConcatSeparatorOperand(ctx) {
|
|
495
|
+
return ctx.node.separator ?? _StandardFunctionStrategy.DEFAULT_GROUP_CONCAT_SEPARATOR;
|
|
496
|
+
}
|
|
497
|
+
static {
|
|
498
|
+
this.DEFAULT_GROUP_CONCAT_SEPARATOR = {
|
|
499
|
+
type: "Literal",
|
|
500
|
+
value: ","
|
|
501
|
+
};
|
|
502
|
+
}
|
|
429
503
|
};
|
|
430
504
|
|
|
431
505
|
// src/core/dialect/abstract.ts
|
|
432
|
-
var Dialect = class {
|
|
506
|
+
var Dialect = class _Dialect {
|
|
433
507
|
/**
|
|
434
508
|
* Compiles a SELECT query AST to SQL
|
|
435
509
|
* @param ast - Query AST to compile
|
|
@@ -602,6 +676,35 @@ var Dialect = class {
|
|
|
602
676
|
this.registerDefaultOperandCompilers();
|
|
603
677
|
this.registerDefaultExpressionCompilers();
|
|
604
678
|
}
|
|
679
|
+
/**
|
|
680
|
+
* Creates a new Dialect instance (for testing purposes)
|
|
681
|
+
* @param functionStrategy - Optional function strategy
|
|
682
|
+
* @returns New Dialect instance
|
|
683
|
+
*/
|
|
684
|
+
static create(functionStrategy) {
|
|
685
|
+
class TestDialect extends _Dialect {
|
|
686
|
+
constructor() {
|
|
687
|
+
super(...arguments);
|
|
688
|
+
this.dialect = "sqlite";
|
|
689
|
+
}
|
|
690
|
+
quoteIdentifier(id) {
|
|
691
|
+
return `"${id}"`;
|
|
692
|
+
}
|
|
693
|
+
compileSelectAst() {
|
|
694
|
+
throw new Error("Not implemented");
|
|
695
|
+
}
|
|
696
|
+
compileInsertAst() {
|
|
697
|
+
throw new Error("Not implemented");
|
|
698
|
+
}
|
|
699
|
+
compileUpdateAst() {
|
|
700
|
+
throw new Error("Not implemented");
|
|
701
|
+
}
|
|
702
|
+
compileDeleteAst() {
|
|
703
|
+
throw new Error("Not implemented");
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
return new TestDialect(functionStrategy);
|
|
707
|
+
}
|
|
605
708
|
/**
|
|
606
709
|
* Registers an expression compiler for a specific node type
|
|
607
710
|
* @param type - Expression node type
|
|
@@ -743,7 +846,11 @@ var Dialect = class {
|
|
|
743
846
|
const compiledArgs = fnNode.args.map((arg) => this.compileOperand(arg, ctx));
|
|
744
847
|
const renderer = this.functionStrategy.getRenderer(fnNode.name);
|
|
745
848
|
if (renderer) {
|
|
746
|
-
return renderer({
|
|
849
|
+
return renderer({
|
|
850
|
+
node: fnNode,
|
|
851
|
+
compiledArgs,
|
|
852
|
+
compileOperand: (operand) => this.compileOperand(operand, ctx)
|
|
853
|
+
});
|
|
747
854
|
}
|
|
748
855
|
return `${fnNode.name}(${compiledArgs.join(", ")})`;
|
|
749
856
|
}
|
|
@@ -1166,6 +1273,14 @@ var PostgresFunctionStrategy = class extends StandardFunctionStrategy {
|
|
|
1166
1273
|
const partClean = String(partArg.value).replace(/['"]/g, "").toLowerCase();
|
|
1167
1274
|
return `DATE_TRUNC('${partClean}', ${date})`;
|
|
1168
1275
|
});
|
|
1276
|
+
this.add("GROUP_CONCAT", (ctx) => {
|
|
1277
|
+
const arg = ctx.compiledArgs[0];
|
|
1278
|
+
const orderClause = this.buildOrderByExpression(ctx);
|
|
1279
|
+
const orderSegment = orderClause ? ` ${orderClause}` : "";
|
|
1280
|
+
const separatorOperand = this.getGroupConcatSeparatorOperand(ctx);
|
|
1281
|
+
const separator = ctx.compileOperand(separatorOperand);
|
|
1282
|
+
return `STRING_AGG(${arg}, ${separator}${orderSegment})`;
|
|
1283
|
+
});
|
|
1169
1284
|
}
|
|
1170
1285
|
};
|
|
1171
1286
|
|
|
@@ -1410,6 +1525,12 @@ var SqliteFunctionStrategy = class extends StandardFunctionStrategy {
|
|
|
1410
1525
|
}
|
|
1411
1526
|
return `date(${date}, 'start of ${partClean}')`;
|
|
1412
1527
|
});
|
|
1528
|
+
this.add("GROUP_CONCAT", (ctx) => {
|
|
1529
|
+
const arg = ctx.compiledArgs[0];
|
|
1530
|
+
const separatorOperand = this.getGroupConcatSeparatorOperand(ctx);
|
|
1531
|
+
const separator = ctx.compileOperand(separatorOperand);
|
|
1532
|
+
return `GROUP_CONCAT(${arg}, ${separator})`;
|
|
1533
|
+
});
|
|
1413
1534
|
}
|
|
1414
1535
|
};
|
|
1415
1536
|
|
|
@@ -1526,6 +1647,14 @@ var MssqlFunctionStrategy = class extends StandardFunctionStrategy {
|
|
|
1526
1647
|
const partClean = String(partArg.value).replace(/['"]/g, "").toLowerCase();
|
|
1527
1648
|
return `DATETRUNC(${partClean}, ${date})`;
|
|
1528
1649
|
});
|
|
1650
|
+
this.add("GROUP_CONCAT", (ctx) => {
|
|
1651
|
+
const arg = ctx.compiledArgs[0];
|
|
1652
|
+
const separatorOperand = this.getGroupConcatSeparatorOperand(ctx);
|
|
1653
|
+
const separator = ctx.compileOperand(separatorOperand);
|
|
1654
|
+
const orderClause = this.buildOrderByExpression(ctx);
|
|
1655
|
+
const withinGroup = orderClause ? ` WITHIN GROUP (${orderClause})` : "";
|
|
1656
|
+
return `STRING_AGG(${arg}, ${separator})${withinGroup}`;
|
|
1657
|
+
});
|
|
1529
1658
|
}
|
|
1530
1659
|
};
|
|
1531
1660
|
|
|
@@ -1895,24 +2024,6 @@ var createJoinNode = (kind, tableName, condition, relationName) => ({
|
|
|
1895
2024
|
meta: relationName ? { relationName } : void 0
|
|
1896
2025
|
});
|
|
1897
2026
|
|
|
1898
|
-
// src/core/sql/sql.ts
|
|
1899
|
-
var JOIN_KINDS = {
|
|
1900
|
-
/** INNER JOIN type */
|
|
1901
|
-
INNER: "INNER",
|
|
1902
|
-
/** LEFT JOIN type */
|
|
1903
|
-
LEFT: "LEFT",
|
|
1904
|
-
/** RIGHT JOIN type */
|
|
1905
|
-
RIGHT: "RIGHT",
|
|
1906
|
-
/** CROSS JOIN type */
|
|
1907
|
-
CROSS: "CROSS"
|
|
1908
|
-
};
|
|
1909
|
-
var ORDER_DIRECTIONS = {
|
|
1910
|
-
/** Ascending order */
|
|
1911
|
-
ASC: "ASC",
|
|
1912
|
-
/** Descending order */
|
|
1913
|
-
DESC: "DESC"
|
|
1914
|
-
};
|
|
1915
|
-
|
|
1916
2027
|
// src/query-builder/hydration-manager.ts
|
|
1917
2028
|
var HydrationManager = class _HydrationManager {
|
|
1918
2029
|
/**
|
|
@@ -3937,31 +4048,43 @@ var flattenResults = (results) => {
|
|
|
3937
4048
|
}
|
|
3938
4049
|
return rows;
|
|
3939
4050
|
};
|
|
3940
|
-
async
|
|
4051
|
+
var executeWithEntityContext = async (entityCtx, qb) => {
|
|
3941
4052
|
const ast = qb.getAST();
|
|
3942
|
-
const compiled =
|
|
3943
|
-
const executed = await
|
|
4053
|
+
const compiled = entityCtx.dialect.compileSelect(ast);
|
|
4054
|
+
const executed = await entityCtx.executor.executeSql(compiled.sql, compiled.params);
|
|
3944
4055
|
const rows = flattenResults(executed);
|
|
3945
4056
|
if (ast.setOps && ast.setOps.length > 0) {
|
|
3946
|
-
return rows.map(
|
|
3947
|
-
(row) => createEntityProxy(ctx, qb.getTable(), row, qb.getLazyRelations())
|
|
3948
|
-
);
|
|
4057
|
+
return rows.map((row) => createEntityProxy(entityCtx, qb.getTable(), row, qb.getLazyRelations()));
|
|
3949
4058
|
}
|
|
3950
4059
|
const hydrated = hydrateRows(rows, qb.getHydrationPlan());
|
|
3951
|
-
return hydrated.map(
|
|
3952
|
-
|
|
3953
|
-
|
|
4060
|
+
return hydrated.map((row) => createEntityFromRow(entityCtx, qb.getTable(), row, qb.getLazyRelations()));
|
|
4061
|
+
};
|
|
4062
|
+
async function executeHydrated(session, qb) {
|
|
4063
|
+
return executeWithEntityContext(session, qb);
|
|
4064
|
+
}
|
|
4065
|
+
async function executeHydratedWithContexts(_execCtx, hydCtx, qb) {
|
|
4066
|
+
const entityCtx = hydCtx.entityContext;
|
|
4067
|
+
if (!entityCtx) {
|
|
4068
|
+
throw new Error("Hydration context is missing an EntityContext");
|
|
4069
|
+
}
|
|
4070
|
+
return executeWithEntityContext(entityCtx, qb);
|
|
3954
4071
|
}
|
|
3955
4072
|
|
|
3956
4073
|
// src/query-builder/select.ts
|
|
3957
4074
|
var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
3958
4075
|
/**
|
|
3959
|
-
|
|
3960
|
-
|
|
3961
|
-
|
|
3962
|
-
|
|
3963
|
-
|
|
3964
|
-
|
|
4076
|
+
|
|
4077
|
+
* Creates a new SelectQueryBuilder instance
|
|
4078
|
+
|
|
4079
|
+
* @param table - Table definition to query
|
|
4080
|
+
|
|
4081
|
+
* @param state - Optional initial query state
|
|
4082
|
+
|
|
4083
|
+
* @param hydration - Optional hydration manager
|
|
4084
|
+
|
|
4085
|
+
* @param dependencies - Optional query builder dependencies
|
|
4086
|
+
|
|
4087
|
+
*/
|
|
3965
4088
|
constructor(table, state, hydration, dependencies, lazyRelations) {
|
|
3966
4089
|
const deps = resolveSelectQueryBuilderDependencies(dependencies);
|
|
3967
4090
|
this.env = { table, deps };
|
|
@@ -3998,112 +4121,183 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
3998
4121
|
return this.applyAst(this.context, (service) => service.withSetOperation(operator, subAst));
|
|
3999
4122
|
}
|
|
4000
4123
|
/**
|
|
4001
|
-
|
|
4002
|
-
|
|
4003
|
-
|
|
4004
|
-
|
|
4124
|
+
|
|
4125
|
+
* Selects specific columns for the query
|
|
4126
|
+
|
|
4127
|
+
* @param columns - Record of column definitions, function nodes, case expressions, or window functions
|
|
4128
|
+
|
|
4129
|
+
* @returns New query builder instance with selected columns
|
|
4130
|
+
|
|
4131
|
+
*/
|
|
4005
4132
|
select(columns) {
|
|
4006
4133
|
return this.clone(this.columnSelector.select(this.context, columns));
|
|
4007
4134
|
}
|
|
4008
4135
|
/**
|
|
4009
|
-
* Selects
|
|
4010
|
-
* @param cols - Column
|
|
4011
|
-
* @returns New query builder instance with raw column selections
|
|
4136
|
+
* Selects columns from the root table by name (typed).
|
|
4137
|
+
* @param cols - Column names on the root table
|
|
4012
4138
|
*/
|
|
4139
|
+
selectColumns(...cols) {
|
|
4140
|
+
const selection = {};
|
|
4141
|
+
for (const key of cols) {
|
|
4142
|
+
const col = this.env.table.columns[key];
|
|
4143
|
+
if (!col) {
|
|
4144
|
+
throw new Error(`Column '${key}' not found on table '${this.env.table.name}'`);
|
|
4145
|
+
}
|
|
4146
|
+
selection[key] = col;
|
|
4147
|
+
}
|
|
4148
|
+
return this.select(selection);
|
|
4149
|
+
}
|
|
4150
|
+
/**
|
|
4151
|
+
|
|
4152
|
+
* Selects raw column expressions
|
|
4153
|
+
|
|
4154
|
+
* @param cols - Column expressions as strings
|
|
4155
|
+
|
|
4156
|
+
* @returns New query builder instance with raw column selections
|
|
4157
|
+
|
|
4158
|
+
*/
|
|
4013
4159
|
selectRaw(...cols) {
|
|
4014
4160
|
return this.clone(this.columnSelector.selectRaw(this.context, cols));
|
|
4015
4161
|
}
|
|
4016
4162
|
/**
|
|
4017
|
-
|
|
4018
|
-
|
|
4019
|
-
|
|
4020
|
-
|
|
4021
|
-
|
|
4022
|
-
|
|
4163
|
+
|
|
4164
|
+
* Adds a Common Table Expression (CTE) to the query
|
|
4165
|
+
|
|
4166
|
+
* @param name - Name of the CTE
|
|
4167
|
+
|
|
4168
|
+
* @param query - Query builder or query node for the CTE
|
|
4169
|
+
|
|
4170
|
+
* @param columns - Optional column names for the CTE
|
|
4171
|
+
|
|
4172
|
+
* @returns New query builder instance with the CTE
|
|
4173
|
+
|
|
4174
|
+
*/
|
|
4023
4175
|
with(name, query, columns) {
|
|
4024
4176
|
const subAst = this.resolveQueryNode(query);
|
|
4025
4177
|
const nextContext = this.applyAst(this.context, (service) => service.withCte(name, subAst, columns, false));
|
|
4026
4178
|
return this.clone(nextContext);
|
|
4027
4179
|
}
|
|
4028
4180
|
/**
|
|
4029
|
-
|
|
4030
|
-
|
|
4031
|
-
|
|
4032
|
-
|
|
4033
|
-
|
|
4034
|
-
|
|
4181
|
+
|
|
4182
|
+
* Adds a recursive Common Table Expression (CTE) to the query
|
|
4183
|
+
|
|
4184
|
+
* @param name - Name of the CTE
|
|
4185
|
+
|
|
4186
|
+
* @param query - Query builder or query node for the CTE
|
|
4187
|
+
|
|
4188
|
+
* @param columns - Optional column names for the CTE
|
|
4189
|
+
|
|
4190
|
+
* @returns New query builder instance with the recursive CTE
|
|
4191
|
+
|
|
4192
|
+
*/
|
|
4035
4193
|
withRecursive(name, query, columns) {
|
|
4036
4194
|
const subAst = this.resolveQueryNode(query);
|
|
4037
4195
|
const nextContext = this.applyAst(this.context, (service) => service.withCte(name, subAst, columns, true));
|
|
4038
4196
|
return this.clone(nextContext);
|
|
4039
4197
|
}
|
|
4040
4198
|
/**
|
|
4041
|
-
|
|
4042
|
-
|
|
4043
|
-
|
|
4044
|
-
|
|
4045
|
-
|
|
4199
|
+
|
|
4200
|
+
* Selects a subquery as a column
|
|
4201
|
+
|
|
4202
|
+
* @param alias - Alias for the subquery column
|
|
4203
|
+
|
|
4204
|
+
* @param sub - Query builder or query node for the subquery
|
|
4205
|
+
|
|
4206
|
+
* @returns New query builder instance with the subquery selection
|
|
4207
|
+
|
|
4208
|
+
*/
|
|
4046
4209
|
selectSubquery(alias, sub) {
|
|
4047
4210
|
const query = this.resolveQueryNode(sub);
|
|
4048
4211
|
return this.clone(this.columnSelector.selectSubquery(this.context, alias, query));
|
|
4049
4212
|
}
|
|
4050
4213
|
/**
|
|
4051
|
-
|
|
4052
|
-
|
|
4053
|
-
|
|
4054
|
-
|
|
4055
|
-
|
|
4214
|
+
|
|
4215
|
+
* Adds an INNER JOIN to the query
|
|
4216
|
+
|
|
4217
|
+
* @param table - Table to join
|
|
4218
|
+
|
|
4219
|
+
* @param condition - Join condition expression
|
|
4220
|
+
|
|
4221
|
+
* @returns New query builder instance with the INNER JOIN
|
|
4222
|
+
|
|
4223
|
+
*/
|
|
4056
4224
|
innerJoin(table, condition) {
|
|
4057
4225
|
const nextContext = this.applyJoin(this.context, table, condition, JOIN_KINDS.INNER);
|
|
4058
4226
|
return this.clone(nextContext);
|
|
4059
4227
|
}
|
|
4060
4228
|
/**
|
|
4061
|
-
|
|
4062
|
-
|
|
4063
|
-
|
|
4064
|
-
|
|
4065
|
-
|
|
4229
|
+
|
|
4230
|
+
* Adds a LEFT JOIN to the query
|
|
4231
|
+
|
|
4232
|
+
* @param table - Table to join
|
|
4233
|
+
|
|
4234
|
+
* @param condition - Join condition expression
|
|
4235
|
+
|
|
4236
|
+
* @returns New query builder instance with the LEFT JOIN
|
|
4237
|
+
|
|
4238
|
+
*/
|
|
4066
4239
|
leftJoin(table, condition) {
|
|
4067
4240
|
const nextContext = this.applyJoin(this.context, table, condition, JOIN_KINDS.LEFT);
|
|
4068
4241
|
return this.clone(nextContext);
|
|
4069
4242
|
}
|
|
4070
4243
|
/**
|
|
4071
|
-
|
|
4072
|
-
|
|
4073
|
-
|
|
4074
|
-
|
|
4075
|
-
|
|
4244
|
+
|
|
4245
|
+
* Adds a RIGHT JOIN to the query
|
|
4246
|
+
|
|
4247
|
+
* @param table - Table to join
|
|
4248
|
+
|
|
4249
|
+
* @param condition - Join condition expression
|
|
4250
|
+
|
|
4251
|
+
* @returns New query builder instance with the RIGHT JOIN
|
|
4252
|
+
|
|
4253
|
+
*/
|
|
4076
4254
|
rightJoin(table, condition) {
|
|
4077
4255
|
const nextContext = this.applyJoin(this.context, table, condition, JOIN_KINDS.RIGHT);
|
|
4078
4256
|
return this.clone(nextContext);
|
|
4079
4257
|
}
|
|
4080
4258
|
/**
|
|
4081
|
-
|
|
4082
|
-
|
|
4083
|
-
|
|
4084
|
-
|
|
4085
|
-
|
|
4259
|
+
|
|
4260
|
+
* Matches records based on a relationship
|
|
4261
|
+
|
|
4262
|
+
* @param relationName - Name of the relationship to match
|
|
4263
|
+
|
|
4264
|
+
* @param predicate - Optional predicate expression
|
|
4265
|
+
|
|
4266
|
+
* @returns New query builder instance with the relationship match
|
|
4267
|
+
|
|
4268
|
+
*/
|
|
4086
4269
|
match(relationName, predicate) {
|
|
4087
4270
|
const nextContext = this.relationManager.match(this.context, relationName, predicate);
|
|
4088
4271
|
return this.clone(nextContext);
|
|
4089
4272
|
}
|
|
4090
4273
|
/**
|
|
4091
|
-
|
|
4092
|
-
|
|
4093
|
-
|
|
4094
|
-
|
|
4095
|
-
|
|
4096
|
-
|
|
4274
|
+
|
|
4275
|
+
* Joins a related table
|
|
4276
|
+
|
|
4277
|
+
* @param relationName - Name of the relationship to join
|
|
4278
|
+
|
|
4279
|
+
* @param joinKind - Type of join (defaults to INNER)
|
|
4280
|
+
|
|
4281
|
+
* @param extraCondition - Optional additional join condition
|
|
4282
|
+
|
|
4283
|
+
* @returns New query builder instance with the relationship join
|
|
4284
|
+
|
|
4285
|
+
*/
|
|
4097
4286
|
joinRelation(relationName, joinKind = JOIN_KINDS.INNER, extraCondition) {
|
|
4098
4287
|
const nextContext = this.relationManager.joinRelation(this.context, relationName, joinKind, extraCondition);
|
|
4099
4288
|
return this.clone(nextContext);
|
|
4100
4289
|
}
|
|
4101
4290
|
/**
|
|
4102
|
-
|
|
4103
|
-
|
|
4104
|
-
|
|
4105
|
-
|
|
4106
|
-
|
|
4291
|
+
|
|
4292
|
+
* Includes related data in the query results
|
|
4293
|
+
|
|
4294
|
+
* @param relationName - Name of the relationship to include
|
|
4295
|
+
|
|
4296
|
+
* @param options - Optional include options
|
|
4297
|
+
|
|
4298
|
+
* @returns New query builder instance with the relationship inclusion
|
|
4299
|
+
|
|
4300
|
+
*/
|
|
4107
4301
|
include(relationName, options) {
|
|
4108
4302
|
const nextContext = this.relationManager.include(this.context, relationName, options);
|
|
4109
4303
|
return this.clone(nextContext);
|
|
@@ -4113,6 +4307,47 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
4113
4307
|
nextLazy.add(relationName);
|
|
4114
4308
|
return this.clone(this.context, nextLazy);
|
|
4115
4309
|
}
|
|
4310
|
+
/**
|
|
4311
|
+
* Selects columns for a related table in a single hop.
|
|
4312
|
+
*/
|
|
4313
|
+
selectRelationColumns(relationName, ...cols) {
|
|
4314
|
+
const relation = this.env.table.relations[relationName];
|
|
4315
|
+
if (!relation) {
|
|
4316
|
+
throw new Error(`Relation '${relationName}' not found on table '${this.env.table.name}'`);
|
|
4317
|
+
}
|
|
4318
|
+
const target = relation.target;
|
|
4319
|
+
for (const col of cols) {
|
|
4320
|
+
if (!target.columns[col]) {
|
|
4321
|
+
throw new Error(
|
|
4322
|
+
`Column '${col}' not found on related table '${target.name}' for relation '${relationName}'`
|
|
4323
|
+
);
|
|
4324
|
+
}
|
|
4325
|
+
}
|
|
4326
|
+
return this.include(relationName, { columns: cols });
|
|
4327
|
+
}
|
|
4328
|
+
/**
|
|
4329
|
+
* Convenience alias for selecting specific columns from a relation.
|
|
4330
|
+
*/
|
|
4331
|
+
includePick(relationName, cols) {
|
|
4332
|
+
return this.selectRelationColumns(relationName, ...cols);
|
|
4333
|
+
}
|
|
4334
|
+
/**
|
|
4335
|
+
* Selects columns for the root table and relations from a single config object.
|
|
4336
|
+
*/
|
|
4337
|
+
selectColumnsDeep(config) {
|
|
4338
|
+
let qb = this;
|
|
4339
|
+
if (config.root?.length) {
|
|
4340
|
+
qb = qb.selectColumns(...config.root);
|
|
4341
|
+
}
|
|
4342
|
+
for (const key of Object.keys(config)) {
|
|
4343
|
+
if (key === "root") continue;
|
|
4344
|
+
const relName = key;
|
|
4345
|
+
const cols = config[relName];
|
|
4346
|
+
if (!cols || !cols.length) continue;
|
|
4347
|
+
qb = qb.selectRelationColumns(relName, ...cols);
|
|
4348
|
+
}
|
|
4349
|
+
return qb;
|
|
4350
|
+
}
|
|
4116
4351
|
getLazyRelations() {
|
|
4117
4352
|
return Array.from(this.lazyRelations);
|
|
4118
4353
|
}
|
|
@@ -4122,125 +4357,186 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
4122
4357
|
async execute(ctx) {
|
|
4123
4358
|
return executeHydrated(ctx, this);
|
|
4124
4359
|
}
|
|
4360
|
+
async executeWithContexts(execCtx, hydCtx) {
|
|
4361
|
+
return executeHydratedWithContexts(execCtx, hydCtx, this);
|
|
4362
|
+
}
|
|
4125
4363
|
/**
|
|
4126
|
-
|
|
4127
|
-
|
|
4128
|
-
|
|
4129
|
-
|
|
4364
|
+
|
|
4365
|
+
* Adds a WHERE condition to the query
|
|
4366
|
+
|
|
4367
|
+
* @param expr - Expression for the WHERE clause
|
|
4368
|
+
|
|
4369
|
+
* @returns New query builder instance with the WHERE condition
|
|
4370
|
+
|
|
4371
|
+
*/
|
|
4130
4372
|
where(expr) {
|
|
4131
4373
|
const nextContext = this.applyAst(this.context, (service) => service.withWhere(expr));
|
|
4132
4374
|
return this.clone(nextContext);
|
|
4133
4375
|
}
|
|
4134
4376
|
/**
|
|
4135
|
-
|
|
4136
|
-
|
|
4137
|
-
|
|
4138
|
-
|
|
4377
|
+
|
|
4378
|
+
* Adds a GROUP BY clause to the query
|
|
4379
|
+
|
|
4380
|
+
* @param col - Column definition or column node to group by
|
|
4381
|
+
|
|
4382
|
+
* @returns New query builder instance with the GROUP BY clause
|
|
4383
|
+
|
|
4384
|
+
*/
|
|
4139
4385
|
groupBy(col) {
|
|
4140
4386
|
const nextContext = this.applyAst(this.context, (service) => service.withGroupBy(col));
|
|
4141
4387
|
return this.clone(nextContext);
|
|
4142
4388
|
}
|
|
4143
4389
|
/**
|
|
4144
|
-
|
|
4145
|
-
|
|
4146
|
-
|
|
4147
|
-
|
|
4390
|
+
|
|
4391
|
+
* Adds a HAVING condition to the query
|
|
4392
|
+
|
|
4393
|
+
* @param expr - Expression for the HAVING clause
|
|
4394
|
+
|
|
4395
|
+
* @returns New query builder instance with the HAVING condition
|
|
4396
|
+
|
|
4397
|
+
*/
|
|
4148
4398
|
having(expr) {
|
|
4149
4399
|
const nextContext = this.applyAst(this.context, (service) => service.withHaving(expr));
|
|
4150
4400
|
return this.clone(nextContext);
|
|
4151
4401
|
}
|
|
4152
4402
|
/**
|
|
4153
|
-
|
|
4154
|
-
|
|
4155
|
-
|
|
4156
|
-
|
|
4157
|
-
|
|
4403
|
+
|
|
4404
|
+
* Adds an ORDER BY clause to the query
|
|
4405
|
+
|
|
4406
|
+
* @param col - Column definition or column node to order by
|
|
4407
|
+
|
|
4408
|
+
* @param direction - Order direction (defaults to ASC)
|
|
4409
|
+
|
|
4410
|
+
* @returns New query builder instance with the ORDER BY clause
|
|
4411
|
+
|
|
4412
|
+
*/
|
|
4158
4413
|
orderBy(col, direction = ORDER_DIRECTIONS.ASC) {
|
|
4159
4414
|
const nextContext = this.applyAst(this.context, (service) => service.withOrderBy(col, direction));
|
|
4160
4415
|
return this.clone(nextContext);
|
|
4161
4416
|
}
|
|
4162
4417
|
/**
|
|
4163
|
-
|
|
4164
|
-
|
|
4165
|
-
|
|
4166
|
-
|
|
4418
|
+
|
|
4419
|
+
* Adds a DISTINCT clause to the query
|
|
4420
|
+
|
|
4421
|
+
* @param cols - Columns to make distinct
|
|
4422
|
+
|
|
4423
|
+
* @returns New query builder instance with the DISTINCT clause
|
|
4424
|
+
|
|
4425
|
+
*/
|
|
4167
4426
|
distinct(...cols) {
|
|
4168
4427
|
return this.clone(this.columnSelector.distinct(this.context, cols));
|
|
4169
4428
|
}
|
|
4170
4429
|
/**
|
|
4171
|
-
|
|
4172
|
-
|
|
4173
|
-
|
|
4174
|
-
|
|
4430
|
+
|
|
4431
|
+
* Adds a LIMIT clause to the query
|
|
4432
|
+
|
|
4433
|
+
* @param n - Maximum number of rows to return
|
|
4434
|
+
|
|
4435
|
+
* @returns New query builder instance with the LIMIT clause
|
|
4436
|
+
|
|
4437
|
+
*/
|
|
4175
4438
|
limit(n) {
|
|
4176
4439
|
const nextContext = this.applyAst(this.context, (service) => service.withLimit(n));
|
|
4177
4440
|
return this.clone(nextContext);
|
|
4178
4441
|
}
|
|
4179
4442
|
/**
|
|
4180
|
-
|
|
4181
|
-
|
|
4182
|
-
|
|
4183
|
-
|
|
4443
|
+
|
|
4444
|
+
* Adds an OFFSET clause to the query
|
|
4445
|
+
|
|
4446
|
+
* @param n - Number of rows to skip
|
|
4447
|
+
|
|
4448
|
+
* @returns New query builder instance with the OFFSET clause
|
|
4449
|
+
|
|
4450
|
+
*/
|
|
4184
4451
|
offset(n) {
|
|
4185
4452
|
const nextContext = this.applyAst(this.context, (service) => service.withOffset(n));
|
|
4186
4453
|
return this.clone(nextContext);
|
|
4187
4454
|
}
|
|
4188
4455
|
/**
|
|
4189
|
-
|
|
4190
|
-
|
|
4191
|
-
|
|
4192
|
-
|
|
4456
|
+
|
|
4457
|
+
* Combines this query with another using UNION
|
|
4458
|
+
|
|
4459
|
+
* @param query - Query to union with
|
|
4460
|
+
|
|
4461
|
+
* @returns New query builder instance with the set operation
|
|
4462
|
+
|
|
4463
|
+
*/
|
|
4193
4464
|
union(query) {
|
|
4194
4465
|
return this.clone(this.applySetOperation("UNION", query));
|
|
4195
4466
|
}
|
|
4196
4467
|
/**
|
|
4197
|
-
|
|
4198
|
-
|
|
4199
|
-
|
|
4200
|
-
|
|
4468
|
+
|
|
4469
|
+
* Combines this query with another using UNION ALL
|
|
4470
|
+
|
|
4471
|
+
* @param query - Query to union with
|
|
4472
|
+
|
|
4473
|
+
* @returns New query builder instance with the set operation
|
|
4474
|
+
|
|
4475
|
+
*/
|
|
4201
4476
|
unionAll(query) {
|
|
4202
4477
|
return this.clone(this.applySetOperation("UNION ALL", query));
|
|
4203
4478
|
}
|
|
4204
4479
|
/**
|
|
4205
|
-
|
|
4206
|
-
|
|
4207
|
-
|
|
4208
|
-
|
|
4480
|
+
|
|
4481
|
+
* Combines this query with another using INTERSECT
|
|
4482
|
+
|
|
4483
|
+
* @param query - Query to intersect with
|
|
4484
|
+
|
|
4485
|
+
* @returns New query builder instance with the set operation
|
|
4486
|
+
|
|
4487
|
+
*/
|
|
4209
4488
|
intersect(query) {
|
|
4210
4489
|
return this.clone(this.applySetOperation("INTERSECT", query));
|
|
4211
4490
|
}
|
|
4212
4491
|
/**
|
|
4213
|
-
|
|
4214
|
-
|
|
4215
|
-
|
|
4216
|
-
|
|
4492
|
+
|
|
4493
|
+
* Combines this query with another using EXCEPT
|
|
4494
|
+
|
|
4495
|
+
* @param query - Query to subtract
|
|
4496
|
+
|
|
4497
|
+
* @returns New query builder instance with the set operation
|
|
4498
|
+
|
|
4499
|
+
*/
|
|
4217
4500
|
except(query) {
|
|
4218
4501
|
return this.clone(this.applySetOperation("EXCEPT", query));
|
|
4219
4502
|
}
|
|
4220
4503
|
/**
|
|
4221
|
-
|
|
4222
|
-
|
|
4223
|
-
|
|
4224
|
-
|
|
4504
|
+
|
|
4505
|
+
* Adds a WHERE EXISTS condition to the query
|
|
4506
|
+
|
|
4507
|
+
* @param subquery - Subquery to check for existence
|
|
4508
|
+
|
|
4509
|
+
* @returns New query builder instance with the WHERE EXISTS condition
|
|
4510
|
+
|
|
4511
|
+
*/
|
|
4225
4512
|
whereExists(subquery) {
|
|
4226
4513
|
const subAst = this.resolveQueryNode(subquery);
|
|
4227
4514
|
return this.where(exists(subAst));
|
|
4228
4515
|
}
|
|
4229
4516
|
/**
|
|
4230
|
-
|
|
4231
|
-
|
|
4232
|
-
|
|
4233
|
-
|
|
4517
|
+
|
|
4518
|
+
* Adds a WHERE NOT EXISTS condition to the query
|
|
4519
|
+
|
|
4520
|
+
* @param subquery - Subquery to check for non-existence
|
|
4521
|
+
|
|
4522
|
+
* @returns New query builder instance with the WHERE NOT EXISTS condition
|
|
4523
|
+
|
|
4524
|
+
*/
|
|
4234
4525
|
whereNotExists(subquery) {
|
|
4235
4526
|
const subAst = this.resolveQueryNode(subquery);
|
|
4236
4527
|
return this.where(notExists(subAst));
|
|
4237
4528
|
}
|
|
4238
4529
|
/**
|
|
4239
|
-
|
|
4240
|
-
|
|
4241
|
-
|
|
4242
|
-
|
|
4243
|
-
|
|
4530
|
+
|
|
4531
|
+
* Adds a WHERE EXISTS condition based on a relationship
|
|
4532
|
+
|
|
4533
|
+
* @param relationName - Name of the relationship to check
|
|
4534
|
+
|
|
4535
|
+
* @param callback - Optional callback to modify the relationship query
|
|
4536
|
+
|
|
4537
|
+
* @returns New query builder instance with the relationship existence check
|
|
4538
|
+
|
|
4539
|
+
*/
|
|
4244
4540
|
whereHas(relationName, callback) {
|
|
4245
4541
|
const relation = this.env.table.relations[relationName];
|
|
4246
4542
|
if (!relation) {
|
|
@@ -4255,11 +4551,16 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
4255
4551
|
return this.where(exists(finalSubAst));
|
|
4256
4552
|
}
|
|
4257
4553
|
/**
|
|
4258
|
-
|
|
4259
|
-
|
|
4260
|
-
|
|
4261
|
-
|
|
4262
|
-
|
|
4554
|
+
|
|
4555
|
+
* Adds a WHERE NOT EXISTS condition based on a relationship
|
|
4556
|
+
|
|
4557
|
+
* @param relationName - Name of the relationship to check
|
|
4558
|
+
|
|
4559
|
+
* @param callback - Optional callback to modify the relationship query
|
|
4560
|
+
|
|
4561
|
+
* @returns New query builder instance with the relationship non-existence check
|
|
4562
|
+
|
|
4563
|
+
*/
|
|
4263
4564
|
whereHasNot(relationName, callback) {
|
|
4264
4565
|
const relation = this.env.table.relations[relationName];
|
|
4265
4566
|
if (!relation) {
|
|
@@ -4274,33 +4575,47 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
4274
4575
|
return this.where(notExists(finalSubAst));
|
|
4275
4576
|
}
|
|
4276
4577
|
/**
|
|
4277
|
-
|
|
4278
|
-
|
|
4279
|
-
|
|
4280
|
-
|
|
4578
|
+
|
|
4579
|
+
* Compiles the query to SQL for a specific dialect
|
|
4580
|
+
|
|
4581
|
+
* @param dialect - Database dialect to compile for
|
|
4582
|
+
|
|
4583
|
+
* @returns Compiled query with SQL and parameters
|
|
4584
|
+
|
|
4585
|
+
*/
|
|
4281
4586
|
compile(dialect) {
|
|
4282
4587
|
const resolved = resolveDialectInput(dialect);
|
|
4283
4588
|
return resolved.compileSelect(this.context.state.ast);
|
|
4284
4589
|
}
|
|
4285
4590
|
/**
|
|
4286
|
-
|
|
4287
|
-
|
|
4288
|
-
|
|
4289
|
-
|
|
4591
|
+
|
|
4592
|
+
* Converts the query to SQL string for a specific dialect
|
|
4593
|
+
|
|
4594
|
+
* @param dialect - Database dialect to generate SQL for
|
|
4595
|
+
|
|
4596
|
+
* @returns SQL string representation of the query
|
|
4597
|
+
|
|
4598
|
+
*/
|
|
4290
4599
|
toSql(dialect) {
|
|
4291
4600
|
return this.compile(dialect).sql;
|
|
4292
4601
|
}
|
|
4293
4602
|
/**
|
|
4294
|
-
|
|
4295
|
-
|
|
4296
|
-
|
|
4603
|
+
|
|
4604
|
+
* Gets the hydration plan for the query
|
|
4605
|
+
|
|
4606
|
+
* @returns Hydration plan or undefined if none exists
|
|
4607
|
+
|
|
4608
|
+
*/
|
|
4297
4609
|
getHydrationPlan() {
|
|
4298
4610
|
return this.context.hydration.getPlan();
|
|
4299
4611
|
}
|
|
4300
4612
|
/**
|
|
4301
|
-
|
|
4302
|
-
|
|
4303
|
-
|
|
4613
|
+
|
|
4614
|
+
* Gets the Abstract Syntax Tree (AST) representation of the query
|
|
4615
|
+
|
|
4616
|
+
* @returns Query AST with hydration applied
|
|
4617
|
+
|
|
4618
|
+
*/
|
|
4304
4619
|
getAST() {
|
|
4305
4620
|
return this.context.hydration.applyToAst(this.context.state.ast);
|
|
4306
4621
|
}
|