metal-orm 1.1.9 → 1.1.11
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 +769 -764
- package/dist/index.cjs +2255 -284
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +559 -39
- package/dist/index.d.ts +559 -39
- package/dist/index.js +2227 -284
- package/dist/index.js.map +1 -1
- package/package.json +17 -12
- package/scripts/generate-entities/render.mjs +21 -12
- package/scripts/generate-entities/schema.mjs +87 -73
- package/scripts/generate-entities/tree-detection.mjs +67 -61
- package/src/bulk/bulk-context.ts +83 -0
- package/src/bulk/bulk-delete-executor.ts +87 -0
- package/src/bulk/bulk-executor.base.ts +73 -0
- package/src/bulk/bulk-insert-executor.ts +74 -0
- package/src/bulk/bulk-types.ts +70 -0
- package/src/bulk/bulk-update-executor.ts +192 -0
- package/src/bulk/bulk-upsert-executor.ts +93 -0
- package/src/bulk/bulk-utils.ts +91 -0
- package/src/bulk/index.ts +18 -0
- package/src/codegen/typescript.ts +30 -21
- package/src/core/ast/expression-builders.ts +107 -10
- package/src/core/ast/expression-nodes.ts +52 -22
- package/src/core/ast/expression-visitor.ts +23 -13
- package/src/core/ddl/introspect/mysql.ts +113 -36
- package/src/core/dialect/abstract.ts +30 -17
- package/src/core/dialect/mysql/index.ts +20 -5
- package/src/core/execution/db-executor.ts +96 -64
- package/src/core/execution/executors/better-sqlite3-executor.ts +94 -0
- package/src/core/execution/executors/mssql-executor.ts +66 -34
- package/src/core/execution/executors/mysql-executor.ts +98 -66
- package/src/core/execution/executors/postgres-executor.ts +33 -11
- package/src/core/execution/executors/sqlite-executor.ts +86 -30
- package/src/decorators/bootstrap.ts +482 -398
- package/src/decorators/column-decorator.ts +87 -96
- package/src/decorators/decorator-metadata.ts +100 -24
- package/src/decorators/entity.ts +27 -24
- package/src/decorators/relations.ts +231 -149
- package/src/decorators/transformers/transformer-decorators.ts +26 -29
- package/src/decorators/validators/country-validators-decorators.ts +9 -15
- package/src/dto/apply-filter.ts +568 -551
- package/src/index.ts +16 -9
- package/src/orm/entity-hydration.ts +116 -72
- package/src/orm/entity-metadata.ts +347 -301
- package/src/orm/entity-relations.ts +264 -207
- package/src/orm/entity.ts +199 -199
- package/src/orm/execute.ts +13 -13
- package/src/orm/lazy-batch/morph-many.ts +70 -0
- package/src/orm/lazy-batch/morph-one.ts +69 -0
- package/src/orm/lazy-batch/morph-to.ts +59 -0
- package/src/orm/lazy-batch.ts +4 -1
- package/src/orm/orm-session.ts +170 -104
- package/src/orm/pooled-executor-factory.ts +99 -58
- package/src/orm/query-logger.ts +49 -40
- package/src/orm/relation-change-processor.ts +198 -96
- package/src/orm/relations/belongs-to.ts +143 -143
- package/src/orm/relations/has-many.ts +204 -204
- package/src/orm/relations/has-one.ts +174 -174
- package/src/orm/relations/many-to-many.ts +288 -288
- package/src/orm/relations/morph-many.ts +156 -0
- package/src/orm/relations/morph-one.ts +151 -0
- package/src/orm/relations/morph-to.ts +162 -0
- package/src/orm/save-graph.ts +116 -1
- package/src/query-builder/expression-table-mapper.ts +5 -0
- package/src/query-builder/hydration-manager.ts +345 -345
- package/src/query-builder/hydration-planner.ts +178 -148
- package/src/query-builder/relation-conditions.ts +171 -151
- package/src/query-builder/relation-cte-builder.ts +5 -1
- package/src/query-builder/relation-filter-utils.ts +9 -6
- package/src/query-builder/relation-include-strategies.ts +44 -2
- package/src/query-builder/relation-join-strategies.ts +8 -1
- package/src/query-builder/relation-service.ts +250 -241
- package/src/query-builder/select/select-operations.ts +110 -105
- package/src/query-builder/update-include.ts +4 -0
- package/src/schema/relation.ts +296 -188
- package/src/schema/types.ts +138 -123
- package/src/tree/tree-decorator.ts +127 -137
package/dist/index.js
CHANGED
|
@@ -328,7 +328,13 @@ var RelationKinds = {
|
|
|
328
328
|
/** Many-to-one relationship */
|
|
329
329
|
BelongsTo: "BELONGS_TO",
|
|
330
330
|
/** Many-to-many relationship with pivot metadata */
|
|
331
|
-
BelongsToMany: "BELONGS_TO_MANY"
|
|
331
|
+
BelongsToMany: "BELONGS_TO_MANY",
|
|
332
|
+
/** Polymorphic inverse (child side) */
|
|
333
|
+
MorphTo: "MORPH_TO",
|
|
334
|
+
/** Polymorphic one-to-one (parent side) */
|
|
335
|
+
MorphOne: "MORPH_ONE",
|
|
336
|
+
/** Polymorphic one-to-many (parent side) */
|
|
337
|
+
MorphMany: "MORPH_MANY"
|
|
332
338
|
};
|
|
333
339
|
var hasMany = (target, foreignKey, localKey, cascade) => ({
|
|
334
340
|
type: RelationKinds.HasMany,
|
|
@@ -363,6 +369,32 @@ var belongsToMany = (target, pivotTable, options) => ({
|
|
|
363
369
|
defaultPivotColumns: options.defaultPivotColumns,
|
|
364
370
|
cascade: options.cascade
|
|
365
371
|
});
|
|
372
|
+
var isSingleTargetRelation = (rel) => rel.type !== RelationKinds.MorphTo;
|
|
373
|
+
var isMorphRelation = (rel) => rel.type === RelationKinds.MorphTo || rel.type === RelationKinds.MorphOne || rel.type === RelationKinds.MorphMany;
|
|
374
|
+
var morphTo = (opts) => ({
|
|
375
|
+
type: RelationKinds.MorphTo,
|
|
376
|
+
...opts
|
|
377
|
+
});
|
|
378
|
+
var morphOne = (target, opts) => ({
|
|
379
|
+
type: RelationKinds.MorphOne,
|
|
380
|
+
target,
|
|
381
|
+
morphName: opts.as,
|
|
382
|
+
typeField: opts.typeField ?? `${opts.as}Type`,
|
|
383
|
+
idField: opts.idField ?? `${opts.as}Id`,
|
|
384
|
+
typeValue: opts.typeValue,
|
|
385
|
+
localKey: opts.localKey,
|
|
386
|
+
cascade: opts.cascade
|
|
387
|
+
});
|
|
388
|
+
var morphMany = (target, opts) => ({
|
|
389
|
+
type: RelationKinds.MorphMany,
|
|
390
|
+
target,
|
|
391
|
+
morphName: opts.as,
|
|
392
|
+
typeField: opts.typeField ?? `${opts.as}Type`,
|
|
393
|
+
idField: opts.idField ?? `${opts.as}Id`,
|
|
394
|
+
typeValue: opts.typeValue,
|
|
395
|
+
localKey: opts.localKey,
|
|
396
|
+
cascade: opts.cascade
|
|
397
|
+
});
|
|
366
398
|
|
|
367
399
|
// src/core/ast/expression-nodes.ts
|
|
368
400
|
var operandTypes = /* @__PURE__ */ new Set([
|
|
@@ -490,6 +522,10 @@ var or = (...operands) => ({
|
|
|
490
522
|
operator: "OR",
|
|
491
523
|
operands
|
|
492
524
|
});
|
|
525
|
+
var not = (operand) => ({
|
|
526
|
+
type: "NotExpression",
|
|
527
|
+
operand
|
|
528
|
+
});
|
|
493
529
|
var isNull = (left2) => ({
|
|
494
530
|
type: "NullExpression",
|
|
495
531
|
left: toOperandNode(left2),
|
|
@@ -573,6 +609,18 @@ var collate = (expression, collation) => ({
|
|
|
573
609
|
expression: toOperand(expression),
|
|
574
610
|
collation
|
|
575
611
|
});
|
|
612
|
+
var isDistinctFrom = (left2, right2) => ({
|
|
613
|
+
type: "IsDistinctExpression",
|
|
614
|
+
left: toOperandNode(left2),
|
|
615
|
+
operator: "IS DISTINCT FROM",
|
|
616
|
+
right: toOperand(right2)
|
|
617
|
+
});
|
|
618
|
+
var isNotDistinctFrom = (left2, right2) => ({
|
|
619
|
+
type: "IsDistinctExpression",
|
|
620
|
+
left: toOperandNode(left2),
|
|
621
|
+
operator: "IS NOT DISTINCT FROM",
|
|
622
|
+
right: toOperand(right2)
|
|
623
|
+
});
|
|
576
624
|
|
|
577
625
|
// src/core/ast/window-functions.ts
|
|
578
626
|
var buildWindowFunction = (name, args = [], partitionBy, orderBy) => {
|
|
@@ -779,6 +827,9 @@ var visitExpression = (node, visitor) => {
|
|
|
779
827
|
case "LogicalExpression":
|
|
780
828
|
if (visitor.visitLogicalExpression) return visitor.visitLogicalExpression(node);
|
|
781
829
|
break;
|
|
830
|
+
case "NotExpression":
|
|
831
|
+
if (visitor.visitNotExpression) return visitor.visitNotExpression(node);
|
|
832
|
+
break;
|
|
782
833
|
case "NullExpression":
|
|
783
834
|
if (visitor.visitNullExpression) return visitor.visitNullExpression(node);
|
|
784
835
|
break;
|
|
@@ -797,6 +848,9 @@ var visitExpression = (node, visitor) => {
|
|
|
797
848
|
case "BitwiseExpression":
|
|
798
849
|
if (visitor.visitBitwiseExpression) return visitor.visitBitwiseExpression(node);
|
|
799
850
|
break;
|
|
851
|
+
case "IsDistinctExpression":
|
|
852
|
+
if (visitor.visitIsDistinctExpression) return visitor.visitIsDistinctExpression(node);
|
|
853
|
+
break;
|
|
800
854
|
default:
|
|
801
855
|
break;
|
|
802
856
|
}
|
|
@@ -1520,6 +1574,10 @@ var Dialect = class _Dialect {
|
|
|
1520
1574
|
});
|
|
1521
1575
|
return parts.join(` ${logical.operator} `);
|
|
1522
1576
|
});
|
|
1577
|
+
this.registerExpressionCompiler("NotExpression", (notExpr, ctx) => {
|
|
1578
|
+
const operand = this.compileExpression(notExpr.operand, ctx);
|
|
1579
|
+
return `NOT (${operand})`;
|
|
1580
|
+
});
|
|
1523
1581
|
this.registerExpressionCompiler("NullExpression", (nullExpr, ctx) => {
|
|
1524
1582
|
const left2 = this.compileOperand(nullExpr.left, ctx);
|
|
1525
1583
|
return `${left2} ${nullExpr.operator}`;
|
|
@@ -1553,6 +1611,11 @@ var Dialect = class _Dialect {
|
|
|
1553
1611
|
const right2 = this.compileOperand(bitwise.right, ctx);
|
|
1554
1612
|
return `${left2} ${bitwise.operator} ${right2}`;
|
|
1555
1613
|
});
|
|
1614
|
+
this.registerExpressionCompiler("IsDistinctExpression", (node, ctx) => {
|
|
1615
|
+
const left2 = this.compileOperand(node.left, ctx);
|
|
1616
|
+
const right2 = this.compileOperand(node.right, ctx);
|
|
1617
|
+
return `${left2} ${node.operator} ${right2}`;
|
|
1618
|
+
});
|
|
1556
1619
|
}
|
|
1557
1620
|
registerDefaultOperandCompilers() {
|
|
1558
1621
|
this.registerOperandCompiler("Literal", (literal, ctx) => ctx.addParameter(literal.value));
|
|
@@ -2474,6 +2537,18 @@ var MySqlDialect = class extends SqlDialectBase {
|
|
|
2474
2537
|
*/
|
|
2475
2538
|
constructor() {
|
|
2476
2539
|
super(new MysqlFunctionStrategy());
|
|
2540
|
+
this.registerExpressionCompiler(
|
|
2541
|
+
"IsDistinctExpression",
|
|
2542
|
+
(node, ctx) => {
|
|
2543
|
+
const left2 = this.compileOperand(node.left, ctx);
|
|
2544
|
+
const right2 = this.compileOperand(node.right, ctx);
|
|
2545
|
+
const spaceship = `${left2} <=> ${right2}`;
|
|
2546
|
+
if (node.operator === "IS NOT DISTINCT FROM") {
|
|
2547
|
+
return spaceship;
|
|
2548
|
+
}
|
|
2549
|
+
return `NOT (${spaceship})`;
|
|
2550
|
+
}
|
|
2551
|
+
);
|
|
2477
2552
|
}
|
|
2478
2553
|
/**
|
|
2479
2554
|
* Quotes an identifier using MySQL backtick syntax
|
|
@@ -3573,7 +3648,7 @@ var HydrationManager = class _HydrationManager {
|
|
|
3573
3648
|
*/
|
|
3574
3649
|
hasMultiplyingRelations(plan) {
|
|
3575
3650
|
return plan.relations.some(
|
|
3576
|
-
(rel) => rel.type === RelationKinds.HasMany || rel.type === RelationKinds.BelongsToMany
|
|
3651
|
+
(rel) => rel.type === RelationKinds.HasMany || rel.type === RelationKinds.BelongsToMany || rel.type === RelationKinds.MorphMany
|
|
3577
3652
|
);
|
|
3578
3653
|
}
|
|
3579
3654
|
/**
|
|
@@ -3907,6 +3982,36 @@ var HydrationPlanner = class _HydrationPlanner {
|
|
|
3907
3982
|
}
|
|
3908
3983
|
};
|
|
3909
3984
|
}
|
|
3985
|
+
case RelationKinds.MorphOne: {
|
|
3986
|
+
const morphRel = rel;
|
|
3987
|
+
const localKey = morphRel.localKey || findPrimaryKey(this.table);
|
|
3988
|
+
return {
|
|
3989
|
+
name: relationName,
|
|
3990
|
+
aliasPrefix,
|
|
3991
|
+
type: rel.type,
|
|
3992
|
+
targetTable: morphRel.target.name,
|
|
3993
|
+
targetPrimaryKey: findPrimaryKey(morphRel.target),
|
|
3994
|
+
foreignKey: morphRel.idField,
|
|
3995
|
+
localKey,
|
|
3996
|
+
columns
|
|
3997
|
+
};
|
|
3998
|
+
}
|
|
3999
|
+
case RelationKinds.MorphMany: {
|
|
4000
|
+
const morphRel = rel;
|
|
4001
|
+
const localKey = morphRel.localKey || findPrimaryKey(this.table);
|
|
4002
|
+
return {
|
|
4003
|
+
name: relationName,
|
|
4004
|
+
aliasPrefix,
|
|
4005
|
+
type: rel.type,
|
|
4006
|
+
targetTable: morphRel.target.name,
|
|
4007
|
+
targetPrimaryKey: findPrimaryKey(morphRel.target),
|
|
4008
|
+
foreignKey: morphRel.idField,
|
|
4009
|
+
localKey,
|
|
4010
|
+
columns
|
|
4011
|
+
};
|
|
4012
|
+
}
|
|
4013
|
+
case RelationKinds.MorphTo:
|
|
4014
|
+
throw new Error("MorphTo relations do not support hydration planning via JOIN.");
|
|
3910
4015
|
}
|
|
3911
4016
|
}
|
|
3912
4017
|
};
|
|
@@ -4211,23 +4316,44 @@ var assertNever = (value) => {
|
|
|
4211
4316
|
};
|
|
4212
4317
|
var baseRelationCondition = (root, relation, rootAlias, targetTableName) => {
|
|
4213
4318
|
const rootTable = rootAlias || root.name;
|
|
4319
|
+
if (relation.type === RelationKinds.MorphTo) {
|
|
4320
|
+
throw new Error("MorphTo relations do not support the standard join condition builder");
|
|
4321
|
+
}
|
|
4214
4322
|
const targetTable = targetTableName ?? relation.target.name;
|
|
4215
|
-
const defaultLocalKey = relation.type === RelationKinds.HasMany || relation.type === RelationKinds.HasOne ? findPrimaryKey(root) : findPrimaryKey(relation.target);
|
|
4216
|
-
const localKey = relation.localKey || defaultLocalKey;
|
|
4217
4323
|
switch (relation.type) {
|
|
4218
4324
|
case RelationKinds.HasMany:
|
|
4219
|
-
case RelationKinds.HasOne:
|
|
4325
|
+
case RelationKinds.HasOne: {
|
|
4326
|
+
const defaultLocalKey = findPrimaryKey(root);
|
|
4327
|
+
const localKey = relation.localKey || defaultLocalKey;
|
|
4220
4328
|
return eq(
|
|
4221
4329
|
{ type: "Column", table: targetTable, name: relation.foreignKey },
|
|
4222
4330
|
{ type: "Column", table: rootTable, name: localKey }
|
|
4223
4331
|
);
|
|
4224
|
-
|
|
4332
|
+
}
|
|
4333
|
+
case RelationKinds.BelongsTo: {
|
|
4334
|
+
const defaultLocalKey = findPrimaryKey(relation.target);
|
|
4335
|
+
const localKey = relation.localKey || defaultLocalKey;
|
|
4225
4336
|
return eq(
|
|
4226
4337
|
{ type: "Column", table: targetTable, name: localKey },
|
|
4227
4338
|
{ type: "Column", table: rootTable, name: relation.foreignKey }
|
|
4228
4339
|
);
|
|
4340
|
+
}
|
|
4229
4341
|
case RelationKinds.BelongsToMany:
|
|
4230
4342
|
throw new Error("BelongsToMany relations do not support the standard join condition builder");
|
|
4343
|
+
case RelationKinds.MorphOne:
|
|
4344
|
+
case RelationKinds.MorphMany: {
|
|
4345
|
+
const morphRel = relation;
|
|
4346
|
+
const morphLocalKey = morphRel.localKey || findPrimaryKey(root);
|
|
4347
|
+
const baseCondition = eq(
|
|
4348
|
+
{ type: "Column", table: targetTable, name: morphRel.idField },
|
|
4349
|
+
{ type: "Column", table: rootTable, name: morphLocalKey }
|
|
4350
|
+
);
|
|
4351
|
+
const discriminatorCondition = eq(
|
|
4352
|
+
{ type: "Column", table: targetTable, name: morphRel.typeField },
|
|
4353
|
+
{ type: "Literal", value: morphRel.typeValue }
|
|
4354
|
+
);
|
|
4355
|
+
return and(baseCondition, discriminatorCondition);
|
|
4356
|
+
}
|
|
4231
4357
|
default:
|
|
4232
4358
|
return assertNever(relation);
|
|
4233
4359
|
}
|
|
@@ -4323,6 +4449,9 @@ var collectFromExpression = (expr, collector) => {
|
|
|
4323
4449
|
case "LogicalExpression":
|
|
4324
4450
|
expr.operands.forEach((operand) => collectFromExpression(operand, collector));
|
|
4325
4451
|
break;
|
|
4452
|
+
case "NotExpression":
|
|
4453
|
+
collectFromExpression(expr.operand, collector);
|
|
4454
|
+
break;
|
|
4326
4455
|
case "NullExpression":
|
|
4327
4456
|
collectFromOperand(expr.left, collector);
|
|
4328
4457
|
break;
|
|
@@ -4429,6 +4558,11 @@ var mapExpression = (expr, fromTable, toTable) => {
|
|
|
4429
4558
|
if (nextOperands.every((op, i) => op === expr.operands[i])) return expr;
|
|
4430
4559
|
return { ...expr, operands: nextOperands };
|
|
4431
4560
|
}
|
|
4561
|
+
case "NotExpression": {
|
|
4562
|
+
const operand = mapExpression(expr.operand, fromTable, toTable);
|
|
4563
|
+
if (operand === expr.operand) return expr;
|
|
4564
|
+
return { ...expr, operand };
|
|
4565
|
+
}
|
|
4432
4566
|
case "NullExpression": {
|
|
4433
4567
|
const left2 = mapOperand(expr.left, fromTable, toTable);
|
|
4434
4568
|
if (left2 === expr.left) return expr;
|
|
@@ -4729,6 +4863,9 @@ var addRelationJoin = (params) => {
|
|
|
4729
4863
|
);
|
|
4730
4864
|
return joins.reduce((curr, join) => curr.withJoin(join), state);
|
|
4731
4865
|
}
|
|
4866
|
+
if (!isSingleTargetRelation(relation)) {
|
|
4867
|
+
throw new Error("Polymorphic MorphTo relations do not support join-based strategies");
|
|
4868
|
+
}
|
|
4732
4869
|
let targetSource = tableSource ?? {
|
|
4733
4870
|
type: "Table",
|
|
4734
4871
|
name: relation.target.name,
|
|
@@ -4744,6 +4881,9 @@ var addRelationJoin = (params) => {
|
|
|
4744
4881
|
var updateRelationJoin = (params) => {
|
|
4745
4882
|
const { joins, joinIndex, relation, currentTable, currentAlias, options } = params;
|
|
4746
4883
|
const join = joins[joinIndex];
|
|
4884
|
+
if (!isSingleTargetRelation(relation)) {
|
|
4885
|
+
throw new Error("Polymorphic MorphTo relations do not support join updates");
|
|
4886
|
+
}
|
|
4747
4887
|
const targetName = resolveTargetTableName(join.table, relation.target.name);
|
|
4748
4888
|
const extra = remapExpressionTable(options.filter, relation.target.name, targetName);
|
|
4749
4889
|
if (relation.type === RelationKinds.BelongsToMany) {
|
|
@@ -4803,6 +4943,9 @@ var RelationCteBuilder = class {
|
|
|
4803
4943
|
if (!predicate) {
|
|
4804
4944
|
throw new Error("Unable to build filter CTE without predicates.");
|
|
4805
4945
|
}
|
|
4946
|
+
if (!isSingleTargetRelation(relation)) {
|
|
4947
|
+
throw new Error("Polymorphic MorphTo relations do not support filter CTEs");
|
|
4948
|
+
}
|
|
4806
4949
|
const columns = Object.keys(relation.target.columns).map((name) => ({
|
|
4807
4950
|
type: "Column",
|
|
4808
4951
|
table: relation.target.name,
|
|
@@ -4850,6 +4993,9 @@ var buildTypedSelection = (columns, prefix, keys, missingMsg, tableOverride) =>
|
|
|
4850
4993
|
}, {});
|
|
4851
4994
|
};
|
|
4852
4995
|
var resolveTargetColumns = (relation, options) => {
|
|
4996
|
+
if (!isSingleTargetRelation(relation)) {
|
|
4997
|
+
return [];
|
|
4998
|
+
}
|
|
4853
4999
|
const requestedColumns = options?.columns?.length ? [...options.columns] : Object.keys(relation.target.columns);
|
|
4854
5000
|
const targetPrimaryKey = findPrimaryKey(relation.target);
|
|
4855
5001
|
if (!requestedColumns.includes(targetPrimaryKey)) {
|
|
@@ -4941,11 +5087,41 @@ var belongsToManyStrategy = (context) => {
|
|
|
4941
5087
|
);
|
|
4942
5088
|
return { state, hydration };
|
|
4943
5089
|
};
|
|
5090
|
+
var morphIncludeStrategy = (context) => {
|
|
5091
|
+
let { state, hydration } = context;
|
|
5092
|
+
const relation = context.relation;
|
|
5093
|
+
const targetColumns = resolveTargetColumns(relation, context.options);
|
|
5094
|
+
const tableOverride = getJoinCorrelationName(state, context.relationName, relation.target.name);
|
|
5095
|
+
const targetSelection = buildTypedSelection(
|
|
5096
|
+
relation.target.columns,
|
|
5097
|
+
context.aliasPrefix,
|
|
5098
|
+
targetColumns,
|
|
5099
|
+
(key) => `Column '${key}' not found on relation '${context.relationName}'`,
|
|
5100
|
+
tableOverride
|
|
5101
|
+
);
|
|
5102
|
+
const relationSelectionResult = context.selectColumns(state, hydration, targetSelection);
|
|
5103
|
+
state = relationSelectionResult.state;
|
|
5104
|
+
hydration = relationSelectionResult.hydration;
|
|
5105
|
+
hydration = hydration.onRelationIncluded(
|
|
5106
|
+
state,
|
|
5107
|
+
relation,
|
|
5108
|
+
context.relationName,
|
|
5109
|
+
context.aliasPrefix,
|
|
5110
|
+
targetColumns
|
|
5111
|
+
);
|
|
5112
|
+
return { state, hydration };
|
|
5113
|
+
};
|
|
5114
|
+
var morphToIncludeStrategy = () => {
|
|
5115
|
+
throw new Error("MorphTo relations do not support JOIN-based include. Use lazy loading instead.");
|
|
5116
|
+
};
|
|
4944
5117
|
var relationIncludeStrategies = {
|
|
4945
5118
|
[RelationKinds.HasMany]: standardIncludeStrategy,
|
|
4946
5119
|
[RelationKinds.HasOne]: standardIncludeStrategy,
|
|
4947
5120
|
[RelationKinds.BelongsTo]: standardIncludeStrategy,
|
|
4948
|
-
[RelationKinds.BelongsToMany]: belongsToManyStrategy
|
|
5121
|
+
[RelationKinds.BelongsToMany]: belongsToManyStrategy,
|
|
5122
|
+
[RelationKinds.MorphOne]: morphIncludeStrategy,
|
|
5123
|
+
[RelationKinds.MorphMany]: morphIncludeStrategy,
|
|
5124
|
+
[RelationKinds.MorphTo]: morphToIncludeStrategy
|
|
4949
5125
|
};
|
|
4950
5126
|
|
|
4951
5127
|
// src/query-builder/relation-service.ts
|
|
@@ -5014,6 +5190,12 @@ var RelationService = class {
|
|
|
5014
5190
|
let state = this.state;
|
|
5015
5191
|
let hydration = this.hydration;
|
|
5016
5192
|
const relation = this.getRelation(relationName);
|
|
5193
|
+
if (relation.type === RelationKinds.MorphTo) {
|
|
5194
|
+
throw new Error(`MorphTo relation '${relationName}' does not support include() via JOIN. Use lazy loading ($load) instead.`);
|
|
5195
|
+
}
|
|
5196
|
+
if (!isSingleTargetRelation(relation)) {
|
|
5197
|
+
return { state, hydration };
|
|
5198
|
+
}
|
|
5017
5199
|
const aliasPrefix = options?.aliasPrefix ?? relationName;
|
|
5018
5200
|
const alreadyJoined = hasJoinForRelationKey(state.ast.joins, relationName);
|
|
5019
5201
|
const { selfFilters, crossFilters } = splitFilterExpressions(
|
|
@@ -5072,6 +5254,9 @@ var RelationService = class {
|
|
|
5072
5254
|
*/
|
|
5073
5255
|
applyRelationCorrelation(relationName, ast, additionalCorrelation) {
|
|
5074
5256
|
const relation = this.getRelation(relationName);
|
|
5257
|
+
if (relation.type === RelationKinds.MorphTo) {
|
|
5258
|
+
throw new Error(`MorphTo relation '${relationName}' does not support correlation-based operations.`);
|
|
5259
|
+
}
|
|
5075
5260
|
const rootAlias = this.state.ast.from.type === "Table" ? this.state.ast.from.alias : void 0;
|
|
5076
5261
|
let correlation = buildRelationCorrelation(this.table, relation, rootAlias);
|
|
5077
5262
|
if (additionalCorrelation) {
|
|
@@ -5531,6 +5716,45 @@ var populateHydrationCache = (entity, row, meta) => {
|
|
|
5531
5716
|
}
|
|
5532
5717
|
}
|
|
5533
5718
|
}
|
|
5719
|
+
for (const relationName of Object.keys(meta.table.relations)) {
|
|
5720
|
+
const relation = meta.table.relations[relationName];
|
|
5721
|
+
const data = row[relationName];
|
|
5722
|
+
if (relation.type === RelationKinds.MorphOne) {
|
|
5723
|
+
const localKey = relation.localKey || findPrimaryKey(meta.table);
|
|
5724
|
+
const rootValue = entity[localKey];
|
|
5725
|
+
if (rootValue === void 0 || rootValue === null) continue;
|
|
5726
|
+
if (!data || typeof data !== "object") continue;
|
|
5727
|
+
const cache = /* @__PURE__ */ new Map();
|
|
5728
|
+
cache.set(toKey2(rootValue), data);
|
|
5729
|
+
meta.relationHydration.set(relationName, cache);
|
|
5730
|
+
meta.relationCache.set(relationName, Promise.resolve(cache));
|
|
5731
|
+
continue;
|
|
5732
|
+
}
|
|
5733
|
+
if (relation.type === RelationKinds.MorphMany) {
|
|
5734
|
+
if (!Array.isArray(data)) continue;
|
|
5735
|
+
const localKey = relation.localKey || findPrimaryKey(meta.table);
|
|
5736
|
+
const rootValue = entity[localKey];
|
|
5737
|
+
if (rootValue === void 0 || rootValue === null) continue;
|
|
5738
|
+
const cache = /* @__PURE__ */ new Map();
|
|
5739
|
+
cache.set(toKey2(rootValue), data);
|
|
5740
|
+
meta.relationHydration.set(relationName, cache);
|
|
5741
|
+
meta.relationCache.set(relationName, Promise.resolve(cache));
|
|
5742
|
+
continue;
|
|
5743
|
+
}
|
|
5744
|
+
if (relation.type === RelationKinds.MorphTo) {
|
|
5745
|
+
if (!data || typeof data !== "object") continue;
|
|
5746
|
+
const morphTo2 = relation;
|
|
5747
|
+
const typeValue = entity[morphTo2.typeField];
|
|
5748
|
+
const idValue = entity[morphTo2.idField];
|
|
5749
|
+
if (!typeValue || idValue === void 0 || idValue === null) continue;
|
|
5750
|
+
const compositeKey = `${toKey2(typeValue)}:${toKey2(idValue)}`;
|
|
5751
|
+
const cache = /* @__PURE__ */ new Map();
|
|
5752
|
+
cache.set(compositeKey, data);
|
|
5753
|
+
meta.relationHydration.set(relationName, cache);
|
|
5754
|
+
meta.relationCache.set(relationName, Promise.resolve(cache));
|
|
5755
|
+
continue;
|
|
5756
|
+
}
|
|
5757
|
+
}
|
|
5534
5758
|
};
|
|
5535
5759
|
|
|
5536
5760
|
// src/orm/relations/has-many.ts
|
|
@@ -6203,113 +6427,519 @@ var DefaultManyToManyCollection = class {
|
|
|
6203
6427
|
}
|
|
6204
6428
|
};
|
|
6205
6429
|
|
|
6206
|
-
// src/orm/
|
|
6207
|
-
var hasColumns = (columns) => Boolean(columns && columns.length > 0);
|
|
6208
|
-
var buildColumnSelection = (table, columns, missingMsg) => {
|
|
6209
|
-
return columns.reduce((acc, column) => {
|
|
6210
|
-
const def = table.columns[column];
|
|
6211
|
-
if (!def) {
|
|
6212
|
-
throw new Error(missingMsg(column));
|
|
6213
|
-
}
|
|
6214
|
-
acc[column] = def;
|
|
6215
|
-
return acc;
|
|
6216
|
-
}, {});
|
|
6217
|
-
};
|
|
6218
|
-
var filterRow = (row, columns) => {
|
|
6219
|
-
const filtered = {};
|
|
6220
|
-
for (const column of columns) {
|
|
6221
|
-
if (column in row) {
|
|
6222
|
-
filtered[column] = row[column];
|
|
6223
|
-
}
|
|
6224
|
-
}
|
|
6225
|
-
return filtered;
|
|
6226
|
-
};
|
|
6227
|
-
var filterRows = (rows, columns) => rows.map((row) => filterRow(row, columns));
|
|
6228
|
-
var rowsFromResults = (results) => {
|
|
6229
|
-
const rows = [];
|
|
6230
|
-
for (const result of results) {
|
|
6231
|
-
const { columns, values } = result;
|
|
6232
|
-
for (const valueRow of values) {
|
|
6233
|
-
const row = {};
|
|
6234
|
-
columns.forEach((column, idx) => {
|
|
6235
|
-
row[column] = valueRow[idx];
|
|
6236
|
-
});
|
|
6237
|
-
rows.push(row);
|
|
6238
|
-
}
|
|
6239
|
-
}
|
|
6240
|
-
return rows;
|
|
6241
|
-
};
|
|
6242
|
-
var executeQuery = async (ctx, qb) => {
|
|
6243
|
-
const compiled = ctx.dialect.compileSelect(qb.getAST());
|
|
6244
|
-
const results = await ctx.executor.executeSql(compiled.sql, compiled.params);
|
|
6245
|
-
return rowsFromResults(results);
|
|
6246
|
-
};
|
|
6430
|
+
// src/orm/relations/morph-one.ts
|
|
6247
6431
|
var toKey7 = (value) => value === null || value === void 0 ? "" : String(value);
|
|
6248
|
-
var
|
|
6249
|
-
const
|
|
6250
|
-
|
|
6251
|
-
|
|
6252
|
-
|
|
6253
|
-
|
|
6254
|
-
|
|
6432
|
+
var hideInternal5 = (obj, keys) => {
|
|
6433
|
+
for (const key of keys) {
|
|
6434
|
+
Object.defineProperty(obj, key, {
|
|
6435
|
+
value: obj[key],
|
|
6436
|
+
writable: false,
|
|
6437
|
+
configurable: false,
|
|
6438
|
+
enumerable: false
|
|
6439
|
+
});
|
|
6255
6440
|
}
|
|
6256
|
-
return collected;
|
|
6257
6441
|
};
|
|
6258
|
-
var
|
|
6259
|
-
|
|
6260
|
-
|
|
6261
|
-
|
|
6262
|
-
|
|
6263
|
-
|
|
6442
|
+
var hideWritable5 = (obj, keys) => {
|
|
6443
|
+
for (const key of keys) {
|
|
6444
|
+
const value = obj[key];
|
|
6445
|
+
Object.defineProperty(obj, key, {
|
|
6446
|
+
value,
|
|
6447
|
+
writable: true,
|
|
6448
|
+
configurable: true,
|
|
6449
|
+
enumerable: false
|
|
6450
|
+
});
|
|
6264
6451
|
}
|
|
6265
|
-
return executeQuery(ctx, qb);
|
|
6266
6452
|
};
|
|
6267
|
-
var
|
|
6268
|
-
|
|
6269
|
-
|
|
6270
|
-
|
|
6271
|
-
|
|
6272
|
-
|
|
6273
|
-
|
|
6274
|
-
|
|
6275
|
-
|
|
6453
|
+
var DefaultMorphOneReference = class {
|
|
6454
|
+
constructor(ctx, meta, root, relationName, relation, rootTable, loader, createEntity, localKey) {
|
|
6455
|
+
this.ctx = ctx;
|
|
6456
|
+
this.meta = meta;
|
|
6457
|
+
this.root = root;
|
|
6458
|
+
this.relationName = relationName;
|
|
6459
|
+
this.relation = relation;
|
|
6460
|
+
this.rootTable = rootTable;
|
|
6461
|
+
this.loader = loader;
|
|
6462
|
+
this.createEntity = createEntity;
|
|
6463
|
+
this.localKey = localKey;
|
|
6464
|
+
hideInternal5(this, [
|
|
6465
|
+
"ctx",
|
|
6466
|
+
"meta",
|
|
6467
|
+
"root",
|
|
6468
|
+
"relationName",
|
|
6469
|
+
"relation",
|
|
6470
|
+
"rootTable",
|
|
6471
|
+
"loader",
|
|
6472
|
+
"createEntity",
|
|
6473
|
+
"localKey"
|
|
6474
|
+
]);
|
|
6475
|
+
hideWritable5(this, ["loaded", "current"]);
|
|
6476
|
+
this.populateFromHydrationCache();
|
|
6276
6477
|
}
|
|
6277
|
-
|
|
6278
|
-
|
|
6279
|
-
|
|
6280
|
-
|
|
6281
|
-
|
|
6282
|
-
const
|
|
6283
|
-
if (
|
|
6284
|
-
|
|
6285
|
-
|
|
6286
|
-
lookup.set(key, row);
|
|
6478
|
+
loaded = false;
|
|
6479
|
+
current = null;
|
|
6480
|
+
async load() {
|
|
6481
|
+
if (this.loaded) return this.current;
|
|
6482
|
+
const map = await this.loader();
|
|
6483
|
+
const keyValue = this.root[this.localKey];
|
|
6484
|
+
if (keyValue === void 0 || keyValue === null) {
|
|
6485
|
+
this.loaded = true;
|
|
6486
|
+
return this.current;
|
|
6287
6487
|
}
|
|
6488
|
+
const row = map.get(toKey7(keyValue));
|
|
6489
|
+
this.current = row ? this.createEntity(row) : null;
|
|
6490
|
+
this.loaded = true;
|
|
6491
|
+
return this.current;
|
|
6288
6492
|
}
|
|
6289
|
-
|
|
6290
|
-
|
|
6291
|
-
|
|
6292
|
-
// src/orm/lazy-batch/has-many.ts
|
|
6293
|
-
var loadHasManyRelation = async (ctx, rootTable, relationName, relation, options) => {
|
|
6294
|
-
const localKey = relation.localKey || findPrimaryKey(rootTable);
|
|
6295
|
-
const roots = ctx.getEntitiesForTable(rootTable);
|
|
6296
|
-
const keys = collectKeysFromRoots(roots, localKey);
|
|
6297
|
-
if (!keys.size) {
|
|
6298
|
-
return /* @__PURE__ */ new Map();
|
|
6299
|
-
}
|
|
6300
|
-
const fkColumn = relation.target.columns[relation.foreignKey];
|
|
6301
|
-
if (!fkColumn) return /* @__PURE__ */ new Map();
|
|
6302
|
-
const requestedColumns = hasColumns(options?.columns) ? [...options.columns] : void 0;
|
|
6303
|
-
const targetPrimaryKey = findPrimaryKey(relation.target);
|
|
6304
|
-
const selectedColumns = requestedColumns ? [...requestedColumns] : Object.keys(relation.target.columns);
|
|
6305
|
-
if (!selectedColumns.includes(targetPrimaryKey)) {
|
|
6306
|
-
selectedColumns.push(targetPrimaryKey);
|
|
6493
|
+
get() {
|
|
6494
|
+
return this.current;
|
|
6307
6495
|
}
|
|
6308
|
-
|
|
6309
|
-
|
|
6310
|
-
|
|
6311
|
-
|
|
6312
|
-
|
|
6496
|
+
set(data) {
|
|
6497
|
+
if (data === null) {
|
|
6498
|
+
return this.detachCurrent();
|
|
6499
|
+
}
|
|
6500
|
+
const entity = hasEntityMeta(data) ? data : this.createEntity(data);
|
|
6501
|
+
if (this.current && this.current !== entity) {
|
|
6502
|
+
this.ctx.registerRelationChange(
|
|
6503
|
+
this.root,
|
|
6504
|
+
this.relationKey,
|
|
6505
|
+
this.rootTable,
|
|
6506
|
+
this.relationName,
|
|
6507
|
+
this.relation,
|
|
6508
|
+
{ kind: "remove", entity: this.current }
|
|
6509
|
+
);
|
|
6510
|
+
}
|
|
6511
|
+
this.assignMorphKeys(entity);
|
|
6512
|
+
this.current = entity;
|
|
6513
|
+
this.loaded = true;
|
|
6514
|
+
this.ctx.registerRelationChange(
|
|
6515
|
+
this.root,
|
|
6516
|
+
this.relationKey,
|
|
6517
|
+
this.rootTable,
|
|
6518
|
+
this.relationName,
|
|
6519
|
+
this.relation,
|
|
6520
|
+
{ kind: "attach", entity }
|
|
6521
|
+
);
|
|
6522
|
+
return entity;
|
|
6523
|
+
}
|
|
6524
|
+
toJSON() {
|
|
6525
|
+
if (!this.current) return null;
|
|
6526
|
+
const entityWithToJSON = this.current;
|
|
6527
|
+
return typeof entityWithToJSON.toJSON === "function" ? entityWithToJSON.toJSON() : this.current;
|
|
6528
|
+
}
|
|
6529
|
+
detachCurrent() {
|
|
6530
|
+
const previous = this.current;
|
|
6531
|
+
if (!previous) return null;
|
|
6532
|
+
this.current = null;
|
|
6533
|
+
this.loaded = true;
|
|
6534
|
+
this.ctx.registerRelationChange(
|
|
6535
|
+
this.root,
|
|
6536
|
+
this.relationKey,
|
|
6537
|
+
this.rootTable,
|
|
6538
|
+
this.relationName,
|
|
6539
|
+
this.relation,
|
|
6540
|
+
{ kind: "remove", entity: previous }
|
|
6541
|
+
);
|
|
6542
|
+
return null;
|
|
6543
|
+
}
|
|
6544
|
+
assignMorphKeys(entity) {
|
|
6545
|
+
const keyValue = this.root[this.localKey];
|
|
6546
|
+
entity[this.relation.idField] = keyValue;
|
|
6547
|
+
entity[this.relation.typeField] = this.relation.typeValue;
|
|
6548
|
+
}
|
|
6549
|
+
get relationKey() {
|
|
6550
|
+
return `${this.rootTable.name}.${this.relationName}`;
|
|
6551
|
+
}
|
|
6552
|
+
populateFromHydrationCache() {
|
|
6553
|
+
const keyValue = this.root[this.localKey];
|
|
6554
|
+
if (keyValue === void 0 || keyValue === null) return;
|
|
6555
|
+
const row = getHydrationRecord(this.meta, this.relationName, keyValue);
|
|
6556
|
+
if (!row) return;
|
|
6557
|
+
this.current = this.createEntity(row);
|
|
6558
|
+
this.loaded = true;
|
|
6559
|
+
}
|
|
6560
|
+
};
|
|
6561
|
+
|
|
6562
|
+
// src/orm/relations/morph-many.ts
|
|
6563
|
+
var toKey8 = (value) => value === null || value === void 0 ? "" : String(value);
|
|
6564
|
+
var hideInternal6 = (obj, keys) => {
|
|
6565
|
+
for (const key of keys) {
|
|
6566
|
+
Object.defineProperty(obj, key, {
|
|
6567
|
+
value: obj[key],
|
|
6568
|
+
writable: false,
|
|
6569
|
+
configurable: false,
|
|
6570
|
+
enumerable: false
|
|
6571
|
+
});
|
|
6572
|
+
}
|
|
6573
|
+
};
|
|
6574
|
+
var hideWritable6 = (obj, keys) => {
|
|
6575
|
+
for (const key of keys) {
|
|
6576
|
+
const value = obj[key];
|
|
6577
|
+
Object.defineProperty(obj, key, {
|
|
6578
|
+
value,
|
|
6579
|
+
writable: true,
|
|
6580
|
+
configurable: true,
|
|
6581
|
+
enumerable: false
|
|
6582
|
+
});
|
|
6583
|
+
}
|
|
6584
|
+
};
|
|
6585
|
+
var DefaultMorphManyCollection = class {
|
|
6586
|
+
constructor(ctx, meta, root, relationName, relation, rootTable, loader, createEntity, localKey) {
|
|
6587
|
+
this.ctx = ctx;
|
|
6588
|
+
this.meta = meta;
|
|
6589
|
+
this.root = root;
|
|
6590
|
+
this.relationName = relationName;
|
|
6591
|
+
this.relation = relation;
|
|
6592
|
+
this.rootTable = rootTable;
|
|
6593
|
+
this.loader = loader;
|
|
6594
|
+
this.createEntity = createEntity;
|
|
6595
|
+
this.localKey = localKey;
|
|
6596
|
+
hideInternal6(this, ["ctx", "meta", "root", "relationName", "relation", "rootTable", "loader", "createEntity", "localKey"]);
|
|
6597
|
+
hideWritable6(this, ["loaded", "items", "added", "removed"]);
|
|
6598
|
+
this.hydrateFromCache();
|
|
6599
|
+
}
|
|
6600
|
+
loaded = false;
|
|
6601
|
+
items = [];
|
|
6602
|
+
added = /* @__PURE__ */ new Set();
|
|
6603
|
+
removed = /* @__PURE__ */ new Set();
|
|
6604
|
+
async load() {
|
|
6605
|
+
if (this.loaded) return this.items;
|
|
6606
|
+
const map = await this.loader();
|
|
6607
|
+
const key = toKey8(this.root[this.localKey]);
|
|
6608
|
+
const rows = map.get(key) ?? [];
|
|
6609
|
+
this.items = rows.map((row) => this.createEntity(row));
|
|
6610
|
+
this.loaded = true;
|
|
6611
|
+
return this.items;
|
|
6612
|
+
}
|
|
6613
|
+
getItems() {
|
|
6614
|
+
return this.items;
|
|
6615
|
+
}
|
|
6616
|
+
get length() {
|
|
6617
|
+
return this.items.length;
|
|
6618
|
+
}
|
|
6619
|
+
[Symbol.iterator]() {
|
|
6620
|
+
return this.items[Symbol.iterator]();
|
|
6621
|
+
}
|
|
6622
|
+
add(data) {
|
|
6623
|
+
const keyValue = this.root[this.localKey];
|
|
6624
|
+
const childRow = {
|
|
6625
|
+
...data,
|
|
6626
|
+
[this.relation.idField]: keyValue,
|
|
6627
|
+
[this.relation.typeField]: this.relation.typeValue
|
|
6628
|
+
};
|
|
6629
|
+
const entity = this.createEntity(childRow);
|
|
6630
|
+
this.added.add(entity);
|
|
6631
|
+
this.items.push(entity);
|
|
6632
|
+
this.ctx.registerRelationChange(
|
|
6633
|
+
this.root,
|
|
6634
|
+
this.relationKey,
|
|
6635
|
+
this.rootTable,
|
|
6636
|
+
this.relationName,
|
|
6637
|
+
this.relation,
|
|
6638
|
+
{ kind: "add", entity }
|
|
6639
|
+
);
|
|
6640
|
+
return entity;
|
|
6641
|
+
}
|
|
6642
|
+
attach(entity) {
|
|
6643
|
+
const keyValue = this.root[this.localKey];
|
|
6644
|
+
entity[this.relation.idField] = keyValue;
|
|
6645
|
+
entity[this.relation.typeField] = this.relation.typeValue;
|
|
6646
|
+
this.ctx.markDirty(entity);
|
|
6647
|
+
this.items.push(entity);
|
|
6648
|
+
this.ctx.registerRelationChange(
|
|
6649
|
+
this.root,
|
|
6650
|
+
this.relationKey,
|
|
6651
|
+
this.rootTable,
|
|
6652
|
+
this.relationName,
|
|
6653
|
+
this.relation,
|
|
6654
|
+
{ kind: "attach", entity }
|
|
6655
|
+
);
|
|
6656
|
+
}
|
|
6657
|
+
remove(entity) {
|
|
6658
|
+
this.items = this.items.filter((item) => item !== entity);
|
|
6659
|
+
this.removed.add(entity);
|
|
6660
|
+
this.ctx.registerRelationChange(
|
|
6661
|
+
this.root,
|
|
6662
|
+
this.relationKey,
|
|
6663
|
+
this.rootTable,
|
|
6664
|
+
this.relationName,
|
|
6665
|
+
this.relation,
|
|
6666
|
+
{ kind: "remove", entity }
|
|
6667
|
+
);
|
|
6668
|
+
}
|
|
6669
|
+
clear() {
|
|
6670
|
+
for (const entity of [...this.items]) {
|
|
6671
|
+
this.remove(entity);
|
|
6672
|
+
}
|
|
6673
|
+
}
|
|
6674
|
+
get relationKey() {
|
|
6675
|
+
return `${this.rootTable.name}.${this.relationName}`;
|
|
6676
|
+
}
|
|
6677
|
+
hydrateFromCache() {
|
|
6678
|
+
const keyValue = this.root[this.localKey];
|
|
6679
|
+
if (keyValue === void 0 || keyValue === null) return;
|
|
6680
|
+
const rows = getHydrationRows(this.meta, this.relationName, keyValue);
|
|
6681
|
+
if (!rows?.length) return;
|
|
6682
|
+
this.items = rows.map((row) => this.createEntity(row));
|
|
6683
|
+
this.loaded = true;
|
|
6684
|
+
}
|
|
6685
|
+
toJSON() {
|
|
6686
|
+
return this.items.map((item) => {
|
|
6687
|
+
const entityWithToJSON = item;
|
|
6688
|
+
return typeof entityWithToJSON.toJSON === "function" ? entityWithToJSON.toJSON() : item;
|
|
6689
|
+
});
|
|
6690
|
+
}
|
|
6691
|
+
};
|
|
6692
|
+
|
|
6693
|
+
// src/orm/relations/morph-to.ts
|
|
6694
|
+
var toKey9 = (value) => value === null || value === void 0 ? "" : String(value);
|
|
6695
|
+
var hideInternal7 = (obj, keys) => {
|
|
6696
|
+
for (const key of keys) {
|
|
6697
|
+
Object.defineProperty(obj, key, {
|
|
6698
|
+
value: obj[key],
|
|
6699
|
+
writable: false,
|
|
6700
|
+
configurable: false,
|
|
6701
|
+
enumerable: false
|
|
6702
|
+
});
|
|
6703
|
+
}
|
|
6704
|
+
};
|
|
6705
|
+
var hideWritable7 = (obj, keys) => {
|
|
6706
|
+
for (const key of keys) {
|
|
6707
|
+
const value = obj[key];
|
|
6708
|
+
Object.defineProperty(obj, key, {
|
|
6709
|
+
value,
|
|
6710
|
+
writable: true,
|
|
6711
|
+
configurable: true,
|
|
6712
|
+
enumerable: false
|
|
6713
|
+
});
|
|
6714
|
+
}
|
|
6715
|
+
};
|
|
6716
|
+
var DefaultMorphToReference = class {
|
|
6717
|
+
constructor(ctx, meta, root, relationName, relation, rootTable, loader, createEntity, resolveTargetTable) {
|
|
6718
|
+
this.ctx = ctx;
|
|
6719
|
+
this.meta = meta;
|
|
6720
|
+
this.root = root;
|
|
6721
|
+
this.relationName = relationName;
|
|
6722
|
+
this.relation = relation;
|
|
6723
|
+
this.rootTable = rootTable;
|
|
6724
|
+
this.loader = loader;
|
|
6725
|
+
this.createEntity = createEntity;
|
|
6726
|
+
this.resolveTargetTable = resolveTargetTable;
|
|
6727
|
+
hideInternal7(this, [
|
|
6728
|
+
"ctx",
|
|
6729
|
+
"meta",
|
|
6730
|
+
"root",
|
|
6731
|
+
"relationName",
|
|
6732
|
+
"relation",
|
|
6733
|
+
"rootTable",
|
|
6734
|
+
"loader",
|
|
6735
|
+
"createEntity",
|
|
6736
|
+
"resolveTargetTable"
|
|
6737
|
+
]);
|
|
6738
|
+
hideWritable7(this, ["loaded", "current"]);
|
|
6739
|
+
this.populateFromHydrationCache();
|
|
6740
|
+
}
|
|
6741
|
+
loaded = false;
|
|
6742
|
+
current = null;
|
|
6743
|
+
async load() {
|
|
6744
|
+
if (this.loaded) return this.current;
|
|
6745
|
+
const rootObj = this.root;
|
|
6746
|
+
const typeValue = rootObj[this.relation.typeField];
|
|
6747
|
+
const idValue = rootObj[this.relation.idField];
|
|
6748
|
+
if (!typeValue || idValue === void 0 || idValue === null) {
|
|
6749
|
+
this.loaded = true;
|
|
6750
|
+
return this.current;
|
|
6751
|
+
}
|
|
6752
|
+
const map = await this.loader();
|
|
6753
|
+
const compositeKey = `${toKey9(typeValue)}:${toKey9(idValue)}`;
|
|
6754
|
+
const row = map.get(compositeKey);
|
|
6755
|
+
if (row) {
|
|
6756
|
+
const targetTable = this.resolveTargetTable(toKey9(typeValue));
|
|
6757
|
+
if (targetTable) {
|
|
6758
|
+
this.current = this.createEntity(targetTable, row);
|
|
6759
|
+
}
|
|
6760
|
+
}
|
|
6761
|
+
this.loaded = true;
|
|
6762
|
+
return this.current;
|
|
6763
|
+
}
|
|
6764
|
+
get() {
|
|
6765
|
+
return this.current;
|
|
6766
|
+
}
|
|
6767
|
+
set(data) {
|
|
6768
|
+
if (data === null) {
|
|
6769
|
+
return this.detachCurrent();
|
|
6770
|
+
}
|
|
6771
|
+
const entity = hasEntityMeta(data) ? data : data;
|
|
6772
|
+
if (this.current && this.current !== entity) {
|
|
6773
|
+
this.ctx.registerRelationChange(
|
|
6774
|
+
this.root,
|
|
6775
|
+
this.relationKey,
|
|
6776
|
+
this.rootTable,
|
|
6777
|
+
this.relationName,
|
|
6778
|
+
this.relation,
|
|
6779
|
+
{ kind: "remove", entity: this.current }
|
|
6780
|
+
);
|
|
6781
|
+
}
|
|
6782
|
+
this.current = entity;
|
|
6783
|
+
this.loaded = true;
|
|
6784
|
+
this.ctx.registerRelationChange(
|
|
6785
|
+
this.root,
|
|
6786
|
+
this.relationKey,
|
|
6787
|
+
this.rootTable,
|
|
6788
|
+
this.relationName,
|
|
6789
|
+
this.relation,
|
|
6790
|
+
{ kind: "attach", entity }
|
|
6791
|
+
);
|
|
6792
|
+
return entity;
|
|
6793
|
+
}
|
|
6794
|
+
toJSON() {
|
|
6795
|
+
if (!this.current) return null;
|
|
6796
|
+
const entityWithToJSON = this.current;
|
|
6797
|
+
return typeof entityWithToJSON.toJSON === "function" ? entityWithToJSON.toJSON() : this.current;
|
|
6798
|
+
}
|
|
6799
|
+
detachCurrent() {
|
|
6800
|
+
const previous = this.current;
|
|
6801
|
+
if (!previous) return null;
|
|
6802
|
+
this.current = null;
|
|
6803
|
+
this.loaded = true;
|
|
6804
|
+
const rootObj = this.root;
|
|
6805
|
+
rootObj[this.relation.typeField] = null;
|
|
6806
|
+
rootObj[this.relation.idField] = null;
|
|
6807
|
+
this.ctx.registerRelationChange(
|
|
6808
|
+
this.root,
|
|
6809
|
+
this.relationKey,
|
|
6810
|
+
this.rootTable,
|
|
6811
|
+
this.relationName,
|
|
6812
|
+
this.relation,
|
|
6813
|
+
{ kind: "remove", entity: previous }
|
|
6814
|
+
);
|
|
6815
|
+
return null;
|
|
6816
|
+
}
|
|
6817
|
+
get relationKey() {
|
|
6818
|
+
return `${this.rootTable.name}.${this.relationName}`;
|
|
6819
|
+
}
|
|
6820
|
+
populateFromHydrationCache() {
|
|
6821
|
+
const rootObj = this.root;
|
|
6822
|
+
const typeValue = rootObj[this.relation.typeField];
|
|
6823
|
+
const idValue = rootObj[this.relation.idField];
|
|
6824
|
+
if (!typeValue || idValue === void 0 || idValue === null) return;
|
|
6825
|
+
const compositeKey = `${toKey9(typeValue)}:${toKey9(idValue)}`;
|
|
6826
|
+
const row = getHydrationRecord(this.meta, this.relationName, compositeKey);
|
|
6827
|
+
if (!row) return;
|
|
6828
|
+
const targetTable = this.resolveTargetTable(toKey9(typeValue));
|
|
6829
|
+
if (targetTable) {
|
|
6830
|
+
this.current = this.createEntity(targetTable, row);
|
|
6831
|
+
this.loaded = true;
|
|
6832
|
+
}
|
|
6833
|
+
}
|
|
6834
|
+
};
|
|
6835
|
+
|
|
6836
|
+
// src/orm/lazy-batch/shared.ts
|
|
6837
|
+
var hasColumns = (columns) => Boolean(columns && columns.length > 0);
|
|
6838
|
+
var buildColumnSelection = (table, columns, missingMsg) => {
|
|
6839
|
+
return columns.reduce((acc, column) => {
|
|
6840
|
+
const def = table.columns[column];
|
|
6841
|
+
if (!def) {
|
|
6842
|
+
throw new Error(missingMsg(column));
|
|
6843
|
+
}
|
|
6844
|
+
acc[column] = def;
|
|
6845
|
+
return acc;
|
|
6846
|
+
}, {});
|
|
6847
|
+
};
|
|
6848
|
+
var filterRow = (row, columns) => {
|
|
6849
|
+
const filtered = {};
|
|
6850
|
+
for (const column of columns) {
|
|
6851
|
+
if (column in row) {
|
|
6852
|
+
filtered[column] = row[column];
|
|
6853
|
+
}
|
|
6854
|
+
}
|
|
6855
|
+
return filtered;
|
|
6856
|
+
};
|
|
6857
|
+
var filterRows = (rows, columns) => rows.map((row) => filterRow(row, columns));
|
|
6858
|
+
var rowsFromResults = (results) => {
|
|
6859
|
+
const rows = [];
|
|
6860
|
+
for (const result of results) {
|
|
6861
|
+
const { columns, values } = result;
|
|
6862
|
+
for (const valueRow of values) {
|
|
6863
|
+
const row = {};
|
|
6864
|
+
columns.forEach((column, idx) => {
|
|
6865
|
+
row[column] = valueRow[idx];
|
|
6866
|
+
});
|
|
6867
|
+
rows.push(row);
|
|
6868
|
+
}
|
|
6869
|
+
}
|
|
6870
|
+
return rows;
|
|
6871
|
+
};
|
|
6872
|
+
var executeQuery = async (ctx, qb) => {
|
|
6873
|
+
const compiled = ctx.dialect.compileSelect(qb.getAST());
|
|
6874
|
+
const results = await ctx.executor.executeSql(compiled.sql, compiled.params);
|
|
6875
|
+
return rowsFromResults(results);
|
|
6876
|
+
};
|
|
6877
|
+
var toKey10 = (value) => value === null || value === void 0 ? "" : String(value);
|
|
6878
|
+
var collectKeysFromRoots = (roots, key) => {
|
|
6879
|
+
const collected = /* @__PURE__ */ new Set();
|
|
6880
|
+
for (const tracked of roots) {
|
|
6881
|
+
const value = tracked.entity[key];
|
|
6882
|
+
if (value !== null && value !== void 0) {
|
|
6883
|
+
collected.add(value);
|
|
6884
|
+
}
|
|
6885
|
+
}
|
|
6886
|
+
return collected;
|
|
6887
|
+
};
|
|
6888
|
+
var buildInListValues = (keys) => Array.from(keys);
|
|
6889
|
+
var fetchRowsForKeys = async (ctx, table, column, keys, selection, filter) => {
|
|
6890
|
+
let qb = new SelectQueryBuilder(table).select(selection);
|
|
6891
|
+
qb = qb.where(inList(column, buildInListValues(keys)));
|
|
6892
|
+
if (filter) {
|
|
6893
|
+
qb = qb.where(filter);
|
|
6894
|
+
}
|
|
6895
|
+
return executeQuery(ctx, qb);
|
|
6896
|
+
};
|
|
6897
|
+
var groupRowsByMany = (rows, keyColumn) => {
|
|
6898
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
6899
|
+
for (const row of rows) {
|
|
6900
|
+
const value = row[keyColumn];
|
|
6901
|
+
if (value === null || value === void 0) continue;
|
|
6902
|
+
const key = toKey10(value);
|
|
6903
|
+
const bucket = grouped.get(key) ?? [];
|
|
6904
|
+
bucket.push(row);
|
|
6905
|
+
grouped.set(key, bucket);
|
|
6906
|
+
}
|
|
6907
|
+
return grouped;
|
|
6908
|
+
};
|
|
6909
|
+
var groupRowsByUnique = (rows, keyColumn) => {
|
|
6910
|
+
const lookup = /* @__PURE__ */ new Map();
|
|
6911
|
+
for (const row of rows) {
|
|
6912
|
+
const value = row[keyColumn];
|
|
6913
|
+
if (value === null || value === void 0) continue;
|
|
6914
|
+
const key = toKey10(value);
|
|
6915
|
+
if (!lookup.has(key)) {
|
|
6916
|
+
lookup.set(key, row);
|
|
6917
|
+
}
|
|
6918
|
+
}
|
|
6919
|
+
return lookup;
|
|
6920
|
+
};
|
|
6921
|
+
|
|
6922
|
+
// src/orm/lazy-batch/has-many.ts
|
|
6923
|
+
var loadHasManyRelation = async (ctx, rootTable, relationName, relation, options) => {
|
|
6924
|
+
const localKey = relation.localKey || findPrimaryKey(rootTable);
|
|
6925
|
+
const roots = ctx.getEntitiesForTable(rootTable);
|
|
6926
|
+
const keys = collectKeysFromRoots(roots, localKey);
|
|
6927
|
+
if (!keys.size) {
|
|
6928
|
+
return /* @__PURE__ */ new Map();
|
|
6929
|
+
}
|
|
6930
|
+
const fkColumn = relation.target.columns[relation.foreignKey];
|
|
6931
|
+
if (!fkColumn) return /* @__PURE__ */ new Map();
|
|
6932
|
+
const requestedColumns = hasColumns(options?.columns) ? [...options.columns] : void 0;
|
|
6933
|
+
const targetPrimaryKey = findPrimaryKey(relation.target);
|
|
6934
|
+
const selectedColumns = requestedColumns ? [...requestedColumns] : Object.keys(relation.target.columns);
|
|
6935
|
+
if (!selectedColumns.includes(targetPrimaryKey)) {
|
|
6936
|
+
selectedColumns.push(targetPrimaryKey);
|
|
6937
|
+
}
|
|
6938
|
+
const queryColumns = new Set(selectedColumns);
|
|
6939
|
+
queryColumns.add(relation.foreignKey);
|
|
6940
|
+
const selection = buildColumnSelection(
|
|
6941
|
+
relation.target,
|
|
6942
|
+
Array.from(queryColumns),
|
|
6313
6943
|
(column) => `Column '${column}' not found on relation '${relationName}'`
|
|
6314
6944
|
);
|
|
6315
6945
|
const rows = await fetchRowsForKeys(ctx, relation.target, fkColumn, keys, selection, options?.filter);
|
|
@@ -6466,12 +7096,12 @@ var loadBelongsToManyRelation = async (ctx, rootTable, relationName, relation, o
|
|
|
6466
7096
|
if (rootValue === null || rootValue === void 0 || targetValue === null || targetValue === void 0) {
|
|
6467
7097
|
continue;
|
|
6468
7098
|
}
|
|
6469
|
-
const bucket = rootLookup.get(
|
|
7099
|
+
const bucket = rootLookup.get(toKey10(rootValue)) ?? [];
|
|
6470
7100
|
bucket.push({
|
|
6471
7101
|
targetId: targetValue,
|
|
6472
7102
|
pivot: pivotVisibleColumns.size ? filterRow(pivot, pivotVisibleColumns) : {}
|
|
6473
7103
|
});
|
|
6474
|
-
rootLookup.set(
|
|
7104
|
+
rootLookup.set(toKey10(rootValue), bucket);
|
|
6475
7105
|
targetIds.add(targetValue);
|
|
6476
7106
|
}
|
|
6477
7107
|
if (!targetIds.size) {
|
|
@@ -6504,7 +7134,7 @@ var loadBelongsToManyRelation = async (ctx, rootTable, relationName, relation, o
|
|
|
6504
7134
|
for (const [rootId, entries] of rootLookup.entries()) {
|
|
6505
7135
|
const bucket = [];
|
|
6506
7136
|
for (const entry of entries) {
|
|
6507
|
-
const targetRow = targetMap.get(
|
|
7137
|
+
const targetRow = targetMap.get(toKey10(entry.targetId));
|
|
6508
7138
|
if (!targetRow) continue;
|
|
6509
7139
|
const row = targetRequestedColumns ? filterRow(targetRow, targetVisibleColumns) : { ...targetRow };
|
|
6510
7140
|
if (options?.pivot?.merge) {
|
|
@@ -6523,6 +7153,123 @@ var mergePivotIntoRow = (row, pivot) => {
|
|
|
6523
7153
|
}
|
|
6524
7154
|
};
|
|
6525
7155
|
|
|
7156
|
+
// src/orm/lazy-batch/morph-one.ts
|
|
7157
|
+
var loadMorphOneRelation = async (ctx, rootTable, relationName, relation, options) => {
|
|
7158
|
+
const localKey = relation.localKey || findPrimaryKey(rootTable);
|
|
7159
|
+
const roots = ctx.getEntitiesForTable(rootTable);
|
|
7160
|
+
const keys = collectKeysFromRoots(roots, localKey);
|
|
7161
|
+
if (!keys.size) {
|
|
7162
|
+
return /* @__PURE__ */ new Map();
|
|
7163
|
+
}
|
|
7164
|
+
const fkColumn = relation.target.columns[relation.idField];
|
|
7165
|
+
if (!fkColumn) return /* @__PURE__ */ new Map();
|
|
7166
|
+
const requestedColumns = hasColumns(options?.columns) ? [...options.columns] : void 0;
|
|
7167
|
+
const targetPrimaryKey = findPrimaryKey(relation.target);
|
|
7168
|
+
const selectedColumns = requestedColumns ? [...requestedColumns] : Object.keys(relation.target.columns);
|
|
7169
|
+
if (!selectedColumns.includes(targetPrimaryKey)) {
|
|
7170
|
+
selectedColumns.push(targetPrimaryKey);
|
|
7171
|
+
}
|
|
7172
|
+
const queryColumns = new Set(selectedColumns);
|
|
7173
|
+
queryColumns.add(relation.idField);
|
|
7174
|
+
const selection = buildColumnSelection(
|
|
7175
|
+
relation.target,
|
|
7176
|
+
Array.from(queryColumns),
|
|
7177
|
+
(column) => `Column '${column}' not found on relation '${relationName}'`
|
|
7178
|
+
);
|
|
7179
|
+
const typeColumn = relation.target.columns[relation.typeField];
|
|
7180
|
+
const discriminatorFilter = eq(
|
|
7181
|
+
typeColumn ?? { type: "Column", table: relation.target.name, name: relation.typeField },
|
|
7182
|
+
{ type: "Literal", value: relation.typeValue }
|
|
7183
|
+
);
|
|
7184
|
+
const combinedFilter = options?.filter ? and(options.filter, discriminatorFilter) : discriminatorFilter;
|
|
7185
|
+
const rows = await fetchRowsForKeys(ctx, relation.target, fkColumn, keys, selection, combinedFilter);
|
|
7186
|
+
const grouped = groupRowsByUnique(rows, relation.idField);
|
|
7187
|
+
if (!requestedColumns) return grouped;
|
|
7188
|
+
const visibleColumns = new Set(selectedColumns);
|
|
7189
|
+
const filtered = /* @__PURE__ */ new Map();
|
|
7190
|
+
for (const [key, row] of grouped.entries()) {
|
|
7191
|
+
filtered.set(key, filterRow(row, visibleColumns));
|
|
7192
|
+
}
|
|
7193
|
+
return filtered;
|
|
7194
|
+
};
|
|
7195
|
+
|
|
7196
|
+
// src/orm/lazy-batch/morph-many.ts
|
|
7197
|
+
var loadMorphManyRelation = async (ctx, rootTable, relationName, relation, options) => {
|
|
7198
|
+
const localKey = relation.localKey || findPrimaryKey(rootTable);
|
|
7199
|
+
const roots = ctx.getEntitiesForTable(rootTable);
|
|
7200
|
+
const keys = collectKeysFromRoots(roots, localKey);
|
|
7201
|
+
if (!keys.size) {
|
|
7202
|
+
return /* @__PURE__ */ new Map();
|
|
7203
|
+
}
|
|
7204
|
+
const fkColumn = relation.target.columns[relation.idField];
|
|
7205
|
+
if (!fkColumn) return /* @__PURE__ */ new Map();
|
|
7206
|
+
const requestedColumns = hasColumns(options?.columns) ? [...options.columns] : void 0;
|
|
7207
|
+
const targetPrimaryKey = findPrimaryKey(relation.target);
|
|
7208
|
+
const selectedColumns = requestedColumns ? [...requestedColumns] : Object.keys(relation.target.columns);
|
|
7209
|
+
if (!selectedColumns.includes(targetPrimaryKey)) {
|
|
7210
|
+
selectedColumns.push(targetPrimaryKey);
|
|
7211
|
+
}
|
|
7212
|
+
const queryColumns = new Set(selectedColumns);
|
|
7213
|
+
queryColumns.add(relation.idField);
|
|
7214
|
+
const selection = buildColumnSelection(
|
|
7215
|
+
relation.target,
|
|
7216
|
+
Array.from(queryColumns),
|
|
7217
|
+
(column) => `Column '${column}' not found on relation '${relationName}'`
|
|
7218
|
+
);
|
|
7219
|
+
const typeColumn = relation.target.columns[relation.typeField];
|
|
7220
|
+
const discriminatorFilter = eq(
|
|
7221
|
+
typeColumn ?? { type: "Column", table: relation.target.name, name: relation.typeField },
|
|
7222
|
+
{ type: "Literal", value: relation.typeValue }
|
|
7223
|
+
);
|
|
7224
|
+
const combinedFilter = options?.filter ? and(options.filter, discriminatorFilter) : discriminatorFilter;
|
|
7225
|
+
const rows = await fetchRowsForKeys(ctx, relation.target, fkColumn, keys, selection, combinedFilter);
|
|
7226
|
+
const grouped = groupRowsByMany(rows, relation.idField);
|
|
7227
|
+
if (!requestedColumns) return grouped;
|
|
7228
|
+
const visibleColumns = new Set(selectedColumns);
|
|
7229
|
+
const filtered = /* @__PURE__ */ new Map();
|
|
7230
|
+
for (const [key, bucket] of grouped.entries()) {
|
|
7231
|
+
filtered.set(key, filterRows(bucket, visibleColumns));
|
|
7232
|
+
}
|
|
7233
|
+
return filtered;
|
|
7234
|
+
};
|
|
7235
|
+
|
|
7236
|
+
// src/orm/lazy-batch/morph-to.ts
|
|
7237
|
+
var loadMorphToRelation = async (ctx, rootTable, _relationName, relation) => {
|
|
7238
|
+
const roots = ctx.getEntitiesForTable(rootTable);
|
|
7239
|
+
const result = /* @__PURE__ */ new Map();
|
|
7240
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
7241
|
+
for (const tracked of roots) {
|
|
7242
|
+
const entity = tracked.entity;
|
|
7243
|
+
const typeValue = entity[relation.typeField];
|
|
7244
|
+
const idValue = entity[relation.idField];
|
|
7245
|
+
if (!typeValue || idValue === void 0 || idValue === null) continue;
|
|
7246
|
+
const typeKey = toKey10(typeValue);
|
|
7247
|
+
const ids = grouped.get(typeKey) ?? /* @__PURE__ */ new Set();
|
|
7248
|
+
ids.add(idValue);
|
|
7249
|
+
grouped.set(typeKey, ids);
|
|
7250
|
+
}
|
|
7251
|
+
for (const [typeKey, ids] of grouped.entries()) {
|
|
7252
|
+
const targetTable = relation.targets[typeKey];
|
|
7253
|
+
if (!targetTable) continue;
|
|
7254
|
+
const targetPk = relation.targetKey || findPrimaryKey(targetTable);
|
|
7255
|
+
const pkColumn = targetTable.columns[targetPk];
|
|
7256
|
+
if (!pkColumn) continue;
|
|
7257
|
+
const selection = buildColumnSelection(
|
|
7258
|
+
targetTable,
|
|
7259
|
+
Object.keys(targetTable.columns),
|
|
7260
|
+
(column) => `Column '${column}' not found on target '${targetTable.name}'`
|
|
7261
|
+
);
|
|
7262
|
+
const rows = await fetchRowsForKeys(ctx, targetTable, pkColumn, ids, selection);
|
|
7263
|
+
for (const row of rows) {
|
|
7264
|
+
const pkValue = row[targetPk];
|
|
7265
|
+
if (pkValue === void 0 || pkValue === null) continue;
|
|
7266
|
+
const compositeKey = `${typeKey}:${toKey10(pkValue)}`;
|
|
7267
|
+
result.set(compositeKey, row);
|
|
7268
|
+
}
|
|
7269
|
+
}
|
|
7270
|
+
return result;
|
|
7271
|
+
};
|
|
7272
|
+
|
|
6526
7273
|
// src/orm/entity-relation-cache.ts
|
|
6527
7274
|
var relationLoaderCache = (meta, relationName, factory) => {
|
|
6528
7275
|
if (meta.relationCache.has(relationName)) {
|
|
@@ -6627,65 +7374,119 @@ var instantiateWrapper = (meta, relationName, relation, owner, createEntity) =>
|
|
|
6627
7374
|
metaBase,
|
|
6628
7375
|
owner,
|
|
6629
7376
|
relationName,
|
|
6630
|
-
hasOne2,
|
|
7377
|
+
hasOne2,
|
|
7378
|
+
meta.table,
|
|
7379
|
+
loader,
|
|
7380
|
+
(row) => createEntity(hasOne2.target, row),
|
|
7381
|
+
localKey
|
|
7382
|
+
);
|
|
7383
|
+
}
|
|
7384
|
+
case RelationKinds.HasMany: {
|
|
7385
|
+
const hasMany2 = relation;
|
|
7386
|
+
const localKey = hasMany2.localKey || findPrimaryKey(meta.table);
|
|
7387
|
+
const loader = () => loadCached(
|
|
7388
|
+
() => loadHasManyRelation(meta.ctx, meta.table, relationName, hasMany2, resolveOptions())
|
|
7389
|
+
);
|
|
7390
|
+
return new DefaultHasManyCollection(
|
|
7391
|
+
meta.ctx,
|
|
7392
|
+
metaBase,
|
|
7393
|
+
owner,
|
|
7394
|
+
relationName,
|
|
7395
|
+
hasMany2,
|
|
7396
|
+
meta.table,
|
|
7397
|
+
loader,
|
|
7398
|
+
(row) => createEntity(relation.target, row),
|
|
7399
|
+
localKey
|
|
7400
|
+
);
|
|
7401
|
+
}
|
|
7402
|
+
case RelationKinds.BelongsTo: {
|
|
7403
|
+
const belongsTo2 = relation;
|
|
7404
|
+
const targetKey = belongsTo2.localKey || findPrimaryKey(belongsTo2.target);
|
|
7405
|
+
const loader = () => loadCached(
|
|
7406
|
+
() => loadBelongsToRelation(meta.ctx, meta.table, relationName, belongsTo2, resolveOptions())
|
|
7407
|
+
);
|
|
7408
|
+
return new DefaultBelongsToReference(
|
|
7409
|
+
meta.ctx,
|
|
7410
|
+
metaBase,
|
|
7411
|
+
owner,
|
|
7412
|
+
relationName,
|
|
7413
|
+
belongsTo2,
|
|
7414
|
+
meta.table,
|
|
7415
|
+
loader,
|
|
7416
|
+
(row) => createEntity(relation.target, row),
|
|
7417
|
+
targetKey
|
|
7418
|
+
);
|
|
7419
|
+
}
|
|
7420
|
+
case RelationKinds.BelongsToMany: {
|
|
7421
|
+
const many = relation;
|
|
7422
|
+
const localKey = many.localKey || findPrimaryKey(meta.table);
|
|
7423
|
+
const loader = () => loadCached(
|
|
7424
|
+
() => loadBelongsToManyRelation(meta.ctx, meta.table, relationName, many, resolveOptions())
|
|
7425
|
+
);
|
|
7426
|
+
return new DefaultManyToManyCollection(
|
|
7427
|
+
meta.ctx,
|
|
7428
|
+
metaBase,
|
|
7429
|
+
owner,
|
|
7430
|
+
relationName,
|
|
7431
|
+
many,
|
|
6631
7432
|
meta.table,
|
|
6632
7433
|
loader,
|
|
6633
|
-
(row) => createEntity(
|
|
7434
|
+
(row) => createEntity(relation.target, row),
|
|
6634
7435
|
localKey
|
|
6635
7436
|
);
|
|
6636
7437
|
}
|
|
6637
|
-
case RelationKinds.
|
|
6638
|
-
const
|
|
6639
|
-
const localKey =
|
|
7438
|
+
case RelationKinds.MorphOne: {
|
|
7439
|
+
const morphOne2 = relation;
|
|
7440
|
+
const localKey = morphOne2.localKey || findPrimaryKey(meta.table);
|
|
6640
7441
|
const loader = () => loadCached(
|
|
6641
|
-
() =>
|
|
7442
|
+
() => loadMorphOneRelation(meta.ctx, meta.table, relationName, morphOne2, resolveOptions())
|
|
6642
7443
|
);
|
|
6643
|
-
return new
|
|
7444
|
+
return new DefaultMorphOneReference(
|
|
6644
7445
|
meta.ctx,
|
|
6645
7446
|
metaBase,
|
|
6646
7447
|
owner,
|
|
6647
7448
|
relationName,
|
|
6648
|
-
|
|
7449
|
+
morphOne2,
|
|
6649
7450
|
meta.table,
|
|
6650
7451
|
loader,
|
|
6651
|
-
(row) => createEntity(
|
|
7452
|
+
(row) => createEntity(morphOne2.target, row),
|
|
6652
7453
|
localKey
|
|
6653
7454
|
);
|
|
6654
7455
|
}
|
|
6655
|
-
case RelationKinds.
|
|
6656
|
-
const
|
|
6657
|
-
const
|
|
7456
|
+
case RelationKinds.MorphMany: {
|
|
7457
|
+
const morphMany2 = relation;
|
|
7458
|
+
const localKey = morphMany2.localKey || findPrimaryKey(meta.table);
|
|
6658
7459
|
const loader = () => loadCached(
|
|
6659
|
-
() =>
|
|
7460
|
+
() => loadMorphManyRelation(meta.ctx, meta.table, relationName, morphMany2, resolveOptions())
|
|
6660
7461
|
);
|
|
6661
|
-
return new
|
|
7462
|
+
return new DefaultMorphManyCollection(
|
|
6662
7463
|
meta.ctx,
|
|
6663
7464
|
metaBase,
|
|
6664
7465
|
owner,
|
|
6665
7466
|
relationName,
|
|
6666
|
-
|
|
7467
|
+
morphMany2,
|
|
6667
7468
|
meta.table,
|
|
6668
7469
|
loader,
|
|
6669
|
-
(row) => createEntity(
|
|
6670
|
-
|
|
7470
|
+
(row) => createEntity(morphMany2.target, row),
|
|
7471
|
+
localKey
|
|
6671
7472
|
);
|
|
6672
7473
|
}
|
|
6673
|
-
case RelationKinds.
|
|
6674
|
-
const
|
|
6675
|
-
const localKey = many.localKey || findPrimaryKey(meta.table);
|
|
7474
|
+
case RelationKinds.MorphTo: {
|
|
7475
|
+
const morphTo2 = relation;
|
|
6676
7476
|
const loader = () => loadCached(
|
|
6677
|
-
() =>
|
|
7477
|
+
() => loadMorphToRelation(meta.ctx, meta.table, relationName, morphTo2)
|
|
6678
7478
|
);
|
|
6679
|
-
|
|
7479
|
+
const resolveTargetTable = (typeValue) => morphTo2.targets[typeValue];
|
|
7480
|
+
return new DefaultMorphToReference(
|
|
6680
7481
|
meta.ctx,
|
|
6681
7482
|
metaBase,
|
|
6682
7483
|
owner,
|
|
6683
7484
|
relationName,
|
|
6684
|
-
|
|
7485
|
+
morphTo2,
|
|
6685
7486
|
meta.table,
|
|
6686
7487
|
loader,
|
|
6687
|
-
(row) => createEntity(
|
|
6688
|
-
|
|
7488
|
+
(table, row) => createEntity(table, row),
|
|
7489
|
+
resolveTargetTable
|
|
6689
7490
|
);
|
|
6690
7491
|
}
|
|
6691
7492
|
default:
|
|
@@ -6713,7 +7514,7 @@ var createEntityProxy = (ctx, table, row, lazyRelations = [], lazyRelationOption
|
|
|
6713
7514
|
const isCollectionRelation = (relationName) => {
|
|
6714
7515
|
const rel = table.relations[relationName];
|
|
6715
7516
|
if (!rel) return false;
|
|
6716
|
-
return rel.type === RelationKinds.HasMany || rel.type === RelationKinds.BelongsToMany;
|
|
7517
|
+
return rel.type === RelationKinds.HasMany || rel.type === RelationKinds.BelongsToMany || rel.type === RelationKinds.MorphMany;
|
|
6717
7518
|
};
|
|
6718
7519
|
const buildJson = (self, options) => {
|
|
6719
7520
|
const json = {};
|
|
@@ -6895,9 +7696,11 @@ function rowsToQueryResult(rows) {
|
|
|
6895
7696
|
}
|
|
6896
7697
|
function createExecutorFromQueryRunner(runner) {
|
|
6897
7698
|
const supportsTransactions = typeof runner.beginTransaction === "function" && typeof runner.commitTransaction === "function" && typeof runner.rollbackTransaction === "function";
|
|
7699
|
+
const supportsSavepoints = supportsTransactions && typeof runner.savepoint === "function" && typeof runner.releaseSavepoint === "function" && typeof runner.rollbackToSavepoint === "function";
|
|
6898
7700
|
return {
|
|
6899
7701
|
capabilities: {
|
|
6900
|
-
transactions: supportsTransactions
|
|
7702
|
+
transactions: supportsTransactions,
|
|
7703
|
+
...supportsSavepoints ? { savepoints: true } : {}
|
|
6901
7704
|
},
|
|
6902
7705
|
async executeSql(sql, params) {
|
|
6903
7706
|
const rows = await runner.query(sql, params);
|
|
@@ -6922,6 +7725,24 @@ function createExecutorFromQueryRunner(runner) {
|
|
|
6922
7725
|
}
|
|
6923
7726
|
await runner.rollbackTransaction.call(runner);
|
|
6924
7727
|
},
|
|
7728
|
+
async savepoint(name) {
|
|
7729
|
+
if (!supportsSavepoints) {
|
|
7730
|
+
throw new Error("Savepoints are not supported by this executor");
|
|
7731
|
+
}
|
|
7732
|
+
await runner.savepoint.call(runner, name);
|
|
7733
|
+
},
|
|
7734
|
+
async releaseSavepoint(name) {
|
|
7735
|
+
if (!supportsSavepoints) {
|
|
7736
|
+
throw new Error("Savepoints are not supported by this executor");
|
|
7737
|
+
}
|
|
7738
|
+
await runner.releaseSavepoint.call(runner, name);
|
|
7739
|
+
},
|
|
7740
|
+
async rollbackToSavepoint(name) {
|
|
7741
|
+
if (!supportsSavepoints) {
|
|
7742
|
+
throw new Error("Savepoints are not supported by this executor");
|
|
7743
|
+
}
|
|
7744
|
+
await runner.rollbackToSavepoint.call(runner, name);
|
|
7745
|
+
},
|
|
6925
7746
|
async dispose() {
|
|
6926
7747
|
await runner.dispose?.call(runner);
|
|
6927
7748
|
}
|
|
@@ -7296,6 +8117,9 @@ function buildWhereHasPredicate(env, context, relationFacet, createChildBuilder,
|
|
|
7296
8117
|
}
|
|
7297
8118
|
const callback = typeof callbackOrOptions === "function" ? callbackOrOptions : void 0;
|
|
7298
8119
|
const options = typeof callbackOrOptions === "function" ? maybeOptions : callbackOrOptions;
|
|
8120
|
+
if (!isSingleTargetRelation(relation)) {
|
|
8121
|
+
throw new Error(`Polymorphic relation '${relationName}' does not support whereHas/whereHasNot`);
|
|
8122
|
+
}
|
|
7299
8123
|
let subQb = createChildBuilder(relation.target);
|
|
7300
8124
|
if (callback) {
|
|
7301
8125
|
subQb = callback(subQb);
|
|
@@ -8882,6 +9706,7 @@ var isTableDef = (value) => {
|
|
|
8882
9706
|
|
|
8883
9707
|
// src/decorators/decorator-metadata.ts
|
|
8884
9708
|
var METADATA_KEY = "metal-orm:decorators";
|
|
9709
|
+
var LEGACY_METADATA_KEY = /* @__PURE__ */ Symbol.for("metal-orm:decorators:legacy");
|
|
8885
9710
|
var getOrCreateMetadataBag = (context) => {
|
|
8886
9711
|
const metadata = context.metadata || (context.metadata = {});
|
|
8887
9712
|
let bag = metadata[METADATA_KEY];
|
|
@@ -8891,16 +9716,65 @@ var getOrCreateMetadataBag = (context) => {
|
|
|
8891
9716
|
}
|
|
8892
9717
|
return bag;
|
|
8893
9718
|
};
|
|
9719
|
+
var getOrCreateMetadataBagOnConstructor = (ctor) => {
|
|
9720
|
+
const carrier = ctor;
|
|
9721
|
+
let bag = carrier[LEGACY_METADATA_KEY];
|
|
9722
|
+
if (!bag) {
|
|
9723
|
+
bag = { columns: [], relations: [], transformers: [] };
|
|
9724
|
+
carrier[LEGACY_METADATA_KEY] = bag;
|
|
9725
|
+
}
|
|
9726
|
+
return bag;
|
|
9727
|
+
};
|
|
8894
9728
|
var readMetadataBag = (context) => {
|
|
8895
9729
|
return context.metadata?.[METADATA_KEY];
|
|
8896
9730
|
};
|
|
8897
9731
|
var readMetadataBagFromConstructor = (ctor) => {
|
|
8898
9732
|
const metadataSymbol = Symbol.metadata;
|
|
8899
|
-
if (
|
|
8900
|
-
|
|
8901
|
-
|
|
9733
|
+
if (metadataSymbol) {
|
|
9734
|
+
const metadata = Reflect.get(ctor, metadataSymbol);
|
|
9735
|
+
const stage3Bag = metadata?.[METADATA_KEY];
|
|
9736
|
+
if (stage3Bag) {
|
|
9737
|
+
return stage3Bag;
|
|
9738
|
+
}
|
|
9739
|
+
}
|
|
9740
|
+
return ctor[LEGACY_METADATA_KEY];
|
|
8902
9741
|
};
|
|
8903
9742
|
var getDecoratorMetadata = (ctor) => readMetadataBagFromConstructor(ctor);
|
|
9743
|
+
var normalizePropertyName = (name) => {
|
|
9744
|
+
if (typeof name === "symbol") {
|
|
9745
|
+
return name.description ?? name.toString();
|
|
9746
|
+
}
|
|
9747
|
+
return name;
|
|
9748
|
+
};
|
|
9749
|
+
var isStage3FieldContext = (value) => {
|
|
9750
|
+
return typeof value === "object" && value !== null && "name" in value && "private" in value && "metadata" in value;
|
|
9751
|
+
};
|
|
9752
|
+
var resolveFieldDecoratorInfo = (targetOrValue, contextOrProperty, decoratorName) => {
|
|
9753
|
+
if (isStage3FieldContext(contextOrProperty)) {
|
|
9754
|
+
if (!contextOrProperty.name) {
|
|
9755
|
+
throw new Error(`${decoratorName} decorator requires a property name`);
|
|
9756
|
+
}
|
|
9757
|
+
if (contextOrProperty.private) {
|
|
9758
|
+
throw new Error(`${decoratorName} decorator does not support private fields`);
|
|
9759
|
+
}
|
|
9760
|
+
return {
|
|
9761
|
+
propertyName: normalizePropertyName(contextOrProperty.name),
|
|
9762
|
+
bag: getOrCreateMetadataBag(contextOrProperty)
|
|
9763
|
+
};
|
|
9764
|
+
}
|
|
9765
|
+
if (typeof contextOrProperty === "string" || typeof contextOrProperty === "symbol") {
|
|
9766
|
+
const legacyTarget = targetOrValue;
|
|
9767
|
+
const ctor = typeof legacyTarget === "function" ? legacyTarget : legacyTarget?.constructor;
|
|
9768
|
+
if (!ctor || typeof ctor !== "function" && typeof ctor !== "object") {
|
|
9769
|
+
throw new Error(`${decoratorName} decorator requires a class field target`);
|
|
9770
|
+
}
|
|
9771
|
+
return {
|
|
9772
|
+
propertyName: normalizePropertyName(contextOrProperty),
|
|
9773
|
+
bag: getOrCreateMetadataBagOnConstructor(ctor)
|
|
9774
|
+
};
|
|
9775
|
+
}
|
|
9776
|
+
throw new Error(`${decoratorName} decorator received an unsupported decorator context`);
|
|
9777
|
+
};
|
|
8904
9778
|
|
|
8905
9779
|
// src/decorators/bootstrap.ts
|
|
8906
9780
|
var unwrapTarget = (target) => {
|
|
@@ -8990,6 +9864,48 @@ var buildRelationDefinitions = (meta, tableMap) => {
|
|
|
8990
9864
|
);
|
|
8991
9865
|
break;
|
|
8992
9866
|
}
|
|
9867
|
+
case RelationKinds.MorphOne: {
|
|
9868
|
+
relations[name] = morphOne(
|
|
9869
|
+
resolveTableTarget(relation.target, tableMap),
|
|
9870
|
+
{
|
|
9871
|
+
as: relation.morphName,
|
|
9872
|
+
typeValue: relation.typeValue,
|
|
9873
|
+
typeField: relation.typeField,
|
|
9874
|
+
idField: relation.idField,
|
|
9875
|
+
localKey: relation.localKey,
|
|
9876
|
+
cascade: relation.cascade
|
|
9877
|
+
}
|
|
9878
|
+
);
|
|
9879
|
+
break;
|
|
9880
|
+
}
|
|
9881
|
+
case RelationKinds.MorphMany: {
|
|
9882
|
+
relations[name] = morphMany(
|
|
9883
|
+
resolveTableTarget(relation.target, tableMap),
|
|
9884
|
+
{
|
|
9885
|
+
as: relation.morphName,
|
|
9886
|
+
typeValue: relation.typeValue,
|
|
9887
|
+
typeField: relation.typeField,
|
|
9888
|
+
idField: relation.idField,
|
|
9889
|
+
localKey: relation.localKey,
|
|
9890
|
+
cascade: relation.cascade
|
|
9891
|
+
}
|
|
9892
|
+
);
|
|
9893
|
+
break;
|
|
9894
|
+
}
|
|
9895
|
+
case RelationKinds.MorphTo: {
|
|
9896
|
+
const resolvedTargets = {};
|
|
9897
|
+
for (const [typeValue, targetResolver] of Object.entries(relation.targets)) {
|
|
9898
|
+
resolvedTargets[typeValue] = resolveTableTarget(targetResolver, tableMap);
|
|
9899
|
+
}
|
|
9900
|
+
relations[name] = morphTo({
|
|
9901
|
+
typeField: relation.typeField,
|
|
9902
|
+
idField: relation.idField,
|
|
9903
|
+
targets: resolvedTargets,
|
|
9904
|
+
targetKey: relation.targetKey,
|
|
9905
|
+
cascade: relation.cascade
|
|
9906
|
+
});
|
|
9907
|
+
break;
|
|
9908
|
+
}
|
|
8993
9909
|
}
|
|
8994
9910
|
}
|
|
8995
9911
|
return relations;
|
|
@@ -9063,6 +9979,45 @@ var resolveSingleRelation = (relationName, relation, rootMeta) => {
|
|
|
9063
9979
|
}
|
|
9064
9980
|
);
|
|
9065
9981
|
}
|
|
9982
|
+
case RelationKinds.MorphOne: {
|
|
9983
|
+
return morphOne(
|
|
9984
|
+
resolveTableTarget(relation.target, tableMap),
|
|
9985
|
+
{
|
|
9986
|
+
as: relation.morphName,
|
|
9987
|
+
typeValue: relation.typeValue,
|
|
9988
|
+
typeField: relation.typeField,
|
|
9989
|
+
idField: relation.idField,
|
|
9990
|
+
localKey: relation.localKey,
|
|
9991
|
+
cascade: relation.cascade
|
|
9992
|
+
}
|
|
9993
|
+
);
|
|
9994
|
+
}
|
|
9995
|
+
case RelationKinds.MorphMany: {
|
|
9996
|
+
return morphMany(
|
|
9997
|
+
resolveTableTarget(relation.target, tableMap),
|
|
9998
|
+
{
|
|
9999
|
+
as: relation.morphName,
|
|
10000
|
+
typeValue: relation.typeValue,
|
|
10001
|
+
typeField: relation.typeField,
|
|
10002
|
+
idField: relation.idField,
|
|
10003
|
+
localKey: relation.localKey,
|
|
10004
|
+
cascade: relation.cascade
|
|
10005
|
+
}
|
|
10006
|
+
);
|
|
10007
|
+
}
|
|
10008
|
+
case RelationKinds.MorphTo: {
|
|
10009
|
+
const resolvedTargets = {};
|
|
10010
|
+
for (const [typeValue, targetResolver] of Object.entries(relation.targets)) {
|
|
10011
|
+
resolvedTargets[typeValue] = resolveTableTarget(targetResolver, tableMap);
|
|
10012
|
+
}
|
|
10013
|
+
return morphTo({
|
|
10014
|
+
typeField: relation.typeField,
|
|
10015
|
+
idField: relation.idField,
|
|
10016
|
+
targets: resolvedTargets,
|
|
10017
|
+
targetKey: relation.targetKey,
|
|
10018
|
+
cascade: relation.cascade
|
|
10019
|
+
});
|
|
10020
|
+
}
|
|
9066
10021
|
default:
|
|
9067
10022
|
throw new Error(`Unknown relation kind for relation '${relationName}'`);
|
|
9068
10023
|
}
|
|
@@ -10966,6 +11921,25 @@ var databaseFunction = {
|
|
|
10966
11921
|
fn: "DATABASE",
|
|
10967
11922
|
args: []
|
|
10968
11923
|
};
|
|
11924
|
+
var readMysqlField = (row, field) => {
|
|
11925
|
+
const record = row;
|
|
11926
|
+
if (Object.prototype.hasOwnProperty.call(record, field)) {
|
|
11927
|
+
return record[field];
|
|
11928
|
+
}
|
|
11929
|
+
const lower2 = field.toLowerCase();
|
|
11930
|
+
if (lower2 !== field && Object.prototype.hasOwnProperty.call(record, lower2)) {
|
|
11931
|
+
return record[lower2];
|
|
11932
|
+
}
|
|
11933
|
+
const upper2 = field.toUpperCase();
|
|
11934
|
+
if (upper2 !== field && Object.prototype.hasOwnProperty.call(record, upper2)) {
|
|
11935
|
+
return record[upper2];
|
|
11936
|
+
}
|
|
11937
|
+
return void 0;
|
|
11938
|
+
};
|
|
11939
|
+
var readMysqlStringField = (row, field) => {
|
|
11940
|
+
const value = readMysqlField(row, field);
|
|
11941
|
+
return typeof value === "string" ? value : void 0;
|
|
11942
|
+
};
|
|
10969
11943
|
var mysqlIntrospector = {
|
|
10970
11944
|
async introspect(ctx, options) {
|
|
10971
11945
|
const schema = options.schema;
|
|
@@ -11107,39 +12081,68 @@ var mysqlIntrospector = {
|
|
|
11107
12081
|
const indexRows = await runSelectNode(indexQuery, ctx);
|
|
11108
12082
|
const tableComments = /* @__PURE__ */ new Map();
|
|
11109
12083
|
tableRows.forEach((r) => {
|
|
11110
|
-
const
|
|
11111
|
-
|
|
11112
|
-
|
|
12084
|
+
const tableSchema = readMysqlStringField(r, "table_schema");
|
|
12085
|
+
const tableName = readMysqlStringField(r, "table_name");
|
|
12086
|
+
const tableComment = readMysqlStringField(r, "table_comment");
|
|
12087
|
+
if (!tableSchema || !tableName) return;
|
|
12088
|
+
const key = `${tableSchema}.${tableName}`;
|
|
12089
|
+
if (tableComment) {
|
|
12090
|
+
tableComments.set(key, tableComment);
|
|
11113
12091
|
}
|
|
11114
12092
|
});
|
|
11115
12093
|
const pkMap = /* @__PURE__ */ new Map();
|
|
11116
12094
|
pkRows.forEach((r) => {
|
|
11117
|
-
const
|
|
12095
|
+
const tableSchema = readMysqlStringField(r, "table_schema");
|
|
12096
|
+
const tableName = readMysqlStringField(r, "table_name");
|
|
12097
|
+
const columnName = readMysqlStringField(r, "column_name");
|
|
12098
|
+
if (!tableSchema || !tableName || !columnName) return;
|
|
12099
|
+
const key = `${tableSchema}.${tableName}`;
|
|
11118
12100
|
const list = pkMap.get(key) || [];
|
|
11119
|
-
list.push(
|
|
12101
|
+
list.push(columnName);
|
|
11120
12102
|
pkMap.set(key, list);
|
|
11121
12103
|
});
|
|
11122
12104
|
const fkMap = /* @__PURE__ */ new Map();
|
|
11123
12105
|
fkRows.forEach((r) => {
|
|
11124
|
-
const
|
|
12106
|
+
const tableSchema = readMysqlStringField(r, "table_schema");
|
|
12107
|
+
const tableName = readMysqlStringField(r, "table_name");
|
|
12108
|
+
const columnName = readMysqlStringField(r, "column_name");
|
|
12109
|
+
const constraintName = readMysqlStringField(r, "constraint_name");
|
|
12110
|
+
const referencedTableSchema = readMysqlStringField(r, "referenced_table_schema");
|
|
12111
|
+
const referencedTableName = readMysqlStringField(r, "referenced_table_name");
|
|
12112
|
+
const referencedColumnName = readMysqlStringField(r, "referenced_column_name");
|
|
12113
|
+
const deleteRule = readMysqlStringField(r, "delete_rule");
|
|
12114
|
+
const updateRule = readMysqlStringField(r, "update_rule");
|
|
12115
|
+
if (!tableSchema || !tableName || !columnName || !constraintName || !referencedTableSchema || !referencedTableName || !referencedColumnName) {
|
|
12116
|
+
return;
|
|
12117
|
+
}
|
|
12118
|
+
const key = `${tableSchema}.${tableName}.${columnName}`;
|
|
11125
12119
|
const list = fkMap.get(key) || [];
|
|
11126
12120
|
list.push({
|
|
11127
|
-
table: `${
|
|
11128
|
-
column:
|
|
11129
|
-
onDelete:
|
|
11130
|
-
onUpdate:
|
|
11131
|
-
name:
|
|
12121
|
+
table: `${referencedTableSchema}.${referencedTableName}`,
|
|
12122
|
+
column: referencedColumnName,
|
|
12123
|
+
onDelete: deleteRule,
|
|
12124
|
+
onUpdate: updateRule,
|
|
12125
|
+
name: constraintName
|
|
11132
12126
|
});
|
|
11133
12127
|
fkMap.set(key, list);
|
|
11134
12128
|
});
|
|
11135
12129
|
const tablesByKey = /* @__PURE__ */ new Map();
|
|
11136
12130
|
columnRows.forEach((r) => {
|
|
11137
|
-
const
|
|
11138
|
-
|
|
12131
|
+
const tableSchema = readMysqlStringField(r, "table_schema");
|
|
12132
|
+
const tableName = readMysqlStringField(r, "table_name");
|
|
12133
|
+
const columnName = readMysqlStringField(r, "column_name");
|
|
12134
|
+
const columnType = readMysqlStringField(r, "column_type") || readMysqlStringField(r, "data_type");
|
|
12135
|
+
const isNullable = readMysqlStringField(r, "is_nullable");
|
|
12136
|
+
const columnDefault = readMysqlField(r, "column_default");
|
|
12137
|
+
const extra = readMysqlStringField(r, "extra");
|
|
12138
|
+
const columnComment = readMysqlStringField(r, "column_comment");
|
|
12139
|
+
if (!tableSchema || !tableName || !columnName || !columnType || !isNullable) return;
|
|
12140
|
+
const key = `${tableSchema}.${tableName}`;
|
|
12141
|
+
if (!shouldIncludeTable(tableName, options)) return;
|
|
11139
12142
|
if (!tablesByKey.has(key)) {
|
|
11140
12143
|
tablesByKey.set(key, {
|
|
11141
|
-
name:
|
|
11142
|
-
schema:
|
|
12144
|
+
name: tableName,
|
|
12145
|
+
schema: tableSchema,
|
|
11143
12146
|
columns: [],
|
|
11144
12147
|
primaryKey: pkMap.get(key) || [],
|
|
11145
12148
|
indexes: [],
|
|
@@ -11147,17 +12150,16 @@ var mysqlIntrospector = {
|
|
|
11147
12150
|
});
|
|
11148
12151
|
}
|
|
11149
12152
|
const table = tablesByKey.get(key);
|
|
11150
|
-
const
|
|
11151
|
-
const comment = r.column_comment?.trim() ? r.column_comment : void 0;
|
|
12153
|
+
const comment = columnComment?.trim() ? columnComment : void 0;
|
|
11152
12154
|
const column = {
|
|
11153
|
-
name:
|
|
12155
|
+
name: columnName,
|
|
11154
12156
|
type: columnType,
|
|
11155
|
-
notNull:
|
|
11156
|
-
default:
|
|
11157
|
-
autoIncrement: typeof
|
|
12157
|
+
notNull: isNullable === "NO",
|
|
12158
|
+
default: columnDefault ?? void 0,
|
|
12159
|
+
autoIncrement: typeof extra === "string" && extra.includes("auto_increment"),
|
|
11158
12160
|
comment
|
|
11159
12161
|
};
|
|
11160
|
-
const fk = fkMap.get(`${key}.${
|
|
12162
|
+
const fk = fkMap.get(`${key}.${columnName}`)?.[0];
|
|
11161
12163
|
if (fk) {
|
|
11162
12164
|
column.references = {
|
|
11163
12165
|
table: fk.table,
|
|
@@ -11170,14 +12172,20 @@ var mysqlIntrospector = {
|
|
|
11170
12172
|
table.columns.push(column);
|
|
11171
12173
|
});
|
|
11172
12174
|
indexRows.forEach((r) => {
|
|
11173
|
-
const
|
|
12175
|
+
const tableSchema = readMysqlStringField(r, "table_schema");
|
|
12176
|
+
const tableName = readMysqlStringField(r, "table_name");
|
|
12177
|
+
const indexName = readMysqlStringField(r, "index_name");
|
|
12178
|
+
const nonUnique = readMysqlField(r, "non_unique");
|
|
12179
|
+
const colsValue = readMysqlField(r, "cols");
|
|
12180
|
+
if (!tableSchema || !tableName || !indexName) return;
|
|
12181
|
+
const key = `${tableSchema}.${tableName}`;
|
|
11174
12182
|
const table = tablesByKey.get(key);
|
|
11175
12183
|
if (!table) return;
|
|
11176
|
-
const cols = (typeof
|
|
12184
|
+
const cols = (typeof colsValue === "string" ? colsValue.split(",") : []).map((c) => ({ column: c.trim() }));
|
|
11177
12185
|
const idx = {
|
|
11178
|
-
name:
|
|
12186
|
+
name: indexName,
|
|
11179
12187
|
columns: cols,
|
|
11180
|
-
unique:
|
|
12188
|
+
unique: Number(nonUnique) === 0
|
|
11181
12189
|
};
|
|
11182
12190
|
table.indexes = table.indexes || [];
|
|
11183
12191
|
table.indexes.push(idx);
|
|
@@ -11239,25 +12247,35 @@ var mysqlIntrospector = {
|
|
|
11239
12247
|
const viewColumnRows = await runSelectNode(viewColumnsQuery, ctx);
|
|
11240
12248
|
const viewsByKey = /* @__PURE__ */ new Map();
|
|
11241
12249
|
for (const r of viewRows) {
|
|
11242
|
-
|
|
11243
|
-
const
|
|
12250
|
+
const tableSchema = readMysqlStringField(r, "table_schema");
|
|
12251
|
+
const tableName = readMysqlStringField(r, "table_name");
|
|
12252
|
+
const viewDefinition = readMysqlStringField(r, "view_definition");
|
|
12253
|
+
if (!tableSchema || !tableName) continue;
|
|
12254
|
+
if (!shouldIncludeView(tableName, options)) continue;
|
|
12255
|
+
const key = `${tableSchema}.${tableName}`;
|
|
11244
12256
|
viewsByKey.set(key, {
|
|
11245
|
-
name:
|
|
11246
|
-
schema:
|
|
12257
|
+
name: tableName,
|
|
12258
|
+
schema: tableSchema,
|
|
11247
12259
|
columns: [],
|
|
11248
|
-
definition:
|
|
12260
|
+
definition: viewDefinition || void 0
|
|
11249
12261
|
});
|
|
11250
12262
|
}
|
|
11251
12263
|
for (const r of viewColumnRows) {
|
|
11252
|
-
const
|
|
12264
|
+
const tableSchema = readMysqlStringField(r, "table_schema");
|
|
12265
|
+
const tableName = readMysqlStringField(r, "table_name");
|
|
12266
|
+
const columnName = readMysqlStringField(r, "column_name");
|
|
12267
|
+
const columnType = readMysqlStringField(r, "column_type") || readMysqlStringField(r, "data_type");
|
|
12268
|
+
const isNullable = readMysqlStringField(r, "is_nullable");
|
|
12269
|
+
const columnComment = readMysqlStringField(r, "column_comment");
|
|
12270
|
+
if (!tableSchema || !tableName || !columnName || !columnType || !isNullable) continue;
|
|
12271
|
+
const key = `${tableSchema}.${tableName}`;
|
|
11253
12272
|
const view = viewsByKey.get(key);
|
|
11254
12273
|
if (!view) continue;
|
|
11255
|
-
const columnType = r.column_type || r.data_type;
|
|
11256
12274
|
const column = {
|
|
11257
|
-
name:
|
|
12275
|
+
name: columnName,
|
|
11258
12276
|
type: columnType,
|
|
11259
|
-
notNull:
|
|
11260
|
-
comment:
|
|
12277
|
+
notNull: isNullable === "NO",
|
|
12278
|
+
comment: columnComment?.trim() || void 0
|
|
11261
12279
|
};
|
|
11262
12280
|
view.columns.push(column);
|
|
11263
12281
|
}
|
|
@@ -12652,6 +13670,9 @@ var TypeScriptGenerator = class {
|
|
|
12652
13670
|
visitLogicalExpression(logical) {
|
|
12653
13671
|
return this.printLogicalExpression(logical);
|
|
12654
13672
|
}
|
|
13673
|
+
visitNotExpression(notExpr) {
|
|
13674
|
+
return this.printNotExpression(notExpr);
|
|
13675
|
+
}
|
|
12655
13676
|
visitNullExpression(nullExpr) {
|
|
12656
13677
|
return this.printNullExpression(nullExpr);
|
|
12657
13678
|
}
|
|
@@ -12727,6 +13748,9 @@ var TypeScriptGenerator = class {
|
|
|
12727
13748
|
${parts.join(",\n ")}
|
|
12728
13749
|
)`;
|
|
12729
13750
|
}
|
|
13751
|
+
printNotExpression(notExpr) {
|
|
13752
|
+
return `not(${this.printExpression(notExpr.operand)})`;
|
|
13753
|
+
}
|
|
12730
13754
|
printArithmeticExpression(expr) {
|
|
12731
13755
|
const left2 = this.printOperand(expr.left);
|
|
12732
13756
|
const right2 = this.printOperand(expr.right);
|
|
@@ -13420,6 +14444,15 @@ var RelationChangeProcessor = class {
|
|
|
13420
14444
|
case RelationKinds.BelongsTo:
|
|
13421
14445
|
await this.handleBelongsToChange(entry);
|
|
13422
14446
|
break;
|
|
14447
|
+
case RelationKinds.MorphOne:
|
|
14448
|
+
await this.handleMorphOneChange(entry);
|
|
14449
|
+
break;
|
|
14450
|
+
case RelationKinds.MorphMany:
|
|
14451
|
+
await this.handleMorphManyChange(entry);
|
|
14452
|
+
break;
|
|
14453
|
+
case RelationKinds.MorphTo:
|
|
14454
|
+
await this.handleMorphToChange(entry);
|
|
14455
|
+
break;
|
|
13423
14456
|
}
|
|
13424
14457
|
}
|
|
13425
14458
|
}
|
|
@@ -13622,6 +14655,86 @@ var RelationChangeProcessor = class {
|
|
|
13622
14655
|
}
|
|
13623
14656
|
return Object.keys(payload).length ? payload : void 0;
|
|
13624
14657
|
}
|
|
14658
|
+
async handleMorphOneChange(entry) {
|
|
14659
|
+
const relation = entry.relation;
|
|
14660
|
+
const target = entry.change.entity;
|
|
14661
|
+
if (!target) return;
|
|
14662
|
+
const tracked = this.unitOfWork.findTracked(target);
|
|
14663
|
+
if (!tracked) return;
|
|
14664
|
+
const localKey = relation.localKey || findPrimaryKey(entry.rootTable);
|
|
14665
|
+
const rootValue = entry.root[localKey];
|
|
14666
|
+
if (rootValue === void 0 || rootValue === null) return;
|
|
14667
|
+
if (entry.change.kind === "add" || entry.change.kind === "attach") {
|
|
14668
|
+
const child = tracked.entity;
|
|
14669
|
+
child[relation.idField] = rootValue;
|
|
14670
|
+
child[relation.typeField] = relation.typeValue;
|
|
14671
|
+
this.unitOfWork.markDirty(tracked.entity);
|
|
14672
|
+
return;
|
|
14673
|
+
}
|
|
14674
|
+
if (entry.change.kind === "remove") {
|
|
14675
|
+
const child = tracked.entity;
|
|
14676
|
+
if (relation.cascade === "all" || relation.cascade === "remove") {
|
|
14677
|
+
this.unitOfWork.markRemoved(child);
|
|
14678
|
+
return;
|
|
14679
|
+
}
|
|
14680
|
+
child[relation.idField] = null;
|
|
14681
|
+
child[relation.typeField] = null;
|
|
14682
|
+
this.unitOfWork.markDirty(child);
|
|
14683
|
+
}
|
|
14684
|
+
}
|
|
14685
|
+
async handleMorphManyChange(entry) {
|
|
14686
|
+
const relation = entry.relation;
|
|
14687
|
+
const target = entry.change.entity;
|
|
14688
|
+
if (!target) return;
|
|
14689
|
+
const tracked = this.unitOfWork.findTracked(target);
|
|
14690
|
+
if (!tracked) return;
|
|
14691
|
+
const localKey = relation.localKey || findPrimaryKey(entry.rootTable);
|
|
14692
|
+
const rootValue = entry.root[localKey];
|
|
14693
|
+
if (rootValue === void 0 || rootValue === null) return;
|
|
14694
|
+
if (entry.change.kind === "add" || entry.change.kind === "attach") {
|
|
14695
|
+
const child = tracked.entity;
|
|
14696
|
+
child[relation.idField] = rootValue;
|
|
14697
|
+
child[relation.typeField] = relation.typeValue;
|
|
14698
|
+
this.unitOfWork.markDirty(tracked.entity);
|
|
14699
|
+
return;
|
|
14700
|
+
}
|
|
14701
|
+
if (entry.change.kind === "remove") {
|
|
14702
|
+
const child = tracked.entity;
|
|
14703
|
+
if (relation.cascade === "all" || relation.cascade === "remove") {
|
|
14704
|
+
this.unitOfWork.markRemoved(child);
|
|
14705
|
+
return;
|
|
14706
|
+
}
|
|
14707
|
+
child[relation.idField] = null;
|
|
14708
|
+
child[relation.typeField] = null;
|
|
14709
|
+
this.unitOfWork.markDirty(child);
|
|
14710
|
+
}
|
|
14711
|
+
}
|
|
14712
|
+
async handleMorphToChange(entry) {
|
|
14713
|
+
const relation = entry.relation;
|
|
14714
|
+
const target = entry.change.entity;
|
|
14715
|
+
if (!target) return;
|
|
14716
|
+
if (entry.change.kind === "attach" || entry.change.kind === "add") {
|
|
14717
|
+
const targetEntity = target;
|
|
14718
|
+
for (const [typeValue, targetTable] of Object.entries(relation.targets)) {
|
|
14719
|
+
const targetPk = relation.targetKey || findPrimaryKey(targetTable);
|
|
14720
|
+
const pkValue = targetEntity[targetPk];
|
|
14721
|
+
if (pkValue !== void 0 && pkValue !== null) {
|
|
14722
|
+
const rootEntity = entry.root;
|
|
14723
|
+
rootEntity[relation.typeField] = typeValue;
|
|
14724
|
+
rootEntity[relation.idField] = pkValue;
|
|
14725
|
+
this.unitOfWork.markDirty(entry.root);
|
|
14726
|
+
break;
|
|
14727
|
+
}
|
|
14728
|
+
}
|
|
14729
|
+
return;
|
|
14730
|
+
}
|
|
14731
|
+
if (entry.change.kind === "remove") {
|
|
14732
|
+
const rootEntity = entry.root;
|
|
14733
|
+
rootEntity[relation.typeField] = null;
|
|
14734
|
+
rootEntity[relation.idField] = null;
|
|
14735
|
+
this.unitOfWork.markDirty(entry.root);
|
|
14736
|
+
}
|
|
14737
|
+
}
|
|
13625
14738
|
};
|
|
13626
14739
|
|
|
13627
14740
|
// src/orm/query-logger.ts
|
|
@@ -13638,6 +14751,9 @@ var createQueryLoggingExecutor = (executor, logger) => {
|
|
|
13638
14751
|
beginTransaction: () => executor.beginTransaction(),
|
|
13639
14752
|
commitTransaction: () => executor.commitTransaction(),
|
|
13640
14753
|
rollbackTransaction: () => executor.rollbackTransaction(),
|
|
14754
|
+
savepoint: executor.savepoint ? (name) => executor.savepoint(name) : void 0,
|
|
14755
|
+
releaseSavepoint: executor.releaseSavepoint ? (name) => executor.releaseSavepoint(name) : void 0,
|
|
14756
|
+
rollbackToSavepoint: executor.rollbackToSavepoint ? (name) => executor.rollbackToSavepoint(name) : void 0,
|
|
13641
14757
|
dispose: () => executor.dispose()
|
|
13642
14758
|
};
|
|
13643
14759
|
return wrapped;
|
|
@@ -13660,7 +14776,7 @@ var runInTransaction = async (executor, action) => {
|
|
|
13660
14776
|
};
|
|
13661
14777
|
|
|
13662
14778
|
// src/orm/save-graph.ts
|
|
13663
|
-
var
|
|
14779
|
+
var toKey11 = (value) => value === null || value === void 0 ? "" : String(value);
|
|
13664
14780
|
var coerceColumnValue = (table, columnName, value, options) => {
|
|
13665
14781
|
if (value === null || value === void 0) return value;
|
|
13666
14782
|
const column = table.columns[columnName];
|
|
@@ -13722,11 +14838,11 @@ var isEntityInCollection = (items, pkName, entity) => {
|
|
|
13722
14838
|
if (items.includes(entity)) return true;
|
|
13723
14839
|
const entityPk = entity[pkName];
|
|
13724
14840
|
if (entityPk === void 0 || entityPk === null) return false;
|
|
13725
|
-
return items.some((item) =>
|
|
14841
|
+
return items.some((item) => toKey11(item[pkName]) === toKey11(entityPk));
|
|
13726
14842
|
};
|
|
13727
14843
|
var findInCollectionByPk = (items, pkName, pkValue) => {
|
|
13728
14844
|
if (pkValue === void 0 || pkValue === null) return void 0;
|
|
13729
|
-
return items.find((item) =>
|
|
14845
|
+
return items.find((item) => toKey11(item[pkName]) === toKey11(pkValue));
|
|
13730
14846
|
};
|
|
13731
14847
|
var extractPivotPayload = (payload) => {
|
|
13732
14848
|
const pivot = payload._pivot ?? payload.pivot;
|
|
@@ -13755,13 +14871,13 @@ var handleHasMany = async (session, root, relationName, relation, payload, optio
|
|
|
13755
14871
|
collection.attach(entity);
|
|
13756
14872
|
}
|
|
13757
14873
|
if (pkValue !== void 0 && pkValue !== null) {
|
|
13758
|
-
seen.add(
|
|
14874
|
+
seen.add(toKey11(pkValue));
|
|
13759
14875
|
}
|
|
13760
14876
|
}
|
|
13761
14877
|
if (options.pruneMissing) {
|
|
13762
14878
|
for (const item of [...collection.getItems()]) {
|
|
13763
14879
|
const pkValue = item[targetPk];
|
|
13764
|
-
if (pkValue !== void 0 && pkValue !== null && !seen.has(
|
|
14880
|
+
if (pkValue !== void 0 && pkValue !== null && !seen.has(toKey11(pkValue))) {
|
|
13765
14881
|
collection.remove(item);
|
|
13766
14882
|
}
|
|
13767
14883
|
}
|
|
@@ -13819,7 +14935,7 @@ var handleBelongsToMany = async (session, root, relationName, relation, payload,
|
|
|
13819
14935
|
if (typeof item === "number" || typeof item === "string") {
|
|
13820
14936
|
const id = item;
|
|
13821
14937
|
collection.attach(id);
|
|
13822
|
-
seen.add(
|
|
14938
|
+
seen.add(toKey11(id));
|
|
13823
14939
|
continue;
|
|
13824
14940
|
}
|
|
13825
14941
|
const asObj = item;
|
|
@@ -13837,18 +14953,89 @@ var handleBelongsToMany = async (session, root, relationName, relation, payload,
|
|
|
13837
14953
|
collection.attach(entity, pivotPayload);
|
|
13838
14954
|
}
|
|
13839
14955
|
if (pkValue !== void 0 && pkValue !== null) {
|
|
13840
|
-
seen.add(
|
|
14956
|
+
seen.add(toKey11(pkValue));
|
|
13841
14957
|
}
|
|
13842
14958
|
}
|
|
13843
14959
|
if (options.pruneMissing) {
|
|
13844
14960
|
for (const item of [...collection.getItems()]) {
|
|
13845
14961
|
const pkValue = item[targetPk];
|
|
13846
|
-
if (pkValue !== void 0 && pkValue !== null && !seen.has(
|
|
14962
|
+
if (pkValue !== void 0 && pkValue !== null && !seen.has(toKey11(pkValue))) {
|
|
13847
14963
|
collection.detach(item);
|
|
13848
14964
|
}
|
|
13849
14965
|
}
|
|
13850
14966
|
}
|
|
13851
14967
|
};
|
|
14968
|
+
var handleMorphOne = async (session, root, relationName, relation, payload, options) => {
|
|
14969
|
+
const ref = root[relationName];
|
|
14970
|
+
if (payload === void 0) return;
|
|
14971
|
+
if (payload === null) {
|
|
14972
|
+
ref.set(null);
|
|
14973
|
+
return;
|
|
14974
|
+
}
|
|
14975
|
+
const pk = findPrimaryKey(relation.target);
|
|
14976
|
+
if (typeof payload === "number" || typeof payload === "string") {
|
|
14977
|
+
const entity = ref.set({ [pk]: payload });
|
|
14978
|
+
if (entity) {
|
|
14979
|
+
await applyGraphToEntity(session, relation.target, entity, { [pk]: payload }, options);
|
|
14980
|
+
}
|
|
14981
|
+
return;
|
|
14982
|
+
}
|
|
14983
|
+
const attached = ref.set(payload);
|
|
14984
|
+
if (attached) {
|
|
14985
|
+
await applyGraphToEntity(session, relation.target, attached, payload, options);
|
|
14986
|
+
}
|
|
14987
|
+
};
|
|
14988
|
+
var handleMorphMany = async (session, root, relationName, relation, payload, options) => {
|
|
14989
|
+
if (!Array.isArray(payload)) return;
|
|
14990
|
+
const collection = root[relationName];
|
|
14991
|
+
await collection.load();
|
|
14992
|
+
const targetTable = relation.target;
|
|
14993
|
+
const targetPk = findPrimaryKey(targetTable);
|
|
14994
|
+
const existing = collection.getItems();
|
|
14995
|
+
const seen = /* @__PURE__ */ new Set();
|
|
14996
|
+
for (const item of payload) {
|
|
14997
|
+
if (item === null || item === void 0) continue;
|
|
14998
|
+
const asObj = typeof item === "object" ? item : { [targetPk]: item };
|
|
14999
|
+
const pkValue = asObj[targetPk];
|
|
15000
|
+
const current = findInCollectionByPk(existing, targetPk, pkValue) ?? (pkValue !== void 0 && pkValue !== null ? session.getEntity(targetTable, pkValue) : void 0);
|
|
15001
|
+
const entity = current ?? ensureEntity(session, targetTable, asObj, options);
|
|
15002
|
+
assignColumns(targetTable, entity, asObj, options);
|
|
15003
|
+
await applyGraphToEntity(session, targetTable, entity, asObj, options);
|
|
15004
|
+
if (!isEntityInCollection(collection.getItems(), targetPk, entity)) {
|
|
15005
|
+
collection.attach(entity);
|
|
15006
|
+
}
|
|
15007
|
+
if (pkValue !== void 0 && pkValue !== null) {
|
|
15008
|
+
seen.add(toKey11(pkValue));
|
|
15009
|
+
}
|
|
15010
|
+
}
|
|
15011
|
+
if (options.pruneMissing) {
|
|
15012
|
+
for (const item of [...collection.getItems()]) {
|
|
15013
|
+
const pkValue = item[targetPk];
|
|
15014
|
+
if (pkValue !== void 0 && pkValue !== null && !seen.has(toKey11(pkValue))) {
|
|
15015
|
+
collection.remove(item);
|
|
15016
|
+
}
|
|
15017
|
+
}
|
|
15018
|
+
}
|
|
15019
|
+
};
|
|
15020
|
+
var handleMorphTo = async (session, root, relationName, relation, payload, options) => {
|
|
15021
|
+
const ref = root[relationName];
|
|
15022
|
+
if (payload === void 0) return;
|
|
15023
|
+
if (payload === null) {
|
|
15024
|
+
ref.set(null);
|
|
15025
|
+
return;
|
|
15026
|
+
}
|
|
15027
|
+
const attached = ref.set(payload);
|
|
15028
|
+
if (attached) {
|
|
15029
|
+
for (const [, targetTable] of Object.entries(relation.targets)) {
|
|
15030
|
+
const pk = relation.targetKey || findPrimaryKey(targetTable);
|
|
15031
|
+
const pkValue = attached[pk];
|
|
15032
|
+
if (pkValue !== void 0 && pkValue !== null) {
|
|
15033
|
+
await applyGraphToEntity(session, targetTable, attached, payload, options);
|
|
15034
|
+
break;
|
|
15035
|
+
}
|
|
15036
|
+
}
|
|
15037
|
+
}
|
|
15038
|
+
};
|
|
13852
15039
|
var applyRelation = async (session, table, entity, relationName, relation, payload, options) => {
|
|
13853
15040
|
switch (relation.type) {
|
|
13854
15041
|
case RelationKinds.HasMany:
|
|
@@ -13859,6 +15046,12 @@ var applyRelation = async (session, table, entity, relationName, relation, paylo
|
|
|
13859
15046
|
return handleBelongsTo(session, entity, relationName, relation, payload, options);
|
|
13860
15047
|
case RelationKinds.BelongsToMany:
|
|
13861
15048
|
return handleBelongsToMany(session, entity, relationName, relation, payload, options);
|
|
15049
|
+
case RelationKinds.MorphOne:
|
|
15050
|
+
return handleMorphOne(session, entity, relationName, relation, payload, options);
|
|
15051
|
+
case RelationKinds.MorphMany:
|
|
15052
|
+
return handleMorphMany(session, entity, relationName, relation, payload, options);
|
|
15053
|
+
case RelationKinds.MorphTo:
|
|
15054
|
+
return handleMorphTo(session, entity, relationName, relation, payload, options);
|
|
13862
15055
|
}
|
|
13863
15056
|
};
|
|
13864
15057
|
var applyGraphToEntity = async (session, table, entity, payload, options) => {
|
|
@@ -13887,6 +15080,8 @@ var patchGraphInternal = async (session, entityClass, existing, payload, options
|
|
|
13887
15080
|
};
|
|
13888
15081
|
|
|
13889
15082
|
// src/orm/orm-session.ts
|
|
15083
|
+
var NESTED_TRANSACTIONS_REQUIRE_SAVEPOINTS = "Nested session.transaction calls require savepoint support in this executor";
|
|
15084
|
+
var ROLLBACK_ONLY_TRANSACTION = "Cannot commit transaction because an inner transaction failed";
|
|
13890
15085
|
var OrmSession = class {
|
|
13891
15086
|
/** The ORM instance */
|
|
13892
15087
|
orm;
|
|
@@ -13906,6 +15101,9 @@ var OrmSession = class {
|
|
|
13906
15101
|
tenantId;
|
|
13907
15102
|
interceptors;
|
|
13908
15103
|
saveGraphDefaults;
|
|
15104
|
+
transactionDepth = 0;
|
|
15105
|
+
savepointCounter = 0;
|
|
15106
|
+
rollbackOnly = false;
|
|
13909
15107
|
/**
|
|
13910
15108
|
* Creates a new OrmSession instance.
|
|
13911
15109
|
* @param opts - Session options
|
|
@@ -14248,16 +15446,43 @@ var OrmSession = class {
|
|
|
14248
15446
|
await this.commit();
|
|
14249
15447
|
return result;
|
|
14250
15448
|
}
|
|
14251
|
-
|
|
15449
|
+
const isOutermost = this.transactionDepth === 0;
|
|
15450
|
+
let savepointName = null;
|
|
15451
|
+
if (isOutermost) {
|
|
15452
|
+
this.rollbackOnly = false;
|
|
15453
|
+
await this.executor.beginTransaction();
|
|
15454
|
+
} else {
|
|
15455
|
+
this.assertSavepointSupport();
|
|
15456
|
+
savepointName = this.nextSavepointName();
|
|
15457
|
+
await this.executor.savepoint(savepointName);
|
|
15458
|
+
}
|
|
15459
|
+
this.transactionDepth += 1;
|
|
14252
15460
|
try {
|
|
14253
15461
|
const result = await fn8(this);
|
|
15462
|
+
this.throwIfRollbackOnly();
|
|
14254
15463
|
await this.flushWithHooks();
|
|
14255
|
-
|
|
14256
|
-
|
|
15464
|
+
this.throwIfRollbackOnly();
|
|
15465
|
+
if (isOutermost) {
|
|
15466
|
+
await this.executor.commitTransaction();
|
|
15467
|
+
await this.domainEvents.dispatch(this.unitOfWork.getTracked(), this);
|
|
15468
|
+
} else {
|
|
15469
|
+
await this.executor.releaseSavepoint(savepointName);
|
|
15470
|
+
}
|
|
14257
15471
|
return result;
|
|
14258
15472
|
} catch (err) {
|
|
14259
|
-
|
|
15473
|
+
if (isOutermost) {
|
|
15474
|
+
await this.rollback();
|
|
15475
|
+
} else {
|
|
15476
|
+
this.rollbackOnly = true;
|
|
15477
|
+
await this.executor.rollbackToSavepoint(savepointName);
|
|
15478
|
+
}
|
|
14260
15479
|
throw err;
|
|
15480
|
+
} finally {
|
|
15481
|
+
this.transactionDepth = Math.max(0, this.transactionDepth - 1);
|
|
15482
|
+
if (this.transactionDepth === 0) {
|
|
15483
|
+
this.rollbackOnly = false;
|
|
15484
|
+
this.savepointCounter = 0;
|
|
15485
|
+
}
|
|
14261
15486
|
}
|
|
14262
15487
|
}
|
|
14263
15488
|
/**
|
|
@@ -14267,6 +15492,9 @@ var OrmSession = class {
|
|
|
14267
15492
|
if (this.executor.capabilities.transactions) {
|
|
14268
15493
|
await this.executor.rollbackTransaction();
|
|
14269
15494
|
}
|
|
15495
|
+
this.transactionDepth = 0;
|
|
15496
|
+
this.savepointCounter = 0;
|
|
15497
|
+
this.rollbackOnly = false;
|
|
14270
15498
|
this.unitOfWork.reset();
|
|
14271
15499
|
this.relationChanges.reset();
|
|
14272
15500
|
}
|
|
@@ -14341,6 +15569,23 @@ var OrmSession = class {
|
|
|
14341
15569
|
resolveSaveGraphOptions(options) {
|
|
14342
15570
|
return { ...this.saveGraphDefaults ?? {}, ...options ?? {} };
|
|
14343
15571
|
}
|
|
15572
|
+
assertSavepointSupport() {
|
|
15573
|
+
if (!this.executor.capabilities.savepoints) {
|
|
15574
|
+
throw new Error(NESTED_TRANSACTIONS_REQUIRE_SAVEPOINTS);
|
|
15575
|
+
}
|
|
15576
|
+
if (typeof this.executor.savepoint !== "function" || typeof this.executor.releaseSavepoint !== "function" || typeof this.executor.rollbackToSavepoint !== "function") {
|
|
15577
|
+
throw new Error(NESTED_TRANSACTIONS_REQUIRE_SAVEPOINTS);
|
|
15578
|
+
}
|
|
15579
|
+
}
|
|
15580
|
+
nextSavepointName() {
|
|
15581
|
+
this.savepointCounter += 1;
|
|
15582
|
+
return `metalorm_sp_${this.savepointCounter}`;
|
|
15583
|
+
}
|
|
15584
|
+
throwIfRollbackOnly() {
|
|
15585
|
+
if (this.rollbackOnly) {
|
|
15586
|
+
throw new Error(ROLLBACK_ONLY_TRANSACTION);
|
|
15587
|
+
}
|
|
15588
|
+
}
|
|
14344
15589
|
};
|
|
14345
15590
|
var buildRelationChangeEntry = (root, relationKey, rootTable, relationName, relation, change) => ({
|
|
14346
15591
|
root,
|
|
@@ -14865,7 +16110,7 @@ var TREE_METADATA_KEY = /* @__PURE__ */ Symbol("metal-orm:tree");
|
|
|
14865
16110
|
function Tree(options = {}) {
|
|
14866
16111
|
return function(target, context) {
|
|
14867
16112
|
const config = resolveTreeConfig(options);
|
|
14868
|
-
const metadataBag = readMetadataBag(context) ?? readMetadataBagFromConstructor(target);
|
|
16113
|
+
const metadataBag = context ? readMetadataBag(context) ?? readMetadataBagFromConstructor(target) : readMetadataBagFromConstructor(target);
|
|
14869
16114
|
const metadata = {
|
|
14870
16115
|
config,
|
|
14871
16116
|
parentProperty: metadataBag?.tree?.parentProperty,
|
|
@@ -14877,28 +16122,22 @@ function Tree(options = {}) {
|
|
|
14877
16122
|
};
|
|
14878
16123
|
}
|
|
14879
16124
|
function TreeParent() {
|
|
14880
|
-
return function(
|
|
14881
|
-
|
|
14882
|
-
|
|
14883
|
-
|
|
14884
|
-
|
|
14885
|
-
|
|
14886
|
-
}
|
|
14887
|
-
const propertyName = String(context.name);
|
|
14888
|
-
const bag = getOrCreateMetadataBag(context);
|
|
16125
|
+
return function(targetOrValue, contextOrProperty) {
|
|
16126
|
+
const { propertyName, bag } = resolveFieldDecoratorInfo(
|
|
16127
|
+
targetOrValue,
|
|
16128
|
+
contextOrProperty,
|
|
16129
|
+
"TreeParent"
|
|
16130
|
+
);
|
|
14889
16131
|
bag.tree = { ...bag.tree, parentProperty: propertyName };
|
|
14890
16132
|
};
|
|
14891
16133
|
}
|
|
14892
16134
|
function TreeChildren() {
|
|
14893
|
-
return function(
|
|
14894
|
-
|
|
14895
|
-
|
|
14896
|
-
|
|
14897
|
-
|
|
14898
|
-
|
|
14899
|
-
}
|
|
14900
|
-
const propertyName = String(context.name);
|
|
14901
|
-
const bag = getOrCreateMetadataBag(context);
|
|
16135
|
+
return function(targetOrValue, contextOrProperty) {
|
|
16136
|
+
const { propertyName, bag } = resolveFieldDecoratorInfo(
|
|
16137
|
+
targetOrValue,
|
|
16138
|
+
contextOrProperty,
|
|
16139
|
+
"TreeChildren"
|
|
16140
|
+
);
|
|
14902
16141
|
bag.tree = { ...bag.tree, childrenProperty: propertyName };
|
|
14903
16142
|
};
|
|
14904
16143
|
}
|
|
@@ -15062,7 +16301,7 @@ function Entity(options = {}) {
|
|
|
15062
16301
|
const ctor = value;
|
|
15063
16302
|
const tableName = options.tableName ?? deriveTableNameFromConstructor(ctor);
|
|
15064
16303
|
setEntityTableName(ctor, tableName, options.hooks, options.type);
|
|
15065
|
-
const bag = readMetadataBag(context);
|
|
16304
|
+
const bag = context ? readMetadataBag(context) : readMetadataBagFromConstructor(ctor);
|
|
15066
16305
|
if (bag) {
|
|
15067
16306
|
const meta = ensureEntityMetadata(ctor);
|
|
15068
16307
|
for (const entry of bag.columns) {
|
|
@@ -15116,29 +16355,20 @@ var normalizeColumnInput = (input) => {
|
|
|
15116
16355
|
}
|
|
15117
16356
|
return column;
|
|
15118
16357
|
};
|
|
15119
|
-
var
|
|
15120
|
-
|
|
15121
|
-
|
|
15122
|
-
|
|
15123
|
-
|
|
15124
|
-
|
|
15125
|
-
var registerColumnFromContext = (context, column) => {
|
|
15126
|
-
if (!context.name) {
|
|
15127
|
-
throw new Error("Column decorator requires a property name");
|
|
15128
|
-
}
|
|
15129
|
-
if (context.private) {
|
|
15130
|
-
throw new Error("Column decorator does not support private fields");
|
|
15131
|
-
}
|
|
15132
|
-
const propertyName = normalizePropertyName(context.name);
|
|
15133
|
-
const bag = getOrCreateMetadataBag(context);
|
|
16358
|
+
var registerColumnFromContext = (targetOrValue, contextOrProperty, column) => {
|
|
16359
|
+
const { propertyName, bag } = resolveFieldDecoratorInfo(
|
|
16360
|
+
targetOrValue,
|
|
16361
|
+
contextOrProperty,
|
|
16362
|
+
"Column"
|
|
16363
|
+
);
|
|
15134
16364
|
if (!bag.columns.some((entry) => entry.propertyName === propertyName)) {
|
|
15135
16365
|
bag.columns.push({ propertyName, column: { ...column } });
|
|
15136
16366
|
}
|
|
15137
16367
|
};
|
|
15138
16368
|
function Column(definition) {
|
|
15139
16369
|
const normalized = normalizeColumnInput(definition);
|
|
15140
|
-
return function(
|
|
15141
|
-
registerColumnFromContext(
|
|
16370
|
+
return function(targetOrValue, contextOrProperty) {
|
|
16371
|
+
registerColumnFromContext(targetOrValue, contextOrProperty, normalized);
|
|
15142
16372
|
};
|
|
15143
16373
|
}
|
|
15144
16374
|
function PrimaryKey(definition) {
|
|
@@ -15148,22 +16378,13 @@ function PrimaryKey(definition) {
|
|
|
15148
16378
|
}
|
|
15149
16379
|
|
|
15150
16380
|
// src/decorators/relations.ts
|
|
15151
|
-
var normalizePropertyName2 = (name) => {
|
|
15152
|
-
if (typeof name === "symbol") {
|
|
15153
|
-
return name.description ?? name.toString();
|
|
15154
|
-
}
|
|
15155
|
-
return name;
|
|
15156
|
-
};
|
|
15157
16381
|
var createFieldDecorator = (metadataFactory) => {
|
|
15158
|
-
return function(
|
|
15159
|
-
|
|
15160
|
-
|
|
15161
|
-
|
|
15162
|
-
|
|
15163
|
-
|
|
15164
|
-
}
|
|
15165
|
-
const propertyName = normalizePropertyName2(context.name);
|
|
15166
|
-
const bag = getOrCreateMetadataBag(context);
|
|
16382
|
+
return function(targetOrValue, contextOrProperty) {
|
|
16383
|
+
const { propertyName, bag } = resolveFieldDecoratorInfo(
|
|
16384
|
+
targetOrValue,
|
|
16385
|
+
contextOrProperty,
|
|
16386
|
+
"Relation"
|
|
16387
|
+
);
|
|
15167
16388
|
const relationMetadata = metadataFactory(propertyName);
|
|
15168
16389
|
if (!bag.relations.some((entry) => entry.propertyName === propertyName)) {
|
|
15169
16390
|
bag.relations.push({ propertyName, relation: relationMetadata });
|
|
@@ -15215,6 +16436,43 @@ function BelongsToMany(options) {
|
|
|
15215
16436
|
cascade: options.cascade
|
|
15216
16437
|
}));
|
|
15217
16438
|
}
|
|
16439
|
+
function MorphTo(options) {
|
|
16440
|
+
return createFieldDecorator((propertyName) => ({
|
|
16441
|
+
kind: RelationKinds.MorphTo,
|
|
16442
|
+
propertyKey: propertyName,
|
|
16443
|
+
typeField: options.typeField,
|
|
16444
|
+
idField: options.idField,
|
|
16445
|
+
targets: options.targets,
|
|
16446
|
+
targetKey: options.targetKey,
|
|
16447
|
+
cascade: options.cascade
|
|
16448
|
+
}));
|
|
16449
|
+
}
|
|
16450
|
+
function MorphOne(options) {
|
|
16451
|
+
return createFieldDecorator((propertyName) => ({
|
|
16452
|
+
kind: RelationKinds.MorphOne,
|
|
16453
|
+
propertyKey: propertyName,
|
|
16454
|
+
target: options.target,
|
|
16455
|
+
morphName: options.morphName,
|
|
16456
|
+
typeValue: options.typeValue,
|
|
16457
|
+
typeField: options.typeField,
|
|
16458
|
+
idField: options.idField,
|
|
16459
|
+
localKey: options.localKey,
|
|
16460
|
+
cascade: options.cascade
|
|
16461
|
+
}));
|
|
16462
|
+
}
|
|
16463
|
+
function MorphMany(options) {
|
|
16464
|
+
return createFieldDecorator((propertyName) => ({
|
|
16465
|
+
kind: RelationKinds.MorphMany,
|
|
16466
|
+
propertyKey: propertyName,
|
|
16467
|
+
target: options.target,
|
|
16468
|
+
morphName: options.morphName,
|
|
16469
|
+
typeValue: options.typeValue,
|
|
16470
|
+
typeField: options.typeField,
|
|
16471
|
+
idField: options.idField,
|
|
16472
|
+
localKey: options.localKey,
|
|
16473
|
+
cascade: options.cascade
|
|
16474
|
+
}));
|
|
16475
|
+
}
|
|
15218
16476
|
|
|
15219
16477
|
// src/decorators/transformers/built-in/string-transformers.ts
|
|
15220
16478
|
var TrimTransformer = class {
|
|
@@ -15400,15 +16658,12 @@ var PatternValidator = class {
|
|
|
15400
16658
|
};
|
|
15401
16659
|
|
|
15402
16660
|
// src/decorators/transformers/transformer-decorators.ts
|
|
15403
|
-
var
|
|
15404
|
-
|
|
15405
|
-
|
|
15406
|
-
|
|
15407
|
-
|
|
15408
|
-
|
|
15409
|
-
var registerTransformerMetadata = (context, metadata) => {
|
|
15410
|
-
const propertyName = normalizePropertyName3(context.name);
|
|
15411
|
-
const bag = getOrCreateMetadataBag(context);
|
|
16661
|
+
var registerTransformerMetadata = (targetOrValue, contextOrProperty, metadata) => {
|
|
16662
|
+
const { propertyName, bag } = resolveFieldDecoratorInfo(
|
|
16663
|
+
targetOrValue,
|
|
16664
|
+
contextOrProperty,
|
|
16665
|
+
"Transformer"
|
|
16666
|
+
);
|
|
15412
16667
|
let existing = bag.transformers.find((t) => t.propertyName === propertyName);
|
|
15413
16668
|
if (!existing) {
|
|
15414
16669
|
existing = {
|
|
@@ -15437,64 +16692,64 @@ var registerTransformerMetadata = (context, metadata) => {
|
|
|
15437
16692
|
}
|
|
15438
16693
|
};
|
|
15439
16694
|
function Trim(options) {
|
|
15440
|
-
return function(
|
|
15441
|
-
registerTransformerMetadata(
|
|
16695
|
+
return function(targetOrValue, contextOrProperty) {
|
|
16696
|
+
registerTransformerMetadata(targetOrValue, contextOrProperty, {
|
|
15442
16697
|
sanitizers: [new TrimTransformer(options)]
|
|
15443
16698
|
});
|
|
15444
16699
|
};
|
|
15445
16700
|
}
|
|
15446
16701
|
function Lower() {
|
|
15447
|
-
return function(
|
|
15448
|
-
registerTransformerMetadata(
|
|
16702
|
+
return function(targetOrValue, contextOrProperty) {
|
|
16703
|
+
registerTransformerMetadata(targetOrValue, contextOrProperty, {
|
|
15449
16704
|
sanitizers: [new CaseTransformer("lower")]
|
|
15450
16705
|
});
|
|
15451
16706
|
};
|
|
15452
16707
|
}
|
|
15453
16708
|
function Upper() {
|
|
15454
|
-
return function(
|
|
15455
|
-
registerTransformerMetadata(
|
|
16709
|
+
return function(targetOrValue, contextOrProperty) {
|
|
16710
|
+
registerTransformerMetadata(targetOrValue, contextOrProperty, {
|
|
15456
16711
|
sanitizers: [new CaseTransformer("upper")]
|
|
15457
16712
|
});
|
|
15458
16713
|
};
|
|
15459
16714
|
}
|
|
15460
16715
|
function Capitalize() {
|
|
15461
|
-
return function(
|
|
15462
|
-
registerTransformerMetadata(
|
|
16716
|
+
return function(targetOrValue, contextOrProperty) {
|
|
16717
|
+
registerTransformerMetadata(targetOrValue, contextOrProperty, {
|
|
15463
16718
|
sanitizers: [new CaseTransformer("capitalize")]
|
|
15464
16719
|
});
|
|
15465
16720
|
};
|
|
15466
16721
|
}
|
|
15467
16722
|
function Title() {
|
|
15468
|
-
return function(
|
|
15469
|
-
registerTransformerMetadata(
|
|
16723
|
+
return function(targetOrValue, contextOrProperty) {
|
|
16724
|
+
registerTransformerMetadata(targetOrValue, contextOrProperty, {
|
|
15470
16725
|
sanitizers: [new CaseTransformer("title")]
|
|
15471
16726
|
});
|
|
15472
16727
|
};
|
|
15473
16728
|
}
|
|
15474
16729
|
function Alphanumeric(options) {
|
|
15475
|
-
return function(
|
|
15476
|
-
registerTransformerMetadata(
|
|
16730
|
+
return function(targetOrValue, contextOrProperty) {
|
|
16731
|
+
registerTransformerMetadata(targetOrValue, contextOrProperty, {
|
|
15477
16732
|
validators: [new AlphanumericValidator(options)]
|
|
15478
16733
|
});
|
|
15479
16734
|
};
|
|
15480
16735
|
}
|
|
15481
16736
|
function Email(options) {
|
|
15482
|
-
return function(
|
|
15483
|
-
registerTransformerMetadata(
|
|
16737
|
+
return function(targetOrValue, contextOrProperty) {
|
|
16738
|
+
registerTransformerMetadata(targetOrValue, contextOrProperty, {
|
|
15484
16739
|
validators: [new EmailValidator(options)]
|
|
15485
16740
|
});
|
|
15486
16741
|
};
|
|
15487
16742
|
}
|
|
15488
16743
|
function Length(options) {
|
|
15489
|
-
return function(
|
|
15490
|
-
registerTransformerMetadata(
|
|
16744
|
+
return function(targetOrValue, contextOrProperty) {
|
|
16745
|
+
registerTransformerMetadata(targetOrValue, contextOrProperty, {
|
|
15491
16746
|
validators: [new LengthValidator(options)]
|
|
15492
16747
|
});
|
|
15493
16748
|
};
|
|
15494
16749
|
}
|
|
15495
16750
|
function Pattern(options) {
|
|
15496
|
-
return function(
|
|
15497
|
-
registerTransformerMetadata(
|
|
16751
|
+
return function(targetOrValue, contextOrProperty) {
|
|
16752
|
+
registerTransformerMetadata(targetOrValue, contextOrProperty, {
|
|
15498
16753
|
validators: [new PatternValidator(options)]
|
|
15499
16754
|
});
|
|
15500
16755
|
};
|
|
@@ -15721,16 +16976,12 @@ var CEPValidator = class {
|
|
|
15721
16976
|
registerValidator("BR", "cpf", () => new CPFValidator());
|
|
15722
16977
|
registerValidator("BR", "cnpj", () => new CNPJValidator());
|
|
15723
16978
|
registerValidator("BR", "cep", () => new CEPValidator());
|
|
15724
|
-
var
|
|
15725
|
-
|
|
15726
|
-
return name.description ?? name.toString();
|
|
15727
|
-
}
|
|
15728
|
-
return name;
|
|
16979
|
+
var resolveCountryDecoratorInfo = (targetOrValue, contextOrProperty) => {
|
|
16980
|
+
return resolveFieldDecoratorInfo(targetOrValue, contextOrProperty, "Country validator");
|
|
15729
16981
|
};
|
|
15730
16982
|
function CPF(options) {
|
|
15731
|
-
return function(
|
|
15732
|
-
const propertyName =
|
|
15733
|
-
const bag = getOrCreateMetadataBag(context);
|
|
16983
|
+
return function(targetOrValue, contextOrProperty) {
|
|
16984
|
+
const { propertyName, bag } = resolveCountryDecoratorInfo(targetOrValue, contextOrProperty);
|
|
15734
16985
|
let existing = bag.transformers.find((t) => t.propertyName === propertyName);
|
|
15735
16986
|
if (!existing) {
|
|
15736
16987
|
existing = {
|
|
@@ -15778,9 +17029,8 @@ function CPF(options) {
|
|
|
15778
17029
|
};
|
|
15779
17030
|
}
|
|
15780
17031
|
function CNPJ(options) {
|
|
15781
|
-
return function(
|
|
15782
|
-
const propertyName =
|
|
15783
|
-
const bag = getOrCreateMetadataBag(context);
|
|
17032
|
+
return function(targetOrValue, contextOrProperty) {
|
|
17033
|
+
const { propertyName, bag } = resolveCountryDecoratorInfo(targetOrValue, contextOrProperty);
|
|
15784
17034
|
let existing = bag.transformers.find((t) => t.propertyName === propertyName);
|
|
15785
17035
|
if (!existing) {
|
|
15786
17036
|
existing = {
|
|
@@ -15828,9 +17078,8 @@ function CNPJ(options) {
|
|
|
15828
17078
|
};
|
|
15829
17079
|
}
|
|
15830
17080
|
function CEP(options) {
|
|
15831
|
-
return function(
|
|
15832
|
-
const propertyName =
|
|
15833
|
-
const bag = getOrCreateMetadataBag(context);
|
|
17081
|
+
return function(targetOrValue, contextOrProperty) {
|
|
17082
|
+
const { propertyName, bag } = resolveCountryDecoratorInfo(targetOrValue, contextOrProperty);
|
|
15834
17083
|
let existing = bag.transformers.find((t) => t.propertyName === propertyName);
|
|
15835
17084
|
if (!existing) {
|
|
15836
17085
|
existing = {
|
|
@@ -16086,6 +17335,14 @@ var Pool = class {
|
|
|
16086
17335
|
};
|
|
16087
17336
|
|
|
16088
17337
|
// src/core/execution/executors/postgres-executor.ts
|
|
17338
|
+
var SAVEPOINT_NAME_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
17339
|
+
var sanitizeSavepointName = (name) => {
|
|
17340
|
+
const trimmed = name.trim();
|
|
17341
|
+
if (!SAVEPOINT_NAME_PATTERN.test(trimmed)) {
|
|
17342
|
+
throw new Error(`Invalid savepoint name: "${name}"`);
|
|
17343
|
+
}
|
|
17344
|
+
return trimmed;
|
|
17345
|
+
};
|
|
16089
17346
|
function createPostgresExecutor(client) {
|
|
16090
17347
|
return createExecutorFromQueryRunner({
|
|
16091
17348
|
async query(sql, params) {
|
|
@@ -16100,11 +17357,24 @@ function createPostgresExecutor(client) {
|
|
|
16100
17357
|
},
|
|
16101
17358
|
async rollbackTransaction() {
|
|
16102
17359
|
await client.query("ROLLBACK");
|
|
17360
|
+
},
|
|
17361
|
+
async savepoint(name) {
|
|
17362
|
+
const savepoint = sanitizeSavepointName(name);
|
|
17363
|
+
await client.query(`SAVEPOINT ${savepoint}`);
|
|
17364
|
+
},
|
|
17365
|
+
async releaseSavepoint(name) {
|
|
17366
|
+
const savepoint = sanitizeSavepointName(name);
|
|
17367
|
+
await client.query(`RELEASE SAVEPOINT ${savepoint}`);
|
|
17368
|
+
},
|
|
17369
|
+
async rollbackToSavepoint(name) {
|
|
17370
|
+
const savepoint = sanitizeSavepointName(name);
|
|
17371
|
+
await client.query(`ROLLBACK TO SAVEPOINT ${savepoint}`);
|
|
16103
17372
|
}
|
|
16104
17373
|
});
|
|
16105
17374
|
}
|
|
16106
17375
|
|
|
16107
17376
|
// src/core/execution/executors/mysql-executor.ts
|
|
17377
|
+
var SAVEPOINT_NAME_PATTERN2 = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
16108
17378
|
var isRowObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
16109
17379
|
var isRowObjectArray = (value) => Array.isArray(value) && value.every(isRowObject);
|
|
16110
17380
|
var isMysqlResultHeader = (value) => isRowObject(value) && ("affectedRows" in value || "insertId" in value || "warningStatus" in value || "serverStatus" in value);
|
|
@@ -16116,6 +17386,13 @@ var headerToQueryResult = (header) => ({
|
|
|
16116
17386
|
rowsAffected: header.affectedRows
|
|
16117
17387
|
}
|
|
16118
17388
|
});
|
|
17389
|
+
var sanitizeSavepointName2 = (name) => {
|
|
17390
|
+
const trimmed = name.trim();
|
|
17391
|
+
if (!SAVEPOINT_NAME_PATTERN2.test(trimmed)) {
|
|
17392
|
+
throw new Error(`Invalid savepoint name: "${name}"`);
|
|
17393
|
+
}
|
|
17394
|
+
return trimmed;
|
|
17395
|
+
};
|
|
16119
17396
|
var normalizeMysqlResults = (rows) => {
|
|
16120
17397
|
if (!Array.isArray(rows)) {
|
|
16121
17398
|
return isMysqlResultHeader(rows) ? [headerToQueryResult(rows)] : [rowsToQueryResult([])];
|
|
@@ -16137,9 +17414,11 @@ var normalizeMysqlResults = (rows) => {
|
|
|
16137
17414
|
};
|
|
16138
17415
|
function createMysqlExecutor(client) {
|
|
16139
17416
|
const supportsTransactions = typeof client.beginTransaction === "function" && typeof client.commit === "function" && typeof client.rollback === "function";
|
|
17417
|
+
const supportsSavepoints = supportsTransactions;
|
|
16140
17418
|
return {
|
|
16141
17419
|
capabilities: {
|
|
16142
|
-
transactions: supportsTransactions
|
|
17420
|
+
transactions: supportsTransactions,
|
|
17421
|
+
...supportsSavepoints ? { savepoints: true } : {}
|
|
16143
17422
|
},
|
|
16144
17423
|
async executeSql(sql, params) {
|
|
16145
17424
|
const [rows] = await client.query(sql, params);
|
|
@@ -16163,17 +17442,55 @@ function createMysqlExecutor(client) {
|
|
|
16163
17442
|
}
|
|
16164
17443
|
await client.rollback();
|
|
16165
17444
|
},
|
|
17445
|
+
async savepoint(name) {
|
|
17446
|
+
if (!supportsSavepoints) {
|
|
17447
|
+
throw new Error("Savepoints are not supported by this executor");
|
|
17448
|
+
}
|
|
17449
|
+
const savepoint = sanitizeSavepointName2(name);
|
|
17450
|
+
await client.query(`SAVEPOINT ${savepoint}`);
|
|
17451
|
+
},
|
|
17452
|
+
async releaseSavepoint(name) {
|
|
17453
|
+
if (!supportsSavepoints) {
|
|
17454
|
+
throw new Error("Savepoints are not supported by this executor");
|
|
17455
|
+
}
|
|
17456
|
+
const savepoint = sanitizeSavepointName2(name);
|
|
17457
|
+
await client.query(`RELEASE SAVEPOINT ${savepoint}`);
|
|
17458
|
+
},
|
|
17459
|
+
async rollbackToSavepoint(name) {
|
|
17460
|
+
if (!supportsSavepoints) {
|
|
17461
|
+
throw new Error("Savepoints are not supported by this executor");
|
|
17462
|
+
}
|
|
17463
|
+
const savepoint = sanitizeSavepointName2(name);
|
|
17464
|
+
await client.query(`ROLLBACK TO SAVEPOINT ${savepoint}`);
|
|
17465
|
+
},
|
|
16166
17466
|
async dispose() {
|
|
16167
17467
|
}
|
|
16168
17468
|
};
|
|
16169
17469
|
}
|
|
16170
17470
|
|
|
16171
17471
|
// src/core/execution/executors/sqlite-executor.ts
|
|
17472
|
+
var SAVEPOINT_NAME_PATTERN3 = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
17473
|
+
var sanitizeSavepointName3 = (name) => {
|
|
17474
|
+
const trimmed = name.trim();
|
|
17475
|
+
if (!SAVEPOINT_NAME_PATTERN3.test(trimmed)) {
|
|
17476
|
+
throw new Error(`Invalid savepoint name: "${name}"`);
|
|
17477
|
+
}
|
|
17478
|
+
return trimmed;
|
|
17479
|
+
};
|
|
16172
17480
|
function createSqliteExecutor(client) {
|
|
16173
17481
|
const supportsTransactions = typeof client.beginTransaction === "function" && typeof client.commitTransaction === "function" && typeof client.rollbackTransaction === "function";
|
|
17482
|
+
const supportsSavepoints = supportsTransactions;
|
|
17483
|
+
const executeControlStatement = async (sql) => {
|
|
17484
|
+
if (typeof client.run === "function") {
|
|
17485
|
+
await client.run(sql);
|
|
17486
|
+
return;
|
|
17487
|
+
}
|
|
17488
|
+
await client.all(sql);
|
|
17489
|
+
};
|
|
16174
17490
|
return {
|
|
16175
17491
|
capabilities: {
|
|
16176
|
-
transactions: supportsTransactions
|
|
17492
|
+
transactions: supportsTransactions,
|
|
17493
|
+
...supportsSavepoints ? { savepoints: true } : {}
|
|
16177
17494
|
},
|
|
16178
17495
|
async executeSql(sql, params) {
|
|
16179
17496
|
const rows = await client.all(sql, params);
|
|
@@ -16198,17 +17515,120 @@ function createSqliteExecutor(client) {
|
|
|
16198
17515
|
}
|
|
16199
17516
|
await client.rollbackTransaction();
|
|
16200
17517
|
},
|
|
17518
|
+
async savepoint(name) {
|
|
17519
|
+
if (!supportsSavepoints) {
|
|
17520
|
+
throw new Error("Savepoints are not supported by this executor");
|
|
17521
|
+
}
|
|
17522
|
+
const savepoint = sanitizeSavepointName3(name);
|
|
17523
|
+
if (typeof client.savepoint === "function") {
|
|
17524
|
+
await client.savepoint(savepoint);
|
|
17525
|
+
return;
|
|
17526
|
+
}
|
|
17527
|
+
await executeControlStatement(`SAVEPOINT ${savepoint}`);
|
|
17528
|
+
},
|
|
17529
|
+
async releaseSavepoint(name) {
|
|
17530
|
+
if (!supportsSavepoints) {
|
|
17531
|
+
throw new Error("Savepoints are not supported by this executor");
|
|
17532
|
+
}
|
|
17533
|
+
const savepoint = sanitizeSavepointName3(name);
|
|
17534
|
+
if (typeof client.releaseSavepoint === "function") {
|
|
17535
|
+
await client.releaseSavepoint(savepoint);
|
|
17536
|
+
return;
|
|
17537
|
+
}
|
|
17538
|
+
await executeControlStatement(`RELEASE SAVEPOINT ${savepoint}`);
|
|
17539
|
+
},
|
|
17540
|
+
async rollbackToSavepoint(name) {
|
|
17541
|
+
if (!supportsSavepoints) {
|
|
17542
|
+
throw new Error("Savepoints are not supported by this executor");
|
|
17543
|
+
}
|
|
17544
|
+
const savepoint = sanitizeSavepointName3(name);
|
|
17545
|
+
if (typeof client.rollbackToSavepoint === "function") {
|
|
17546
|
+
await client.rollbackToSavepoint(savepoint);
|
|
17547
|
+
return;
|
|
17548
|
+
}
|
|
17549
|
+
await executeControlStatement(`ROLLBACK TO SAVEPOINT ${savepoint}`);
|
|
17550
|
+
},
|
|
17551
|
+
async dispose() {
|
|
17552
|
+
}
|
|
17553
|
+
};
|
|
17554
|
+
}
|
|
17555
|
+
|
|
17556
|
+
// src/core/execution/executors/better-sqlite3-executor.ts
|
|
17557
|
+
var SAVEPOINT_NAME_PATTERN4 = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
17558
|
+
var sanitizeSavepointName4 = (name) => {
|
|
17559
|
+
const trimmed = name.trim();
|
|
17560
|
+
if (!SAVEPOINT_NAME_PATTERN4.test(trimmed)) {
|
|
17561
|
+
throw new Error(`Invalid savepoint name: "${name}"`);
|
|
17562
|
+
}
|
|
17563
|
+
return trimmed;
|
|
17564
|
+
};
|
|
17565
|
+
function createBetterSqlite3Executor(client) {
|
|
17566
|
+
return {
|
|
17567
|
+
capabilities: {
|
|
17568
|
+
transactions: true,
|
|
17569
|
+
savepoints: true
|
|
17570
|
+
},
|
|
17571
|
+
async executeSql(sql, params) {
|
|
17572
|
+
const stmt = client.prepare(sql);
|
|
17573
|
+
let result;
|
|
17574
|
+
if (stmt.reader) {
|
|
17575
|
+
const rows = stmt.all(...params ?? []);
|
|
17576
|
+
result = rowsToQueryResult(rows);
|
|
17577
|
+
} else {
|
|
17578
|
+
const info = stmt.run(...params ?? []);
|
|
17579
|
+
result = {
|
|
17580
|
+
columns: [],
|
|
17581
|
+
values: [],
|
|
17582
|
+
meta: {
|
|
17583
|
+
rowsAffected: info.changes,
|
|
17584
|
+
insertId: typeof info.lastInsertRowid === "bigint" ? info.lastInsertRowid.toString() : info.lastInsertRowid
|
|
17585
|
+
}
|
|
17586
|
+
};
|
|
17587
|
+
}
|
|
17588
|
+
return toExecutionPayload([result]);
|
|
17589
|
+
},
|
|
17590
|
+
async beginTransaction() {
|
|
17591
|
+
client.prepare("BEGIN").run();
|
|
17592
|
+
},
|
|
17593
|
+
async commitTransaction() {
|
|
17594
|
+
client.prepare("COMMIT").run();
|
|
17595
|
+
},
|
|
17596
|
+
async rollbackTransaction() {
|
|
17597
|
+
client.prepare("ROLLBACK").run();
|
|
17598
|
+
},
|
|
17599
|
+
async savepoint(name) {
|
|
17600
|
+
const savepoint = sanitizeSavepointName4(name);
|
|
17601
|
+
client.prepare(`SAVEPOINT ${savepoint}`).run();
|
|
17602
|
+
},
|
|
17603
|
+
async releaseSavepoint(name) {
|
|
17604
|
+
const savepoint = sanitizeSavepointName4(name);
|
|
17605
|
+
client.prepare(`RELEASE SAVEPOINT ${savepoint}`).run();
|
|
17606
|
+
},
|
|
17607
|
+
async rollbackToSavepoint(name) {
|
|
17608
|
+
const savepoint = sanitizeSavepointName4(name);
|
|
17609
|
+
client.prepare(`ROLLBACK TO SAVEPOINT ${savepoint}`).run();
|
|
17610
|
+
},
|
|
16201
17611
|
async dispose() {
|
|
16202
17612
|
}
|
|
16203
17613
|
};
|
|
16204
17614
|
}
|
|
16205
17615
|
|
|
16206
17616
|
// src/core/execution/executors/mssql-executor.ts
|
|
17617
|
+
var SAVEPOINT_NAME_PATTERN5 = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
17618
|
+
var sanitizeSavepointName5 = (name) => {
|
|
17619
|
+
const trimmed = name.trim();
|
|
17620
|
+
if (!SAVEPOINT_NAME_PATTERN5.test(trimmed)) {
|
|
17621
|
+
throw new Error(`Invalid savepoint name: "${name}"`);
|
|
17622
|
+
}
|
|
17623
|
+
return trimmed;
|
|
17624
|
+
};
|
|
16207
17625
|
function createMssqlExecutor(client) {
|
|
16208
17626
|
const supportsTransactions = typeof client.beginTransaction === "function" && typeof client.commit === "function" && typeof client.rollback === "function";
|
|
17627
|
+
const supportsSavepoints = supportsTransactions;
|
|
16209
17628
|
return {
|
|
16210
17629
|
capabilities: {
|
|
16211
|
-
transactions: supportsTransactions
|
|
17630
|
+
transactions: supportsTransactions,
|
|
17631
|
+
...supportsSavepoints ? { savepoints: true } : {}
|
|
16212
17632
|
},
|
|
16213
17633
|
async executeSql(sql, params) {
|
|
16214
17634
|
const { recordset, recordsets } = await client.query(sql, params);
|
|
@@ -16233,6 +17653,25 @@ function createMssqlExecutor(client) {
|
|
|
16233
17653
|
}
|
|
16234
17654
|
await client.rollback();
|
|
16235
17655
|
},
|
|
17656
|
+
async savepoint(name) {
|
|
17657
|
+
if (!supportsSavepoints) {
|
|
17658
|
+
throw new Error("Savepoints are not supported by this executor");
|
|
17659
|
+
}
|
|
17660
|
+
const savepoint = sanitizeSavepointName5(name);
|
|
17661
|
+
await client.query(`SAVE TRANSACTION ${savepoint}`);
|
|
17662
|
+
},
|
|
17663
|
+
async releaseSavepoint(_name) {
|
|
17664
|
+
if (!supportsSavepoints) {
|
|
17665
|
+
throw new Error("Savepoints are not supported by this executor");
|
|
17666
|
+
}
|
|
17667
|
+
},
|
|
17668
|
+
async rollbackToSavepoint(name) {
|
|
17669
|
+
if (!supportsSavepoints) {
|
|
17670
|
+
throw new Error("Savepoints are not supported by this executor");
|
|
17671
|
+
}
|
|
17672
|
+
const savepoint = sanitizeSavepointName5(name);
|
|
17673
|
+
await client.query(`ROLLBACK TRANSACTION ${savepoint}`);
|
|
17674
|
+
},
|
|
16236
17675
|
async dispose() {
|
|
16237
17676
|
}
|
|
16238
17677
|
};
|
|
@@ -16308,6 +17747,7 @@ var isQueryResult = (value) => typeof value === "object" && value !== null && Ar
|
|
|
16308
17747
|
var isRowArray = (value) => Array.isArray(value) && value.every((item) => typeof item === "object" && item !== null && !Array.isArray(item));
|
|
16309
17748
|
function createPooledExecutorFactory(opts) {
|
|
16310
17749
|
const { pool, adapter } = opts;
|
|
17750
|
+
const supportsSavepoints = typeof adapter.savepoint === "function" && typeof adapter.releaseSavepoint === "function" && typeof adapter.rollbackToSavepoint === "function";
|
|
16311
17751
|
const makeExecutor = (mode) => {
|
|
16312
17752
|
let lease = null;
|
|
16313
17753
|
const getLease = async () => {
|
|
@@ -16325,8 +17765,17 @@ function createPooledExecutorFactory(opts) {
|
|
|
16325
17765
|
}
|
|
16326
17766
|
return toExecutionPayload([rowsToQueryResult(rows)]);
|
|
16327
17767
|
};
|
|
17768
|
+
const requireActiveTransactionLease = () => {
|
|
17769
|
+
if (!lease) {
|
|
17770
|
+
throw new Error("savepoint operation called without an active transaction");
|
|
17771
|
+
}
|
|
17772
|
+
return lease;
|
|
17773
|
+
};
|
|
16328
17774
|
return {
|
|
16329
|
-
capabilities: {
|
|
17775
|
+
capabilities: {
|
|
17776
|
+
transactions: true,
|
|
17777
|
+
...supportsSavepoints ? { savepoints: true } : {}
|
|
17778
|
+
},
|
|
16330
17779
|
async executeSql(sql, params) {
|
|
16331
17780
|
if (mode === "sticky") {
|
|
16332
17781
|
const l2 = await getLease();
|
|
@@ -16370,6 +17819,27 @@ function createPooledExecutorFactory(opts) {
|
|
|
16370
17819
|
await l.release();
|
|
16371
17820
|
}
|
|
16372
17821
|
},
|
|
17822
|
+
async savepoint(name) {
|
|
17823
|
+
if (!supportsSavepoints) {
|
|
17824
|
+
throw new Error("Savepoints are not supported by this executor");
|
|
17825
|
+
}
|
|
17826
|
+
const l = requireActiveTransactionLease();
|
|
17827
|
+
await adapter.savepoint(l.resource, name);
|
|
17828
|
+
},
|
|
17829
|
+
async releaseSavepoint(name) {
|
|
17830
|
+
if (!supportsSavepoints) {
|
|
17831
|
+
throw new Error("Savepoints are not supported by this executor");
|
|
17832
|
+
}
|
|
17833
|
+
const l = requireActiveTransactionLease();
|
|
17834
|
+
await adapter.releaseSavepoint(l.resource, name);
|
|
17835
|
+
},
|
|
17836
|
+
async rollbackToSavepoint(name) {
|
|
17837
|
+
if (!supportsSavepoints) {
|
|
17838
|
+
throw new Error("Savepoints are not supported by this executor");
|
|
17839
|
+
}
|
|
17840
|
+
const l = requireActiveTransactionLease();
|
|
17841
|
+
await adapter.rollbackToSavepoint(l.resource, name);
|
|
17842
|
+
},
|
|
16373
17843
|
async dispose() {
|
|
16374
17844
|
if (!lease) return;
|
|
16375
17845
|
const l = lease;
|
|
@@ -16464,6 +17934,9 @@ var updateInclude = (qb, relationPath, updater) => {
|
|
|
16464
17934
|
filter: segmentOptions?.filter
|
|
16465
17935
|
});
|
|
16466
17936
|
}
|
|
17937
|
+
if (!isSingleTargetRelation(relation)) {
|
|
17938
|
+
continue;
|
|
17939
|
+
}
|
|
16467
17940
|
const joinForSegment = findJoinByRelationKey(state.ast.joins, relationKey);
|
|
16468
17941
|
currentAlias = joinForSegment ? getExposedName(joinForSegment.table) ?? relation.target.name : relation.target.name;
|
|
16469
17942
|
currentTable = relation.target;
|
|
@@ -16592,6 +18065,9 @@ function applyRelationFilter(qb, table, relationName, filter) {
|
|
|
16592
18065
|
`Relation filter "${relationName}" must include at least one of "some", "none", "every", "isEmpty", or "isNotEmpty".`
|
|
16593
18066
|
);
|
|
16594
18067
|
}
|
|
18068
|
+
if (!isSingleTargetRelation(relation)) {
|
|
18069
|
+
return qb;
|
|
18070
|
+
}
|
|
16595
18071
|
if (filter.some) {
|
|
16596
18072
|
const predicate = buildFilterExpression(relation.target, filter.some);
|
|
16597
18073
|
if (predicate) {
|
|
@@ -16637,6 +18113,9 @@ function applyRelationFilter(qb, table, relationName, filter) {
|
|
|
16637
18113
|
return qb;
|
|
16638
18114
|
}
|
|
16639
18115
|
var buildRelationSubqueryBase = (table, relation) => {
|
|
18116
|
+
if (!isSingleTargetRelation(relation)) {
|
|
18117
|
+
throw new Error("MorphTo relations do not support subquery-based filtering");
|
|
18118
|
+
}
|
|
16640
18119
|
const target = relation.target;
|
|
16641
18120
|
if (relation.type === RelationKinds.BelongsToMany) {
|
|
16642
18121
|
const many = relation;
|
|
@@ -16682,7 +18161,14 @@ var buildRelationSubqueryBase = (table, relation) => {
|
|
|
16682
18161
|
schema: target.schema
|
|
16683
18162
|
};
|
|
16684
18163
|
const correlation = buildRelationCorrelation(table, relation);
|
|
16685
|
-
|
|
18164
|
+
let groupByColumnName;
|
|
18165
|
+
if (relation.type === RelationKinds.BelongsTo) {
|
|
18166
|
+
groupByColumnName = relation.localKey || findPrimaryKey(target);
|
|
18167
|
+
} else if (relation.type === RelationKinds.MorphOne || relation.type === RelationKinds.MorphMany) {
|
|
18168
|
+
groupByColumnName = relation.idField;
|
|
18169
|
+
} else {
|
|
18170
|
+
groupByColumnName = relation.foreignKey;
|
|
18171
|
+
}
|
|
16686
18172
|
return {
|
|
16687
18173
|
from,
|
|
16688
18174
|
joins: [],
|
|
@@ -16714,6 +18200,9 @@ function buildRelationFilterExpression(table, relationName, filter) {
|
|
|
16714
18200
|
where
|
|
16715
18201
|
};
|
|
16716
18202
|
};
|
|
18203
|
+
if (!isSingleTargetRelation(relation)) {
|
|
18204
|
+
return null;
|
|
18205
|
+
}
|
|
16717
18206
|
if (filter.some) {
|
|
16718
18207
|
const predicate = buildFilterExpression(relation.target, filter.some);
|
|
16719
18208
|
if (predicate) {
|
|
@@ -19683,6 +21172,432 @@ var TagIndex = class {
|
|
|
19683
21172
|
};
|
|
19684
21173
|
}
|
|
19685
21174
|
};
|
|
21175
|
+
|
|
21176
|
+
// src/bulk/bulk-context.ts
|
|
21177
|
+
function createBulkExecutionContext(session) {
|
|
21178
|
+
const executionContext = session.getExecutionContext();
|
|
21179
|
+
return {
|
|
21180
|
+
session,
|
|
21181
|
+
executionContext,
|
|
21182
|
+
dialect: executionContext.dialect,
|
|
21183
|
+
supportsReturning: executionContext.dialect.supportsDmlReturningClause()
|
|
21184
|
+
};
|
|
21185
|
+
}
|
|
21186
|
+
async function executeCompiled(ctx, compiled) {
|
|
21187
|
+
const payload = await ctx.executionContext.interceptors.run(
|
|
21188
|
+
{ sql: compiled.sql, params: compiled.params },
|
|
21189
|
+
ctx.executionContext.executor
|
|
21190
|
+
);
|
|
21191
|
+
return extractResultSets(payload);
|
|
21192
|
+
}
|
|
21193
|
+
function extractResultSets(payload) {
|
|
21194
|
+
const result = payload;
|
|
21195
|
+
if (result.resultSets) {
|
|
21196
|
+
return result.resultSets;
|
|
21197
|
+
}
|
|
21198
|
+
return [];
|
|
21199
|
+
}
|
|
21200
|
+
function flattenQueryResults(resultSets) {
|
|
21201
|
+
const rows = [];
|
|
21202
|
+
for (const rs of resultSets) {
|
|
21203
|
+
for (const valueRow of rs.values) {
|
|
21204
|
+
const obj = {};
|
|
21205
|
+
rs.columns.forEach((col2, idx) => {
|
|
21206
|
+
const bare = col2.split(".").pop().replace(/^["`[\]]+|["`[\]]+$/g, "");
|
|
21207
|
+
obj[bare] = valueRow[idx];
|
|
21208
|
+
});
|
|
21209
|
+
rows.push(obj);
|
|
21210
|
+
}
|
|
21211
|
+
}
|
|
21212
|
+
return rows;
|
|
21213
|
+
}
|
|
21214
|
+
function resolveReturningColumns(ctx, table, returning) {
|
|
21215
|
+
if (!returning) return void 0;
|
|
21216
|
+
if (!ctx.supportsReturning) return void 0;
|
|
21217
|
+
if (returning === true) {
|
|
21218
|
+
return Object.values(table.columns).map((col2) => ({
|
|
21219
|
+
type: "Column",
|
|
21220
|
+
table: table.name,
|
|
21221
|
+
name: col2.name,
|
|
21222
|
+
alias: col2.name
|
|
21223
|
+
}));
|
|
21224
|
+
}
|
|
21225
|
+
return returning.map((col2) => ({
|
|
21226
|
+
type: "Column",
|
|
21227
|
+
table: table.name,
|
|
21228
|
+
name: col2.name,
|
|
21229
|
+
alias: col2.name
|
|
21230
|
+
}));
|
|
21231
|
+
}
|
|
21232
|
+
|
|
21233
|
+
// src/bulk/bulk-utils.ts
|
|
21234
|
+
function splitIntoChunks(items, size) {
|
|
21235
|
+
if (size < 1) throw new RangeError(`chunkSize must be >= 1, got ${size}`);
|
|
21236
|
+
const chunks = [];
|
|
21237
|
+
for (let i = 0; i < items.length; i += size) {
|
|
21238
|
+
chunks.push(items.slice(i, i + size));
|
|
21239
|
+
}
|
|
21240
|
+
return chunks;
|
|
21241
|
+
}
|
|
21242
|
+
async function runWithConcurrency(tasks, concurrency) {
|
|
21243
|
+
const limit = concurrency === "sequential" ? 1 : Math.max(1, concurrency);
|
|
21244
|
+
if (limit === 1) {
|
|
21245
|
+
const results2 = [];
|
|
21246
|
+
for (const task of tasks) {
|
|
21247
|
+
results2.push(await task());
|
|
21248
|
+
}
|
|
21249
|
+
return results2;
|
|
21250
|
+
}
|
|
21251
|
+
const results = new Array(tasks.length);
|
|
21252
|
+
let nextIndex = 0;
|
|
21253
|
+
const worker = async () => {
|
|
21254
|
+
while (nextIndex < tasks.length) {
|
|
21255
|
+
const i = nextIndex++;
|
|
21256
|
+
results[i] = await tasks[i]();
|
|
21257
|
+
}
|
|
21258
|
+
};
|
|
21259
|
+
const workers = Array.from({ length: Math.min(limit, tasks.length) }, worker);
|
|
21260
|
+
await Promise.all(workers);
|
|
21261
|
+
return results;
|
|
21262
|
+
}
|
|
21263
|
+
async function runChunk(task, chunkIndex, totalChunks, rowsInChunk, timing, onChunkComplete) {
|
|
21264
|
+
const start = timing || onChunkComplete ? Date.now() : 0;
|
|
21265
|
+
const result = await task();
|
|
21266
|
+
const elapsedMs = start ? Date.now() - start : 0;
|
|
21267
|
+
if (onChunkComplete) {
|
|
21268
|
+
await onChunkComplete({ chunkIndex, totalChunks, rowsInChunk, elapsedMs });
|
|
21269
|
+
}
|
|
21270
|
+
return result;
|
|
21271
|
+
}
|
|
21272
|
+
async function maybeTransaction(session, transactional, fn8) {
|
|
21273
|
+
if (!transactional) return fn8();
|
|
21274
|
+
const ormSession = session;
|
|
21275
|
+
return ormSession.transaction(fn8);
|
|
21276
|
+
}
|
|
21277
|
+
function aggregateOutcomes(outcomes) {
|
|
21278
|
+
const result = {
|
|
21279
|
+
processedRows: 0,
|
|
21280
|
+
chunksExecuted: outcomes.length,
|
|
21281
|
+
returning: []
|
|
21282
|
+
};
|
|
21283
|
+
for (const o of outcomes) {
|
|
21284
|
+
result.processedRows += o.processedRows;
|
|
21285
|
+
result.returning.push(...o.returning);
|
|
21286
|
+
}
|
|
21287
|
+
return result;
|
|
21288
|
+
}
|
|
21289
|
+
function aggregateOutcomesWithTimings(outcomes) {
|
|
21290
|
+
const result = aggregateOutcomes(outcomes);
|
|
21291
|
+
result.chunkTimings = outcomes.map((o) => o.elapsedMs);
|
|
21292
|
+
return result;
|
|
21293
|
+
}
|
|
21294
|
+
|
|
21295
|
+
// src/bulk/bulk-executor.base.ts
|
|
21296
|
+
var DEFAULT_CHUNK_SIZE = 500;
|
|
21297
|
+
var BulkBaseExecutor = class {
|
|
21298
|
+
session;
|
|
21299
|
+
table;
|
|
21300
|
+
ctx;
|
|
21301
|
+
options;
|
|
21302
|
+
chunks;
|
|
21303
|
+
totalChunks;
|
|
21304
|
+
constructor(session, table, rows, options = {}) {
|
|
21305
|
+
this.session = session;
|
|
21306
|
+
this.table = table;
|
|
21307
|
+
this.ctx = createBulkExecutionContext(session);
|
|
21308
|
+
this.options = {
|
|
21309
|
+
chunkSize: DEFAULT_CHUNK_SIZE,
|
|
21310
|
+
concurrency: "sequential",
|
|
21311
|
+
transactional: true,
|
|
21312
|
+
timing: false,
|
|
21313
|
+
...options
|
|
21314
|
+
};
|
|
21315
|
+
this.chunks = splitIntoChunks(rows, this.options.chunkSize);
|
|
21316
|
+
this.totalChunks = this.chunks.length;
|
|
21317
|
+
}
|
|
21318
|
+
async execute() {
|
|
21319
|
+
const buildTask = (chunk, chunkIndex) => async () => {
|
|
21320
|
+
return runChunk(
|
|
21321
|
+
() => this.executeChunk(chunk, chunkIndex),
|
|
21322
|
+
chunkIndex,
|
|
21323
|
+
this.totalChunks,
|
|
21324
|
+
chunk.length,
|
|
21325
|
+
this.options.timing,
|
|
21326
|
+
this.options.onChunkComplete
|
|
21327
|
+
);
|
|
21328
|
+
};
|
|
21329
|
+
const tasks = this.chunks.map((chunk, i) => buildTask(chunk, i));
|
|
21330
|
+
const outcomes = await maybeTransaction(
|
|
21331
|
+
this.session,
|
|
21332
|
+
this.options.transactional,
|
|
21333
|
+
() => runWithConcurrency(tasks, this.options.concurrency)
|
|
21334
|
+
);
|
|
21335
|
+
return this.options.timing ? aggregateOutcomesWithTimings(outcomes) : aggregateOutcomes(outcomes);
|
|
21336
|
+
}
|
|
21337
|
+
};
|
|
21338
|
+
|
|
21339
|
+
// src/bulk/bulk-insert-executor.ts
|
|
21340
|
+
var BulkInsertExecutor = class extends BulkBaseExecutor {
|
|
21341
|
+
constructor(session, table, rows, options = {}) {
|
|
21342
|
+
super(session, table, rows, options);
|
|
21343
|
+
}
|
|
21344
|
+
async executeChunk(chunk, _chunkIndex) {
|
|
21345
|
+
const returningColumns = resolveReturningColumns(this.ctx, this.table, this.options.returning);
|
|
21346
|
+
let builder = new InsertQueryBuilder(this.table).values(chunk);
|
|
21347
|
+
if (this.options.onConflict) {
|
|
21348
|
+
const conflictColumns = this.options.onConflict.target?.columns ?? [];
|
|
21349
|
+
const conflictBuilder = builder.onConflict(conflictColumns);
|
|
21350
|
+
if (this.options.onConflict.action.type === "DoNothing") {
|
|
21351
|
+
builder = conflictBuilder.doNothing();
|
|
21352
|
+
} else if (this.options.onConflict.action.type === "DoUpdate" && this.options.onConflict.action.set) {
|
|
21353
|
+
const setMap = {};
|
|
21354
|
+
for (const assignment of this.options.onConflict.action.set) {
|
|
21355
|
+
const colName = typeof assignment.column === "object" ? assignment.column.name : assignment.column;
|
|
21356
|
+
setMap[colName] = assignment.value;
|
|
21357
|
+
}
|
|
21358
|
+
builder = conflictBuilder.doUpdate(setMap);
|
|
21359
|
+
}
|
|
21360
|
+
}
|
|
21361
|
+
const finalBuilder = builder;
|
|
21362
|
+
if (returningColumns?.length) {
|
|
21363
|
+
finalBuilder.returning(...returningColumns);
|
|
21364
|
+
}
|
|
21365
|
+
const compiled = finalBuilder.compile(this.ctx.dialect);
|
|
21366
|
+
const resultSets = await executeCompiled(this.ctx, compiled);
|
|
21367
|
+
return {
|
|
21368
|
+
processedRows: chunk.length,
|
|
21369
|
+
returning: returningColumns ? flattenQueryResults(resultSets) : [],
|
|
21370
|
+
elapsedMs: 0
|
|
21371
|
+
};
|
|
21372
|
+
}
|
|
21373
|
+
};
|
|
21374
|
+
async function bulkInsert(session, table, rows, options = {}) {
|
|
21375
|
+
if (!rows.length) {
|
|
21376
|
+
return { processedRows: 0, chunksExecuted: 0, returning: [] };
|
|
21377
|
+
}
|
|
21378
|
+
const executor = new BulkInsertExecutor(session, table, rows, options);
|
|
21379
|
+
return executor.execute();
|
|
21380
|
+
}
|
|
21381
|
+
|
|
21382
|
+
// src/bulk/bulk-update-executor.ts
|
|
21383
|
+
function resolveByColumns(table, by) {
|
|
21384
|
+
if (!by) return [findPrimaryKey(table)];
|
|
21385
|
+
return Array.isArray(by) ? by : [by];
|
|
21386
|
+
}
|
|
21387
|
+
var BulkUpdateExecutor = class extends BulkBaseExecutor {
|
|
21388
|
+
byColumns;
|
|
21389
|
+
constructor(session, table, rows, options = {}) {
|
|
21390
|
+
super(session, table, rows, options);
|
|
21391
|
+
this.byColumns = resolveByColumns(table, options.by);
|
|
21392
|
+
}
|
|
21393
|
+
async executeChunk(chunk, _chunkIndex) {
|
|
21394
|
+
const allReturning = [];
|
|
21395
|
+
const returningColumns = resolveReturningColumns(this.ctx, this.table, this.options.returning);
|
|
21396
|
+
const extraWhere = this.options.where;
|
|
21397
|
+
for (const row of chunk) {
|
|
21398
|
+
const predicates = this.byColumns.map((colName) => {
|
|
21399
|
+
const col2 = this.table.columns[colName];
|
|
21400
|
+
if (!col2) {
|
|
21401
|
+
throw new Error(
|
|
21402
|
+
`bulkUpdate: column "${colName}" not found in table "${this.table.name}"`
|
|
21403
|
+
);
|
|
21404
|
+
}
|
|
21405
|
+
const val = row[colName];
|
|
21406
|
+
if (val === void 0) {
|
|
21407
|
+
throw new Error(
|
|
21408
|
+
`bulkUpdate: row is missing the identity column "${colName}" required by the "by" option`
|
|
21409
|
+
);
|
|
21410
|
+
}
|
|
21411
|
+
return eq(col2, val);
|
|
21412
|
+
});
|
|
21413
|
+
const whereExpr = predicates.length === 1 ? predicates[0] : predicates.reduce((acc, p) => and(acc, p), predicates[0]);
|
|
21414
|
+
const finalWhere = extraWhere ? and(whereExpr, extraWhere) : whereExpr;
|
|
21415
|
+
const bySet = new Set(this.byColumns);
|
|
21416
|
+
const setPayload = {};
|
|
21417
|
+
for (const [key, val] of Object.entries(row)) {
|
|
21418
|
+
if (!bySet.has(key) && key in this.table.columns) {
|
|
21419
|
+
setPayload[key] = val;
|
|
21420
|
+
}
|
|
21421
|
+
}
|
|
21422
|
+
if (!Object.keys(setPayload).length) continue;
|
|
21423
|
+
let builder = new UpdateQueryBuilder(this.table).set(setPayload).where(finalWhere);
|
|
21424
|
+
if (returningColumns?.length) {
|
|
21425
|
+
builder = builder.returning(...returningColumns);
|
|
21426
|
+
}
|
|
21427
|
+
const compiled = builder.compile(this.ctx.dialect);
|
|
21428
|
+
const resultSets = await executeCompiled(this.ctx, compiled);
|
|
21429
|
+
if (returningColumns) {
|
|
21430
|
+
allReturning.push(...flattenQueryResults(resultSets));
|
|
21431
|
+
}
|
|
21432
|
+
}
|
|
21433
|
+
return {
|
|
21434
|
+
processedRows: chunk.length,
|
|
21435
|
+
returning: allReturning,
|
|
21436
|
+
elapsedMs: 0
|
|
21437
|
+
};
|
|
21438
|
+
}
|
|
21439
|
+
};
|
|
21440
|
+
async function bulkUpdate(session, table, rows, options = {}) {
|
|
21441
|
+
if (!rows.length) {
|
|
21442
|
+
return { processedRows: 0, chunksExecuted: 0, returning: [] };
|
|
21443
|
+
}
|
|
21444
|
+
const executor = new BulkUpdateExecutor(session, table, rows, options);
|
|
21445
|
+
return executor.execute();
|
|
21446
|
+
}
|
|
21447
|
+
var DEFAULT_BULK_UPDATE_WHERE_CHUNK_SIZE = 500;
|
|
21448
|
+
async function bulkUpdateWhere(session, table, ids, set, options = {}) {
|
|
21449
|
+
if (!ids.length) {
|
|
21450
|
+
return { processedRows: 0, chunksExecuted: 0, returning: [] };
|
|
21451
|
+
}
|
|
21452
|
+
const {
|
|
21453
|
+
chunkSize = DEFAULT_BULK_UPDATE_WHERE_CHUNK_SIZE,
|
|
21454
|
+
concurrency = "sequential",
|
|
21455
|
+
transactional = true,
|
|
21456
|
+
timing = false,
|
|
21457
|
+
onChunkComplete,
|
|
21458
|
+
by,
|
|
21459
|
+
where: extraWhere,
|
|
21460
|
+
returning
|
|
21461
|
+
} = options;
|
|
21462
|
+
const ctx = createBulkExecutionContext(session);
|
|
21463
|
+
const byColumnName = by ?? findPrimaryKey(table);
|
|
21464
|
+
const byColumn = table.columns[byColumnName];
|
|
21465
|
+
if (!byColumn) {
|
|
21466
|
+
throw new Error(
|
|
21467
|
+
`bulkUpdateWhere: column "${byColumnName}" not found in table "${table.name}"`
|
|
21468
|
+
);
|
|
21469
|
+
}
|
|
21470
|
+
const returningColumns = resolveReturningColumns(ctx, table, returning);
|
|
21471
|
+
const chunks = splitIntoChunks(ids, chunkSize);
|
|
21472
|
+
const totalChunks = chunks.length;
|
|
21473
|
+
const buildTask = (chunk, chunkIndex) => async () => {
|
|
21474
|
+
return runChunk(
|
|
21475
|
+
async () => {
|
|
21476
|
+
const inExpr = inList(byColumn, chunk);
|
|
21477
|
+
const finalWhere = extraWhere ? and(inExpr, extraWhere) : inExpr;
|
|
21478
|
+
let builder = new UpdateQueryBuilder(table).set(set).where(finalWhere);
|
|
21479
|
+
if (returningColumns?.length) {
|
|
21480
|
+
builder = builder.returning(...returningColumns);
|
|
21481
|
+
}
|
|
21482
|
+
const compiled = builder.compile(ctx.dialect);
|
|
21483
|
+
const resultSets = await executeCompiled(ctx, compiled);
|
|
21484
|
+
return {
|
|
21485
|
+
processedRows: chunk.length,
|
|
21486
|
+
returning: returningColumns ? flattenQueryResults(resultSets) : [],
|
|
21487
|
+
elapsedMs: 0
|
|
21488
|
+
};
|
|
21489
|
+
},
|
|
21490
|
+
chunkIndex,
|
|
21491
|
+
totalChunks,
|
|
21492
|
+
chunk.length,
|
|
21493
|
+
timing,
|
|
21494
|
+
onChunkComplete
|
|
21495
|
+
);
|
|
21496
|
+
};
|
|
21497
|
+
const tasks = chunks.map((chunk, i) => buildTask(chunk, i));
|
|
21498
|
+
const outcomes = await maybeTransaction(
|
|
21499
|
+
session,
|
|
21500
|
+
transactional,
|
|
21501
|
+
() => runWithConcurrency(tasks, concurrency)
|
|
21502
|
+
);
|
|
21503
|
+
return timing ? aggregateOutcomesWithTimings(outcomes) : aggregateOutcomes(outcomes);
|
|
21504
|
+
}
|
|
21505
|
+
|
|
21506
|
+
// src/bulk/bulk-delete-executor.ts
|
|
21507
|
+
var BulkDeleteExecutor = class extends BulkBaseExecutor {
|
|
21508
|
+
byColumnName;
|
|
21509
|
+
constructor(session, table, ids, options = {}) {
|
|
21510
|
+
super(session, table, ids, options);
|
|
21511
|
+
this.byColumnName = options.by ?? findPrimaryKey(table);
|
|
21512
|
+
}
|
|
21513
|
+
async executeChunk(chunk, _chunkIndex) {
|
|
21514
|
+
const byColumn = this.table.columns[this.byColumnName];
|
|
21515
|
+
if (!byColumn) {
|
|
21516
|
+
throw new Error(
|
|
21517
|
+
`bulkDelete: column "${this.byColumnName}" not found in table "${this.table.name}"`
|
|
21518
|
+
);
|
|
21519
|
+
}
|
|
21520
|
+
const extraWhere = this.options.where;
|
|
21521
|
+
const inExpr = inList(byColumn, chunk);
|
|
21522
|
+
const finalWhere = extraWhere ? and(inExpr, extraWhere) : inExpr;
|
|
21523
|
+
const builder = new DeleteQueryBuilder(this.table).where(finalWhere);
|
|
21524
|
+
const compiled = builder.compile(this.ctx.dialect);
|
|
21525
|
+
await executeCompiled(this.ctx, compiled);
|
|
21526
|
+
return {
|
|
21527
|
+
processedRows: chunk.length,
|
|
21528
|
+
returning: [],
|
|
21529
|
+
elapsedMs: 0
|
|
21530
|
+
};
|
|
21531
|
+
}
|
|
21532
|
+
};
|
|
21533
|
+
async function bulkDelete(session, table, ids, options = {}) {
|
|
21534
|
+
if (!ids.length) {
|
|
21535
|
+
return { processedRows: 0, chunksExecuted: 0, returning: [] };
|
|
21536
|
+
}
|
|
21537
|
+
const executor = new BulkDeleteExecutor(session, table, ids, options);
|
|
21538
|
+
return executor.execute();
|
|
21539
|
+
}
|
|
21540
|
+
async function bulkDeleteWhere(session, table, where, options = {}) {
|
|
21541
|
+
const { transactional = false } = options;
|
|
21542
|
+
const ctx = createBulkExecutionContext(session);
|
|
21543
|
+
const builder = new DeleteQueryBuilder(table).where(where);
|
|
21544
|
+
const compiled = builder.compile(ctx.dialect);
|
|
21545
|
+
const execute = async () => {
|
|
21546
|
+
await executeCompiled(ctx, compiled);
|
|
21547
|
+
return { processedRows: 0, chunksExecuted: 1, returning: [] };
|
|
21548
|
+
};
|
|
21549
|
+
return maybeTransaction(session, transactional, execute);
|
|
21550
|
+
}
|
|
21551
|
+
|
|
21552
|
+
// src/bulk/bulk-upsert-executor.ts
|
|
21553
|
+
var DEFAULT_CHUNK_SIZE2 = 500;
|
|
21554
|
+
var BulkUpsertExecutor = class extends BulkBaseExecutor {
|
|
21555
|
+
conflictTargetNodes;
|
|
21556
|
+
updateColumns;
|
|
21557
|
+
constructor(session, table, rows, options = {}) {
|
|
21558
|
+
super(session, table, rows, { ...options, chunkSize: options.chunkSize ?? DEFAULT_CHUNK_SIZE2 });
|
|
21559
|
+
const pkName = findPrimaryKey(table);
|
|
21560
|
+
const conflictTargetNames = options.conflictColumns ?? [pkName];
|
|
21561
|
+
this.conflictTargetNodes = conflictTargetNames.map((name) => ({
|
|
21562
|
+
type: "Column",
|
|
21563
|
+
table: table.name,
|
|
21564
|
+
name
|
|
21565
|
+
}));
|
|
21566
|
+
const conflictSet = new Set(conflictTargetNames);
|
|
21567
|
+
this.updateColumns = options.updateColumns ?? Object.keys(rows[0] ?? {}).filter((col2) => !conflictSet.has(col2) && col2 in table.columns);
|
|
21568
|
+
}
|
|
21569
|
+
async executeChunk(chunk, _chunkIndex) {
|
|
21570
|
+
const returningColumns = resolveReturningColumns(this.ctx, this.table, this.options.returning);
|
|
21571
|
+
const set = {};
|
|
21572
|
+
for (const col2 of this.updateColumns) {
|
|
21573
|
+
set[col2] = { type: "ExcludedColumn", name: col2 };
|
|
21574
|
+
}
|
|
21575
|
+
let builder;
|
|
21576
|
+
if (this.updateColumns.length === 0) {
|
|
21577
|
+
builder = new InsertQueryBuilder(this.table).values(chunk).onConflict(this.conflictTargetNodes).doNothing();
|
|
21578
|
+
} else {
|
|
21579
|
+
builder = new InsertQueryBuilder(this.table).values(chunk).onConflict(this.conflictTargetNodes).doUpdate(set);
|
|
21580
|
+
}
|
|
21581
|
+
const finalBuilder = builder;
|
|
21582
|
+
if (returningColumns?.length) {
|
|
21583
|
+
finalBuilder.returning(...returningColumns);
|
|
21584
|
+
}
|
|
21585
|
+
const compiled = finalBuilder.compile(this.ctx.dialect);
|
|
21586
|
+
const resultSets = await executeCompiled(this.ctx, compiled);
|
|
21587
|
+
return {
|
|
21588
|
+
processedRows: chunk.length,
|
|
21589
|
+
returning: returningColumns ? flattenQueryResults(resultSets) : [],
|
|
21590
|
+
elapsedMs: 0
|
|
21591
|
+
};
|
|
21592
|
+
}
|
|
21593
|
+
};
|
|
21594
|
+
async function bulkUpsert(session, table, rows, options = {}) {
|
|
21595
|
+
if (!rows.length) {
|
|
21596
|
+
return { processedRows: 0, chunksExecuted: 0, returning: [] };
|
|
21597
|
+
}
|
|
21598
|
+
const executor = new BulkUpsertExecutor(session, table, rows, options);
|
|
21599
|
+
return executor.execute();
|
|
21600
|
+
}
|
|
19686
21601
|
export {
|
|
19687
21602
|
Alphanumeric,
|
|
19688
21603
|
AsyncLocalStorage,
|
|
@@ -19691,6 +21606,10 @@ export {
|
|
|
19691
21606
|
BigIntTypeStrategy,
|
|
19692
21607
|
BinaryTypeStrategy,
|
|
19693
21608
|
BooleanTypeStrategy,
|
|
21609
|
+
BulkDeleteExecutor,
|
|
21610
|
+
BulkInsertExecutor,
|
|
21611
|
+
BulkUpdateExecutor,
|
|
21612
|
+
BulkUpsertExecutor,
|
|
19694
21613
|
CEP,
|
|
19695
21614
|
CNPJ,
|
|
19696
21615
|
CPF,
|
|
@@ -19706,6 +21625,9 @@ export {
|
|
|
19706
21625
|
DefaultEntityMaterializer,
|
|
19707
21626
|
DefaultHasManyCollection,
|
|
19708
21627
|
DefaultManyToManyCollection,
|
|
21628
|
+
DefaultMorphManyCollection,
|
|
21629
|
+
DefaultMorphOneReference,
|
|
21630
|
+
DefaultMorphToReference,
|
|
19709
21631
|
DefaultTypeStrategy,
|
|
19710
21632
|
DeleteQueryBuilder,
|
|
19711
21633
|
DomainEventBus,
|
|
@@ -19721,6 +21643,9 @@ export {
|
|
|
19721
21643
|
Length,
|
|
19722
21644
|
Lower,
|
|
19723
21645
|
MemoryCacheAdapter,
|
|
21646
|
+
MorphMany,
|
|
21647
|
+
MorphOne,
|
|
21648
|
+
MorphTo,
|
|
19724
21649
|
MySqlDialect,
|
|
19725
21650
|
NestedSetStrategy,
|
|
19726
21651
|
Orm,
|
|
@@ -19779,6 +21704,12 @@ export {
|
|
|
19779
21704
|
bootstrapEntities,
|
|
19780
21705
|
buildFilterExpression,
|
|
19781
21706
|
buildScopeConditions,
|
|
21707
|
+
bulkDelete,
|
|
21708
|
+
bulkDeleteWhere,
|
|
21709
|
+
bulkInsert,
|
|
21710
|
+
bulkUpdate,
|
|
21711
|
+
bulkUpdateWhere,
|
|
21712
|
+
bulkUpsert,
|
|
19782
21713
|
calculateRowDepths,
|
|
19783
21714
|
calculateTotalPages,
|
|
19784
21715
|
callProcedure,
|
|
@@ -19811,6 +21742,7 @@ export {
|
|
|
19811
21742
|
count,
|
|
19812
21743
|
countAll,
|
|
19813
21744
|
createApiComponentsSection,
|
|
21745
|
+
createBetterSqlite3Executor,
|
|
19814
21746
|
createDeterministicNamingState,
|
|
19815
21747
|
createDtoToOpenApiSchema,
|
|
19816
21748
|
createEntityFromRow,
|
|
@@ -19912,12 +21844,16 @@ export {
|
|
|
19912
21844
|
isCastExpressionNode,
|
|
19913
21845
|
isCollateExpressionNode,
|
|
19914
21846
|
isComponentReference,
|
|
21847
|
+
isDistinctFrom,
|
|
19915
21848
|
isExpressionSelectionNode,
|
|
19916
21849
|
isFunctionNode,
|
|
21850
|
+
isMorphRelation,
|
|
21851
|
+
isNotDistinctFrom,
|
|
19917
21852
|
isNotNull,
|
|
19918
21853
|
isNull,
|
|
19919
21854
|
isNullableColumn,
|
|
19920
21855
|
isOperandNode,
|
|
21856
|
+
isSingleTargetRelation,
|
|
19921
21857
|
isTableDef2 as isTableDef,
|
|
19922
21858
|
isTreeConfig,
|
|
19923
21859
|
isValidDuration,
|
|
@@ -19941,6 +21877,9 @@ export {
|
|
|
19941
21877
|
loadBelongsToRelation,
|
|
19942
21878
|
loadHasManyRelation,
|
|
19943
21879
|
loadHasOneRelation,
|
|
21880
|
+
loadMorphManyRelation,
|
|
21881
|
+
loadMorphOneRelation,
|
|
21882
|
+
loadMorphToRelation,
|
|
19944
21883
|
localTime,
|
|
19945
21884
|
localTimestamp,
|
|
19946
21885
|
locate,
|
|
@@ -19962,11 +21901,15 @@ export {
|
|
|
19962
21901
|
minute,
|
|
19963
21902
|
mod,
|
|
19964
21903
|
month,
|
|
21904
|
+
morphMany,
|
|
21905
|
+
morphOne,
|
|
21906
|
+
morphTo,
|
|
19965
21907
|
mul,
|
|
19966
21908
|
neq,
|
|
19967
21909
|
nestedDtoToOpenApiSchema,
|
|
19968
21910
|
nestedWhereInputToOpenApiSchema,
|
|
19969
21911
|
normalizeColumnType,
|
|
21912
|
+
not,
|
|
19970
21913
|
notBetween,
|
|
19971
21914
|
notExists,
|
|
19972
21915
|
notInList,
|