-
Notifications
You must be signed in to change notification settings - Fork 3
Open
Description
Hi, huge fan of your library. I went ahead and forked it to meet the following needs:
- Make it work with cache-manager@5, which simplified the storage contract to be less variadic and more predictable. This doesn't appear to be backwards compatible.
- Converted it to Typescript so that I can get code completion when passing it to
cacheManager.caching
. - Swapped in better-sqlite3 for sqlite3 as the former is "faster" and the latter uses a node-gyp fork that has bunch of testing required into code that is shipped with the library which breaks builds in an Astro / Vite setup that I'm working in.
Feel free to port/steal whatever you would like for this library! Open source!
In doing the porting, I noticed a bug in your implementation of mget
. The SELECT
statement for this is just an IN
query which will return unpredictably if keys do not exist OR the keys are not provided in alphabetical order. In practice, the following have issues from what I can tell:
await cache.set('a', 'a')
await cache.set('b', 'b')
await cache.set('z', 'z')
// This mget has a gap at position 'c' and it should return ['a', 'b', undefined, 'z'] but it returns ['a', 'b', 'z']
let [a, b, c, z] = await cache.mget('a', 'b', 'c', 'z')
// this will actually equal 'z'
assert(c === undefined)
// this is undefined as the array is only 3 elements long
assert(z === 'z')
// This mget returns items in reverse order and should be ['z', 'b', 'a'] but it returns ['a', 'b', 'z']
let [z, b, a] = await cache.mget('z', 'b', 'a')
// this will actually equal 'a'
assert(z === 'z')
// this will actually equal 'z'
assert(a === 'a')
The way I got around this is by using a varadic CTE that correctly orders and fills in the gaps in the query with almost equal complexity to an IN
statement you have.
> explain query plan WITH getKeys(key) AS (VALUES ("a"), ("b"), ("c"), ("z"))
SELECT
getKeys.key,
val,
created_at,
expire_at
FROM getKeys
LEFT JOIN kv ON kv.key = getKeys.key;
QUERY PLAN
|--CO-ROUTINE getKeys
| `--SCAN 3 CONSTANT ROWS
|--SCAN getKeys
`--SEARCH kv USING INDEX sqlite_autoindex_kv_1 (key=?) LEFT-JOIN
> explain query plan select * from kv where key in ("a", "b", "c", "z");
QUERY PLAN
`--SEARCH kv USING INDEX sqlite_autoindex_kv_1 (key=?)
Metadata
Metadata
Assignees
Labels
No labels