mirror of
https://github.com/docmost/docmost.git
synced 2026-09-11 07:56:54 +08:00
fix: advisory lock for page move
This commit is contained in:
@@ -161,6 +161,22 @@ export class PageRepo {
|
||||
return result;
|
||||
}
|
||||
|
||||
async lockPageHierarchySpaces(
|
||||
spaceIds: string[],
|
||||
trx: KyselyTransaction,
|
||||
): Promise<void> {
|
||||
const sortedSpaceIds = [...new Set(spaceIds)].sort();
|
||||
|
||||
for (const spaceId of sortedSpaceIds) {
|
||||
await sql`
|
||||
SELECT pg_advisory_xact_lock(
|
||||
hashtext('page-hierarchy'),
|
||||
hashtext(${spaceId})
|
||||
)
|
||||
`.execute(trx);
|
||||
}
|
||||
}
|
||||
|
||||
async insertPage(
|
||||
insertablePage: InsertablePage,
|
||||
trx?: KyselyTransaction,
|
||||
@@ -489,9 +505,9 @@ export class PageRepo {
|
||||
|
||||
async getPageAndDescendants(
|
||||
parentPageId: string,
|
||||
opts: { includeContent: boolean },
|
||||
opts: { includeContent: boolean; trx?: KyselyTransaction },
|
||||
) {
|
||||
return this.db
|
||||
return dbOrTx(this.db, opts.trx)
|
||||
.withRecursive('page_hierarchy', (db) =>
|
||||
db
|
||||
.selectFrom('pages')
|
||||
@@ -535,6 +551,36 @@ export class PageRepo {
|
||||
.execute();
|
||||
}
|
||||
|
||||
async isPageDescendant(
|
||||
ancestorPageId: string,
|
||||
descendantPageId: string,
|
||||
trx?: KyselyTransaction,
|
||||
): Promise<boolean> {
|
||||
const result = await dbOrTx(this.db, trx)
|
||||
.withRecursive('page_ancestors', (db) =>
|
||||
db
|
||||
.selectFrom('pages')
|
||||
.select(['id', 'parentPageId'])
|
||||
.where('id', '=', descendantPageId)
|
||||
.union((exp) =>
|
||||
exp
|
||||
.selectFrom('pages as parent')
|
||||
.select(['parent.id', 'parent.parentPageId'])
|
||||
.innerJoin(
|
||||
'page_ancestors as ancestor',
|
||||
'ancestor.parentPageId',
|
||||
'parent.id',
|
||||
),
|
||||
),
|
||||
)
|
||||
.selectFrom('page_ancestors')
|
||||
.select('id')
|
||||
.where('id', '=', ancestorPageId)
|
||||
.executeTakeFirst();
|
||||
|
||||
return Boolean(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get page and all descendants, excluding restricted pages and their subtrees.
|
||||
* More efficient than getPageAndDescendants + filtering because:
|
||||
|
||||
Reference in New Issue
Block a user