From 5ca12eee19a8d64d0a2f029465e228da15ca799c Mon Sep 17 00:00:00 2001 From: advplyr Date: Thu, 13 Feb 2025 18:07:59 -0600 Subject: [PATCH] Fix count cache by stringify Symbols #3979 --- .../utils/queries/libraryItemsBookFilters.js | 5 +-- server/utils/stringifySequelizeQuery.js | 34 +++++++++++++++++++ 2 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 server/utils/stringifySequelizeQuery.js diff --git a/server/utils/queries/libraryItemsBookFilters.js b/server/utils/queries/libraryItemsBookFilters.js index 65ab1fef..d446a5e9 100644 --- a/server/utils/queries/libraryItemsBookFilters.js +++ b/server/utils/queries/libraryItemsBookFilters.js @@ -5,7 +5,7 @@ const authorFilters = require('./authorFilters') const ShareManager = require('../../managers/ShareManager') const { profile } = require('../profiler') - +const stringifySequelizeQuery = require('../stringifySequelizeQuery') const countCache = new Map() module.exports = { @@ -345,7 +345,7 @@ module.exports = { }, async findAndCountAll(findOptions, limit, offset) { - const findOptionsKey = JSON.stringify(findOptions) + const findOptionsKey = stringifySequelizeQuery(findOptions) Logger.debug(`[LibraryItemsBookFilters] findOptionsKey: ${findOptionsKey}`) findOptions.limit = limit || null @@ -353,6 +353,7 @@ module.exports = { if (countCache.has(findOptionsKey)) { const rows = await Database.bookModel.findAll(findOptions) + return { rows, count: countCache.get(findOptionsKey) } } else { const result = await Database.bookModel.findAndCountAll(findOptions) diff --git a/server/utils/stringifySequelizeQuery.js b/server/utils/stringifySequelizeQuery.js new file mode 100644 index 00000000..a41e0650 --- /dev/null +++ b/server/utils/stringifySequelizeQuery.js @@ -0,0 +1,34 @@ +function stringifySequelizeQuery(findOptions) { + // Helper function to handle symbols in nested objects + function handleSymbols(obj) { + if (!obj || typeof obj !== 'object') return obj + + if (Array.isArray(obj)) { + return obj.map(handleSymbols) + } + + const newObj = {} + for (const [key, value] of Object.entries(obj)) { + // Handle Symbol keys from Object.getOwnPropertySymbols + Object.getOwnPropertySymbols(obj).forEach((sym) => { + newObj[`__Op.${sym.toString()}`] = handleSymbols(obj[sym]) + }) + + // Handle regular keys + if (typeof key === 'string') { + if (value && typeof value === 'object' && Object.getPrototypeOf(value) === Symbol.prototype) { + // Handle Symbol values + newObj[key] = `__Op.${value.toString()}` + } else { + // Recursively handle nested objects + newObj[key] = handleSymbols(value) + } + } + } + return newObj + } + + const sanitizedOptions = handleSymbols(findOptions) + return JSON.stringify(sanitizedOptions) +} +module.exports = stringifySequelizeQuery