metal-orm 1.0.16 → 1.0.18
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 +37 -40
- package/dist/decorators/index.cjs +344 -69
- package/dist/decorators/index.cjs.map +1 -1
- package/dist/decorators/index.d.cts +1 -1
- package/dist/decorators/index.d.ts +1 -1
- package/dist/decorators/index.js +344 -69
- package/dist/decorators/index.js.map +1 -1
- package/dist/index.cjs +567 -181
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +66 -30
- package/dist/index.d.ts +66 -30
- package/dist/index.js +559 -181
- package/dist/index.js.map +1 -1
- package/dist/{select-BKZrMRCQ.d.cts → select-BuMpVcVt.d.cts} +265 -74
- package/dist/{select-BKZrMRCQ.d.ts → select-BuMpVcVt.d.ts} +265 -74
- package/package.json +5 -1
- package/src/codegen/naming-strategy.ts +15 -10
- package/src/core/ast/aggregate-functions.ts +50 -4
- package/src/core/ast/builders.ts +23 -3
- package/src/core/ast/expression-builders.ts +36 -16
- package/src/core/ast/expression-nodes.ts +17 -9
- package/src/core/ast/join-node.ts +5 -3
- package/src/core/ast/join.ts +16 -16
- package/src/core/ast/query.ts +44 -29
- package/src/core/ddl/dialects/mssql-schema-dialect.ts +18 -0
- package/src/core/ddl/dialects/mysql-schema-dialect.ts +11 -0
- package/src/core/ddl/dialects/postgres-schema-dialect.ts +9 -0
- package/src/core/ddl/dialects/sqlite-schema-dialect.ts +9 -0
- package/src/core/ddl/introspect/functions/postgres.ts +2 -6
- package/src/core/dialect/abstract.ts +12 -8
- package/src/core/dialect/base/sql-dialect.ts +58 -46
- package/src/core/dialect/mssql/functions.ts +24 -15
- package/src/core/dialect/mssql/index.ts +53 -28
- package/src/core/dialect/postgres/functions.ts +33 -24
- package/src/core/dialect/sqlite/functions.ts +19 -12
- package/src/core/dialect/sqlite/index.ts +22 -13
- package/src/core/functions/datetime.ts +2 -1
- package/src/core/functions/numeric.ts +2 -1
- package/src/core/functions/standard-strategy.ts +52 -12
- package/src/core/functions/text.ts +2 -1
- package/src/core/functions/types.ts +8 -8
- package/src/index.ts +5 -4
- package/src/orm/domain-event-bus.ts +43 -25
- package/src/orm/entity-meta.ts +40 -0
- package/src/orm/execution-context.ts +6 -0
- package/src/orm/hydration-context.ts +6 -4
- package/src/orm/orm-session.ts +35 -24
- package/src/orm/orm.ts +10 -10
- package/src/orm/query-logger.ts +15 -0
- package/src/orm/runtime-types.ts +60 -2
- package/src/orm/transaction-runner.ts +7 -0
- package/src/orm/unit-of-work.ts +1 -0
- package/src/query-builder/column-selector.ts +9 -7
- package/src/query-builder/insert-query-state.ts +13 -3
- package/src/query-builder/query-ast-service.ts +59 -38
- package/src/query-builder/relation-conditions.ts +38 -34
- package/src/query-builder/relation-manager.ts +8 -3
- package/src/query-builder/relation-service.ts +59 -46
- package/src/query-builder/select-helpers.ts +50 -0
- package/src/query-builder/select-query-state.ts +19 -7
- package/src/query-builder/select.ts +339 -167
- package/src/query-builder/update-query-state.ts +31 -9
- package/src/schema/column.ts +75 -39
- package/src/schema/types.ts +17 -6
package/dist/index.js
CHANGED
|
@@ -88,6 +88,30 @@ var col = {
|
|
|
88
88
|
* Creates a UUID column definition
|
|
89
89
|
*/
|
|
90
90
|
uuid: () => ({ name: "", type: "UUID" }),
|
|
91
|
+
/**
|
|
92
|
+
* Creates a binary large object column definition
|
|
93
|
+
*/
|
|
94
|
+
blob: () => ({ name: "", type: "BLOB" }),
|
|
95
|
+
/**
|
|
96
|
+
* Creates a fixed-length binary column definition
|
|
97
|
+
*/
|
|
98
|
+
binary: (length2) => ({
|
|
99
|
+
name: "",
|
|
100
|
+
type: "BINARY",
|
|
101
|
+
args: length2 !== void 0 ? [length2] : void 0
|
|
102
|
+
}),
|
|
103
|
+
/**
|
|
104
|
+
* Creates a variable-length binary column definition
|
|
105
|
+
*/
|
|
106
|
+
varbinary: (length2) => ({
|
|
107
|
+
name: "",
|
|
108
|
+
type: "VARBINARY",
|
|
109
|
+
args: length2 !== void 0 ? [length2] : void 0
|
|
110
|
+
}),
|
|
111
|
+
/**
|
|
112
|
+
* Creates a Postgres bytea column definition
|
|
113
|
+
*/
|
|
114
|
+
bytea: () => ({ name: "", type: "BYTEA" }),
|
|
91
115
|
/**
|
|
92
116
|
* Creates a timestamp column definition
|
|
93
117
|
*/
|
|
@@ -237,10 +261,13 @@ var isExpressionSelectionNode = (node) => isFunctionNode(node) || isCaseExpressi
|
|
|
237
261
|
|
|
238
262
|
// src/core/ast/expression-builders.ts
|
|
239
263
|
var valueToOperand = (value) => {
|
|
240
|
-
if (value
|
|
241
|
-
return
|
|
264
|
+
if (isOperandNode(value)) {
|
|
265
|
+
return value;
|
|
242
266
|
}
|
|
243
|
-
return
|
|
267
|
+
return {
|
|
268
|
+
type: "Literal",
|
|
269
|
+
value
|
|
270
|
+
};
|
|
244
271
|
};
|
|
245
272
|
var toNode = (col2) => {
|
|
246
273
|
if (isOperandNode(col2)) return col2;
|
|
@@ -251,14 +278,20 @@ var toLiteralNode = (value) => ({
|
|
|
251
278
|
type: "Literal",
|
|
252
279
|
value
|
|
253
280
|
});
|
|
281
|
+
var isLiteralValue = (value) => value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean";
|
|
282
|
+
var isValueOperandInput = (value) => isOperandNode(value) || isLiteralValue(value);
|
|
254
283
|
var toOperand = (val) => {
|
|
255
|
-
if (val
|
|
256
|
-
|
|
257
|
-
return { type: "Literal", value: val };
|
|
284
|
+
if (isLiteralValue(val)) {
|
|
285
|
+
return valueToOperand(val);
|
|
258
286
|
}
|
|
259
287
|
return toNode(val);
|
|
260
288
|
};
|
|
261
289
|
var columnOperand = (col2) => toNode(col2);
|
|
290
|
+
var outerRef = (col2) => ({
|
|
291
|
+
...columnOperand(col2),
|
|
292
|
+
scope: "outer"
|
|
293
|
+
});
|
|
294
|
+
var correlateBy = (table, column) => outerRef({ name: column, table });
|
|
262
295
|
var createBinaryExpression = (operator, left2, right2, escape) => {
|
|
263
296
|
const node = {
|
|
264
297
|
type: "BinaryExpression",
|
|
@@ -400,6 +433,62 @@ var windowFunction = (name, args = [], partitionBy, orderBy) => {
|
|
|
400
433
|
return buildWindowFunction(name, nodeArgs, partitionNodes, orderNodes);
|
|
401
434
|
};
|
|
402
435
|
|
|
436
|
+
// src/core/sql/sql.ts
|
|
437
|
+
var SQL_OPERATORS = {
|
|
438
|
+
/** Equality operator */
|
|
439
|
+
EQUALS: "=",
|
|
440
|
+
/** Not equals operator */
|
|
441
|
+
NOT_EQUALS: "!=",
|
|
442
|
+
/** Greater than operator */
|
|
443
|
+
GREATER_THAN: ">",
|
|
444
|
+
/** Greater than or equal operator */
|
|
445
|
+
GREATER_OR_EQUAL: ">=",
|
|
446
|
+
/** Less than operator */
|
|
447
|
+
LESS_THAN: "<",
|
|
448
|
+
/** Less than or equal operator */
|
|
449
|
+
LESS_OR_EQUAL: "<=",
|
|
450
|
+
/** LIKE pattern matching operator */
|
|
451
|
+
LIKE: "LIKE",
|
|
452
|
+
/** NOT LIKE pattern matching operator */
|
|
453
|
+
NOT_LIKE: "NOT LIKE",
|
|
454
|
+
/** IN membership operator */
|
|
455
|
+
IN: "IN",
|
|
456
|
+
/** NOT IN membership operator */
|
|
457
|
+
NOT_IN: "NOT IN",
|
|
458
|
+
/** BETWEEN range operator */
|
|
459
|
+
BETWEEN: "BETWEEN",
|
|
460
|
+
/** NOT BETWEEN range operator */
|
|
461
|
+
NOT_BETWEEN: "NOT BETWEEN",
|
|
462
|
+
/** IS NULL null check operator */
|
|
463
|
+
IS_NULL: "IS NULL",
|
|
464
|
+
/** IS NOT NULL null check operator */
|
|
465
|
+
IS_NOT_NULL: "IS NOT NULL",
|
|
466
|
+
/** Logical AND operator */
|
|
467
|
+
AND: "AND",
|
|
468
|
+
/** Logical OR operator */
|
|
469
|
+
OR: "OR",
|
|
470
|
+
/** EXISTS operator */
|
|
471
|
+
EXISTS: "EXISTS",
|
|
472
|
+
/** NOT EXISTS operator */
|
|
473
|
+
NOT_EXISTS: "NOT EXISTS"
|
|
474
|
+
};
|
|
475
|
+
var JOIN_KINDS = {
|
|
476
|
+
/** INNER JOIN type */
|
|
477
|
+
INNER: "INNER",
|
|
478
|
+
/** LEFT JOIN type */
|
|
479
|
+
LEFT: "LEFT",
|
|
480
|
+
/** RIGHT JOIN type */
|
|
481
|
+
RIGHT: "RIGHT",
|
|
482
|
+
/** CROSS JOIN type */
|
|
483
|
+
CROSS: "CROSS"
|
|
484
|
+
};
|
|
485
|
+
var ORDER_DIRECTIONS = {
|
|
486
|
+
/** Ascending order */
|
|
487
|
+
ASC: "ASC",
|
|
488
|
+
/** Descending order */
|
|
489
|
+
DESC: "DESC"
|
|
490
|
+
};
|
|
491
|
+
|
|
403
492
|
// src/core/ast/aggregate-functions.ts
|
|
404
493
|
var buildAggregate = (name) => (col2) => ({
|
|
405
494
|
type: "Function",
|
|
@@ -409,6 +498,20 @@ var buildAggregate = (name) => (col2) => ({
|
|
|
409
498
|
var count = buildAggregate("COUNT");
|
|
410
499
|
var sum = buildAggregate("SUM");
|
|
411
500
|
var avg = buildAggregate("AVG");
|
|
501
|
+
var min = buildAggregate("MIN");
|
|
502
|
+
var max = buildAggregate("MAX");
|
|
503
|
+
var toOrderByNode = (order) => ({
|
|
504
|
+
type: "OrderBy",
|
|
505
|
+
column: columnOperand(order.column),
|
|
506
|
+
direction: order.direction ?? ORDER_DIRECTIONS.ASC
|
|
507
|
+
});
|
|
508
|
+
var groupConcat = (col2, options) => ({
|
|
509
|
+
type: "Function",
|
|
510
|
+
name: "GROUP_CONCAT",
|
|
511
|
+
args: [columnOperand(col2)],
|
|
512
|
+
orderBy: options?.orderBy?.map(toOrderByNode),
|
|
513
|
+
separator: options?.separator !== void 0 ? valueToOperand(options.separator) : void 0
|
|
514
|
+
});
|
|
412
515
|
|
|
413
516
|
// src/core/ast/expression-visitor.ts
|
|
414
517
|
var expressionDispatchers = /* @__PURE__ */ new Map();
|
|
@@ -499,13 +602,57 @@ var toTableRef = (table) => ({
|
|
|
499
602
|
alias: table.alias
|
|
500
603
|
});
|
|
501
604
|
|
|
605
|
+
// src/core/ast/builders.ts
|
|
606
|
+
var buildColumnNode = (table, column) => {
|
|
607
|
+
if (column.type === "Column") {
|
|
608
|
+
return column;
|
|
609
|
+
}
|
|
610
|
+
const def = column;
|
|
611
|
+
const baseTable = def.table ? table.alias && def.table === table.name ? table.alias : def.table : table.alias || table.name;
|
|
612
|
+
return {
|
|
613
|
+
type: "Column",
|
|
614
|
+
table: baseTable,
|
|
615
|
+
name: def.name
|
|
616
|
+
};
|
|
617
|
+
};
|
|
618
|
+
var buildColumnNodes = (table, names) => names.map((name) => ({
|
|
619
|
+
type: "Column",
|
|
620
|
+
table: table.alias || table.name,
|
|
621
|
+
name
|
|
622
|
+
}));
|
|
623
|
+
var createTableNode = (table) => ({
|
|
624
|
+
type: "Table",
|
|
625
|
+
name: table.name
|
|
626
|
+
});
|
|
627
|
+
var fnTable = (name, args = [], alias, opts) => ({
|
|
628
|
+
type: "FunctionTable",
|
|
629
|
+
name,
|
|
630
|
+
args,
|
|
631
|
+
alias,
|
|
632
|
+
lateral: opts?.lateral,
|
|
633
|
+
withOrdinality: opts?.withOrdinality,
|
|
634
|
+
columnAliases: opts?.columnAliases,
|
|
635
|
+
schema: opts?.schema
|
|
636
|
+
});
|
|
637
|
+
var derivedTable = (query, alias, columnAliases) => ({
|
|
638
|
+
type: "DerivedTable",
|
|
639
|
+
query,
|
|
640
|
+
alias,
|
|
641
|
+
columnAliases
|
|
642
|
+
});
|
|
643
|
+
|
|
502
644
|
// src/core/functions/standard-strategy.ts
|
|
503
|
-
var StandardFunctionStrategy = class {
|
|
645
|
+
var StandardFunctionStrategy = class _StandardFunctionStrategy {
|
|
504
646
|
constructor() {
|
|
505
647
|
this.renderers = /* @__PURE__ */ new Map();
|
|
506
648
|
this.registerStandard();
|
|
507
649
|
}
|
|
508
650
|
registerStandard() {
|
|
651
|
+
this.add("COUNT", ({ compiledArgs }) => `COUNT(${compiledArgs.join(", ")})`);
|
|
652
|
+
this.add("SUM", ({ compiledArgs }) => `SUM(${compiledArgs[0]})`);
|
|
653
|
+
this.add("AVG", ({ compiledArgs }) => `AVG(${compiledArgs[0]})`);
|
|
654
|
+
this.add("MIN", ({ compiledArgs }) => `MIN(${compiledArgs[0]})`);
|
|
655
|
+
this.add("MAX", ({ compiledArgs }) => `MAX(${compiledArgs[0]})`);
|
|
509
656
|
this.add("ABS", ({ compiledArgs }) => `ABS(${compiledArgs[0]})`);
|
|
510
657
|
this.add("UPPER", ({ compiledArgs }) => `UPPER(${compiledArgs[0]})`);
|
|
511
658
|
this.add("LOWER", ({ compiledArgs }) => `LOWER(${compiledArgs[0]})`);
|
|
@@ -532,6 +679,7 @@ var StandardFunctionStrategy = class {
|
|
|
532
679
|
this.add("DAY_OF_WEEK", ({ compiledArgs }) => `DAYOFWEEK(${compiledArgs[0]})`);
|
|
533
680
|
this.add("WEEK_OF_YEAR", ({ compiledArgs }) => `WEEKOFYEAR(${compiledArgs[0]})`);
|
|
534
681
|
this.add("DATE_TRUNC", ({ compiledArgs }) => `DATE_TRUNC(${compiledArgs[0]}, ${compiledArgs[1]})`);
|
|
682
|
+
this.add("GROUP_CONCAT", (ctx) => this.renderGroupConcat(ctx));
|
|
535
683
|
}
|
|
536
684
|
add(name, renderer) {
|
|
537
685
|
this.renderers.set(name, renderer);
|
|
@@ -539,6 +687,36 @@ var StandardFunctionStrategy = class {
|
|
|
539
687
|
getRenderer(name) {
|
|
540
688
|
return this.renderers.get(name);
|
|
541
689
|
}
|
|
690
|
+
renderGroupConcat(ctx) {
|
|
691
|
+
const arg = ctx.compiledArgs[0];
|
|
692
|
+
const orderClause = this.buildOrderByExpression(ctx);
|
|
693
|
+
const orderSegment = orderClause ? ` ${orderClause}` : "";
|
|
694
|
+
const separatorClause = this.formatGroupConcatSeparator(ctx);
|
|
695
|
+
return `GROUP_CONCAT(${arg}${orderSegment}${separatorClause})`;
|
|
696
|
+
}
|
|
697
|
+
buildOrderByExpression(ctx) {
|
|
698
|
+
const orderBy = ctx.node.orderBy;
|
|
699
|
+
if (!orderBy || orderBy.length === 0) {
|
|
700
|
+
return "";
|
|
701
|
+
}
|
|
702
|
+
const parts = orderBy.map((order) => `${ctx.compileOperand(order.column)} ${order.direction}`);
|
|
703
|
+
return `ORDER BY ${parts.join(", ")}`;
|
|
704
|
+
}
|
|
705
|
+
formatGroupConcatSeparator(ctx) {
|
|
706
|
+
if (!ctx.node.separator) {
|
|
707
|
+
return "";
|
|
708
|
+
}
|
|
709
|
+
return ` SEPARATOR ${ctx.compileOperand(ctx.node.separator)}`;
|
|
710
|
+
}
|
|
711
|
+
getGroupConcatSeparatorOperand(ctx) {
|
|
712
|
+
return ctx.node.separator ?? _StandardFunctionStrategy.DEFAULT_GROUP_CONCAT_SEPARATOR;
|
|
713
|
+
}
|
|
714
|
+
static {
|
|
715
|
+
this.DEFAULT_GROUP_CONCAT_SEPARATOR = {
|
|
716
|
+
type: "Literal",
|
|
717
|
+
value: ","
|
|
718
|
+
};
|
|
719
|
+
}
|
|
542
720
|
};
|
|
543
721
|
|
|
544
722
|
// src/core/dialect/abstract.ts
|
|
@@ -885,7 +1063,11 @@ var Dialect = class _Dialect {
|
|
|
885
1063
|
const compiledArgs = fnNode.args.map((arg) => this.compileOperand(arg, ctx));
|
|
886
1064
|
const renderer = this.functionStrategy.getRenderer(fnNode.name);
|
|
887
1065
|
if (renderer) {
|
|
888
|
-
return renderer({
|
|
1066
|
+
return renderer({
|
|
1067
|
+
node: fnNode,
|
|
1068
|
+
compiledArgs,
|
|
1069
|
+
compileOperand: (operand) => this.compileOperand(operand, ctx)
|
|
1070
|
+
});
|
|
889
1071
|
}
|
|
890
1072
|
return `${fnNode.name}(${compiledArgs.join(", ")})`;
|
|
891
1073
|
}
|
|
@@ -1148,7 +1330,7 @@ var SqlDialectBase = class extends Dialect {
|
|
|
1148
1330
|
return this.returningStrategy.compileReturning(returning, ctx);
|
|
1149
1331
|
}
|
|
1150
1332
|
compileInsertColumnList(columns) {
|
|
1151
|
-
return columns.map((column) =>
|
|
1333
|
+
return columns.map((column) => this.quoteIdentifier(column.name)).join(", ");
|
|
1152
1334
|
}
|
|
1153
1335
|
compileInsertValues(values, ctx) {
|
|
1154
1336
|
return values.map((row) => `(${row.map((value) => this.compileOperand(value, ctx)).join(", ")})`).join(", ");
|
|
@@ -1174,7 +1356,7 @@ var SqlDialectBase = class extends Dialect {
|
|
|
1174
1356
|
compileUpdateAssignments(assignments, ctx) {
|
|
1175
1357
|
return assignments.map((assignment) => {
|
|
1176
1358
|
const col2 = assignment.column;
|
|
1177
|
-
const target =
|
|
1359
|
+
const target = this.quoteIdentifier(col2.name);
|
|
1178
1360
|
const value = this.compileOperand(assignment.value, ctx);
|
|
1179
1361
|
return `${target} = ${value}`;
|
|
1180
1362
|
}).join(", ");
|
|
@@ -1206,12 +1388,29 @@ var SqlDialectBase = class extends Dialect {
|
|
|
1206
1388
|
if (tableSource.type === "FunctionTable") {
|
|
1207
1389
|
return this.compileFunctionTable(tableSource, ctx);
|
|
1208
1390
|
}
|
|
1391
|
+
if (tableSource.type === "DerivedTable") {
|
|
1392
|
+
return this.compileDerivedTable(tableSource, ctx);
|
|
1393
|
+
}
|
|
1209
1394
|
return this.compileTableSource(tableSource);
|
|
1210
1395
|
}
|
|
1211
1396
|
compileFunctionTable(fn4, ctx) {
|
|
1212
1397
|
return FunctionTableFormatter.format(fn4, ctx, this);
|
|
1213
1398
|
}
|
|
1399
|
+
compileDerivedTable(table, ctx) {
|
|
1400
|
+
if (!table.alias) {
|
|
1401
|
+
throw new Error("Derived tables must have an alias.");
|
|
1402
|
+
}
|
|
1403
|
+
const subquery = this.compileSelectAst(this.normalizeSelectAst(table.query), ctx).trim().replace(/;$/, "");
|
|
1404
|
+
const columns = table.columnAliases?.length ? ` (${table.columnAliases.map((c) => this.quoteIdentifier(c)).join(", ")})` : "";
|
|
1405
|
+
return `(${subquery}) AS ${this.quoteIdentifier(table.alias)}${columns}`;
|
|
1406
|
+
}
|
|
1214
1407
|
compileTableSource(table) {
|
|
1408
|
+
if (table.type === "FunctionTable") {
|
|
1409
|
+
return this.compileFunctionTable(table);
|
|
1410
|
+
}
|
|
1411
|
+
if (table.type === "DerivedTable") {
|
|
1412
|
+
return this.compileDerivedTable(table);
|
|
1413
|
+
}
|
|
1215
1414
|
const base = this.compileTableName(table);
|
|
1216
1415
|
return table.alias ? `${base} AS ${this.quoteIdentifier(table.alias)}` : base;
|
|
1217
1416
|
}
|
|
@@ -1308,6 +1507,14 @@ var PostgresFunctionStrategy = class extends StandardFunctionStrategy {
|
|
|
1308
1507
|
const partClean = String(partArg.value).replace(/['"]/g, "").toLowerCase();
|
|
1309
1508
|
return `DATE_TRUNC('${partClean}', ${date})`;
|
|
1310
1509
|
});
|
|
1510
|
+
this.add("GROUP_CONCAT", (ctx) => {
|
|
1511
|
+
const arg = ctx.compiledArgs[0];
|
|
1512
|
+
const orderClause = this.buildOrderByExpression(ctx);
|
|
1513
|
+
const orderSegment = orderClause ? ` ${orderClause}` : "";
|
|
1514
|
+
const separatorOperand = this.getGroupConcatSeparatorOperand(ctx);
|
|
1515
|
+
const separator = ctx.compileOperand(separatorOperand);
|
|
1516
|
+
return `STRING_AGG(${arg}, ${separator}${orderSegment})`;
|
|
1517
|
+
});
|
|
1311
1518
|
}
|
|
1312
1519
|
};
|
|
1313
1520
|
|
|
@@ -1552,6 +1759,12 @@ var SqliteFunctionStrategy = class extends StandardFunctionStrategy {
|
|
|
1552
1759
|
}
|
|
1553
1760
|
return `date(${date}, 'start of ${partClean}')`;
|
|
1554
1761
|
});
|
|
1762
|
+
this.add("GROUP_CONCAT", (ctx) => {
|
|
1763
|
+
const arg = ctx.compiledArgs[0];
|
|
1764
|
+
const separatorOperand = this.getGroupConcatSeparatorOperand(ctx);
|
|
1765
|
+
const separator = ctx.compileOperand(separatorOperand);
|
|
1766
|
+
return `GROUP_CONCAT(${arg}, ${separator})`;
|
|
1767
|
+
});
|
|
1555
1768
|
}
|
|
1556
1769
|
};
|
|
1557
1770
|
|
|
@@ -1586,6 +1799,12 @@ var SqliteDialect = class extends SqlDialectBase {
|
|
|
1586
1799
|
const columns = this.formatReturningColumns(returning);
|
|
1587
1800
|
return ` RETURNING ${columns}`;
|
|
1588
1801
|
}
|
|
1802
|
+
formatReturningColumns(returning) {
|
|
1803
|
+
return returning.map((column) => {
|
|
1804
|
+
const alias = column.alias ? ` AS ${this.quoteIdentifier(column.alias)}` : "";
|
|
1805
|
+
return `${this.quoteIdentifier(column.name)}${alias}`;
|
|
1806
|
+
}).join(", ");
|
|
1807
|
+
}
|
|
1589
1808
|
supportsReturning() {
|
|
1590
1809
|
return true;
|
|
1591
1810
|
}
|
|
@@ -1668,6 +1887,14 @@ var MssqlFunctionStrategy = class extends StandardFunctionStrategy {
|
|
|
1668
1887
|
const partClean = String(partArg.value).replace(/['"]/g, "").toLowerCase();
|
|
1669
1888
|
return `DATETRUNC(${partClean}, ${date})`;
|
|
1670
1889
|
});
|
|
1890
|
+
this.add("GROUP_CONCAT", (ctx) => {
|
|
1891
|
+
const arg = ctx.compiledArgs[0];
|
|
1892
|
+
const separatorOperand = this.getGroupConcatSeparatorOperand(ctx);
|
|
1893
|
+
const separator = ctx.compileOperand(separatorOperand);
|
|
1894
|
+
const orderClause = this.buildOrderByExpression(ctx);
|
|
1895
|
+
const withinGroup = orderClause ? ` WITHIN GROUP (${orderClause})` : "";
|
|
1896
|
+
return `STRING_AGG(${arg}, ${separator})${withinGroup}`;
|
|
1897
|
+
});
|
|
1671
1898
|
}
|
|
1672
1899
|
};
|
|
1673
1900
|
|
|
@@ -1744,6 +1971,9 @@ var SqlServerDialect = class extends Dialect {
|
|
|
1744
1971
|
return `UPDATE ${table} SET ${assignments}${whereClause};`;
|
|
1745
1972
|
}
|
|
1746
1973
|
compileDeleteAst(ast, ctx) {
|
|
1974
|
+
if (ast.from.type !== "Table") {
|
|
1975
|
+
throw new Error("DELETE only supports base tables in the MSSQL dialect.");
|
|
1976
|
+
}
|
|
1747
1977
|
const table = this.quoteIdentifier(ast.from.name);
|
|
1748
1978
|
const whereClause = this.compileWhere(ast.where, ctx);
|
|
1749
1979
|
return `DELETE FROM ${table}${whereClause};`;
|
|
@@ -1767,9 +1997,9 @@ var SqlServerDialect = class extends Dialect {
|
|
|
1767
1997
|
return expr;
|
|
1768
1998
|
}).join(", ");
|
|
1769
1999
|
const distinct = ast.distinct ? "DISTINCT " : "";
|
|
1770
|
-
const from =
|
|
2000
|
+
const from = this.compileTableSource(ast.from, ctx);
|
|
1771
2001
|
const joins = ast.joins.map((j) => {
|
|
1772
|
-
const table = this.
|
|
2002
|
+
const table = this.compileTableSource(j.table, ctx);
|
|
1773
2003
|
const cond = this.compileExpression(j.condition, ctx);
|
|
1774
2004
|
return `${j.kind} JOIN ${table} ON ${cond}`;
|
|
1775
2005
|
}).join(" ");
|
|
@@ -1799,6 +2029,21 @@ var SqlServerDialect = class extends Dialect {
|
|
|
1799
2029
|
}
|
|
1800
2030
|
return pagination;
|
|
1801
2031
|
}
|
|
2032
|
+
compileTableSource(table, ctx) {
|
|
2033
|
+
if (table.type === "FunctionTable") {
|
|
2034
|
+
return FunctionTableFormatter.format(table, ctx, this);
|
|
2035
|
+
}
|
|
2036
|
+
if (table.type === "DerivedTable") {
|
|
2037
|
+
return this.compileDerivedTable(table, ctx);
|
|
2038
|
+
}
|
|
2039
|
+
const base = table.schema ? `${this.quoteIdentifier(table.schema)}.${this.quoteIdentifier(table.name)}` : this.quoteIdentifier(table.name);
|
|
2040
|
+
return table.alias ? `${base} AS ${this.quoteIdentifier(table.alias)}` : base;
|
|
2041
|
+
}
|
|
2042
|
+
compileDerivedTable(table, ctx) {
|
|
2043
|
+
const sub = this.compileSelectAst(this.normalizeSelectAst(table.query), ctx).trim().replace(/;$/, "");
|
|
2044
|
+
const cols = table.columnAliases?.length ? ` (${table.columnAliases.map((c) => this.quoteIdentifier(c)).join(", ")})` : "";
|
|
2045
|
+
return `(${sub}) AS ${this.quoteIdentifier(table.alias)}${cols}`;
|
|
2046
|
+
}
|
|
1802
2047
|
compileCtes(ast, ctx) {
|
|
1803
2048
|
if (!ast.ctes || ast.ctes.length === 0) return "";
|
|
1804
2049
|
const defs = ast.ctes.map((cte) => {
|
|
@@ -1927,6 +2172,17 @@ var SelectQueryState = class _SelectQueryState {
|
|
|
1927
2172
|
joins: [...this.ast.joins ?? [], join]
|
|
1928
2173
|
});
|
|
1929
2174
|
}
|
|
2175
|
+
/**
|
|
2176
|
+
* Replaces the FROM clause.
|
|
2177
|
+
* @param from - Table source for the FROM clause
|
|
2178
|
+
* @returns New SelectQueryState with updated FROM
|
|
2179
|
+
*/
|
|
2180
|
+
withFrom(from) {
|
|
2181
|
+
return this.clone({
|
|
2182
|
+
...this.ast,
|
|
2183
|
+
from
|
|
2184
|
+
});
|
|
2185
|
+
}
|
|
1930
2186
|
/**
|
|
1931
2187
|
* Adds a WHERE clause to the query
|
|
1932
2188
|
* @param predicate - WHERE predicate expression
|
|
@@ -2037,62 +2293,6 @@ var createJoinNode = (kind, tableName, condition, relationName) => ({
|
|
|
2037
2293
|
meta: relationName ? { relationName } : void 0
|
|
2038
2294
|
});
|
|
2039
2295
|
|
|
2040
|
-
// src/core/sql/sql.ts
|
|
2041
|
-
var SQL_OPERATORS = {
|
|
2042
|
-
/** Equality operator */
|
|
2043
|
-
EQUALS: "=",
|
|
2044
|
-
/** Not equals operator */
|
|
2045
|
-
NOT_EQUALS: "!=",
|
|
2046
|
-
/** Greater than operator */
|
|
2047
|
-
GREATER_THAN: ">",
|
|
2048
|
-
/** Greater than or equal operator */
|
|
2049
|
-
GREATER_OR_EQUAL: ">=",
|
|
2050
|
-
/** Less than operator */
|
|
2051
|
-
LESS_THAN: "<",
|
|
2052
|
-
/** Less than or equal operator */
|
|
2053
|
-
LESS_OR_EQUAL: "<=",
|
|
2054
|
-
/** LIKE pattern matching operator */
|
|
2055
|
-
LIKE: "LIKE",
|
|
2056
|
-
/** NOT LIKE pattern matching operator */
|
|
2057
|
-
NOT_LIKE: "NOT LIKE",
|
|
2058
|
-
/** IN membership operator */
|
|
2059
|
-
IN: "IN",
|
|
2060
|
-
/** NOT IN membership operator */
|
|
2061
|
-
NOT_IN: "NOT IN",
|
|
2062
|
-
/** BETWEEN range operator */
|
|
2063
|
-
BETWEEN: "BETWEEN",
|
|
2064
|
-
/** NOT BETWEEN range operator */
|
|
2065
|
-
NOT_BETWEEN: "NOT BETWEEN",
|
|
2066
|
-
/** IS NULL null check operator */
|
|
2067
|
-
IS_NULL: "IS NULL",
|
|
2068
|
-
/** IS NOT NULL null check operator */
|
|
2069
|
-
IS_NOT_NULL: "IS NOT NULL",
|
|
2070
|
-
/** Logical AND operator */
|
|
2071
|
-
AND: "AND",
|
|
2072
|
-
/** Logical OR operator */
|
|
2073
|
-
OR: "OR",
|
|
2074
|
-
/** EXISTS operator */
|
|
2075
|
-
EXISTS: "EXISTS",
|
|
2076
|
-
/** NOT EXISTS operator */
|
|
2077
|
-
NOT_EXISTS: "NOT EXISTS"
|
|
2078
|
-
};
|
|
2079
|
-
var JOIN_KINDS = {
|
|
2080
|
-
/** INNER JOIN type */
|
|
2081
|
-
INNER: "INNER",
|
|
2082
|
-
/** LEFT JOIN type */
|
|
2083
|
-
LEFT: "LEFT",
|
|
2084
|
-
/** RIGHT JOIN type */
|
|
2085
|
-
RIGHT: "RIGHT",
|
|
2086
|
-
/** CROSS JOIN type */
|
|
2087
|
-
CROSS: "CROSS"
|
|
2088
|
-
};
|
|
2089
|
-
var ORDER_DIRECTIONS = {
|
|
2090
|
-
/** Ascending order */
|
|
2091
|
-
ASC: "ASC",
|
|
2092
|
-
/** Descending order */
|
|
2093
|
-
DESC: "DESC"
|
|
2094
|
-
};
|
|
2095
|
-
|
|
2096
2296
|
// src/query-builder/hydration-manager.ts
|
|
2097
2297
|
var HydrationManager = class _HydrationManager {
|
|
2098
2298
|
/**
|
|
@@ -2475,38 +2675,6 @@ var buildDefaultHydrationPlan = (table) => ({
|
|
|
2475
2675
|
relations: []
|
|
2476
2676
|
});
|
|
2477
2677
|
|
|
2478
|
-
// src/core/ast/builders.ts
|
|
2479
|
-
var buildColumnNode = (table, column) => {
|
|
2480
|
-
if (column.type === "Column") {
|
|
2481
|
-
return column;
|
|
2482
|
-
}
|
|
2483
|
-
const def = column;
|
|
2484
|
-
return {
|
|
2485
|
-
type: "Column",
|
|
2486
|
-
table: def.table || table.name,
|
|
2487
|
-
name: def.name
|
|
2488
|
-
};
|
|
2489
|
-
};
|
|
2490
|
-
var buildColumnNodes = (table, names) => names.map((name) => ({
|
|
2491
|
-
type: "Column",
|
|
2492
|
-
table: table.name,
|
|
2493
|
-
name
|
|
2494
|
-
}));
|
|
2495
|
-
var createTableNode = (table) => ({
|
|
2496
|
-
type: "Table",
|
|
2497
|
-
name: table.name
|
|
2498
|
-
});
|
|
2499
|
-
var fnTable = (name, args = [], alias, opts) => ({
|
|
2500
|
-
type: "FunctionTable",
|
|
2501
|
-
name,
|
|
2502
|
-
args,
|
|
2503
|
-
alias,
|
|
2504
|
-
lateral: opts?.lateral,
|
|
2505
|
-
withOrdinality: opts?.withOrdinality,
|
|
2506
|
-
columnAliases: opts?.columnAliases,
|
|
2507
|
-
schema: opts?.schema
|
|
2508
|
-
});
|
|
2509
|
-
|
|
2510
2678
|
// src/query-builder/raw-column-parser.ts
|
|
2511
2679
|
var parseRawColumn = (col2, tableName, ctes) => {
|
|
2512
2680
|
if (col2.includes("(")) {
|
|
@@ -2546,6 +2714,8 @@ var QueryAstService = class {
|
|
|
2546
2714
|
const existingAliases = new Set(
|
|
2547
2715
|
this.state.ast.columns.map((c) => c.alias || c.name)
|
|
2548
2716
|
);
|
|
2717
|
+
const from = this.state.ast.from;
|
|
2718
|
+
const rootTableName = from.type === "Table" && from.alias ? from.alias : this.table.name;
|
|
2549
2719
|
const newCols = Object.entries(columns).reduce((acc, [alias, val]) => {
|
|
2550
2720
|
if (existingAliases.has(alias)) return acc;
|
|
2551
2721
|
if (isExpressionSelectionNode(val)) {
|
|
@@ -2553,9 +2723,10 @@ var QueryAstService = class {
|
|
|
2553
2723
|
return acc;
|
|
2554
2724
|
}
|
|
2555
2725
|
const colDef = val;
|
|
2726
|
+
const resolvedTable = colDef.table && colDef.table === this.table.name && from.type === "Table" && from.alias ? from.alias : colDef.table || rootTableName;
|
|
2556
2727
|
acc.push({
|
|
2557
2728
|
type: "Column",
|
|
2558
|
-
table:
|
|
2729
|
+
table: resolvedTable,
|
|
2559
2730
|
name: colDef.name,
|
|
2560
2731
|
alias
|
|
2561
2732
|
});
|
|
@@ -2570,7 +2741,9 @@ var QueryAstService = class {
|
|
|
2570
2741
|
* @returns Column selection result with updated state and added columns
|
|
2571
2742
|
*/
|
|
2572
2743
|
selectRaw(cols) {
|
|
2573
|
-
const
|
|
2744
|
+
const from = this.state.ast.from;
|
|
2745
|
+
const defaultTable = from.type === "Table" && from.alias ? from.alias : this.table.name;
|
|
2746
|
+
const newCols = cols.map((col2) => parseRawColumn(col2, defaultTable, this.state.ast.ctes));
|
|
2574
2747
|
const nextState = this.state.withColumns(newCols);
|
|
2575
2748
|
return { state: nextState, addedColumns: newCols };
|
|
2576
2749
|
}
|
|
@@ -2606,6 +2779,14 @@ var QueryAstService = class {
|
|
|
2606
2779
|
};
|
|
2607
2780
|
return this.state.withSetOperation(op);
|
|
2608
2781
|
}
|
|
2782
|
+
/**
|
|
2783
|
+
* Replaces the FROM clause for the current query.
|
|
2784
|
+
* @param from - Table source to use in the FROM clause
|
|
2785
|
+
* @returns Updated query state with new FROM
|
|
2786
|
+
*/
|
|
2787
|
+
withFrom(from) {
|
|
2788
|
+
return this.state.withFrom(from);
|
|
2789
|
+
}
|
|
2609
2790
|
/**
|
|
2610
2791
|
* Selects a subquery as a column
|
|
2611
2792
|
* @param alias - Alias for the subquery
|
|
@@ -2639,7 +2820,9 @@ var QueryAstService = class {
|
|
|
2639
2820
|
* @returns Updated query state with GROUP BY clause
|
|
2640
2821
|
*/
|
|
2641
2822
|
withGroupBy(col2) {
|
|
2642
|
-
const
|
|
2823
|
+
const from = this.state.ast.from;
|
|
2824
|
+
const tableRef = from.type === "Table" && from.alias ? { ...this.table, alias: from.alias } : this.table;
|
|
2825
|
+
const node = buildColumnNode(tableRef, col2);
|
|
2643
2826
|
return this.state.withGroupBy([node]);
|
|
2644
2827
|
}
|
|
2645
2828
|
/**
|
|
@@ -2658,7 +2841,9 @@ var QueryAstService = class {
|
|
|
2658
2841
|
* @returns Updated query state with ORDER BY clause
|
|
2659
2842
|
*/
|
|
2660
2843
|
withOrderBy(col2, direction) {
|
|
2661
|
-
const
|
|
2844
|
+
const from = this.state.ast.from;
|
|
2845
|
+
const tableRef = from.type === "Table" && from.alias ? { ...this.table, alias: from.alias } : this.table;
|
|
2846
|
+
const node = buildColumnNode(tableRef, col2);
|
|
2662
2847
|
return this.state.withOrderBy([{ type: "OrderBy", column: node, direction }]);
|
|
2663
2848
|
}
|
|
2664
2849
|
/**
|
|
@@ -2762,7 +2947,8 @@ var RelationProjectionHelper = class {
|
|
|
2762
2947
|
var assertNever = (value) => {
|
|
2763
2948
|
throw new Error(`Unhandled relation type: ${JSON.stringify(value)}`);
|
|
2764
2949
|
};
|
|
2765
|
-
var baseRelationCondition = (root, relation) => {
|
|
2950
|
+
var baseRelationCondition = (root, relation, rootAlias) => {
|
|
2951
|
+
const rootTable = rootAlias || root.name;
|
|
2766
2952
|
const defaultLocalKey = relation.type === RelationKinds.HasMany || relation.type === RelationKinds.HasOne ? findPrimaryKey(root) : findPrimaryKey(relation.target);
|
|
2767
2953
|
const localKey = relation.localKey || defaultLocalKey;
|
|
2768
2954
|
switch (relation.type) {
|
|
@@ -2770,12 +2956,12 @@ var baseRelationCondition = (root, relation) => {
|
|
|
2770
2956
|
case RelationKinds.HasOne:
|
|
2771
2957
|
return eq(
|
|
2772
2958
|
{ type: "Column", table: relation.target.name, name: relation.foreignKey },
|
|
2773
|
-
{ type: "Column", table:
|
|
2959
|
+
{ type: "Column", table: rootTable, name: localKey }
|
|
2774
2960
|
);
|
|
2775
2961
|
case RelationKinds.BelongsTo:
|
|
2776
2962
|
return eq(
|
|
2777
2963
|
{ type: "Column", table: relation.target.name, name: localKey },
|
|
2778
|
-
{ type: "Column", table:
|
|
2964
|
+
{ type: "Column", table: rootTable, name: relation.foreignKey }
|
|
2779
2965
|
);
|
|
2780
2966
|
case RelationKinds.BelongsToMany:
|
|
2781
2967
|
throw new Error("BelongsToMany relations do not support the standard join condition builder");
|
|
@@ -2783,12 +2969,13 @@ var baseRelationCondition = (root, relation) => {
|
|
|
2783
2969
|
return assertNever(relation);
|
|
2784
2970
|
}
|
|
2785
2971
|
};
|
|
2786
|
-
var buildBelongsToManyJoins = (root, relationName, relation, joinKind, extra) => {
|
|
2972
|
+
var buildBelongsToManyJoins = (root, relationName, relation, joinKind, extra, rootAlias) => {
|
|
2787
2973
|
const rootKey = relation.localKey || findPrimaryKey(root);
|
|
2788
2974
|
const targetKey = relation.targetKey || findPrimaryKey(relation.target);
|
|
2975
|
+
const rootTable = rootAlias || root.name;
|
|
2789
2976
|
const pivotCondition = eq(
|
|
2790
2977
|
{ type: "Column", table: relation.pivotTable.name, name: relation.pivotForeignKeyToRoot },
|
|
2791
|
-
{ type: "Column", table:
|
|
2978
|
+
{ type: "Column", table: rootTable, name: rootKey }
|
|
2792
2979
|
);
|
|
2793
2980
|
const pivotJoin = createJoinNode(joinKind, relation.pivotTable.name, pivotCondition);
|
|
2794
2981
|
let targetCondition = eq(
|
|
@@ -2806,12 +2993,12 @@ var buildBelongsToManyJoins = (root, relationName, relation, joinKind, extra) =>
|
|
|
2806
2993
|
);
|
|
2807
2994
|
return [pivotJoin, targetJoin];
|
|
2808
2995
|
};
|
|
2809
|
-
var buildRelationJoinCondition = (root, relation, extra) => {
|
|
2810
|
-
const base = baseRelationCondition(root, relation);
|
|
2996
|
+
var buildRelationJoinCondition = (root, relation, extra, rootAlias) => {
|
|
2997
|
+
const base = baseRelationCondition(root, relation, rootAlias);
|
|
2811
2998
|
return extra ? and(base, extra) : base;
|
|
2812
2999
|
};
|
|
2813
|
-
var buildRelationCorrelation = (root, relation) => {
|
|
2814
|
-
return baseRelationCondition(root, relation);
|
|
3000
|
+
var buildRelationCorrelation = (root, relation, rootAlias) => {
|
|
3001
|
+
return baseRelationCondition(root, relation, rootAlias);
|
|
2815
3002
|
};
|
|
2816
3003
|
|
|
2817
3004
|
// src/core/ast/join-metadata.ts
|
|
@@ -2855,7 +3042,7 @@ var RelationService = class {
|
|
|
2855
3042
|
match(relationName, predicate) {
|
|
2856
3043
|
const joined = this.joinRelation(relationName, JOIN_KINDS.INNER, predicate);
|
|
2857
3044
|
const pk = findPrimaryKey(this.table);
|
|
2858
|
-
const distinctCols = [{ type: "Column", table: this.
|
|
3045
|
+
const distinctCols = [{ type: "Column", table: this.rootTableName(), name: pk }];
|
|
2859
3046
|
const existingDistinct = joined.state.ast.distinct ? joined.state.ast.distinct : [];
|
|
2860
3047
|
const nextState = this.astService(joined.state).withDistinct([...existingDistinct, ...distinctCols]);
|
|
2861
3048
|
return { state: nextState, hydration: joined.hydration };
|
|
@@ -2942,9 +3129,13 @@ var RelationService = class {
|
|
|
2942
3129
|
* @param ast - Query AST to modify
|
|
2943
3130
|
* @returns Modified query AST with relation correlation
|
|
2944
3131
|
*/
|
|
2945
|
-
applyRelationCorrelation(relationName, ast) {
|
|
3132
|
+
applyRelationCorrelation(relationName, ast, additionalCorrelation) {
|
|
2946
3133
|
const relation = this.getRelation(relationName);
|
|
2947
|
-
const
|
|
3134
|
+
const rootAlias = this.state.ast.from.type === "Table" ? this.state.ast.from.alias : void 0;
|
|
3135
|
+
let correlation = buildRelationCorrelation(this.table, relation, rootAlias);
|
|
3136
|
+
if (additionalCorrelation) {
|
|
3137
|
+
correlation = and(correlation, additionalCorrelation);
|
|
3138
|
+
}
|
|
2948
3139
|
const whereInSubquery = ast.where ? and(correlation, ast.where) : correlation;
|
|
2949
3140
|
return {
|
|
2950
3141
|
...ast,
|
|
@@ -2961,17 +3152,19 @@ var RelationService = class {
|
|
|
2961
3152
|
*/
|
|
2962
3153
|
withJoin(state, relationName, joinKind, extraCondition) {
|
|
2963
3154
|
const relation = this.getRelation(relationName);
|
|
3155
|
+
const rootAlias = state.ast.from.type === "Table" ? state.ast.from.alias : void 0;
|
|
2964
3156
|
if (relation.type === RelationKinds.BelongsToMany) {
|
|
2965
3157
|
const joins = buildBelongsToManyJoins(
|
|
2966
3158
|
this.table,
|
|
2967
3159
|
relationName,
|
|
2968
3160
|
relation,
|
|
2969
3161
|
joinKind,
|
|
2970
|
-
extraCondition
|
|
3162
|
+
extraCondition,
|
|
3163
|
+
rootAlias
|
|
2971
3164
|
);
|
|
2972
3165
|
return joins.reduce((current, join) => this.astService(current).withJoin(join), state);
|
|
2973
3166
|
}
|
|
2974
|
-
const condition = buildRelationJoinCondition(this.table, relation, extraCondition);
|
|
3167
|
+
const condition = buildRelationJoinCondition(this.table, relation, extraCondition, rootAlias);
|
|
2975
3168
|
const joinNode = createJoinNode(joinKind, relation.target.name, condition, relationName);
|
|
2976
3169
|
return this.astService(state).withJoin(joinNode);
|
|
2977
3170
|
}
|
|
@@ -3010,6 +3203,11 @@ var RelationService = class {
|
|
|
3010
3203
|
astService(state = this.state) {
|
|
3011
3204
|
return this.createQueryAstService(this.table, state);
|
|
3012
3205
|
}
|
|
3206
|
+
rootTableName() {
|
|
3207
|
+
const from = this.state.ast.from;
|
|
3208
|
+
if (from.type === "Table" && from.alias) return from.alias;
|
|
3209
|
+
return this.table.name;
|
|
3210
|
+
}
|
|
3013
3211
|
};
|
|
3014
3212
|
|
|
3015
3213
|
// src/query-builder/select-query-builder-deps.ts
|
|
@@ -3084,7 +3282,9 @@ var ColumnSelector = class {
|
|
|
3084
3282
|
* @returns Updated query context with DISTINCT clause
|
|
3085
3283
|
*/
|
|
3086
3284
|
distinct(context, columns) {
|
|
3087
|
-
const
|
|
3285
|
+
const from = context.state.ast.from;
|
|
3286
|
+
const tableRef = from.type === "Table" && from.alias ? { ...this.env.table, alias: from.alias } : this.env.table;
|
|
3287
|
+
const nodes = columns.map((col2) => buildColumnNode(tableRef, col2));
|
|
3088
3288
|
const astService = this.env.deps.createQueryAstService(this.env.table, context.state);
|
|
3089
3289
|
const nextState = astService.withDistinct(nodes);
|
|
3090
3290
|
return { state: nextState, hydration: context.hydration };
|
|
@@ -3141,8 +3341,8 @@ var RelationManager = class {
|
|
|
3141
3341
|
* @param ast - Query AST to modify
|
|
3142
3342
|
* @returns Modified query AST with relation correlation
|
|
3143
3343
|
*/
|
|
3144
|
-
applyRelationCorrelation(context, relationName, ast) {
|
|
3145
|
-
return this.createService(context).applyRelationCorrelation(relationName, ast);
|
|
3344
|
+
applyRelationCorrelation(context, relationName, ast, additionalCorrelation) {
|
|
3345
|
+
return this.createService(context).applyRelationCorrelation(relationName, ast, additionalCorrelation);
|
|
3146
3346
|
}
|
|
3147
3347
|
/**
|
|
3148
3348
|
* Creates a relation service instance
|
|
@@ -4189,9 +4389,30 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
4189
4389
|
clone(context = this.context, lazyRelations = new Set(this.lazyRelations)) {
|
|
4190
4390
|
return new _SelectQueryBuilder(this.env.table, context.state, context.hydration, this.env.deps, lazyRelations);
|
|
4191
4391
|
}
|
|
4392
|
+
/**
|
|
4393
|
+
* Applies an alias to the root FROM table.
|
|
4394
|
+
* @param alias - Alias to apply
|
|
4395
|
+
*/
|
|
4396
|
+
as(alias) {
|
|
4397
|
+
const from = this.context.state.ast.from;
|
|
4398
|
+
if (from.type !== "Table") {
|
|
4399
|
+
throw new Error("Cannot alias non-table FROM sources");
|
|
4400
|
+
}
|
|
4401
|
+
const nextFrom = { ...from, alias };
|
|
4402
|
+
const nextContext = this.applyAst(this.context, (service) => service.withFrom(nextFrom));
|
|
4403
|
+
return this.clone(nextContext);
|
|
4404
|
+
}
|
|
4192
4405
|
resolveQueryNode(query) {
|
|
4193
4406
|
return typeof query.getAST === "function" ? query.getAST() : query;
|
|
4194
4407
|
}
|
|
4408
|
+
applyCorrelation(ast, correlation) {
|
|
4409
|
+
if (!correlation) return ast;
|
|
4410
|
+
const combinedWhere = ast.where ? and(correlation, ast.where) : correlation;
|
|
4411
|
+
return {
|
|
4412
|
+
...ast,
|
|
4413
|
+
where: combinedWhere
|
|
4414
|
+
};
|
|
4415
|
+
}
|
|
4195
4416
|
createChildBuilder(table) {
|
|
4196
4417
|
return new _SelectQueryBuilder(table, void 0, void 0, this.env.deps);
|
|
4197
4418
|
}
|
|
@@ -4220,6 +4441,21 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
4220
4441
|
select(columns) {
|
|
4221
4442
|
return this.clone(this.columnSelector.select(this.context, columns));
|
|
4222
4443
|
}
|
|
4444
|
+
/**
|
|
4445
|
+
* Selects columns from the root table by name (typed).
|
|
4446
|
+
* @param cols - Column names on the root table
|
|
4447
|
+
*/
|
|
4448
|
+
selectColumns(...cols) {
|
|
4449
|
+
const selection = {};
|
|
4450
|
+
for (const key of cols) {
|
|
4451
|
+
const col2 = this.env.table.columns[key];
|
|
4452
|
+
if (!col2) {
|
|
4453
|
+
throw new Error(`Column '${key}' not found on table '${this.env.table.name}'`);
|
|
4454
|
+
}
|
|
4455
|
+
selection[key] = col2;
|
|
4456
|
+
}
|
|
4457
|
+
return this.select(selection);
|
|
4458
|
+
}
|
|
4223
4459
|
/**
|
|
4224
4460
|
|
|
4225
4461
|
* Selects raw column expressions
|
|
@@ -4268,6 +4504,19 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
4268
4504
|
const nextContext = this.applyAst(this.context, (service) => service.withCte(name, subAst, columns, true));
|
|
4269
4505
|
return this.clone(nextContext);
|
|
4270
4506
|
}
|
|
4507
|
+
/**
|
|
4508
|
+
* Replaces the FROM clause with a derived table (subquery with alias)
|
|
4509
|
+
* @param subquery - Subquery to use as the FROM source
|
|
4510
|
+
* @param alias - Alias for the derived table
|
|
4511
|
+
* @param columnAliases - Optional column alias list
|
|
4512
|
+
* @returns New query builder instance with updated FROM
|
|
4513
|
+
*/
|
|
4514
|
+
fromSubquery(subquery, alias, columnAliases) {
|
|
4515
|
+
const subAst = this.resolveQueryNode(subquery);
|
|
4516
|
+
const fromNode = derivedTable(subAst, alias, columnAliases);
|
|
4517
|
+
const nextContext = this.applyAst(this.context, (service) => service.withFrom(fromNode));
|
|
4518
|
+
return this.clone(nextContext);
|
|
4519
|
+
}
|
|
4271
4520
|
/**
|
|
4272
4521
|
|
|
4273
4522
|
* Selects a subquery as a column
|
|
@@ -4283,6 +4532,21 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
4283
4532
|
const query = this.resolveQueryNode(sub);
|
|
4284
4533
|
return this.clone(this.columnSelector.selectSubquery(this.context, alias, query));
|
|
4285
4534
|
}
|
|
4535
|
+
/**
|
|
4536
|
+
* Adds a JOIN against a derived table (subquery with alias)
|
|
4537
|
+
* @param subquery - Subquery to join
|
|
4538
|
+
* @param alias - Alias for the derived table
|
|
4539
|
+
* @param condition - Join condition expression
|
|
4540
|
+
* @param joinKind - Join kind (defaults to INNER)
|
|
4541
|
+
* @param columnAliases - Optional column alias list for the derived table
|
|
4542
|
+
* @returns New query builder instance with the derived-table join
|
|
4543
|
+
*/
|
|
4544
|
+
joinSubquery(subquery, alias, condition, joinKind = JOIN_KINDS.INNER, columnAliases) {
|
|
4545
|
+
const subAst = this.resolveQueryNode(subquery);
|
|
4546
|
+
const joinNode = createJoinNode(joinKind, derivedTable(subAst, alias, columnAliases), condition);
|
|
4547
|
+
const nextContext = this.applyAst(this.context, (service) => service.withJoin(joinNode));
|
|
4548
|
+
return this.clone(nextContext);
|
|
4549
|
+
}
|
|
4286
4550
|
/**
|
|
4287
4551
|
|
|
4288
4552
|
* Adds an INNER JOIN to the query
|
|
@@ -4380,6 +4644,47 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
4380
4644
|
nextLazy.add(relationName);
|
|
4381
4645
|
return this.clone(this.context, nextLazy);
|
|
4382
4646
|
}
|
|
4647
|
+
/**
|
|
4648
|
+
* Selects columns for a related table in a single hop.
|
|
4649
|
+
*/
|
|
4650
|
+
selectRelationColumns(relationName, ...cols) {
|
|
4651
|
+
const relation = this.env.table.relations[relationName];
|
|
4652
|
+
if (!relation) {
|
|
4653
|
+
throw new Error(`Relation '${relationName}' not found on table '${this.env.table.name}'`);
|
|
4654
|
+
}
|
|
4655
|
+
const target = relation.target;
|
|
4656
|
+
for (const col2 of cols) {
|
|
4657
|
+
if (!target.columns[col2]) {
|
|
4658
|
+
throw new Error(
|
|
4659
|
+
`Column '${col2}' not found on related table '${target.name}' for relation '${relationName}'`
|
|
4660
|
+
);
|
|
4661
|
+
}
|
|
4662
|
+
}
|
|
4663
|
+
return this.include(relationName, { columns: cols });
|
|
4664
|
+
}
|
|
4665
|
+
/**
|
|
4666
|
+
* Convenience alias for selecting specific columns from a relation.
|
|
4667
|
+
*/
|
|
4668
|
+
includePick(relationName, cols) {
|
|
4669
|
+
return this.selectRelationColumns(relationName, ...cols);
|
|
4670
|
+
}
|
|
4671
|
+
/**
|
|
4672
|
+
* Selects columns for the root table and relations from a single config object.
|
|
4673
|
+
*/
|
|
4674
|
+
selectColumnsDeep(config) {
|
|
4675
|
+
let qb = this;
|
|
4676
|
+
if (config.root?.length) {
|
|
4677
|
+
qb = qb.selectColumns(...config.root);
|
|
4678
|
+
}
|
|
4679
|
+
for (const key of Object.keys(config)) {
|
|
4680
|
+
if (key === "root") continue;
|
|
4681
|
+
const relName = key;
|
|
4682
|
+
const cols = config[relName];
|
|
4683
|
+
if (!cols || !cols.length) continue;
|
|
4684
|
+
qb = qb.selectRelationColumns(relName, ...cols);
|
|
4685
|
+
}
|
|
4686
|
+
return qb;
|
|
4687
|
+
}
|
|
4383
4688
|
getLazyRelations() {
|
|
4384
4689
|
return Array.from(this.lazyRelations);
|
|
4385
4690
|
}
|
|
@@ -4541,9 +4846,10 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
4541
4846
|
* @returns New query builder instance with the WHERE EXISTS condition
|
|
4542
4847
|
|
|
4543
4848
|
*/
|
|
4544
|
-
whereExists(subquery) {
|
|
4849
|
+
whereExists(subquery, correlate) {
|
|
4545
4850
|
const subAst = this.resolveQueryNode(subquery);
|
|
4546
|
-
|
|
4851
|
+
const correlated = this.applyCorrelation(subAst, correlate);
|
|
4852
|
+
return this.where(exists(correlated));
|
|
4547
4853
|
}
|
|
4548
4854
|
/**
|
|
4549
4855
|
|
|
@@ -4554,9 +4860,10 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
4554
4860
|
* @returns New query builder instance with the WHERE NOT EXISTS condition
|
|
4555
4861
|
|
|
4556
4862
|
*/
|
|
4557
|
-
whereNotExists(subquery) {
|
|
4863
|
+
whereNotExists(subquery, correlate) {
|
|
4558
4864
|
const subAst = this.resolveQueryNode(subquery);
|
|
4559
|
-
|
|
4865
|
+
const correlated = this.applyCorrelation(subAst, correlate);
|
|
4866
|
+
return this.where(notExists(correlated));
|
|
4560
4867
|
}
|
|
4561
4868
|
/**
|
|
4562
4869
|
|
|
@@ -4569,17 +4876,19 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
4569
4876
|
* @returns New query builder instance with the relationship existence check
|
|
4570
4877
|
|
|
4571
4878
|
*/
|
|
4572
|
-
whereHas(relationName,
|
|
4879
|
+
whereHas(relationName, callbackOrOptions, maybeOptions) {
|
|
4573
4880
|
const relation = this.env.table.relations[relationName];
|
|
4574
4881
|
if (!relation) {
|
|
4575
4882
|
throw new Error(`Relation '${relationName}' not found on table '${this.env.table.name}'`);
|
|
4576
4883
|
}
|
|
4884
|
+
const callback = typeof callbackOrOptions === "function" ? callbackOrOptions : void 0;
|
|
4885
|
+
const options = typeof callbackOrOptions === "function" ? maybeOptions : callbackOrOptions;
|
|
4577
4886
|
let subQb = this.createChildBuilder(relation.target);
|
|
4578
4887
|
if (callback) {
|
|
4579
4888
|
subQb = callback(subQb);
|
|
4580
4889
|
}
|
|
4581
4890
|
const subAst = subQb.getAST();
|
|
4582
|
-
const finalSubAst = this.relationManager.applyRelationCorrelation(this.context, relationName, subAst);
|
|
4891
|
+
const finalSubAst = this.relationManager.applyRelationCorrelation(this.context, relationName, subAst, options?.correlate);
|
|
4583
4892
|
return this.where(exists(finalSubAst));
|
|
4584
4893
|
}
|
|
4585
4894
|
/**
|
|
@@ -4593,17 +4902,19 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
4593
4902
|
* @returns New query builder instance with the relationship non-existence check
|
|
4594
4903
|
|
|
4595
4904
|
*/
|
|
4596
|
-
whereHasNot(relationName,
|
|
4905
|
+
whereHasNot(relationName, callbackOrOptions, maybeOptions) {
|
|
4597
4906
|
const relation = this.env.table.relations[relationName];
|
|
4598
4907
|
if (!relation) {
|
|
4599
4908
|
throw new Error(`Relation '${relationName}' not found on table '${this.env.table.name}'`);
|
|
4600
4909
|
}
|
|
4910
|
+
const callback = typeof callbackOrOptions === "function" ? callbackOrOptions : void 0;
|
|
4911
|
+
const options = typeof callbackOrOptions === "function" ? maybeOptions : callbackOrOptions;
|
|
4601
4912
|
let subQb = this.createChildBuilder(relation.target);
|
|
4602
4913
|
if (callback) {
|
|
4603
4914
|
subQb = callback(subQb);
|
|
4604
4915
|
}
|
|
4605
4916
|
const subAst = subQb.getAST();
|
|
4606
|
-
const finalSubAst = this.relationManager.applyRelationCorrelation(this.context, relationName, subAst);
|
|
4917
|
+
const finalSubAst = this.relationManager.applyRelationCorrelation(this.context, relationName, subAst, options?.correlate);
|
|
4607
4918
|
return this.where(notExists(finalSubAst));
|
|
4608
4919
|
}
|
|
4609
4920
|
/**
|
|
@@ -4655,6 +4966,54 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
4655
4966
|
var createColumn = (table, name) => ({ type: "Column", table, name });
|
|
4656
4967
|
var createLiteral = (val) => ({ type: "Literal", value: val });
|
|
4657
4968
|
|
|
4969
|
+
// src/orm/entity-metadata.ts
|
|
4970
|
+
var metadataMap = /* @__PURE__ */ new Map();
|
|
4971
|
+
var getEntityMetadata = (target) => {
|
|
4972
|
+
return metadataMap.get(target);
|
|
4973
|
+
};
|
|
4974
|
+
|
|
4975
|
+
// src/decorators/bootstrap.ts
|
|
4976
|
+
var getTableDefFromEntity = (ctor) => {
|
|
4977
|
+
const meta = getEntityMetadata(ctor);
|
|
4978
|
+
if (!meta) return void 0;
|
|
4979
|
+
return meta.table;
|
|
4980
|
+
};
|
|
4981
|
+
var selectFromEntity = (ctor) => {
|
|
4982
|
+
const table = getTableDefFromEntity(ctor);
|
|
4983
|
+
if (!table) {
|
|
4984
|
+
throw new Error("Entity metadata has not been bootstrapped");
|
|
4985
|
+
}
|
|
4986
|
+
return new SelectQueryBuilder(table);
|
|
4987
|
+
};
|
|
4988
|
+
|
|
4989
|
+
// src/query-builder/select-helpers.ts
|
|
4990
|
+
function sel(table, ...cols) {
|
|
4991
|
+
const selection = {};
|
|
4992
|
+
for (const col2 of cols) {
|
|
4993
|
+
const def = table.columns[col2];
|
|
4994
|
+
if (!def) {
|
|
4995
|
+
throw new Error(`Column '${col2}' not found on table '${table.name}'`);
|
|
4996
|
+
}
|
|
4997
|
+
selection[col2] = def;
|
|
4998
|
+
}
|
|
4999
|
+
return selection;
|
|
5000
|
+
}
|
|
5001
|
+
function esel(entity, ...props) {
|
|
5002
|
+
const table = getTableDefFromEntity(entity);
|
|
5003
|
+
if (!table) {
|
|
5004
|
+
throw new Error(`No table definition registered for entity '${entity.name}'`);
|
|
5005
|
+
}
|
|
5006
|
+
const selection = {};
|
|
5007
|
+
for (const prop of props) {
|
|
5008
|
+
const col2 = table.columns[prop];
|
|
5009
|
+
if (!col2) {
|
|
5010
|
+
throw new Error(`No column '${prop}' found for entity '${entity.name}'`);
|
|
5011
|
+
}
|
|
5012
|
+
selection[prop] = col2;
|
|
5013
|
+
}
|
|
5014
|
+
return selection;
|
|
5015
|
+
}
|
|
5016
|
+
|
|
4658
5017
|
// src/query-builder/insert-query-state.ts
|
|
4659
5018
|
var InsertQueryState = class _InsertQueryState {
|
|
4660
5019
|
constructor(table, ast) {
|
|
@@ -4673,7 +5032,15 @@ var InsertQueryState = class _InsertQueryState {
|
|
|
4673
5032
|
if (!rows.length) return this;
|
|
4674
5033
|
const definedColumns = this.ast.columns.length ? this.ast.columns : buildColumnNodes(this.table, Object.keys(rows[0]));
|
|
4675
5034
|
const newRows = rows.map(
|
|
4676
|
-
(row) => definedColumns.map((column) =>
|
|
5035
|
+
(row, rowIndex) => definedColumns.map((column) => {
|
|
5036
|
+
const rawValue = row[column.name];
|
|
5037
|
+
if (!isValueOperandInput(rawValue)) {
|
|
5038
|
+
throw new Error(
|
|
5039
|
+
`Invalid insert value for column "${column.name}" in row ${rowIndex}: only primitives, null, or OperandNodes are allowed`
|
|
5040
|
+
);
|
|
5041
|
+
}
|
|
5042
|
+
return valueToOperand(rawValue);
|
|
5043
|
+
})
|
|
4677
5044
|
);
|
|
4678
5045
|
return this.clone({
|
|
4679
5046
|
...this.ast,
|
|
@@ -4724,6 +5091,17 @@ var InsertQueryBuilder = class _InsertQueryBuilder {
|
|
|
4724
5091
|
};
|
|
4725
5092
|
|
|
4726
5093
|
// src/query-builder/update-query-state.ts
|
|
5094
|
+
var isUpdateValue = (value) => {
|
|
5095
|
+
if (value === null) return true;
|
|
5096
|
+
switch (typeof value) {
|
|
5097
|
+
case "string":
|
|
5098
|
+
case "number":
|
|
5099
|
+
case "boolean":
|
|
5100
|
+
return true;
|
|
5101
|
+
default:
|
|
5102
|
+
return isOperandNode(value);
|
|
5103
|
+
}
|
|
5104
|
+
};
|
|
4727
5105
|
var UpdateQueryState = class _UpdateQueryState {
|
|
4728
5106
|
constructor(table, ast) {
|
|
4729
5107
|
this.table = table;
|
|
@@ -4737,14 +5115,21 @@ var UpdateQueryState = class _UpdateQueryState {
|
|
|
4737
5115
|
return new _UpdateQueryState(this.table, nextAst);
|
|
4738
5116
|
}
|
|
4739
5117
|
withSet(values) {
|
|
4740
|
-
const assignments = Object.entries(values).map(([column,
|
|
4741
|
-
|
|
4742
|
-
|
|
4743
|
-
|
|
4744
|
-
|
|
4745
|
-
}
|
|
4746
|
-
|
|
4747
|
-
|
|
5118
|
+
const assignments = Object.entries(values).map(([column, rawValue]) => {
|
|
5119
|
+
if (!isUpdateValue(rawValue)) {
|
|
5120
|
+
throw new Error(
|
|
5121
|
+
`Invalid update value for column "${column}": only primitives, null, or OperandNodes are allowed`
|
|
5122
|
+
);
|
|
5123
|
+
}
|
|
5124
|
+
return {
|
|
5125
|
+
column: {
|
|
5126
|
+
type: "Column",
|
|
5127
|
+
table: this.table.name,
|
|
5128
|
+
name: column
|
|
5129
|
+
},
|
|
5130
|
+
value: valueToOperand(rawValue)
|
|
5131
|
+
};
|
|
5132
|
+
});
|
|
4748
5133
|
return this.clone({
|
|
4749
5134
|
...this.ast,
|
|
4750
5135
|
set: assignments
|
|
@@ -5953,7 +6338,7 @@ var DefaultNamingStrategy = class {
|
|
|
5953
6338
|
* @returns Capitalized table name (handles schema-qualified names)
|
|
5954
6339
|
*/
|
|
5955
6340
|
tableToSymbol(table) {
|
|
5956
|
-
const tableName = typeof table === "string" ? table : table.name;
|
|
6341
|
+
const tableName = typeof table === "string" ? table : table.type === "DerivedTable" ? table.alias : table.name;
|
|
5957
6342
|
if (tableName.includes(".")) {
|
|
5958
6343
|
return tableName.split(".").map((part) => this.capitalize(part)).join("");
|
|
5959
6344
|
}
|
|
@@ -6012,8 +6397,8 @@ var TypeScriptGenerator = class {
|
|
|
6012
6397
|
return `${key}: ${this.printOperand(operand)}`;
|
|
6013
6398
|
});
|
|
6014
6399
|
lines.push(`db.select({`);
|
|
6015
|
-
selections.forEach((
|
|
6016
|
-
lines.push(` ${
|
|
6400
|
+
selections.forEach((sel2, index) => {
|
|
6401
|
+
lines.push(` ${sel2}${index < selections.length - 1 ? "," : ""}`);
|
|
6017
6402
|
});
|
|
6018
6403
|
lines.push(`})`);
|
|
6019
6404
|
lines.push(`.from(${this.namingStrategy.tableToSymbol(ast.from)})`);
|
|
@@ -6296,26 +6681,6 @@ var TypeScriptGenerator = class {
|
|
|
6296
6681
|
}
|
|
6297
6682
|
};
|
|
6298
6683
|
|
|
6299
|
-
// src/orm/entity-metadata.ts
|
|
6300
|
-
var metadataMap = /* @__PURE__ */ new Map();
|
|
6301
|
-
var getEntityMetadata = (target) => {
|
|
6302
|
-
return metadataMap.get(target);
|
|
6303
|
-
};
|
|
6304
|
-
|
|
6305
|
-
// src/decorators/bootstrap.ts
|
|
6306
|
-
var getTableDefFromEntity = (ctor) => {
|
|
6307
|
-
const meta = getEntityMetadata(ctor);
|
|
6308
|
-
if (!meta) return void 0;
|
|
6309
|
-
return meta.table;
|
|
6310
|
-
};
|
|
6311
|
-
var selectFromEntity = (ctor) => {
|
|
6312
|
-
const table = getTableDefFromEntity(ctor);
|
|
6313
|
-
if (!table) {
|
|
6314
|
-
throw new Error("Entity metadata has not been bootstrapped");
|
|
6315
|
-
}
|
|
6316
|
-
return new SelectQueryBuilder(table);
|
|
6317
|
-
};
|
|
6318
|
-
|
|
6319
6684
|
// src/orm/identity-map.ts
|
|
6320
6685
|
var IdentityMap = class {
|
|
6321
6686
|
constructor() {
|
|
@@ -6528,6 +6893,7 @@ var UnitOfWork = class {
|
|
|
6528
6893
|
extractColumns(table, entity) {
|
|
6529
6894
|
const payload = {};
|
|
6530
6895
|
for (const column of Object.keys(table.columns)) {
|
|
6896
|
+
if (entity[column] === void 0) continue;
|
|
6531
6897
|
payload[column] = entity[column];
|
|
6532
6898
|
}
|
|
6533
6899
|
return payload;
|
|
@@ -6582,24 +6948,30 @@ var UnitOfWork = class {
|
|
|
6582
6948
|
var DomainEventBus = class {
|
|
6583
6949
|
constructor(initialHandlers) {
|
|
6584
6950
|
this.handlers = /* @__PURE__ */ new Map();
|
|
6585
|
-
|
|
6586
|
-
|
|
6587
|
-
|
|
6588
|
-
|
|
6951
|
+
if (initialHandlers) {
|
|
6952
|
+
for (const key in initialHandlers) {
|
|
6953
|
+
const type = key;
|
|
6954
|
+
const list = initialHandlers[type] ?? [];
|
|
6955
|
+
this.handlers.set(type, [...list]);
|
|
6956
|
+
}
|
|
6957
|
+
}
|
|
6589
6958
|
}
|
|
6590
|
-
|
|
6591
|
-
const
|
|
6959
|
+
on(type, handler) {
|
|
6960
|
+
const key = type;
|
|
6961
|
+
const existing = this.handlers.get(key) ?? [];
|
|
6592
6962
|
existing.push(handler);
|
|
6593
|
-
this.handlers.set(
|
|
6963
|
+
this.handlers.set(key, existing);
|
|
6964
|
+
}
|
|
6965
|
+
register(type, handler) {
|
|
6966
|
+
this.on(type, handler);
|
|
6594
6967
|
}
|
|
6595
6968
|
async dispatch(trackedEntities, ctx) {
|
|
6596
6969
|
for (const tracked of trackedEntities) {
|
|
6597
6970
|
const entity = tracked.entity;
|
|
6598
|
-
if (!entity.domainEvents
|
|
6971
|
+
if (!entity.domainEvents?.length) continue;
|
|
6599
6972
|
for (const event of entity.domainEvents) {
|
|
6600
|
-
const
|
|
6601
|
-
|
|
6602
|
-
if (!handlers) continue;
|
|
6973
|
+
const handlers = this.handlers.get(event.type);
|
|
6974
|
+
if (!handlers?.length) continue;
|
|
6603
6975
|
for (const handler of handlers) {
|
|
6604
6976
|
await handler(event, ctx);
|
|
6605
6977
|
}
|
|
@@ -6607,11 +6979,6 @@ var DomainEventBus = class {
|
|
|
6607
6979
|
entity.domainEvents = [];
|
|
6608
6980
|
}
|
|
6609
6981
|
}
|
|
6610
|
-
getEventName(event) {
|
|
6611
|
-
if (!event) return "Unknown";
|
|
6612
|
-
if (typeof event === "string") return event;
|
|
6613
|
-
return event.constructor?.name ?? "Unknown";
|
|
6614
|
-
}
|
|
6615
6982
|
};
|
|
6616
6983
|
var addDomainEvent = (entity, event) => {
|
|
6617
6984
|
if (!entity.domainEvents) {
|
|
@@ -6853,8 +7220,8 @@ var OrmSession = class {
|
|
|
6853
7220
|
registerInterceptor(interceptor) {
|
|
6854
7221
|
this.interceptors.push(interceptor);
|
|
6855
7222
|
}
|
|
6856
|
-
registerDomainEventHandler(
|
|
6857
|
-
this.domainEvents.
|
|
7223
|
+
registerDomainEventHandler(type, handler) {
|
|
7224
|
+
this.domainEvents.on(type, handler);
|
|
6858
7225
|
}
|
|
6859
7226
|
async find(entityClass, id) {
|
|
6860
7227
|
const table = getTableDefFromEntity(entityClass);
|
|
@@ -6866,7 +7233,11 @@ var OrmSession = class {
|
|
|
6866
7233
|
if (!column) {
|
|
6867
7234
|
throw new Error("Entity table does not expose a primary key");
|
|
6868
7235
|
}
|
|
6869
|
-
const
|
|
7236
|
+
const columnSelections = Object.values(table.columns).reduce((acc, col2) => {
|
|
7237
|
+
acc[col2.name] = col2;
|
|
7238
|
+
return acc;
|
|
7239
|
+
}, {});
|
|
7240
|
+
const qb = selectFromEntity(entityClass).select(columnSelections).where(eq(column, id)).limit(1);
|
|
6870
7241
|
const rows = await executeHydrated(this, qb);
|
|
6871
7242
|
return rows[0] ?? null;
|
|
6872
7243
|
}
|
|
@@ -6978,7 +7349,6 @@ var Orm = class {
|
|
|
6978
7349
|
const executor = this.executorFactory.createExecutor(options?.tx);
|
|
6979
7350
|
return new OrmSession({ orm: this, executor });
|
|
6980
7351
|
}
|
|
6981
|
-
// Nice convenience:
|
|
6982
7352
|
async transaction(fn4) {
|
|
6983
7353
|
const executor = this.executorFactory.createTransactionalExecutor();
|
|
6984
7354
|
const session = new OrmSession({ orm: this, executor });
|
|
@@ -7141,6 +7511,7 @@ export {
|
|
|
7141
7511
|
columnOperand,
|
|
7142
7512
|
concat,
|
|
7143
7513
|
concatWs,
|
|
7514
|
+
correlateBy,
|
|
7144
7515
|
cos,
|
|
7145
7516
|
cot,
|
|
7146
7517
|
count,
|
|
@@ -7169,6 +7540,7 @@ export {
|
|
|
7169
7540
|
diffSchema,
|
|
7170
7541
|
endOfMonth,
|
|
7171
7542
|
eq,
|
|
7543
|
+
esel,
|
|
7172
7544
|
executeHydrated,
|
|
7173
7545
|
executeHydratedWithContexts,
|
|
7174
7546
|
exists,
|
|
@@ -7180,6 +7552,7 @@ export {
|
|
|
7180
7552
|
generateCreateTableSql,
|
|
7181
7553
|
generateSchemaSql,
|
|
7182
7554
|
getSchemaIntrospector,
|
|
7555
|
+
groupConcat,
|
|
7183
7556
|
gt,
|
|
7184
7557
|
gte,
|
|
7185
7558
|
hasMany,
|
|
@@ -7194,6 +7567,7 @@ export {
|
|
|
7194
7567
|
isNotNull,
|
|
7195
7568
|
isNull,
|
|
7196
7569
|
isOperandNode,
|
|
7570
|
+
isValueOperandInput,
|
|
7197
7571
|
isWindowFunctionNode,
|
|
7198
7572
|
jsonPath,
|
|
7199
7573
|
lag,
|
|
@@ -7216,6 +7590,8 @@ export {
|
|
|
7216
7590
|
lt,
|
|
7217
7591
|
lte,
|
|
7218
7592
|
ltrim,
|
|
7593
|
+
max,
|
|
7594
|
+
min,
|
|
7219
7595
|
mod,
|
|
7220
7596
|
month,
|
|
7221
7597
|
neq,
|
|
@@ -7226,6 +7602,7 @@ export {
|
|
|
7226
7602
|
now,
|
|
7227
7603
|
ntile,
|
|
7228
7604
|
or,
|
|
7605
|
+
outerRef,
|
|
7229
7606
|
pi,
|
|
7230
7607
|
position,
|
|
7231
7608
|
pow,
|
|
@@ -7246,6 +7623,7 @@ export {
|
|
|
7246
7623
|
rowsToQueryResult,
|
|
7247
7624
|
rpad,
|
|
7248
7625
|
rtrim,
|
|
7626
|
+
sel,
|
|
7249
7627
|
sign,
|
|
7250
7628
|
sin,
|
|
7251
7629
|
space,
|