diff --git a/package.json b/package.json index 941983f..53de4eb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@resolid/cache-manager-sqlite", - "version": "5.1.3", + "version": "5.1.4", "description": "A new SQLite store for cache-manager", "keywords": ["cache-manager", "sqlite", "better-sqlite3"], "license": "MIT", diff --git a/src/index.bench.ts b/src/index.bench.ts index 26598ff..af140b0 100644 --- a/src/index.bench.ts +++ b/src/index.bench.ts @@ -7,14 +7,14 @@ let sqlite: Database.Database; const sqliteFile = join(process.cwd(), "runtime", "cache.sqlite3"); const cacheTableName = "caches"; -const argsCount = 3; +const argsCount = 2; const keys = Array.from({ length: 10000 }, (_, i) => i + 1); beforeAll(async () => { sqlite = new Database(sqliteFile); - sqlite.pragma("journal_mode = WAL"); + //sqlite.pragma("journal_mode = WAL"); sqlite.exec(` CREATE TABLE IF NOT EXISTS ${cacheTableName} ( @@ -32,7 +32,7 @@ CREATE INDEX IF NOT EXISTS idx_expired_caches ON ${cacheTableName}(expiredAt); const createdAt = new Date().getTime(); - for (const k in keys) { + for (const k of keys) { updateStatement.run(k, "cacheData", createdAt, -1); } }); @@ -42,7 +42,7 @@ describe("sqlite select", () => { const selectStatement = sqlite.prepare(`SELECT * FROM ${cacheTableName} WHERE cacheKey = ?`); const selectKeys = Array.from({ length: argsCount }, (_, i) => i + 1); - for (const k in selectKeys) { + for (const k of selectKeys) { selectStatement.get(k); } }); @@ -61,7 +61,7 @@ describe("sqlite delete", () => { const deleteStatement = sqlite.prepare(`DELETE FROM ${cacheTableName} WHERE cacheKey = ?`); const deleteKeys = Array.from({ length: argsCount }, (_, i) => i + 1000); - for (const k in deleteKeys) { + for (const k of deleteKeys) { deleteStatement.run(k); } }); diff --git a/src/index.ts b/src/index.ts index 0fec564..6784eb8 100644 --- a/src/index.ts +++ b/src/index.ts @@ -46,12 +46,14 @@ export const sqliteStore = (options: SqliteStoreOptions): SqliteStore => { CREATE INDEX IF NOT EXISTS idx_expired_caches ON ${tableName}(expiredAt); `); + const selectSingleStatement = sqlite.prepare(`SELECT * FROM ${tableName} WHERE cacheKey = ?`); const selectStatement = sqlite.prepare( `SELECT * FROM ${tableName} WHERE cacheKey IN (SELECT value FROM json_each(?))`, ); const updateStatement = sqlite.prepare( `INSERT OR REPLACE INTO ${tableName}(cacheKey, cacheData, createdAt, expiredAt) VALUES (?, ?, ?, ?)`, ); + const deleteSingleStatement = sqlite.prepare(`DELETE FROM ${tableName} WHERE cacheKey = ?`); const deleteStatement = sqlite.prepare(`DELETE FROM ${tableName} WHERE cacheKey IN (SELECT value FROM json_each(?))`); const finderStatement = sqlite.prepare( `SELECT cacheKey FROM ${tableName} WHERE cacheKey LIKE ? AND (expiredAt = -1 OR expiredAt > ?)`, @@ -63,26 +65,45 @@ CREATE INDEX IF NOT EXISTS idx_expired_caches ON ${tableName}(expiredAt); const ts = now(); let purgeExpired = false; - const result = selectStatement - .all(JSON.stringify(args)) - .map((data) => { - if (data.expiredAt !== -1 && data.expiredAt < ts) { - purgeExpired = true; - return undefined; - } - return data; - }) - .filter((data) => data !== undefined) as CacheObject[]; + const result = + args.length >= 3 + ? selectStatement + .all(JSON.stringify(args)) + .map((data) => { + if (data.expiredAt !== -1 && data.expiredAt < ts) { + purgeExpired = true; + return undefined; + } + return data; + }) + .filter((data) => data !== undefined) + : args + .map((key) => { + const data = selectSingleStatement.get(key); + if (data !== undefined && data.expiredAt !== -1 && data.expiredAt < ts) { + purgeExpired = true; + return undefined; + } + + return data; + }) + .filter((data) => data !== undefined); if (purgeExpired) { process.nextTick(() => purgeStatement.run(ts)); } - return result; + return result as CacheObject[]; }; const deleteCaches = (...args: string[]) => { - deleteStatement.run(JSON.stringify(args)); + if (args.length >= 3) { + deleteStatement.run(JSON.stringify(args)); + } else { + for (const k of args) { + deleteSingleStatement.run(k); + } + } }; const updateCatches = (args: [string, unknown][], ttl?: Milliseconds) => {