metal-orm 1.0.42 → 1.0.44
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 +195 -37
- package/dist/index.cjs +1014 -538
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1267 -371
- package/dist/index.d.ts +1267 -371
- package/dist/index.js +1012 -536
- package/dist/index.js.map +1 -1
- package/package.json +8 -2
- package/scripts/run-eslint.mjs +34 -0
- package/src/codegen/typescript.ts +32 -15
- package/src/core/ast/adapters.ts +8 -2
- package/src/core/ast/builders.ts +105 -76
- package/src/core/ast/expression-builders.ts +430 -392
- package/src/core/ast/expression-nodes.ts +14 -5
- package/src/core/ast/expression-visitor.ts +56 -14
- package/src/core/ast/helpers.ts +23 -0
- package/src/core/ast/join-node.ts +18 -2
- package/src/core/ast/query.ts +6 -6
- package/src/core/ast/window-functions.ts +10 -2
- package/src/core/ddl/dialects/base-schema-dialect.ts +37 -4
- package/src/core/ddl/dialects/index.ts +1 -0
- package/src/core/ddl/dialects/mssql-schema-dialect.ts +5 -0
- package/src/core/ddl/dialects/mysql-schema-dialect.ts +3 -0
- package/src/core/ddl/dialects/postgres-schema-dialect.ts +14 -1
- package/src/core/ddl/dialects/render-reference.test.ts +69 -0
- package/src/core/ddl/dialects/sqlite-schema-dialect.ts +10 -0
- package/src/core/ddl/introspect/catalogs/index.ts +1 -0
- package/src/core/ddl/introspect/catalogs/postgres.ts +2 -0
- package/src/core/ddl/introspect/context.ts +6 -0
- package/src/core/ddl/introspect/functions/postgres.ts +13 -0
- package/src/core/ddl/introspect/mssql.ts +53 -8
- package/src/core/ddl/introspect/mysql.ts +32 -6
- package/src/core/ddl/introspect/postgres.ts +102 -34
- package/src/core/ddl/introspect/registry.ts +14 -0
- package/src/core/ddl/introspect/run-select.ts +19 -4
- package/src/core/ddl/introspect/sqlite.ts +78 -11
- package/src/core/ddl/introspect/types.ts +0 -1
- package/src/core/ddl/introspect/utils.ts +21 -3
- package/src/core/ddl/naming-strategy.ts +6 -0
- package/src/core/ddl/schema-dialect.ts +20 -6
- package/src/core/ddl/schema-diff.ts +22 -0
- package/src/core/ddl/schema-generator.ts +26 -12
- package/src/core/ddl/schema-plan-executor.ts +6 -0
- package/src/core/ddl/schema-types.ts +6 -0
- package/src/core/ddl/sql-writing.ts +4 -4
- package/src/core/dialect/abstract.ts +19 -7
- package/src/core/dialect/base/function-table-formatter.ts +3 -2
- package/src/core/dialect/base/join-compiler.ts +5 -3
- package/src/core/dialect/base/returning-strategy.ts +1 -0
- package/src/core/dialect/base/sql-dialect.ts +3 -3
- package/src/core/dialect/mssql/functions.ts +24 -25
- package/src/core/dialect/mssql/index.ts +1 -4
- package/src/core/dialect/mysql/functions.ts +0 -1
- package/src/core/dialect/postgres/functions.ts +33 -34
- package/src/core/dialect/postgres/index.ts +1 -0
- package/src/core/dialect/sqlite/functions.ts +18 -19
- package/src/core/dialect/sqlite/index.ts +2 -0
- package/src/core/execution/db-executor.ts +1 -1
- package/src/core/execution/executors/mysql-executor.ts +2 -2
- package/src/core/execution/executors/postgres-executor.ts +1 -1
- package/src/core/execution/pooling/pool.ts +12 -5
- package/src/core/functions/datetime.ts +58 -34
- package/src/core/functions/numeric.ts +96 -31
- package/src/core/functions/standard-strategy.ts +35 -0
- package/src/core/functions/text.ts +84 -23
- package/src/core/functions/types.ts +23 -8
- package/src/decorators/bootstrap.ts +42 -11
- package/src/decorators/column.ts +20 -11
- package/src/decorators/decorator-metadata.ts +30 -9
- package/src/decorators/entity.ts +29 -5
- package/src/decorators/index.ts +3 -0
- package/src/decorators/relations.ts +34 -11
- package/src/orm/als.ts +34 -9
- package/src/orm/entity-context.ts +62 -8
- package/src/orm/entity-meta.ts +8 -8
- package/src/orm/entity-metadata.ts +131 -16
- package/src/orm/entity.ts +28 -29
- package/src/orm/execute.ts +19 -4
- package/src/orm/hydration.ts +42 -39
- package/src/orm/identity-map.ts +1 -1
- package/src/orm/lazy-batch.ts +74 -104
- package/src/orm/orm-session.ts +24 -23
- package/src/orm/orm.ts +2 -5
- package/src/orm/relation-change-processor.ts +12 -11
- package/src/orm/relations/belongs-to.ts +11 -11
- package/src/orm/relations/has-many.ts +54 -10
- package/src/orm/relations/has-one.ts +8 -7
- package/src/orm/relations/many-to-many.ts +13 -13
- package/src/orm/runtime-types.ts +4 -4
- package/src/orm/save-graph.ts +31 -25
- package/src/orm/unit-of-work.ts +17 -17
- package/src/query/index.ts +74 -0
- package/src/query/target.ts +46 -0
- package/src/query-builder/delete-query-state.ts +30 -0
- package/src/query-builder/delete.ts +64 -18
- package/src/query-builder/hydration-manager.ts +52 -5
- package/src/query-builder/insert-query-state.ts +30 -0
- package/src/query-builder/insert.ts +58 -10
- package/src/query-builder/query-ast-service.ts +7 -2
- package/src/query-builder/query-resolution.ts +78 -0
- package/src/query-builder/raw-column-parser.ts +7 -1
- package/src/query-builder/relation-alias.ts +7 -0
- package/src/query-builder/relation-conditions.ts +61 -48
- package/src/query-builder/relation-service.ts +68 -63
- package/src/query-builder/relation-utils.ts +3 -0
- package/src/query-builder/select/cte-facet.ts +40 -0
- package/src/query-builder/select/from-facet.ts +80 -0
- package/src/query-builder/select/join-facet.ts +62 -0
- package/src/query-builder/select/predicate-facet.ts +103 -0
- package/src/query-builder/select/projection-facet.ts +69 -0
- package/src/query-builder/select/relation-facet.ts +81 -0
- package/src/query-builder/select/setop-facet.ts +36 -0
- package/src/query-builder/select-helpers.ts +15 -2
- package/src/query-builder/select-query-builder-deps.ts +19 -1
- package/src/query-builder/select-query-state.ts +2 -1
- package/src/query-builder/select.ts +795 -1163
- package/src/query-builder/update-query-state.ts +52 -0
- package/src/query-builder/update.ts +69 -18
- package/src/schema/column.ts +26 -26
- package/src/schema/table-guards.ts +31 -0
- package/src/schema/table.ts +47 -18
- package/src/schema/types.ts +22 -22
package/dist/index.js
CHANGED
|
@@ -32,7 +32,8 @@ var init_schema_plan_executor = __esm({
|
|
|
32
32
|
// src/schema/table.ts
|
|
33
33
|
var defineTable = (name, columns, relations = {}, hooks, options = {}) => {
|
|
34
34
|
const colsWithNames = Object.entries(columns).reduce((acc, [key, def]) => {
|
|
35
|
-
|
|
35
|
+
const colDef = { ...def, name: key, table: name };
|
|
36
|
+
acc[key] = colDef;
|
|
36
37
|
return acc;
|
|
37
38
|
}, {});
|
|
38
39
|
return {
|
|
@@ -56,17 +57,20 @@ var withColumnProps = (table) => {
|
|
|
56
57
|
if (cached) return cached;
|
|
57
58
|
const proxy = new Proxy(table, {
|
|
58
59
|
get(target, prop, receiver) {
|
|
59
|
-
|
|
60
|
+
const t = target;
|
|
61
|
+
if (prop === "$") return t.columns;
|
|
60
62
|
if (Reflect.has(target, prop)) return Reflect.get(target, prop, receiver);
|
|
61
|
-
if (typeof prop === "string" && prop in
|
|
63
|
+
if (typeof prop === "string" && prop in t.columns) return t.columns[prop];
|
|
62
64
|
return void 0;
|
|
63
65
|
},
|
|
64
66
|
has(target, prop) {
|
|
65
|
-
|
|
67
|
+
const t = target;
|
|
68
|
+
return prop === "$" || Reflect.has(target, prop) || typeof prop === "string" && prop in t.columns;
|
|
66
69
|
},
|
|
67
70
|
ownKeys(target) {
|
|
71
|
+
const t = target;
|
|
68
72
|
const base = Reflect.ownKeys(target);
|
|
69
|
-
const cols = Object.keys(
|
|
73
|
+
const cols = Object.keys(t.columns);
|
|
70
74
|
for (const k of cols) {
|
|
71
75
|
if (!base.includes(k)) base.push(k);
|
|
72
76
|
}
|
|
@@ -98,6 +102,14 @@ var withColumnProps = (table) => {
|
|
|
98
102
|
return proxy;
|
|
99
103
|
};
|
|
100
104
|
var tableRef = (table) => withColumnProps(table);
|
|
105
|
+
function getColumn(table, key) {
|
|
106
|
+
const col2 = table.columns[key];
|
|
107
|
+
if (!col2) {
|
|
108
|
+
const tableName = table.name || "<unknown>";
|
|
109
|
+
throw new Error(`Column '${key}' does not exist on table '${tableName}'`);
|
|
110
|
+
}
|
|
111
|
+
return col2;
|
|
112
|
+
}
|
|
101
113
|
|
|
102
114
|
// src/schema/column.ts
|
|
103
115
|
var col = {
|
|
@@ -302,46 +314,59 @@ var operandTypes = /* @__PURE__ */ new Set([
|
|
|
302
314
|
"CaseExpression",
|
|
303
315
|
"WindowFunction"
|
|
304
316
|
]);
|
|
305
|
-
var
|
|
306
|
-
var
|
|
307
|
-
|
|
308
|
-
|
|
317
|
+
var hasTypeProperty = (value) => typeof value === "object" && value !== null && "type" in value;
|
|
318
|
+
var isOperandNode = (node) => {
|
|
319
|
+
if (!hasTypeProperty(node)) return false;
|
|
320
|
+
return operandTypes.has(node.type);
|
|
321
|
+
};
|
|
322
|
+
var isFunctionNode = (node) => isOperandNode(node) && node.type === "Function";
|
|
323
|
+
var isCaseExpressionNode = (node) => isOperandNode(node) && node.type === "CaseExpression";
|
|
324
|
+
var isWindowFunctionNode = (node) => isOperandNode(node) && node.type === "WindowFunction";
|
|
309
325
|
var isExpressionSelectionNode = (node) => isFunctionNode(node) || isCaseExpressionNode(node) || isWindowFunctionNode(node);
|
|
310
326
|
|
|
311
327
|
// src/core/ast/expression-builders.ts
|
|
312
|
-
var
|
|
313
|
-
if (isOperandNode(value)) {
|
|
314
|
-
return value;
|
|
315
|
-
}
|
|
316
|
-
return {
|
|
317
|
-
type: "Literal",
|
|
318
|
-
value
|
|
319
|
-
};
|
|
320
|
-
};
|
|
321
|
-
var toNode = (col2) => {
|
|
322
|
-
if (isOperandNode(col2)) return col2;
|
|
323
|
-
const def = col2;
|
|
324
|
-
return { type: "Column", table: def.table || "unknown", name: def.name };
|
|
325
|
-
};
|
|
328
|
+
var isLiteralValue = (value) => value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean";
|
|
326
329
|
var toLiteralNode = (value) => ({
|
|
327
330
|
type: "Literal",
|
|
328
331
|
value
|
|
329
332
|
});
|
|
330
|
-
var
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
333
|
+
var columnRefToNode = (col2) => {
|
|
334
|
+
if (!col2.table) {
|
|
335
|
+
throw new Error(
|
|
336
|
+
`Column "${col2.name}" requires a table reference. Use columnOperand with a fully qualified ColumnRef or ColumnNode.`
|
|
337
|
+
);
|
|
335
338
|
}
|
|
336
|
-
return
|
|
339
|
+
return { type: "Column", table: col2.table, name: col2.name };
|
|
337
340
|
};
|
|
341
|
+
var toOperandNode = (value) => {
|
|
342
|
+
if (isOperandNode(value)) {
|
|
343
|
+
return value;
|
|
344
|
+
}
|
|
345
|
+
if (isLiteralValue(value)) {
|
|
346
|
+
return toLiteralNode(value);
|
|
347
|
+
}
|
|
348
|
+
return columnRefToNode(value);
|
|
349
|
+
};
|
|
350
|
+
var valueToOperand = (value) => {
|
|
351
|
+
if (isOperandNode(value)) {
|
|
352
|
+
return value;
|
|
353
|
+
}
|
|
354
|
+
return toLiteralNode(value);
|
|
355
|
+
};
|
|
356
|
+
var toOperand = (val) => toOperandNode(val);
|
|
357
|
+
var isValueOperandInput = (value) => isOperandNode(value) || isLiteralValue(value);
|
|
338
358
|
var hasQueryAst = (value) => typeof value.getAST === "function";
|
|
339
359
|
var resolveSelectQueryNode = (query) => hasQueryAst(query) ? query.getAST() : query;
|
|
340
360
|
var toScalarSubqueryNode = (query) => ({
|
|
341
361
|
type: "ScalarSubquery",
|
|
342
362
|
query: resolveSelectQueryNode(query)
|
|
343
363
|
});
|
|
344
|
-
var columnOperand = (col2) =>
|
|
364
|
+
var columnOperand = (col2) => {
|
|
365
|
+
if (isOperandNode(col2) && col2.type === "Column") {
|
|
366
|
+
return col2;
|
|
367
|
+
}
|
|
368
|
+
return columnRefToNode(col2);
|
|
369
|
+
};
|
|
345
370
|
var outerRef = (col2) => ({
|
|
346
371
|
...columnOperand(col2),
|
|
347
372
|
scope: "outer"
|
|
@@ -354,7 +379,7 @@ var correlateBy = (table, column) => outerRef({ name: column, table });
|
|
|
354
379
|
var createBinaryExpression = (operator, left2, right2, escape) => {
|
|
355
380
|
const node = {
|
|
356
381
|
type: "BinaryExpression",
|
|
357
|
-
left:
|
|
382
|
+
left: toOperandNode(left2),
|
|
358
383
|
operator,
|
|
359
384
|
right: toOperand(right2)
|
|
360
385
|
};
|
|
@@ -383,17 +408,17 @@ var or = (...operands) => ({
|
|
|
383
408
|
});
|
|
384
409
|
var isNull = (left2) => ({
|
|
385
410
|
type: "NullExpression",
|
|
386
|
-
left:
|
|
411
|
+
left: toOperandNode(left2),
|
|
387
412
|
operator: "IS NULL"
|
|
388
413
|
});
|
|
389
414
|
var isNotNull = (left2) => ({
|
|
390
415
|
type: "NullExpression",
|
|
391
|
-
left:
|
|
416
|
+
left: toOperandNode(left2),
|
|
392
417
|
operator: "IS NOT NULL"
|
|
393
418
|
});
|
|
394
419
|
var createInExpression = (operator, left2, right2) => ({
|
|
395
420
|
type: "InExpression",
|
|
396
|
-
left:
|
|
421
|
+
left: toOperandNode(left2),
|
|
397
422
|
operator,
|
|
398
423
|
right: right2
|
|
399
424
|
});
|
|
@@ -403,7 +428,7 @@ var inSubquery = (left2, subquery) => createInExpression("IN", left2, toScalarSu
|
|
|
403
428
|
var notInSubquery = (left2, subquery) => createInExpression("NOT IN", left2, toScalarSubqueryNode(subquery));
|
|
404
429
|
var createBetweenExpression = (operator, left2, lower2, upper2) => ({
|
|
405
430
|
type: "BetweenExpression",
|
|
406
|
-
left:
|
|
431
|
+
left: toOperandNode(left2),
|
|
407
432
|
operator,
|
|
408
433
|
lower: toOperand(lower2),
|
|
409
434
|
upper: toOperand(upper2)
|
|
@@ -585,24 +610,54 @@ var groupConcat = (col2, options) => ({
|
|
|
585
610
|
});
|
|
586
611
|
|
|
587
612
|
// src/core/ast/expression-visitor.ts
|
|
588
|
-
var
|
|
589
|
-
|
|
613
|
+
var DispatcherRegistry = class _DispatcherRegistry {
|
|
614
|
+
constructor(dispatchers = /* @__PURE__ */ new Map()) {
|
|
615
|
+
this.dispatchers = dispatchers;
|
|
616
|
+
}
|
|
617
|
+
/**
|
|
618
|
+
* Registers a new dispatcher and returns a new registry instance
|
|
619
|
+
*/
|
|
620
|
+
register(type, dispatcher) {
|
|
621
|
+
const newMap = new Map(this.dispatchers);
|
|
622
|
+
newMap.set(type, dispatcher);
|
|
623
|
+
return new _DispatcherRegistry(newMap);
|
|
624
|
+
}
|
|
625
|
+
/**
|
|
626
|
+
* Gets a dispatcher for the given type
|
|
627
|
+
*/
|
|
628
|
+
get(type) {
|
|
629
|
+
return this.dispatchers.get(type);
|
|
630
|
+
}
|
|
631
|
+
/**
|
|
632
|
+
* Returns a new empty registry
|
|
633
|
+
*/
|
|
634
|
+
clear() {
|
|
635
|
+
return new _DispatcherRegistry();
|
|
636
|
+
}
|
|
637
|
+
};
|
|
638
|
+
var expressionRegistry = new DispatcherRegistry();
|
|
639
|
+
var operandRegistry = new DispatcherRegistry();
|
|
590
640
|
var registerExpressionDispatcher = (type, dispatcher) => {
|
|
591
|
-
|
|
641
|
+
expressionRegistry = expressionRegistry.register(type, dispatcher);
|
|
592
642
|
};
|
|
593
643
|
var registerOperandDispatcher = (type, dispatcher) => {
|
|
594
|
-
|
|
644
|
+
operandRegistry = operandRegistry.register(type, dispatcher);
|
|
595
645
|
};
|
|
596
|
-
var clearExpressionDispatchers = () =>
|
|
597
|
-
|
|
646
|
+
var clearExpressionDispatchers = () => {
|
|
647
|
+
expressionRegistry = expressionRegistry.clear();
|
|
648
|
+
};
|
|
649
|
+
var clearOperandDispatchers = () => {
|
|
650
|
+
operandRegistry = operandRegistry.clear();
|
|
651
|
+
};
|
|
652
|
+
var getNodeType = (node) => typeof node === "object" && node !== null && typeof node.type === "string" ? node.type : void 0;
|
|
598
653
|
var unsupportedExpression = (node) => {
|
|
599
|
-
throw new Error(`Unsupported expression type "${node
|
|
654
|
+
throw new Error(`Unsupported expression type "${getNodeType(node) ?? "unknown"}"`);
|
|
600
655
|
};
|
|
601
656
|
var unsupportedOperand = (node) => {
|
|
602
|
-
throw new Error(`Unsupported operand type "${node
|
|
657
|
+
throw new Error(`Unsupported operand type "${getNodeType(node) ?? "unknown"}"`);
|
|
603
658
|
};
|
|
604
659
|
var visitExpression = (node, visitor) => {
|
|
605
|
-
const dynamic =
|
|
660
|
+
const dynamic = expressionRegistry.get(node.type);
|
|
606
661
|
if (dynamic) return dynamic(node, visitor);
|
|
607
662
|
switch (node.type) {
|
|
608
663
|
case "BinaryExpression":
|
|
@@ -633,7 +688,7 @@ var visitExpression = (node, visitor) => {
|
|
|
633
688
|
return unsupportedExpression(node);
|
|
634
689
|
};
|
|
635
690
|
var visitOperand = (node, visitor) => {
|
|
636
|
-
const dynamic =
|
|
691
|
+
const dynamic = operandRegistry.get(node.type);
|
|
637
692
|
if (dynamic) return dynamic(node, visitor);
|
|
638
693
|
switch (node.type) {
|
|
639
694
|
case "Column":
|
|
@@ -668,24 +723,35 @@ var visitOperand = (node, visitor) => {
|
|
|
668
723
|
};
|
|
669
724
|
|
|
670
725
|
// src/core/ast/adapters.ts
|
|
726
|
+
var hasAlias = (obj) => typeof obj === "object" && obj !== null && "alias" in obj;
|
|
671
727
|
var toColumnRef = (col2) => ({
|
|
672
728
|
name: col2.name,
|
|
673
729
|
table: col2.table,
|
|
674
|
-
alias: col2.alias
|
|
730
|
+
alias: hasAlias(col2) ? col2.alias : void 0
|
|
675
731
|
});
|
|
676
732
|
var toTableRef = (table) => ({
|
|
677
733
|
name: table.name,
|
|
678
734
|
schema: table.schema,
|
|
679
|
-
alias: table.alias
|
|
735
|
+
alias: hasAlias(table) ? table.alias : void 0
|
|
680
736
|
});
|
|
681
737
|
|
|
682
738
|
// src/core/ast/builders.ts
|
|
739
|
+
var isColumnNode = (col2) => "type" in col2 && col2.type === "Column";
|
|
740
|
+
var resolveTableName = (def, table) => {
|
|
741
|
+
if (!def.table) {
|
|
742
|
+
return table.alias || table.name;
|
|
743
|
+
}
|
|
744
|
+
if (table.alias && def.table === table.name) {
|
|
745
|
+
return table.alias;
|
|
746
|
+
}
|
|
747
|
+
return def.table;
|
|
748
|
+
};
|
|
683
749
|
var buildColumnNode = (table, column) => {
|
|
684
|
-
if (column
|
|
750
|
+
if (isColumnNode(column)) {
|
|
685
751
|
return column;
|
|
686
752
|
}
|
|
687
753
|
const def = column;
|
|
688
|
-
const baseTable = def
|
|
754
|
+
const baseTable = resolveTableName(def, table);
|
|
689
755
|
return {
|
|
690
756
|
type: "Column",
|
|
691
757
|
table: baseTable,
|
|
@@ -699,7 +765,8 @@ var buildColumnNodes = (table, names) => names.map((name) => ({
|
|
|
699
765
|
}));
|
|
700
766
|
var createTableNode = (table) => ({
|
|
701
767
|
type: "Table",
|
|
702
|
-
name: table.name
|
|
768
|
+
name: table.name,
|
|
769
|
+
schema: table.schema
|
|
703
770
|
});
|
|
704
771
|
var fnTable = (name, args = [], alias, opts) => ({
|
|
705
772
|
type: "FunctionTable",
|
|
@@ -720,6 +787,9 @@ var derivedTable = (query, alias, columnAliases) => ({
|
|
|
720
787
|
|
|
721
788
|
// src/core/functions/standard-strategy.ts
|
|
722
789
|
var StandardFunctionStrategy = class _StandardFunctionStrategy {
|
|
790
|
+
/**
|
|
791
|
+
* Creates a new StandardFunctionStrategy and registers standard functions.
|
|
792
|
+
*/
|
|
723
793
|
constructor() {
|
|
724
794
|
this.renderers = /* @__PURE__ */ new Map();
|
|
725
795
|
this.registerStandard();
|
|
@@ -758,12 +828,25 @@ var StandardFunctionStrategy = class _StandardFunctionStrategy {
|
|
|
758
828
|
this.add("DATE_TRUNC", ({ compiledArgs }) => `DATE_TRUNC(${compiledArgs[0]}, ${compiledArgs[1]})`);
|
|
759
829
|
this.add("GROUP_CONCAT", (ctx) => this.renderGroupConcat(ctx));
|
|
760
830
|
}
|
|
831
|
+
/**
|
|
832
|
+
* Registers a renderer for a function name.
|
|
833
|
+
* @param name - The function name.
|
|
834
|
+
* @param renderer - The renderer function.
|
|
835
|
+
*/
|
|
761
836
|
add(name, renderer) {
|
|
762
837
|
this.renderers.set(name, renderer);
|
|
763
838
|
}
|
|
839
|
+
/**
|
|
840
|
+
* @inheritDoc
|
|
841
|
+
*/
|
|
764
842
|
getRenderer(name) {
|
|
765
843
|
return this.renderers.get(name);
|
|
766
844
|
}
|
|
845
|
+
/**
|
|
846
|
+
* Renders the GROUP_CONCAT function with optional ORDER BY and SEPARATOR.
|
|
847
|
+
* @param ctx - The function render context.
|
|
848
|
+
* @returns The rendered SQL string.
|
|
849
|
+
*/
|
|
767
850
|
renderGroupConcat(ctx) {
|
|
768
851
|
const arg = ctx.compiledArgs[0];
|
|
769
852
|
const orderClause = this.buildOrderByExpression(ctx);
|
|
@@ -771,6 +854,11 @@ var StandardFunctionStrategy = class _StandardFunctionStrategy {
|
|
|
771
854
|
const separatorClause = this.formatGroupConcatSeparator(ctx);
|
|
772
855
|
return `GROUP_CONCAT(${arg}${orderSegment}${separatorClause})`;
|
|
773
856
|
}
|
|
857
|
+
/**
|
|
858
|
+
* Builds the ORDER BY clause for functions like GROUP_CONCAT.
|
|
859
|
+
* @param ctx - The function render context.
|
|
860
|
+
* @returns The ORDER BY SQL clause or empty string.
|
|
861
|
+
*/
|
|
774
862
|
buildOrderByExpression(ctx) {
|
|
775
863
|
const orderBy = ctx.node.orderBy;
|
|
776
864
|
if (!orderBy || orderBy.length === 0) {
|
|
@@ -786,16 +874,27 @@ var StandardFunctionStrategy = class _StandardFunctionStrategy {
|
|
|
786
874
|
});
|
|
787
875
|
return `ORDER BY ${parts.join(", ")}`;
|
|
788
876
|
}
|
|
877
|
+
/**
|
|
878
|
+
* Formats the SEPARATOR clause for GROUP_CONCAT.
|
|
879
|
+
* @param ctx - The function render context.
|
|
880
|
+
* @returns The SEPARATOR SQL clause or empty string.
|
|
881
|
+
*/
|
|
789
882
|
formatGroupConcatSeparator(ctx) {
|
|
790
883
|
if (!ctx.node.separator) {
|
|
791
884
|
return "";
|
|
792
885
|
}
|
|
793
886
|
return ` SEPARATOR ${ctx.compileOperand(ctx.node.separator)}`;
|
|
794
887
|
}
|
|
888
|
+
/**
|
|
889
|
+
* Gets the separator operand for GROUP_CONCAT, defaulting to comma.
|
|
890
|
+
* @param ctx - The function render context.
|
|
891
|
+
* @returns The separator operand.
|
|
892
|
+
*/
|
|
795
893
|
getGroupConcatSeparatorOperand(ctx) {
|
|
796
894
|
return ctx.node.separator ?? _StandardFunctionStrategy.DEFAULT_GROUP_CONCAT_SEPARATOR;
|
|
797
895
|
}
|
|
798
896
|
static {
|
|
897
|
+
/** Default separator for GROUP_CONCAT, a comma. */
|
|
799
898
|
this.DEFAULT_GROUP_CONCAT_SEPARATOR = {
|
|
800
899
|
type: "Literal",
|
|
801
900
|
value: ","
|
|
@@ -860,7 +959,8 @@ var Dialect = class _Dialect {
|
|
|
860
959
|
if (!where) return "";
|
|
861
960
|
return ` WHERE ${this.compileExpression(where, ctx)}`;
|
|
862
961
|
}
|
|
863
|
-
compileReturning(returning,
|
|
962
|
+
compileReturning(returning, _ctx) {
|
|
963
|
+
void _ctx;
|
|
864
964
|
if (!returning || returning.length === 0) return "";
|
|
865
965
|
throw new Error("RETURNING is not supported by this dialect.");
|
|
866
966
|
}
|
|
@@ -908,14 +1008,16 @@ var Dialect = class _Dialect {
|
|
|
908
1008
|
* @param index - Parameter index
|
|
909
1009
|
* @returns Formatted placeholder string
|
|
910
1010
|
*/
|
|
911
|
-
formatPlaceholder(
|
|
1011
|
+
formatPlaceholder(_index) {
|
|
1012
|
+
void _index;
|
|
912
1013
|
return "?";
|
|
913
1014
|
}
|
|
914
1015
|
/**
|
|
915
1016
|
* Whether the current dialect supports a given set operation.
|
|
916
1017
|
* Override in concrete dialects to restrict support.
|
|
917
1018
|
*/
|
|
918
|
-
supportsSetOperation(
|
|
1019
|
+
supportsSetOperation(_kind) {
|
|
1020
|
+
void _kind;
|
|
919
1021
|
return true;
|
|
920
1022
|
}
|
|
921
1023
|
/**
|
|
@@ -1108,15 +1210,22 @@ var Dialect = class _Dialect {
|
|
|
1108
1210
|
}
|
|
1109
1211
|
registerDefaultOperandCompilers() {
|
|
1110
1212
|
this.registerOperandCompiler("Literal", (literal, ctx) => ctx.addParameter(literal.value));
|
|
1111
|
-
this.registerOperandCompiler("AliasRef", (alias, _ctx) =>
|
|
1213
|
+
this.registerOperandCompiler("AliasRef", (alias, _ctx) => {
|
|
1214
|
+
void _ctx;
|
|
1215
|
+
return this.quoteIdentifier(alias.name);
|
|
1216
|
+
});
|
|
1112
1217
|
this.registerOperandCompiler("Column", (column, _ctx) => {
|
|
1218
|
+
void _ctx;
|
|
1113
1219
|
return `${this.quoteIdentifier(column.table)}.${this.quoteIdentifier(column.name)}`;
|
|
1114
1220
|
});
|
|
1115
1221
|
this.registerOperandCompiler(
|
|
1116
1222
|
"Function",
|
|
1117
1223
|
(fnNode, ctx) => this.compileFunctionOperand(fnNode, ctx)
|
|
1118
1224
|
);
|
|
1119
|
-
this.registerOperandCompiler("JsonPath", (path, _ctx) =>
|
|
1225
|
+
this.registerOperandCompiler("JsonPath", (path, _ctx) => {
|
|
1226
|
+
void _ctx;
|
|
1227
|
+
return this.compileJsonPath(path);
|
|
1228
|
+
});
|
|
1120
1229
|
this.registerOperandCompiler("ScalarSubquery", (node, ctx) => {
|
|
1121
1230
|
const sql = this.compileSelectAst(node.query, ctx).trim().replace(/;$/, "");
|
|
1122
1231
|
return `(${sql})`;
|
|
@@ -1160,7 +1269,8 @@ var Dialect = class _Dialect {
|
|
|
1160
1269
|
});
|
|
1161
1270
|
}
|
|
1162
1271
|
// Default fallback, should be overridden by dialects if supported
|
|
1163
|
-
compileJsonPath(
|
|
1272
|
+
compileJsonPath(_node) {
|
|
1273
|
+
void _node;
|
|
1164
1274
|
throw new Error("JSON Path not supported by this dialect");
|
|
1165
1275
|
}
|
|
1166
1276
|
/**
|
|
@@ -1326,6 +1436,7 @@ var NoReturningStrategy = class {
|
|
|
1326
1436
|
* @throws Error indicating RETURNING is not supported.
|
|
1327
1437
|
*/
|
|
1328
1438
|
compileReturning(returning, _ctx) {
|
|
1439
|
+
void _ctx;
|
|
1329
1440
|
if (!returning || returning.length === 0) return "";
|
|
1330
1441
|
throw new Error("RETURNING is not supported by this dialect.");
|
|
1331
1442
|
}
|
|
@@ -1727,6 +1838,7 @@ var PostgresDialect = class extends SqlDialectBase {
|
|
|
1727
1838
|
return `${col2}->>'${node.path}'`;
|
|
1728
1839
|
}
|
|
1729
1840
|
compileReturning(returning, ctx) {
|
|
1841
|
+
void ctx;
|
|
1730
1842
|
if (!returning || returning.length === 0) return "";
|
|
1731
1843
|
const columns = this.formatReturningColumns(returning);
|
|
1732
1844
|
return ` RETURNING ${columns}`;
|
|
@@ -1977,9 +2089,11 @@ var SqliteDialect = class extends SqlDialectBase {
|
|
|
1977
2089
|
return `json_extract(${col2}, '${node.path}')`;
|
|
1978
2090
|
}
|
|
1979
2091
|
compileQualifiedColumn(column, _table) {
|
|
2092
|
+
void _table;
|
|
1980
2093
|
return this.quoteIdentifier(column.name);
|
|
1981
2094
|
}
|
|
1982
2095
|
compileReturning(returning, ctx) {
|
|
2096
|
+
void ctx;
|
|
1983
2097
|
if (!returning || returning.length === 0) return "";
|
|
1984
2098
|
const columns = this.formatReturningColumns(returning);
|
|
1985
2099
|
return ` RETURNING ${columns}`;
|
|
@@ -2301,7 +2415,7 @@ var SelectQueryState = class _SelectQueryState {
|
|
|
2301
2415
|
this.table = table;
|
|
2302
2416
|
this.ast = ast ?? {
|
|
2303
2417
|
type: "SelectQuery",
|
|
2304
|
-
from:
|
|
2418
|
+
from: createTableNode(table),
|
|
2305
2419
|
columns: [],
|
|
2306
2420
|
joins: []
|
|
2307
2421
|
};
|
|
@@ -2452,10 +2566,18 @@ var SelectQueryState = class _SelectQueryState {
|
|
|
2452
2566
|
var createJoinNode = (kind, tableName, condition, relationName) => ({
|
|
2453
2567
|
type: "Join",
|
|
2454
2568
|
kind,
|
|
2455
|
-
table: typeof tableName === "string" ?
|
|
2569
|
+
table: typeof tableName === "string" ? parseQualifiedTableRef(tableName) : tableName,
|
|
2456
2570
|
condition,
|
|
2457
2571
|
meta: relationName ? { relationName } : void 0
|
|
2458
2572
|
});
|
|
2573
|
+
var parseQualifiedTableRef = (ref) => {
|
|
2574
|
+
const parts = ref.split(".");
|
|
2575
|
+
if (parts.length === 2) {
|
|
2576
|
+
const [schema, name] = parts;
|
|
2577
|
+
return { type: "Table", schema, name };
|
|
2578
|
+
}
|
|
2579
|
+
return { type: "Table", name: ref };
|
|
2580
|
+
};
|
|
2459
2581
|
|
|
2460
2582
|
// src/query-builder/hydration-manager.ts
|
|
2461
2583
|
var HydrationManager = class _HydrationManager {
|
|
@@ -2542,6 +2664,11 @@ var HydrationManager = class _HydrationManager {
|
|
|
2542
2664
|
const hasPagination = ast.limit !== void 0 || ast.offset !== void 0;
|
|
2543
2665
|
return hasPagination && this.hasMultiplyingRelations(plan);
|
|
2544
2666
|
}
|
|
2667
|
+
/**
|
|
2668
|
+
* Checks if the hydration plan contains relations that multiply rows
|
|
2669
|
+
* @param plan - Hydration plan to check
|
|
2670
|
+
* @returns True if plan has HasMany or BelongsToMany relations
|
|
2671
|
+
*/
|
|
2545
2672
|
hasMultiplyingRelations(plan) {
|
|
2546
2673
|
return plan.relations.some(
|
|
2547
2674
|
(rel) => rel.type === RelationKinds.HasMany || rel.type === RelationKinds.BelongsToMany
|
|
@@ -2619,6 +2746,12 @@ var HydrationManager = class _HydrationManager {
|
|
|
2619
2746
|
ctes: [...ast.ctes ?? [], baseCte, pageCte]
|
|
2620
2747
|
};
|
|
2621
2748
|
}
|
|
2749
|
+
/**
|
|
2750
|
+
* Generates a unique CTE name by appending a suffix if needed
|
|
2751
|
+
* @param existing - Existing CTE nodes
|
|
2752
|
+
* @param baseName - Base name for the CTE
|
|
2753
|
+
* @returns Unique CTE name
|
|
2754
|
+
*/
|
|
2622
2755
|
nextCteName(existing, baseName) {
|
|
2623
2756
|
const names = new Set((existing ?? []).map((cte) => cte.name));
|
|
2624
2757
|
let candidate = baseName;
|
|
@@ -2629,15 +2762,26 @@ var HydrationManager = class _HydrationManager {
|
|
|
2629
2762
|
}
|
|
2630
2763
|
return candidate;
|
|
2631
2764
|
}
|
|
2765
|
+
/**
|
|
2766
|
+
* Extracts projection names from column nodes
|
|
2767
|
+
* @param columns - Projection nodes
|
|
2768
|
+
* @returns Array of names or undefined if any column lacks name/alias
|
|
2769
|
+
*/
|
|
2632
2770
|
getProjectionNames(columns) {
|
|
2633
2771
|
const names = [];
|
|
2634
2772
|
for (const col2 of columns) {
|
|
2635
|
-
const
|
|
2773
|
+
const node = col2;
|
|
2774
|
+
const alias = node.alias ?? node.name;
|
|
2636
2775
|
if (!alias) return void 0;
|
|
2637
2776
|
names.push(alias);
|
|
2638
2777
|
}
|
|
2639
2778
|
return names;
|
|
2640
2779
|
}
|
|
2780
|
+
/**
|
|
2781
|
+
* Builds a map of column keys to their aliases from projection nodes
|
|
2782
|
+
* @param columns - Projection nodes
|
|
2783
|
+
* @returns Map of 'table.name' to alias
|
|
2784
|
+
*/
|
|
2641
2785
|
buildProjectionAliasMap(columns) {
|
|
2642
2786
|
const map = /* @__PURE__ */ new Map();
|
|
2643
2787
|
for (const col2 of columns) {
|
|
@@ -2648,6 +2792,15 @@ var HydrationManager = class _HydrationManager {
|
|
|
2648
2792
|
}
|
|
2649
2793
|
return map;
|
|
2650
2794
|
}
|
|
2795
|
+
/**
|
|
2796
|
+
* Maps order by nodes to use base CTE alias
|
|
2797
|
+
* @param orderBy - Original order by nodes
|
|
2798
|
+
* @param plan - Hydration plan
|
|
2799
|
+
* @param projectionAliases - Map of column aliases
|
|
2800
|
+
* @param baseAlias - Base CTE alias
|
|
2801
|
+
* @param availableColumns - Set of available column names
|
|
2802
|
+
* @returns Mapped order by nodes, null if cannot map
|
|
2803
|
+
*/
|
|
2651
2804
|
mapOrderBy(orderBy, plan, projectionAliases, baseAlias, availableColumns) {
|
|
2652
2805
|
if (!orderBy || orderBy.length === 0) {
|
|
2653
2806
|
return void 0;
|
|
@@ -2660,6 +2813,15 @@ var HydrationManager = class _HydrationManager {
|
|
|
2660
2813
|
}
|
|
2661
2814
|
return mapped;
|
|
2662
2815
|
}
|
|
2816
|
+
/**
|
|
2817
|
+
* Maps a single ordering term to use base CTE alias
|
|
2818
|
+
* @param term - Ordering term to map
|
|
2819
|
+
* @param plan - Hydration plan
|
|
2820
|
+
* @param projectionAliases - Map of column aliases
|
|
2821
|
+
* @param baseAlias - Base CTE alias
|
|
2822
|
+
* @param availableColumns - Set of available column names
|
|
2823
|
+
* @returns Mapped term or null if cannot map
|
|
2824
|
+
*/
|
|
2663
2825
|
mapOrderingTerm(term, plan, projectionAliases, baseAlias, availableColumns) {
|
|
2664
2826
|
if (term.type === "Column") {
|
|
2665
2827
|
const col2 = term;
|
|
@@ -2675,6 +2837,13 @@ var HydrationManager = class _HydrationManager {
|
|
|
2675
2837
|
}
|
|
2676
2838
|
return null;
|
|
2677
2839
|
}
|
|
2840
|
+
/**
|
|
2841
|
+
* Builds column nodes for paging CTE
|
|
2842
|
+
* @param primaryKey - Primary key name
|
|
2843
|
+
* @param orderBy - Order by nodes
|
|
2844
|
+
* @param tableAlias - Table alias for columns
|
|
2845
|
+
* @returns Array of column nodes for paging
|
|
2846
|
+
*/
|
|
2678
2847
|
buildPagingColumns(primaryKey, orderBy, tableAlias) {
|
|
2679
2848
|
const columns = [{ type: "Column", table: tableAlias, name: primaryKey, alias: primaryKey }];
|
|
2680
2849
|
if (!orderBy) return columns;
|
|
@@ -2849,7 +3018,8 @@ var buildDefaultHydrationPlan = (table) => ({
|
|
|
2849
3018
|
// src/query-builder/raw-column-parser.ts
|
|
2850
3019
|
var parseRawColumn = (col2, tableName, ctes) => {
|
|
2851
3020
|
if (col2.includes("(")) {
|
|
2852
|
-
const [
|
|
3021
|
+
const [_fn, rest] = col2.split("(");
|
|
3022
|
+
void _fn;
|
|
2853
3023
|
const colName = rest.replace(")", "");
|
|
2854
3024
|
const [table, name] = colName.includes(".") ? colName.split(".") : [tableName, colName];
|
|
2855
3025
|
return { type: "Column", table, name, alias: col2 };
|
|
@@ -3046,10 +3216,15 @@ var QueryAstService = class {
|
|
|
3046
3216
|
combineExpressions(existing, next) {
|
|
3047
3217
|
return existing ? and(existing, next) : next;
|
|
3048
3218
|
}
|
|
3219
|
+
/**
|
|
3220
|
+
* Normalizes an ordering term to a standard OrderingTerm
|
|
3221
|
+
* @param term - Column definition or ordering term to normalize
|
|
3222
|
+
* @returns Normalized ordering term
|
|
3223
|
+
*/
|
|
3049
3224
|
normalizeOrderingTerm(term) {
|
|
3050
3225
|
const from = this.state.ast.from;
|
|
3051
3226
|
const tableRef2 = from.type === "Table" && from.alias ? { ...this.table, alias: from.alias } : this.table;
|
|
3052
|
-
const termType = term
|
|
3227
|
+
const termType = term.type;
|
|
3053
3228
|
if (termType === "Column") {
|
|
3054
3229
|
return term;
|
|
3055
3230
|
}
|
|
@@ -3162,7 +3337,11 @@ var buildBelongsToManyJoins = (root, relationName, relation, joinKind, extra, ro
|
|
|
3162
3337
|
{ type: "Column", table: relation.pivotTable.name, name: relation.pivotForeignKeyToRoot },
|
|
3163
3338
|
{ type: "Column", table: rootTable, name: rootKey }
|
|
3164
3339
|
);
|
|
3165
|
-
const pivotJoin = createJoinNode(
|
|
3340
|
+
const pivotJoin = createJoinNode(
|
|
3341
|
+
joinKind,
|
|
3342
|
+
{ type: "Table", name: relation.pivotTable.name, schema: relation.pivotTable.schema },
|
|
3343
|
+
pivotCondition
|
|
3344
|
+
);
|
|
3166
3345
|
let targetCondition = eq(
|
|
3167
3346
|
{ type: "Column", table: relation.target.name, name: targetKey },
|
|
3168
3347
|
{ type: "Column", table: relation.pivotTable.name, name: relation.pivotForeignKeyToTarget }
|
|
@@ -3172,7 +3351,7 @@ var buildBelongsToManyJoins = (root, relationName, relation, joinKind, extra, ro
|
|
|
3172
3351
|
}
|
|
3173
3352
|
const targetJoin = createJoinNode(
|
|
3174
3353
|
joinKind,
|
|
3175
|
-
relation.target.name,
|
|
3354
|
+
{ type: "Table", name: relation.target.name, schema: relation.target.schema },
|
|
3176
3355
|
targetCondition,
|
|
3177
3356
|
relationName
|
|
3178
3357
|
);
|
|
@@ -3350,7 +3529,12 @@ var RelationService = class {
|
|
|
3350
3529
|
return joins.reduce((current, join) => this.astService(current).withJoin(join), state);
|
|
3351
3530
|
}
|
|
3352
3531
|
const condition = buildRelationJoinCondition(this.table, relation, extraCondition, rootAlias);
|
|
3353
|
-
const joinNode = createJoinNode(
|
|
3532
|
+
const joinNode = createJoinNode(
|
|
3533
|
+
joinKind,
|
|
3534
|
+
{ type: "Table", name: relation.target.name, schema: relation.target.schema },
|
|
3535
|
+
condition,
|
|
3536
|
+
relationName
|
|
3537
|
+
);
|
|
3354
3538
|
return this.astService(state).withJoin(joinNode);
|
|
3355
3539
|
}
|
|
3356
3540
|
/**
|
|
@@ -3395,25 +3579,6 @@ var RelationService = class {
|
|
|
3395
3579
|
}
|
|
3396
3580
|
};
|
|
3397
3581
|
|
|
3398
|
-
// src/query-builder/select-query-builder-deps.ts
|
|
3399
|
-
var defaultCreateQueryAstService = (table, state) => new QueryAstService(table, state);
|
|
3400
|
-
var defaultCreateHydrationPlanner = (table) => new HydrationPlanner(table);
|
|
3401
|
-
var defaultCreateHydration = (table, plannerFactory) => new HydrationManager(table, plannerFactory(table));
|
|
3402
|
-
var resolveSelectQueryBuilderDependencies = (overrides = {}) => {
|
|
3403
|
-
const createQueryAstService = overrides.createQueryAstService ?? defaultCreateQueryAstService;
|
|
3404
|
-
const createHydrationPlanner = overrides.createHydrationPlanner ?? defaultCreateHydrationPlanner;
|
|
3405
|
-
const createHydration = overrides.createHydration ?? ((table) => defaultCreateHydration(table, createHydrationPlanner));
|
|
3406
|
-
const createRelationService = overrides.createRelationService ?? ((table, state, hydration) => new RelationService(table, state, hydration, createQueryAstService));
|
|
3407
|
-
return {
|
|
3408
|
-
createState: overrides.createState ?? ((table) => new SelectQueryState(table)),
|
|
3409
|
-
createHydration,
|
|
3410
|
-
createHydrationPlanner,
|
|
3411
|
-
createQueryAstService,
|
|
3412
|
-
createRelationService
|
|
3413
|
-
};
|
|
3414
|
-
};
|
|
3415
|
-
var defaultSelectQueryBuilderDependencies = resolveSelectQueryBuilderDependencies();
|
|
3416
|
-
|
|
3417
3582
|
// src/query-builder/column-selector.ts
|
|
3418
3583
|
var ColumnSelector = class {
|
|
3419
3584
|
/**
|
|
@@ -3539,6 +3704,29 @@ var RelationManager = class {
|
|
|
3539
3704
|
}
|
|
3540
3705
|
};
|
|
3541
3706
|
|
|
3707
|
+
// src/query-builder/select-query-builder-deps.ts
|
|
3708
|
+
var defaultCreateQueryAstService = (table, state) => new QueryAstService(table, state);
|
|
3709
|
+
var defaultCreateHydrationPlanner = (table) => new HydrationPlanner(table);
|
|
3710
|
+
var defaultCreateHydration = (table, plannerFactory) => new HydrationManager(table, plannerFactory(table));
|
|
3711
|
+
var resolveSelectQueryBuilderDependencies = (overrides = {}) => {
|
|
3712
|
+
const createQueryAstService = overrides.createQueryAstService ?? defaultCreateQueryAstService;
|
|
3713
|
+
const createHydrationPlanner = overrides.createHydrationPlanner ?? defaultCreateHydrationPlanner;
|
|
3714
|
+
const createHydration = overrides.createHydration ?? ((table) => defaultCreateHydration(table, createHydrationPlanner));
|
|
3715
|
+
const createRelationService = overrides.createRelationService ?? ((table, state, hydration) => new RelationService(table, state, hydration, createQueryAstService));
|
|
3716
|
+
const createColumnSelector = overrides.createColumnSelector ?? ((env) => new ColumnSelector(env));
|
|
3717
|
+
const createRelationManager = overrides.createRelationManager ?? ((env) => new RelationManager(env));
|
|
3718
|
+
return {
|
|
3719
|
+
createState: overrides.createState ?? ((table) => new SelectQueryState(table)),
|
|
3720
|
+
createHydration,
|
|
3721
|
+
createHydrationPlanner,
|
|
3722
|
+
createQueryAstService,
|
|
3723
|
+
createRelationService,
|
|
3724
|
+
createColumnSelector,
|
|
3725
|
+
createRelationManager
|
|
3726
|
+
};
|
|
3727
|
+
};
|
|
3728
|
+
var defaultSelectQueryBuilderDependencies = resolveSelectQueryBuilderDependencies();
|
|
3729
|
+
|
|
3542
3730
|
// src/orm/hydration.ts
|
|
3543
3731
|
var hydrateRows = (rows, plan) => {
|
|
3544
3732
|
if (!plan || !rows.length) return rows;
|
|
@@ -3664,6 +3852,18 @@ var hideInternal = (obj, keys) => {
|
|
|
3664
3852
|
}
|
|
3665
3853
|
};
|
|
3666
3854
|
var DefaultHasManyCollection = class {
|
|
3855
|
+
/**
|
|
3856
|
+
* Creates a new DefaultHasManyCollection instance.
|
|
3857
|
+
* @param ctx - The entity context
|
|
3858
|
+
* @param meta - The entity metadata
|
|
3859
|
+
* @param root - The root entity
|
|
3860
|
+
* @param relationName - The relation name
|
|
3861
|
+
* @param relation - The relation definition
|
|
3862
|
+
* @param rootTable - The root table definition
|
|
3863
|
+
* @param loader - The loader function for lazy loading
|
|
3864
|
+
* @param createEntity - Function to create entities from rows
|
|
3865
|
+
* @param localKey - The local key for the relation
|
|
3866
|
+
*/
|
|
3667
3867
|
constructor(ctx, meta, root, relationName, relation, rootTable, loader, createEntity, localKey) {
|
|
3668
3868
|
this.ctx = ctx;
|
|
3669
3869
|
this.meta = meta;
|
|
@@ -3681,6 +3881,10 @@ var DefaultHasManyCollection = class {
|
|
|
3681
3881
|
hideInternal(this, ["ctx", "meta", "root", "relationName", "relation", "rootTable", "loader", "createEntity", "localKey"]);
|
|
3682
3882
|
this.hydrateFromCache();
|
|
3683
3883
|
}
|
|
3884
|
+
/**
|
|
3885
|
+
* Loads the related entities if not already loaded.
|
|
3886
|
+
* @returns Promise resolving to the array of child entities
|
|
3887
|
+
*/
|
|
3684
3888
|
async load() {
|
|
3685
3889
|
if (this.loaded) return this.items;
|
|
3686
3890
|
const map = await this.loader();
|
|
@@ -3690,9 +3894,18 @@ var DefaultHasManyCollection = class {
|
|
|
3690
3894
|
this.loaded = true;
|
|
3691
3895
|
return this.items;
|
|
3692
3896
|
}
|
|
3897
|
+
/**
|
|
3898
|
+
* Gets the current items in the collection.
|
|
3899
|
+
* @returns Array of child entities
|
|
3900
|
+
*/
|
|
3693
3901
|
getItems() {
|
|
3694
3902
|
return this.items;
|
|
3695
3903
|
}
|
|
3904
|
+
/**
|
|
3905
|
+
* Adds a new child entity to the collection.
|
|
3906
|
+
* @param data - Partial data for the new entity
|
|
3907
|
+
* @returns The created entity
|
|
3908
|
+
*/
|
|
3696
3909
|
add(data) {
|
|
3697
3910
|
const keyValue = this.root[this.localKey];
|
|
3698
3911
|
const childRow = {
|
|
@@ -3712,6 +3925,10 @@ var DefaultHasManyCollection = class {
|
|
|
3712
3925
|
);
|
|
3713
3926
|
return entity;
|
|
3714
3927
|
}
|
|
3928
|
+
/**
|
|
3929
|
+
* Attaches an existing entity to the collection.
|
|
3930
|
+
* @param entity - The entity to attach
|
|
3931
|
+
*/
|
|
3715
3932
|
attach(entity) {
|
|
3716
3933
|
const keyValue = this.root[this.localKey];
|
|
3717
3934
|
entity[this.relation.foreignKey] = keyValue;
|
|
@@ -3726,6 +3943,10 @@ var DefaultHasManyCollection = class {
|
|
|
3726
3943
|
{ kind: "attach", entity }
|
|
3727
3944
|
);
|
|
3728
3945
|
}
|
|
3946
|
+
/**
|
|
3947
|
+
* Removes an entity from the collection.
|
|
3948
|
+
* @param entity - The entity to remove
|
|
3949
|
+
*/
|
|
3729
3950
|
remove(entity) {
|
|
3730
3951
|
this.items = this.items.filter((item) => item !== entity);
|
|
3731
3952
|
this.removed.add(entity);
|
|
@@ -3738,6 +3959,9 @@ var DefaultHasManyCollection = class {
|
|
|
3738
3959
|
{ kind: "remove", entity }
|
|
3739
3960
|
);
|
|
3740
3961
|
}
|
|
3962
|
+
/**
|
|
3963
|
+
* Clears all entities from the collection.
|
|
3964
|
+
*/
|
|
3741
3965
|
clear() {
|
|
3742
3966
|
for (const entity of [...this.items]) {
|
|
3743
3967
|
this.remove(entity);
|
|
@@ -3754,6 +3978,10 @@ var DefaultHasManyCollection = class {
|
|
|
3754
3978
|
this.items = rows.map((row) => this.createEntity(row));
|
|
3755
3979
|
this.loaded = true;
|
|
3756
3980
|
}
|
|
3981
|
+
/**
|
|
3982
|
+
* Returns the items for JSON serialization.
|
|
3983
|
+
* @returns Array of child entities
|
|
3984
|
+
*/
|
|
3757
3985
|
toJSON() {
|
|
3758
3986
|
return this.items;
|
|
3759
3987
|
}
|
|
@@ -4049,7 +4277,6 @@ var DefaultManyToManyCollection = class {
|
|
|
4049
4277
|
}
|
|
4050
4278
|
async syncByIds(ids) {
|
|
4051
4279
|
await this.load();
|
|
4052
|
-
const targetKey = this.relation.targetKey || findPrimaryKey(this.relation.target);
|
|
4053
4280
|
const normalized = new Set(ids.map((id) => toKey5(id)));
|
|
4054
4281
|
const currentIds = new Set(this.items.map((item) => toKey5(this.extractId(item))));
|
|
4055
4282
|
for (const id of normalized) {
|
|
@@ -4130,112 +4357,92 @@ var executeQuery = async (ctx, qb) => {
|
|
|
4130
4357
|
return rowsFromResults(results);
|
|
4131
4358
|
};
|
|
4132
4359
|
var toKey6 = (value) => value === null || value === void 0 ? "" : String(value);
|
|
4133
|
-
var
|
|
4134
|
-
const
|
|
4135
|
-
const roots = ctx.getEntitiesForTable(rootTable);
|
|
4136
|
-
const keys = /* @__PURE__ */ new Set();
|
|
4360
|
+
var collectKeysFromRoots = (roots, key) => {
|
|
4361
|
+
const collected = /* @__PURE__ */ new Set();
|
|
4137
4362
|
for (const tracked of roots) {
|
|
4138
|
-
const value = tracked.entity[
|
|
4363
|
+
const value = tracked.entity[key];
|
|
4139
4364
|
if (value !== null && value !== void 0) {
|
|
4140
|
-
|
|
4365
|
+
collected.add(value);
|
|
4141
4366
|
}
|
|
4142
4367
|
}
|
|
4143
|
-
|
|
4144
|
-
|
|
4145
|
-
|
|
4146
|
-
|
|
4147
|
-
const
|
|
4148
|
-
|
|
4149
|
-
|
|
4150
|
-
|
|
4151
|
-
|
|
4368
|
+
return collected;
|
|
4369
|
+
};
|
|
4370
|
+
var buildInListValues = (keys) => Array.from(keys);
|
|
4371
|
+
var fetchRowsForKeys = async (ctx, table, column, keys) => {
|
|
4372
|
+
const qb = new SelectQueryBuilder(table).select(selectAllColumns(table));
|
|
4373
|
+
qb.where(inList(column, buildInListValues(keys)));
|
|
4374
|
+
return executeQuery(ctx, qb);
|
|
4375
|
+
};
|
|
4376
|
+
var groupRowsByMany = (rows, keyColumn) => {
|
|
4152
4377
|
const grouped = /* @__PURE__ */ new Map();
|
|
4153
4378
|
for (const row of rows) {
|
|
4154
|
-
const
|
|
4155
|
-
if (
|
|
4156
|
-
const key = toKey6(
|
|
4379
|
+
const value = row[keyColumn];
|
|
4380
|
+
if (value === null || value === void 0) continue;
|
|
4381
|
+
const key = toKey6(value);
|
|
4157
4382
|
const bucket = grouped.get(key) ?? [];
|
|
4158
4383
|
bucket.push(row);
|
|
4159
4384
|
grouped.set(key, bucket);
|
|
4160
4385
|
}
|
|
4161
4386
|
return grouped;
|
|
4162
4387
|
};
|
|
4163
|
-
var
|
|
4164
|
-
const
|
|
4165
|
-
const
|
|
4166
|
-
|
|
4167
|
-
|
|
4168
|
-
const
|
|
4169
|
-
if (
|
|
4170
|
-
|
|
4388
|
+
var groupRowsByUnique = (rows, keyColumn) => {
|
|
4389
|
+
const lookup = /* @__PURE__ */ new Map();
|
|
4390
|
+
for (const row of rows) {
|
|
4391
|
+
const value = row[keyColumn];
|
|
4392
|
+
if (value === null || value === void 0) continue;
|
|
4393
|
+
const key = toKey6(value);
|
|
4394
|
+
if (!lookup.has(key)) {
|
|
4395
|
+
lookup.set(key, row);
|
|
4171
4396
|
}
|
|
4172
4397
|
}
|
|
4398
|
+
return lookup;
|
|
4399
|
+
};
|
|
4400
|
+
var loadHasManyRelation = async (ctx, rootTable, _relationName, relation) => {
|
|
4401
|
+
const localKey = relation.localKey || findPrimaryKey(rootTable);
|
|
4402
|
+
const roots = ctx.getEntitiesForTable(rootTable);
|
|
4403
|
+
const keys = collectKeysFromRoots(roots, localKey);
|
|
4173
4404
|
if (!keys.size) {
|
|
4174
4405
|
return /* @__PURE__ */ new Map();
|
|
4175
4406
|
}
|
|
4176
|
-
const selectMap = selectAllColumns(relation.target);
|
|
4177
|
-
const qb = new SelectQueryBuilder(relation.target).select(selectMap);
|
|
4178
4407
|
const fkColumn = relation.target.columns[relation.foreignKey];
|
|
4179
4408
|
if (!fkColumn) return /* @__PURE__ */ new Map();
|
|
4180
|
-
|
|
4181
|
-
|
|
4182
|
-
|
|
4183
|
-
|
|
4184
|
-
|
|
4185
|
-
|
|
4186
|
-
|
|
4187
|
-
|
|
4188
|
-
|
|
4189
|
-
}
|
|
4409
|
+
const rows = await fetchRowsForKeys(ctx, relation.target, fkColumn, keys);
|
|
4410
|
+
return groupRowsByMany(rows, relation.foreignKey);
|
|
4411
|
+
};
|
|
4412
|
+
var loadHasOneRelation = async (ctx, rootTable, _relationName, relation) => {
|
|
4413
|
+
const localKey = relation.localKey || findPrimaryKey(rootTable);
|
|
4414
|
+
const roots = ctx.getEntitiesForTable(rootTable);
|
|
4415
|
+
const keys = collectKeysFromRoots(roots, localKey);
|
|
4416
|
+
if (!keys.size) {
|
|
4417
|
+
return /* @__PURE__ */ new Map();
|
|
4190
4418
|
}
|
|
4191
|
-
|
|
4419
|
+
const fkColumn = relation.target.columns[relation.foreignKey];
|
|
4420
|
+
if (!fkColumn) return /* @__PURE__ */ new Map();
|
|
4421
|
+
const rows = await fetchRowsForKeys(ctx, relation.target, fkColumn, keys);
|
|
4422
|
+
return groupRowsByUnique(rows, relation.foreignKey);
|
|
4192
4423
|
};
|
|
4193
4424
|
var loadBelongsToRelation = async (ctx, rootTable, _relationName, relation) => {
|
|
4194
4425
|
const roots = ctx.getEntitiesForTable(rootTable);
|
|
4195
|
-
const foreignKeys =
|
|
4196
|
-
for (const tracked of roots) {
|
|
4197
|
-
const value = tracked.entity[relation.foreignKey];
|
|
4198
|
-
if (value !== null && value !== void 0) {
|
|
4199
|
-
foreignKeys.add(value);
|
|
4200
|
-
}
|
|
4201
|
-
}
|
|
4426
|
+
const foreignKeys = collectKeysFromRoots(roots, relation.foreignKey);
|
|
4202
4427
|
if (!foreignKeys.size) {
|
|
4203
4428
|
return /* @__PURE__ */ new Map();
|
|
4204
4429
|
}
|
|
4205
|
-
const selectMap = selectAllColumns(relation.target);
|
|
4206
|
-
const qb = new SelectQueryBuilder(relation.target).select(selectMap);
|
|
4207
4430
|
const targetKey = relation.localKey || findPrimaryKey(relation.target);
|
|
4208
4431
|
const pkColumn = relation.target.columns[targetKey];
|
|
4209
4432
|
if (!pkColumn) return /* @__PURE__ */ new Map();
|
|
4210
|
-
|
|
4211
|
-
|
|
4212
|
-
const map = /* @__PURE__ */ new Map();
|
|
4213
|
-
for (const row of rows) {
|
|
4214
|
-
const keyValue = row[targetKey];
|
|
4215
|
-
if (keyValue === null || keyValue === void 0) continue;
|
|
4216
|
-
map.set(toKey6(keyValue), row);
|
|
4217
|
-
}
|
|
4218
|
-
return map;
|
|
4433
|
+
const rows = await fetchRowsForKeys(ctx, relation.target, pkColumn, foreignKeys);
|
|
4434
|
+
return groupRowsByUnique(rows, targetKey);
|
|
4219
4435
|
};
|
|
4220
4436
|
var loadBelongsToManyRelation = async (ctx, rootTable, _relationName, relation) => {
|
|
4221
4437
|
const rootKey = relation.localKey || findPrimaryKey(rootTable);
|
|
4222
4438
|
const roots = ctx.getEntitiesForTable(rootTable);
|
|
4223
|
-
const rootIds =
|
|
4224
|
-
for (const tracked of roots) {
|
|
4225
|
-
const value = tracked.entity[rootKey];
|
|
4226
|
-
if (value !== null && value !== void 0) {
|
|
4227
|
-
rootIds.add(value);
|
|
4228
|
-
}
|
|
4229
|
-
}
|
|
4439
|
+
const rootIds = collectKeysFromRoots(roots, rootKey);
|
|
4230
4440
|
if (!rootIds.size) {
|
|
4231
4441
|
return /* @__PURE__ */ new Map();
|
|
4232
4442
|
}
|
|
4233
|
-
const
|
|
4234
|
-
|
|
4235
|
-
const
|
|
4236
|
-
if (!pivotFkCol) return /* @__PURE__ */ new Map();
|
|
4237
|
-
pivotQb.where(inList(pivotFkCol, Array.from(rootIds)));
|
|
4238
|
-
const pivotRows = await executeQuery(ctx, pivotQb);
|
|
4443
|
+
const pivotColumn = relation.pivotTable.columns[relation.pivotForeignKeyToRoot];
|
|
4444
|
+
if (!pivotColumn) return /* @__PURE__ */ new Map();
|
|
4445
|
+
const pivotRows = await fetchRowsForKeys(ctx, relation.pivotTable, pivotColumn, rootIds);
|
|
4239
4446
|
const rootLookup = /* @__PURE__ */ new Map();
|
|
4240
4447
|
const targetIds = /* @__PURE__ */ new Set();
|
|
4241
4448
|
for (const pivot of pivotRows) {
|
|
@@ -4255,19 +4462,11 @@ var loadBelongsToManyRelation = async (ctx, rootTable, _relationName, relation)
|
|
|
4255
4462
|
if (!targetIds.size) {
|
|
4256
4463
|
return /* @__PURE__ */ new Map();
|
|
4257
4464
|
}
|
|
4258
|
-
const targetSelect = selectAllColumns(relation.target);
|
|
4259
4465
|
const targetKey = relation.targetKey || findPrimaryKey(relation.target);
|
|
4260
4466
|
const targetPkColumn = relation.target.columns[targetKey];
|
|
4261
4467
|
if (!targetPkColumn) return /* @__PURE__ */ new Map();
|
|
4262
|
-
const
|
|
4263
|
-
|
|
4264
|
-
const targetRows = await executeQuery(ctx, targetQb);
|
|
4265
|
-
const targetMap = /* @__PURE__ */ new Map();
|
|
4266
|
-
for (const row of targetRows) {
|
|
4267
|
-
const pkValue = row[targetKey];
|
|
4268
|
-
if (pkValue === null || pkValue === void 0) continue;
|
|
4269
|
-
targetMap.set(toKey6(pkValue), row);
|
|
4270
|
-
}
|
|
4468
|
+
const targetRows = await fetchRowsForKeys(ctx, relation.target, targetPkColumn, targetIds);
|
|
4469
|
+
const targetMap = groupRowsByUnique(targetRows, targetKey);
|
|
4271
4470
|
const result = /* @__PURE__ */ new Map();
|
|
4272
4471
|
for (const [rootId, entries] of rootLookup.entries()) {
|
|
4273
4472
|
const bucket = [];
|
|
@@ -4320,7 +4519,6 @@ var createEntityProxy = (ctx, table, row, lazyRelations = []) => {
|
|
|
4320
4519
|
enumerable: false,
|
|
4321
4520
|
writable: false
|
|
4322
4521
|
});
|
|
4323
|
-
let proxy;
|
|
4324
4522
|
const handler = {
|
|
4325
4523
|
get(targetObj, prop, receiver) {
|
|
4326
4524
|
if (prop === ENTITY_META) {
|
|
@@ -4328,7 +4526,7 @@ var createEntityProxy = (ctx, table, row, lazyRelations = []) => {
|
|
|
4328
4526
|
}
|
|
4329
4527
|
if (prop === "$load") {
|
|
4330
4528
|
return async (relationName) => {
|
|
4331
|
-
const wrapper = getRelationWrapper(meta, relationName,
|
|
4529
|
+
const wrapper = getRelationWrapper(meta, relationName, receiver);
|
|
4332
4530
|
if (wrapper && typeof wrapper.load === "function") {
|
|
4333
4531
|
return wrapper.load();
|
|
4334
4532
|
}
|
|
@@ -4336,19 +4534,19 @@ var createEntityProxy = (ctx, table, row, lazyRelations = []) => {
|
|
|
4336
4534
|
};
|
|
4337
4535
|
}
|
|
4338
4536
|
if (typeof prop === "string" && table.relations[prop]) {
|
|
4339
|
-
return getRelationWrapper(meta, prop,
|
|
4537
|
+
return getRelationWrapper(meta, prop, receiver);
|
|
4340
4538
|
}
|
|
4341
4539
|
return Reflect.get(targetObj, prop, receiver);
|
|
4342
4540
|
},
|
|
4343
4541
|
set(targetObj, prop, value, receiver) {
|
|
4344
4542
|
const result = Reflect.set(targetObj, prop, value, receiver);
|
|
4345
4543
|
if (typeof prop === "string" && table.columns[prop]) {
|
|
4346
|
-
ctx.markDirty(
|
|
4544
|
+
ctx.markDirty(receiver);
|
|
4347
4545
|
}
|
|
4348
4546
|
return result;
|
|
4349
4547
|
}
|
|
4350
4548
|
};
|
|
4351
|
-
proxy = new Proxy(target, handler);
|
|
4549
|
+
const proxy = new Proxy(target, handler);
|
|
4352
4550
|
populateHydrationCache(proxy, row, meta);
|
|
4353
4551
|
return proxy;
|
|
4354
4552
|
};
|
|
@@ -4545,21 +4743,21 @@ async function executeHydratedWithContexts(_execCtx, hydCtx, qb) {
|
|
|
4545
4743
|
return executeWithEntityContext(entityCtx, qb);
|
|
4546
4744
|
}
|
|
4547
4745
|
|
|
4746
|
+
// src/query-builder/query-resolution.ts
|
|
4747
|
+
function resolveSelectQuery(query) {
|
|
4748
|
+
const candidate = query;
|
|
4749
|
+
return typeof candidate.getAST === "function" && candidate.getAST ? candidate.getAST() : query;
|
|
4750
|
+
}
|
|
4751
|
+
|
|
4548
4752
|
// src/query-builder/select.ts
|
|
4549
4753
|
var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
4550
4754
|
/**
|
|
4551
|
-
|
|
4552
|
-
|
|
4553
|
-
|
|
4554
|
-
|
|
4555
|
-
|
|
4556
|
-
|
|
4557
|
-
|
|
4558
|
-
* @param hydration - Optional hydration manager
|
|
4559
|
-
|
|
4560
|
-
* @param dependencies - Optional query builder dependencies
|
|
4561
|
-
|
|
4562
|
-
*/
|
|
4755
|
+
* Creates a new SelectQueryBuilder instance
|
|
4756
|
+
* @param table - Table definition to query
|
|
4757
|
+
* @param state - Optional initial query state
|
|
4758
|
+
* @param hydration - Optional hydration manager
|
|
4759
|
+
* @param dependencies - Optional query builder dependencies
|
|
4760
|
+
*/
|
|
4563
4761
|
constructor(table, state, hydration, dependencies, lazyRelations) {
|
|
4564
4762
|
const deps = resolveSelectQueryBuilderDependencies(dependencies);
|
|
4565
4763
|
this.env = { table, deps };
|
|
@@ -4570,9 +4768,15 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
4570
4768
|
hydration: initialHydration
|
|
4571
4769
|
};
|
|
4572
4770
|
this.lazyRelations = new Set(lazyRelations ?? []);
|
|
4573
|
-
this.columnSelector =
|
|
4574
|
-
this.relationManager =
|
|
4771
|
+
this.columnSelector = deps.createColumnSelector(this.env);
|
|
4772
|
+
this.relationManager = deps.createRelationManager(this.env);
|
|
4575
4773
|
}
|
|
4774
|
+
/**
|
|
4775
|
+
* Creates a new SelectQueryBuilder instance with updated context and lazy relations
|
|
4776
|
+
* @param context - Updated query context
|
|
4777
|
+
* @param lazyRelations - Updated lazy relations set
|
|
4778
|
+
* @returns New SelectQueryBuilder instance
|
|
4779
|
+
*/
|
|
4576
4780
|
clone(context = this.context, lazyRelations = new Set(this.lazyRelations)) {
|
|
4577
4781
|
return new _SelectQueryBuilder(this.env.table, context.state, context.hydration, this.env.deps, lazyRelations);
|
|
4578
4782
|
}
|
|
@@ -4589,9 +4793,12 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
4589
4793
|
const nextContext = this.applyAst(this.context, (service) => service.withFrom(nextFrom));
|
|
4590
4794
|
return this.clone(nextContext);
|
|
4591
4795
|
}
|
|
4592
|
-
|
|
4593
|
-
|
|
4594
|
-
|
|
4796
|
+
/**
|
|
4797
|
+
* Applies correlation expression to the query AST
|
|
4798
|
+
* @param ast - Query AST to modify
|
|
4799
|
+
* @param correlation - Correlation expression
|
|
4800
|
+
* @returns Modified AST with correlation applied
|
|
4801
|
+
*/
|
|
4595
4802
|
applyCorrelation(ast, correlation) {
|
|
4596
4803
|
if (!correlation) return ast;
|
|
4597
4804
|
const combinedWhere = ast.where ? and(correlation, ast.where) : correlation;
|
|
@@ -4600,39 +4807,53 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
4600
4807
|
where: combinedWhere
|
|
4601
4808
|
};
|
|
4602
4809
|
}
|
|
4810
|
+
/**
|
|
4811
|
+
* Creates a new child query builder for a related table
|
|
4812
|
+
* @param table - Table definition for the child builder
|
|
4813
|
+
* @returns New SelectQueryBuilder instance for the child table
|
|
4814
|
+
*/
|
|
4603
4815
|
createChildBuilder(table) {
|
|
4604
4816
|
return new _SelectQueryBuilder(table, void 0, void 0, this.env.deps);
|
|
4605
4817
|
}
|
|
4818
|
+
/**
|
|
4819
|
+
* Applies an AST mutation using the query AST service
|
|
4820
|
+
* @param context - Current query context
|
|
4821
|
+
* @param mutator - Function that mutates the AST
|
|
4822
|
+
* @returns Updated query context
|
|
4823
|
+
*/
|
|
4606
4824
|
applyAst(context, mutator) {
|
|
4607
4825
|
const astService = this.env.deps.createQueryAstService(this.env.table, context.state);
|
|
4608
4826
|
const nextState = mutator(astService);
|
|
4609
4827
|
return { state: nextState, hydration: context.hydration };
|
|
4610
4828
|
}
|
|
4829
|
+
/**
|
|
4830
|
+
* Applies a join to the query context
|
|
4831
|
+
* @param context - Current query context
|
|
4832
|
+
* @param table - Table to join
|
|
4833
|
+
* @param condition - Join condition
|
|
4834
|
+
* @param kind - Join kind
|
|
4835
|
+
* @returns Updated query context with join applied
|
|
4836
|
+
*/
|
|
4611
4837
|
applyJoin(context, table, condition, kind) {
|
|
4612
|
-
const joinNode = createJoinNode(kind, table.name, condition);
|
|
4838
|
+
const joinNode = createJoinNode(kind, { type: "Table", name: table.name, schema: table.schema }, condition);
|
|
4613
4839
|
return this.applyAst(context, (service) => service.withJoin(joinNode));
|
|
4614
4840
|
}
|
|
4841
|
+
/**
|
|
4842
|
+
* Applies a set operation to the query
|
|
4843
|
+
* @param operator - Set operation kind
|
|
4844
|
+
* @param query - Query to combine with
|
|
4845
|
+
* @returns Updated query context with set operation
|
|
4846
|
+
*/
|
|
4615
4847
|
applySetOperation(operator, query) {
|
|
4616
|
-
const subAst =
|
|
4848
|
+
const subAst = resolveSelectQuery(query);
|
|
4617
4849
|
return this.applyAst(this.context, (service) => service.withSetOperation(operator, subAst));
|
|
4618
4850
|
}
|
|
4619
|
-
|
|
4620
|
-
|
|
4621
|
-
|
|
4622
|
-
|
|
4623
|
-
|
|
4624
|
-
|
|
4625
|
-
* @returns New query builder instance with selected columns
|
|
4626
|
-
|
|
4627
|
-
*/
|
|
4628
|
-
select(columns) {
|
|
4629
|
-
return this.clone(this.columnSelector.select(this.context, columns));
|
|
4630
|
-
}
|
|
4631
|
-
/**
|
|
4632
|
-
* Selects columns from the root table by name (typed).
|
|
4633
|
-
* @param cols - Column names on the root table
|
|
4634
|
-
*/
|
|
4635
|
-
selectColumns(...cols) {
|
|
4851
|
+
select(...args) {
|
|
4852
|
+
if (args.length === 1 && typeof args[0] === "object" && args[0] !== null && typeof args[0] !== "string") {
|
|
4853
|
+
const columns = args[0];
|
|
4854
|
+
return this.clone(this.columnSelector.select(this.context, columns));
|
|
4855
|
+
}
|
|
4856
|
+
const cols = args;
|
|
4636
4857
|
const selection = {};
|
|
4637
4858
|
for (const key of cols) {
|
|
4638
4859
|
const col2 = this.env.table.columns[key];
|
|
@@ -4641,53 +4862,37 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
4641
4862
|
}
|
|
4642
4863
|
selection[key] = col2;
|
|
4643
4864
|
}
|
|
4644
|
-
return this.select(selection);
|
|
4865
|
+
return this.clone(this.columnSelector.select(this.context, selection));
|
|
4645
4866
|
}
|
|
4646
4867
|
/**
|
|
4647
|
-
|
|
4648
|
-
|
|
4649
|
-
|
|
4650
|
-
|
|
4651
|
-
|
|
4652
|
-
* @returns New query builder instance with raw column selections
|
|
4653
|
-
|
|
4654
|
-
*/
|
|
4868
|
+
* Selects raw column expressions
|
|
4869
|
+
* @param cols - Column expressions as strings
|
|
4870
|
+
* @returns New query builder instance with raw column selections
|
|
4871
|
+
*/
|
|
4655
4872
|
selectRaw(...cols) {
|
|
4656
4873
|
return this.clone(this.columnSelector.selectRaw(this.context, cols));
|
|
4657
4874
|
}
|
|
4658
4875
|
/**
|
|
4659
|
-
|
|
4660
|
-
|
|
4661
|
-
|
|
4662
|
-
|
|
4663
|
-
|
|
4664
|
-
|
|
4665
|
-
|
|
4666
|
-
* @param columns - Optional column names for the CTE
|
|
4667
|
-
|
|
4668
|
-
* @returns New query builder instance with the CTE
|
|
4669
|
-
|
|
4670
|
-
*/
|
|
4876
|
+
* Adds a Common Table Expression (CTE) to the query
|
|
4877
|
+
* @param name - Name of the CTE
|
|
4878
|
+
* @param query - Query builder or query node for the CTE
|
|
4879
|
+
* @param columns - Optional column names for the CTE
|
|
4880
|
+
* @returns New query builder instance with the CTE
|
|
4881
|
+
*/
|
|
4671
4882
|
with(name, query, columns) {
|
|
4672
|
-
const subAst =
|
|
4883
|
+
const subAst = resolveSelectQuery(query);
|
|
4673
4884
|
const nextContext = this.applyAst(this.context, (service) => service.withCte(name, subAst, columns, false));
|
|
4674
4885
|
return this.clone(nextContext);
|
|
4675
4886
|
}
|
|
4676
4887
|
/**
|
|
4677
|
-
|
|
4678
|
-
|
|
4679
|
-
|
|
4680
|
-
|
|
4681
|
-
|
|
4682
|
-
|
|
4683
|
-
|
|
4684
|
-
* @param columns - Optional column names for the CTE
|
|
4685
|
-
|
|
4686
|
-
* @returns New query builder instance with the recursive CTE
|
|
4687
|
-
|
|
4688
|
-
*/
|
|
4888
|
+
* Adds a recursive Common Table Expression (CTE) to the query
|
|
4889
|
+
* @param name - Name of the CTE
|
|
4890
|
+
* @param query - Query builder or query node for the CTE
|
|
4891
|
+
* @param columns - Optional column names for the CTE
|
|
4892
|
+
* @returns New query builder instance with the recursive CTE
|
|
4893
|
+
*/
|
|
4689
4894
|
withRecursive(name, query, columns) {
|
|
4690
|
-
const subAst =
|
|
4895
|
+
const subAst = resolveSelectQuery(query);
|
|
4691
4896
|
const nextContext = this.applyAst(this.context, (service) => service.withCte(name, subAst, columns, true));
|
|
4692
4897
|
return this.clone(nextContext);
|
|
4693
4898
|
}
|
|
@@ -4699,24 +4904,31 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
4699
4904
|
* @returns New query builder instance with updated FROM
|
|
4700
4905
|
*/
|
|
4701
4906
|
fromSubquery(subquery, alias, columnAliases) {
|
|
4702
|
-
const subAst =
|
|
4907
|
+
const subAst = resolveSelectQuery(subquery);
|
|
4703
4908
|
const fromNode = derivedTable(subAst, alias, columnAliases);
|
|
4704
4909
|
const nextContext = this.applyAst(this.context, (service) => service.withFrom(fromNode));
|
|
4705
4910
|
return this.clone(nextContext);
|
|
4706
4911
|
}
|
|
4707
4912
|
/**
|
|
4708
|
-
|
|
4709
|
-
|
|
4710
|
-
|
|
4711
|
-
|
|
4712
|
-
|
|
4713
|
-
|
|
4714
|
-
|
|
4715
|
-
|
|
4716
|
-
|
|
4717
|
-
|
|
4913
|
+
* Replaces the FROM clause with a function table expression.
|
|
4914
|
+
* @param name - Function name
|
|
4915
|
+
* @param args - Optional function arguments
|
|
4916
|
+
* @param alias - Optional alias for the function table
|
|
4917
|
+
* @param options - Optional function-table metadata (lateral, ordinality, column aliases, schema)
|
|
4918
|
+
*/
|
|
4919
|
+
fromFunctionTable(name, args = [], alias, options) {
|
|
4920
|
+
const functionTable = fnTable(name, args, alias, options);
|
|
4921
|
+
const nextContext = this.applyAst(this.context, (service) => service.withFrom(functionTable));
|
|
4922
|
+
return this.clone(nextContext);
|
|
4923
|
+
}
|
|
4924
|
+
/**
|
|
4925
|
+
* Selects a subquery as a column
|
|
4926
|
+
* @param alias - Alias for the subquery column
|
|
4927
|
+
* @param sub - Query builder or query node for the subquery
|
|
4928
|
+
* @returns New query builder instance with the subquery selection
|
|
4929
|
+
*/
|
|
4718
4930
|
selectSubquery(alias, sub2) {
|
|
4719
|
-
const query =
|
|
4931
|
+
const query = resolveSelectQuery(sub2);
|
|
4720
4932
|
return this.clone(this.columnSelector.selectSubquery(this.context, alias, query));
|
|
4721
4933
|
}
|
|
4722
4934
|
/**
|
|
@@ -4729,103 +4941,92 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
4729
4941
|
* @returns New query builder instance with the derived-table join
|
|
4730
4942
|
*/
|
|
4731
4943
|
joinSubquery(subquery, alias, condition, joinKind = JOIN_KINDS.INNER, columnAliases) {
|
|
4732
|
-
const subAst =
|
|
4944
|
+
const subAst = resolveSelectQuery(subquery);
|
|
4733
4945
|
const joinNode = createJoinNode(joinKind, derivedTable(subAst, alias, columnAliases), condition);
|
|
4734
4946
|
const nextContext = this.applyAst(this.context, (service) => service.withJoin(joinNode));
|
|
4735
4947
|
return this.clone(nextContext);
|
|
4736
4948
|
}
|
|
4737
4949
|
/**
|
|
4738
|
-
|
|
4739
|
-
|
|
4740
|
-
|
|
4741
|
-
|
|
4742
|
-
|
|
4743
|
-
|
|
4744
|
-
|
|
4745
|
-
|
|
4746
|
-
|
|
4747
|
-
|
|
4950
|
+
* Adds a join against a function table (e.g., `generate_series`) using `fnTable` internally.
|
|
4951
|
+
* @param name - Function name
|
|
4952
|
+
* @param args - Optional arguments passed to the function
|
|
4953
|
+
* @param alias - Alias for the function table so columns can be referenced
|
|
4954
|
+
* @param condition - Join condition expression
|
|
4955
|
+
* @param joinKind - Kind of join (defaults to INNER)
|
|
4956
|
+
* @param options - Optional metadata (lateral, ordinality, column aliases, schema)
|
|
4957
|
+
*/
|
|
4958
|
+
joinFunctionTable(name, args = [], alias, condition, joinKind = JOIN_KINDS.INNER, options) {
|
|
4959
|
+
const functionTable = fnTable(name, args, alias, options);
|
|
4960
|
+
const joinNode = createJoinNode(joinKind, functionTable, condition);
|
|
4961
|
+
const nextContext = this.applyAst(this.context, (service) => service.withJoin(joinNode));
|
|
4962
|
+
return this.clone(nextContext);
|
|
4963
|
+
}
|
|
4964
|
+
/**
|
|
4965
|
+
* Adds an INNER JOIN to the query
|
|
4966
|
+
* @param table - Table to join
|
|
4967
|
+
* @param condition - Join condition expression
|
|
4968
|
+
* @returns New query builder instance with the INNER JOIN
|
|
4969
|
+
*/
|
|
4748
4970
|
innerJoin(table, condition) {
|
|
4749
4971
|
const nextContext = this.applyJoin(this.context, table, condition, JOIN_KINDS.INNER);
|
|
4750
4972
|
return this.clone(nextContext);
|
|
4751
4973
|
}
|
|
4752
4974
|
/**
|
|
4753
|
-
|
|
4754
|
-
|
|
4755
|
-
|
|
4756
|
-
|
|
4757
|
-
|
|
4758
|
-
* @param condition - Join condition expression
|
|
4759
|
-
|
|
4760
|
-
* @returns New query builder instance with the LEFT JOIN
|
|
4761
|
-
|
|
4762
|
-
*/
|
|
4975
|
+
* Adds a LEFT JOIN to the query
|
|
4976
|
+
* @param table - Table to join
|
|
4977
|
+
* @param condition - Join condition expression
|
|
4978
|
+
* @returns New query builder instance with the LEFT JOIN
|
|
4979
|
+
*/
|
|
4763
4980
|
leftJoin(table, condition) {
|
|
4764
4981
|
const nextContext = this.applyJoin(this.context, table, condition, JOIN_KINDS.LEFT);
|
|
4765
4982
|
return this.clone(nextContext);
|
|
4766
4983
|
}
|
|
4767
4984
|
/**
|
|
4768
|
-
|
|
4769
|
-
|
|
4770
|
-
|
|
4771
|
-
|
|
4772
|
-
|
|
4773
|
-
* @param condition - Join condition expression
|
|
4774
|
-
|
|
4775
|
-
* @returns New query builder instance with the RIGHT JOIN
|
|
4776
|
-
|
|
4777
|
-
*/
|
|
4985
|
+
* Adds a RIGHT JOIN to the query
|
|
4986
|
+
* @param table - Table to join
|
|
4987
|
+
* @param condition - Join condition expression
|
|
4988
|
+
* @returns New query builder instance with the RIGHT JOIN
|
|
4989
|
+
*/
|
|
4778
4990
|
rightJoin(table, condition) {
|
|
4779
4991
|
const nextContext = this.applyJoin(this.context, table, condition, JOIN_KINDS.RIGHT);
|
|
4780
4992
|
return this.clone(nextContext);
|
|
4781
4993
|
}
|
|
4782
4994
|
/**
|
|
4783
|
-
|
|
4784
|
-
|
|
4785
|
-
|
|
4786
|
-
|
|
4787
|
-
|
|
4788
|
-
* @param predicate - Optional predicate expression
|
|
4789
|
-
|
|
4790
|
-
* @returns New query builder instance with the relationship match
|
|
4791
|
-
|
|
4792
|
-
*/
|
|
4995
|
+
* Matches records based on a relationship
|
|
4996
|
+
* @param relationName - Name of the relationship to match
|
|
4997
|
+
* @param predicate - Optional predicate expression
|
|
4998
|
+
* @returns New query builder instance with the relationship match
|
|
4999
|
+
*/
|
|
4793
5000
|
match(relationName, predicate) {
|
|
4794
5001
|
const nextContext = this.relationManager.match(this.context, relationName, predicate);
|
|
4795
5002
|
return this.clone(nextContext);
|
|
4796
5003
|
}
|
|
4797
5004
|
/**
|
|
4798
|
-
|
|
4799
|
-
|
|
4800
|
-
|
|
4801
|
-
|
|
4802
|
-
|
|
4803
|
-
|
|
4804
|
-
|
|
4805
|
-
* @param extraCondition - Optional additional join condition
|
|
4806
|
-
|
|
4807
|
-
* @returns New query builder instance with the relationship join
|
|
4808
|
-
|
|
4809
|
-
*/
|
|
5005
|
+
* Joins a related table
|
|
5006
|
+
* @param relationName - Name of the relationship to join
|
|
5007
|
+
* @param joinKind - Type of join (defaults to INNER)
|
|
5008
|
+
* @param extraCondition - Optional additional join condition
|
|
5009
|
+
* @returns New query builder instance with the relationship join
|
|
5010
|
+
*/
|
|
4810
5011
|
joinRelation(relationName, joinKind = JOIN_KINDS.INNER, extraCondition) {
|
|
4811
5012
|
const nextContext = this.relationManager.joinRelation(this.context, relationName, joinKind, extraCondition);
|
|
4812
5013
|
return this.clone(nextContext);
|
|
4813
5014
|
}
|
|
4814
5015
|
/**
|
|
4815
|
-
|
|
4816
|
-
|
|
4817
|
-
|
|
4818
|
-
|
|
4819
|
-
|
|
4820
|
-
* @param options - Optional include options
|
|
4821
|
-
|
|
4822
|
-
* @returns New query builder instance with the relationship inclusion
|
|
4823
|
-
|
|
4824
|
-
*/
|
|
5016
|
+
* Includes related data in the query results
|
|
5017
|
+
* @param relationName - Name of the relationship to include
|
|
5018
|
+
* @param options - Optional include options
|
|
5019
|
+
* @returns New query builder instance with the relationship inclusion
|
|
5020
|
+
*/
|
|
4825
5021
|
include(relationName, options) {
|
|
4826
5022
|
const nextContext = this.relationManager.include(this.context, relationName, options);
|
|
4827
5023
|
return this.clone(nextContext);
|
|
4828
5024
|
}
|
|
5025
|
+
/**
|
|
5026
|
+
* Includes a relation lazily in the query results
|
|
5027
|
+
* @param relationName - Name of the relation to include lazily
|
|
5028
|
+
* @returns New query builder instance with lazy relation inclusion
|
|
5029
|
+
*/
|
|
4829
5030
|
includeLazy(relationName) {
|
|
4830
5031
|
const nextLazy = new Set(this.lazyRelations);
|
|
4831
5032
|
nextLazy.add(relationName);
|
|
@@ -4856,43 +5057,57 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
4856
5057
|
return this.selectRelationColumns(relationName, ...cols);
|
|
4857
5058
|
}
|
|
4858
5059
|
/**
|
|
4859
|
-
* Selects columns for the root table and relations from
|
|
5060
|
+
* Selects columns for the root table and relations from an array of entries
|
|
5061
|
+
* @param config - Configuration array for deep column selection
|
|
5062
|
+
* @returns New query builder instance with deep column selections
|
|
4860
5063
|
*/
|
|
4861
5064
|
selectColumnsDeep(config) {
|
|
4862
|
-
let
|
|
4863
|
-
|
|
4864
|
-
|
|
4865
|
-
|
|
4866
|
-
|
|
4867
|
-
|
|
4868
|
-
|
|
4869
|
-
const cols = config[relName];
|
|
4870
|
-
if (!cols || !cols.length) continue;
|
|
4871
|
-
qb = qb.selectRelationColumns(relName, ...cols);
|
|
5065
|
+
let currBuilder = this;
|
|
5066
|
+
for (const entry of config) {
|
|
5067
|
+
if (entry.type === "root") {
|
|
5068
|
+
currBuilder = currBuilder.select(...entry.columns);
|
|
5069
|
+
} else {
|
|
5070
|
+
currBuilder = currBuilder.selectRelationColumns(entry.relationName, ...entry.columns);
|
|
5071
|
+
}
|
|
4872
5072
|
}
|
|
4873
|
-
return
|
|
5073
|
+
return currBuilder;
|
|
4874
5074
|
}
|
|
5075
|
+
/**
|
|
5076
|
+
* Gets the list of lazy relations
|
|
5077
|
+
* @returns Array of lazy relation names
|
|
5078
|
+
*/
|
|
4875
5079
|
getLazyRelations() {
|
|
4876
5080
|
return Array.from(this.lazyRelations);
|
|
4877
5081
|
}
|
|
5082
|
+
/**
|
|
5083
|
+
* Gets the table definition for this query builder
|
|
5084
|
+
* @returns Table definition
|
|
5085
|
+
*/
|
|
4878
5086
|
getTable() {
|
|
4879
5087
|
return this.env.table;
|
|
4880
5088
|
}
|
|
5089
|
+
/**
|
|
5090
|
+
* Executes the query and returns hydrated results
|
|
5091
|
+
* @param ctx - ORM session context
|
|
5092
|
+
* @returns Promise of entity instances
|
|
5093
|
+
*/
|
|
4881
5094
|
async execute(ctx) {
|
|
4882
5095
|
return executeHydrated(ctx, this);
|
|
4883
5096
|
}
|
|
5097
|
+
/**
|
|
5098
|
+
* Executes the query with provided execution and hydration contexts
|
|
5099
|
+
* @param execCtx - Execution context
|
|
5100
|
+
* @param hydCtx - Hydration context
|
|
5101
|
+
* @returns Promise of entity instances
|
|
5102
|
+
*/
|
|
4884
5103
|
async executeWithContexts(execCtx, hydCtx) {
|
|
4885
5104
|
return executeHydratedWithContexts(execCtx, hydCtx, this);
|
|
4886
5105
|
}
|
|
4887
5106
|
/**
|
|
4888
|
-
|
|
4889
|
-
|
|
4890
|
-
|
|
4891
|
-
|
|
4892
|
-
|
|
4893
|
-
* @returns New query builder instance with the WHERE condition
|
|
4894
|
-
|
|
4895
|
-
*/
|
|
5107
|
+
* Adds a WHERE condition to the query
|
|
5108
|
+
* @param expr - Expression for the WHERE clause
|
|
5109
|
+
* @returns New query builder instance with the WHERE condition
|
|
5110
|
+
*/
|
|
4896
5111
|
where(expr) {
|
|
4897
5112
|
const nextContext = this.applyAst(this.context, (service) => service.withWhere(expr));
|
|
4898
5113
|
return this.clone(nextContext);
|
|
@@ -4907,14 +5122,10 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
4907
5122
|
return this.clone(nextContext);
|
|
4908
5123
|
}
|
|
4909
5124
|
/**
|
|
4910
|
-
|
|
4911
|
-
|
|
4912
|
-
|
|
4913
|
-
|
|
4914
|
-
|
|
4915
|
-
* @returns New query builder instance with the HAVING condition
|
|
4916
|
-
|
|
4917
|
-
*/
|
|
5125
|
+
* Adds a HAVING condition to the query
|
|
5126
|
+
* @param expr - Expression for the HAVING clause
|
|
5127
|
+
* @returns New query builder instance with the HAVING condition
|
|
5128
|
+
*/
|
|
4918
5129
|
having(expr) {
|
|
4919
5130
|
const nextContext = this.applyAst(this.context, (service) => service.withHaving(expr));
|
|
4920
5131
|
return this.clone(nextContext);
|
|
@@ -4935,130 +5146,89 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
4935
5146
|
return this.clone(nextContext);
|
|
4936
5147
|
}
|
|
4937
5148
|
/**
|
|
4938
|
-
|
|
4939
|
-
|
|
4940
|
-
|
|
4941
|
-
|
|
4942
|
-
|
|
4943
|
-
* @returns New query builder instance with the DISTINCT clause
|
|
4944
|
-
|
|
4945
|
-
*/
|
|
5149
|
+
* Adds a DISTINCT clause to the query
|
|
5150
|
+
* @param cols - Columns to make distinct
|
|
5151
|
+
* @returns New query builder instance with the DISTINCT clause
|
|
5152
|
+
*/
|
|
4946
5153
|
distinct(...cols) {
|
|
4947
5154
|
return this.clone(this.columnSelector.distinct(this.context, cols));
|
|
4948
5155
|
}
|
|
4949
5156
|
/**
|
|
4950
|
-
|
|
4951
|
-
|
|
4952
|
-
|
|
4953
|
-
|
|
4954
|
-
|
|
4955
|
-
* @returns New query builder instance with the LIMIT clause
|
|
4956
|
-
|
|
4957
|
-
*/
|
|
5157
|
+
* Adds a LIMIT clause to the query
|
|
5158
|
+
* @param n - Maximum number of rows to return
|
|
5159
|
+
* @returns New query builder instance with the LIMIT clause
|
|
5160
|
+
*/
|
|
4958
5161
|
limit(n) {
|
|
4959
5162
|
const nextContext = this.applyAst(this.context, (service) => service.withLimit(n));
|
|
4960
5163
|
return this.clone(nextContext);
|
|
4961
5164
|
}
|
|
4962
5165
|
/**
|
|
4963
|
-
|
|
4964
|
-
|
|
4965
|
-
|
|
4966
|
-
|
|
4967
|
-
|
|
4968
|
-
* @returns New query builder instance with the OFFSET clause
|
|
4969
|
-
|
|
4970
|
-
*/
|
|
5166
|
+
* Adds an OFFSET clause to the query
|
|
5167
|
+
* @param n - Number of rows to skip
|
|
5168
|
+
* @returns New query builder instance with the OFFSET clause
|
|
5169
|
+
*/
|
|
4971
5170
|
offset(n) {
|
|
4972
5171
|
const nextContext = this.applyAst(this.context, (service) => service.withOffset(n));
|
|
4973
5172
|
return this.clone(nextContext);
|
|
4974
5173
|
}
|
|
4975
5174
|
/**
|
|
4976
|
-
|
|
4977
|
-
|
|
4978
|
-
|
|
4979
|
-
|
|
4980
|
-
|
|
4981
|
-
* @returns New query builder instance with the set operation
|
|
4982
|
-
|
|
4983
|
-
*/
|
|
5175
|
+
* Combines this query with another using UNION
|
|
5176
|
+
* @param query - Query to union with
|
|
5177
|
+
* @returns New query builder instance with the set operation
|
|
5178
|
+
*/
|
|
4984
5179
|
union(query) {
|
|
4985
5180
|
return this.clone(this.applySetOperation("UNION", query));
|
|
4986
5181
|
}
|
|
4987
5182
|
/**
|
|
4988
|
-
|
|
4989
|
-
|
|
4990
|
-
|
|
4991
|
-
|
|
4992
|
-
|
|
4993
|
-
* @returns New query builder instance with the set operation
|
|
4994
|
-
|
|
4995
|
-
*/
|
|
5183
|
+
* Combines this query with another using UNION ALL
|
|
5184
|
+
* @param query - Query to union with
|
|
5185
|
+
* @returns New query builder instance with the set operation
|
|
5186
|
+
*/
|
|
4996
5187
|
unionAll(query) {
|
|
4997
5188
|
return this.clone(this.applySetOperation("UNION ALL", query));
|
|
4998
5189
|
}
|
|
4999
5190
|
/**
|
|
5000
|
-
|
|
5001
|
-
|
|
5002
|
-
|
|
5003
|
-
|
|
5004
|
-
|
|
5005
|
-
* @returns New query builder instance with the set operation
|
|
5006
|
-
|
|
5007
|
-
*/
|
|
5191
|
+
* Combines this query with another using INTERSECT
|
|
5192
|
+
* @param query - Query to intersect with
|
|
5193
|
+
* @returns New query builder instance with the set operation
|
|
5194
|
+
*/
|
|
5008
5195
|
intersect(query) {
|
|
5009
5196
|
return this.clone(this.applySetOperation("INTERSECT", query));
|
|
5010
5197
|
}
|
|
5011
5198
|
/**
|
|
5012
|
-
|
|
5013
|
-
|
|
5014
|
-
|
|
5015
|
-
|
|
5016
|
-
|
|
5017
|
-
* @returns New query builder instance with the set operation
|
|
5018
|
-
|
|
5019
|
-
*/
|
|
5199
|
+
* Combines this query with another using EXCEPT
|
|
5200
|
+
* @param query - Query to subtract
|
|
5201
|
+
* @returns New query builder instance with the set operation
|
|
5202
|
+
*/
|
|
5020
5203
|
except(query) {
|
|
5021
5204
|
return this.clone(this.applySetOperation("EXCEPT", query));
|
|
5022
5205
|
}
|
|
5023
5206
|
/**
|
|
5024
|
-
|
|
5025
|
-
|
|
5026
|
-
|
|
5027
|
-
|
|
5028
|
-
|
|
5029
|
-
* @returns New query builder instance with the WHERE EXISTS condition
|
|
5030
|
-
|
|
5031
|
-
*/
|
|
5207
|
+
* Adds a WHERE EXISTS condition to the query
|
|
5208
|
+
* @param subquery - Subquery to check for existence
|
|
5209
|
+
* @returns New query builder instance with the WHERE EXISTS condition
|
|
5210
|
+
*/
|
|
5032
5211
|
whereExists(subquery, correlate) {
|
|
5033
|
-
const subAst =
|
|
5212
|
+
const subAst = resolveSelectQuery(subquery);
|
|
5034
5213
|
const correlated = this.applyCorrelation(subAst, correlate);
|
|
5035
5214
|
return this.where(exists(correlated));
|
|
5036
5215
|
}
|
|
5037
5216
|
/**
|
|
5038
|
-
|
|
5039
|
-
|
|
5040
|
-
|
|
5041
|
-
|
|
5042
|
-
|
|
5043
|
-
* @returns New query builder instance with the WHERE NOT EXISTS condition
|
|
5044
|
-
|
|
5045
|
-
*/
|
|
5217
|
+
* Adds a WHERE NOT EXISTS condition to the query
|
|
5218
|
+
* @param subquery - Subquery to check for non-existence
|
|
5219
|
+
* @returns New query builder instance with the WHERE NOT EXISTS condition
|
|
5220
|
+
*/
|
|
5046
5221
|
whereNotExists(subquery, correlate) {
|
|
5047
|
-
const subAst =
|
|
5222
|
+
const subAst = resolveSelectQuery(subquery);
|
|
5048
5223
|
const correlated = this.applyCorrelation(subAst, correlate);
|
|
5049
5224
|
return this.where(notExists(correlated));
|
|
5050
5225
|
}
|
|
5051
5226
|
/**
|
|
5052
|
-
|
|
5053
|
-
|
|
5054
|
-
|
|
5055
|
-
|
|
5056
|
-
|
|
5057
|
-
* @param callback - Optional callback to modify the relationship query
|
|
5058
|
-
|
|
5059
|
-
* @returns New query builder instance with the relationship existence check
|
|
5060
|
-
|
|
5061
|
-
*/
|
|
5227
|
+
* Adds a WHERE EXISTS condition based on a relationship
|
|
5228
|
+
* @param relationName - Name of the relationship to check
|
|
5229
|
+
* @param callback - Optional callback to modify the relationship query
|
|
5230
|
+
* @returns New query builder instance with the relationship existence check
|
|
5231
|
+
*/
|
|
5062
5232
|
whereHas(relationName, callbackOrOptions, maybeOptions) {
|
|
5063
5233
|
const relation = this.env.table.relations[relationName];
|
|
5064
5234
|
if (!relation) {
|
|
@@ -5075,16 +5245,11 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
5075
5245
|
return this.where(exists(finalSubAst));
|
|
5076
5246
|
}
|
|
5077
5247
|
/**
|
|
5078
|
-
|
|
5079
|
-
|
|
5080
|
-
|
|
5081
|
-
|
|
5082
|
-
|
|
5083
|
-
* @param callback - Optional callback to modify the relationship query
|
|
5084
|
-
|
|
5085
|
-
* @returns New query builder instance with the relationship non-existence check
|
|
5086
|
-
|
|
5087
|
-
*/
|
|
5248
|
+
* Adds a WHERE NOT EXISTS condition based on a relationship
|
|
5249
|
+
* @param relationName - Name of the relationship to check
|
|
5250
|
+
* @param callback - Optional callback to modify the relationship query
|
|
5251
|
+
* @returns New query builder instance with the relationship non-existence check
|
|
5252
|
+
*/
|
|
5088
5253
|
whereHasNot(relationName, callbackOrOptions, maybeOptions) {
|
|
5089
5254
|
const relation = this.env.table.relations[relationName];
|
|
5090
5255
|
if (!relation) {
|
|
@@ -5101,53 +5266,61 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
5101
5266
|
return this.where(notExists(finalSubAst));
|
|
5102
5267
|
}
|
|
5103
5268
|
/**
|
|
5104
|
-
|
|
5105
|
-
|
|
5106
|
-
|
|
5107
|
-
|
|
5108
|
-
|
|
5109
|
-
* @returns Compiled query with SQL and parameters
|
|
5110
|
-
|
|
5111
|
-
*/
|
|
5269
|
+
* Compiles the query to SQL for a specific dialect
|
|
5270
|
+
* @param dialect - Database dialect to compile for
|
|
5271
|
+
* @returns Compiled query with SQL and parameters
|
|
5272
|
+
*/
|
|
5112
5273
|
compile(dialect) {
|
|
5113
5274
|
const resolved = resolveDialectInput(dialect);
|
|
5114
|
-
return resolved.compileSelect(this.
|
|
5275
|
+
return resolved.compileSelect(this.getAST());
|
|
5115
5276
|
}
|
|
5116
5277
|
/**
|
|
5117
|
-
|
|
5118
|
-
|
|
5119
|
-
|
|
5120
|
-
|
|
5121
|
-
|
|
5122
|
-
* @returns SQL string representation of the query
|
|
5123
|
-
|
|
5124
|
-
*/
|
|
5278
|
+
* Converts the query to SQL string for a specific dialect
|
|
5279
|
+
* @param dialect - Database dialect to generate SQL for
|
|
5280
|
+
* @returns SQL string representation of the query
|
|
5281
|
+
*/
|
|
5125
5282
|
toSql(dialect) {
|
|
5126
5283
|
return this.compile(dialect).sql;
|
|
5127
5284
|
}
|
|
5128
5285
|
/**
|
|
5129
|
-
|
|
5130
|
-
|
|
5131
|
-
|
|
5132
|
-
* @returns Hydration plan or undefined if none exists
|
|
5133
|
-
|
|
5134
|
-
*/
|
|
5286
|
+
* Gets the hydration plan for the query
|
|
5287
|
+
* @returns Hydration plan or undefined if none exists
|
|
5288
|
+
*/
|
|
5135
5289
|
getHydrationPlan() {
|
|
5136
5290
|
return this.context.hydration.getPlan();
|
|
5137
5291
|
}
|
|
5138
5292
|
/**
|
|
5139
|
-
|
|
5140
|
-
|
|
5141
|
-
|
|
5142
|
-
* @returns Query AST with hydration applied
|
|
5143
|
-
|
|
5144
|
-
*/
|
|
5293
|
+
* Gets the Abstract Syntax Tree (AST) representation of the query
|
|
5294
|
+
* @returns Query AST with hydration applied
|
|
5295
|
+
*/
|
|
5145
5296
|
getAST() {
|
|
5146
5297
|
return this.context.hydration.applyToAst(this.context.state.ast);
|
|
5147
5298
|
}
|
|
5148
5299
|
};
|
|
5149
|
-
|
|
5150
|
-
|
|
5300
|
+
|
|
5301
|
+
// src/schema/table-guards.ts
|
|
5302
|
+
var isColumnsRecord = (columns) => {
|
|
5303
|
+
return typeof columns === "object" && columns !== null;
|
|
5304
|
+
};
|
|
5305
|
+
var isRelationsRecord = (relations) => {
|
|
5306
|
+
return typeof relations === "object" && relations !== null;
|
|
5307
|
+
};
|
|
5308
|
+
var isTableDef = (value) => {
|
|
5309
|
+
if (typeof value !== "object" || value === null) {
|
|
5310
|
+
return false;
|
|
5311
|
+
}
|
|
5312
|
+
const candidate = value;
|
|
5313
|
+
if (typeof candidate.name !== "string") {
|
|
5314
|
+
return false;
|
|
5315
|
+
}
|
|
5316
|
+
if (!isColumnsRecord(candidate.columns)) {
|
|
5317
|
+
return false;
|
|
5318
|
+
}
|
|
5319
|
+
if (!isRelationsRecord(candidate.relations)) {
|
|
5320
|
+
return false;
|
|
5321
|
+
}
|
|
5322
|
+
return true;
|
|
5323
|
+
};
|
|
5151
5324
|
|
|
5152
5325
|
// src/orm/entity-metadata.ts
|
|
5153
5326
|
var metadataMap = /* @__PURE__ */ new Map();
|
|
@@ -5191,23 +5364,20 @@ var buildTableDef = (meta) => {
|
|
|
5191
5364
|
if (meta.table) {
|
|
5192
5365
|
return meta.table;
|
|
5193
5366
|
}
|
|
5194
|
-
const columns =
|
|
5195
|
-
|
|
5367
|
+
const columns = {};
|
|
5368
|
+
for (const [key, def] of Object.entries(meta.columns)) {
|
|
5369
|
+
columns[key] = {
|
|
5196
5370
|
...def,
|
|
5197
5371
|
name: key,
|
|
5198
5372
|
table: meta.tableName
|
|
5199
5373
|
};
|
|
5200
|
-
|
|
5201
|
-
}, {});
|
|
5374
|
+
}
|
|
5202
5375
|
const table = defineTable(meta.tableName, columns, {}, meta.hooks);
|
|
5203
5376
|
meta.table = table;
|
|
5204
5377
|
return table;
|
|
5205
5378
|
};
|
|
5206
5379
|
|
|
5207
5380
|
// src/decorators/bootstrap.ts
|
|
5208
|
-
var isTableDef = (value) => {
|
|
5209
|
-
return typeof value === "object" && value !== null && "columns" in value;
|
|
5210
|
-
};
|
|
5211
5381
|
var unwrapTarget = (target) => {
|
|
5212
5382
|
if (typeof target === "function" && target.prototype === void 0) {
|
|
5213
5383
|
return target();
|
|
@@ -5305,6 +5475,13 @@ var selectFromEntity = (ctor) => {
|
|
|
5305
5475
|
}
|
|
5306
5476
|
return new SelectQueryBuilder(table);
|
|
5307
5477
|
};
|
|
5478
|
+
var entityRef = (ctor) => {
|
|
5479
|
+
const table = getTableDefFromEntity(ctor);
|
|
5480
|
+
if (!table) {
|
|
5481
|
+
throw new Error(`Entity '${ctor.name}' is not registered with decorators or has not been bootstrapped`);
|
|
5482
|
+
}
|
|
5483
|
+
return tableRef(table);
|
|
5484
|
+
};
|
|
5308
5485
|
|
|
5309
5486
|
// src/query-builder/select-helpers.ts
|
|
5310
5487
|
function sel(table, ...cols) {
|
|
@@ -5336,6 +5513,11 @@ function esel(entity, ...props) {
|
|
|
5336
5513
|
|
|
5337
5514
|
// src/query-builder/insert-query-state.ts
|
|
5338
5515
|
var InsertQueryState = class _InsertQueryState {
|
|
5516
|
+
/**
|
|
5517
|
+
* Creates a new InsertQueryState instance
|
|
5518
|
+
* @param table - The table definition for the INSERT query
|
|
5519
|
+
* @param ast - Optional initial AST node, defaults to a basic INSERT query
|
|
5520
|
+
*/
|
|
5339
5521
|
constructor(table, ast) {
|
|
5340
5522
|
this.table = table;
|
|
5341
5523
|
this.ast = ast ?? {
|
|
@@ -5366,6 +5548,13 @@ var InsertQueryState = class _InsertQueryState {
|
|
|
5366
5548
|
if (!names.length) return [];
|
|
5367
5549
|
return buildColumnNodes(this.table, names);
|
|
5368
5550
|
}
|
|
5551
|
+
/**
|
|
5552
|
+
* Adds VALUES clause to the INSERT query
|
|
5553
|
+
* @param rows - Array of row objects to insert
|
|
5554
|
+
* @returns A new InsertQueryState with the VALUES clause added
|
|
5555
|
+
* @throws Error if mixing VALUES with SELECT source
|
|
5556
|
+
* @throws Error if invalid values are provided
|
|
5557
|
+
*/
|
|
5369
5558
|
withValues(rows) {
|
|
5370
5559
|
if (!rows.length) return this;
|
|
5371
5560
|
if (this.ast.source.type === "InsertSelect") {
|
|
@@ -5392,6 +5581,11 @@ var InsertQueryState = class _InsertQueryState {
|
|
|
5392
5581
|
}
|
|
5393
5582
|
});
|
|
5394
5583
|
}
|
|
5584
|
+
/**
|
|
5585
|
+
* Sets the columns for the INSERT query
|
|
5586
|
+
* @param columns - Column nodes to insert into
|
|
5587
|
+
* @returns A new InsertQueryState with the specified columns
|
|
5588
|
+
*/
|
|
5395
5589
|
withColumns(columns) {
|
|
5396
5590
|
if (!columns.length) return this;
|
|
5397
5591
|
return this.clone({
|
|
@@ -5399,6 +5593,14 @@ var InsertQueryState = class _InsertQueryState {
|
|
|
5399
5593
|
columns: [...columns]
|
|
5400
5594
|
});
|
|
5401
5595
|
}
|
|
5596
|
+
/**
|
|
5597
|
+
* Adds SELECT source to the INSERT query
|
|
5598
|
+
* @param query - The SELECT query to use as source
|
|
5599
|
+
* @param columns - Target columns for the INSERT
|
|
5600
|
+
* @returns A new InsertQueryState with the SELECT source
|
|
5601
|
+
* @throws Error if mixing SELECT with VALUES source
|
|
5602
|
+
* @throws Error if no destination columns specified
|
|
5603
|
+
*/
|
|
5402
5604
|
withSelect(query, columns) {
|
|
5403
5605
|
const targetColumns = columns.length ? columns : this.ast.columns.length ? this.ast.columns : this.getTableColumns();
|
|
5404
5606
|
if (!targetColumns.length) {
|
|
@@ -5416,6 +5618,11 @@ var InsertQueryState = class _InsertQueryState {
|
|
|
5416
5618
|
}
|
|
5417
5619
|
});
|
|
5418
5620
|
}
|
|
5621
|
+
/**
|
|
5622
|
+
* Adds a RETURNING clause to the INSERT query
|
|
5623
|
+
* @param columns - Columns to return after insertion
|
|
5624
|
+
* @returns A new InsertQueryState with the RETURNING clause added
|
|
5625
|
+
*/
|
|
5419
5626
|
withReturning(columns) {
|
|
5420
5627
|
return this.clone({
|
|
5421
5628
|
...this.ast,
|
|
@@ -5426,6 +5633,11 @@ var InsertQueryState = class _InsertQueryState {
|
|
|
5426
5633
|
|
|
5427
5634
|
// src/query-builder/insert.ts
|
|
5428
5635
|
var InsertQueryBuilder = class _InsertQueryBuilder {
|
|
5636
|
+
/**
|
|
5637
|
+
* Creates a new InsertQueryBuilder instance
|
|
5638
|
+
* @param table - The table definition for the INSERT query
|
|
5639
|
+
* @param state - Optional initial query state, defaults to a new InsertQueryState
|
|
5640
|
+
*/
|
|
5429
5641
|
constructor(table, state) {
|
|
5430
5642
|
this.table = table;
|
|
5431
5643
|
this.state = state ?? new InsertQueryState(table);
|
|
@@ -5433,20 +5645,42 @@ var InsertQueryBuilder = class _InsertQueryBuilder {
|
|
|
5433
5645
|
clone(state) {
|
|
5434
5646
|
return new _InsertQueryBuilder(this.table, state);
|
|
5435
5647
|
}
|
|
5648
|
+
/**
|
|
5649
|
+
* Adds VALUES to the INSERT query
|
|
5650
|
+
* @param rowOrRows - Single row object or array of row objects to insert
|
|
5651
|
+
* @returns A new InsertQueryBuilder with the VALUES clause added
|
|
5652
|
+
*/
|
|
5436
5653
|
values(rowOrRows) {
|
|
5437
5654
|
const rows = Array.isArray(rowOrRows) ? rowOrRows : [rowOrRows];
|
|
5438
5655
|
if (!rows.length) return this;
|
|
5439
5656
|
return this.clone(this.state.withValues(rows));
|
|
5440
5657
|
}
|
|
5658
|
+
/**
|
|
5659
|
+
* Specifies the columns for the INSERT query
|
|
5660
|
+
* @param columns - Column definitions or nodes to insert into
|
|
5661
|
+
* @returns A new InsertQueryBuilder with the specified columns
|
|
5662
|
+
*/
|
|
5441
5663
|
columns(...columns) {
|
|
5442
5664
|
if (!columns.length) return this;
|
|
5443
5665
|
return this.clone(this.state.withColumns(this.resolveColumnNodes(columns)));
|
|
5444
5666
|
}
|
|
5667
|
+
/**
|
|
5668
|
+
* Sets the source of the INSERT query to a SELECT query
|
|
5669
|
+
* @template TSource - The source table type
|
|
5670
|
+
* @param query - The SELECT query or query builder to use as source
|
|
5671
|
+
* @param columns - Optional target columns for the INSERT
|
|
5672
|
+
* @returns A new InsertQueryBuilder with the SELECT source
|
|
5673
|
+
*/
|
|
5445
5674
|
fromSelect(query, columns = []) {
|
|
5446
5675
|
const ast = this.resolveSelectQuery(query);
|
|
5447
5676
|
const nodes = columns.length ? this.resolveColumnNodes(columns) : [];
|
|
5448
5677
|
return this.clone(this.state.withSelect(ast, nodes));
|
|
5449
5678
|
}
|
|
5679
|
+
/**
|
|
5680
|
+
* Adds a RETURNING clause to the INSERT query
|
|
5681
|
+
* @param columns - Columns to return after insertion
|
|
5682
|
+
* @returns A new InsertQueryBuilder with the RETURNING clause added
|
|
5683
|
+
*/
|
|
5450
5684
|
returning(...columns) {
|
|
5451
5685
|
if (!columns.length) return this;
|
|
5452
5686
|
const nodes = columns.map((column) => buildColumnNode(this.table, column));
|
|
@@ -5457,18 +5691,29 @@ var InsertQueryBuilder = class _InsertQueryBuilder {
|
|
|
5457
5691
|
return columns.map((column) => buildColumnNode(this.table, column));
|
|
5458
5692
|
}
|
|
5459
5693
|
resolveSelectQuery(query) {
|
|
5460
|
-
|
|
5694
|
+
const candidate = query;
|
|
5695
|
+
return typeof candidate.getAST === "function" && candidate.getAST ? candidate.getAST() : query;
|
|
5461
5696
|
}
|
|
5462
5697
|
compile(arg) {
|
|
5463
|
-
|
|
5464
|
-
|
|
5698
|
+
const candidate = arg;
|
|
5699
|
+
if (typeof candidate.compileInsert === "function") {
|
|
5700
|
+
return candidate.compileInsert(this.state.ast);
|
|
5465
5701
|
}
|
|
5466
5702
|
const dialect = resolveDialectInput(arg);
|
|
5467
5703
|
return dialect.compileInsert(this.state.ast);
|
|
5468
5704
|
}
|
|
5705
|
+
/**
|
|
5706
|
+
* Returns the SQL string for the INSERT query
|
|
5707
|
+
* @param arg - The compiler or dialect to generate SQL for
|
|
5708
|
+
* @returns The SQL string representation of the query
|
|
5709
|
+
*/
|
|
5469
5710
|
toSql(arg) {
|
|
5470
5711
|
return this.compile(arg).sql;
|
|
5471
5712
|
}
|
|
5713
|
+
/**
|
|
5714
|
+
* Returns the Abstract Syntax Tree (AST) representation of the query
|
|
5715
|
+
* @returns The AST node for the INSERT query
|
|
5716
|
+
*/
|
|
5472
5717
|
getAST() {
|
|
5473
5718
|
return this.state.ast;
|
|
5474
5719
|
}
|
|
@@ -5487,6 +5732,11 @@ var isUpdateValue = (value) => {
|
|
|
5487
5732
|
}
|
|
5488
5733
|
};
|
|
5489
5734
|
var UpdateQueryState = class _UpdateQueryState {
|
|
5735
|
+
/**
|
|
5736
|
+
* Creates a new UpdateQueryState instance
|
|
5737
|
+
* @param table - Table definition for the update
|
|
5738
|
+
* @param ast - Optional existing AST
|
|
5739
|
+
*/
|
|
5490
5740
|
constructor(table, ast) {
|
|
5491
5741
|
this.table = table;
|
|
5492
5742
|
this.ast = ast ?? {
|
|
@@ -5496,9 +5746,19 @@ var UpdateQueryState = class _UpdateQueryState {
|
|
|
5496
5746
|
joins: []
|
|
5497
5747
|
};
|
|
5498
5748
|
}
|
|
5749
|
+
/**
|
|
5750
|
+
* Creates a new UpdateQueryState with updated AST
|
|
5751
|
+
* @param nextAst - Updated AST
|
|
5752
|
+
* @returns New UpdateQueryState instance
|
|
5753
|
+
*/
|
|
5499
5754
|
clone(nextAst) {
|
|
5500
5755
|
return new _UpdateQueryState(this.table, nextAst);
|
|
5501
5756
|
}
|
|
5757
|
+
/**
|
|
5758
|
+
* Sets the columns to update with their new values
|
|
5759
|
+
* @param values - Record of column names to values
|
|
5760
|
+
* @returns New UpdateQueryState with SET clause
|
|
5761
|
+
*/
|
|
5502
5762
|
withSet(values) {
|
|
5503
5763
|
const assignments = Object.entries(values).map(([column, rawValue]) => {
|
|
5504
5764
|
if (!isUpdateValue(rawValue)) {
|
|
@@ -5520,30 +5780,55 @@ var UpdateQueryState = class _UpdateQueryState {
|
|
|
5520
5780
|
set: assignments
|
|
5521
5781
|
});
|
|
5522
5782
|
}
|
|
5783
|
+
/**
|
|
5784
|
+
* Adds a WHERE condition to the update query
|
|
5785
|
+
* @param expr - WHERE expression
|
|
5786
|
+
* @returns New UpdateQueryState with WHERE clause
|
|
5787
|
+
*/
|
|
5523
5788
|
withWhere(expr) {
|
|
5524
5789
|
return this.clone({
|
|
5525
5790
|
...this.ast,
|
|
5526
5791
|
where: expr
|
|
5527
5792
|
});
|
|
5528
5793
|
}
|
|
5794
|
+
/**
|
|
5795
|
+
* Adds a RETURNING clause to the update query
|
|
5796
|
+
* @param columns - Columns to return
|
|
5797
|
+
* @returns New UpdateQueryState with RETURNING clause
|
|
5798
|
+
*/
|
|
5529
5799
|
withReturning(columns) {
|
|
5530
5800
|
return this.clone({
|
|
5531
5801
|
...this.ast,
|
|
5532
5802
|
returning: [...columns]
|
|
5533
5803
|
});
|
|
5534
5804
|
}
|
|
5805
|
+
/**
|
|
5806
|
+
* Sets the FROM clause for the update query
|
|
5807
|
+
* @param from - Table source for FROM
|
|
5808
|
+
* @returns New UpdateQueryState with FROM clause
|
|
5809
|
+
*/
|
|
5535
5810
|
withFrom(from) {
|
|
5536
5811
|
return this.clone({
|
|
5537
5812
|
...this.ast,
|
|
5538
5813
|
from
|
|
5539
5814
|
});
|
|
5540
5815
|
}
|
|
5816
|
+
/**
|
|
5817
|
+
* Adds a JOIN to the update query
|
|
5818
|
+
* @param join - Join node to add
|
|
5819
|
+
* @returns New UpdateQueryState with JOIN
|
|
5820
|
+
*/
|
|
5541
5821
|
withJoin(join) {
|
|
5542
5822
|
return this.clone({
|
|
5543
5823
|
...this.ast,
|
|
5544
5824
|
joins: [...this.ast.joins ?? [], join]
|
|
5545
5825
|
});
|
|
5546
5826
|
}
|
|
5827
|
+
/**
|
|
5828
|
+
* Applies an alias to the table being updated
|
|
5829
|
+
* @param alias - Alias for the table
|
|
5830
|
+
* @returns New UpdateQueryState with table alias
|
|
5831
|
+
*/
|
|
5547
5832
|
withTableAlias(alias) {
|
|
5548
5833
|
return this.clone({
|
|
5549
5834
|
...this.ast,
|
|
@@ -5557,6 +5842,11 @@ var UpdateQueryState = class _UpdateQueryState {
|
|
|
5557
5842
|
|
|
5558
5843
|
// src/query-builder/update.ts
|
|
5559
5844
|
var UpdateQueryBuilder = class _UpdateQueryBuilder {
|
|
5845
|
+
/**
|
|
5846
|
+
* Creates a new UpdateQueryBuilder instance
|
|
5847
|
+
* @param table - The table definition for the UPDATE query
|
|
5848
|
+
* @param state - Optional initial query state, defaults to a new UpdateQueryState
|
|
5849
|
+
*/
|
|
5560
5850
|
constructor(table, state) {
|
|
5561
5851
|
this.table = table;
|
|
5562
5852
|
this.state = state ?? new UpdateQueryState(table);
|
|
@@ -5564,24 +5854,57 @@ var UpdateQueryBuilder = class _UpdateQueryBuilder {
|
|
|
5564
5854
|
clone(state) {
|
|
5565
5855
|
return new _UpdateQueryBuilder(this.table, state);
|
|
5566
5856
|
}
|
|
5857
|
+
/**
|
|
5858
|
+
* Sets an alias for the table in the UPDATE query
|
|
5859
|
+
* @param alias - The alias to assign to the table
|
|
5860
|
+
* @returns A new UpdateQueryBuilder with the table alias set
|
|
5861
|
+
*/
|
|
5567
5862
|
as(alias) {
|
|
5568
5863
|
return this.clone(this.state.withTableAlias(alias));
|
|
5569
5864
|
}
|
|
5865
|
+
/**
|
|
5866
|
+
* Adds a FROM clause to the UPDATE query
|
|
5867
|
+
* @param source - The table source to use in the FROM clause
|
|
5868
|
+
* @returns A new UpdateQueryBuilder with the FROM clause added
|
|
5869
|
+
*/
|
|
5570
5870
|
from(source) {
|
|
5571
5871
|
const tableSource = this.resolveTableSource(source);
|
|
5572
5872
|
return this.clone(this.state.withFrom(tableSource));
|
|
5573
5873
|
}
|
|
5874
|
+
/**
|
|
5875
|
+
* Adds a JOIN clause to the UPDATE query
|
|
5876
|
+
* @param table - The table to join with
|
|
5877
|
+
* @param condition - The join condition expression
|
|
5878
|
+
* @param kind - The type of join (defaults to INNER)
|
|
5879
|
+
* @param relationName - Optional name for the relation
|
|
5880
|
+
* @returns A new UpdateQueryBuilder with the JOIN clause added
|
|
5881
|
+
*/
|
|
5574
5882
|
join(table, condition, kind = JOIN_KINDS.INNER, relationName) {
|
|
5575
5883
|
const joinTarget = this.resolveJoinTarget(table);
|
|
5576
5884
|
const joinNode = createJoinNode(kind, joinTarget, condition, relationName);
|
|
5577
5885
|
return this.clone(this.state.withJoin(joinNode));
|
|
5578
5886
|
}
|
|
5887
|
+
/**
|
|
5888
|
+
* Adds a SET clause to the UPDATE query
|
|
5889
|
+
* @param values - The column-value pairs to update
|
|
5890
|
+
* @returns A new UpdateQueryBuilder with the SET clause added
|
|
5891
|
+
*/
|
|
5579
5892
|
set(values) {
|
|
5580
5893
|
return this.clone(this.state.withSet(values));
|
|
5581
5894
|
}
|
|
5895
|
+
/**
|
|
5896
|
+
* Adds a WHERE clause to the UPDATE query
|
|
5897
|
+
* @param expr - The expression to use as the WHERE condition
|
|
5898
|
+
* @returns A new UpdateQueryBuilder with the WHERE clause added
|
|
5899
|
+
*/
|
|
5582
5900
|
where(expr) {
|
|
5583
5901
|
return this.clone(this.state.withWhere(expr));
|
|
5584
5902
|
}
|
|
5903
|
+
/**
|
|
5904
|
+
* Adds a RETURNING clause to the UPDATE query
|
|
5905
|
+
* @param columns - Columns to return after update
|
|
5906
|
+
* @returns A new UpdateQueryBuilder with the RETURNING clause added
|
|
5907
|
+
*/
|
|
5585
5908
|
returning(...columns) {
|
|
5586
5909
|
if (!columns.length) return this;
|
|
5587
5910
|
const nodes = columns.map((column) => buildColumnNode(this.table, column));
|
|
@@ -5597,16 +5920,36 @@ var UpdateQueryBuilder = class _UpdateQueryBuilder {
|
|
|
5597
5920
|
if (typeof table === "string") return table;
|
|
5598
5921
|
return this.resolveTableSource(table);
|
|
5599
5922
|
}
|
|
5600
|
-
|
|
5601
|
-
|
|
5602
|
-
|
|
5603
|
-
|
|
5604
|
-
|
|
5605
|
-
|
|
5923
|
+
/**
|
|
5924
|
+
* Compiles the UPDATE query for the specified dialect
|
|
5925
|
+
* @param dialect - The SQL dialect to compile for
|
|
5926
|
+
* @returns The compiled query with SQL and parameters
|
|
5927
|
+
*/
|
|
5928
|
+
compile(dialect) {
|
|
5929
|
+
const resolved = resolveDialectInput(dialect);
|
|
5930
|
+
return resolved.compileUpdate(this.state.ast);
|
|
5606
5931
|
}
|
|
5607
|
-
|
|
5608
|
-
|
|
5932
|
+
/**
|
|
5933
|
+
* Returns the SQL string for the UPDATE query
|
|
5934
|
+
* @param dialect - The SQL dialect to generate SQL for
|
|
5935
|
+
* @returns The SQL string representation of the query
|
|
5936
|
+
*/
|
|
5937
|
+
toSql(dialect) {
|
|
5938
|
+
return this.compile(dialect).sql;
|
|
5609
5939
|
}
|
|
5940
|
+
/**
|
|
5941
|
+
* Executes the UPDATE query using the provided session
|
|
5942
|
+
* @param session - The ORM session to execute the query with
|
|
5943
|
+
* @returns A promise that resolves to the query results
|
|
5944
|
+
*/
|
|
5945
|
+
async execute(session) {
|
|
5946
|
+
const compiled = this.compile(session.dialect);
|
|
5947
|
+
return session.executor.executeSql(compiled.sql, compiled.params);
|
|
5948
|
+
}
|
|
5949
|
+
/**
|
|
5950
|
+
* Returns the Abstract Syntax Tree (AST) representation of the query
|
|
5951
|
+
* @returns The AST node for the UPDATE query
|
|
5952
|
+
*/
|
|
5610
5953
|
getAST() {
|
|
5611
5954
|
return this.state.ast;
|
|
5612
5955
|
}
|
|
@@ -5615,6 +5958,11 @@ var isTableSourceNode = (source) => typeof source.type === "string";
|
|
|
5615
5958
|
|
|
5616
5959
|
// src/query-builder/delete-query-state.ts
|
|
5617
5960
|
var DeleteQueryState = class _DeleteQueryState {
|
|
5961
|
+
/**
|
|
5962
|
+
* Creates a new DeleteQueryState instance
|
|
5963
|
+
* @param table - The table definition for the DELETE query
|
|
5964
|
+
* @param ast - Optional initial AST node, defaults to a basic DELETE query
|
|
5965
|
+
*/
|
|
5618
5966
|
constructor(table, ast) {
|
|
5619
5967
|
this.table = table;
|
|
5620
5968
|
this.ast = ast ?? {
|
|
@@ -5626,30 +5974,55 @@ var DeleteQueryState = class _DeleteQueryState {
|
|
|
5626
5974
|
clone(nextAst) {
|
|
5627
5975
|
return new _DeleteQueryState(this.table, nextAst);
|
|
5628
5976
|
}
|
|
5977
|
+
/**
|
|
5978
|
+
* Adds a WHERE clause to the DELETE query
|
|
5979
|
+
* @param expr - The expression to use as the WHERE condition
|
|
5980
|
+
* @returns A new DeleteQueryState with the WHERE clause added
|
|
5981
|
+
*/
|
|
5629
5982
|
withWhere(expr) {
|
|
5630
5983
|
return this.clone({
|
|
5631
5984
|
...this.ast,
|
|
5632
5985
|
where: expr
|
|
5633
5986
|
});
|
|
5634
5987
|
}
|
|
5988
|
+
/**
|
|
5989
|
+
* Adds a RETURNING clause to the DELETE query
|
|
5990
|
+
* @param columns - The columns to return after deletion
|
|
5991
|
+
* @returns A new DeleteQueryState with the RETURNING clause added
|
|
5992
|
+
*/
|
|
5635
5993
|
withReturning(columns) {
|
|
5636
5994
|
return this.clone({
|
|
5637
5995
|
...this.ast,
|
|
5638
5996
|
returning: [...columns]
|
|
5639
5997
|
});
|
|
5640
5998
|
}
|
|
5999
|
+
/**
|
|
6000
|
+
* Adds a USING clause to the DELETE query
|
|
6001
|
+
* @param source - The table source to use in the USING clause
|
|
6002
|
+
* @returns A new DeleteQueryState with the USING clause added
|
|
6003
|
+
*/
|
|
5641
6004
|
withUsing(source) {
|
|
5642
6005
|
return this.clone({
|
|
5643
6006
|
...this.ast,
|
|
5644
6007
|
using: source
|
|
5645
6008
|
});
|
|
5646
6009
|
}
|
|
6010
|
+
/**
|
|
6011
|
+
* Adds a JOIN clause to the DELETE query
|
|
6012
|
+
* @param join - The join node to add
|
|
6013
|
+
* @returns A new DeleteQueryState with the JOIN clause added
|
|
6014
|
+
*/
|
|
5647
6015
|
withJoin(join) {
|
|
5648
6016
|
return this.clone({
|
|
5649
6017
|
...this.ast,
|
|
5650
6018
|
joins: [...this.ast.joins ?? [], join]
|
|
5651
6019
|
});
|
|
5652
6020
|
}
|
|
6021
|
+
/**
|
|
6022
|
+
* Sets an alias for the table in the DELETE query
|
|
6023
|
+
* @param alias - The alias to assign to the table
|
|
6024
|
+
* @returns A new DeleteQueryState with the table alias set
|
|
6025
|
+
*/
|
|
5653
6026
|
withTableAlias(alias) {
|
|
5654
6027
|
return this.clone({
|
|
5655
6028
|
...this.ast,
|
|
@@ -5663,6 +6036,11 @@ var DeleteQueryState = class _DeleteQueryState {
|
|
|
5663
6036
|
|
|
5664
6037
|
// src/query-builder/delete.ts
|
|
5665
6038
|
var DeleteQueryBuilder = class _DeleteQueryBuilder {
|
|
6039
|
+
/**
|
|
6040
|
+
* Creates a new DeleteQueryBuilder instance
|
|
6041
|
+
* @param table - The table definition for the DELETE query
|
|
6042
|
+
* @param state - Optional initial query state, defaults to a new DeleteQueryState
|
|
6043
|
+
*/
|
|
5666
6044
|
constructor(table, state) {
|
|
5667
6045
|
this.table = table;
|
|
5668
6046
|
this.state = state ?? new DeleteQueryState(table);
|
|
@@ -5670,20 +6048,48 @@ var DeleteQueryBuilder = class _DeleteQueryBuilder {
|
|
|
5670
6048
|
clone(state) {
|
|
5671
6049
|
return new _DeleteQueryBuilder(this.table, state);
|
|
5672
6050
|
}
|
|
6051
|
+
/**
|
|
6052
|
+
* Adds a WHERE clause to the DELETE query
|
|
6053
|
+
* @param expr - The expression to use as the WHERE condition
|
|
6054
|
+
* @returns A new DeleteQueryBuilder with the WHERE clause added
|
|
6055
|
+
*/
|
|
5673
6056
|
where(expr) {
|
|
5674
6057
|
return this.clone(this.state.withWhere(expr));
|
|
5675
6058
|
}
|
|
6059
|
+
/**
|
|
6060
|
+
* Sets an alias for the table in the DELETE query
|
|
6061
|
+
* @param alias - The alias to assign to the table
|
|
6062
|
+
* @returns A new DeleteQueryBuilder with the table alias set
|
|
6063
|
+
*/
|
|
5676
6064
|
as(alias) {
|
|
5677
6065
|
return this.clone(this.state.withTableAlias(alias));
|
|
5678
6066
|
}
|
|
6067
|
+
/**
|
|
6068
|
+
* Adds a USING clause to the DELETE query
|
|
6069
|
+
* @param source - The table source to use in the USING clause
|
|
6070
|
+
* @returns A new DeleteQueryBuilder with the USING clause added
|
|
6071
|
+
*/
|
|
5679
6072
|
using(source) {
|
|
5680
6073
|
return this.clone(this.state.withUsing(this.resolveTableSource(source)));
|
|
5681
6074
|
}
|
|
6075
|
+
/**
|
|
6076
|
+
* Adds a JOIN clause to the DELETE query
|
|
6077
|
+
* @param table - The table to join with
|
|
6078
|
+
* @param condition - The join condition expression
|
|
6079
|
+
* @param kind - The type of join (defaults to INNER)
|
|
6080
|
+
* @param relationName - Optional name for the relation
|
|
6081
|
+
* @returns A new DeleteQueryBuilder with the JOIN clause added
|
|
6082
|
+
*/
|
|
5682
6083
|
join(table, condition, kind = JOIN_KINDS.INNER, relationName) {
|
|
5683
6084
|
const target = this.resolveJoinTarget(table);
|
|
5684
6085
|
const joinNode = createJoinNode(kind, target, condition, relationName);
|
|
5685
6086
|
return this.clone(this.state.withJoin(joinNode));
|
|
5686
6087
|
}
|
|
6088
|
+
/**
|
|
6089
|
+
* Adds a RETURNING clause to the DELETE query
|
|
6090
|
+
* @param columns - The columns to return after deletion
|
|
6091
|
+
* @returns A new DeleteQueryBuilder with the RETURNING clause added
|
|
6092
|
+
*/
|
|
5687
6093
|
returning(...columns) {
|
|
5688
6094
|
if (!columns.length) return this;
|
|
5689
6095
|
const nodes = columns.map((column) => buildColumnNode(this.table, column));
|
|
@@ -5699,16 +6105,36 @@ var DeleteQueryBuilder = class _DeleteQueryBuilder {
|
|
|
5699
6105
|
if (typeof table === "string") return table;
|
|
5700
6106
|
return this.resolveTableSource(table);
|
|
5701
6107
|
}
|
|
5702
|
-
|
|
5703
|
-
|
|
5704
|
-
|
|
5705
|
-
|
|
5706
|
-
|
|
5707
|
-
|
|
6108
|
+
/**
|
|
6109
|
+
* Compiles the DELETE query for the specified dialect
|
|
6110
|
+
* @param dialect - The SQL dialect to compile for
|
|
6111
|
+
* @returns The compiled query with SQL and parameters
|
|
6112
|
+
*/
|
|
6113
|
+
compile(dialect) {
|
|
6114
|
+
const resolved = resolveDialectInput(dialect);
|
|
6115
|
+
return resolved.compileDelete(this.state.ast);
|
|
5708
6116
|
}
|
|
5709
|
-
|
|
5710
|
-
|
|
6117
|
+
/**
|
|
6118
|
+
* Returns the SQL string for the DELETE query
|
|
6119
|
+
* @param dialect - The SQL dialect to generate SQL for
|
|
6120
|
+
* @returns The SQL string representation of the query
|
|
6121
|
+
*/
|
|
6122
|
+
toSql(dialect) {
|
|
6123
|
+
return this.compile(dialect).sql;
|
|
6124
|
+
}
|
|
6125
|
+
/**
|
|
6126
|
+
* Executes the DELETE query using the provided session
|
|
6127
|
+
* @param session - The ORM session to execute the query with
|
|
6128
|
+
* @returns A promise that resolves to the query results
|
|
6129
|
+
*/
|
|
6130
|
+
async execute(session) {
|
|
6131
|
+
const compiled = this.compile(session.dialect);
|
|
6132
|
+
return session.executor.executeSql(compiled.sql, compiled.params);
|
|
5711
6133
|
}
|
|
6134
|
+
/**
|
|
6135
|
+
* Returns the Abstract Syntax Tree (AST) representation of the query
|
|
6136
|
+
* @returns The AST node for the DELETE query
|
|
6137
|
+
*/
|
|
5712
6138
|
getAST() {
|
|
5713
6139
|
return this.state.ast;
|
|
5714
6140
|
}
|
|
@@ -5751,7 +6177,7 @@ var generateCreateTableSql = (table, dialect) => {
|
|
|
5751
6177
|
const pk = resolvePrimaryKey(table);
|
|
5752
6178
|
const inlinePkColumns = /* @__PURE__ */ new Set();
|
|
5753
6179
|
const columnLines = Object.values(table.columns).map((col2) => {
|
|
5754
|
-
const includePk = dialect.preferInlinePkAutoincrement
|
|
6180
|
+
const includePk = dialect.preferInlinePkAutoincrement(col2, table, pk) && pk.includes(col2.name);
|
|
5755
6181
|
if (includePk) {
|
|
5756
6182
|
inlinePkColumns.add(col2.name);
|
|
5757
6183
|
}
|
|
@@ -6143,6 +6569,13 @@ async function runSelectNode(ast, ctx) {
|
|
|
6143
6569
|
|
|
6144
6570
|
// src/core/ddl/introspect/postgres.ts
|
|
6145
6571
|
var postgresIntrospector = {
|
|
6572
|
+
/**
|
|
6573
|
+
* Introspects the PostgreSQL database schema by querying information_schema and pg_catalog.
|
|
6574
|
+
* Builds tables with columns, primary keys, foreign keys, and indexes.
|
|
6575
|
+
* @param ctx - The introspection context with database executor.
|
|
6576
|
+
* @param options - Options for schema selection and table filtering.
|
|
6577
|
+
* @returns A promise resolving to the complete database schema.
|
|
6578
|
+
*/
|
|
6146
6579
|
async introspect(ctx, options) {
|
|
6147
6580
|
const schema = options.schema || "public";
|
|
6148
6581
|
const tables = [];
|
|
@@ -6256,7 +6689,7 @@ var postgresIntrospector = {
|
|
|
6256
6689
|
],
|
|
6257
6690
|
where: and(
|
|
6258
6691
|
eq({ table: "ns", name: "nspname" }, schema),
|
|
6259
|
-
eq({ table: "i", name: "indisprimary" },
|
|
6692
|
+
eq({ table: "i", name: "indisprimary" }, false)
|
|
6260
6693
|
)
|
|
6261
6694
|
};
|
|
6262
6695
|
const indexQueryRows = await runSelectNode(indexQuery, ctx);
|
|
@@ -6420,8 +6853,22 @@ var mysqlIntrospector = {
|
|
|
6420
6853
|
};
|
|
6421
6854
|
|
|
6422
6855
|
// src/core/ddl/introspect/sqlite.ts
|
|
6856
|
+
var toReferentialAction = (value) => {
|
|
6857
|
+
if (!value) return void 0;
|
|
6858
|
+
const normalized = value.toUpperCase();
|
|
6859
|
+
if (normalized === "NO ACTION" || normalized === "RESTRICT" || normalized === "CASCADE" || normalized === "SET NULL" || normalized === "SET DEFAULT") {
|
|
6860
|
+
return normalized;
|
|
6861
|
+
}
|
|
6862
|
+
return void 0;
|
|
6863
|
+
};
|
|
6423
6864
|
var escapeSingleQuotes = (name) => name.replace(/'/g, "''");
|
|
6424
6865
|
var sqliteIntrospector = {
|
|
6866
|
+
/**
|
|
6867
|
+
* Introspects the SQLite database schema by querying sqlite_master and various PRAGMAs.
|
|
6868
|
+
* @param ctx - The database execution context containing the DbExecutor.
|
|
6869
|
+
* @param options - Options controlling which tables and schemas to include.
|
|
6870
|
+
* @returns A promise that resolves to the introspected DatabaseSchema.
|
|
6871
|
+
*/
|
|
6425
6872
|
async introspect(ctx, options) {
|
|
6426
6873
|
const tables = [];
|
|
6427
6874
|
const tableRows = await queryRows(
|
|
@@ -6453,8 +6900,8 @@ var sqliteIntrospector = {
|
|
|
6453
6900
|
col2.references = {
|
|
6454
6901
|
table: fk.table,
|
|
6455
6902
|
column: fk.to,
|
|
6456
|
-
onDelete: fk.on_delete
|
|
6457
|
-
onUpdate: fk.on_update
|
|
6903
|
+
onDelete: toReferentialAction(fk.on_delete),
|
|
6904
|
+
onUpdate: toReferentialAction(fk.on_update)
|
|
6458
6905
|
};
|
|
6459
6906
|
}
|
|
6460
6907
|
});
|
|
@@ -6477,6 +6924,12 @@ var sqliteIntrospector = {
|
|
|
6477
6924
|
|
|
6478
6925
|
// src/core/ddl/introspect/mssql.ts
|
|
6479
6926
|
var mssqlIntrospector = {
|
|
6927
|
+
/**
|
|
6928
|
+
* Introspects the MSSQL database schema.
|
|
6929
|
+
* @param ctx - The introspection context containing the database executor.
|
|
6930
|
+
* @param options - Options for introspection, such as schema filter.
|
|
6931
|
+
* @returns A promise that resolves to the introspected database schema.
|
|
6932
|
+
*/
|
|
6480
6933
|
async introspect(ctx, options) {
|
|
6481
6934
|
const schema = options.schema;
|
|
6482
6935
|
const filterSchema = schema ? "sch.name = @p1" : "1=1";
|
|
@@ -6759,10 +7212,21 @@ var dateTrunc = (part, date) => fn3("DATE_TRUNC", [part, date]);
|
|
|
6759
7212
|
// src/orm/als.ts
|
|
6760
7213
|
var AsyncLocalStorage = class {
|
|
6761
7214
|
/**
|
|
6762
|
-
* Executes a callback
|
|
6763
|
-
*
|
|
6764
|
-
*
|
|
6765
|
-
*
|
|
7215
|
+
* Executes a callback function within a context containing the specified store value.
|
|
7216
|
+
* The store value is only available during the callback's execution and is automatically
|
|
7217
|
+
* cleared afterward.
|
|
7218
|
+
*
|
|
7219
|
+
* @param store - The context value to make available during callback execution
|
|
7220
|
+
* @param callback - Function to execute with the store value available
|
|
7221
|
+
* @returns Result of the callback function execution
|
|
7222
|
+
*
|
|
7223
|
+
* @example
|
|
7224
|
+
* ```
|
|
7225
|
+
* const als = new AsyncLocalStorage<number>();
|
|
7226
|
+
* als.run(42, () => {
|
|
7227
|
+
* console.log(als.getStore()); // Outputs: 42
|
|
7228
|
+
* });
|
|
7229
|
+
* ```
|
|
6766
7230
|
*/
|
|
6767
7231
|
run(store, callback) {
|
|
6768
7232
|
this.store = store;
|
|
@@ -6773,8 +7237,20 @@ var AsyncLocalStorage = class {
|
|
|
6773
7237
|
}
|
|
6774
7238
|
}
|
|
6775
7239
|
/**
|
|
6776
|
-
*
|
|
6777
|
-
*
|
|
7240
|
+
* Retrieves the current store value from the async context.
|
|
7241
|
+
* Returns undefined if called outside of a `run()` callback execution.
|
|
7242
|
+
*
|
|
7243
|
+
* @returns Current store value or undefined if no context exists
|
|
7244
|
+
*
|
|
7245
|
+
* @example
|
|
7246
|
+
* ```
|
|
7247
|
+
* const als = new AsyncLocalStorage<string>();
|
|
7248
|
+
* console.log(als.getStore()); // Outputs: undefined
|
|
7249
|
+
*
|
|
7250
|
+
* als.run('hello', () => {
|
|
7251
|
+
* console.log(als.getStore()); // Outputs: 'hello'
|
|
7252
|
+
* });
|
|
7253
|
+
* ```
|
|
6778
7254
|
*/
|
|
6779
7255
|
getStore() {
|
|
6780
7256
|
return this.store;
|
|
@@ -6864,11 +7340,7 @@ var TypeScriptGenerator = class {
|
|
|
6864
7340
|
const lines = [];
|
|
6865
7341
|
const hydration = ast.meta?.hydration;
|
|
6866
7342
|
const hydratedRelations = new Set(hydration?.relations?.map((r) => r.name) ?? []);
|
|
6867
|
-
const selections = ast.columns.filter((col2) => !(hydration && isRelationAlias(col2.alias))).map((col2) => {
|
|
6868
|
-
const key = col2.alias || col2.name;
|
|
6869
|
-
const operand = col2;
|
|
6870
|
-
return `${key}: ${this.printOperand(operand)}`;
|
|
6871
|
-
});
|
|
7343
|
+
const selections = ast.columns.filter((col2) => !(hydration && isRelationAlias(col2.alias))).map((col2, index) => `${this.getSelectionKey(col2, index)}: ${this.printOperand(col2)}`);
|
|
6872
7344
|
lines.push(`db.select({`);
|
|
6873
7345
|
selections.forEach((sel2, index) => {
|
|
6874
7346
|
lines.push(` ${sel2}${index < selections.length - 1 ? "," : ""}`);
|
|
@@ -6956,7 +7428,7 @@ var TypeScriptGenerator = class {
|
|
|
6956
7428
|
* Prints an ordering term (operand/expression/alias) to TypeScript code.
|
|
6957
7429
|
*/
|
|
6958
7430
|
printOrderingTerm(term) {
|
|
6959
|
-
if (!term || !term
|
|
7431
|
+
if (!term || !("type" in term)) {
|
|
6960
7432
|
throw new Error("Unsupported ordering term");
|
|
6961
7433
|
}
|
|
6962
7434
|
switch (term.type) {
|
|
@@ -6975,6 +7447,18 @@ var TypeScriptGenerator = class {
|
|
|
6975
7447
|
return this.printExpression(term);
|
|
6976
7448
|
}
|
|
6977
7449
|
}
|
|
7450
|
+
getSelectionKey(selection, index) {
|
|
7451
|
+
if (selection.alias) {
|
|
7452
|
+
return selection.alias;
|
|
7453
|
+
}
|
|
7454
|
+
if (this.isNamedSelection(selection)) {
|
|
7455
|
+
return selection.name;
|
|
7456
|
+
}
|
|
7457
|
+
return `selection${index + 1}`;
|
|
7458
|
+
}
|
|
7459
|
+
isNamedSelection(selection) {
|
|
7460
|
+
return "name" in selection;
|
|
7461
|
+
}
|
|
6978
7462
|
visitBinaryExpression(binary) {
|
|
6979
7463
|
return this.printBinaryExpression(binary);
|
|
6980
7464
|
}
|
|
@@ -7758,6 +8242,7 @@ var RelationChangeProcessor = class {
|
|
|
7758
8242
|
* @param _entry - The relation change entry (reserved for future use)
|
|
7759
8243
|
*/
|
|
7760
8244
|
async handleBelongsToChange(_entry) {
|
|
8245
|
+
void _entry;
|
|
7761
8246
|
}
|
|
7762
8247
|
/**
|
|
7763
8248
|
* Handles changes for belongs-to-many relations.
|
|
@@ -7871,7 +8356,7 @@ var RelationChangeProcessor = class {
|
|
|
7871
8356
|
const key = findPrimaryKey(table);
|
|
7872
8357
|
const value = entity[key];
|
|
7873
8358
|
if (value === void 0 || value === null) return null;
|
|
7874
|
-
return value;
|
|
8359
|
+
return value ?? null;
|
|
7875
8360
|
}
|
|
7876
8361
|
};
|
|
7877
8362
|
|
|
@@ -8463,8 +8948,6 @@ var Orm = class {
|
|
|
8463
8948
|
const session = new OrmSession({ orm: this, executor });
|
|
8464
8949
|
try {
|
|
8465
8950
|
return await session.transaction(() => fn4(session));
|
|
8466
|
-
} catch (err) {
|
|
8467
|
-
throw err;
|
|
8468
8951
|
} finally {
|
|
8469
8952
|
await session.dispose();
|
|
8470
8953
|
}
|
|
@@ -8495,9 +8978,6 @@ var getOrCreateMetadataBag = (context) => {
|
|
|
8495
8978
|
var readMetadataBag = (context) => {
|
|
8496
8979
|
return context.metadata?.[METADATA_KEY];
|
|
8497
8980
|
};
|
|
8498
|
-
var registerInitializer = (context, initializer) => {
|
|
8499
|
-
context.addInitializer?.(initializer);
|
|
8500
|
-
};
|
|
8501
8981
|
|
|
8502
8982
|
// src/decorators/entity.ts
|
|
8503
8983
|
var toSnakeCase = (value) => {
|
|
@@ -8527,14 +9007,24 @@ function Entity(options = {}) {
|
|
|
8527
9007
|
if (bag) {
|
|
8528
9008
|
const meta = ensureEntityMetadata(ctor);
|
|
8529
9009
|
for (const entry of bag.columns) {
|
|
8530
|
-
if (
|
|
8531
|
-
|
|
9010
|
+
if (meta.columns[entry.propertyName]) {
|
|
9011
|
+
throw new Error(
|
|
9012
|
+
`Column '${entry.propertyName}' is already defined on entity '${ctor.name}'.`
|
|
9013
|
+
);
|
|
8532
9014
|
}
|
|
9015
|
+
addColumnMetadata(ctor, entry.propertyName, { ...entry.column });
|
|
8533
9016
|
}
|
|
8534
9017
|
for (const entry of bag.relations) {
|
|
8535
|
-
if (
|
|
8536
|
-
|
|
9018
|
+
if (meta.relations[entry.propertyName]) {
|
|
9019
|
+
throw new Error(
|
|
9020
|
+
`Relation '${entry.propertyName}' is already defined on entity '${ctor.name}'.`
|
|
9021
|
+
);
|
|
8537
9022
|
}
|
|
9023
|
+
const relationCopy = entry.relation.kind === RelationKinds.BelongsToMany ? {
|
|
9024
|
+
...entry.relation,
|
|
9025
|
+
defaultPivotColumns: entry.relation.defaultPivotColumns ? [...entry.relation.defaultPivotColumns] : void 0
|
|
9026
|
+
} : { ...entry.relation };
|
|
9027
|
+
addRelationMetadata(ctor, entry.propertyName, relationCopy);
|
|
8538
9028
|
}
|
|
8539
9029
|
}
|
|
8540
9030
|
}
|
|
@@ -8597,13 +9087,6 @@ var registerColumnFromContext = (context, column) => {
|
|
|
8597
9087
|
if (!bag.columns.some((entry) => entry.propertyName === propertyName)) {
|
|
8598
9088
|
bag.columns.push({ propertyName, column: { ...column } });
|
|
8599
9089
|
}
|
|
8600
|
-
registerInitializer(context, function() {
|
|
8601
|
-
const ctor = resolveConstructor(this);
|
|
8602
|
-
if (!ctor) {
|
|
8603
|
-
return;
|
|
8604
|
-
}
|
|
8605
|
-
registerColumn(ctor, propertyName, column);
|
|
8606
|
-
});
|
|
8607
9090
|
};
|
|
8608
9091
|
function Column(definition) {
|
|
8609
9092
|
const normalized = normalizeColumnInput(definition);
|
|
@@ -8659,13 +9142,6 @@ var createFieldDecorator = (metadataFactory) => {
|
|
|
8659
9142
|
if (!bag.relations.some((entry) => entry.propertyName === propertyName2)) {
|
|
8660
9143
|
bag.relations.push({ propertyName: propertyName2, relation: relationMetadata });
|
|
8661
9144
|
}
|
|
8662
|
-
registerInitializer(ctx, function() {
|
|
8663
|
-
const ctor2 = resolveConstructor2(this);
|
|
8664
|
-
if (!ctor2) {
|
|
8665
|
-
return;
|
|
8666
|
-
}
|
|
8667
|
-
registerRelation(ctor2, propertyName2, relationMetadata);
|
|
8668
|
-
});
|
|
8669
9145
|
return;
|
|
8670
9146
|
}
|
|
8671
9147
|
const propertyName = normalizePropertyName2(propertyKeyOrContext);
|
|
@@ -9302,11 +9778,9 @@ export {
|
|
|
9302
9778
|
cos,
|
|
9303
9779
|
cot,
|
|
9304
9780
|
count,
|
|
9305
|
-
createColumn,
|
|
9306
9781
|
createEntityFromRow,
|
|
9307
9782
|
createEntityProxy,
|
|
9308
9783
|
createExecutorFromQueryRunner,
|
|
9309
|
-
createLiteral,
|
|
9310
9784
|
createMssqlExecutor,
|
|
9311
9785
|
createMysqlExecutor,
|
|
9312
9786
|
createPooledExecutorFactory,
|
|
@@ -9330,6 +9804,7 @@ export {
|
|
|
9330
9804
|
diffSchema,
|
|
9331
9805
|
div,
|
|
9332
9806
|
endOfMonth,
|
|
9807
|
+
entityRef,
|
|
9333
9808
|
eq,
|
|
9334
9809
|
esel,
|
|
9335
9810
|
executeHydrated,
|
|
@@ -9342,6 +9817,7 @@ export {
|
|
|
9342
9817
|
fromUnixTime,
|
|
9343
9818
|
generateCreateTableSql,
|
|
9344
9819
|
generateSchemaSql,
|
|
9820
|
+
getColumn,
|
|
9345
9821
|
getSchemaIntrospector,
|
|
9346
9822
|
getTableDefFromEntity,
|
|
9347
9823
|
groupConcat,
|