metal-orm 1.1.20 → 1.1.22
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/dist/index.cjs +124 -84
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +58 -31
- package/dist/index.d.ts +58 -31
- package/dist/index.js +124 -84
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/core/ddl/introspect/catalogs/mssql.ts +0 -8
- package/src/core/ddl/introspect/catalogs/mysql.ts +0 -5
- package/src/core/ddl/introspect/catalogs/postgres.ts +0 -9
- package/src/core/ddl/introspect/catalogs/sqlite.ts +0 -3
- package/src/decorators/entity.ts +2 -3
- package/src/index.ts +2 -1
- package/src/orm/entity-metadata.ts +6 -11
- package/src/orm/lifecycle.ts +20 -0
- package/src/orm/orm-session.ts +37 -3
- package/src/orm/relation-change-processor.ts +15 -11
- package/src/orm/unit-of-work.ts +15 -9
- package/src/schema/table.ts +10 -25
- package/src/tree/tree-manager.ts +111 -43
package/dist/index.js
CHANGED
|
@@ -36,7 +36,7 @@ var init_schema_plan_executor = __esm({
|
|
|
36
36
|
});
|
|
37
37
|
|
|
38
38
|
// src/schema/table.ts
|
|
39
|
-
var defineTable = (name, columns, relations = {},
|
|
39
|
+
var defineTable = (name, columns, relations = {}, options = {}) => {
|
|
40
40
|
const colsWithNames = Object.entries(columns).reduce((acc, [key, def]) => {
|
|
41
41
|
const colDef = { ...def, name: key, table: name };
|
|
42
42
|
acc[key] = colDef;
|
|
@@ -47,7 +47,6 @@ var defineTable = (name, columns, relations = {}, hooks, options = {}) => {
|
|
|
47
47
|
schema: options.schema,
|
|
48
48
|
columns: colsWithNames,
|
|
49
49
|
relations,
|
|
50
|
-
hooks,
|
|
51
50
|
primaryKey: options.primaryKey,
|
|
52
51
|
indexes: options.indexes,
|
|
53
52
|
checks: options.checks,
|
|
@@ -7963,14 +7962,11 @@ var addTransformerMetadata = (target, propertyKey, transformer) => {
|
|
|
7963
7962
|
const meta = ensureEntityMetadata(target);
|
|
7964
7963
|
meta.transformers[propertyKey] = transformer;
|
|
7965
7964
|
};
|
|
7966
|
-
var setEntityTableName = (target, tableName,
|
|
7965
|
+
var setEntityTableName = (target, tableName, type) => {
|
|
7967
7966
|
const meta = ensureEntityMetadata(target);
|
|
7968
7967
|
if (tableName && tableName.length > 0) {
|
|
7969
7968
|
meta.tableName = tableName;
|
|
7970
7969
|
}
|
|
7971
|
-
if (hooks) {
|
|
7972
|
-
meta.hooks = hooks;
|
|
7973
|
-
}
|
|
7974
7970
|
if (type) {
|
|
7975
7971
|
meta.type = type;
|
|
7976
7972
|
}
|
|
@@ -7987,7 +7983,7 @@ var buildTableDef = (meta) => {
|
|
|
7987
7983
|
table: meta.tableName
|
|
7988
7984
|
};
|
|
7989
7985
|
}
|
|
7990
|
-
const table = defineTable(meta.tableName, columns
|
|
7986
|
+
const table = defineTable(meta.tableName, columns);
|
|
7991
7987
|
meta.table = table;
|
|
7992
7988
|
return table;
|
|
7993
7989
|
};
|
|
@@ -11409,7 +11405,6 @@ var PgInformationSchemaColumns = defineTable(
|
|
|
11409
11405
|
ordinal_position: col.int()
|
|
11410
11406
|
},
|
|
11411
11407
|
{},
|
|
11412
|
-
void 0,
|
|
11413
11408
|
{ schema: "information_schema" }
|
|
11414
11409
|
);
|
|
11415
11410
|
var PgClass = defineTable(
|
|
@@ -11421,7 +11416,6 @@ var PgClass = defineTable(
|
|
|
11421
11416
|
relkind: col.varchar(1)
|
|
11422
11417
|
},
|
|
11423
11418
|
{},
|
|
11424
|
-
void 0,
|
|
11425
11419
|
{ schema: "pg_catalog" }
|
|
11426
11420
|
);
|
|
11427
11421
|
var PgNamespace = defineTable(
|
|
@@ -11431,7 +11425,6 @@ var PgNamespace = defineTable(
|
|
|
11431
11425
|
nspname: col.varchar(255)
|
|
11432
11426
|
},
|
|
11433
11427
|
{},
|
|
11434
|
-
void 0,
|
|
11435
11428
|
{ schema: "pg_catalog" }
|
|
11436
11429
|
);
|
|
11437
11430
|
var PgIndex = defineTable(
|
|
@@ -11444,7 +11437,6 @@ var PgIndex = defineTable(
|
|
|
11444
11437
|
indpred: col.varchar(1024)
|
|
11445
11438
|
},
|
|
11446
11439
|
{},
|
|
11447
|
-
void 0,
|
|
11448
11440
|
{ schema: "pg_catalog" }
|
|
11449
11441
|
);
|
|
11450
11442
|
var PgAttribute = defineTable(
|
|
@@ -11455,7 +11447,6 @@ var PgAttribute = defineTable(
|
|
|
11455
11447
|
attnum: col.int()
|
|
11456
11448
|
},
|
|
11457
11449
|
{},
|
|
11458
|
-
void 0,
|
|
11459
11450
|
{ schema: "pg_catalog" }
|
|
11460
11451
|
);
|
|
11461
11452
|
var PgTableConstraints = defineTable(
|
|
@@ -11470,7 +11461,6 @@ var PgTableConstraints = defineTable(
|
|
|
11470
11461
|
constraint_type: col.varchar(255)
|
|
11471
11462
|
},
|
|
11472
11463
|
{},
|
|
11473
|
-
void 0,
|
|
11474
11464
|
{ schema: "information_schema" }
|
|
11475
11465
|
);
|
|
11476
11466
|
var PgKeyColumnUsage = defineTable(
|
|
@@ -11486,7 +11476,6 @@ var PgKeyColumnUsage = defineTable(
|
|
|
11486
11476
|
ordinal_position: col.int()
|
|
11487
11477
|
},
|
|
11488
11478
|
{},
|
|
11489
|
-
void 0,
|
|
11490
11479
|
{ schema: "information_schema" }
|
|
11491
11480
|
);
|
|
11492
11481
|
var PgConstraintColumnUsage = defineTable(
|
|
@@ -11501,7 +11490,6 @@ var PgConstraintColumnUsage = defineTable(
|
|
|
11501
11490
|
column_name: col.varchar(255)
|
|
11502
11491
|
},
|
|
11503
11492
|
{},
|
|
11504
|
-
void 0,
|
|
11505
11493
|
{ schema: "information_schema" }
|
|
11506
11494
|
);
|
|
11507
11495
|
var PgReferentialConstraints = defineTable(
|
|
@@ -11518,7 +11506,6 @@ var PgReferentialConstraints = defineTable(
|
|
|
11518
11506
|
delete_rule: col.varchar(64)
|
|
11519
11507
|
},
|
|
11520
11508
|
{},
|
|
11521
|
-
void 0,
|
|
11522
11509
|
{ schema: "information_schema" }
|
|
11523
11510
|
);
|
|
11524
11511
|
|
|
@@ -11900,7 +11887,6 @@ var InformationSchemaTables = defineTable(
|
|
|
11900
11887
|
table_comment: col.varchar(1024)
|
|
11901
11888
|
},
|
|
11902
11889
|
{},
|
|
11903
|
-
void 0,
|
|
11904
11890
|
{ schema: INFORMATION_SCHEMA }
|
|
11905
11891
|
);
|
|
11906
11892
|
var InformationSchemaColumns = defineTable(
|
|
@@ -11918,7 +11904,6 @@ var InformationSchemaColumns = defineTable(
|
|
|
11918
11904
|
ordinal_position: col.int()
|
|
11919
11905
|
},
|
|
11920
11906
|
{},
|
|
11921
|
-
void 0,
|
|
11922
11907
|
{ schema: INFORMATION_SCHEMA }
|
|
11923
11908
|
);
|
|
11924
11909
|
var InformationSchemaKeyColumnUsage = defineTable(
|
|
@@ -11935,7 +11920,6 @@ var InformationSchemaKeyColumnUsage = defineTable(
|
|
|
11935
11920
|
referenced_column_name: col.varchar(255)
|
|
11936
11921
|
},
|
|
11937
11922
|
{},
|
|
11938
|
-
void 0,
|
|
11939
11923
|
{ schema: INFORMATION_SCHEMA }
|
|
11940
11924
|
);
|
|
11941
11925
|
var InformationSchemaReferentialConstraints = defineTable(
|
|
@@ -11947,7 +11931,6 @@ var InformationSchemaReferentialConstraints = defineTable(
|
|
|
11947
11931
|
update_rule: col.varchar(255)
|
|
11948
11932
|
},
|
|
11949
11933
|
{},
|
|
11950
|
-
void 0,
|
|
11951
11934
|
{ schema: INFORMATION_SCHEMA }
|
|
11952
11935
|
);
|
|
11953
11936
|
var InformationSchemaStatistics = defineTable(
|
|
@@ -11961,7 +11944,6 @@ var InformationSchemaStatistics = defineTable(
|
|
|
11961
11944
|
seq_in_index: col.int()
|
|
11962
11945
|
},
|
|
11963
11946
|
{},
|
|
11964
|
-
void 0,
|
|
11965
11947
|
{ schema: INFORMATION_SCHEMA }
|
|
11966
11948
|
);
|
|
11967
11949
|
|
|
@@ -12582,7 +12564,6 @@ var SysColumns = defineTable(
|
|
|
12582
12564
|
user_type_id: col.int()
|
|
12583
12565
|
},
|
|
12584
12566
|
{},
|
|
12585
|
-
void 0,
|
|
12586
12567
|
{ schema: "sys" }
|
|
12587
12568
|
);
|
|
12588
12569
|
var SysTables = defineTable(
|
|
@@ -12594,7 +12575,6 @@ var SysTables = defineTable(
|
|
|
12594
12575
|
is_ms_shipped: col.boolean()
|
|
12595
12576
|
},
|
|
12596
12577
|
{},
|
|
12597
|
-
void 0,
|
|
12598
12578
|
{ schema: "sys" }
|
|
12599
12579
|
);
|
|
12600
12580
|
var SysSchemas = defineTable(
|
|
@@ -12604,7 +12584,6 @@ var SysSchemas = defineTable(
|
|
|
12604
12584
|
name: col.varchar(255)
|
|
12605
12585
|
},
|
|
12606
12586
|
{},
|
|
12607
|
-
void 0,
|
|
12608
12587
|
{ schema: "sys" }
|
|
12609
12588
|
);
|
|
12610
12589
|
var SysTypes = defineTable(
|
|
@@ -12614,7 +12593,6 @@ var SysTypes = defineTable(
|
|
|
12614
12593
|
name: col.varchar(255)
|
|
12615
12594
|
},
|
|
12616
12595
|
{},
|
|
12617
|
-
void 0,
|
|
12618
12596
|
{ schema: "sys" }
|
|
12619
12597
|
);
|
|
12620
12598
|
var SysIndexes = defineTable(
|
|
@@ -12630,7 +12608,6 @@ var SysIndexes = defineTable(
|
|
|
12630
12608
|
is_hypothetical: col.boolean()
|
|
12631
12609
|
},
|
|
12632
12610
|
{},
|
|
12633
|
-
void 0,
|
|
12634
12611
|
{ schema: "sys" }
|
|
12635
12612
|
);
|
|
12636
12613
|
var SysIndexColumns = defineTable(
|
|
@@ -12642,7 +12619,6 @@ var SysIndexColumns = defineTable(
|
|
|
12642
12619
|
key_ordinal: col.int()
|
|
12643
12620
|
},
|
|
12644
12621
|
{},
|
|
12645
|
-
void 0,
|
|
12646
12622
|
{ schema: "sys" }
|
|
12647
12623
|
);
|
|
12648
12624
|
var SysForeignKeys = defineTable(
|
|
@@ -12654,7 +12630,6 @@ var SysForeignKeys = defineTable(
|
|
|
12654
12630
|
update_referential_action_desc: col.varchar(64)
|
|
12655
12631
|
},
|
|
12656
12632
|
{},
|
|
12657
|
-
void 0,
|
|
12658
12633
|
{ schema: "sys" }
|
|
12659
12634
|
);
|
|
12660
12635
|
var SysForeignKeyColumns = defineTable(
|
|
@@ -12668,7 +12643,6 @@ var SysForeignKeyColumns = defineTable(
|
|
|
12668
12643
|
constraint_column_id: col.int()
|
|
12669
12644
|
},
|
|
12670
12645
|
{},
|
|
12671
|
-
void 0,
|
|
12672
12646
|
{ schema: "sys" }
|
|
12673
12647
|
);
|
|
12674
12648
|
|
|
@@ -14093,12 +14067,14 @@ var UnitOfWork = class {
|
|
|
14093
14067
|
* @param executor - The database executor
|
|
14094
14068
|
* @param identityMap - The identity map
|
|
14095
14069
|
* @param hookContext - Function to get the hook context
|
|
14070
|
+
* @param resolveTableHooks - Session/runtime lifecycle hook resolver
|
|
14096
14071
|
*/
|
|
14097
|
-
constructor(dialect, executor, identityMap, hookContext) {
|
|
14072
|
+
constructor(dialect, executor, identityMap, hookContext, resolveTableHooks = () => void 0) {
|
|
14098
14073
|
this.dialect = dialect;
|
|
14099
14074
|
this.executor = executor;
|
|
14100
14075
|
this.identityMap = identityMap;
|
|
14101
14076
|
this.hookContext = hookContext;
|
|
14077
|
+
this.resolveTableHooks = resolveTableHooks;
|
|
14102
14078
|
}
|
|
14103
14079
|
trackedEntities = /* @__PURE__ */ new Map();
|
|
14104
14080
|
/**
|
|
@@ -14250,7 +14226,8 @@ var UnitOfWork = class {
|
|
|
14250
14226
|
* @param tracked - The tracked entity to insert
|
|
14251
14227
|
*/
|
|
14252
14228
|
async flushInsert(tracked) {
|
|
14253
|
-
|
|
14229
|
+
const hooks = this.resolveTableHooks(tracked.table);
|
|
14230
|
+
await this.runHook(hooks?.beforeInsert, tracked);
|
|
14254
14231
|
const payload = this.extractColumns(tracked.table, tracked.entity);
|
|
14255
14232
|
let builder = new InsertQueryBuilder(tracked.table).values(payload);
|
|
14256
14233
|
if (this.dialect.supportsDmlReturningClause()) {
|
|
@@ -14264,7 +14241,7 @@ var UnitOfWork = class {
|
|
|
14264
14241
|
tracked.original = this.createSnapshot(tracked.table, tracked.entity);
|
|
14265
14242
|
tracked.pk = this.getPrimaryKeyValue(tracked);
|
|
14266
14243
|
this.registerIdentity(tracked);
|
|
14267
|
-
await this.runHook(
|
|
14244
|
+
await this.runHook(hooks?.afterInsert, tracked);
|
|
14268
14245
|
}
|
|
14269
14246
|
/**
|
|
14270
14247
|
* Flushes an update operation for a modified entity.
|
|
@@ -14277,7 +14254,8 @@ var UnitOfWork = class {
|
|
|
14277
14254
|
tracked.status = "managed" /* Managed */;
|
|
14278
14255
|
return;
|
|
14279
14256
|
}
|
|
14280
|
-
|
|
14257
|
+
const hooks = this.resolveTableHooks(tracked.table);
|
|
14258
|
+
await this.runHook(hooks?.beforeUpdate, tracked);
|
|
14281
14259
|
const pkColumn = tracked.table.columns[findPrimaryKey(tracked.table)];
|
|
14282
14260
|
if (!pkColumn) return;
|
|
14283
14261
|
let builder = new UpdateQueryBuilder(tracked.table).set(changes).where(eq(pkColumn, tracked.pk));
|
|
@@ -14290,7 +14268,7 @@ var UnitOfWork = class {
|
|
|
14290
14268
|
tracked.status = "managed" /* Managed */;
|
|
14291
14269
|
tracked.original = this.createSnapshot(tracked.table, tracked.entity);
|
|
14292
14270
|
this.registerIdentity(tracked);
|
|
14293
|
-
await this.runHook(
|
|
14271
|
+
await this.runHook(hooks?.afterUpdate, tracked);
|
|
14294
14272
|
}
|
|
14295
14273
|
/**
|
|
14296
14274
|
* Flushes a delete operation for a removed entity.
|
|
@@ -14298,7 +14276,8 @@ var UnitOfWork = class {
|
|
|
14298
14276
|
*/
|
|
14299
14277
|
async flushDelete(tracked) {
|
|
14300
14278
|
if (tracked.pk == null) return;
|
|
14301
|
-
|
|
14279
|
+
const hooks = this.resolveTableHooks(tracked.table);
|
|
14280
|
+
await this.runHook(hooks?.beforeDelete, tracked);
|
|
14302
14281
|
const pkColumn = tracked.table.columns[findPrimaryKey(tracked.table)];
|
|
14303
14282
|
if (!pkColumn) return;
|
|
14304
14283
|
const builder = new DeleteQueryBuilder(tracked.table).where(eq(pkColumn, tracked.pk));
|
|
@@ -14307,10 +14286,10 @@ var UnitOfWork = class {
|
|
|
14307
14286
|
tracked.status = "detached" /* Detached */;
|
|
14308
14287
|
this.trackedEntities.delete(tracked.entity);
|
|
14309
14288
|
this.identityMap.remove(tracked);
|
|
14310
|
-
await this.runHook(
|
|
14289
|
+
await this.runHook(hooks?.afterDelete, tracked);
|
|
14311
14290
|
}
|
|
14312
14291
|
/**
|
|
14313
|
-
* Runs a
|
|
14292
|
+
* Runs a lifecycle hook if defined.
|
|
14314
14293
|
* @param hook - The hook function
|
|
14315
14294
|
* @param tracked - The tracked entity
|
|
14316
14295
|
*/
|
|
@@ -14629,7 +14608,10 @@ var RelationChangeProcessor = class {
|
|
|
14629
14608
|
const rootKey = relation.localKey || findPrimaryKey(entry.rootTable);
|
|
14630
14609
|
const rootId = entry.root[rootKey];
|
|
14631
14610
|
if (rootId === void 0 || rootId === null) return;
|
|
14632
|
-
const targetId = this.
|
|
14611
|
+
const targetId = this.resolveBelongsToManyTargetValue(
|
|
14612
|
+
entry.change.entity,
|
|
14613
|
+
relation
|
|
14614
|
+
);
|
|
14633
14615
|
if (targetId === null) return;
|
|
14634
14616
|
const pivotPayload = this.buildPivotPayload(relation, entry.change.pivot);
|
|
14635
14617
|
if (entry.change.kind === "update") {
|
|
@@ -14701,7 +14683,7 @@ var RelationChangeProcessor = class {
|
|
|
14701
14683
|
* Inserts a pivot row for belongs-to-many relations.
|
|
14702
14684
|
* @param relation - The belongs-to-many relation
|
|
14703
14685
|
* @param rootId - The root entity's primary key value
|
|
14704
|
-
* @param targetId - The target entity's
|
|
14686
|
+
* @param targetId - The target entity's relation key value
|
|
14705
14687
|
*/
|
|
14706
14688
|
async insertPivotRow(relation, rootId, targetId, pivotPayload) {
|
|
14707
14689
|
const payload = {
|
|
@@ -14717,7 +14699,7 @@ var RelationChangeProcessor = class {
|
|
|
14717
14699
|
* Updates a pivot row for belongs-to-many relations.
|
|
14718
14700
|
* @param relation - The belongs-to-many relation
|
|
14719
14701
|
* @param rootId - The root entity's primary key value
|
|
14720
|
-
* @param targetId - The target entity's
|
|
14702
|
+
* @param targetId - The target entity's relation key value
|
|
14721
14703
|
* @param pivotPayload - The pivot columns to update
|
|
14722
14704
|
*/
|
|
14723
14705
|
async updatePivotRow(relation, rootId, targetId, pivotPayload) {
|
|
@@ -14732,7 +14714,7 @@ var RelationChangeProcessor = class {
|
|
|
14732
14714
|
* Deletes a pivot row for belongs-to-many relations.
|
|
14733
14715
|
* @param relation - The belongs-to-many relation
|
|
14734
14716
|
* @param rootId - The root entity's primary key value
|
|
14735
|
-
* @param targetId - The target entity's
|
|
14717
|
+
* @param targetId - The target entity's relation key value
|
|
14736
14718
|
*/
|
|
14737
14719
|
async deletePivotRow(relation, rootId, targetId) {
|
|
14738
14720
|
const rootCol = relation.pivotTable.columns[relation.pivotForeignKeyToRoot];
|
|
@@ -14745,14 +14727,13 @@ var RelationChangeProcessor = class {
|
|
|
14745
14727
|
await this.executor.executeSql(compiled.sql, compiled.params);
|
|
14746
14728
|
}
|
|
14747
14729
|
/**
|
|
14748
|
-
* Resolves the
|
|
14749
|
-
*
|
|
14750
|
-
*
|
|
14751
|
-
* @returns The primary key value or null
|
|
14730
|
+
* Resolves the target-side key value used by a belongs-to-many relation.
|
|
14731
|
+
* The declared targetKey is part of the relation contract and takes
|
|
14732
|
+
* precedence over the target table primary key.
|
|
14752
14733
|
*/
|
|
14753
|
-
|
|
14734
|
+
resolveBelongsToManyTargetValue(entity, relation) {
|
|
14754
14735
|
if (!entity) return null;
|
|
14755
|
-
const key = findPrimaryKey(
|
|
14736
|
+
const key = relation.targetKey || findPrimaryKey(relation.target);
|
|
14756
14737
|
const value = entity[key];
|
|
14757
14738
|
if (value === void 0 || value === null) return null;
|
|
14758
14739
|
return value ?? null;
|
|
@@ -15213,6 +15194,7 @@ var OrmSession = class {
|
|
|
15213
15194
|
/** The tenant ID for multi-tenancy support */
|
|
15214
15195
|
tenantId;
|
|
15215
15196
|
interceptors;
|
|
15197
|
+
tableHooks = /* @__PURE__ */ new WeakMap();
|
|
15216
15198
|
saveGraphDefaults;
|
|
15217
15199
|
transactionDepth = 0;
|
|
15218
15200
|
savepointCounter = 0;
|
|
@@ -15226,7 +15208,13 @@ var OrmSession = class {
|
|
|
15226
15208
|
this.executor = createQueryLoggingExecutor(opts.executor, opts.queryLogger);
|
|
15227
15209
|
this.interceptors = [...opts.interceptors ?? []];
|
|
15228
15210
|
this.identityMap = new IdentityMap();
|
|
15229
|
-
this.unitOfWork = new UnitOfWork(
|
|
15211
|
+
this.unitOfWork = new UnitOfWork(
|
|
15212
|
+
this.orm.dialect,
|
|
15213
|
+
this.executor,
|
|
15214
|
+
this.identityMap,
|
|
15215
|
+
() => this,
|
|
15216
|
+
(table) => this.tableHooks.get(table)
|
|
15217
|
+
);
|
|
15230
15218
|
this.relationChanges = new RelationChangeProcessor(this.unitOfWork, this.orm.dialect, this.executor);
|
|
15231
15219
|
this.domainEvents = new DomainEventBus(opts.domainEventHandlers);
|
|
15232
15220
|
this.cacheManager = opts.cacheManager;
|
|
@@ -15334,6 +15322,18 @@ var OrmSession = class {
|
|
|
15334
15322
|
getEntitiesForTable(table) {
|
|
15335
15323
|
return this.unitOfWork.getEntitiesForTable(table);
|
|
15336
15324
|
}
|
|
15325
|
+
/**
|
|
15326
|
+
* Registers INSERT/UPDATE/DELETE lifecycle hooks for this Session only.
|
|
15327
|
+
* The target can be a TableDef or a decorated entity constructor.
|
|
15328
|
+
* Registering again for the same table replaces the previous hook set.
|
|
15329
|
+
*/
|
|
15330
|
+
registerTableHooks(target, hooks) {
|
|
15331
|
+
const table = typeof target === "function" ? getTableDefFromEntity(target) : target;
|
|
15332
|
+
if (!table) {
|
|
15333
|
+
throw new Error("Entity metadata has not been bootstrapped");
|
|
15334
|
+
}
|
|
15335
|
+
this.tableHooks.set(table, hooks);
|
|
15336
|
+
}
|
|
15337
15337
|
/**
|
|
15338
15338
|
* Registers an interceptor for flush lifecycle hooks.
|
|
15339
15339
|
* @param interceptor - The interceptor to register
|
|
@@ -15344,7 +15344,7 @@ var OrmSession = class {
|
|
|
15344
15344
|
/**
|
|
15345
15345
|
* Registers a domain event handler.
|
|
15346
15346
|
* @param type - The event type
|
|
15347
|
-
* @param handler - The event handler
|
|
15347
|
+
* @param handler - The domain event handler
|
|
15348
15348
|
*/
|
|
15349
15349
|
registerDomainEventHandler(type, handler) {
|
|
15350
15350
|
this.domainEvents.on(type, handler);
|
|
@@ -15518,7 +15518,9 @@ var OrmSession = class {
|
|
|
15518
15518
|
this.markRemoved(entity);
|
|
15519
15519
|
}
|
|
15520
15520
|
/**
|
|
15521
|
-
* Flushes pending changes to the database without session
|
|
15521
|
+
* Flushes pending changes to the database without session interceptors,
|
|
15522
|
+
* relation processing, or domain events. Table lifecycle hooks still run
|
|
15523
|
+
* because they are part of the Unit of Work.
|
|
15522
15524
|
*/
|
|
15523
15525
|
async flush() {
|
|
15524
15526
|
await this.unitOfWork.flush();
|
|
@@ -16413,7 +16415,7 @@ function Entity(options = {}) {
|
|
|
16413
16415
|
return function(value, context) {
|
|
16414
16416
|
const ctor = value;
|
|
16415
16417
|
const tableName = options.tableName ?? deriveTableNameFromConstructor(ctor);
|
|
16416
|
-
setEntityTableName(ctor, tableName, options.
|
|
16418
|
+
setEntityTableName(ctor, tableName, options.type);
|
|
16417
16419
|
const bag = context ? readMetadataBag(context) : readMetadataBagFromConstructor(ctor);
|
|
16418
16420
|
if (bag) {
|
|
16419
16421
|
const meta = ensureEntityMetadata(ctor);
|
|
@@ -20633,7 +20635,7 @@ var TreeManager = class _TreeManager {
|
|
|
20633
20635
|
* Moves a node to be the last child of a new parent.
|
|
20634
20636
|
*/
|
|
20635
20637
|
async moveTo(node, newParentId) {
|
|
20636
|
-
NestedSetStrategy.subtreeWidth(node.lft, node.rght);
|
|
20638
|
+
const width = NestedSetStrategy.subtreeWidth(node.lft, node.rght);
|
|
20637
20639
|
let newPos;
|
|
20638
20640
|
if (newParentId === null) {
|
|
20639
20641
|
const maxRght = await this.getMaxRght();
|
|
@@ -20648,7 +20650,8 @@ var TreeManager = class _TreeManager {
|
|
|
20648
20650
|
newParent.depth ?? await this.getLevel(newParent)
|
|
20649
20651
|
);
|
|
20650
20652
|
}
|
|
20651
|
-
|
|
20653
|
+
const targetLft = newPos.lft > node.rght ? newPos.lft - width : newPos.lft;
|
|
20654
|
+
await this.moveSubtree(node, targetLft, newParentId, newPos.depth);
|
|
20652
20655
|
}
|
|
20653
20656
|
/**
|
|
20654
20657
|
* Inserts a new node as a child of a parent.
|
|
@@ -20687,7 +20690,10 @@ var TreeManager = class _TreeManager {
|
|
|
20687
20690
|
if (insertData[this.pkName] !== void 0) {
|
|
20688
20691
|
return insertData[this.pkName];
|
|
20689
20692
|
}
|
|
20690
|
-
const
|
|
20693
|
+
const scopeExpressions = this.getScopeExpressions();
|
|
20694
|
+
const lftCondition = eq(this.table.columns[this.config.leftKey], insertPos.lft);
|
|
20695
|
+
const findCondition = scopeExpressions.length > 0 ? and(lftCondition, ...scopeExpressions) : lftCondition;
|
|
20696
|
+
const findQuery = selectFrom(this.table).where(findCondition);
|
|
20691
20697
|
const { sql: findSql, params: findParams } = findQuery.compile(this.dialect);
|
|
20692
20698
|
const results = await this.executor.executeSql(findSql, findParams);
|
|
20693
20699
|
const rows = queryResultsToRows(results);
|
|
@@ -20697,23 +20703,37 @@ var TreeManager = class _TreeManager {
|
|
|
20697
20703
|
return void 0;
|
|
20698
20704
|
}
|
|
20699
20705
|
/**
|
|
20700
|
-
* Removes a node
|
|
20706
|
+
* Removes a node from its current tree position, promotes its direct children
|
|
20707
|
+
* to the removed node's parent, and retains the removed row as a standalone root.
|
|
20701
20708
|
*/
|
|
20702
20709
|
async removeFromTree(node) {
|
|
20703
20710
|
const nodeId = node.data[this.pkName];
|
|
20711
|
+
const originalMaxRght = await this.getMaxRght();
|
|
20704
20712
|
await this.executeUpdate(
|
|
20705
20713
|
eq(this.table.columns[this.config.parentKey], nodeId),
|
|
20706
20714
|
{ [this.config.parentKey]: node.parentId }
|
|
20707
20715
|
);
|
|
20708
|
-
|
|
20716
|
+
if (node.rght - node.lft > 1) {
|
|
20717
|
+
let sql = `UPDATE ${this.quoteTable()} SET ${this.quoteCol(this.config.leftKey)} = ${this.quoteCol(this.config.leftKey)} - 1, ${this.quoteCol(this.config.rightKey)} = ${this.quoteCol(this.config.rightKey)} - 1`;
|
|
20718
|
+
if (this.config.depthKey) {
|
|
20719
|
+
sql += `, ${this.quoteCol(this.config.depthKey)} = ${this.quoteCol(this.config.depthKey)} - 1`;
|
|
20720
|
+
}
|
|
20721
|
+
sql += ` WHERE ${this.quoteCol(this.config.leftKey)} > ? AND ${this.quoteCol(this.config.rightKey)} < ?`;
|
|
20722
|
+
await this.executeRawUpdate(sql, [node.lft, node.rght]);
|
|
20723
|
+
}
|
|
20709
20724
|
await this.shiftForDelete(node.rght, 2);
|
|
20710
|
-
|
|
20711
|
-
|
|
20712
|
-
|
|
20713
|
-
|
|
20714
|
-
|
|
20715
|
-
|
|
20725
|
+
const detachedData = {
|
|
20726
|
+
[this.config.parentKey]: null,
|
|
20727
|
+
[this.config.leftKey]: originalMaxRght - 1,
|
|
20728
|
+
[this.config.rightKey]: originalMaxRght
|
|
20729
|
+
};
|
|
20730
|
+
if (this.config.depthKey) {
|
|
20731
|
+
detachedData[this.config.depthKey] = 0;
|
|
20716
20732
|
}
|
|
20733
|
+
await this.executeUpdate(
|
|
20734
|
+
eq(this.table.columns[this.pkName], nodeId),
|
|
20735
|
+
detachedData
|
|
20736
|
+
);
|
|
20717
20737
|
}
|
|
20718
20738
|
/**
|
|
20719
20739
|
* Deletes a node and all its descendants.
|
|
@@ -20838,22 +20858,32 @@ var TreeManager = class _TreeManager {
|
|
|
20838
20858
|
}
|
|
20839
20859
|
return "id";
|
|
20840
20860
|
}
|
|
20861
|
+
getScopeEntries() {
|
|
20862
|
+
return Object.entries(buildScopeConditions(this.config.scope, this.scopeValues));
|
|
20863
|
+
}
|
|
20864
|
+
getScopeExpressions() {
|
|
20865
|
+
return this.getScopeEntries().map(
|
|
20866
|
+
([key, value]) => eq(this.table.columns[key], value)
|
|
20867
|
+
);
|
|
20868
|
+
}
|
|
20841
20869
|
async getMaxRght() {
|
|
20842
20870
|
const query = selectFrom(this.table).selectRaw(`MAX(${this.config.rightKey}) as max_rght`);
|
|
20843
|
-
const
|
|
20871
|
+
const scopeExpressions = this.getScopeExpressions();
|
|
20872
|
+
const finalQuery = scopeExpressions.length > 0 ? query.where(and(...scopeExpressions)) : query;
|
|
20873
|
+
const { sql, params } = finalQuery.compile(this.dialect);
|
|
20844
20874
|
const queryResults = await this.executor.executeSql(sql, params);
|
|
20845
20875
|
const rows = queryResultsToRows(queryResults);
|
|
20846
20876
|
const maxRght = rows[0]?.max_rght;
|
|
20847
20877
|
return typeof maxRght === "number" ? maxRght : 0;
|
|
20848
20878
|
}
|
|
20849
|
-
async shiftForInsert(insertPoint) {
|
|
20879
|
+
async shiftForInsert(insertPoint, width = 2) {
|
|
20850
20880
|
await this.executeRawUpdate(
|
|
20851
|
-
`UPDATE ${this.quoteTable()} SET ${this.quoteCol(this.config.rightKey)} = ${this.quoteCol(this.config.rightKey)} +
|
|
20852
|
-
[insertPoint]
|
|
20881
|
+
`UPDATE ${this.quoteTable()} SET ${this.quoteCol(this.config.rightKey)} = ${this.quoteCol(this.config.rightKey)} + ? WHERE ${this.quoteCol(this.config.rightKey)} >= ?`,
|
|
20882
|
+
[width, insertPoint]
|
|
20853
20883
|
);
|
|
20854
20884
|
await this.executeRawUpdate(
|
|
20855
|
-
`UPDATE ${this.quoteTable()} SET ${this.quoteCol(this.config.leftKey)} = ${this.quoteCol(this.config.leftKey)} +
|
|
20856
|
-
[insertPoint]
|
|
20885
|
+
`UPDATE ${this.quoteTable()} SET ${this.quoteCol(this.config.leftKey)} = ${this.quoteCol(this.config.leftKey)} + ? WHERE ${this.quoteCol(this.config.leftKey)} > ?`,
|
|
20886
|
+
[width, insertPoint]
|
|
20857
20887
|
);
|
|
20858
20888
|
}
|
|
20859
20889
|
async shiftForDelete(deletedRght, width) {
|
|
@@ -20889,28 +20919,27 @@ var TreeManager = class _TreeManager {
|
|
|
20889
20919
|
}
|
|
20890
20920
|
async moveSubtree(node, newLft, newParentId, newDepth) {
|
|
20891
20921
|
const width = NestedSetStrategy.subtreeWidth(node.lft, node.rght);
|
|
20892
|
-
const
|
|
20893
|
-
const depthDelta = this.config.depthKey ? newDepth -
|
|
20922
|
+
const oldDepth = this.config.depthKey ? node.depth ?? await this.getLevel(node) : 0;
|
|
20923
|
+
const depthDelta = this.config.depthKey ? newDepth - oldDepth : 0;
|
|
20894
20924
|
const nodeId = node.data[this.pkName];
|
|
20895
|
-
const
|
|
20925
|
+
const isolateDelta = -1e7 - node.rght;
|
|
20926
|
+
const isolatedLft = node.lft + isolateDelta;
|
|
20927
|
+
const isolatedRght = node.rght + isolateDelta;
|
|
20896
20928
|
await this.executeRawUpdate(
|
|
20897
|
-
`UPDATE ${this.quoteTable()} SET ${this.quoteCol(this.config.leftKey)} = ${this.quoteCol(this.config.leftKey)} + ? WHERE ${this.quoteCol(this.config.leftKey)} >= ? AND ${this.quoteCol(this.config.rightKey)} <= ?`,
|
|
20898
|
-
[
|
|
20899
|
-
);
|
|
20900
|
-
await this.executeRawUpdate(
|
|
20901
|
-
`UPDATE ${this.quoteTable()} SET ${this.quoteCol(this.config.rightKey)} = ${this.quoteCol(this.config.rightKey)} + ? WHERE ${this.quoteCol(this.config.leftKey)} >= ? AND ${this.quoteCol(this.config.rightKey)} <= ?`,
|
|
20902
|
-
[tempOffset, node.lft + tempOffset, node.rght]
|
|
20929
|
+
`UPDATE ${this.quoteTable()} SET ${this.quoteCol(this.config.leftKey)} = ${this.quoteCol(this.config.leftKey)} + ?, ${this.quoteCol(this.config.rightKey)} = ${this.quoteCol(this.config.rightKey)} + ? WHERE ${this.quoteCol(this.config.leftKey)} >= ? AND ${this.quoteCol(this.config.rightKey)} <= ?`,
|
|
20930
|
+
[isolateDelta, isolateDelta, node.lft, node.rght]
|
|
20903
20931
|
);
|
|
20904
20932
|
await this.shiftForDelete(node.rght, width);
|
|
20905
|
-
await this.shiftForInsert(newLft);
|
|
20906
|
-
|
|
20907
|
-
|
|
20933
|
+
await this.shiftForInsert(newLft, width);
|
|
20934
|
+
const restoreDelta = newLft - node.lft - isolateDelta;
|
|
20935
|
+
let updateSql = `UPDATE ${this.quoteTable()} SET ${this.quoteCol(this.config.leftKey)} = ${this.quoteCol(this.config.leftKey)} + ?, ${this.quoteCol(this.config.rightKey)} = ${this.quoteCol(this.config.rightKey)} + ?`;
|
|
20936
|
+
const updateParams = [restoreDelta, restoreDelta];
|
|
20908
20937
|
if (this.config.depthKey && depthDelta !== 0) {
|
|
20909
20938
|
updateSql += `, ${this.quoteCol(this.config.depthKey)} = ${this.quoteCol(this.config.depthKey)} + ?`;
|
|
20910
20939
|
updateParams.push(depthDelta);
|
|
20911
20940
|
}
|
|
20912
|
-
updateSql += ` WHERE ${this.quoteCol(this.config.leftKey)} >= ?`;
|
|
20913
|
-
updateParams.push(
|
|
20941
|
+
updateSql += ` WHERE ${this.quoteCol(this.config.leftKey)} >= ? AND ${this.quoteCol(this.config.rightKey)} <= ?`;
|
|
20942
|
+
updateParams.push(isolatedLft, isolatedRght);
|
|
20914
20943
|
await this.executeRawUpdate(updateSql, updateParams);
|
|
20915
20944
|
await this.executeUpdate(
|
|
20916
20945
|
eq(this.table.columns[this.pkName], nodeId),
|
|
@@ -20935,12 +20964,23 @@ var TreeManager = class _TreeManager {
|
|
|
20935
20964
|
}));
|
|
20936
20965
|
}
|
|
20937
20966
|
async executeUpdate(condition, data) {
|
|
20938
|
-
const
|
|
20967
|
+
const scopeExpressions = this.getScopeExpressions();
|
|
20968
|
+
const finalCondition = scopeExpressions.length > 0 ? and(condition, ...scopeExpressions) : condition;
|
|
20969
|
+
const query = update(this.table).set(data).where(finalCondition);
|
|
20939
20970
|
const { sql, params } = query.compile(this.dialect);
|
|
20940
20971
|
await this.executor.executeSql(sql, params);
|
|
20941
20972
|
}
|
|
20942
20973
|
async executeRawUpdate(sql, params) {
|
|
20943
|
-
|
|
20974
|
+
let scopedSql = sql;
|
|
20975
|
+
const scopedParams = [...params];
|
|
20976
|
+
let hasWhere = /\bWHERE\b/i.test(scopedSql);
|
|
20977
|
+
for (const [key, value] of this.getScopeEntries()) {
|
|
20978
|
+
scopedSql += hasWhere ? " AND " : " WHERE ";
|
|
20979
|
+
scopedSql += `${this.quoteCol(key)} = ?`;
|
|
20980
|
+
scopedParams.push(value);
|
|
20981
|
+
hasWhere = true;
|
|
20982
|
+
}
|
|
20983
|
+
await this.executor.executeSql(scopedSql, scopedParams);
|
|
20944
20984
|
}
|
|
20945
20985
|
quoteTable() {
|
|
20946
20986
|
const quote = this.getQuoteChar();
|