From f827aa97f8d74aead118387f2e8cd608cad26393 Mon Sep 17 00:00:00 2001 From: advplyr Date: Sat, 23 Mar 2024 14:56:32 -0500 Subject: [PATCH] Update library scanner findLibraryItemByItemToFileInoMatch query to iterate through json objects comparing inodes --- server/Logger.js | 2 +- server/models/LibraryItem.js | 10 ++++++---- server/scanner/LibraryScanner.js | 28 ++++++++++++++++------------ 3 files changed, 23 insertions(+), 17 deletions(-) diff --git a/server/Logger.js b/server/Logger.js index 7cc7aa4c..8283e1f0 100644 --- a/server/Logger.js +++ b/server/Logger.js @@ -93,7 +93,7 @@ class Logger { // Save log to file if (level >= this.logLevel) { - await this.logManager.logToFile(logObj) + await this.logManager?.logToFile(logObj) } } diff --git a/server/models/LibraryItem.js b/server/models/LibraryItem.js index 44758750..704e2f10 100644 --- a/server/models/LibraryItem.js +++ b/server/models/LibraryItem.js @@ -1,4 +1,4 @@ -const { DataTypes, Model, WhereOptions } = require('sequelize') +const { DataTypes, Model } = require('sequelize') const Logger = require('../Logger') const oldLibraryItem = require('../objects/LibraryItem') const libraryFilters = require('../utils/queries/libraryFilters') @@ -116,7 +116,7 @@ class LibraryItem extends Model { /** * Currently unused because this is too slow and uses too much mem - * @param {[WhereOptions]} where + * @param {import('sequelize').WhereOptions} [where] * @returns {Array} old library items */ static async getAllOldLibraryItems(where = null) { @@ -773,12 +773,14 @@ class LibraryItem extends Model { /** * - * @param {WhereOptions} where + * @param {import('sequelize').WhereOptions} where + * @param {import('sequelize').BindOrReplacements} replacements * @returns {Object} oldLibraryItem */ - static async findOneOld(where) { + static async findOneOld(where, replacements = {}) { const libraryItem = await this.findOne({ where, + replacements, include: [ { model: this.sequelize.models.book, diff --git a/server/scanner/LibraryScanner.js b/server/scanner/LibraryScanner.js index d394128c..8131300d 100644 --- a/server/scanner/LibraryScanner.js +++ b/server/scanner/LibraryScanner.js @@ -155,10 +155,10 @@ class LibraryScanner { if (!libraryItemData) { // Fallback to finding matching library item with matching inode value libraryItemData = libraryItemDataFound.find(lid => - ItemToItemInoMatch(lid, existingLibraryItem) || - ItemToFileInoMatch(lid, existingLibraryItem) || + ItemToItemInoMatch(lid, existingLibraryItem) || + ItemToFileInoMatch(lid, existingLibraryItem) || ItemToFileInoMatch(existingLibraryItem, lid) - ) + ) if (libraryItemData) { libraryScan.addLog(LogLevel.INFO, `Library item with path "${existingLibraryItem.path}" was not found, but library item inode "${existingLibraryItem.ino}" was found at path "${libraryItemData.path}"`) } @@ -533,8 +533,8 @@ class LibraryScanner { let updatedLibraryItemDetails = {} if (!existingLibraryItem) { const isSingleMedia = isSingleMediaFile(fileUpdateGroup, itemDir) - existingLibraryItem = - await findLibraryItemByItemToItemInoMatch(library.id, fullPath) || + existingLibraryItem = + await findLibraryItemByItemToItemInoMatch(library.id, fullPath) || await findLibraryItemByItemToFileInoMatch(library.id, fullPath, isSingleMedia) || await findLibraryItemByFileToItemInoMatch(library.id, fullPath, isSingleMedia, fileUpdateGroup[itemDir]) if (existingLibraryItem) { @@ -630,16 +630,20 @@ async function findLibraryItemByItemToItemInoMatch(libraryId, fullPath) { return existingLibraryItem } -async function findLibraryItemByItemToFileInoMatch(libraryId, fullPath, isSingleMedia) { +async function findLibraryItemByItemToFileInoMatch(libraryId, fullPath, isSingleMedia) { if (!isSingleMedia) return null // check if it was moved from another folder by comparing the ino to the library files const ino = await fileUtils.getIno(fullPath) if (!ino) return null - const existingLibraryItem = await Database.libraryItemModel.findOneOld({ - libraryId: libraryId, - libraryFiles: { - [ sequelize.Op.substring ]: ino - } + const existingLibraryItem = await Database.libraryItemModel.findOneOld([ + { + libraryId: libraryId + }, + sequelize.where(sequelize.literal('(SELECT count(*) FROM json_each(libraryFiles) WHERE json_valid(json_each.value) AND json_each.value->>"$.ino" = :inode)'), { + [sequelize.Op.gt]: 0 + }) + ], { + inode: ino }) if (existingLibraryItem) Logger.debug(`[LibraryScanner] Found library item with a library file matching inode "${ino}" at path "${existingLibraryItem.path}"`) @@ -658,7 +662,7 @@ async function findLibraryItemByFileToItemInoMatch(libraryId, fullPath, isSingle const existingLibraryItem = await Database.libraryItemModel.findOneOld({ libraryId: libraryId, ino: { - [ sequelize.Op.in ] : itemFileInos + [sequelize.Op.in]: itemFileInos } }) if (existingLibraryItem)