fix: tag clean up query and add tests (#22633)

* fix delete empty tags query

* rewrite as a single statement

* create tag service medium test

* single tag exists, connected to one asset, and is not deleted

* do not delete parent tag if children have an asset

* hierarchical tag tests

* fix query to match 3 test

* remove transaction and format:fix

* remove transaction and format:fix

* simplify query, handle nested empty tag

* unused helper

---------

Co-authored-by: mertalev <101130780+mertalev@users.noreply.github.com>
This commit is contained in:
Jorge Montejo
2025-10-16 00:51:57 +02:00
committed by GitHub
parent 74a9be4a0e
commit 9d639607c7
3 changed files with 171 additions and 17 deletions

View File

@@ -163,22 +163,22 @@ export class TagRepository {
}
async deleteEmptyTags() {
// TODO rewrite as a single statement
await this.db.transaction().execute(async (tx) => {
const result = await tx
.selectFrom('asset')
.innerJoin('tag_asset', 'tag_asset.assetsId', 'asset.id')
.innerJoin('tag_closure', 'tag_closure.id_descendant', 'tag_asset.tagsId')
.innerJoin('tag', 'tag.id', 'tag_closure.id_descendant')
.select((eb) => ['tag.id', eb.fn.count<number>('asset.id').as('count')])
.groupBy('tag.id')
.execute();
const result = await this.db
.deleteFrom('tag')
.where(({ not, exists, selectFrom }) =>
not(
exists(
selectFrom('tag_closure')
.whereRef('tag.id', '=', 'tag_closure.id_ancestor')
.innerJoin('tag_asset', 'tag_closure.id_descendant', 'tag_asset.tagsId'),
),
),
)
.executeTakeFirst();
const ids = result.filter(({ count }) => count === 0).map(({ id }) => id);
if (ids.length > 0) {
await this.db.deleteFrom('tag').where('id', 'in', ids).execute();
this.logger.log(`Deleted ${ids.length} empty tags`);
}
});
const deletedRows = Number(result.numDeletedRows);
if (deletedRows > 0) {
this.logger.log(`Deleted ${deletedRows} empty tags`);
}
}
}