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.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
|
*/
|
|
@@ -15656,6 +15635,7 @@ var OrmSession = class {
|
|
|
15656
15635
|
/** The tenant ID for multi-tenancy support */
|
|
15657
15636
|
tenantId;
|
|
15658
15637
|
interceptors;
|
|
15638
|
+
tableHooks = /* @__PURE__ */ new WeakMap();
|
|
15659
15639
|
saveGraphDefaults;
|
|
15660
15640
|
transactionDepth = 0;
|
|
15661
15641
|
savepointCounter = 0;
|
|
@@ -15669,7 +15649,13 @@ var OrmSession = class {
|
|
|
15669
15649
|
this.executor = createQueryLoggingExecutor(opts.executor, opts.queryLogger);
|
|
15670
15650
|
this.interceptors = [...opts.interceptors ?? []];
|
|
15671
15651
|
this.identityMap = new IdentityMap();
|
|
15672
|
-
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
|
+
);
|
|
15673
15659
|
this.relationChanges = new RelationChangeProcessor(this.unitOfWork, this.orm.dialect, this.executor);
|
|
15674
15660
|
this.domainEvents = new DomainEventBus(opts.domainEventHandlers);
|
|
15675
15661
|
this.cacheManager = opts.cacheManager;
|
|
@@ -15777,6 +15763,18 @@ var OrmSession = class {
|
|
|
15777
15763
|
getEntitiesForTable(table) {
|
|
15778
15764
|
return this.unitOfWork.getEntitiesForTable(table);
|
|
15779
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
|
+
}
|
|
15780
15778
|
/**
|
|
15781
15779
|
* Registers an interceptor for flush lifecycle hooks.
|
|
15782
15780
|
* @param interceptor - The interceptor to register
|
|
@@ -15787,7 +15785,7 @@ var OrmSession = class {
|
|
|
15787
15785
|
/**
|
|
15788
15786
|
* Registers a domain event handler.
|
|
15789
15787
|
* @param type - The event type
|
|
15790
|
-
* @param handler - The event handler
|
|
15788
|
+
* @param handler - The domain event handler
|
|
15791
15789
|
*/
|
|
15792
15790
|
registerDomainEventHandler(type, handler) {
|
|
15793
15791
|
this.domainEvents.on(type, handler);
|
|
@@ -15961,7 +15959,9 @@ var OrmSession = class {
|
|
|
15961
15959
|
this.markRemoved(entity);
|
|
15962
15960
|
}
|
|
15963
15961
|
/**
|
|
15964
|
-
* 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.
|
|
15965
15965
|
*/
|
|
15966
15966
|
async flush() {
|
|
15967
15967
|
await this.unitOfWork.flush();
|
|
@@ -16856,7 +16856,7 @@ function Entity(options = {}) {
|
|
|
16856
16856
|
return function(value, context) {
|
|
16857
16857
|
const ctor = value;
|
|
16858
16858
|
const tableName = options.tableName ?? deriveTableNameFromConstructor(ctor);
|
|
16859
|
-
setEntityTableName(ctor, tableName, options.
|
|
16859
|
+
setEntityTableName(ctor, tableName, options.type);
|
|
16860
16860
|
const bag = context ? readMetadataBag(context) : readMetadataBagFromConstructor(ctor);
|
|
16861
16861
|
if (bag) {
|
|
16862
16862
|
const meta = ensureEntityMetadata(ctor);
|
|
@@ -21076,7 +21076,7 @@ var TreeManager = class _TreeManager {
|
|
|
21076
21076
|
* Moves a node to be the last child of a new parent.
|
|
21077
21077
|
*/
|
|
21078
21078
|
async moveTo(node, newParentId) {
|
|
21079
|
-
NestedSetStrategy.subtreeWidth(node.lft, node.rght);
|
|
21079
|
+
const width = NestedSetStrategy.subtreeWidth(node.lft, node.rght);
|
|
21080
21080
|
let newPos;
|
|
21081
21081
|
if (newParentId === null) {
|
|
21082
21082
|
const maxRght = await this.getMaxRght();
|
|
@@ -21091,7 +21091,8 @@ var TreeManager = class _TreeManager {
|
|
|
21091
21091
|
newParent.depth ?? await this.getLevel(newParent)
|
|
21092
21092
|
);
|
|
21093
21093
|
}
|
|
21094
|
-
|
|
21094
|
+
const targetLft = newPos.lft > node.rght ? newPos.lft - width : newPos.lft;
|
|
21095
|
+
await this.moveSubtree(node, targetLft, newParentId, newPos.depth);
|
|
21095
21096
|
}
|
|
21096
21097
|
/**
|
|
21097
21098
|
* Inserts a new node as a child of a parent.
|
|
@@ -21130,7 +21131,10 @@ var TreeManager = class _TreeManager {
|
|
|
21130
21131
|
if (insertData[this.pkName] !== void 0) {
|
|
21131
21132
|
return insertData[this.pkName];
|
|
21132
21133
|
}
|
|
21133
|
-
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);
|
|
21134
21138
|
const { sql: findSql, params: findParams } = findQuery.compile(this.dialect);
|
|
21135
21139
|
const results = await this.executor.executeSql(findSql, findParams);
|
|
21136
21140
|
const rows = queryResultsToRows(results);
|
|
@@ -21140,23 +21144,37 @@ var TreeManager = class _TreeManager {
|
|
|
21140
21144
|
return void 0;
|
|
21141
21145
|
}
|
|
21142
21146
|
/**
|
|
21143
|
-
* 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.
|
|
21144
21149
|
*/
|
|
21145
21150
|
async removeFromTree(node) {
|
|
21146
21151
|
const nodeId = node.data[this.pkName];
|
|
21152
|
+
const originalMaxRght = await this.getMaxRght();
|
|
21147
21153
|
await this.executeUpdate(
|
|
21148
21154
|
eq(this.table.columns[this.config.parentKey], nodeId),
|
|
21149
21155
|
{ [this.config.parentKey]: node.parentId }
|
|
21150
21156
|
);
|
|
21151
|
-
|
|
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
|
+
}
|
|
21152
21165
|
await this.shiftForDelete(node.rght, 2);
|
|
21153
|
-
|
|
21154
|
-
|
|
21155
|
-
|
|
21156
|
-
|
|
21157
|
-
|
|
21158
|
-
|
|
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;
|
|
21159
21173
|
}
|
|
21174
|
+
await this.executeUpdate(
|
|
21175
|
+
eq(this.table.columns[this.pkName], nodeId),
|
|
21176
|
+
detachedData
|
|
21177
|
+
);
|
|
21160
21178
|
}
|
|
21161
21179
|
/**
|
|
21162
21180
|
* Deletes a node and all its descendants.
|
|
@@ -21281,22 +21299,32 @@ var TreeManager = class _TreeManager {
|
|
|
21281
21299
|
}
|
|
21282
21300
|
return "id";
|
|
21283
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
|
+
}
|
|
21284
21310
|
async getMaxRght() {
|
|
21285
21311
|
const query = selectFrom(this.table).selectRaw(`MAX(${this.config.rightKey}) as max_rght`);
|
|
21286
|
-
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);
|
|
21287
21315
|
const queryResults = await this.executor.executeSql(sql, params);
|
|
21288
21316
|
const rows = queryResultsToRows(queryResults);
|
|
21289
21317
|
const maxRght = rows[0]?.max_rght;
|
|
21290
21318
|
return typeof maxRght === "number" ? maxRght : 0;
|
|
21291
21319
|
}
|
|
21292
|
-
async shiftForInsert(insertPoint) {
|
|
21320
|
+
async shiftForInsert(insertPoint, width = 2) {
|
|
21293
21321
|
await this.executeRawUpdate(
|
|
21294
|
-
`UPDATE ${this.quoteTable()} SET ${this.quoteCol(this.config.rightKey)} = ${this.quoteCol(this.config.rightKey)} +
|
|
21295
|
-
[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]
|
|
21296
21324
|
);
|
|
21297
21325
|
await this.executeRawUpdate(
|
|
21298
|
-
`UPDATE ${this.quoteTable()} SET ${this.quoteCol(this.config.leftKey)} = ${this.quoteCol(this.config.leftKey)} +
|
|
21299
|
-
[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]
|
|
21300
21328
|
);
|
|
21301
21329
|
}
|
|
21302
21330
|
async shiftForDelete(deletedRght, width) {
|
|
@@ -21332,28 +21360,27 @@ var TreeManager = class _TreeManager {
|
|
|
21332
21360
|
}
|
|
21333
21361
|
async moveSubtree(node, newLft, newParentId, newDepth) {
|
|
21334
21362
|
const width = NestedSetStrategy.subtreeWidth(node.lft, node.rght);
|
|
21335
|
-
const
|
|
21336
|
-
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;
|
|
21337
21365
|
const nodeId = node.data[this.pkName];
|
|
21338
|
-
const
|
|
21366
|
+
const isolateDelta = -1e7 - node.rght;
|
|
21367
|
+
const isolatedLft = node.lft + isolateDelta;
|
|
21368
|
+
const isolatedRght = node.rght + isolateDelta;
|
|
21339
21369
|
await this.executeRawUpdate(
|
|
21340
|
-
`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)} <= ?`,
|
|
21341
|
-
[
|
|
21342
|
-
);
|
|
21343
|
-
await this.executeRawUpdate(
|
|
21344
|
-
`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)} <= ?`,
|
|
21345
|
-
[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]
|
|
21346
21372
|
);
|
|
21347
21373
|
await this.shiftForDelete(node.rght, width);
|
|
21348
|
-
await this.shiftForInsert(newLft);
|
|
21349
|
-
|
|
21350
|
-
|
|
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];
|
|
21351
21378
|
if (this.config.depthKey && depthDelta !== 0) {
|
|
21352
21379
|
updateSql += `, ${this.quoteCol(this.config.depthKey)} = ${this.quoteCol(this.config.depthKey)} + ?`;
|
|
21353
21380
|
updateParams.push(depthDelta);
|
|
21354
21381
|
}
|
|
21355
|
-
updateSql += ` WHERE ${this.quoteCol(this.config.leftKey)} >= ?`;
|
|
21356
|
-
updateParams.push(
|
|
21382
|
+
updateSql += ` WHERE ${this.quoteCol(this.config.leftKey)} >= ? AND ${this.quoteCol(this.config.rightKey)} <= ?`;
|
|
21383
|
+
updateParams.push(isolatedLft, isolatedRght);
|
|
21357
21384
|
await this.executeRawUpdate(updateSql, updateParams);
|
|
21358
21385
|
await this.executeUpdate(
|
|
21359
21386
|
eq(this.table.columns[this.pkName], nodeId),
|
|
@@ -21378,12 +21405,23 @@ var TreeManager = class _TreeManager {
|
|
|
21378
21405
|
}));
|
|
21379
21406
|
}
|
|
21380
21407
|
async executeUpdate(condition, data) {
|
|
21381
|
-
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);
|
|
21382
21411
|
const { sql, params } = query.compile(this.dialect);
|
|
21383
21412
|
await this.executor.executeSql(sql, params);
|
|
21384
21413
|
}
|
|
21385
21414
|
async executeRawUpdate(sql, params) {
|
|
21386
|
-
|
|
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);
|
|
21387
21425
|
}
|
|
21388
21426
|
quoteTable() {
|
|
21389
21427
|
const quote = this.getQuoteChar();
|