Create helper function to regenerate rows in tables faster

This commit is contained in:
Nicholas Wallace 2026-05-13 15:34:51 -07:00
parent 38b810bc2e
commit 6a983a53b4
2 changed files with 56 additions and 15 deletions

View file

@ -211,34 +211,56 @@ class Database {
}
/**
* Rebuild all author rows so derived fields stay in sync with the model logic.
* Rebuild rows for a model so hooks can recompute derived fields.
*
* @param {import('sequelize').ModelStatic<any>} model
* @param {{
* label?: string,
* pageSize?: number,
* attributes?: string[],
* order?: import('sequelize').Order,
* prepareRow?: (row: any) => void | Promise<void>
* }} [options]
*/
async rebuildAuthorRows() {
const pageSize = 500
async rebuildComputedTableRows(model, options = {}) {
const { label = model?.name || 'rows', pageSize = 500, attributes = ['id'], order = [['id', 'ASC']], prepareRow = async () => {} } = options
let offset = 0
let totalChange = 0
while (true) {
const authors = await this.authorModel.findAll({
attributes: ['id', 'name', 'libraryId'],
order: [['id', 'ASC']],
const rows = await model.findAll({
attributes,
order,
limit: pageSize,
offset
})
if (!authors.length) break
if (!rows.length) break
for (const authorRef of authors) {
const author = await this.authorModel.findByPk(authorRef.id)
if (!author) continue
author.changed('name', true)
await author.save({ silent: true })
for (const row of rows) {
await prepareRow(row)
if (!row.changed()) continue
totalChange++
await row.save({ silent: true })
}
offset += authors.length
if (authors.length < pageSize) break
offset += rows.length
if (rows.length < pageSize) break
}
Logger.debug(`Sanitized ${offset} author rows`)
Logger.debug(`${totalChange} out of ${offset} ${label} rows required recalculation of derived columns`)
}
/**
* Rebuild all author rows so derived fields stay in sync with the model logic.
*/
async rebuildAuthorRows() {
await this.rebuildComputedTableRows(this.authorModel, {
label: 'author',
attributes: ['id', 'name', 'lastFirst', 'searchName', 'libraryId'],
prepareRow: (author) => this.authorModel.isDerivedFieldChange(author)
})
}
/**

View file

@ -66,6 +66,25 @@ class Author extends Model {
return this.normalizeSearchName(leftName) === this.normalizeSearchName(rightName)
}
static isDerivedFieldChange(author) {
const derivedFields = this.buildAuthorDerivedFields(author.name)
let changed = false
if (author.lastFirst !== derivedFields.lastFirst) {
author.setDataValue('lastFirst', derivedFields.lastFirst)
author.changed('lastFirst', true)
changed = true
}
if (author.searchName !== derivedFields.searchName) {
author.setDataValue('searchName', derivedFields.searchName)
author.changed('searchName', true)
changed = true
}
return changed
}
/**
* Check if author exists
* @param {string} authorId