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.cjs
CHANGED
|
@@ -477,7 +477,7 @@ __export(index_exports, {
|
|
|
477
477
|
module.exports = __toCommonJS(index_exports);
|
|
478
478
|
|
|
479
479
|
// src/schema/table.ts
|
|
480
|
-
var defineTable = (name, columns, relations = {},
|
|
480
|
+
var defineTable = (name, columns, relations = {}, options = {}) => {
|
|
481
481
|
const colsWithNames = Object.entries(columns).reduce((acc, [key, def]) => {
|
|
482
482
|
const colDef = { ...def, name: key, table: name };
|
|
483
483
|
acc[key] = colDef;
|
|
@@ -488,7 +488,6 @@ var defineTable = (name, columns, relations = {}, hooks, options = {}) => {
|
|
|
488
488
|
schema: options.schema,
|
|
489
489
|
columns: colsWithNames,
|
|
490
490
|
relations,
|
|
491
|
-
hooks,
|
|
492
491
|
primaryKey: options.primaryKey,
|
|
493
492
|
indexes: options.indexes,
|
|
494
493
|
checks: options.checks,
|
|
@@ -8404,14 +8403,11 @@ var addTransformerMetadata = (target, propertyKey, transformer) => {
|
|
|
8404
8403
|
const meta = ensureEntityMetadata(target);
|
|
8405
8404
|
meta.transformers[propertyKey] = transformer;
|
|
8406
8405
|
};
|
|
8407
|
-
var setEntityTableName = (target, tableName,
|
|
8406
|
+
var setEntityTableName = (target, tableName, type) => {
|
|
8408
8407
|
const meta = ensureEntityMetadata(target);
|
|
8409
8408
|
if (tableName && tableName.length > 0) {
|
|
8410
8409
|
meta.tableName = tableName;
|
|
8411
8410
|
}
|
|
8412
|
-
if (hooks) {
|
|
8413
|
-
meta.hooks = hooks;
|
|
8414
|
-
}
|
|
8415
8411
|
if (type) {
|
|
8416
8412
|
meta.type = type;
|
|
8417
8413
|
}
|
|
@@ -8428,7 +8424,7 @@ var buildTableDef = (meta) => {
|
|
|
8428
8424
|
table: meta.tableName
|
|
8429
8425
|
};
|
|
8430
8426
|
}
|
|
8431
|
-
const table = defineTable(meta.tableName, columns
|
|
8427
|
+
const table = defineTable(meta.tableName, columns);
|
|
8432
8428
|
meta.table = table;
|
|
8433
8429
|
return table;
|
|
8434
8430
|
};
|
|
@@ -11850,7 +11846,6 @@ var PgInformationSchemaColumns = defineTable(
|
|
|
11850
11846
|
ordinal_position: col.int()
|
|
11851
11847
|
},
|
|
11852
11848
|
{},
|
|
11853
|
-
void 0,
|
|
11854
11849
|
{ schema: "information_schema" }
|
|
11855
11850
|
);
|
|
11856
11851
|
var PgClass = defineTable(
|
|
@@ -11862,7 +11857,6 @@ var PgClass = defineTable(
|
|
|
11862
11857
|
relkind: col.varchar(1)
|
|
11863
11858
|
},
|
|
11864
11859
|
{},
|
|
11865
|
-
void 0,
|
|
11866
11860
|
{ schema: "pg_catalog" }
|
|
11867
11861
|
);
|
|
11868
11862
|
var PgNamespace = defineTable(
|
|
@@ -11872,7 +11866,6 @@ var PgNamespace = defineTable(
|
|
|
11872
11866
|
nspname: col.varchar(255)
|
|
11873
11867
|
},
|
|
11874
11868
|
{},
|
|
11875
|
-
void 0,
|
|
11876
11869
|
{ schema: "pg_catalog" }
|
|
11877
11870
|
);
|
|
11878
11871
|
var PgIndex = defineTable(
|
|
@@ -11885,7 +11878,6 @@ var PgIndex = defineTable(
|
|
|
11885
11878
|
indpred: col.varchar(1024)
|
|
11886
11879
|
},
|
|
11887
11880
|
{},
|
|
11888
|
-
void 0,
|
|
11889
11881
|
{ schema: "pg_catalog" }
|
|
11890
11882
|
);
|
|
11891
11883
|
var PgAttribute = defineTable(
|
|
@@ -11896,7 +11888,6 @@ var PgAttribute = defineTable(
|
|
|
11896
11888
|
attnum: col.int()
|
|
11897
11889
|
},
|
|
11898
11890
|
{},
|
|
11899
|
-
void 0,
|
|
11900
11891
|
{ schema: "pg_catalog" }
|
|
11901
11892
|
);
|
|
11902
11893
|
var PgTableConstraints = defineTable(
|
|
@@ -11911,7 +11902,6 @@ var PgTableConstraints = defineTable(
|
|
|
11911
11902
|
constraint_type: col.varchar(255)
|
|
11912
11903
|
},
|
|
11913
11904
|
{},
|
|
11914
|
-
void 0,
|
|
11915
11905
|
{ schema: "information_schema" }
|
|
11916
11906
|
);
|
|
11917
11907
|
var PgKeyColumnUsage = defineTable(
|
|
@@ -11927,7 +11917,6 @@ var PgKeyColumnUsage = defineTable(
|
|
|
11927
11917
|
ordinal_position: col.int()
|
|
11928
11918
|
},
|
|
11929
11919
|
{},
|
|
11930
|
-
void 0,
|
|
11931
11920
|
{ schema: "information_schema" }
|
|
11932
11921
|
);
|
|
11933
11922
|
var PgConstraintColumnUsage = defineTable(
|
|
@@ -11942,7 +11931,6 @@ var PgConstraintColumnUsage = defineTable(
|
|
|
11942
11931
|
column_name: col.varchar(255)
|
|
11943
11932
|
},
|
|
11944
11933
|
{},
|
|
11945
|
-
void 0,
|
|
11946
11934
|
{ schema: "information_schema" }
|
|
11947
11935
|
);
|
|
11948
11936
|
var PgReferentialConstraints = defineTable(
|
|
@@ -11959,7 +11947,6 @@ var PgReferentialConstraints = defineTable(
|
|
|
11959
11947
|
delete_rule: col.varchar(64)
|
|
11960
11948
|
},
|
|
11961
11949
|
{},
|
|
11962
|
-
void 0,
|
|
11963
11950
|
{ schema: "information_schema" }
|
|
11964
11951
|
);
|
|
11965
11952
|
|
|
@@ -12341,7 +12328,6 @@ var InformationSchemaTables = defineTable(
|
|
|
12341
12328
|
table_comment: col.varchar(1024)
|
|
12342
12329
|
},
|
|
12343
12330
|
{},
|
|
12344
|
-
void 0,
|
|
12345
12331
|
{ schema: INFORMATION_SCHEMA }
|
|
12346
12332
|
);
|
|
12347
12333
|
var InformationSchemaColumns = defineTable(
|
|
@@ -12359,7 +12345,6 @@ var InformationSchemaColumns = defineTable(
|
|
|
12359
12345
|
ordinal_position: col.int()
|
|
12360
12346
|
},
|
|
12361
12347
|
{},
|
|
12362
|
-
void 0,
|
|
12363
12348
|
{ schema: INFORMATION_SCHEMA }
|
|
12364
12349
|
);
|
|
12365
12350
|
var InformationSchemaKeyColumnUsage = defineTable(
|
|
@@ -12376,7 +12361,6 @@ var InformationSchemaKeyColumnUsage = defineTable(
|
|
|
12376
12361
|
referenced_column_name: col.varchar(255)
|
|
12377
12362
|
},
|
|
12378
12363
|
{},
|
|
12379
|
-
void 0,
|
|
12380
12364
|
{ schema: INFORMATION_SCHEMA }
|
|
12381
12365
|
);
|
|
12382
12366
|
var InformationSchemaReferentialConstraints = defineTable(
|
|
@@ -12388,7 +12372,6 @@ var InformationSchemaReferentialConstraints = defineTable(
|
|
|
12388
12372
|
update_rule: col.varchar(255)
|
|
12389
12373
|
},
|
|
12390
12374
|
{},
|
|
12391
|
-
void 0,
|
|
12392
12375
|
{ schema: INFORMATION_SCHEMA }
|
|
12393
12376
|
);
|
|
12394
12377
|
var InformationSchemaStatistics = defineTable(
|
|
@@ -12402,7 +12385,6 @@ var InformationSchemaStatistics = defineTable(
|
|
|
12402
12385
|
seq_in_index: col.int()
|
|
12403
12386
|
},
|
|
12404
12387
|
{},
|
|
12405
|
-
void 0,
|
|
12406
12388
|
{ schema: INFORMATION_SCHEMA }
|
|
12407
12389
|
);
|
|
12408
12390
|
|
|
@@ -13023,7 +13005,6 @@ var SysColumns = defineTable(
|
|
|
13023
13005
|
user_type_id: col.int()
|
|
13024
13006
|
},
|
|
13025
13007
|
{},
|
|
13026
|
-
void 0,
|
|
13027
13008
|
{ schema: "sys" }
|
|
13028
13009
|
);
|
|
13029
13010
|
var SysTables = defineTable(
|
|
@@ -13035,7 +13016,6 @@ var SysTables = defineTable(
|
|
|
13035
13016
|
is_ms_shipped: col.boolean()
|
|
13036
13017
|
},
|
|
13037
13018
|
{},
|
|
13038
|
-
void 0,
|
|
13039
13019
|
{ schema: "sys" }
|
|
13040
13020
|
);
|
|
13041
13021
|
var SysSchemas = defineTable(
|
|
@@ -13045,7 +13025,6 @@ var SysSchemas = defineTable(
|
|
|
13045
13025
|
name: col.varchar(255)
|
|
13046
13026
|
},
|
|
13047
13027
|
{},
|
|
13048
|
-
void 0,
|
|
13049
13028
|
{ schema: "sys" }
|
|
13050
13029
|
);
|
|
13051
13030
|
var SysTypes = defineTable(
|
|
@@ -13055,7 +13034,6 @@ var SysTypes = defineTable(
|
|
|
13055
13034
|
name: col.varchar(255)
|
|
13056
13035
|
},
|
|
13057
13036
|
{},
|
|
13058
|
-
void 0,
|
|
13059
13037
|
{ schema: "sys" }
|
|
13060
13038
|
);
|
|
13061
13039
|
var SysIndexes = defineTable(
|
|
@@ -13071,7 +13049,6 @@ var SysIndexes = defineTable(
|
|
|
13071
13049
|
is_hypothetical: col.boolean()
|
|
13072
13050
|
},
|
|
13073
13051
|
{},
|
|
13074
|
-
void 0,
|
|
13075
13052
|
{ schema: "sys" }
|
|
13076
13053
|
);
|
|
13077
13054
|
var SysIndexColumns = defineTable(
|
|
@@ -13083,7 +13060,6 @@ var SysIndexColumns = defineTable(
|
|
|
13083
13060
|
key_ordinal: col.int()
|
|
13084
13061
|
},
|
|
13085
13062
|
{},
|
|
13086
|
-
void 0,
|
|
13087
13063
|
{ schema: "sys" }
|
|
13088
13064
|
);
|
|
13089
13065
|
var SysForeignKeys = defineTable(
|
|
@@ -13095,7 +13071,6 @@ var SysForeignKeys = defineTable(
|
|
|
13095
13071
|
update_referential_action_desc: col.varchar(64)
|
|
13096
13072
|
},
|
|
13097
13073
|
{},
|
|
13098
|
-
void 0,
|
|
13099
13074
|
{ schema: "sys" }
|
|
13100
13075
|
);
|
|
13101
13076
|
var SysForeignKeyColumns = defineTable(
|
|
@@ -13109,7 +13084,6 @@ var SysForeignKeyColumns = defineTable(
|
|
|
13109
13084
|
constraint_column_id: col.int()
|
|
13110
13085
|
},
|
|
13111
13086
|
{},
|
|
13112
|
-
void 0,
|
|
13113
13087
|
{ schema: "sys" }
|
|
13114
13088
|
);
|
|
13115
13089
|
|
|
@@ -14534,12 +14508,14 @@ var UnitOfWork = class {
|
|
|
14534
14508
|
* @param executor - The database executor
|
|
14535
14509
|
* @param identityMap - The identity map
|
|
14536
14510
|
* @param hookContext - Function to get the hook context
|
|
14511
|
+
* @param resolveTableHooks - Session/runtime lifecycle hook resolver
|
|
14537
14512
|
*/
|
|
14538
|
-
constructor(dialect, executor, identityMap, hookContext) {
|
|
14513
|
+
constructor(dialect, executor, identityMap, hookContext, resolveTableHooks = () => void 0) {
|
|
14539
14514
|
this.dialect = dialect;
|
|
14540
14515
|
this.executor = executor;
|
|
14541
14516
|
this.identityMap = identityMap;
|
|
14542
14517
|
this.hookContext = hookContext;
|
|
14518
|
+
this.resolveTableHooks = resolveTableHooks;
|
|
14543
14519
|
}
|
|
14544
14520
|
trackedEntities = /* @__PURE__ */ new Map();
|
|
14545
14521
|
/**
|
|
@@ -14691,7 +14667,8 @@ var UnitOfWork = class {
|
|
|
14691
14667
|
* @param tracked - The tracked entity to insert
|
|
14692
14668
|
*/
|
|
14693
14669
|
async flushInsert(tracked) {
|
|
14694
|
-
|
|
14670
|
+
const hooks = this.resolveTableHooks(tracked.table);
|
|
14671
|
+
await this.runHook(hooks?.beforeInsert, tracked);
|
|
14695
14672
|
const payload = this.extractColumns(tracked.table, tracked.entity);
|
|
14696
14673
|
let builder = new InsertQueryBuilder(tracked.table).values(payload);
|
|
14697
14674
|
if (this.dialect.supportsDmlReturningClause()) {
|
|
@@ -14705,7 +14682,7 @@ var UnitOfWork = class {
|
|
|
14705
14682
|
tracked.original = this.createSnapshot(tracked.table, tracked.entity);
|
|
14706
14683
|
tracked.pk = this.getPrimaryKeyValue(tracked);
|
|
14707
14684
|
this.registerIdentity(tracked);
|
|
14708
|
-
await this.runHook(
|
|
14685
|
+
await this.runHook(hooks?.afterInsert, tracked);
|
|
14709
14686
|
}
|
|
14710
14687
|
/**
|
|
14711
14688
|
* Flushes an update operation for a modified entity.
|
|
@@ -14718,7 +14695,8 @@ var UnitOfWork = class {
|
|
|
14718
14695
|
tracked.status = "managed" /* Managed */;
|
|
14719
14696
|
return;
|
|
14720
14697
|
}
|
|
14721
|
-
|
|
14698
|
+
const hooks = this.resolveTableHooks(tracked.table);
|
|
14699
|
+
await this.runHook(hooks?.beforeUpdate, tracked);
|
|
14722
14700
|
const pkColumn = tracked.table.columns[findPrimaryKey(tracked.table)];
|
|
14723
14701
|
if (!pkColumn) return;
|
|
14724
14702
|
let builder = new UpdateQueryBuilder(tracked.table).set(changes).where(eq(pkColumn, tracked.pk));
|
|
@@ -14731,7 +14709,7 @@ var UnitOfWork = class {
|
|
|
14731
14709
|
tracked.status = "managed" /* Managed */;
|
|
14732
14710
|
tracked.original = this.createSnapshot(tracked.table, tracked.entity);
|
|
14733
14711
|
this.registerIdentity(tracked);
|
|
14734
|
-
await this.runHook(
|
|
14712
|
+
await this.runHook(hooks?.afterUpdate, tracked);
|
|
14735
14713
|
}
|
|
14736
14714
|
/**
|
|
14737
14715
|
* Flushes a delete operation for a removed entity.
|
|
@@ -14739,7 +14717,8 @@ var UnitOfWork = class {
|
|
|
14739
14717
|
*/
|
|
14740
14718
|
async flushDelete(tracked) {
|
|
14741
14719
|
if (tracked.pk == null) return;
|
|
14742
|
-
|
|
14720
|
+
const hooks = this.resolveTableHooks(tracked.table);
|
|
14721
|
+
await this.runHook(hooks?.beforeDelete, tracked);
|
|
14743
14722
|
const pkColumn = tracked.table.columns[findPrimaryKey(tracked.table)];
|
|
14744
14723
|
if (!pkColumn) return;
|
|
14745
14724
|
const builder = new DeleteQueryBuilder(tracked.table).where(eq(pkColumn, tracked.pk));
|
|
@@ -14748,10 +14727,10 @@ var UnitOfWork = class {
|
|
|
14748
14727
|
tracked.status = "detached" /* Detached */;
|
|
14749
14728
|
this.trackedEntities.delete(tracked.entity);
|
|
14750
14729
|
this.identityMap.remove(tracked);
|
|
14751
|
-
await this.runHook(
|
|
14730
|
+
await this.runHook(hooks?.afterDelete, tracked);
|
|
14752
14731
|
}
|
|
14753
14732
|
/**
|
|
14754
|
-
* Runs a
|
|
14733
|
+
* Runs a lifecycle hook if defined.
|
|
14755
14734
|
* @param hook - The hook function
|
|
14756
14735
|
* @param tracked - The tracked entity
|
|
14757
14736
|
*/
|
|
@@ -15070,7 +15049,10 @@ var RelationChangeProcessor = class {
|
|
|
15070
15049
|
const rootKey = relation.localKey || findPrimaryKey(entry.rootTable);
|
|
15071
15050
|
const rootId = entry.root[rootKey];
|
|
15072
15051
|
if (rootId === void 0 || rootId === null) return;
|
|
15073
|
-
const targetId = this.
|
|
15052
|
+
const targetId = this.resolveBelongsToManyTargetValue(
|
|
15053
|
+
entry.change.entity,
|
|
15054
|
+
relation
|
|
15055
|
+
);
|
|
15074
15056
|
if (targetId === null) return;
|
|
15075
15057
|
const pivotPayload = this.buildPivotPayload(relation, entry.change.pivot);
|
|
15076
15058
|
if (entry.change.kind === "update") {
|
|
@@ -15142,7 +15124,7 @@ var RelationChangeProcessor = class {
|
|
|
15142
15124
|
* Inserts a pivot row for belongs-to-many relations.
|
|
15143
15125
|
* @param relation - The belongs-to-many relation
|
|
15144
15126
|
* @param rootId - The root entity's primary key value
|
|
15145
|
-
* @param targetId - The target entity's
|
|
15127
|
+
* @param targetId - The target entity's relation key value
|
|
15146
15128
|
*/
|
|
15147
15129
|
async insertPivotRow(relation, rootId, targetId, pivotPayload) {
|
|
15148
15130
|
const payload = {
|
|
@@ -15158,7 +15140,7 @@ var RelationChangeProcessor = class {
|
|
|
15158
15140
|
* Updates a pivot row for belongs-to-many relations.
|
|
15159
15141
|
* @param relation - The belongs-to-many relation
|
|
15160
15142
|
* @param rootId - The root entity's primary key value
|
|
15161
|
-
* @param targetId - The target entity's
|
|
15143
|
+
* @param targetId - The target entity's relation key value
|
|
15162
15144
|
* @param pivotPayload - The pivot columns to update
|
|
15163
15145
|
*/
|
|
15164
15146
|
async updatePivotRow(relation, rootId, targetId, pivotPayload) {
|
|
@@ -15173,7 +15155,7 @@ var RelationChangeProcessor = class {
|
|
|
15173
15155
|
* Deletes a pivot row for belongs-to-many relations.
|
|
15174
15156
|
* @param relation - The belongs-to-many relation
|
|
15175
15157
|
* @param rootId - The root entity's primary key value
|
|
15176
|
-
* @param targetId - The target entity's
|
|
15158
|
+
* @param targetId - The target entity's relation key value
|
|
15177
15159
|
*/
|
|
15178
15160
|
async deletePivotRow(relation, rootId, targetId) {
|
|
15179
15161
|
const rootCol = relation.pivotTable.columns[relation.pivotForeignKeyToRoot];
|
|
@@ -15186,14 +15168,13 @@ var RelationChangeProcessor = class {
|
|
|
15186
15168
|
await this.executor.executeSql(compiled.sql, compiled.params);
|
|
15187
15169
|
}
|
|
15188
15170
|
/**
|
|
15189
|
-
* Resolves the
|
|
15190
|
-
*
|
|
15191
|
-
*
|
|
15192
|
-
* @returns The primary key value or null
|
|
15171
|
+
* Resolves the target-side key value used by a belongs-to-many relation.
|
|
15172
|
+
* The declared targetKey is part of the relation contract and takes
|
|
15173
|
+
* precedence over the target table primary key.
|
|
15193
15174
|
*/
|
|
15194
|
-
|
|
15175
|
+
resolveBelongsToManyTargetValue(entity, relation) {
|
|
15195
15176
|
if (!entity) return null;
|
|
15196
|
-
const key = findPrimaryKey(
|
|
15177
|
+
const key = relation.targetKey || findPrimaryKey(relation.target);
|
|
15197
15178
|
const value = entity[key];
|
|
15198
15179
|
if (value === void 0 || value === null) return null;
|
|
15199
15180
|
return value ?? null;
|
|
@@ -15654,6 +15635,7 @@ var OrmSession = class {
|
|
|
15654
15635
|
/** The tenant ID for multi-tenancy support */
|
|
15655
15636
|
tenantId;
|
|
15656
15637
|
interceptors;
|
|
15638
|
+
tableHooks = /* @__PURE__ */ new WeakMap();
|
|
15657
15639
|
saveGraphDefaults;
|
|
15658
15640
|
transactionDepth = 0;
|
|
15659
15641
|
savepointCounter = 0;
|
|
@@ -15667,7 +15649,13 @@ var OrmSession = class {
|
|
|
15667
15649
|
this.executor = createQueryLoggingExecutor(opts.executor, opts.queryLogger);
|
|
15668
15650
|
this.interceptors = [...opts.interceptors ?? []];
|
|
15669
15651
|
this.identityMap = new IdentityMap();
|
|
15670
|
-
this.unitOfWork = new UnitOfWork(
|
|
15652
|
+
this.unitOfWork = new UnitOfWork(
|
|
15653
|
+
this.orm.dialect,
|
|
15654
|
+
this.executor,
|
|
15655
|
+
this.identityMap,
|
|
15656
|
+
() => this,
|
|
15657
|
+
(table) => this.tableHooks.get(table)
|
|
15658
|
+
);
|
|
15671
15659
|
this.relationChanges = new RelationChangeProcessor(this.unitOfWork, this.orm.dialect, this.executor);
|
|
15672
15660
|
this.domainEvents = new DomainEventBus(opts.domainEventHandlers);
|
|
15673
15661
|
this.cacheManager = opts.cacheManager;
|
|
@@ -15775,6 +15763,18 @@ var OrmSession = class {
|
|
|
15775
15763
|
getEntitiesForTable(table) {
|
|
15776
15764
|
return this.unitOfWork.getEntitiesForTable(table);
|
|
15777
15765
|
}
|
|
15766
|
+
/**
|
|
15767
|
+
* Registers INSERT/UPDATE/DELETE lifecycle hooks for this Session only.
|
|
15768
|
+
* The target can be a TableDef or a decorated entity constructor.
|
|
15769
|
+
* Registering again for the same table replaces the previous hook set.
|
|
15770
|
+
*/
|
|
15771
|
+
registerTableHooks(target, hooks) {
|
|
15772
|
+
const table = typeof target === "function" ? getTableDefFromEntity(target) : target;
|
|
15773
|
+
if (!table) {
|
|
15774
|
+
throw new Error("Entity metadata has not been bootstrapped");
|
|
15775
|
+
}
|
|
15776
|
+
this.tableHooks.set(table, hooks);
|
|
15777
|
+
}
|
|
15778
15778
|
/**
|
|
15779
15779
|
* Registers an interceptor for flush lifecycle hooks.
|
|
15780
15780
|
* @param interceptor - The interceptor to register
|
|
@@ -15785,7 +15785,7 @@ var OrmSession = class {
|
|
|
15785
15785
|
/**
|
|
15786
15786
|
* Registers a domain event handler.
|
|
15787
15787
|
* @param type - The event type
|
|
15788
|
-
* @param handler - The event handler
|
|
15788
|
+
* @param handler - The domain event handler
|
|
15789
15789
|
*/
|
|
15790
15790
|
registerDomainEventHandler(type, handler) {
|
|
15791
15791
|
this.domainEvents.on(type, handler);
|
|
@@ -15959,7 +15959,9 @@ var OrmSession = class {
|
|
|
15959
15959
|
this.markRemoved(entity);
|
|
15960
15960
|
}
|
|
15961
15961
|
/**
|
|
15962
|
-
* Flushes pending changes to the database without session
|
|
15962
|
+
* Flushes pending changes to the database without session interceptors,
|
|
15963
|
+
* relation processing, or domain events. Table lifecycle hooks still run
|
|
15964
|
+
* because they are part of the Unit of Work.
|
|
15963
15965
|
*/
|
|
15964
15966
|
async flush() {
|
|
15965
15967
|
await this.unitOfWork.flush();
|
|
@@ -16854,7 +16856,7 @@ function Entity(options = {}) {
|
|
|
16854
16856
|
return function(value, context) {
|
|
16855
16857
|
const ctor = value;
|
|
16856
16858
|
const tableName = options.tableName ?? deriveTableNameFromConstructor(ctor);
|
|
16857
|
-
setEntityTableName(ctor, tableName, options.
|
|
16859
|
+
setEntityTableName(ctor, tableName, options.type);
|
|
16858
16860
|
const bag = context ? readMetadataBag(context) : readMetadataBagFromConstructor(ctor);
|
|
16859
16861
|
if (bag) {
|
|
16860
16862
|
const meta = ensureEntityMetadata(ctor);
|
|
@@ -21074,7 +21076,7 @@ var TreeManager = class _TreeManager {
|
|
|
21074
21076
|
* Moves a node to be the last child of a new parent.
|
|
21075
21077
|
*/
|
|
21076
21078
|
async moveTo(node, newParentId) {
|
|
21077
|
-
NestedSetStrategy.subtreeWidth(node.lft, node.rght);
|
|
21079
|
+
const width = NestedSetStrategy.subtreeWidth(node.lft, node.rght);
|
|
21078
21080
|
let newPos;
|
|
21079
21081
|
if (newParentId === null) {
|
|
21080
21082
|
const maxRght = await this.getMaxRght();
|
|
@@ -21089,7 +21091,8 @@ var TreeManager = class _TreeManager {
|
|
|
21089
21091
|
newParent.depth ?? await this.getLevel(newParent)
|
|
21090
21092
|
);
|
|
21091
21093
|
}
|
|
21092
|
-
|
|
21094
|
+
const targetLft = newPos.lft > node.rght ? newPos.lft - width : newPos.lft;
|
|
21095
|
+
await this.moveSubtree(node, targetLft, newParentId, newPos.depth);
|
|
21093
21096
|
}
|
|
21094
21097
|
/**
|
|
21095
21098
|
* Inserts a new node as a child of a parent.
|
|
@@ -21128,7 +21131,10 @@ var TreeManager = class _TreeManager {
|
|
|
21128
21131
|
if (insertData[this.pkName] !== void 0) {
|
|
21129
21132
|
return insertData[this.pkName];
|
|
21130
21133
|
}
|
|
21131
|
-
const
|
|
21134
|
+
const scopeExpressions = this.getScopeExpressions();
|
|
21135
|
+
const lftCondition = eq(this.table.columns[this.config.leftKey], insertPos.lft);
|
|
21136
|
+
const findCondition = scopeExpressions.length > 0 ? and(lftCondition, ...scopeExpressions) : lftCondition;
|
|
21137
|
+
const findQuery = selectFrom(this.table).where(findCondition);
|
|
21132
21138
|
const { sql: findSql, params: findParams } = findQuery.compile(this.dialect);
|
|
21133
21139
|
const results = await this.executor.executeSql(findSql, findParams);
|
|
21134
21140
|
const rows = queryResultsToRows(results);
|
|
@@ -21138,23 +21144,37 @@ var TreeManager = class _TreeManager {
|
|
|
21138
21144
|
return void 0;
|
|
21139
21145
|
}
|
|
21140
21146
|
/**
|
|
21141
|
-
* Removes a node
|
|
21147
|
+
* Removes a node from its current tree position, promotes its direct children
|
|
21148
|
+
* to the removed node's parent, and retains the removed row as a standalone root.
|
|
21142
21149
|
*/
|
|
21143
21150
|
async removeFromTree(node) {
|
|
21144
21151
|
const nodeId = node.data[this.pkName];
|
|
21152
|
+
const originalMaxRght = await this.getMaxRght();
|
|
21145
21153
|
await this.executeUpdate(
|
|
21146
21154
|
eq(this.table.columns[this.config.parentKey], nodeId),
|
|
21147
21155
|
{ [this.config.parentKey]: node.parentId }
|
|
21148
21156
|
);
|
|
21149
|
-
|
|
21157
|
+
if (node.rght - node.lft > 1) {
|
|
21158
|
+
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`;
|
|
21159
|
+
if (this.config.depthKey) {
|
|
21160
|
+
sql += `, ${this.quoteCol(this.config.depthKey)} = ${this.quoteCol(this.config.depthKey)} - 1`;
|
|
21161
|
+
}
|
|
21162
|
+
sql += ` WHERE ${this.quoteCol(this.config.leftKey)} > ? AND ${this.quoteCol(this.config.rightKey)} < ?`;
|
|
21163
|
+
await this.executeRawUpdate(sql, [node.lft, node.rght]);
|
|
21164
|
+
}
|
|
21150
21165
|
await this.shiftForDelete(node.rght, 2);
|
|
21151
|
-
|
|
21152
|
-
|
|
21153
|
-
|
|
21154
|
-
|
|
21155
|
-
|
|
21156
|
-
|
|
21166
|
+
const detachedData = {
|
|
21167
|
+
[this.config.parentKey]: null,
|
|
21168
|
+
[this.config.leftKey]: originalMaxRght - 1,
|
|
21169
|
+
[this.config.rightKey]: originalMaxRght
|
|
21170
|
+
};
|
|
21171
|
+
if (this.config.depthKey) {
|
|
21172
|
+
detachedData[this.config.depthKey] = 0;
|
|
21157
21173
|
}
|
|
21174
|
+
await this.executeUpdate(
|
|
21175
|
+
eq(this.table.columns[this.pkName], nodeId),
|
|
21176
|
+
detachedData
|
|
21177
|
+
);
|
|
21158
21178
|
}
|
|
21159
21179
|
/**
|
|
21160
21180
|
* Deletes a node and all its descendants.
|
|
@@ -21279,22 +21299,32 @@ var TreeManager = class _TreeManager {
|
|
|
21279
21299
|
}
|
|
21280
21300
|
return "id";
|
|
21281
21301
|
}
|
|
21302
|
+
getScopeEntries() {
|
|
21303
|
+
return Object.entries(buildScopeConditions(this.config.scope, this.scopeValues));
|
|
21304
|
+
}
|
|
21305
|
+
getScopeExpressions() {
|
|
21306
|
+
return this.getScopeEntries().map(
|
|
21307
|
+
([key, value]) => eq(this.table.columns[key], value)
|
|
21308
|
+
);
|
|
21309
|
+
}
|
|
21282
21310
|
async getMaxRght() {
|
|
21283
21311
|
const query = selectFrom(this.table).selectRaw(`MAX(${this.config.rightKey}) as max_rght`);
|
|
21284
|
-
const
|
|
21312
|
+
const scopeExpressions = this.getScopeExpressions();
|
|
21313
|
+
const finalQuery = scopeExpressions.length > 0 ? query.where(and(...scopeExpressions)) : query;
|
|
21314
|
+
const { sql, params } = finalQuery.compile(this.dialect);
|
|
21285
21315
|
const queryResults = await this.executor.executeSql(sql, params);
|
|
21286
21316
|
const rows = queryResultsToRows(queryResults);
|
|
21287
21317
|
const maxRght = rows[0]?.max_rght;
|
|
21288
21318
|
return typeof maxRght === "number" ? maxRght : 0;
|
|
21289
21319
|
}
|
|
21290
|
-
async shiftForInsert(insertPoint) {
|
|
21320
|
+
async shiftForInsert(insertPoint, width = 2) {
|
|
21291
21321
|
await this.executeRawUpdate(
|
|
21292
|
-
`UPDATE ${this.quoteTable()} SET ${this.quoteCol(this.config.rightKey)} = ${this.quoteCol(this.config.rightKey)} +
|
|
21293
|
-
[insertPoint]
|
|
21322
|
+
`UPDATE ${this.quoteTable()} SET ${this.quoteCol(this.config.rightKey)} = ${this.quoteCol(this.config.rightKey)} + ? WHERE ${this.quoteCol(this.config.rightKey)} >= ?`,
|
|
21323
|
+
[width, insertPoint]
|
|
21294
21324
|
);
|
|
21295
21325
|
await this.executeRawUpdate(
|
|
21296
|
-
`UPDATE ${this.quoteTable()} SET ${this.quoteCol(this.config.leftKey)} = ${this.quoteCol(this.config.leftKey)} +
|
|
21297
|
-
[insertPoint]
|
|
21326
|
+
`UPDATE ${this.quoteTable()} SET ${this.quoteCol(this.config.leftKey)} = ${this.quoteCol(this.config.leftKey)} + ? WHERE ${this.quoteCol(this.config.leftKey)} > ?`,
|
|
21327
|
+
[width, insertPoint]
|
|
21298
21328
|
);
|
|
21299
21329
|
}
|
|
21300
21330
|
async shiftForDelete(deletedRght, width) {
|
|
@@ -21330,28 +21360,27 @@ var TreeManager = class _TreeManager {
|
|
|
21330
21360
|
}
|
|
21331
21361
|
async moveSubtree(node, newLft, newParentId, newDepth) {
|
|
21332
21362
|
const width = NestedSetStrategy.subtreeWidth(node.lft, node.rght);
|
|
21333
|
-
const
|
|
21334
|
-
const depthDelta = this.config.depthKey ? newDepth -
|
|
21363
|
+
const oldDepth = this.config.depthKey ? node.depth ?? await this.getLevel(node) : 0;
|
|
21364
|
+
const depthDelta = this.config.depthKey ? newDepth - oldDepth : 0;
|
|
21335
21365
|
const nodeId = node.data[this.pkName];
|
|
21336
|
-
const
|
|
21366
|
+
const isolateDelta = -1e7 - node.rght;
|
|
21367
|
+
const isolatedLft = node.lft + isolateDelta;
|
|
21368
|
+
const isolatedRght = node.rght + isolateDelta;
|
|
21337
21369
|
await this.executeRawUpdate(
|
|
21338
|
-
`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)} <= ?`,
|
|
21339
|
-
[
|
|
21340
|
-
);
|
|
21341
|
-
await this.executeRawUpdate(
|
|
21342
|
-
`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)} <= ?`,
|
|
21343
|
-
[tempOffset, node.lft + tempOffset, node.rght]
|
|
21370
|
+
`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)} <= ?`,
|
|
21371
|
+
[isolateDelta, isolateDelta, node.lft, node.rght]
|
|
21344
21372
|
);
|
|
21345
21373
|
await this.shiftForDelete(node.rght, width);
|
|
21346
|
-
await this.shiftForInsert(newLft);
|
|
21347
|
-
|
|
21348
|
-
|
|
21374
|
+
await this.shiftForInsert(newLft, width);
|
|
21375
|
+
const restoreDelta = newLft - node.lft - isolateDelta;
|
|
21376
|
+
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)} + ?`;
|
|
21377
|
+
const updateParams = [restoreDelta, restoreDelta];
|
|
21349
21378
|
if (this.config.depthKey && depthDelta !== 0) {
|
|
21350
21379
|
updateSql += `, ${this.quoteCol(this.config.depthKey)} = ${this.quoteCol(this.config.depthKey)} + ?`;
|
|
21351
21380
|
updateParams.push(depthDelta);
|
|
21352
21381
|
}
|
|
21353
|
-
updateSql += ` WHERE ${this.quoteCol(this.config.leftKey)} >= ?`;
|
|
21354
|
-
updateParams.push(
|
|
21382
|
+
updateSql += ` WHERE ${this.quoteCol(this.config.leftKey)} >= ? AND ${this.quoteCol(this.config.rightKey)} <= ?`;
|
|
21383
|
+
updateParams.push(isolatedLft, isolatedRght);
|
|
21355
21384
|
await this.executeRawUpdate(updateSql, updateParams);
|
|
21356
21385
|
await this.executeUpdate(
|
|
21357
21386
|
eq(this.table.columns[this.pkName], nodeId),
|
|
@@ -21376,12 +21405,23 @@ var TreeManager = class _TreeManager {
|
|
|
21376
21405
|
}));
|
|
21377
21406
|
}
|
|
21378
21407
|
async executeUpdate(condition, data) {
|
|
21379
|
-
const
|
|
21408
|
+
const scopeExpressions = this.getScopeExpressions();
|
|
21409
|
+
const finalCondition = scopeExpressions.length > 0 ? and(condition, ...scopeExpressions) : condition;
|
|
21410
|
+
const query = update(this.table).set(data).where(finalCondition);
|
|
21380
21411
|
const { sql, params } = query.compile(this.dialect);
|
|
21381
21412
|
await this.executor.executeSql(sql, params);
|
|
21382
21413
|
}
|
|
21383
21414
|
async executeRawUpdate(sql, params) {
|
|
21384
|
-
|
|
21415
|
+
let scopedSql = sql;
|
|
21416
|
+
const scopedParams = [...params];
|
|
21417
|
+
let hasWhere = /\bWHERE\b/i.test(scopedSql);
|
|
21418
|
+
for (const [key, value] of this.getScopeEntries()) {
|
|
21419
|
+
scopedSql += hasWhere ? " AND " : " WHERE ";
|
|
21420
|
+
scopedSql += `${this.quoteCol(key)} = ?`;
|
|
21421
|
+
scopedParams.push(value);
|
|
21422
|
+
hasWhere = true;
|
|
21423
|
+
}
|
|
21424
|
+
await this.executor.executeSql(scopedSql, scopedParams);
|
|
21385
21425
|
}
|
|
21386
21426
|
quoteTable() {
|
|
21387
21427
|
const quote = this.getQuoteChar();
|