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.cjs
CHANGED
|
@@ -99,11 +99,9 @@ __export(index_exports, {
|
|
|
99
99
|
cos: () => cos,
|
|
100
100
|
cot: () => cot,
|
|
101
101
|
count: () => count,
|
|
102
|
-
createColumn: () => createColumn,
|
|
103
102
|
createEntityFromRow: () => createEntityFromRow,
|
|
104
103
|
createEntityProxy: () => createEntityProxy,
|
|
105
104
|
createExecutorFromQueryRunner: () => createExecutorFromQueryRunner,
|
|
106
|
-
createLiteral: () => createLiteral,
|
|
107
105
|
createMssqlExecutor: () => createMssqlExecutor,
|
|
108
106
|
createMysqlExecutor: () => createMysqlExecutor,
|
|
109
107
|
createPooledExecutorFactory: () => createPooledExecutorFactory,
|
|
@@ -127,6 +125,7 @@ __export(index_exports, {
|
|
|
127
125
|
diffSchema: () => diffSchema,
|
|
128
126
|
div: () => div,
|
|
129
127
|
endOfMonth: () => endOfMonth,
|
|
128
|
+
entityRef: () => entityRef,
|
|
130
129
|
eq: () => eq,
|
|
131
130
|
esel: () => esel,
|
|
132
131
|
executeHydrated: () => executeHydrated,
|
|
@@ -139,6 +138,7 @@ __export(index_exports, {
|
|
|
139
138
|
fromUnixTime: () => fromUnixTime,
|
|
140
139
|
generateCreateTableSql: () => generateCreateTableSql,
|
|
141
140
|
generateSchemaSql: () => generateSchemaSql,
|
|
141
|
+
getColumn: () => getColumn,
|
|
142
142
|
getSchemaIntrospector: () => getSchemaIntrospector,
|
|
143
143
|
getTableDefFromEntity: () => getTableDefFromEntity,
|
|
144
144
|
groupConcat: () => groupConcat,
|
|
@@ -247,7 +247,8 @@ module.exports = __toCommonJS(index_exports);
|
|
|
247
247
|
// src/schema/table.ts
|
|
248
248
|
var defineTable = (name, columns, relations = {}, hooks, options = {}) => {
|
|
249
249
|
const colsWithNames = Object.entries(columns).reduce((acc, [key, def]) => {
|
|
250
|
-
|
|
250
|
+
const colDef = { ...def, name: key, table: name };
|
|
251
|
+
acc[key] = colDef;
|
|
251
252
|
return acc;
|
|
252
253
|
}, {});
|
|
253
254
|
return {
|
|
@@ -271,17 +272,20 @@ var withColumnProps = (table) => {
|
|
|
271
272
|
if (cached) return cached;
|
|
272
273
|
const proxy = new Proxy(table, {
|
|
273
274
|
get(target, prop, receiver) {
|
|
274
|
-
|
|
275
|
+
const t = target;
|
|
276
|
+
if (prop === "$") return t.columns;
|
|
275
277
|
if (Reflect.has(target, prop)) return Reflect.get(target, prop, receiver);
|
|
276
|
-
if (typeof prop === "string" && prop in
|
|
278
|
+
if (typeof prop === "string" && prop in t.columns) return t.columns[prop];
|
|
277
279
|
return void 0;
|
|
278
280
|
},
|
|
279
281
|
has(target, prop) {
|
|
280
|
-
|
|
282
|
+
const t = target;
|
|
283
|
+
return prop === "$" || Reflect.has(target, prop) || typeof prop === "string" && prop in t.columns;
|
|
281
284
|
},
|
|
282
285
|
ownKeys(target) {
|
|
286
|
+
const t = target;
|
|
283
287
|
const base = Reflect.ownKeys(target);
|
|
284
|
-
const cols = Object.keys(
|
|
288
|
+
const cols = Object.keys(t.columns);
|
|
285
289
|
for (const k of cols) {
|
|
286
290
|
if (!base.includes(k)) base.push(k);
|
|
287
291
|
}
|
|
@@ -313,6 +317,14 @@ var withColumnProps = (table) => {
|
|
|
313
317
|
return proxy;
|
|
314
318
|
};
|
|
315
319
|
var tableRef = (table) => withColumnProps(table);
|
|
320
|
+
function getColumn(table, key) {
|
|
321
|
+
const col2 = table.columns[key];
|
|
322
|
+
if (!col2) {
|
|
323
|
+
const tableName = table.name || "<unknown>";
|
|
324
|
+
throw new Error(`Column '${key}' does not exist on table '${tableName}'`);
|
|
325
|
+
}
|
|
326
|
+
return col2;
|
|
327
|
+
}
|
|
316
328
|
|
|
317
329
|
// src/schema/column.ts
|
|
318
330
|
var col = {
|
|
@@ -517,46 +529,59 @@ var operandTypes = /* @__PURE__ */ new Set([
|
|
|
517
529
|
"CaseExpression",
|
|
518
530
|
"WindowFunction"
|
|
519
531
|
]);
|
|
520
|
-
var
|
|
521
|
-
var
|
|
522
|
-
|
|
523
|
-
|
|
532
|
+
var hasTypeProperty = (value) => typeof value === "object" && value !== null && "type" in value;
|
|
533
|
+
var isOperandNode = (node) => {
|
|
534
|
+
if (!hasTypeProperty(node)) return false;
|
|
535
|
+
return operandTypes.has(node.type);
|
|
536
|
+
};
|
|
537
|
+
var isFunctionNode = (node) => isOperandNode(node) && node.type === "Function";
|
|
538
|
+
var isCaseExpressionNode = (node) => isOperandNode(node) && node.type === "CaseExpression";
|
|
539
|
+
var isWindowFunctionNode = (node) => isOperandNode(node) && node.type === "WindowFunction";
|
|
524
540
|
var isExpressionSelectionNode = (node) => isFunctionNode(node) || isCaseExpressionNode(node) || isWindowFunctionNode(node);
|
|
525
541
|
|
|
526
542
|
// src/core/ast/expression-builders.ts
|
|
527
|
-
var
|
|
528
|
-
if (isOperandNode(value)) {
|
|
529
|
-
return value;
|
|
530
|
-
}
|
|
531
|
-
return {
|
|
532
|
-
type: "Literal",
|
|
533
|
-
value
|
|
534
|
-
};
|
|
535
|
-
};
|
|
536
|
-
var toNode = (col2) => {
|
|
537
|
-
if (isOperandNode(col2)) return col2;
|
|
538
|
-
const def = col2;
|
|
539
|
-
return { type: "Column", table: def.table || "unknown", name: def.name };
|
|
540
|
-
};
|
|
543
|
+
var isLiteralValue = (value) => value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean";
|
|
541
544
|
var toLiteralNode = (value) => ({
|
|
542
545
|
type: "Literal",
|
|
543
546
|
value
|
|
544
547
|
});
|
|
545
|
-
var
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
548
|
+
var columnRefToNode = (col2) => {
|
|
549
|
+
if (!col2.table) {
|
|
550
|
+
throw new Error(
|
|
551
|
+
`Column "${col2.name}" requires a table reference. Use columnOperand with a fully qualified ColumnRef or ColumnNode.`
|
|
552
|
+
);
|
|
550
553
|
}
|
|
551
|
-
return
|
|
554
|
+
return { type: "Column", table: col2.table, name: col2.name };
|
|
552
555
|
};
|
|
556
|
+
var toOperandNode = (value) => {
|
|
557
|
+
if (isOperandNode(value)) {
|
|
558
|
+
return value;
|
|
559
|
+
}
|
|
560
|
+
if (isLiteralValue(value)) {
|
|
561
|
+
return toLiteralNode(value);
|
|
562
|
+
}
|
|
563
|
+
return columnRefToNode(value);
|
|
564
|
+
};
|
|
565
|
+
var valueToOperand = (value) => {
|
|
566
|
+
if (isOperandNode(value)) {
|
|
567
|
+
return value;
|
|
568
|
+
}
|
|
569
|
+
return toLiteralNode(value);
|
|
570
|
+
};
|
|
571
|
+
var toOperand = (val) => toOperandNode(val);
|
|
572
|
+
var isValueOperandInput = (value) => isOperandNode(value) || isLiteralValue(value);
|
|
553
573
|
var hasQueryAst = (value) => typeof value.getAST === "function";
|
|
554
574
|
var resolveSelectQueryNode = (query) => hasQueryAst(query) ? query.getAST() : query;
|
|
555
575
|
var toScalarSubqueryNode = (query) => ({
|
|
556
576
|
type: "ScalarSubquery",
|
|
557
577
|
query: resolveSelectQueryNode(query)
|
|
558
578
|
});
|
|
559
|
-
var columnOperand = (col2) =>
|
|
579
|
+
var columnOperand = (col2) => {
|
|
580
|
+
if (isOperandNode(col2) && col2.type === "Column") {
|
|
581
|
+
return col2;
|
|
582
|
+
}
|
|
583
|
+
return columnRefToNode(col2);
|
|
584
|
+
};
|
|
560
585
|
var outerRef = (col2) => ({
|
|
561
586
|
...columnOperand(col2),
|
|
562
587
|
scope: "outer"
|
|
@@ -569,7 +594,7 @@ var correlateBy = (table, column) => outerRef({ name: column, table });
|
|
|
569
594
|
var createBinaryExpression = (operator, left2, right2, escape) => {
|
|
570
595
|
const node = {
|
|
571
596
|
type: "BinaryExpression",
|
|
572
|
-
left:
|
|
597
|
+
left: toOperandNode(left2),
|
|
573
598
|
operator,
|
|
574
599
|
right: toOperand(right2)
|
|
575
600
|
};
|
|
@@ -598,17 +623,17 @@ var or = (...operands) => ({
|
|
|
598
623
|
});
|
|
599
624
|
var isNull = (left2) => ({
|
|
600
625
|
type: "NullExpression",
|
|
601
|
-
left:
|
|
626
|
+
left: toOperandNode(left2),
|
|
602
627
|
operator: "IS NULL"
|
|
603
628
|
});
|
|
604
629
|
var isNotNull = (left2) => ({
|
|
605
630
|
type: "NullExpression",
|
|
606
|
-
left:
|
|
631
|
+
left: toOperandNode(left2),
|
|
607
632
|
operator: "IS NOT NULL"
|
|
608
633
|
});
|
|
609
634
|
var createInExpression = (operator, left2, right2) => ({
|
|
610
635
|
type: "InExpression",
|
|
611
|
-
left:
|
|
636
|
+
left: toOperandNode(left2),
|
|
612
637
|
operator,
|
|
613
638
|
right: right2
|
|
614
639
|
});
|
|
@@ -618,7 +643,7 @@ var inSubquery = (left2, subquery) => createInExpression("IN", left2, toScalarSu
|
|
|
618
643
|
var notInSubquery = (left2, subquery) => createInExpression("NOT IN", left2, toScalarSubqueryNode(subquery));
|
|
619
644
|
var createBetweenExpression = (operator, left2, lower2, upper2) => ({
|
|
620
645
|
type: "BetweenExpression",
|
|
621
|
-
left:
|
|
646
|
+
left: toOperandNode(left2),
|
|
622
647
|
operator,
|
|
623
648
|
lower: toOperand(lower2),
|
|
624
649
|
upper: toOperand(upper2)
|
|
@@ -800,24 +825,54 @@ var groupConcat = (col2, options) => ({
|
|
|
800
825
|
});
|
|
801
826
|
|
|
802
827
|
// src/core/ast/expression-visitor.ts
|
|
803
|
-
var
|
|
804
|
-
|
|
828
|
+
var DispatcherRegistry = class _DispatcherRegistry {
|
|
829
|
+
constructor(dispatchers = /* @__PURE__ */ new Map()) {
|
|
830
|
+
this.dispatchers = dispatchers;
|
|
831
|
+
}
|
|
832
|
+
/**
|
|
833
|
+
* Registers a new dispatcher and returns a new registry instance
|
|
834
|
+
*/
|
|
835
|
+
register(type, dispatcher) {
|
|
836
|
+
const newMap = new Map(this.dispatchers);
|
|
837
|
+
newMap.set(type, dispatcher);
|
|
838
|
+
return new _DispatcherRegistry(newMap);
|
|
839
|
+
}
|
|
840
|
+
/**
|
|
841
|
+
* Gets a dispatcher for the given type
|
|
842
|
+
*/
|
|
843
|
+
get(type) {
|
|
844
|
+
return this.dispatchers.get(type);
|
|
845
|
+
}
|
|
846
|
+
/**
|
|
847
|
+
* Returns a new empty registry
|
|
848
|
+
*/
|
|
849
|
+
clear() {
|
|
850
|
+
return new _DispatcherRegistry();
|
|
851
|
+
}
|
|
852
|
+
};
|
|
853
|
+
var expressionRegistry = new DispatcherRegistry();
|
|
854
|
+
var operandRegistry = new DispatcherRegistry();
|
|
805
855
|
var registerExpressionDispatcher = (type, dispatcher) => {
|
|
806
|
-
|
|
856
|
+
expressionRegistry = expressionRegistry.register(type, dispatcher);
|
|
807
857
|
};
|
|
808
858
|
var registerOperandDispatcher = (type, dispatcher) => {
|
|
809
|
-
|
|
859
|
+
operandRegistry = operandRegistry.register(type, dispatcher);
|
|
810
860
|
};
|
|
811
|
-
var clearExpressionDispatchers = () =>
|
|
812
|
-
|
|
861
|
+
var clearExpressionDispatchers = () => {
|
|
862
|
+
expressionRegistry = expressionRegistry.clear();
|
|
863
|
+
};
|
|
864
|
+
var clearOperandDispatchers = () => {
|
|
865
|
+
operandRegistry = operandRegistry.clear();
|
|
866
|
+
};
|
|
867
|
+
var getNodeType = (node) => typeof node === "object" && node !== null && typeof node.type === "string" ? node.type : void 0;
|
|
813
868
|
var unsupportedExpression = (node) => {
|
|
814
|
-
throw new Error(`Unsupported expression type "${node
|
|
869
|
+
throw new Error(`Unsupported expression type "${getNodeType(node) ?? "unknown"}"`);
|
|
815
870
|
};
|
|
816
871
|
var unsupportedOperand = (node) => {
|
|
817
|
-
throw new Error(`Unsupported operand type "${node
|
|
872
|
+
throw new Error(`Unsupported operand type "${getNodeType(node) ?? "unknown"}"`);
|
|
818
873
|
};
|
|
819
874
|
var visitExpression = (node, visitor) => {
|
|
820
|
-
const dynamic =
|
|
875
|
+
const dynamic = expressionRegistry.get(node.type);
|
|
821
876
|
if (dynamic) return dynamic(node, visitor);
|
|
822
877
|
switch (node.type) {
|
|
823
878
|
case "BinaryExpression":
|
|
@@ -848,7 +903,7 @@ var visitExpression = (node, visitor) => {
|
|
|
848
903
|
return unsupportedExpression(node);
|
|
849
904
|
};
|
|
850
905
|
var visitOperand = (node, visitor) => {
|
|
851
|
-
const dynamic =
|
|
906
|
+
const dynamic = operandRegistry.get(node.type);
|
|
852
907
|
if (dynamic) return dynamic(node, visitor);
|
|
853
908
|
switch (node.type) {
|
|
854
909
|
case "Column":
|
|
@@ -883,24 +938,35 @@ var visitOperand = (node, visitor) => {
|
|
|
883
938
|
};
|
|
884
939
|
|
|
885
940
|
// src/core/ast/adapters.ts
|
|
941
|
+
var hasAlias = (obj) => typeof obj === "object" && obj !== null && "alias" in obj;
|
|
886
942
|
var toColumnRef = (col2) => ({
|
|
887
943
|
name: col2.name,
|
|
888
944
|
table: col2.table,
|
|
889
|
-
alias: col2.alias
|
|
945
|
+
alias: hasAlias(col2) ? col2.alias : void 0
|
|
890
946
|
});
|
|
891
947
|
var toTableRef = (table) => ({
|
|
892
948
|
name: table.name,
|
|
893
949
|
schema: table.schema,
|
|
894
|
-
alias: table.alias
|
|
950
|
+
alias: hasAlias(table) ? table.alias : void 0
|
|
895
951
|
});
|
|
896
952
|
|
|
897
953
|
// src/core/ast/builders.ts
|
|
954
|
+
var isColumnNode = (col2) => "type" in col2 && col2.type === "Column";
|
|
955
|
+
var resolveTableName = (def, table) => {
|
|
956
|
+
if (!def.table) {
|
|
957
|
+
return table.alias || table.name;
|
|
958
|
+
}
|
|
959
|
+
if (table.alias && def.table === table.name) {
|
|
960
|
+
return table.alias;
|
|
961
|
+
}
|
|
962
|
+
return def.table;
|
|
963
|
+
};
|
|
898
964
|
var buildColumnNode = (table, column) => {
|
|
899
|
-
if (column
|
|
965
|
+
if (isColumnNode(column)) {
|
|
900
966
|
return column;
|
|
901
967
|
}
|
|
902
968
|
const def = column;
|
|
903
|
-
const baseTable = def
|
|
969
|
+
const baseTable = resolveTableName(def, table);
|
|
904
970
|
return {
|
|
905
971
|
type: "Column",
|
|
906
972
|
table: baseTable,
|
|
@@ -914,7 +980,8 @@ var buildColumnNodes = (table, names) => names.map((name) => ({
|
|
|
914
980
|
}));
|
|
915
981
|
var createTableNode = (table) => ({
|
|
916
982
|
type: "Table",
|
|
917
|
-
name: table.name
|
|
983
|
+
name: table.name,
|
|
984
|
+
schema: table.schema
|
|
918
985
|
});
|
|
919
986
|
var fnTable = (name, args = [], alias, opts) => ({
|
|
920
987
|
type: "FunctionTable",
|
|
@@ -935,6 +1002,9 @@ var derivedTable = (query, alias, columnAliases) => ({
|
|
|
935
1002
|
|
|
936
1003
|
// src/core/functions/standard-strategy.ts
|
|
937
1004
|
var StandardFunctionStrategy = class _StandardFunctionStrategy {
|
|
1005
|
+
/**
|
|
1006
|
+
* Creates a new StandardFunctionStrategy and registers standard functions.
|
|
1007
|
+
*/
|
|
938
1008
|
constructor() {
|
|
939
1009
|
this.renderers = /* @__PURE__ */ new Map();
|
|
940
1010
|
this.registerStandard();
|
|
@@ -973,12 +1043,25 @@ var StandardFunctionStrategy = class _StandardFunctionStrategy {
|
|
|
973
1043
|
this.add("DATE_TRUNC", ({ compiledArgs }) => `DATE_TRUNC(${compiledArgs[0]}, ${compiledArgs[1]})`);
|
|
974
1044
|
this.add("GROUP_CONCAT", (ctx) => this.renderGroupConcat(ctx));
|
|
975
1045
|
}
|
|
1046
|
+
/**
|
|
1047
|
+
* Registers a renderer for a function name.
|
|
1048
|
+
* @param name - The function name.
|
|
1049
|
+
* @param renderer - The renderer function.
|
|
1050
|
+
*/
|
|
976
1051
|
add(name, renderer) {
|
|
977
1052
|
this.renderers.set(name, renderer);
|
|
978
1053
|
}
|
|
1054
|
+
/**
|
|
1055
|
+
* @inheritDoc
|
|
1056
|
+
*/
|
|
979
1057
|
getRenderer(name) {
|
|
980
1058
|
return this.renderers.get(name);
|
|
981
1059
|
}
|
|
1060
|
+
/**
|
|
1061
|
+
* Renders the GROUP_CONCAT function with optional ORDER BY and SEPARATOR.
|
|
1062
|
+
* @param ctx - The function render context.
|
|
1063
|
+
* @returns The rendered SQL string.
|
|
1064
|
+
*/
|
|
982
1065
|
renderGroupConcat(ctx) {
|
|
983
1066
|
const arg = ctx.compiledArgs[0];
|
|
984
1067
|
const orderClause = this.buildOrderByExpression(ctx);
|
|
@@ -986,6 +1069,11 @@ var StandardFunctionStrategy = class _StandardFunctionStrategy {
|
|
|
986
1069
|
const separatorClause = this.formatGroupConcatSeparator(ctx);
|
|
987
1070
|
return `GROUP_CONCAT(${arg}${orderSegment}${separatorClause})`;
|
|
988
1071
|
}
|
|
1072
|
+
/**
|
|
1073
|
+
* Builds the ORDER BY clause for functions like GROUP_CONCAT.
|
|
1074
|
+
* @param ctx - The function render context.
|
|
1075
|
+
* @returns The ORDER BY SQL clause or empty string.
|
|
1076
|
+
*/
|
|
989
1077
|
buildOrderByExpression(ctx) {
|
|
990
1078
|
const orderBy = ctx.node.orderBy;
|
|
991
1079
|
if (!orderBy || orderBy.length === 0) {
|
|
@@ -1001,16 +1089,27 @@ var StandardFunctionStrategy = class _StandardFunctionStrategy {
|
|
|
1001
1089
|
});
|
|
1002
1090
|
return `ORDER BY ${parts.join(", ")}`;
|
|
1003
1091
|
}
|
|
1092
|
+
/**
|
|
1093
|
+
* Formats the SEPARATOR clause for GROUP_CONCAT.
|
|
1094
|
+
* @param ctx - The function render context.
|
|
1095
|
+
* @returns The SEPARATOR SQL clause or empty string.
|
|
1096
|
+
*/
|
|
1004
1097
|
formatGroupConcatSeparator(ctx) {
|
|
1005
1098
|
if (!ctx.node.separator) {
|
|
1006
1099
|
return "";
|
|
1007
1100
|
}
|
|
1008
1101
|
return ` SEPARATOR ${ctx.compileOperand(ctx.node.separator)}`;
|
|
1009
1102
|
}
|
|
1103
|
+
/**
|
|
1104
|
+
* Gets the separator operand for GROUP_CONCAT, defaulting to comma.
|
|
1105
|
+
* @param ctx - The function render context.
|
|
1106
|
+
* @returns The separator operand.
|
|
1107
|
+
*/
|
|
1010
1108
|
getGroupConcatSeparatorOperand(ctx) {
|
|
1011
1109
|
return ctx.node.separator ?? _StandardFunctionStrategy.DEFAULT_GROUP_CONCAT_SEPARATOR;
|
|
1012
1110
|
}
|
|
1013
1111
|
static {
|
|
1112
|
+
/** Default separator for GROUP_CONCAT, a comma. */
|
|
1014
1113
|
this.DEFAULT_GROUP_CONCAT_SEPARATOR = {
|
|
1015
1114
|
type: "Literal",
|
|
1016
1115
|
value: ","
|
|
@@ -1075,7 +1174,8 @@ var Dialect = class _Dialect {
|
|
|
1075
1174
|
if (!where) return "";
|
|
1076
1175
|
return ` WHERE ${this.compileExpression(where, ctx)}`;
|
|
1077
1176
|
}
|
|
1078
|
-
compileReturning(returning,
|
|
1177
|
+
compileReturning(returning, _ctx) {
|
|
1178
|
+
void _ctx;
|
|
1079
1179
|
if (!returning || returning.length === 0) return "";
|
|
1080
1180
|
throw new Error("RETURNING is not supported by this dialect.");
|
|
1081
1181
|
}
|
|
@@ -1123,14 +1223,16 @@ var Dialect = class _Dialect {
|
|
|
1123
1223
|
* @param index - Parameter index
|
|
1124
1224
|
* @returns Formatted placeholder string
|
|
1125
1225
|
*/
|
|
1126
|
-
formatPlaceholder(
|
|
1226
|
+
formatPlaceholder(_index) {
|
|
1227
|
+
void _index;
|
|
1127
1228
|
return "?";
|
|
1128
1229
|
}
|
|
1129
1230
|
/**
|
|
1130
1231
|
* Whether the current dialect supports a given set operation.
|
|
1131
1232
|
* Override in concrete dialects to restrict support.
|
|
1132
1233
|
*/
|
|
1133
|
-
supportsSetOperation(
|
|
1234
|
+
supportsSetOperation(_kind) {
|
|
1235
|
+
void _kind;
|
|
1134
1236
|
return true;
|
|
1135
1237
|
}
|
|
1136
1238
|
/**
|
|
@@ -1323,15 +1425,22 @@ var Dialect = class _Dialect {
|
|
|
1323
1425
|
}
|
|
1324
1426
|
registerDefaultOperandCompilers() {
|
|
1325
1427
|
this.registerOperandCompiler("Literal", (literal, ctx) => ctx.addParameter(literal.value));
|
|
1326
|
-
this.registerOperandCompiler("AliasRef", (alias, _ctx) =>
|
|
1428
|
+
this.registerOperandCompiler("AliasRef", (alias, _ctx) => {
|
|
1429
|
+
void _ctx;
|
|
1430
|
+
return this.quoteIdentifier(alias.name);
|
|
1431
|
+
});
|
|
1327
1432
|
this.registerOperandCompiler("Column", (column, _ctx) => {
|
|
1433
|
+
void _ctx;
|
|
1328
1434
|
return `${this.quoteIdentifier(column.table)}.${this.quoteIdentifier(column.name)}`;
|
|
1329
1435
|
});
|
|
1330
1436
|
this.registerOperandCompiler(
|
|
1331
1437
|
"Function",
|
|
1332
1438
|
(fnNode, ctx) => this.compileFunctionOperand(fnNode, ctx)
|
|
1333
1439
|
);
|
|
1334
|
-
this.registerOperandCompiler("JsonPath", (path, _ctx) =>
|
|
1440
|
+
this.registerOperandCompiler("JsonPath", (path, _ctx) => {
|
|
1441
|
+
void _ctx;
|
|
1442
|
+
return this.compileJsonPath(path);
|
|
1443
|
+
});
|
|
1335
1444
|
this.registerOperandCompiler("ScalarSubquery", (node, ctx) => {
|
|
1336
1445
|
const sql = this.compileSelectAst(node.query, ctx).trim().replace(/;$/, "");
|
|
1337
1446
|
return `(${sql})`;
|
|
@@ -1375,7 +1484,8 @@ var Dialect = class _Dialect {
|
|
|
1375
1484
|
});
|
|
1376
1485
|
}
|
|
1377
1486
|
// Default fallback, should be overridden by dialects if supported
|
|
1378
|
-
compileJsonPath(
|
|
1487
|
+
compileJsonPath(_node) {
|
|
1488
|
+
void _node;
|
|
1379
1489
|
throw new Error("JSON Path not supported by this dialect");
|
|
1380
1490
|
}
|
|
1381
1491
|
/**
|
|
@@ -1541,6 +1651,7 @@ var NoReturningStrategy = class {
|
|
|
1541
1651
|
* @throws Error indicating RETURNING is not supported.
|
|
1542
1652
|
*/
|
|
1543
1653
|
compileReturning(returning, _ctx) {
|
|
1654
|
+
void _ctx;
|
|
1544
1655
|
if (!returning || returning.length === 0) return "";
|
|
1545
1656
|
throw new Error("RETURNING is not supported by this dialect.");
|
|
1546
1657
|
}
|
|
@@ -1942,6 +2053,7 @@ var PostgresDialect = class extends SqlDialectBase {
|
|
|
1942
2053
|
return `${col2}->>'${node.path}'`;
|
|
1943
2054
|
}
|
|
1944
2055
|
compileReturning(returning, ctx) {
|
|
2056
|
+
void ctx;
|
|
1945
2057
|
if (!returning || returning.length === 0) return "";
|
|
1946
2058
|
const columns = this.formatReturningColumns(returning);
|
|
1947
2059
|
return ` RETURNING ${columns}`;
|
|
@@ -2192,9 +2304,11 @@ var SqliteDialect = class extends SqlDialectBase {
|
|
|
2192
2304
|
return `json_extract(${col2}, '${node.path}')`;
|
|
2193
2305
|
}
|
|
2194
2306
|
compileQualifiedColumn(column, _table) {
|
|
2307
|
+
void _table;
|
|
2195
2308
|
return this.quoteIdentifier(column.name);
|
|
2196
2309
|
}
|
|
2197
2310
|
compileReturning(returning, ctx) {
|
|
2311
|
+
void ctx;
|
|
2198
2312
|
if (!returning || returning.length === 0) return "";
|
|
2199
2313
|
const columns = this.formatReturningColumns(returning);
|
|
2200
2314
|
return ` RETURNING ${columns}`;
|
|
@@ -2516,7 +2630,7 @@ var SelectQueryState = class _SelectQueryState {
|
|
|
2516
2630
|
this.table = table;
|
|
2517
2631
|
this.ast = ast ?? {
|
|
2518
2632
|
type: "SelectQuery",
|
|
2519
|
-
from:
|
|
2633
|
+
from: createTableNode(table),
|
|
2520
2634
|
columns: [],
|
|
2521
2635
|
joins: []
|
|
2522
2636
|
};
|
|
@@ -2667,10 +2781,18 @@ var SelectQueryState = class _SelectQueryState {
|
|
|
2667
2781
|
var createJoinNode = (kind, tableName, condition, relationName) => ({
|
|
2668
2782
|
type: "Join",
|
|
2669
2783
|
kind,
|
|
2670
|
-
table: typeof tableName === "string" ?
|
|
2784
|
+
table: typeof tableName === "string" ? parseQualifiedTableRef(tableName) : tableName,
|
|
2671
2785
|
condition,
|
|
2672
2786
|
meta: relationName ? { relationName } : void 0
|
|
2673
2787
|
});
|
|
2788
|
+
var parseQualifiedTableRef = (ref) => {
|
|
2789
|
+
const parts = ref.split(".");
|
|
2790
|
+
if (parts.length === 2) {
|
|
2791
|
+
const [schema, name] = parts;
|
|
2792
|
+
return { type: "Table", schema, name };
|
|
2793
|
+
}
|
|
2794
|
+
return { type: "Table", name: ref };
|
|
2795
|
+
};
|
|
2674
2796
|
|
|
2675
2797
|
// src/query-builder/hydration-manager.ts
|
|
2676
2798
|
var HydrationManager = class _HydrationManager {
|
|
@@ -2757,6 +2879,11 @@ var HydrationManager = class _HydrationManager {
|
|
|
2757
2879
|
const hasPagination = ast.limit !== void 0 || ast.offset !== void 0;
|
|
2758
2880
|
return hasPagination && this.hasMultiplyingRelations(plan);
|
|
2759
2881
|
}
|
|
2882
|
+
/**
|
|
2883
|
+
* Checks if the hydration plan contains relations that multiply rows
|
|
2884
|
+
* @param plan - Hydration plan to check
|
|
2885
|
+
* @returns True if plan has HasMany or BelongsToMany relations
|
|
2886
|
+
*/
|
|
2760
2887
|
hasMultiplyingRelations(plan) {
|
|
2761
2888
|
return plan.relations.some(
|
|
2762
2889
|
(rel) => rel.type === RelationKinds.HasMany || rel.type === RelationKinds.BelongsToMany
|
|
@@ -2834,6 +2961,12 @@ var HydrationManager = class _HydrationManager {
|
|
|
2834
2961
|
ctes: [...ast.ctes ?? [], baseCte, pageCte]
|
|
2835
2962
|
};
|
|
2836
2963
|
}
|
|
2964
|
+
/**
|
|
2965
|
+
* Generates a unique CTE name by appending a suffix if needed
|
|
2966
|
+
* @param existing - Existing CTE nodes
|
|
2967
|
+
* @param baseName - Base name for the CTE
|
|
2968
|
+
* @returns Unique CTE name
|
|
2969
|
+
*/
|
|
2837
2970
|
nextCteName(existing, baseName) {
|
|
2838
2971
|
const names = new Set((existing ?? []).map((cte) => cte.name));
|
|
2839
2972
|
let candidate = baseName;
|
|
@@ -2844,15 +2977,26 @@ var HydrationManager = class _HydrationManager {
|
|
|
2844
2977
|
}
|
|
2845
2978
|
return candidate;
|
|
2846
2979
|
}
|
|
2980
|
+
/**
|
|
2981
|
+
* Extracts projection names from column nodes
|
|
2982
|
+
* @param columns - Projection nodes
|
|
2983
|
+
* @returns Array of names or undefined if any column lacks name/alias
|
|
2984
|
+
*/
|
|
2847
2985
|
getProjectionNames(columns) {
|
|
2848
2986
|
const names = [];
|
|
2849
2987
|
for (const col2 of columns) {
|
|
2850
|
-
const
|
|
2988
|
+
const node = col2;
|
|
2989
|
+
const alias = node.alias ?? node.name;
|
|
2851
2990
|
if (!alias) return void 0;
|
|
2852
2991
|
names.push(alias);
|
|
2853
2992
|
}
|
|
2854
2993
|
return names;
|
|
2855
2994
|
}
|
|
2995
|
+
/**
|
|
2996
|
+
* Builds a map of column keys to their aliases from projection nodes
|
|
2997
|
+
* @param columns - Projection nodes
|
|
2998
|
+
* @returns Map of 'table.name' to alias
|
|
2999
|
+
*/
|
|
2856
3000
|
buildProjectionAliasMap(columns) {
|
|
2857
3001
|
const map = /* @__PURE__ */ new Map();
|
|
2858
3002
|
for (const col2 of columns) {
|
|
@@ -2863,6 +3007,15 @@ var HydrationManager = class _HydrationManager {
|
|
|
2863
3007
|
}
|
|
2864
3008
|
return map;
|
|
2865
3009
|
}
|
|
3010
|
+
/**
|
|
3011
|
+
* Maps order by nodes to use base CTE alias
|
|
3012
|
+
* @param orderBy - Original order by nodes
|
|
3013
|
+
* @param plan - Hydration plan
|
|
3014
|
+
* @param projectionAliases - Map of column aliases
|
|
3015
|
+
* @param baseAlias - Base CTE alias
|
|
3016
|
+
* @param availableColumns - Set of available column names
|
|
3017
|
+
* @returns Mapped order by nodes, null if cannot map
|
|
3018
|
+
*/
|
|
2866
3019
|
mapOrderBy(orderBy, plan, projectionAliases, baseAlias, availableColumns) {
|
|
2867
3020
|
if (!orderBy || orderBy.length === 0) {
|
|
2868
3021
|
return void 0;
|
|
@@ -2875,6 +3028,15 @@ var HydrationManager = class _HydrationManager {
|
|
|
2875
3028
|
}
|
|
2876
3029
|
return mapped;
|
|
2877
3030
|
}
|
|
3031
|
+
/**
|
|
3032
|
+
* Maps a single ordering term to use base CTE alias
|
|
3033
|
+
* @param term - Ordering term to map
|
|
3034
|
+
* @param plan - Hydration plan
|
|
3035
|
+
* @param projectionAliases - Map of column aliases
|
|
3036
|
+
* @param baseAlias - Base CTE alias
|
|
3037
|
+
* @param availableColumns - Set of available column names
|
|
3038
|
+
* @returns Mapped term or null if cannot map
|
|
3039
|
+
*/
|
|
2878
3040
|
mapOrderingTerm(term, plan, projectionAliases, baseAlias, availableColumns) {
|
|
2879
3041
|
if (term.type === "Column") {
|
|
2880
3042
|
const col2 = term;
|
|
@@ -2890,6 +3052,13 @@ var HydrationManager = class _HydrationManager {
|
|
|
2890
3052
|
}
|
|
2891
3053
|
return null;
|
|
2892
3054
|
}
|
|
3055
|
+
/**
|
|
3056
|
+
* Builds column nodes for paging CTE
|
|
3057
|
+
* @param primaryKey - Primary key name
|
|
3058
|
+
* @param orderBy - Order by nodes
|
|
3059
|
+
* @param tableAlias - Table alias for columns
|
|
3060
|
+
* @returns Array of column nodes for paging
|
|
3061
|
+
*/
|
|
2893
3062
|
buildPagingColumns(primaryKey, orderBy, tableAlias) {
|
|
2894
3063
|
const columns = [{ type: "Column", table: tableAlias, name: primaryKey, alias: primaryKey }];
|
|
2895
3064
|
if (!orderBy) return columns;
|
|
@@ -3064,7 +3233,8 @@ var buildDefaultHydrationPlan = (table) => ({
|
|
|
3064
3233
|
// src/query-builder/raw-column-parser.ts
|
|
3065
3234
|
var parseRawColumn = (col2, tableName, ctes) => {
|
|
3066
3235
|
if (col2.includes("(")) {
|
|
3067
|
-
const [
|
|
3236
|
+
const [_fn, rest] = col2.split("(");
|
|
3237
|
+
void _fn;
|
|
3068
3238
|
const colName = rest.replace(")", "");
|
|
3069
3239
|
const [table, name] = colName.includes(".") ? colName.split(".") : [tableName, colName];
|
|
3070
3240
|
return { type: "Column", table, name, alias: col2 };
|
|
@@ -3261,10 +3431,15 @@ var QueryAstService = class {
|
|
|
3261
3431
|
combineExpressions(existing, next) {
|
|
3262
3432
|
return existing ? and(existing, next) : next;
|
|
3263
3433
|
}
|
|
3434
|
+
/**
|
|
3435
|
+
* Normalizes an ordering term to a standard OrderingTerm
|
|
3436
|
+
* @param term - Column definition or ordering term to normalize
|
|
3437
|
+
* @returns Normalized ordering term
|
|
3438
|
+
*/
|
|
3264
3439
|
normalizeOrderingTerm(term) {
|
|
3265
3440
|
const from = this.state.ast.from;
|
|
3266
3441
|
const tableRef2 = from.type === "Table" && from.alias ? { ...this.table, alias: from.alias } : this.table;
|
|
3267
|
-
const termType = term
|
|
3442
|
+
const termType = term.type;
|
|
3268
3443
|
if (termType === "Column") {
|
|
3269
3444
|
return term;
|
|
3270
3445
|
}
|
|
@@ -3377,7 +3552,11 @@ var buildBelongsToManyJoins = (root, relationName, relation, joinKind, extra, ro
|
|
|
3377
3552
|
{ type: "Column", table: relation.pivotTable.name, name: relation.pivotForeignKeyToRoot },
|
|
3378
3553
|
{ type: "Column", table: rootTable, name: rootKey }
|
|
3379
3554
|
);
|
|
3380
|
-
const pivotJoin = createJoinNode(
|
|
3555
|
+
const pivotJoin = createJoinNode(
|
|
3556
|
+
joinKind,
|
|
3557
|
+
{ type: "Table", name: relation.pivotTable.name, schema: relation.pivotTable.schema },
|
|
3558
|
+
pivotCondition
|
|
3559
|
+
);
|
|
3381
3560
|
let targetCondition = eq(
|
|
3382
3561
|
{ type: "Column", table: relation.target.name, name: targetKey },
|
|
3383
3562
|
{ type: "Column", table: relation.pivotTable.name, name: relation.pivotForeignKeyToTarget }
|
|
@@ -3387,7 +3566,7 @@ var buildBelongsToManyJoins = (root, relationName, relation, joinKind, extra, ro
|
|
|
3387
3566
|
}
|
|
3388
3567
|
const targetJoin = createJoinNode(
|
|
3389
3568
|
joinKind,
|
|
3390
|
-
relation.target.name,
|
|
3569
|
+
{ type: "Table", name: relation.target.name, schema: relation.target.schema },
|
|
3391
3570
|
targetCondition,
|
|
3392
3571
|
relationName
|
|
3393
3572
|
);
|
|
@@ -3565,7 +3744,12 @@ var RelationService = class {
|
|
|
3565
3744
|
return joins.reduce((current, join) => this.astService(current).withJoin(join), state);
|
|
3566
3745
|
}
|
|
3567
3746
|
const condition = buildRelationJoinCondition(this.table, relation, extraCondition, rootAlias);
|
|
3568
|
-
const joinNode = createJoinNode(
|
|
3747
|
+
const joinNode = createJoinNode(
|
|
3748
|
+
joinKind,
|
|
3749
|
+
{ type: "Table", name: relation.target.name, schema: relation.target.schema },
|
|
3750
|
+
condition,
|
|
3751
|
+
relationName
|
|
3752
|
+
);
|
|
3569
3753
|
return this.astService(state).withJoin(joinNode);
|
|
3570
3754
|
}
|
|
3571
3755
|
/**
|
|
@@ -3610,25 +3794,6 @@ var RelationService = class {
|
|
|
3610
3794
|
}
|
|
3611
3795
|
};
|
|
3612
3796
|
|
|
3613
|
-
// src/query-builder/select-query-builder-deps.ts
|
|
3614
|
-
var defaultCreateQueryAstService = (table, state) => new QueryAstService(table, state);
|
|
3615
|
-
var defaultCreateHydrationPlanner = (table) => new HydrationPlanner(table);
|
|
3616
|
-
var defaultCreateHydration = (table, plannerFactory) => new HydrationManager(table, plannerFactory(table));
|
|
3617
|
-
var resolveSelectQueryBuilderDependencies = (overrides = {}) => {
|
|
3618
|
-
const createQueryAstService = overrides.createQueryAstService ?? defaultCreateQueryAstService;
|
|
3619
|
-
const createHydrationPlanner = overrides.createHydrationPlanner ?? defaultCreateHydrationPlanner;
|
|
3620
|
-
const createHydration = overrides.createHydration ?? ((table) => defaultCreateHydration(table, createHydrationPlanner));
|
|
3621
|
-
const createRelationService = overrides.createRelationService ?? ((table, state, hydration) => new RelationService(table, state, hydration, createQueryAstService));
|
|
3622
|
-
return {
|
|
3623
|
-
createState: overrides.createState ?? ((table) => new SelectQueryState(table)),
|
|
3624
|
-
createHydration,
|
|
3625
|
-
createHydrationPlanner,
|
|
3626
|
-
createQueryAstService,
|
|
3627
|
-
createRelationService
|
|
3628
|
-
};
|
|
3629
|
-
};
|
|
3630
|
-
var defaultSelectQueryBuilderDependencies = resolveSelectQueryBuilderDependencies();
|
|
3631
|
-
|
|
3632
3797
|
// src/query-builder/column-selector.ts
|
|
3633
3798
|
var ColumnSelector = class {
|
|
3634
3799
|
/**
|
|
@@ -3754,6 +3919,29 @@ var RelationManager = class {
|
|
|
3754
3919
|
}
|
|
3755
3920
|
};
|
|
3756
3921
|
|
|
3922
|
+
// src/query-builder/select-query-builder-deps.ts
|
|
3923
|
+
var defaultCreateQueryAstService = (table, state) => new QueryAstService(table, state);
|
|
3924
|
+
var defaultCreateHydrationPlanner = (table) => new HydrationPlanner(table);
|
|
3925
|
+
var defaultCreateHydration = (table, plannerFactory) => new HydrationManager(table, plannerFactory(table));
|
|
3926
|
+
var resolveSelectQueryBuilderDependencies = (overrides = {}) => {
|
|
3927
|
+
const createQueryAstService = overrides.createQueryAstService ?? defaultCreateQueryAstService;
|
|
3928
|
+
const createHydrationPlanner = overrides.createHydrationPlanner ?? defaultCreateHydrationPlanner;
|
|
3929
|
+
const createHydration = overrides.createHydration ?? ((table) => defaultCreateHydration(table, createHydrationPlanner));
|
|
3930
|
+
const createRelationService = overrides.createRelationService ?? ((table, state, hydration) => new RelationService(table, state, hydration, createQueryAstService));
|
|
3931
|
+
const createColumnSelector = overrides.createColumnSelector ?? ((env) => new ColumnSelector(env));
|
|
3932
|
+
const createRelationManager = overrides.createRelationManager ?? ((env) => new RelationManager(env));
|
|
3933
|
+
return {
|
|
3934
|
+
createState: overrides.createState ?? ((table) => new SelectQueryState(table)),
|
|
3935
|
+
createHydration,
|
|
3936
|
+
createHydrationPlanner,
|
|
3937
|
+
createQueryAstService,
|
|
3938
|
+
createRelationService,
|
|
3939
|
+
createColumnSelector,
|
|
3940
|
+
createRelationManager
|
|
3941
|
+
};
|
|
3942
|
+
};
|
|
3943
|
+
var defaultSelectQueryBuilderDependencies = resolveSelectQueryBuilderDependencies();
|
|
3944
|
+
|
|
3757
3945
|
// src/orm/hydration.ts
|
|
3758
3946
|
var hydrateRows = (rows, plan) => {
|
|
3759
3947
|
if (!plan || !rows.length) return rows;
|
|
@@ -3879,6 +4067,18 @@ var hideInternal = (obj, keys) => {
|
|
|
3879
4067
|
}
|
|
3880
4068
|
};
|
|
3881
4069
|
var DefaultHasManyCollection = class {
|
|
4070
|
+
/**
|
|
4071
|
+
* Creates a new DefaultHasManyCollection instance.
|
|
4072
|
+
* @param ctx - The entity context
|
|
4073
|
+
* @param meta - The entity metadata
|
|
4074
|
+
* @param root - The root entity
|
|
4075
|
+
* @param relationName - The relation name
|
|
4076
|
+
* @param relation - The relation definition
|
|
4077
|
+
* @param rootTable - The root table definition
|
|
4078
|
+
* @param loader - The loader function for lazy loading
|
|
4079
|
+
* @param createEntity - Function to create entities from rows
|
|
4080
|
+
* @param localKey - The local key for the relation
|
|
4081
|
+
*/
|
|
3882
4082
|
constructor(ctx, meta, root, relationName, relation, rootTable, loader, createEntity, localKey) {
|
|
3883
4083
|
this.ctx = ctx;
|
|
3884
4084
|
this.meta = meta;
|
|
@@ -3896,6 +4096,10 @@ var DefaultHasManyCollection = class {
|
|
|
3896
4096
|
hideInternal(this, ["ctx", "meta", "root", "relationName", "relation", "rootTable", "loader", "createEntity", "localKey"]);
|
|
3897
4097
|
this.hydrateFromCache();
|
|
3898
4098
|
}
|
|
4099
|
+
/**
|
|
4100
|
+
* Loads the related entities if not already loaded.
|
|
4101
|
+
* @returns Promise resolving to the array of child entities
|
|
4102
|
+
*/
|
|
3899
4103
|
async load() {
|
|
3900
4104
|
if (this.loaded) return this.items;
|
|
3901
4105
|
const map = await this.loader();
|
|
@@ -3905,9 +4109,18 @@ var DefaultHasManyCollection = class {
|
|
|
3905
4109
|
this.loaded = true;
|
|
3906
4110
|
return this.items;
|
|
3907
4111
|
}
|
|
4112
|
+
/**
|
|
4113
|
+
* Gets the current items in the collection.
|
|
4114
|
+
* @returns Array of child entities
|
|
4115
|
+
*/
|
|
3908
4116
|
getItems() {
|
|
3909
4117
|
return this.items;
|
|
3910
4118
|
}
|
|
4119
|
+
/**
|
|
4120
|
+
* Adds a new child entity to the collection.
|
|
4121
|
+
* @param data - Partial data for the new entity
|
|
4122
|
+
* @returns The created entity
|
|
4123
|
+
*/
|
|
3911
4124
|
add(data) {
|
|
3912
4125
|
const keyValue = this.root[this.localKey];
|
|
3913
4126
|
const childRow = {
|
|
@@ -3927,6 +4140,10 @@ var DefaultHasManyCollection = class {
|
|
|
3927
4140
|
);
|
|
3928
4141
|
return entity;
|
|
3929
4142
|
}
|
|
4143
|
+
/**
|
|
4144
|
+
* Attaches an existing entity to the collection.
|
|
4145
|
+
* @param entity - The entity to attach
|
|
4146
|
+
*/
|
|
3930
4147
|
attach(entity) {
|
|
3931
4148
|
const keyValue = this.root[this.localKey];
|
|
3932
4149
|
entity[this.relation.foreignKey] = keyValue;
|
|
@@ -3941,6 +4158,10 @@ var DefaultHasManyCollection = class {
|
|
|
3941
4158
|
{ kind: "attach", entity }
|
|
3942
4159
|
);
|
|
3943
4160
|
}
|
|
4161
|
+
/**
|
|
4162
|
+
* Removes an entity from the collection.
|
|
4163
|
+
* @param entity - The entity to remove
|
|
4164
|
+
*/
|
|
3944
4165
|
remove(entity) {
|
|
3945
4166
|
this.items = this.items.filter((item) => item !== entity);
|
|
3946
4167
|
this.removed.add(entity);
|
|
@@ -3953,6 +4174,9 @@ var DefaultHasManyCollection = class {
|
|
|
3953
4174
|
{ kind: "remove", entity }
|
|
3954
4175
|
);
|
|
3955
4176
|
}
|
|
4177
|
+
/**
|
|
4178
|
+
* Clears all entities from the collection.
|
|
4179
|
+
*/
|
|
3956
4180
|
clear() {
|
|
3957
4181
|
for (const entity of [...this.items]) {
|
|
3958
4182
|
this.remove(entity);
|
|
@@ -3969,6 +4193,10 @@ var DefaultHasManyCollection = class {
|
|
|
3969
4193
|
this.items = rows.map((row) => this.createEntity(row));
|
|
3970
4194
|
this.loaded = true;
|
|
3971
4195
|
}
|
|
4196
|
+
/**
|
|
4197
|
+
* Returns the items for JSON serialization.
|
|
4198
|
+
* @returns Array of child entities
|
|
4199
|
+
*/
|
|
3972
4200
|
toJSON() {
|
|
3973
4201
|
return this.items;
|
|
3974
4202
|
}
|
|
@@ -4264,7 +4492,6 @@ var DefaultManyToManyCollection = class {
|
|
|
4264
4492
|
}
|
|
4265
4493
|
async syncByIds(ids) {
|
|
4266
4494
|
await this.load();
|
|
4267
|
-
const targetKey = this.relation.targetKey || findPrimaryKey(this.relation.target);
|
|
4268
4495
|
const normalized = new Set(ids.map((id) => toKey5(id)));
|
|
4269
4496
|
const currentIds = new Set(this.items.map((item) => toKey5(this.extractId(item))));
|
|
4270
4497
|
for (const id of normalized) {
|
|
@@ -4345,112 +4572,92 @@ var executeQuery = async (ctx, qb) => {
|
|
|
4345
4572
|
return rowsFromResults(results);
|
|
4346
4573
|
};
|
|
4347
4574
|
var toKey6 = (value) => value === null || value === void 0 ? "" : String(value);
|
|
4348
|
-
var
|
|
4349
|
-
const
|
|
4350
|
-
const roots = ctx.getEntitiesForTable(rootTable);
|
|
4351
|
-
const keys = /* @__PURE__ */ new Set();
|
|
4575
|
+
var collectKeysFromRoots = (roots, key) => {
|
|
4576
|
+
const collected = /* @__PURE__ */ new Set();
|
|
4352
4577
|
for (const tracked of roots) {
|
|
4353
|
-
const value = tracked.entity[
|
|
4578
|
+
const value = tracked.entity[key];
|
|
4354
4579
|
if (value !== null && value !== void 0) {
|
|
4355
|
-
|
|
4580
|
+
collected.add(value);
|
|
4356
4581
|
}
|
|
4357
4582
|
}
|
|
4358
|
-
|
|
4359
|
-
|
|
4360
|
-
|
|
4361
|
-
|
|
4362
|
-
const
|
|
4363
|
-
|
|
4364
|
-
|
|
4365
|
-
|
|
4366
|
-
|
|
4583
|
+
return collected;
|
|
4584
|
+
};
|
|
4585
|
+
var buildInListValues = (keys) => Array.from(keys);
|
|
4586
|
+
var fetchRowsForKeys = async (ctx, table, column, keys) => {
|
|
4587
|
+
const qb = new SelectQueryBuilder(table).select(selectAllColumns(table));
|
|
4588
|
+
qb.where(inList(column, buildInListValues(keys)));
|
|
4589
|
+
return executeQuery(ctx, qb);
|
|
4590
|
+
};
|
|
4591
|
+
var groupRowsByMany = (rows, keyColumn) => {
|
|
4367
4592
|
const grouped = /* @__PURE__ */ new Map();
|
|
4368
4593
|
for (const row of rows) {
|
|
4369
|
-
const
|
|
4370
|
-
if (
|
|
4371
|
-
const key = toKey6(
|
|
4594
|
+
const value = row[keyColumn];
|
|
4595
|
+
if (value === null || value === void 0) continue;
|
|
4596
|
+
const key = toKey6(value);
|
|
4372
4597
|
const bucket = grouped.get(key) ?? [];
|
|
4373
4598
|
bucket.push(row);
|
|
4374
4599
|
grouped.set(key, bucket);
|
|
4375
4600
|
}
|
|
4376
4601
|
return grouped;
|
|
4377
4602
|
};
|
|
4378
|
-
var
|
|
4379
|
-
const
|
|
4380
|
-
const
|
|
4381
|
-
|
|
4382
|
-
|
|
4383
|
-
const
|
|
4384
|
-
if (
|
|
4385
|
-
|
|
4603
|
+
var groupRowsByUnique = (rows, keyColumn) => {
|
|
4604
|
+
const lookup = /* @__PURE__ */ new Map();
|
|
4605
|
+
for (const row of rows) {
|
|
4606
|
+
const value = row[keyColumn];
|
|
4607
|
+
if (value === null || value === void 0) continue;
|
|
4608
|
+
const key = toKey6(value);
|
|
4609
|
+
if (!lookup.has(key)) {
|
|
4610
|
+
lookup.set(key, row);
|
|
4386
4611
|
}
|
|
4387
4612
|
}
|
|
4613
|
+
return lookup;
|
|
4614
|
+
};
|
|
4615
|
+
var loadHasManyRelation = async (ctx, rootTable, _relationName, relation) => {
|
|
4616
|
+
const localKey = relation.localKey || findPrimaryKey(rootTable);
|
|
4617
|
+
const roots = ctx.getEntitiesForTable(rootTable);
|
|
4618
|
+
const keys = collectKeysFromRoots(roots, localKey);
|
|
4388
4619
|
if (!keys.size) {
|
|
4389
4620
|
return /* @__PURE__ */ new Map();
|
|
4390
4621
|
}
|
|
4391
|
-
const selectMap = selectAllColumns(relation.target);
|
|
4392
|
-
const qb = new SelectQueryBuilder(relation.target).select(selectMap);
|
|
4393
4622
|
const fkColumn = relation.target.columns[relation.foreignKey];
|
|
4394
4623
|
if (!fkColumn) return /* @__PURE__ */ new Map();
|
|
4395
|
-
|
|
4396
|
-
|
|
4397
|
-
|
|
4398
|
-
|
|
4399
|
-
|
|
4400
|
-
|
|
4401
|
-
|
|
4402
|
-
|
|
4403
|
-
|
|
4404
|
-
}
|
|
4624
|
+
const rows = await fetchRowsForKeys(ctx, relation.target, fkColumn, keys);
|
|
4625
|
+
return groupRowsByMany(rows, relation.foreignKey);
|
|
4626
|
+
};
|
|
4627
|
+
var loadHasOneRelation = async (ctx, rootTable, _relationName, relation) => {
|
|
4628
|
+
const localKey = relation.localKey || findPrimaryKey(rootTable);
|
|
4629
|
+
const roots = ctx.getEntitiesForTable(rootTable);
|
|
4630
|
+
const keys = collectKeysFromRoots(roots, localKey);
|
|
4631
|
+
if (!keys.size) {
|
|
4632
|
+
return /* @__PURE__ */ new Map();
|
|
4405
4633
|
}
|
|
4406
|
-
|
|
4634
|
+
const fkColumn = relation.target.columns[relation.foreignKey];
|
|
4635
|
+
if (!fkColumn) return /* @__PURE__ */ new Map();
|
|
4636
|
+
const rows = await fetchRowsForKeys(ctx, relation.target, fkColumn, keys);
|
|
4637
|
+
return groupRowsByUnique(rows, relation.foreignKey);
|
|
4407
4638
|
};
|
|
4408
4639
|
var loadBelongsToRelation = async (ctx, rootTable, _relationName, relation) => {
|
|
4409
4640
|
const roots = ctx.getEntitiesForTable(rootTable);
|
|
4410
|
-
const foreignKeys =
|
|
4411
|
-
for (const tracked of roots) {
|
|
4412
|
-
const value = tracked.entity[relation.foreignKey];
|
|
4413
|
-
if (value !== null && value !== void 0) {
|
|
4414
|
-
foreignKeys.add(value);
|
|
4415
|
-
}
|
|
4416
|
-
}
|
|
4641
|
+
const foreignKeys = collectKeysFromRoots(roots, relation.foreignKey);
|
|
4417
4642
|
if (!foreignKeys.size) {
|
|
4418
4643
|
return /* @__PURE__ */ new Map();
|
|
4419
4644
|
}
|
|
4420
|
-
const selectMap = selectAllColumns(relation.target);
|
|
4421
|
-
const qb = new SelectQueryBuilder(relation.target).select(selectMap);
|
|
4422
4645
|
const targetKey = relation.localKey || findPrimaryKey(relation.target);
|
|
4423
4646
|
const pkColumn = relation.target.columns[targetKey];
|
|
4424
4647
|
if (!pkColumn) return /* @__PURE__ */ new Map();
|
|
4425
|
-
|
|
4426
|
-
|
|
4427
|
-
const map = /* @__PURE__ */ new Map();
|
|
4428
|
-
for (const row of rows) {
|
|
4429
|
-
const keyValue = row[targetKey];
|
|
4430
|
-
if (keyValue === null || keyValue === void 0) continue;
|
|
4431
|
-
map.set(toKey6(keyValue), row);
|
|
4432
|
-
}
|
|
4433
|
-
return map;
|
|
4648
|
+
const rows = await fetchRowsForKeys(ctx, relation.target, pkColumn, foreignKeys);
|
|
4649
|
+
return groupRowsByUnique(rows, targetKey);
|
|
4434
4650
|
};
|
|
4435
4651
|
var loadBelongsToManyRelation = async (ctx, rootTable, _relationName, relation) => {
|
|
4436
4652
|
const rootKey = relation.localKey || findPrimaryKey(rootTable);
|
|
4437
4653
|
const roots = ctx.getEntitiesForTable(rootTable);
|
|
4438
|
-
const rootIds =
|
|
4439
|
-
for (const tracked of roots) {
|
|
4440
|
-
const value = tracked.entity[rootKey];
|
|
4441
|
-
if (value !== null && value !== void 0) {
|
|
4442
|
-
rootIds.add(value);
|
|
4443
|
-
}
|
|
4444
|
-
}
|
|
4654
|
+
const rootIds = collectKeysFromRoots(roots, rootKey);
|
|
4445
4655
|
if (!rootIds.size) {
|
|
4446
4656
|
return /* @__PURE__ */ new Map();
|
|
4447
4657
|
}
|
|
4448
|
-
const
|
|
4449
|
-
|
|
4450
|
-
const
|
|
4451
|
-
if (!pivotFkCol) return /* @__PURE__ */ new Map();
|
|
4452
|
-
pivotQb.where(inList(pivotFkCol, Array.from(rootIds)));
|
|
4453
|
-
const pivotRows = await executeQuery(ctx, pivotQb);
|
|
4658
|
+
const pivotColumn = relation.pivotTable.columns[relation.pivotForeignKeyToRoot];
|
|
4659
|
+
if (!pivotColumn) return /* @__PURE__ */ new Map();
|
|
4660
|
+
const pivotRows = await fetchRowsForKeys(ctx, relation.pivotTable, pivotColumn, rootIds);
|
|
4454
4661
|
const rootLookup = /* @__PURE__ */ new Map();
|
|
4455
4662
|
const targetIds = /* @__PURE__ */ new Set();
|
|
4456
4663
|
for (const pivot of pivotRows) {
|
|
@@ -4470,19 +4677,11 @@ var loadBelongsToManyRelation = async (ctx, rootTable, _relationName, relation)
|
|
|
4470
4677
|
if (!targetIds.size) {
|
|
4471
4678
|
return /* @__PURE__ */ new Map();
|
|
4472
4679
|
}
|
|
4473
|
-
const targetSelect = selectAllColumns(relation.target);
|
|
4474
4680
|
const targetKey = relation.targetKey || findPrimaryKey(relation.target);
|
|
4475
4681
|
const targetPkColumn = relation.target.columns[targetKey];
|
|
4476
4682
|
if (!targetPkColumn) return /* @__PURE__ */ new Map();
|
|
4477
|
-
const
|
|
4478
|
-
|
|
4479
|
-
const targetRows = await executeQuery(ctx, targetQb);
|
|
4480
|
-
const targetMap = /* @__PURE__ */ new Map();
|
|
4481
|
-
for (const row of targetRows) {
|
|
4482
|
-
const pkValue = row[targetKey];
|
|
4483
|
-
if (pkValue === null || pkValue === void 0) continue;
|
|
4484
|
-
targetMap.set(toKey6(pkValue), row);
|
|
4485
|
-
}
|
|
4683
|
+
const targetRows = await fetchRowsForKeys(ctx, relation.target, targetPkColumn, targetIds);
|
|
4684
|
+
const targetMap = groupRowsByUnique(targetRows, targetKey);
|
|
4486
4685
|
const result = /* @__PURE__ */ new Map();
|
|
4487
4686
|
for (const [rootId, entries] of rootLookup.entries()) {
|
|
4488
4687
|
const bucket = [];
|
|
@@ -4535,7 +4734,6 @@ var createEntityProxy = (ctx, table, row, lazyRelations = []) => {
|
|
|
4535
4734
|
enumerable: false,
|
|
4536
4735
|
writable: false
|
|
4537
4736
|
});
|
|
4538
|
-
let proxy;
|
|
4539
4737
|
const handler = {
|
|
4540
4738
|
get(targetObj, prop, receiver) {
|
|
4541
4739
|
if (prop === ENTITY_META) {
|
|
@@ -4543,7 +4741,7 @@ var createEntityProxy = (ctx, table, row, lazyRelations = []) => {
|
|
|
4543
4741
|
}
|
|
4544
4742
|
if (prop === "$load") {
|
|
4545
4743
|
return async (relationName) => {
|
|
4546
|
-
const wrapper = getRelationWrapper(meta, relationName,
|
|
4744
|
+
const wrapper = getRelationWrapper(meta, relationName, receiver);
|
|
4547
4745
|
if (wrapper && typeof wrapper.load === "function") {
|
|
4548
4746
|
return wrapper.load();
|
|
4549
4747
|
}
|
|
@@ -4551,19 +4749,19 @@ var createEntityProxy = (ctx, table, row, lazyRelations = []) => {
|
|
|
4551
4749
|
};
|
|
4552
4750
|
}
|
|
4553
4751
|
if (typeof prop === "string" && table.relations[prop]) {
|
|
4554
|
-
return getRelationWrapper(meta, prop,
|
|
4752
|
+
return getRelationWrapper(meta, prop, receiver);
|
|
4555
4753
|
}
|
|
4556
4754
|
return Reflect.get(targetObj, prop, receiver);
|
|
4557
4755
|
},
|
|
4558
4756
|
set(targetObj, prop, value, receiver) {
|
|
4559
4757
|
const result = Reflect.set(targetObj, prop, value, receiver);
|
|
4560
4758
|
if (typeof prop === "string" && table.columns[prop]) {
|
|
4561
|
-
ctx.markDirty(
|
|
4759
|
+
ctx.markDirty(receiver);
|
|
4562
4760
|
}
|
|
4563
4761
|
return result;
|
|
4564
4762
|
}
|
|
4565
4763
|
};
|
|
4566
|
-
proxy = new Proxy(target, handler);
|
|
4764
|
+
const proxy = new Proxy(target, handler);
|
|
4567
4765
|
populateHydrationCache(proxy, row, meta);
|
|
4568
4766
|
return proxy;
|
|
4569
4767
|
};
|
|
@@ -4760,21 +4958,21 @@ async function executeHydratedWithContexts(_execCtx, hydCtx, qb) {
|
|
|
4760
4958
|
return executeWithEntityContext(entityCtx, qb);
|
|
4761
4959
|
}
|
|
4762
4960
|
|
|
4961
|
+
// src/query-builder/query-resolution.ts
|
|
4962
|
+
function resolveSelectQuery(query) {
|
|
4963
|
+
const candidate = query;
|
|
4964
|
+
return typeof candidate.getAST === "function" && candidate.getAST ? candidate.getAST() : query;
|
|
4965
|
+
}
|
|
4966
|
+
|
|
4763
4967
|
// src/query-builder/select.ts
|
|
4764
4968
|
var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
4765
4969
|
/**
|
|
4766
|
-
|
|
4767
|
-
|
|
4768
|
-
|
|
4769
|
-
|
|
4770
|
-
|
|
4771
|
-
|
|
4772
|
-
|
|
4773
|
-
* @param hydration - Optional hydration manager
|
|
4774
|
-
|
|
4775
|
-
* @param dependencies - Optional query builder dependencies
|
|
4776
|
-
|
|
4777
|
-
*/
|
|
4970
|
+
* Creates a new SelectQueryBuilder instance
|
|
4971
|
+
* @param table - Table definition to query
|
|
4972
|
+
* @param state - Optional initial query state
|
|
4973
|
+
* @param hydration - Optional hydration manager
|
|
4974
|
+
* @param dependencies - Optional query builder dependencies
|
|
4975
|
+
*/
|
|
4778
4976
|
constructor(table, state, hydration, dependencies, lazyRelations) {
|
|
4779
4977
|
const deps = resolveSelectQueryBuilderDependencies(dependencies);
|
|
4780
4978
|
this.env = { table, deps };
|
|
@@ -4785,9 +4983,15 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
4785
4983
|
hydration: initialHydration
|
|
4786
4984
|
};
|
|
4787
4985
|
this.lazyRelations = new Set(lazyRelations ?? []);
|
|
4788
|
-
this.columnSelector =
|
|
4789
|
-
this.relationManager =
|
|
4986
|
+
this.columnSelector = deps.createColumnSelector(this.env);
|
|
4987
|
+
this.relationManager = deps.createRelationManager(this.env);
|
|
4790
4988
|
}
|
|
4989
|
+
/**
|
|
4990
|
+
* Creates a new SelectQueryBuilder instance with updated context and lazy relations
|
|
4991
|
+
* @param context - Updated query context
|
|
4992
|
+
* @param lazyRelations - Updated lazy relations set
|
|
4993
|
+
* @returns New SelectQueryBuilder instance
|
|
4994
|
+
*/
|
|
4791
4995
|
clone(context = this.context, lazyRelations = new Set(this.lazyRelations)) {
|
|
4792
4996
|
return new _SelectQueryBuilder(this.env.table, context.state, context.hydration, this.env.deps, lazyRelations);
|
|
4793
4997
|
}
|
|
@@ -4804,9 +5008,12 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
4804
5008
|
const nextContext = this.applyAst(this.context, (service) => service.withFrom(nextFrom));
|
|
4805
5009
|
return this.clone(nextContext);
|
|
4806
5010
|
}
|
|
4807
|
-
|
|
4808
|
-
|
|
4809
|
-
|
|
5011
|
+
/**
|
|
5012
|
+
* Applies correlation expression to the query AST
|
|
5013
|
+
* @param ast - Query AST to modify
|
|
5014
|
+
* @param correlation - Correlation expression
|
|
5015
|
+
* @returns Modified AST with correlation applied
|
|
5016
|
+
*/
|
|
4810
5017
|
applyCorrelation(ast, correlation) {
|
|
4811
5018
|
if (!correlation) return ast;
|
|
4812
5019
|
const combinedWhere = ast.where ? and(correlation, ast.where) : correlation;
|
|
@@ -4815,39 +5022,53 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
4815
5022
|
where: combinedWhere
|
|
4816
5023
|
};
|
|
4817
5024
|
}
|
|
5025
|
+
/**
|
|
5026
|
+
* Creates a new child query builder for a related table
|
|
5027
|
+
* @param table - Table definition for the child builder
|
|
5028
|
+
* @returns New SelectQueryBuilder instance for the child table
|
|
5029
|
+
*/
|
|
4818
5030
|
createChildBuilder(table) {
|
|
4819
5031
|
return new _SelectQueryBuilder(table, void 0, void 0, this.env.deps);
|
|
4820
5032
|
}
|
|
5033
|
+
/**
|
|
5034
|
+
* Applies an AST mutation using the query AST service
|
|
5035
|
+
* @param context - Current query context
|
|
5036
|
+
* @param mutator - Function that mutates the AST
|
|
5037
|
+
* @returns Updated query context
|
|
5038
|
+
*/
|
|
4821
5039
|
applyAst(context, mutator) {
|
|
4822
5040
|
const astService = this.env.deps.createQueryAstService(this.env.table, context.state);
|
|
4823
5041
|
const nextState = mutator(astService);
|
|
4824
5042
|
return { state: nextState, hydration: context.hydration };
|
|
4825
5043
|
}
|
|
5044
|
+
/**
|
|
5045
|
+
* Applies a join to the query context
|
|
5046
|
+
* @param context - Current query context
|
|
5047
|
+
* @param table - Table to join
|
|
5048
|
+
* @param condition - Join condition
|
|
5049
|
+
* @param kind - Join kind
|
|
5050
|
+
* @returns Updated query context with join applied
|
|
5051
|
+
*/
|
|
4826
5052
|
applyJoin(context, table, condition, kind) {
|
|
4827
|
-
const joinNode = createJoinNode(kind, table.name, condition);
|
|
5053
|
+
const joinNode = createJoinNode(kind, { type: "Table", name: table.name, schema: table.schema }, condition);
|
|
4828
5054
|
return this.applyAst(context, (service) => service.withJoin(joinNode));
|
|
4829
5055
|
}
|
|
5056
|
+
/**
|
|
5057
|
+
* Applies a set operation to the query
|
|
5058
|
+
* @param operator - Set operation kind
|
|
5059
|
+
* @param query - Query to combine with
|
|
5060
|
+
* @returns Updated query context with set operation
|
|
5061
|
+
*/
|
|
4830
5062
|
applySetOperation(operator, query) {
|
|
4831
|
-
const subAst =
|
|
5063
|
+
const subAst = resolveSelectQuery(query);
|
|
4832
5064
|
return this.applyAst(this.context, (service) => service.withSetOperation(operator, subAst));
|
|
4833
5065
|
}
|
|
4834
|
-
|
|
4835
|
-
|
|
4836
|
-
|
|
4837
|
-
|
|
4838
|
-
|
|
4839
|
-
|
|
4840
|
-
* @returns New query builder instance with selected columns
|
|
4841
|
-
|
|
4842
|
-
*/
|
|
4843
|
-
select(columns) {
|
|
4844
|
-
return this.clone(this.columnSelector.select(this.context, columns));
|
|
4845
|
-
}
|
|
4846
|
-
/**
|
|
4847
|
-
* Selects columns from the root table by name (typed).
|
|
4848
|
-
* @param cols - Column names on the root table
|
|
4849
|
-
*/
|
|
4850
|
-
selectColumns(...cols) {
|
|
5066
|
+
select(...args) {
|
|
5067
|
+
if (args.length === 1 && typeof args[0] === "object" && args[0] !== null && typeof args[0] !== "string") {
|
|
5068
|
+
const columns = args[0];
|
|
5069
|
+
return this.clone(this.columnSelector.select(this.context, columns));
|
|
5070
|
+
}
|
|
5071
|
+
const cols = args;
|
|
4851
5072
|
const selection = {};
|
|
4852
5073
|
for (const key of cols) {
|
|
4853
5074
|
const col2 = this.env.table.columns[key];
|
|
@@ -4856,53 +5077,37 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
4856
5077
|
}
|
|
4857
5078
|
selection[key] = col2;
|
|
4858
5079
|
}
|
|
4859
|
-
return this.select(selection);
|
|
5080
|
+
return this.clone(this.columnSelector.select(this.context, selection));
|
|
4860
5081
|
}
|
|
4861
5082
|
/**
|
|
4862
|
-
|
|
4863
|
-
|
|
4864
|
-
|
|
4865
|
-
|
|
4866
|
-
|
|
4867
|
-
* @returns New query builder instance with raw column selections
|
|
4868
|
-
|
|
4869
|
-
*/
|
|
5083
|
+
* Selects raw column expressions
|
|
5084
|
+
* @param cols - Column expressions as strings
|
|
5085
|
+
* @returns New query builder instance with raw column selections
|
|
5086
|
+
*/
|
|
4870
5087
|
selectRaw(...cols) {
|
|
4871
5088
|
return this.clone(this.columnSelector.selectRaw(this.context, cols));
|
|
4872
5089
|
}
|
|
4873
5090
|
/**
|
|
4874
|
-
|
|
4875
|
-
|
|
4876
|
-
|
|
4877
|
-
|
|
4878
|
-
|
|
4879
|
-
|
|
4880
|
-
|
|
4881
|
-
* @param columns - Optional column names for the CTE
|
|
4882
|
-
|
|
4883
|
-
* @returns New query builder instance with the CTE
|
|
4884
|
-
|
|
4885
|
-
*/
|
|
5091
|
+
* Adds a Common Table Expression (CTE) to the query
|
|
5092
|
+
* @param name - Name of the CTE
|
|
5093
|
+
* @param query - Query builder or query node for the CTE
|
|
5094
|
+
* @param columns - Optional column names for the CTE
|
|
5095
|
+
* @returns New query builder instance with the CTE
|
|
5096
|
+
*/
|
|
4886
5097
|
with(name, query, columns) {
|
|
4887
|
-
const subAst =
|
|
5098
|
+
const subAst = resolveSelectQuery(query);
|
|
4888
5099
|
const nextContext = this.applyAst(this.context, (service) => service.withCte(name, subAst, columns, false));
|
|
4889
5100
|
return this.clone(nextContext);
|
|
4890
5101
|
}
|
|
4891
5102
|
/**
|
|
4892
|
-
|
|
4893
|
-
|
|
4894
|
-
|
|
4895
|
-
|
|
4896
|
-
|
|
4897
|
-
|
|
4898
|
-
|
|
4899
|
-
* @param columns - Optional column names for the CTE
|
|
4900
|
-
|
|
4901
|
-
* @returns New query builder instance with the recursive CTE
|
|
4902
|
-
|
|
4903
|
-
*/
|
|
5103
|
+
* Adds a recursive Common Table Expression (CTE) to the query
|
|
5104
|
+
* @param name - Name of the CTE
|
|
5105
|
+
* @param query - Query builder or query node for the CTE
|
|
5106
|
+
* @param columns - Optional column names for the CTE
|
|
5107
|
+
* @returns New query builder instance with the recursive CTE
|
|
5108
|
+
*/
|
|
4904
5109
|
withRecursive(name, query, columns) {
|
|
4905
|
-
const subAst =
|
|
5110
|
+
const subAst = resolveSelectQuery(query);
|
|
4906
5111
|
const nextContext = this.applyAst(this.context, (service) => service.withCte(name, subAst, columns, true));
|
|
4907
5112
|
return this.clone(nextContext);
|
|
4908
5113
|
}
|
|
@@ -4914,24 +5119,31 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
4914
5119
|
* @returns New query builder instance with updated FROM
|
|
4915
5120
|
*/
|
|
4916
5121
|
fromSubquery(subquery, alias, columnAliases) {
|
|
4917
|
-
const subAst =
|
|
5122
|
+
const subAst = resolveSelectQuery(subquery);
|
|
4918
5123
|
const fromNode = derivedTable(subAst, alias, columnAliases);
|
|
4919
5124
|
const nextContext = this.applyAst(this.context, (service) => service.withFrom(fromNode));
|
|
4920
5125
|
return this.clone(nextContext);
|
|
4921
5126
|
}
|
|
4922
5127
|
/**
|
|
4923
|
-
|
|
4924
|
-
|
|
4925
|
-
|
|
4926
|
-
|
|
4927
|
-
|
|
4928
|
-
|
|
4929
|
-
|
|
4930
|
-
|
|
4931
|
-
|
|
4932
|
-
|
|
5128
|
+
* Replaces the FROM clause with a function table expression.
|
|
5129
|
+
* @param name - Function name
|
|
5130
|
+
* @param args - Optional function arguments
|
|
5131
|
+
* @param alias - Optional alias for the function table
|
|
5132
|
+
* @param options - Optional function-table metadata (lateral, ordinality, column aliases, schema)
|
|
5133
|
+
*/
|
|
5134
|
+
fromFunctionTable(name, args = [], alias, options) {
|
|
5135
|
+
const functionTable = fnTable(name, args, alias, options);
|
|
5136
|
+
const nextContext = this.applyAst(this.context, (service) => service.withFrom(functionTable));
|
|
5137
|
+
return this.clone(nextContext);
|
|
5138
|
+
}
|
|
5139
|
+
/**
|
|
5140
|
+
* Selects a subquery as a column
|
|
5141
|
+
* @param alias - Alias for the subquery column
|
|
5142
|
+
* @param sub - Query builder or query node for the subquery
|
|
5143
|
+
* @returns New query builder instance with the subquery selection
|
|
5144
|
+
*/
|
|
4933
5145
|
selectSubquery(alias, sub2) {
|
|
4934
|
-
const query =
|
|
5146
|
+
const query = resolveSelectQuery(sub2);
|
|
4935
5147
|
return this.clone(this.columnSelector.selectSubquery(this.context, alias, query));
|
|
4936
5148
|
}
|
|
4937
5149
|
/**
|
|
@@ -4944,103 +5156,92 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
4944
5156
|
* @returns New query builder instance with the derived-table join
|
|
4945
5157
|
*/
|
|
4946
5158
|
joinSubquery(subquery, alias, condition, joinKind = JOIN_KINDS.INNER, columnAliases) {
|
|
4947
|
-
const subAst =
|
|
5159
|
+
const subAst = resolveSelectQuery(subquery);
|
|
4948
5160
|
const joinNode = createJoinNode(joinKind, derivedTable(subAst, alias, columnAliases), condition);
|
|
4949
5161
|
const nextContext = this.applyAst(this.context, (service) => service.withJoin(joinNode));
|
|
4950
5162
|
return this.clone(nextContext);
|
|
4951
5163
|
}
|
|
4952
5164
|
/**
|
|
4953
|
-
|
|
4954
|
-
|
|
4955
|
-
|
|
4956
|
-
|
|
4957
|
-
|
|
4958
|
-
|
|
4959
|
-
|
|
4960
|
-
|
|
4961
|
-
|
|
4962
|
-
|
|
5165
|
+
* Adds a join against a function table (e.g., `generate_series`) using `fnTable` internally.
|
|
5166
|
+
* @param name - Function name
|
|
5167
|
+
* @param args - Optional arguments passed to the function
|
|
5168
|
+
* @param alias - Alias for the function table so columns can be referenced
|
|
5169
|
+
* @param condition - Join condition expression
|
|
5170
|
+
* @param joinKind - Kind of join (defaults to INNER)
|
|
5171
|
+
* @param options - Optional metadata (lateral, ordinality, column aliases, schema)
|
|
5172
|
+
*/
|
|
5173
|
+
joinFunctionTable(name, args = [], alias, condition, joinKind = JOIN_KINDS.INNER, options) {
|
|
5174
|
+
const functionTable = fnTable(name, args, alias, options);
|
|
5175
|
+
const joinNode = createJoinNode(joinKind, functionTable, condition);
|
|
5176
|
+
const nextContext = this.applyAst(this.context, (service) => service.withJoin(joinNode));
|
|
5177
|
+
return this.clone(nextContext);
|
|
5178
|
+
}
|
|
5179
|
+
/**
|
|
5180
|
+
* Adds an INNER JOIN to the query
|
|
5181
|
+
* @param table - Table to join
|
|
5182
|
+
* @param condition - Join condition expression
|
|
5183
|
+
* @returns New query builder instance with the INNER JOIN
|
|
5184
|
+
*/
|
|
4963
5185
|
innerJoin(table, condition) {
|
|
4964
5186
|
const nextContext = this.applyJoin(this.context, table, condition, JOIN_KINDS.INNER);
|
|
4965
5187
|
return this.clone(nextContext);
|
|
4966
5188
|
}
|
|
4967
5189
|
/**
|
|
4968
|
-
|
|
4969
|
-
|
|
4970
|
-
|
|
4971
|
-
|
|
4972
|
-
|
|
4973
|
-
* @param condition - Join condition expression
|
|
4974
|
-
|
|
4975
|
-
* @returns New query builder instance with the LEFT JOIN
|
|
4976
|
-
|
|
4977
|
-
*/
|
|
5190
|
+
* Adds a LEFT JOIN to the query
|
|
5191
|
+
* @param table - Table to join
|
|
5192
|
+
* @param condition - Join condition expression
|
|
5193
|
+
* @returns New query builder instance with the LEFT JOIN
|
|
5194
|
+
*/
|
|
4978
5195
|
leftJoin(table, condition) {
|
|
4979
5196
|
const nextContext = this.applyJoin(this.context, table, condition, JOIN_KINDS.LEFT);
|
|
4980
5197
|
return this.clone(nextContext);
|
|
4981
5198
|
}
|
|
4982
5199
|
/**
|
|
4983
|
-
|
|
4984
|
-
|
|
4985
|
-
|
|
4986
|
-
|
|
4987
|
-
|
|
4988
|
-
* @param condition - Join condition expression
|
|
4989
|
-
|
|
4990
|
-
* @returns New query builder instance with the RIGHT JOIN
|
|
4991
|
-
|
|
4992
|
-
*/
|
|
5200
|
+
* Adds a RIGHT JOIN to the query
|
|
5201
|
+
* @param table - Table to join
|
|
5202
|
+
* @param condition - Join condition expression
|
|
5203
|
+
* @returns New query builder instance with the RIGHT JOIN
|
|
5204
|
+
*/
|
|
4993
5205
|
rightJoin(table, condition) {
|
|
4994
5206
|
const nextContext = this.applyJoin(this.context, table, condition, JOIN_KINDS.RIGHT);
|
|
4995
5207
|
return this.clone(nextContext);
|
|
4996
5208
|
}
|
|
4997
5209
|
/**
|
|
4998
|
-
|
|
4999
|
-
|
|
5000
|
-
|
|
5001
|
-
|
|
5002
|
-
|
|
5003
|
-
* @param predicate - Optional predicate expression
|
|
5004
|
-
|
|
5005
|
-
* @returns New query builder instance with the relationship match
|
|
5006
|
-
|
|
5007
|
-
*/
|
|
5210
|
+
* Matches records based on a relationship
|
|
5211
|
+
* @param relationName - Name of the relationship to match
|
|
5212
|
+
* @param predicate - Optional predicate expression
|
|
5213
|
+
* @returns New query builder instance with the relationship match
|
|
5214
|
+
*/
|
|
5008
5215
|
match(relationName, predicate) {
|
|
5009
5216
|
const nextContext = this.relationManager.match(this.context, relationName, predicate);
|
|
5010
5217
|
return this.clone(nextContext);
|
|
5011
5218
|
}
|
|
5012
5219
|
/**
|
|
5013
|
-
|
|
5014
|
-
|
|
5015
|
-
|
|
5016
|
-
|
|
5017
|
-
|
|
5018
|
-
|
|
5019
|
-
|
|
5020
|
-
* @param extraCondition - Optional additional join condition
|
|
5021
|
-
|
|
5022
|
-
* @returns New query builder instance with the relationship join
|
|
5023
|
-
|
|
5024
|
-
*/
|
|
5220
|
+
* Joins a related table
|
|
5221
|
+
* @param relationName - Name of the relationship to join
|
|
5222
|
+
* @param joinKind - Type of join (defaults to INNER)
|
|
5223
|
+
* @param extraCondition - Optional additional join condition
|
|
5224
|
+
* @returns New query builder instance with the relationship join
|
|
5225
|
+
*/
|
|
5025
5226
|
joinRelation(relationName, joinKind = JOIN_KINDS.INNER, extraCondition) {
|
|
5026
5227
|
const nextContext = this.relationManager.joinRelation(this.context, relationName, joinKind, extraCondition);
|
|
5027
5228
|
return this.clone(nextContext);
|
|
5028
5229
|
}
|
|
5029
5230
|
/**
|
|
5030
|
-
|
|
5031
|
-
|
|
5032
|
-
|
|
5033
|
-
|
|
5034
|
-
|
|
5035
|
-
* @param options - Optional include options
|
|
5036
|
-
|
|
5037
|
-
* @returns New query builder instance with the relationship inclusion
|
|
5038
|
-
|
|
5039
|
-
*/
|
|
5231
|
+
* Includes related data in the query results
|
|
5232
|
+
* @param relationName - Name of the relationship to include
|
|
5233
|
+
* @param options - Optional include options
|
|
5234
|
+
* @returns New query builder instance with the relationship inclusion
|
|
5235
|
+
*/
|
|
5040
5236
|
include(relationName, options) {
|
|
5041
5237
|
const nextContext = this.relationManager.include(this.context, relationName, options);
|
|
5042
5238
|
return this.clone(nextContext);
|
|
5043
5239
|
}
|
|
5240
|
+
/**
|
|
5241
|
+
* Includes a relation lazily in the query results
|
|
5242
|
+
* @param relationName - Name of the relation to include lazily
|
|
5243
|
+
* @returns New query builder instance with lazy relation inclusion
|
|
5244
|
+
*/
|
|
5044
5245
|
includeLazy(relationName) {
|
|
5045
5246
|
const nextLazy = new Set(this.lazyRelations);
|
|
5046
5247
|
nextLazy.add(relationName);
|
|
@@ -5071,43 +5272,57 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
5071
5272
|
return this.selectRelationColumns(relationName, ...cols);
|
|
5072
5273
|
}
|
|
5073
5274
|
/**
|
|
5074
|
-
* Selects columns for the root table and relations from
|
|
5275
|
+
* Selects columns for the root table and relations from an array of entries
|
|
5276
|
+
* @param config - Configuration array for deep column selection
|
|
5277
|
+
* @returns New query builder instance with deep column selections
|
|
5075
5278
|
*/
|
|
5076
5279
|
selectColumnsDeep(config) {
|
|
5077
|
-
let
|
|
5078
|
-
|
|
5079
|
-
|
|
5080
|
-
|
|
5081
|
-
|
|
5082
|
-
|
|
5083
|
-
|
|
5084
|
-
const cols = config[relName];
|
|
5085
|
-
if (!cols || !cols.length) continue;
|
|
5086
|
-
qb = qb.selectRelationColumns(relName, ...cols);
|
|
5280
|
+
let currBuilder = this;
|
|
5281
|
+
for (const entry of config) {
|
|
5282
|
+
if (entry.type === "root") {
|
|
5283
|
+
currBuilder = currBuilder.select(...entry.columns);
|
|
5284
|
+
} else {
|
|
5285
|
+
currBuilder = currBuilder.selectRelationColumns(entry.relationName, ...entry.columns);
|
|
5286
|
+
}
|
|
5087
5287
|
}
|
|
5088
|
-
return
|
|
5288
|
+
return currBuilder;
|
|
5089
5289
|
}
|
|
5290
|
+
/**
|
|
5291
|
+
* Gets the list of lazy relations
|
|
5292
|
+
* @returns Array of lazy relation names
|
|
5293
|
+
*/
|
|
5090
5294
|
getLazyRelations() {
|
|
5091
5295
|
return Array.from(this.lazyRelations);
|
|
5092
5296
|
}
|
|
5297
|
+
/**
|
|
5298
|
+
* Gets the table definition for this query builder
|
|
5299
|
+
* @returns Table definition
|
|
5300
|
+
*/
|
|
5093
5301
|
getTable() {
|
|
5094
5302
|
return this.env.table;
|
|
5095
5303
|
}
|
|
5304
|
+
/**
|
|
5305
|
+
* Executes the query and returns hydrated results
|
|
5306
|
+
* @param ctx - ORM session context
|
|
5307
|
+
* @returns Promise of entity instances
|
|
5308
|
+
*/
|
|
5096
5309
|
async execute(ctx) {
|
|
5097
5310
|
return executeHydrated(ctx, this);
|
|
5098
5311
|
}
|
|
5312
|
+
/**
|
|
5313
|
+
* Executes the query with provided execution and hydration contexts
|
|
5314
|
+
* @param execCtx - Execution context
|
|
5315
|
+
* @param hydCtx - Hydration context
|
|
5316
|
+
* @returns Promise of entity instances
|
|
5317
|
+
*/
|
|
5099
5318
|
async executeWithContexts(execCtx, hydCtx) {
|
|
5100
5319
|
return executeHydratedWithContexts(execCtx, hydCtx, this);
|
|
5101
5320
|
}
|
|
5102
5321
|
/**
|
|
5103
|
-
|
|
5104
|
-
|
|
5105
|
-
|
|
5106
|
-
|
|
5107
|
-
|
|
5108
|
-
* @returns New query builder instance with the WHERE condition
|
|
5109
|
-
|
|
5110
|
-
*/
|
|
5322
|
+
* Adds a WHERE condition to the query
|
|
5323
|
+
* @param expr - Expression for the WHERE clause
|
|
5324
|
+
* @returns New query builder instance with the WHERE condition
|
|
5325
|
+
*/
|
|
5111
5326
|
where(expr) {
|
|
5112
5327
|
const nextContext = this.applyAst(this.context, (service) => service.withWhere(expr));
|
|
5113
5328
|
return this.clone(nextContext);
|
|
@@ -5122,14 +5337,10 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
5122
5337
|
return this.clone(nextContext);
|
|
5123
5338
|
}
|
|
5124
5339
|
/**
|
|
5125
|
-
|
|
5126
|
-
|
|
5127
|
-
|
|
5128
|
-
|
|
5129
|
-
|
|
5130
|
-
* @returns New query builder instance with the HAVING condition
|
|
5131
|
-
|
|
5132
|
-
*/
|
|
5340
|
+
* Adds a HAVING condition to the query
|
|
5341
|
+
* @param expr - Expression for the HAVING clause
|
|
5342
|
+
* @returns New query builder instance with the HAVING condition
|
|
5343
|
+
*/
|
|
5133
5344
|
having(expr) {
|
|
5134
5345
|
const nextContext = this.applyAst(this.context, (service) => service.withHaving(expr));
|
|
5135
5346
|
return this.clone(nextContext);
|
|
@@ -5150,130 +5361,89 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
5150
5361
|
return this.clone(nextContext);
|
|
5151
5362
|
}
|
|
5152
5363
|
/**
|
|
5153
|
-
|
|
5154
|
-
|
|
5155
|
-
|
|
5156
|
-
|
|
5157
|
-
|
|
5158
|
-
* @returns New query builder instance with the DISTINCT clause
|
|
5159
|
-
|
|
5160
|
-
*/
|
|
5364
|
+
* Adds a DISTINCT clause to the query
|
|
5365
|
+
* @param cols - Columns to make distinct
|
|
5366
|
+
* @returns New query builder instance with the DISTINCT clause
|
|
5367
|
+
*/
|
|
5161
5368
|
distinct(...cols) {
|
|
5162
5369
|
return this.clone(this.columnSelector.distinct(this.context, cols));
|
|
5163
5370
|
}
|
|
5164
5371
|
/**
|
|
5165
|
-
|
|
5166
|
-
|
|
5167
|
-
|
|
5168
|
-
|
|
5169
|
-
|
|
5170
|
-
* @returns New query builder instance with the LIMIT clause
|
|
5171
|
-
|
|
5172
|
-
*/
|
|
5372
|
+
* Adds a LIMIT clause to the query
|
|
5373
|
+
* @param n - Maximum number of rows to return
|
|
5374
|
+
* @returns New query builder instance with the LIMIT clause
|
|
5375
|
+
*/
|
|
5173
5376
|
limit(n) {
|
|
5174
5377
|
const nextContext = this.applyAst(this.context, (service) => service.withLimit(n));
|
|
5175
5378
|
return this.clone(nextContext);
|
|
5176
5379
|
}
|
|
5177
5380
|
/**
|
|
5178
|
-
|
|
5179
|
-
|
|
5180
|
-
|
|
5181
|
-
|
|
5182
|
-
|
|
5183
|
-
* @returns New query builder instance with the OFFSET clause
|
|
5184
|
-
|
|
5185
|
-
*/
|
|
5381
|
+
* Adds an OFFSET clause to the query
|
|
5382
|
+
* @param n - Number of rows to skip
|
|
5383
|
+
* @returns New query builder instance with the OFFSET clause
|
|
5384
|
+
*/
|
|
5186
5385
|
offset(n) {
|
|
5187
5386
|
const nextContext = this.applyAst(this.context, (service) => service.withOffset(n));
|
|
5188
5387
|
return this.clone(nextContext);
|
|
5189
5388
|
}
|
|
5190
5389
|
/**
|
|
5191
|
-
|
|
5192
|
-
|
|
5193
|
-
|
|
5194
|
-
|
|
5195
|
-
|
|
5196
|
-
* @returns New query builder instance with the set operation
|
|
5197
|
-
|
|
5198
|
-
*/
|
|
5390
|
+
* Combines this query with another using UNION
|
|
5391
|
+
* @param query - Query to union with
|
|
5392
|
+
* @returns New query builder instance with the set operation
|
|
5393
|
+
*/
|
|
5199
5394
|
union(query) {
|
|
5200
5395
|
return this.clone(this.applySetOperation("UNION", query));
|
|
5201
5396
|
}
|
|
5202
5397
|
/**
|
|
5203
|
-
|
|
5204
|
-
|
|
5205
|
-
|
|
5206
|
-
|
|
5207
|
-
|
|
5208
|
-
* @returns New query builder instance with the set operation
|
|
5209
|
-
|
|
5210
|
-
*/
|
|
5398
|
+
* Combines this query with another using UNION ALL
|
|
5399
|
+
* @param query - Query to union with
|
|
5400
|
+
* @returns New query builder instance with the set operation
|
|
5401
|
+
*/
|
|
5211
5402
|
unionAll(query) {
|
|
5212
5403
|
return this.clone(this.applySetOperation("UNION ALL", query));
|
|
5213
5404
|
}
|
|
5214
5405
|
/**
|
|
5215
|
-
|
|
5216
|
-
|
|
5217
|
-
|
|
5218
|
-
|
|
5219
|
-
|
|
5220
|
-
* @returns New query builder instance with the set operation
|
|
5221
|
-
|
|
5222
|
-
*/
|
|
5406
|
+
* Combines this query with another using INTERSECT
|
|
5407
|
+
* @param query - Query to intersect with
|
|
5408
|
+
* @returns New query builder instance with the set operation
|
|
5409
|
+
*/
|
|
5223
5410
|
intersect(query) {
|
|
5224
5411
|
return this.clone(this.applySetOperation("INTERSECT", query));
|
|
5225
5412
|
}
|
|
5226
5413
|
/**
|
|
5227
|
-
|
|
5228
|
-
|
|
5229
|
-
|
|
5230
|
-
|
|
5231
|
-
|
|
5232
|
-
* @returns New query builder instance with the set operation
|
|
5233
|
-
|
|
5234
|
-
*/
|
|
5414
|
+
* Combines this query with another using EXCEPT
|
|
5415
|
+
* @param query - Query to subtract
|
|
5416
|
+
* @returns New query builder instance with the set operation
|
|
5417
|
+
*/
|
|
5235
5418
|
except(query) {
|
|
5236
5419
|
return this.clone(this.applySetOperation("EXCEPT", query));
|
|
5237
5420
|
}
|
|
5238
5421
|
/**
|
|
5239
|
-
|
|
5240
|
-
|
|
5241
|
-
|
|
5242
|
-
|
|
5243
|
-
|
|
5244
|
-
* @returns New query builder instance with the WHERE EXISTS condition
|
|
5245
|
-
|
|
5246
|
-
*/
|
|
5422
|
+
* Adds a WHERE EXISTS condition to the query
|
|
5423
|
+
* @param subquery - Subquery to check for existence
|
|
5424
|
+
* @returns New query builder instance with the WHERE EXISTS condition
|
|
5425
|
+
*/
|
|
5247
5426
|
whereExists(subquery, correlate) {
|
|
5248
|
-
const subAst =
|
|
5427
|
+
const subAst = resolveSelectQuery(subquery);
|
|
5249
5428
|
const correlated = this.applyCorrelation(subAst, correlate);
|
|
5250
5429
|
return this.where(exists(correlated));
|
|
5251
5430
|
}
|
|
5252
5431
|
/**
|
|
5253
|
-
|
|
5254
|
-
|
|
5255
|
-
|
|
5256
|
-
|
|
5257
|
-
|
|
5258
|
-
* @returns New query builder instance with the WHERE NOT EXISTS condition
|
|
5259
|
-
|
|
5260
|
-
*/
|
|
5432
|
+
* Adds a WHERE NOT EXISTS condition to the query
|
|
5433
|
+
* @param subquery - Subquery to check for non-existence
|
|
5434
|
+
* @returns New query builder instance with the WHERE NOT EXISTS condition
|
|
5435
|
+
*/
|
|
5261
5436
|
whereNotExists(subquery, correlate) {
|
|
5262
|
-
const subAst =
|
|
5437
|
+
const subAst = resolveSelectQuery(subquery);
|
|
5263
5438
|
const correlated = this.applyCorrelation(subAst, correlate);
|
|
5264
5439
|
return this.where(notExists(correlated));
|
|
5265
5440
|
}
|
|
5266
5441
|
/**
|
|
5267
|
-
|
|
5268
|
-
|
|
5269
|
-
|
|
5270
|
-
|
|
5271
|
-
|
|
5272
|
-
* @param callback - Optional callback to modify the relationship query
|
|
5273
|
-
|
|
5274
|
-
* @returns New query builder instance with the relationship existence check
|
|
5275
|
-
|
|
5276
|
-
*/
|
|
5442
|
+
* Adds a WHERE EXISTS condition based on a relationship
|
|
5443
|
+
* @param relationName - Name of the relationship to check
|
|
5444
|
+
* @param callback - Optional callback to modify the relationship query
|
|
5445
|
+
* @returns New query builder instance with the relationship existence check
|
|
5446
|
+
*/
|
|
5277
5447
|
whereHas(relationName, callbackOrOptions, maybeOptions) {
|
|
5278
5448
|
const relation = this.env.table.relations[relationName];
|
|
5279
5449
|
if (!relation) {
|
|
@@ -5290,16 +5460,11 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
5290
5460
|
return this.where(exists(finalSubAst));
|
|
5291
5461
|
}
|
|
5292
5462
|
/**
|
|
5293
|
-
|
|
5294
|
-
|
|
5295
|
-
|
|
5296
|
-
|
|
5297
|
-
|
|
5298
|
-
* @param callback - Optional callback to modify the relationship query
|
|
5299
|
-
|
|
5300
|
-
* @returns New query builder instance with the relationship non-existence check
|
|
5301
|
-
|
|
5302
|
-
*/
|
|
5463
|
+
* Adds a WHERE NOT EXISTS condition based on a relationship
|
|
5464
|
+
* @param relationName - Name of the relationship to check
|
|
5465
|
+
* @param callback - Optional callback to modify the relationship query
|
|
5466
|
+
* @returns New query builder instance with the relationship non-existence check
|
|
5467
|
+
*/
|
|
5303
5468
|
whereHasNot(relationName, callbackOrOptions, maybeOptions) {
|
|
5304
5469
|
const relation = this.env.table.relations[relationName];
|
|
5305
5470
|
if (!relation) {
|
|
@@ -5316,53 +5481,61 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
5316
5481
|
return this.where(notExists(finalSubAst));
|
|
5317
5482
|
}
|
|
5318
5483
|
/**
|
|
5319
|
-
|
|
5320
|
-
|
|
5321
|
-
|
|
5322
|
-
|
|
5323
|
-
|
|
5324
|
-
* @returns Compiled query with SQL and parameters
|
|
5325
|
-
|
|
5326
|
-
*/
|
|
5484
|
+
* Compiles the query to SQL for a specific dialect
|
|
5485
|
+
* @param dialect - Database dialect to compile for
|
|
5486
|
+
* @returns Compiled query with SQL and parameters
|
|
5487
|
+
*/
|
|
5327
5488
|
compile(dialect) {
|
|
5328
5489
|
const resolved = resolveDialectInput(dialect);
|
|
5329
|
-
return resolved.compileSelect(this.
|
|
5490
|
+
return resolved.compileSelect(this.getAST());
|
|
5330
5491
|
}
|
|
5331
5492
|
/**
|
|
5332
|
-
|
|
5333
|
-
|
|
5334
|
-
|
|
5335
|
-
|
|
5336
|
-
|
|
5337
|
-
* @returns SQL string representation of the query
|
|
5338
|
-
|
|
5339
|
-
*/
|
|
5493
|
+
* Converts the query to SQL string for a specific dialect
|
|
5494
|
+
* @param dialect - Database dialect to generate SQL for
|
|
5495
|
+
* @returns SQL string representation of the query
|
|
5496
|
+
*/
|
|
5340
5497
|
toSql(dialect) {
|
|
5341
5498
|
return this.compile(dialect).sql;
|
|
5342
5499
|
}
|
|
5343
5500
|
/**
|
|
5344
|
-
|
|
5345
|
-
|
|
5346
|
-
|
|
5347
|
-
* @returns Hydration plan or undefined if none exists
|
|
5348
|
-
|
|
5349
|
-
*/
|
|
5501
|
+
* Gets the hydration plan for the query
|
|
5502
|
+
* @returns Hydration plan or undefined if none exists
|
|
5503
|
+
*/
|
|
5350
5504
|
getHydrationPlan() {
|
|
5351
5505
|
return this.context.hydration.getPlan();
|
|
5352
5506
|
}
|
|
5353
5507
|
/**
|
|
5354
|
-
|
|
5355
|
-
|
|
5356
|
-
|
|
5357
|
-
* @returns Query AST with hydration applied
|
|
5358
|
-
|
|
5359
|
-
*/
|
|
5508
|
+
* Gets the Abstract Syntax Tree (AST) representation of the query
|
|
5509
|
+
* @returns Query AST with hydration applied
|
|
5510
|
+
*/
|
|
5360
5511
|
getAST() {
|
|
5361
5512
|
return this.context.hydration.applyToAst(this.context.state.ast);
|
|
5362
5513
|
}
|
|
5363
5514
|
};
|
|
5364
|
-
|
|
5365
|
-
|
|
5515
|
+
|
|
5516
|
+
// src/schema/table-guards.ts
|
|
5517
|
+
var isColumnsRecord = (columns) => {
|
|
5518
|
+
return typeof columns === "object" && columns !== null;
|
|
5519
|
+
};
|
|
5520
|
+
var isRelationsRecord = (relations) => {
|
|
5521
|
+
return typeof relations === "object" && relations !== null;
|
|
5522
|
+
};
|
|
5523
|
+
var isTableDef = (value) => {
|
|
5524
|
+
if (typeof value !== "object" || value === null) {
|
|
5525
|
+
return false;
|
|
5526
|
+
}
|
|
5527
|
+
const candidate = value;
|
|
5528
|
+
if (typeof candidate.name !== "string") {
|
|
5529
|
+
return false;
|
|
5530
|
+
}
|
|
5531
|
+
if (!isColumnsRecord(candidate.columns)) {
|
|
5532
|
+
return false;
|
|
5533
|
+
}
|
|
5534
|
+
if (!isRelationsRecord(candidate.relations)) {
|
|
5535
|
+
return false;
|
|
5536
|
+
}
|
|
5537
|
+
return true;
|
|
5538
|
+
};
|
|
5366
5539
|
|
|
5367
5540
|
// src/orm/entity-metadata.ts
|
|
5368
5541
|
var metadataMap = /* @__PURE__ */ new Map();
|
|
@@ -5406,23 +5579,20 @@ var buildTableDef = (meta) => {
|
|
|
5406
5579
|
if (meta.table) {
|
|
5407
5580
|
return meta.table;
|
|
5408
5581
|
}
|
|
5409
|
-
const columns =
|
|
5410
|
-
|
|
5582
|
+
const columns = {};
|
|
5583
|
+
for (const [key, def] of Object.entries(meta.columns)) {
|
|
5584
|
+
columns[key] = {
|
|
5411
5585
|
...def,
|
|
5412
5586
|
name: key,
|
|
5413
5587
|
table: meta.tableName
|
|
5414
5588
|
};
|
|
5415
|
-
|
|
5416
|
-
}, {});
|
|
5589
|
+
}
|
|
5417
5590
|
const table = defineTable(meta.tableName, columns, {}, meta.hooks);
|
|
5418
5591
|
meta.table = table;
|
|
5419
5592
|
return table;
|
|
5420
5593
|
};
|
|
5421
5594
|
|
|
5422
5595
|
// src/decorators/bootstrap.ts
|
|
5423
|
-
var isTableDef = (value) => {
|
|
5424
|
-
return typeof value === "object" && value !== null && "columns" in value;
|
|
5425
|
-
};
|
|
5426
5596
|
var unwrapTarget = (target) => {
|
|
5427
5597
|
if (typeof target === "function" && target.prototype === void 0) {
|
|
5428
5598
|
return target();
|
|
@@ -5520,6 +5690,13 @@ var selectFromEntity = (ctor) => {
|
|
|
5520
5690
|
}
|
|
5521
5691
|
return new SelectQueryBuilder(table);
|
|
5522
5692
|
};
|
|
5693
|
+
var entityRef = (ctor) => {
|
|
5694
|
+
const table = getTableDefFromEntity(ctor);
|
|
5695
|
+
if (!table) {
|
|
5696
|
+
throw new Error(`Entity '${ctor.name}' is not registered with decorators or has not been bootstrapped`);
|
|
5697
|
+
}
|
|
5698
|
+
return tableRef(table);
|
|
5699
|
+
};
|
|
5523
5700
|
|
|
5524
5701
|
// src/query-builder/select-helpers.ts
|
|
5525
5702
|
function sel(table, ...cols) {
|
|
@@ -5551,6 +5728,11 @@ function esel(entity, ...props) {
|
|
|
5551
5728
|
|
|
5552
5729
|
// src/query-builder/insert-query-state.ts
|
|
5553
5730
|
var InsertQueryState = class _InsertQueryState {
|
|
5731
|
+
/**
|
|
5732
|
+
* Creates a new InsertQueryState instance
|
|
5733
|
+
* @param table - The table definition for the INSERT query
|
|
5734
|
+
* @param ast - Optional initial AST node, defaults to a basic INSERT query
|
|
5735
|
+
*/
|
|
5554
5736
|
constructor(table, ast) {
|
|
5555
5737
|
this.table = table;
|
|
5556
5738
|
this.ast = ast ?? {
|
|
@@ -5581,6 +5763,13 @@ var InsertQueryState = class _InsertQueryState {
|
|
|
5581
5763
|
if (!names.length) return [];
|
|
5582
5764
|
return buildColumnNodes(this.table, names);
|
|
5583
5765
|
}
|
|
5766
|
+
/**
|
|
5767
|
+
* Adds VALUES clause to the INSERT query
|
|
5768
|
+
* @param rows - Array of row objects to insert
|
|
5769
|
+
* @returns A new InsertQueryState with the VALUES clause added
|
|
5770
|
+
* @throws Error if mixing VALUES with SELECT source
|
|
5771
|
+
* @throws Error if invalid values are provided
|
|
5772
|
+
*/
|
|
5584
5773
|
withValues(rows) {
|
|
5585
5774
|
if (!rows.length) return this;
|
|
5586
5775
|
if (this.ast.source.type === "InsertSelect") {
|
|
@@ -5607,6 +5796,11 @@ var InsertQueryState = class _InsertQueryState {
|
|
|
5607
5796
|
}
|
|
5608
5797
|
});
|
|
5609
5798
|
}
|
|
5799
|
+
/**
|
|
5800
|
+
* Sets the columns for the INSERT query
|
|
5801
|
+
* @param columns - Column nodes to insert into
|
|
5802
|
+
* @returns A new InsertQueryState with the specified columns
|
|
5803
|
+
*/
|
|
5610
5804
|
withColumns(columns) {
|
|
5611
5805
|
if (!columns.length) return this;
|
|
5612
5806
|
return this.clone({
|
|
@@ -5614,6 +5808,14 @@ var InsertQueryState = class _InsertQueryState {
|
|
|
5614
5808
|
columns: [...columns]
|
|
5615
5809
|
});
|
|
5616
5810
|
}
|
|
5811
|
+
/**
|
|
5812
|
+
* Adds SELECT source to the INSERT query
|
|
5813
|
+
* @param query - The SELECT query to use as source
|
|
5814
|
+
* @param columns - Target columns for the INSERT
|
|
5815
|
+
* @returns A new InsertQueryState with the SELECT source
|
|
5816
|
+
* @throws Error if mixing SELECT with VALUES source
|
|
5817
|
+
* @throws Error if no destination columns specified
|
|
5818
|
+
*/
|
|
5617
5819
|
withSelect(query, columns) {
|
|
5618
5820
|
const targetColumns = columns.length ? columns : this.ast.columns.length ? this.ast.columns : this.getTableColumns();
|
|
5619
5821
|
if (!targetColumns.length) {
|
|
@@ -5631,6 +5833,11 @@ var InsertQueryState = class _InsertQueryState {
|
|
|
5631
5833
|
}
|
|
5632
5834
|
});
|
|
5633
5835
|
}
|
|
5836
|
+
/**
|
|
5837
|
+
* Adds a RETURNING clause to the INSERT query
|
|
5838
|
+
* @param columns - Columns to return after insertion
|
|
5839
|
+
* @returns A new InsertQueryState with the RETURNING clause added
|
|
5840
|
+
*/
|
|
5634
5841
|
withReturning(columns) {
|
|
5635
5842
|
return this.clone({
|
|
5636
5843
|
...this.ast,
|
|
@@ -5641,6 +5848,11 @@ var InsertQueryState = class _InsertQueryState {
|
|
|
5641
5848
|
|
|
5642
5849
|
// src/query-builder/insert.ts
|
|
5643
5850
|
var InsertQueryBuilder = class _InsertQueryBuilder {
|
|
5851
|
+
/**
|
|
5852
|
+
* Creates a new InsertQueryBuilder instance
|
|
5853
|
+
* @param table - The table definition for the INSERT query
|
|
5854
|
+
* @param state - Optional initial query state, defaults to a new InsertQueryState
|
|
5855
|
+
*/
|
|
5644
5856
|
constructor(table, state) {
|
|
5645
5857
|
this.table = table;
|
|
5646
5858
|
this.state = state ?? new InsertQueryState(table);
|
|
@@ -5648,20 +5860,42 @@ var InsertQueryBuilder = class _InsertQueryBuilder {
|
|
|
5648
5860
|
clone(state) {
|
|
5649
5861
|
return new _InsertQueryBuilder(this.table, state);
|
|
5650
5862
|
}
|
|
5863
|
+
/**
|
|
5864
|
+
* Adds VALUES to the INSERT query
|
|
5865
|
+
* @param rowOrRows - Single row object or array of row objects to insert
|
|
5866
|
+
* @returns A new InsertQueryBuilder with the VALUES clause added
|
|
5867
|
+
*/
|
|
5651
5868
|
values(rowOrRows) {
|
|
5652
5869
|
const rows = Array.isArray(rowOrRows) ? rowOrRows : [rowOrRows];
|
|
5653
5870
|
if (!rows.length) return this;
|
|
5654
5871
|
return this.clone(this.state.withValues(rows));
|
|
5655
5872
|
}
|
|
5873
|
+
/**
|
|
5874
|
+
* Specifies the columns for the INSERT query
|
|
5875
|
+
* @param columns - Column definitions or nodes to insert into
|
|
5876
|
+
* @returns A new InsertQueryBuilder with the specified columns
|
|
5877
|
+
*/
|
|
5656
5878
|
columns(...columns) {
|
|
5657
5879
|
if (!columns.length) return this;
|
|
5658
5880
|
return this.clone(this.state.withColumns(this.resolveColumnNodes(columns)));
|
|
5659
5881
|
}
|
|
5882
|
+
/**
|
|
5883
|
+
* Sets the source of the INSERT query to a SELECT query
|
|
5884
|
+
* @template TSource - The source table type
|
|
5885
|
+
* @param query - The SELECT query or query builder to use as source
|
|
5886
|
+
* @param columns - Optional target columns for the INSERT
|
|
5887
|
+
* @returns A new InsertQueryBuilder with the SELECT source
|
|
5888
|
+
*/
|
|
5660
5889
|
fromSelect(query, columns = []) {
|
|
5661
5890
|
const ast = this.resolveSelectQuery(query);
|
|
5662
5891
|
const nodes = columns.length ? this.resolveColumnNodes(columns) : [];
|
|
5663
5892
|
return this.clone(this.state.withSelect(ast, nodes));
|
|
5664
5893
|
}
|
|
5894
|
+
/**
|
|
5895
|
+
* Adds a RETURNING clause to the INSERT query
|
|
5896
|
+
* @param columns - Columns to return after insertion
|
|
5897
|
+
* @returns A new InsertQueryBuilder with the RETURNING clause added
|
|
5898
|
+
*/
|
|
5665
5899
|
returning(...columns) {
|
|
5666
5900
|
if (!columns.length) return this;
|
|
5667
5901
|
const nodes = columns.map((column) => buildColumnNode(this.table, column));
|
|
@@ -5672,18 +5906,29 @@ var InsertQueryBuilder = class _InsertQueryBuilder {
|
|
|
5672
5906
|
return columns.map((column) => buildColumnNode(this.table, column));
|
|
5673
5907
|
}
|
|
5674
5908
|
resolveSelectQuery(query) {
|
|
5675
|
-
|
|
5909
|
+
const candidate = query;
|
|
5910
|
+
return typeof candidate.getAST === "function" && candidate.getAST ? candidate.getAST() : query;
|
|
5676
5911
|
}
|
|
5677
5912
|
compile(arg) {
|
|
5678
|
-
|
|
5679
|
-
|
|
5913
|
+
const candidate = arg;
|
|
5914
|
+
if (typeof candidate.compileInsert === "function") {
|
|
5915
|
+
return candidate.compileInsert(this.state.ast);
|
|
5680
5916
|
}
|
|
5681
5917
|
const dialect = resolveDialectInput(arg);
|
|
5682
5918
|
return dialect.compileInsert(this.state.ast);
|
|
5683
5919
|
}
|
|
5920
|
+
/**
|
|
5921
|
+
* Returns the SQL string for the INSERT query
|
|
5922
|
+
* @param arg - The compiler or dialect to generate SQL for
|
|
5923
|
+
* @returns The SQL string representation of the query
|
|
5924
|
+
*/
|
|
5684
5925
|
toSql(arg) {
|
|
5685
5926
|
return this.compile(arg).sql;
|
|
5686
5927
|
}
|
|
5928
|
+
/**
|
|
5929
|
+
* Returns the Abstract Syntax Tree (AST) representation of the query
|
|
5930
|
+
* @returns The AST node for the INSERT query
|
|
5931
|
+
*/
|
|
5687
5932
|
getAST() {
|
|
5688
5933
|
return this.state.ast;
|
|
5689
5934
|
}
|
|
@@ -5702,6 +5947,11 @@ var isUpdateValue = (value) => {
|
|
|
5702
5947
|
}
|
|
5703
5948
|
};
|
|
5704
5949
|
var UpdateQueryState = class _UpdateQueryState {
|
|
5950
|
+
/**
|
|
5951
|
+
* Creates a new UpdateQueryState instance
|
|
5952
|
+
* @param table - Table definition for the update
|
|
5953
|
+
* @param ast - Optional existing AST
|
|
5954
|
+
*/
|
|
5705
5955
|
constructor(table, ast) {
|
|
5706
5956
|
this.table = table;
|
|
5707
5957
|
this.ast = ast ?? {
|
|
@@ -5711,9 +5961,19 @@ var UpdateQueryState = class _UpdateQueryState {
|
|
|
5711
5961
|
joins: []
|
|
5712
5962
|
};
|
|
5713
5963
|
}
|
|
5964
|
+
/**
|
|
5965
|
+
* Creates a new UpdateQueryState with updated AST
|
|
5966
|
+
* @param nextAst - Updated AST
|
|
5967
|
+
* @returns New UpdateQueryState instance
|
|
5968
|
+
*/
|
|
5714
5969
|
clone(nextAst) {
|
|
5715
5970
|
return new _UpdateQueryState(this.table, nextAst);
|
|
5716
5971
|
}
|
|
5972
|
+
/**
|
|
5973
|
+
* Sets the columns to update with their new values
|
|
5974
|
+
* @param values - Record of column names to values
|
|
5975
|
+
* @returns New UpdateQueryState with SET clause
|
|
5976
|
+
*/
|
|
5717
5977
|
withSet(values) {
|
|
5718
5978
|
const assignments = Object.entries(values).map(([column, rawValue]) => {
|
|
5719
5979
|
if (!isUpdateValue(rawValue)) {
|
|
@@ -5735,30 +5995,55 @@ var UpdateQueryState = class _UpdateQueryState {
|
|
|
5735
5995
|
set: assignments
|
|
5736
5996
|
});
|
|
5737
5997
|
}
|
|
5998
|
+
/**
|
|
5999
|
+
* Adds a WHERE condition to the update query
|
|
6000
|
+
* @param expr - WHERE expression
|
|
6001
|
+
* @returns New UpdateQueryState with WHERE clause
|
|
6002
|
+
*/
|
|
5738
6003
|
withWhere(expr) {
|
|
5739
6004
|
return this.clone({
|
|
5740
6005
|
...this.ast,
|
|
5741
6006
|
where: expr
|
|
5742
6007
|
});
|
|
5743
6008
|
}
|
|
6009
|
+
/**
|
|
6010
|
+
* Adds a RETURNING clause to the update query
|
|
6011
|
+
* @param columns - Columns to return
|
|
6012
|
+
* @returns New UpdateQueryState with RETURNING clause
|
|
6013
|
+
*/
|
|
5744
6014
|
withReturning(columns) {
|
|
5745
6015
|
return this.clone({
|
|
5746
6016
|
...this.ast,
|
|
5747
6017
|
returning: [...columns]
|
|
5748
6018
|
});
|
|
5749
6019
|
}
|
|
6020
|
+
/**
|
|
6021
|
+
* Sets the FROM clause for the update query
|
|
6022
|
+
* @param from - Table source for FROM
|
|
6023
|
+
* @returns New UpdateQueryState with FROM clause
|
|
6024
|
+
*/
|
|
5750
6025
|
withFrom(from) {
|
|
5751
6026
|
return this.clone({
|
|
5752
6027
|
...this.ast,
|
|
5753
6028
|
from
|
|
5754
6029
|
});
|
|
5755
6030
|
}
|
|
6031
|
+
/**
|
|
6032
|
+
* Adds a JOIN to the update query
|
|
6033
|
+
* @param join - Join node to add
|
|
6034
|
+
* @returns New UpdateQueryState with JOIN
|
|
6035
|
+
*/
|
|
5756
6036
|
withJoin(join) {
|
|
5757
6037
|
return this.clone({
|
|
5758
6038
|
...this.ast,
|
|
5759
6039
|
joins: [...this.ast.joins ?? [], join]
|
|
5760
6040
|
});
|
|
5761
6041
|
}
|
|
6042
|
+
/**
|
|
6043
|
+
* Applies an alias to the table being updated
|
|
6044
|
+
* @param alias - Alias for the table
|
|
6045
|
+
* @returns New UpdateQueryState with table alias
|
|
6046
|
+
*/
|
|
5762
6047
|
withTableAlias(alias) {
|
|
5763
6048
|
return this.clone({
|
|
5764
6049
|
...this.ast,
|
|
@@ -5772,6 +6057,11 @@ var UpdateQueryState = class _UpdateQueryState {
|
|
|
5772
6057
|
|
|
5773
6058
|
// src/query-builder/update.ts
|
|
5774
6059
|
var UpdateQueryBuilder = class _UpdateQueryBuilder {
|
|
6060
|
+
/**
|
|
6061
|
+
* Creates a new UpdateQueryBuilder instance
|
|
6062
|
+
* @param table - The table definition for the UPDATE query
|
|
6063
|
+
* @param state - Optional initial query state, defaults to a new UpdateQueryState
|
|
6064
|
+
*/
|
|
5775
6065
|
constructor(table, state) {
|
|
5776
6066
|
this.table = table;
|
|
5777
6067
|
this.state = state ?? new UpdateQueryState(table);
|
|
@@ -5779,24 +6069,57 @@ var UpdateQueryBuilder = class _UpdateQueryBuilder {
|
|
|
5779
6069
|
clone(state) {
|
|
5780
6070
|
return new _UpdateQueryBuilder(this.table, state);
|
|
5781
6071
|
}
|
|
6072
|
+
/**
|
|
6073
|
+
* Sets an alias for the table in the UPDATE query
|
|
6074
|
+
* @param alias - The alias to assign to the table
|
|
6075
|
+
* @returns A new UpdateQueryBuilder with the table alias set
|
|
6076
|
+
*/
|
|
5782
6077
|
as(alias) {
|
|
5783
6078
|
return this.clone(this.state.withTableAlias(alias));
|
|
5784
6079
|
}
|
|
6080
|
+
/**
|
|
6081
|
+
* Adds a FROM clause to the UPDATE query
|
|
6082
|
+
* @param source - The table source to use in the FROM clause
|
|
6083
|
+
* @returns A new UpdateQueryBuilder with the FROM clause added
|
|
6084
|
+
*/
|
|
5785
6085
|
from(source) {
|
|
5786
6086
|
const tableSource = this.resolveTableSource(source);
|
|
5787
6087
|
return this.clone(this.state.withFrom(tableSource));
|
|
5788
6088
|
}
|
|
6089
|
+
/**
|
|
6090
|
+
* Adds a JOIN clause to the UPDATE query
|
|
6091
|
+
* @param table - The table to join with
|
|
6092
|
+
* @param condition - The join condition expression
|
|
6093
|
+
* @param kind - The type of join (defaults to INNER)
|
|
6094
|
+
* @param relationName - Optional name for the relation
|
|
6095
|
+
* @returns A new UpdateQueryBuilder with the JOIN clause added
|
|
6096
|
+
*/
|
|
5789
6097
|
join(table, condition, kind = JOIN_KINDS.INNER, relationName) {
|
|
5790
6098
|
const joinTarget = this.resolveJoinTarget(table);
|
|
5791
6099
|
const joinNode = createJoinNode(kind, joinTarget, condition, relationName);
|
|
5792
6100
|
return this.clone(this.state.withJoin(joinNode));
|
|
5793
6101
|
}
|
|
6102
|
+
/**
|
|
6103
|
+
* Adds a SET clause to the UPDATE query
|
|
6104
|
+
* @param values - The column-value pairs to update
|
|
6105
|
+
* @returns A new UpdateQueryBuilder with the SET clause added
|
|
6106
|
+
*/
|
|
5794
6107
|
set(values) {
|
|
5795
6108
|
return this.clone(this.state.withSet(values));
|
|
5796
6109
|
}
|
|
6110
|
+
/**
|
|
6111
|
+
* Adds a WHERE clause to the UPDATE query
|
|
6112
|
+
* @param expr - The expression to use as the WHERE condition
|
|
6113
|
+
* @returns A new UpdateQueryBuilder with the WHERE clause added
|
|
6114
|
+
*/
|
|
5797
6115
|
where(expr) {
|
|
5798
6116
|
return this.clone(this.state.withWhere(expr));
|
|
5799
6117
|
}
|
|
6118
|
+
/**
|
|
6119
|
+
* Adds a RETURNING clause to the UPDATE query
|
|
6120
|
+
* @param columns - Columns to return after update
|
|
6121
|
+
* @returns A new UpdateQueryBuilder with the RETURNING clause added
|
|
6122
|
+
*/
|
|
5800
6123
|
returning(...columns) {
|
|
5801
6124
|
if (!columns.length) return this;
|
|
5802
6125
|
const nodes = columns.map((column) => buildColumnNode(this.table, column));
|
|
@@ -5812,16 +6135,36 @@ var UpdateQueryBuilder = class _UpdateQueryBuilder {
|
|
|
5812
6135
|
if (typeof table === "string") return table;
|
|
5813
6136
|
return this.resolveTableSource(table);
|
|
5814
6137
|
}
|
|
5815
|
-
|
|
5816
|
-
|
|
5817
|
-
|
|
5818
|
-
|
|
5819
|
-
|
|
5820
|
-
|
|
6138
|
+
/**
|
|
6139
|
+
* Compiles the UPDATE query for the specified dialect
|
|
6140
|
+
* @param dialect - The SQL dialect to compile for
|
|
6141
|
+
* @returns The compiled query with SQL and parameters
|
|
6142
|
+
*/
|
|
6143
|
+
compile(dialect) {
|
|
6144
|
+
const resolved = resolveDialectInput(dialect);
|
|
6145
|
+
return resolved.compileUpdate(this.state.ast);
|
|
5821
6146
|
}
|
|
5822
|
-
|
|
5823
|
-
|
|
6147
|
+
/**
|
|
6148
|
+
* Returns the SQL string for the UPDATE query
|
|
6149
|
+
* @param dialect - The SQL dialect to generate SQL for
|
|
6150
|
+
* @returns The SQL string representation of the query
|
|
6151
|
+
*/
|
|
6152
|
+
toSql(dialect) {
|
|
6153
|
+
return this.compile(dialect).sql;
|
|
5824
6154
|
}
|
|
6155
|
+
/**
|
|
6156
|
+
* Executes the UPDATE query using the provided session
|
|
6157
|
+
* @param session - The ORM session to execute the query with
|
|
6158
|
+
* @returns A promise that resolves to the query results
|
|
6159
|
+
*/
|
|
6160
|
+
async execute(session) {
|
|
6161
|
+
const compiled = this.compile(session.dialect);
|
|
6162
|
+
return session.executor.executeSql(compiled.sql, compiled.params);
|
|
6163
|
+
}
|
|
6164
|
+
/**
|
|
6165
|
+
* Returns the Abstract Syntax Tree (AST) representation of the query
|
|
6166
|
+
* @returns The AST node for the UPDATE query
|
|
6167
|
+
*/
|
|
5825
6168
|
getAST() {
|
|
5826
6169
|
return this.state.ast;
|
|
5827
6170
|
}
|
|
@@ -5830,6 +6173,11 @@ var isTableSourceNode = (source) => typeof source.type === "string";
|
|
|
5830
6173
|
|
|
5831
6174
|
// src/query-builder/delete-query-state.ts
|
|
5832
6175
|
var DeleteQueryState = class _DeleteQueryState {
|
|
6176
|
+
/**
|
|
6177
|
+
* Creates a new DeleteQueryState instance
|
|
6178
|
+
* @param table - The table definition for the DELETE query
|
|
6179
|
+
* @param ast - Optional initial AST node, defaults to a basic DELETE query
|
|
6180
|
+
*/
|
|
5833
6181
|
constructor(table, ast) {
|
|
5834
6182
|
this.table = table;
|
|
5835
6183
|
this.ast = ast ?? {
|
|
@@ -5841,30 +6189,55 @@ var DeleteQueryState = class _DeleteQueryState {
|
|
|
5841
6189
|
clone(nextAst) {
|
|
5842
6190
|
return new _DeleteQueryState(this.table, nextAst);
|
|
5843
6191
|
}
|
|
6192
|
+
/**
|
|
6193
|
+
* Adds a WHERE clause to the DELETE query
|
|
6194
|
+
* @param expr - The expression to use as the WHERE condition
|
|
6195
|
+
* @returns A new DeleteQueryState with the WHERE clause added
|
|
6196
|
+
*/
|
|
5844
6197
|
withWhere(expr) {
|
|
5845
6198
|
return this.clone({
|
|
5846
6199
|
...this.ast,
|
|
5847
6200
|
where: expr
|
|
5848
6201
|
});
|
|
5849
6202
|
}
|
|
6203
|
+
/**
|
|
6204
|
+
* Adds a RETURNING clause to the DELETE query
|
|
6205
|
+
* @param columns - The columns to return after deletion
|
|
6206
|
+
* @returns A new DeleteQueryState with the RETURNING clause added
|
|
6207
|
+
*/
|
|
5850
6208
|
withReturning(columns) {
|
|
5851
6209
|
return this.clone({
|
|
5852
6210
|
...this.ast,
|
|
5853
6211
|
returning: [...columns]
|
|
5854
6212
|
});
|
|
5855
6213
|
}
|
|
6214
|
+
/**
|
|
6215
|
+
* Adds a USING clause to the DELETE query
|
|
6216
|
+
* @param source - The table source to use in the USING clause
|
|
6217
|
+
* @returns A new DeleteQueryState with the USING clause added
|
|
6218
|
+
*/
|
|
5856
6219
|
withUsing(source) {
|
|
5857
6220
|
return this.clone({
|
|
5858
6221
|
...this.ast,
|
|
5859
6222
|
using: source
|
|
5860
6223
|
});
|
|
5861
6224
|
}
|
|
6225
|
+
/**
|
|
6226
|
+
* Adds a JOIN clause to the DELETE query
|
|
6227
|
+
* @param join - The join node to add
|
|
6228
|
+
* @returns A new DeleteQueryState with the JOIN clause added
|
|
6229
|
+
*/
|
|
5862
6230
|
withJoin(join) {
|
|
5863
6231
|
return this.clone({
|
|
5864
6232
|
...this.ast,
|
|
5865
6233
|
joins: [...this.ast.joins ?? [], join]
|
|
5866
6234
|
});
|
|
5867
6235
|
}
|
|
6236
|
+
/**
|
|
6237
|
+
* Sets an alias for the table in the DELETE query
|
|
6238
|
+
* @param alias - The alias to assign to the table
|
|
6239
|
+
* @returns A new DeleteQueryState with the table alias set
|
|
6240
|
+
*/
|
|
5868
6241
|
withTableAlias(alias) {
|
|
5869
6242
|
return this.clone({
|
|
5870
6243
|
...this.ast,
|
|
@@ -5878,6 +6251,11 @@ var DeleteQueryState = class _DeleteQueryState {
|
|
|
5878
6251
|
|
|
5879
6252
|
// src/query-builder/delete.ts
|
|
5880
6253
|
var DeleteQueryBuilder = class _DeleteQueryBuilder {
|
|
6254
|
+
/**
|
|
6255
|
+
* Creates a new DeleteQueryBuilder instance
|
|
6256
|
+
* @param table - The table definition for the DELETE query
|
|
6257
|
+
* @param state - Optional initial query state, defaults to a new DeleteQueryState
|
|
6258
|
+
*/
|
|
5881
6259
|
constructor(table, state) {
|
|
5882
6260
|
this.table = table;
|
|
5883
6261
|
this.state = state ?? new DeleteQueryState(table);
|
|
@@ -5885,20 +6263,48 @@ var DeleteQueryBuilder = class _DeleteQueryBuilder {
|
|
|
5885
6263
|
clone(state) {
|
|
5886
6264
|
return new _DeleteQueryBuilder(this.table, state);
|
|
5887
6265
|
}
|
|
6266
|
+
/**
|
|
6267
|
+
* Adds a WHERE clause to the DELETE query
|
|
6268
|
+
* @param expr - The expression to use as the WHERE condition
|
|
6269
|
+
* @returns A new DeleteQueryBuilder with the WHERE clause added
|
|
6270
|
+
*/
|
|
5888
6271
|
where(expr) {
|
|
5889
6272
|
return this.clone(this.state.withWhere(expr));
|
|
5890
6273
|
}
|
|
6274
|
+
/**
|
|
6275
|
+
* Sets an alias for the table in the DELETE query
|
|
6276
|
+
* @param alias - The alias to assign to the table
|
|
6277
|
+
* @returns A new DeleteQueryBuilder with the table alias set
|
|
6278
|
+
*/
|
|
5891
6279
|
as(alias) {
|
|
5892
6280
|
return this.clone(this.state.withTableAlias(alias));
|
|
5893
6281
|
}
|
|
6282
|
+
/**
|
|
6283
|
+
* Adds a USING clause to the DELETE query
|
|
6284
|
+
* @param source - The table source to use in the USING clause
|
|
6285
|
+
* @returns A new DeleteQueryBuilder with the USING clause added
|
|
6286
|
+
*/
|
|
5894
6287
|
using(source) {
|
|
5895
6288
|
return this.clone(this.state.withUsing(this.resolveTableSource(source)));
|
|
5896
6289
|
}
|
|
6290
|
+
/**
|
|
6291
|
+
* Adds a JOIN clause to the DELETE query
|
|
6292
|
+
* @param table - The table to join with
|
|
6293
|
+
* @param condition - The join condition expression
|
|
6294
|
+
* @param kind - The type of join (defaults to INNER)
|
|
6295
|
+
* @param relationName - Optional name for the relation
|
|
6296
|
+
* @returns A new DeleteQueryBuilder with the JOIN clause added
|
|
6297
|
+
*/
|
|
5897
6298
|
join(table, condition, kind = JOIN_KINDS.INNER, relationName) {
|
|
5898
6299
|
const target = this.resolveJoinTarget(table);
|
|
5899
6300
|
const joinNode = createJoinNode(kind, target, condition, relationName);
|
|
5900
6301
|
return this.clone(this.state.withJoin(joinNode));
|
|
5901
6302
|
}
|
|
6303
|
+
/**
|
|
6304
|
+
* Adds a RETURNING clause to the DELETE query
|
|
6305
|
+
* @param columns - The columns to return after deletion
|
|
6306
|
+
* @returns A new DeleteQueryBuilder with the RETURNING clause added
|
|
6307
|
+
*/
|
|
5902
6308
|
returning(...columns) {
|
|
5903
6309
|
if (!columns.length) return this;
|
|
5904
6310
|
const nodes = columns.map((column) => buildColumnNode(this.table, column));
|
|
@@ -5914,16 +6320,36 @@ var DeleteQueryBuilder = class _DeleteQueryBuilder {
|
|
|
5914
6320
|
if (typeof table === "string") return table;
|
|
5915
6321
|
return this.resolveTableSource(table);
|
|
5916
6322
|
}
|
|
5917
|
-
|
|
5918
|
-
|
|
5919
|
-
|
|
5920
|
-
|
|
5921
|
-
|
|
5922
|
-
|
|
6323
|
+
/**
|
|
6324
|
+
* Compiles the DELETE query for the specified dialect
|
|
6325
|
+
* @param dialect - The SQL dialect to compile for
|
|
6326
|
+
* @returns The compiled query with SQL and parameters
|
|
6327
|
+
*/
|
|
6328
|
+
compile(dialect) {
|
|
6329
|
+
const resolved = resolveDialectInput(dialect);
|
|
6330
|
+
return resolved.compileDelete(this.state.ast);
|
|
5923
6331
|
}
|
|
5924
|
-
|
|
5925
|
-
|
|
6332
|
+
/**
|
|
6333
|
+
* Returns the SQL string for the DELETE query
|
|
6334
|
+
* @param dialect - The SQL dialect to generate SQL for
|
|
6335
|
+
* @returns The SQL string representation of the query
|
|
6336
|
+
*/
|
|
6337
|
+
toSql(dialect) {
|
|
6338
|
+
return this.compile(dialect).sql;
|
|
6339
|
+
}
|
|
6340
|
+
/**
|
|
6341
|
+
* Executes the DELETE query using the provided session
|
|
6342
|
+
* @param session - The ORM session to execute the query with
|
|
6343
|
+
* @returns A promise that resolves to the query results
|
|
6344
|
+
*/
|
|
6345
|
+
async execute(session) {
|
|
6346
|
+
const compiled = this.compile(session.dialect);
|
|
6347
|
+
return session.executor.executeSql(compiled.sql, compiled.params);
|
|
5926
6348
|
}
|
|
6349
|
+
/**
|
|
6350
|
+
* Returns the Abstract Syntax Tree (AST) representation of the query
|
|
6351
|
+
* @returns The AST node for the DELETE query
|
|
6352
|
+
*/
|
|
5927
6353
|
getAST() {
|
|
5928
6354
|
return this.state.ast;
|
|
5929
6355
|
}
|
|
@@ -5966,7 +6392,7 @@ var generateCreateTableSql = (table, dialect) => {
|
|
|
5966
6392
|
const pk = resolvePrimaryKey(table);
|
|
5967
6393
|
const inlinePkColumns = /* @__PURE__ */ new Set();
|
|
5968
6394
|
const columnLines = Object.values(table.columns).map((col2) => {
|
|
5969
|
-
const includePk = dialect.preferInlinePkAutoincrement
|
|
6395
|
+
const includePk = dialect.preferInlinePkAutoincrement(col2, table, pk) && pk.includes(col2.name);
|
|
5970
6396
|
if (includePk) {
|
|
5971
6397
|
inlinePkColumns.add(col2.name);
|
|
5972
6398
|
}
|
|
@@ -6358,6 +6784,13 @@ async function runSelectNode(ast, ctx) {
|
|
|
6358
6784
|
|
|
6359
6785
|
// src/core/ddl/introspect/postgres.ts
|
|
6360
6786
|
var postgresIntrospector = {
|
|
6787
|
+
/**
|
|
6788
|
+
* Introspects the PostgreSQL database schema by querying information_schema and pg_catalog.
|
|
6789
|
+
* Builds tables with columns, primary keys, foreign keys, and indexes.
|
|
6790
|
+
* @param ctx - The introspection context with database executor.
|
|
6791
|
+
* @param options - Options for schema selection and table filtering.
|
|
6792
|
+
* @returns A promise resolving to the complete database schema.
|
|
6793
|
+
*/
|
|
6361
6794
|
async introspect(ctx, options) {
|
|
6362
6795
|
const schema = options.schema || "public";
|
|
6363
6796
|
const tables = [];
|
|
@@ -6471,7 +6904,7 @@ var postgresIntrospector = {
|
|
|
6471
6904
|
],
|
|
6472
6905
|
where: and(
|
|
6473
6906
|
eq({ table: "ns", name: "nspname" }, schema),
|
|
6474
|
-
eq({ table: "i", name: "indisprimary" },
|
|
6907
|
+
eq({ table: "i", name: "indisprimary" }, false)
|
|
6475
6908
|
)
|
|
6476
6909
|
};
|
|
6477
6910
|
const indexQueryRows = await runSelectNode(indexQuery, ctx);
|
|
@@ -6635,8 +7068,22 @@ var mysqlIntrospector = {
|
|
|
6635
7068
|
};
|
|
6636
7069
|
|
|
6637
7070
|
// src/core/ddl/introspect/sqlite.ts
|
|
7071
|
+
var toReferentialAction = (value) => {
|
|
7072
|
+
if (!value) return void 0;
|
|
7073
|
+
const normalized = value.toUpperCase();
|
|
7074
|
+
if (normalized === "NO ACTION" || normalized === "RESTRICT" || normalized === "CASCADE" || normalized === "SET NULL" || normalized === "SET DEFAULT") {
|
|
7075
|
+
return normalized;
|
|
7076
|
+
}
|
|
7077
|
+
return void 0;
|
|
7078
|
+
};
|
|
6638
7079
|
var escapeSingleQuotes = (name) => name.replace(/'/g, "''");
|
|
6639
7080
|
var sqliteIntrospector = {
|
|
7081
|
+
/**
|
|
7082
|
+
* Introspects the SQLite database schema by querying sqlite_master and various PRAGMAs.
|
|
7083
|
+
* @param ctx - The database execution context containing the DbExecutor.
|
|
7084
|
+
* @param options - Options controlling which tables and schemas to include.
|
|
7085
|
+
* @returns A promise that resolves to the introspected DatabaseSchema.
|
|
7086
|
+
*/
|
|
6640
7087
|
async introspect(ctx, options) {
|
|
6641
7088
|
const tables = [];
|
|
6642
7089
|
const tableRows = await queryRows(
|
|
@@ -6668,8 +7115,8 @@ var sqliteIntrospector = {
|
|
|
6668
7115
|
col2.references = {
|
|
6669
7116
|
table: fk.table,
|
|
6670
7117
|
column: fk.to,
|
|
6671
|
-
onDelete: fk.on_delete
|
|
6672
|
-
onUpdate: fk.on_update
|
|
7118
|
+
onDelete: toReferentialAction(fk.on_delete),
|
|
7119
|
+
onUpdate: toReferentialAction(fk.on_update)
|
|
6673
7120
|
};
|
|
6674
7121
|
}
|
|
6675
7122
|
});
|
|
@@ -6692,6 +7139,12 @@ var sqliteIntrospector = {
|
|
|
6692
7139
|
|
|
6693
7140
|
// src/core/ddl/introspect/mssql.ts
|
|
6694
7141
|
var mssqlIntrospector = {
|
|
7142
|
+
/**
|
|
7143
|
+
* Introspects the MSSQL database schema.
|
|
7144
|
+
* @param ctx - The introspection context containing the database executor.
|
|
7145
|
+
* @param options - Options for introspection, such as schema filter.
|
|
7146
|
+
* @returns A promise that resolves to the introspected database schema.
|
|
7147
|
+
*/
|
|
6695
7148
|
async introspect(ctx, options) {
|
|
6696
7149
|
const schema = options.schema;
|
|
6697
7150
|
const filterSchema = schema ? "sch.name = @p1" : "1=1";
|
|
@@ -6974,10 +7427,21 @@ var dateTrunc = (part, date) => fn3("DATE_TRUNC", [part, date]);
|
|
|
6974
7427
|
// src/orm/als.ts
|
|
6975
7428
|
var AsyncLocalStorage = class {
|
|
6976
7429
|
/**
|
|
6977
|
-
* Executes a callback
|
|
6978
|
-
*
|
|
6979
|
-
*
|
|
6980
|
-
*
|
|
7430
|
+
* Executes a callback function within a context containing the specified store value.
|
|
7431
|
+
* The store value is only available during the callback's execution and is automatically
|
|
7432
|
+
* cleared afterward.
|
|
7433
|
+
*
|
|
7434
|
+
* @param store - The context value to make available during callback execution
|
|
7435
|
+
* @param callback - Function to execute with the store value available
|
|
7436
|
+
* @returns Result of the callback function execution
|
|
7437
|
+
*
|
|
7438
|
+
* @example
|
|
7439
|
+
* ```
|
|
7440
|
+
* const als = new AsyncLocalStorage<number>();
|
|
7441
|
+
* als.run(42, () => {
|
|
7442
|
+
* console.log(als.getStore()); // Outputs: 42
|
|
7443
|
+
* });
|
|
7444
|
+
* ```
|
|
6981
7445
|
*/
|
|
6982
7446
|
run(store, callback) {
|
|
6983
7447
|
this.store = store;
|
|
@@ -6988,8 +7452,20 @@ var AsyncLocalStorage = class {
|
|
|
6988
7452
|
}
|
|
6989
7453
|
}
|
|
6990
7454
|
/**
|
|
6991
|
-
*
|
|
6992
|
-
*
|
|
7455
|
+
* Retrieves the current store value from the async context.
|
|
7456
|
+
* Returns undefined if called outside of a `run()` callback execution.
|
|
7457
|
+
*
|
|
7458
|
+
* @returns Current store value or undefined if no context exists
|
|
7459
|
+
*
|
|
7460
|
+
* @example
|
|
7461
|
+
* ```
|
|
7462
|
+
* const als = new AsyncLocalStorage<string>();
|
|
7463
|
+
* console.log(als.getStore()); // Outputs: undefined
|
|
7464
|
+
*
|
|
7465
|
+
* als.run('hello', () => {
|
|
7466
|
+
* console.log(als.getStore()); // Outputs: 'hello'
|
|
7467
|
+
* });
|
|
7468
|
+
* ```
|
|
6993
7469
|
*/
|
|
6994
7470
|
getStore() {
|
|
6995
7471
|
return this.store;
|
|
@@ -7079,11 +7555,7 @@ var TypeScriptGenerator = class {
|
|
|
7079
7555
|
const lines = [];
|
|
7080
7556
|
const hydration = ast.meta?.hydration;
|
|
7081
7557
|
const hydratedRelations = new Set(hydration?.relations?.map((r) => r.name) ?? []);
|
|
7082
|
-
const selections = ast.columns.filter((col2) => !(hydration && isRelationAlias(col2.alias))).map((col2) => {
|
|
7083
|
-
const key = col2.alias || col2.name;
|
|
7084
|
-
const operand = col2;
|
|
7085
|
-
return `${key}: ${this.printOperand(operand)}`;
|
|
7086
|
-
});
|
|
7558
|
+
const selections = ast.columns.filter((col2) => !(hydration && isRelationAlias(col2.alias))).map((col2, index) => `${this.getSelectionKey(col2, index)}: ${this.printOperand(col2)}`);
|
|
7087
7559
|
lines.push(`db.select({`);
|
|
7088
7560
|
selections.forEach((sel2, index) => {
|
|
7089
7561
|
lines.push(` ${sel2}${index < selections.length - 1 ? "," : ""}`);
|
|
@@ -7171,7 +7643,7 @@ var TypeScriptGenerator = class {
|
|
|
7171
7643
|
* Prints an ordering term (operand/expression/alias) to TypeScript code.
|
|
7172
7644
|
*/
|
|
7173
7645
|
printOrderingTerm(term) {
|
|
7174
|
-
if (!term || !term
|
|
7646
|
+
if (!term || !("type" in term)) {
|
|
7175
7647
|
throw new Error("Unsupported ordering term");
|
|
7176
7648
|
}
|
|
7177
7649
|
switch (term.type) {
|
|
@@ -7190,6 +7662,18 @@ var TypeScriptGenerator = class {
|
|
|
7190
7662
|
return this.printExpression(term);
|
|
7191
7663
|
}
|
|
7192
7664
|
}
|
|
7665
|
+
getSelectionKey(selection, index) {
|
|
7666
|
+
if (selection.alias) {
|
|
7667
|
+
return selection.alias;
|
|
7668
|
+
}
|
|
7669
|
+
if (this.isNamedSelection(selection)) {
|
|
7670
|
+
return selection.name;
|
|
7671
|
+
}
|
|
7672
|
+
return `selection${index + 1}`;
|
|
7673
|
+
}
|
|
7674
|
+
isNamedSelection(selection) {
|
|
7675
|
+
return "name" in selection;
|
|
7676
|
+
}
|
|
7193
7677
|
visitBinaryExpression(binary) {
|
|
7194
7678
|
return this.printBinaryExpression(binary);
|
|
7195
7679
|
}
|
|
@@ -7973,6 +8457,7 @@ var RelationChangeProcessor = class {
|
|
|
7973
8457
|
* @param _entry - The relation change entry (reserved for future use)
|
|
7974
8458
|
*/
|
|
7975
8459
|
async handleBelongsToChange(_entry) {
|
|
8460
|
+
void _entry;
|
|
7976
8461
|
}
|
|
7977
8462
|
/**
|
|
7978
8463
|
* Handles changes for belongs-to-many relations.
|
|
@@ -8086,7 +8571,7 @@ var RelationChangeProcessor = class {
|
|
|
8086
8571
|
const key = findPrimaryKey(table);
|
|
8087
8572
|
const value = entity[key];
|
|
8088
8573
|
if (value === void 0 || value === null) return null;
|
|
8089
|
-
return value;
|
|
8574
|
+
return value ?? null;
|
|
8090
8575
|
}
|
|
8091
8576
|
};
|
|
8092
8577
|
|
|
@@ -8678,8 +9163,6 @@ var Orm = class {
|
|
|
8678
9163
|
const session = new OrmSession({ orm: this, executor });
|
|
8679
9164
|
try {
|
|
8680
9165
|
return await session.transaction(() => fn4(session));
|
|
8681
|
-
} catch (err) {
|
|
8682
|
-
throw err;
|
|
8683
9166
|
} finally {
|
|
8684
9167
|
await session.dispose();
|
|
8685
9168
|
}
|
|
@@ -8710,9 +9193,6 @@ var getOrCreateMetadataBag = (context) => {
|
|
|
8710
9193
|
var readMetadataBag = (context) => {
|
|
8711
9194
|
return context.metadata?.[METADATA_KEY];
|
|
8712
9195
|
};
|
|
8713
|
-
var registerInitializer = (context, initializer) => {
|
|
8714
|
-
context.addInitializer?.(initializer);
|
|
8715
|
-
};
|
|
8716
9196
|
|
|
8717
9197
|
// src/decorators/entity.ts
|
|
8718
9198
|
var toSnakeCase = (value) => {
|
|
@@ -8742,14 +9222,24 @@ function Entity(options = {}) {
|
|
|
8742
9222
|
if (bag) {
|
|
8743
9223
|
const meta = ensureEntityMetadata(ctor);
|
|
8744
9224
|
for (const entry of bag.columns) {
|
|
8745
|
-
if (
|
|
8746
|
-
|
|
9225
|
+
if (meta.columns[entry.propertyName]) {
|
|
9226
|
+
throw new Error(
|
|
9227
|
+
`Column '${entry.propertyName}' is already defined on entity '${ctor.name}'.`
|
|
9228
|
+
);
|
|
8747
9229
|
}
|
|
9230
|
+
addColumnMetadata(ctor, entry.propertyName, { ...entry.column });
|
|
8748
9231
|
}
|
|
8749
9232
|
for (const entry of bag.relations) {
|
|
8750
|
-
if (
|
|
8751
|
-
|
|
9233
|
+
if (meta.relations[entry.propertyName]) {
|
|
9234
|
+
throw new Error(
|
|
9235
|
+
`Relation '${entry.propertyName}' is already defined on entity '${ctor.name}'.`
|
|
9236
|
+
);
|
|
8752
9237
|
}
|
|
9238
|
+
const relationCopy = entry.relation.kind === RelationKinds.BelongsToMany ? {
|
|
9239
|
+
...entry.relation,
|
|
9240
|
+
defaultPivotColumns: entry.relation.defaultPivotColumns ? [...entry.relation.defaultPivotColumns] : void 0
|
|
9241
|
+
} : { ...entry.relation };
|
|
9242
|
+
addRelationMetadata(ctor, entry.propertyName, relationCopy);
|
|
8753
9243
|
}
|
|
8754
9244
|
}
|
|
8755
9245
|
}
|
|
@@ -8812,13 +9302,6 @@ var registerColumnFromContext = (context, column) => {
|
|
|
8812
9302
|
if (!bag.columns.some((entry) => entry.propertyName === propertyName)) {
|
|
8813
9303
|
bag.columns.push({ propertyName, column: { ...column } });
|
|
8814
9304
|
}
|
|
8815
|
-
registerInitializer(context, function() {
|
|
8816
|
-
const ctor = resolveConstructor(this);
|
|
8817
|
-
if (!ctor) {
|
|
8818
|
-
return;
|
|
8819
|
-
}
|
|
8820
|
-
registerColumn(ctor, propertyName, column);
|
|
8821
|
-
});
|
|
8822
9305
|
};
|
|
8823
9306
|
function Column(definition) {
|
|
8824
9307
|
const normalized = normalizeColumnInput(definition);
|
|
@@ -8874,13 +9357,6 @@ var createFieldDecorator = (metadataFactory) => {
|
|
|
8874
9357
|
if (!bag.relations.some((entry) => entry.propertyName === propertyName2)) {
|
|
8875
9358
|
bag.relations.push({ propertyName: propertyName2, relation: relationMetadata });
|
|
8876
9359
|
}
|
|
8877
|
-
registerInitializer(ctx, function() {
|
|
8878
|
-
const ctor2 = resolveConstructor2(this);
|
|
8879
|
-
if (!ctor2) {
|
|
8880
|
-
return;
|
|
8881
|
-
}
|
|
8882
|
-
registerRelation(ctor2, propertyName2, relationMetadata);
|
|
8883
|
-
});
|
|
8884
9360
|
return;
|
|
8885
9361
|
}
|
|
8886
9362
|
const propertyName = normalizePropertyName2(propertyKeyOrContext);
|
|
@@ -9518,11 +9994,9 @@ function createPooledExecutorFactory(opts) {
|
|
|
9518
9994
|
cos,
|
|
9519
9995
|
cot,
|
|
9520
9996
|
count,
|
|
9521
|
-
createColumn,
|
|
9522
9997
|
createEntityFromRow,
|
|
9523
9998
|
createEntityProxy,
|
|
9524
9999
|
createExecutorFromQueryRunner,
|
|
9525
|
-
createLiteral,
|
|
9526
10000
|
createMssqlExecutor,
|
|
9527
10001
|
createMysqlExecutor,
|
|
9528
10002
|
createPooledExecutorFactory,
|
|
@@ -9546,6 +10020,7 @@ function createPooledExecutorFactory(opts) {
|
|
|
9546
10020
|
diffSchema,
|
|
9547
10021
|
div,
|
|
9548
10022
|
endOfMonth,
|
|
10023
|
+
entityRef,
|
|
9549
10024
|
eq,
|
|
9550
10025
|
esel,
|
|
9551
10026
|
executeHydrated,
|
|
@@ -9558,6 +10033,7 @@ function createPooledExecutorFactory(opts) {
|
|
|
9558
10033
|
fromUnixTime,
|
|
9559
10034
|
generateCreateTableSql,
|
|
9560
10035
|
generateSchemaSql,
|
|
10036
|
+
getColumn,
|
|
9561
10037
|
getSchemaIntrospector,
|
|
9562
10038
|
getTableDefFromEntity,
|
|
9563
10039
|
groupConcat,
|