- CTE approach

- Remove closure table usage
This commit is contained in:
Philipinho
2026-01-11 04:36:32 +00:00
parent 4c635b4faf
commit a5696bb8e8
11 changed files with 219 additions and 727 deletions
@@ -27,7 +27,6 @@ export class AddPagePermissionDto extends PageIdDto {
@ArrayMaxSize(25, {
message: 'userIds must be an array with no more than 25 elements',
})
@ArrayMinSize(1)
@IsUUID('all', { each: true })
userIds?: string[];
@@ -36,7 +35,6 @@ export class AddPagePermissionDto extends PageIdDto {
@ArrayMaxSize(25, {
message: 'groupIds must be an array with no more than 25 elements',
})
@ArrayMinSize(1)
@IsUUID('all', { each: true })
groupIds?: string[];
}
@@ -47,7 +45,6 @@ export class RemovePagePermissionDto extends PageIdDto {
@ArrayMaxSize(25, {
message: 'userIds must be an array with no more than 25 elements',
})
@ArrayMinSize(1)
@IsUUID('all', { each: true })
userIds?: string[];
@@ -56,7 +53,6 @@ export class RemovePagePermissionDto extends PageIdDto {
@ArrayMaxSize(25, {
message: 'groupIds must be an array with no more than 25 elements',
})
@ArrayMinSize(1)
@IsUUID('all', { each: true })
groupIds?: string[];
}
+1 -8
View File
@@ -4,7 +4,6 @@ import { PageController } from './page.controller';
import { PageHistoryService } from './services/page-history.service';
import { TrashCleanupService } from './services/trash-cleanup.service';
import { PagePermissionService } from './services/page-permission.service';
import { PageHierarchyService } from './services/page-hierarchy.service';
import { PagePermissionController } from './page-permission.controller';
import { StorageModule } from '../../integrations/storage/storage.module';
@@ -15,14 +14,8 @@ import { StorageModule } from '../../integrations/storage/storage.module';
PageHistoryService,
TrashCleanupService,
PagePermissionService,
PageHierarchyService,
],
exports: [
PageService,
PageHistoryService,
PagePermissionService,
PageHierarchyService,
],
exports: [PageService, PageHistoryService, PagePermissionService],
imports: [StorageModule],
})
export class PageModule {}
@@ -1,56 +0,0 @@
import { Injectable, Logger } from '@nestjs/common';
import { InjectKysely } from 'nestjs-kysely';
import { KyselyDB } from '@docmost/db/types/kysely.types';
import { PageHierarchyRepo } from '@docmost/db/repos/page/page-hierarchy.repo';
import { executeTx } from '@docmost/db/utils';
type RebuildResult = { rebuilt: boolean; count: number };
@Injectable()
export class PageHierarchyService {
private readonly logger = new Logger(PageHierarchyService.name);
constructor(
@InjectKysely() private readonly db: KyselyDB,
private readonly pageHierarchyRepo: PageHierarchyRepo,
) {}
async rebuildAll(): Promise<RebuildResult> {
return executeTx(this.db, async (trx) => {
const locked = await this.pageHierarchyRepo.tryAcquireGlobalLock(trx);
if (!locked) {
this.logger.debug('Rebuild all skipped - another process holds the lock');
return { rebuilt: false, count: 0 };
}
this.logger.log('Rebuilding hierarchy for all pages');
const count = await this.pageHierarchyRepo.rebuildAll(trx);
this.logger.log(`Rebuilt hierarchy for all pages (${count} entries)`);
return { rebuilt: true, count };
});
}
async rebuildBySpace(spaceId: string): Promise<RebuildResult> {
return executeTx(this.db, async (trx) => {
const locked = await this.pageHierarchyRepo.tryAcquireSpaceLock(
spaceId,
trx,
);
if (!locked) {
this.logger.debug(
`Rebuild for space ${spaceId} skipped - another process holds the lock`,
);
return { rebuilt: false, count: 0 };
}
this.logger.log(`Rebuilding hierarchy for space ${spaceId}`);
const count = await this.pageHierarchyRepo.rebuildBySpace(spaceId, trx);
this.logger.log(
`Rebuilt hierarchy for space ${spaceId} (${count} entries)`,
);
return { rebuilt: true, count };
});
}
}