Add: transaction to empty author remove

This commit is contained in:
Nicholas Wallace 2025-03-08 10:43:27 -07:00
parent d3fd19da65
commit 167617cce0

View File

@ -420,40 +420,53 @@ class ApiRouter {
async checkRemoveAuthorsWithNoBooks(authorIds) { async checkRemoveAuthorsWithNoBooks(authorIds) {
if (!authorIds?.length) return if (!authorIds?.length) return
const bookAuthorsToRemove = ( const transaction = await Database.sequelize.transaction()
await Database.authorModel.findAll({ try {
where: [ // Select authors with locking to prevent concurrent updates
{ const bookAuthorsToRemove = (
id: authorIds, await Database.authorModel.findAll({
asin: { where: [
[sequelize.Op.or]: [null, ''] {
id: authorIds,
asin: {
[sequelize.Op.or]: [null, '']
},
description: {
[sequelize.Op.or]: [null, '']
},
imagePath: {
[sequelize.Op.or]: [null, '']
}
}, },
description: { sequelize.where(sequelize.literal('(SELECT count(*) FROM bookAuthors ba WHERE ba.authorId = author.id)'), 0)
[sequelize.Op.or]: [null, ''] ],
}, attributes: ['id', 'name', 'libraryId'],
imagePath: { raw: true,
[sequelize.Op.or]: [null, ''] transaction
} })
}, ).map((au) => ({ id: au.id, name: au.name, libraryId: au.libraryId }))
sequelize.where(sequelize.literal('(SELECT count(*) FROM bookAuthors ba WHERE ba.authorId = author.id)'), 0)
],
attributes: ['id', 'name', 'libraryId'],
raw: true
})
).map((au) => ({ id: au.id, name: au.name, libraryId: au.libraryId }))
if (bookAuthorsToRemove.length) { if (bookAuthorsToRemove.length) {
await Database.authorModel.destroy({ await Database.authorModel.destroy({
where: { where: {
id: bookAuthorsToRemove.map((au) => au.id) id: bookAuthorsToRemove.map((au) => au.id)
} },
}) transaction
})
}
await transaction.commit()
// Remove all book authors after completing remove from database
bookAuthorsToRemove.forEach(({ id, name, libraryId }) => { bookAuthorsToRemove.forEach(({ id, name, libraryId }) => {
Database.removeAuthorFromFilterData(libraryId, id) Database.removeAuthorFromFilterData(libraryId, id)
// TODO: Clients were expecting full author in payload but its unnecessary // TODO: Clients were expecting full author in payload but its unnecessary
SocketAuthority.emitter('author_removed', { id, libraryId }) SocketAuthority.emitter('author_removed', { id, libraryId })
Logger.info(`[ApiRouter] Removed author "${name}" with no books`) Logger.info(`[ApiRouter] Removed author "${name}" with no books`)
}) })
} catch (error) {
await transaction.rollback()
Logger.error(`[ApiRouter] Error removing authors: ${error.message}`)
} }
} }