metal-orm 1.1.21 → 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 +112 -74
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +51 -23
- package/dist/index.d.ts +51 -23
- package/dist/index.js +112 -74
- 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/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
|
*/
|
|
@@ -15215,6 +15194,7 @@ var OrmSession = class {
|
|
|
15215
15194
|
/** The tenant ID for multi-tenancy support */
|
|
15216
15195
|
tenantId;
|
|
15217
15196
|
interceptors;
|
|
15197
|
+
tableHooks = /* @__PURE__ */ new WeakMap();
|
|
15218
15198
|
saveGraphDefaults;
|
|
15219
15199
|
transactionDepth = 0;
|
|
15220
15200
|
savepointCounter = 0;
|
|
@@ -15228,7 +15208,13 @@ var OrmSession = class {
|
|
|
15228
15208
|
this.executor = createQueryLoggingExecutor(opts.executor, opts.queryLogger);
|
|
15229
15209
|
this.interceptors = [...opts.interceptors ?? []];
|
|
15230
15210
|
this.identityMap = new IdentityMap();
|
|
15231
|
-
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
|
+
);
|
|
15232
15218
|
this.relationChanges = new RelationChangeProcessor(this.unitOfWork, this.orm.dialect, this.executor);
|
|
15233
15219
|
this.domainEvents = new DomainEventBus(opts.domainEventHandlers);
|
|
15234
15220
|
this.cacheManager = opts.cacheManager;
|
|
@@ -15336,6 +15322,18 @@ var OrmSession = class {
|
|
|
15336
15322
|
getEntitiesForTable(table) {
|
|
15337
15323
|
return this.unitOfWork.getEntitiesForTable(table);
|
|
15338
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
|
+
}
|
|
15339
15337
|
/**
|
|
15340
15338
|
* Registers an interceptor for flush lifecycle hooks.
|
|
15341
15339
|
* @param interceptor - The interceptor to register
|
|
@@ -15346,7 +15344,7 @@ var OrmSession = class {
|
|
|
15346
15344
|
/**
|
|
15347
15345
|
* Registers a domain event handler.
|
|
15348
15346
|
* @param type - The event type
|
|
15349
|
-
* @param handler - The event handler
|
|
15347
|
+
* @param handler - The domain event handler
|
|
15350
15348
|
*/
|
|
15351
15349
|
registerDomainEventHandler(type, handler) {
|
|
15352
15350
|
this.domainEvents.on(type, handler);
|
|
@@ -15520,7 +15518,9 @@ var OrmSession = class {
|
|
|
15520
15518
|
this.markRemoved(entity);
|
|
15521
15519
|
}
|
|
15522
15520
|
/**
|
|
15523
|
-
* 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.
|
|
15524
15524
|
*/
|
|
15525
15525
|
async flush() {
|
|
15526
15526
|
await this.unitOfWork.flush();
|
|
@@ -16415,7 +16415,7 @@ function Entity(options = {}) {
|
|
|
16415
16415
|
return function(value, context) {
|
|
16416
16416
|
const ctor = value;
|
|
16417
16417
|
const tableName = options.tableName ?? deriveTableNameFromConstructor(ctor);
|
|
16418
|
-
setEntityTableName(ctor, tableName, options.
|
|
16418
|
+
setEntityTableName(ctor, tableName, options.type);
|
|
16419
16419
|
const bag = context ? readMetadataBag(context) : readMetadataBagFromConstructor(ctor);
|
|
16420
16420
|
if (bag) {
|
|
16421
16421
|
const meta = ensureEntityMetadata(ctor);
|
|
@@ -20635,7 +20635,7 @@ var TreeManager = class _TreeManager {
|
|
|
20635
20635
|
* Moves a node to be the last child of a new parent.
|
|
20636
20636
|
*/
|
|
20637
20637
|
async moveTo(node, newParentId) {
|
|
20638
|
-
NestedSetStrategy.subtreeWidth(node.lft, node.rght);
|
|
20638
|
+
const width = NestedSetStrategy.subtreeWidth(node.lft, node.rght);
|
|
20639
20639
|
let newPos;
|
|
20640
20640
|
if (newParentId === null) {
|
|
20641
20641
|
const maxRght = await this.getMaxRght();
|
|
@@ -20650,7 +20650,8 @@ var TreeManager = class _TreeManager {
|
|
|
20650
20650
|
newParent.depth ?? await this.getLevel(newParent)
|
|
20651
20651
|
);
|
|
20652
20652
|
}
|
|
20653
|
-
|
|
20653
|
+
const targetLft = newPos.lft > node.rght ? newPos.lft - width : newPos.lft;
|
|
20654
|
+
await this.moveSubtree(node, targetLft, newParentId, newPos.depth);
|
|
20654
20655
|
}
|
|
20655
20656
|
/**
|
|
20656
20657
|
* Inserts a new node as a child of a parent.
|
|
@@ -20689,7 +20690,10 @@ var TreeManager = class _TreeManager {
|
|
|
20689
20690
|
if (insertData[this.pkName] !== void 0) {
|
|
20690
20691
|
return insertData[this.pkName];
|
|
20691
20692
|
}
|
|
20692
|
-
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);
|
|
20693
20697
|
const { sql: findSql, params: findParams } = findQuery.compile(this.dialect);
|
|
20694
20698
|
const results = await this.executor.executeSql(findSql, findParams);
|
|
20695
20699
|
const rows = queryResultsToRows(results);
|
|
@@ -20699,23 +20703,37 @@ var TreeManager = class _TreeManager {
|
|
|
20699
20703
|
return void 0;
|
|
20700
20704
|
}
|
|
20701
20705
|
/**
|
|
20702
|
-
* 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.
|
|
20703
20708
|
*/
|
|
20704
20709
|
async removeFromTree(node) {
|
|
20705
20710
|
const nodeId = node.data[this.pkName];
|
|
20711
|
+
const originalMaxRght = await this.getMaxRght();
|
|
20706
20712
|
await this.executeUpdate(
|
|
20707
20713
|
eq(this.table.columns[this.config.parentKey], nodeId),
|
|
20708
20714
|
{ [this.config.parentKey]: node.parentId }
|
|
20709
20715
|
);
|
|
20710
|
-
|
|
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
|
+
}
|
|
20711
20724
|
await this.shiftForDelete(node.rght, 2);
|
|
20712
|
-
|
|
20713
|
-
|
|
20714
|
-
|
|
20715
|
-
|
|
20716
|
-
|
|
20717
|
-
|
|
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;
|
|
20718
20732
|
}
|
|
20733
|
+
await this.executeUpdate(
|
|
20734
|
+
eq(this.table.columns[this.pkName], nodeId),
|
|
20735
|
+
detachedData
|
|
20736
|
+
);
|
|
20719
20737
|
}
|
|
20720
20738
|
/**
|
|
20721
20739
|
* Deletes a node and all its descendants.
|
|
@@ -20840,22 +20858,32 @@ var TreeManager = class _TreeManager {
|
|
|
20840
20858
|
}
|
|
20841
20859
|
return "id";
|
|
20842
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
|
+
}
|
|
20843
20869
|
async getMaxRght() {
|
|
20844
20870
|
const query = selectFrom(this.table).selectRaw(`MAX(${this.config.rightKey}) as max_rght`);
|
|
20845
|
-
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);
|
|
20846
20874
|
const queryResults = await this.executor.executeSql(sql, params);
|
|
20847
20875
|
const rows = queryResultsToRows(queryResults);
|
|
20848
20876
|
const maxRght = rows[0]?.max_rght;
|
|
20849
20877
|
return typeof maxRght === "number" ? maxRght : 0;
|
|
20850
20878
|
}
|
|
20851
|
-
async shiftForInsert(insertPoint) {
|
|
20879
|
+
async shiftForInsert(insertPoint, width = 2) {
|
|
20852
20880
|
await this.executeRawUpdate(
|
|
20853
|
-
`UPDATE ${this.quoteTable()} SET ${this.quoteCol(this.config.rightKey)} = ${this.quoteCol(this.config.rightKey)} +
|
|
20854
|
-
[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]
|
|
20855
20883
|
);
|
|
20856
20884
|
await this.executeRawUpdate(
|
|
20857
|
-
`UPDATE ${this.quoteTable()} SET ${this.quoteCol(this.config.leftKey)} = ${this.quoteCol(this.config.leftKey)} +
|
|
20858
|
-
[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]
|
|
20859
20887
|
);
|
|
20860
20888
|
}
|
|
20861
20889
|
async shiftForDelete(deletedRght, width) {
|
|
@@ -20891,28 +20919,27 @@ var TreeManager = class _TreeManager {
|
|
|
20891
20919
|
}
|
|
20892
20920
|
async moveSubtree(node, newLft, newParentId, newDepth) {
|
|
20893
20921
|
const width = NestedSetStrategy.subtreeWidth(node.lft, node.rght);
|
|
20894
|
-
const
|
|
20895
|
-
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;
|
|
20896
20924
|
const nodeId = node.data[this.pkName];
|
|
20897
|
-
const
|
|
20925
|
+
const isolateDelta = -1e7 - node.rght;
|
|
20926
|
+
const isolatedLft = node.lft + isolateDelta;
|
|
20927
|
+
const isolatedRght = node.rght + isolateDelta;
|
|
20898
20928
|
await this.executeRawUpdate(
|
|
20899
|
-
`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)} <= ?`,
|
|
20900
|
-
[
|
|
20901
|
-
);
|
|
20902
|
-
await this.executeRawUpdate(
|
|
20903
|
-
`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)} <= ?`,
|
|
20904
|
-
[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]
|
|
20905
20931
|
);
|
|
20906
20932
|
await this.shiftForDelete(node.rght, width);
|
|
20907
|
-
await this.shiftForInsert(newLft);
|
|
20908
|
-
|
|
20909
|
-
|
|
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];
|
|
20910
20937
|
if (this.config.depthKey && depthDelta !== 0) {
|
|
20911
20938
|
updateSql += `, ${this.quoteCol(this.config.depthKey)} = ${this.quoteCol(this.config.depthKey)} + ?`;
|
|
20912
20939
|
updateParams.push(depthDelta);
|
|
20913
20940
|
}
|
|
20914
|
-
updateSql += ` WHERE ${this.quoteCol(this.config.leftKey)} >= ?`;
|
|
20915
|
-
updateParams.push(
|
|
20941
|
+
updateSql += ` WHERE ${this.quoteCol(this.config.leftKey)} >= ? AND ${this.quoteCol(this.config.rightKey)} <= ?`;
|
|
20942
|
+
updateParams.push(isolatedLft, isolatedRght);
|
|
20916
20943
|
await this.executeRawUpdate(updateSql, updateParams);
|
|
20917
20944
|
await this.executeUpdate(
|
|
20918
20945
|
eq(this.table.columns[this.pkName], nodeId),
|
|
@@ -20937,12 +20964,23 @@ var TreeManager = class _TreeManager {
|
|
|
20937
20964
|
}));
|
|
20938
20965
|
}
|
|
20939
20966
|
async executeUpdate(condition, data) {
|
|
20940
|
-
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);
|
|
20941
20970
|
const { sql, params } = query.compile(this.dialect);
|
|
20942
20971
|
await this.executor.executeSql(sql, params);
|
|
20943
20972
|
}
|
|
20944
20973
|
async executeRawUpdate(sql, params) {
|
|
20945
|
-
|
|
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);
|
|
20946
20984
|
}
|
|
20947
20985
|
quoteTable() {
|
|
20948
20986
|
const quote = this.getQuoteChar();
|