Skip to content

Commit fb9d520

Browse files
committed
feat: sqlite add set and minor cleanup
1 parent d76f5cf commit fb9d520

File tree

2 files changed

+100
-46
lines changed

2 files changed

+100
-46
lines changed

lib/cache/sqlite-cache-store.js

+56-45
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ module.exports = class SqliteCacheStore {
239239
statusMessage: value.statusMessage,
240240
headers: value.headers ? JSON.parse(value.headers) : undefined,
241241
etag: value.etag ? value.etag : undefined,
242-
vary: value.vary ?? undefined,
242+
vary: value.vary ? JSON.parse(value.vary) : undefined,
243243
cacheControlDirectives: value.cacheControlDirectives
244244
? JSON.parse(value.cacheControlDirectives)
245245
: undefined,
@@ -251,6 +251,56 @@ module.exports = class SqliteCacheStore {
251251
return result
252252
}
253253

254+
/**
255+
* @param {import('../../types/cache-interceptor.d.ts').default.CacheKey} key
256+
* @param {import('../../types/cache-interceptor.d.ts').default.CacheValue & { body: null | Buffer | Array<Buffer>}} value
257+
*/
258+
set (key, value) {
259+
const url = this.#makeValueUrl(key)
260+
const body = Array.isArray(value.body) ? Buffer.concat(value.body) : value.body
261+
const size = body?.byteLength
262+
263+
if (size && size > this.#maxEntrySize) {
264+
return
265+
}
266+
267+
const existingValue = this.#findValue(key, true)
268+
if (existingValue) {
269+
// Updating an existing response, let's overwrite it
270+
this.#updateValueQuery.run(
271+
body,
272+
value.deleteAt,
273+
value.statusCode,
274+
value.statusMessage,
275+
value.headers ? JSON.stringify(value.headers) : null,
276+
value.etag ? value.etag : null,
277+
value.cacheControlDirectives ? JSON.stringify(value.cacheControlDirectives) : null,
278+
value.cachedAt,
279+
value.staleAt,
280+
value.deleteAt,
281+
existingValue.id
282+
)
283+
} else {
284+
this.#prune()
285+
// New response, let's insert it
286+
this.#insertValueQuery.run(
287+
url,
288+
key.method,
289+
body ?? null,
290+
value.deleteAt,
291+
value.statusCode,
292+
value.statusMessage,
293+
value.headers ? JSON.stringify(value.headers) : null,
294+
value.etag ? value.etag : null,
295+
value.cacheControlDirectives ? JSON.stringify(value.cacheControlDirectives) : null,
296+
value.vary ? JSON.stringify(value.vary) : null,
297+
value.cachedAt,
298+
value.staleAt,
299+
value.deleteAt
300+
)
301+
}
302+
}
303+
254304
/**
255305
* @param {import('../../types/cache-interceptor.d.ts').default.CacheKey} key
256306
* @param {import('../../types/cache-interceptor.d.ts').default.CacheValue} value
@@ -260,7 +310,6 @@ module.exports = class SqliteCacheStore {
260310
assertCacheKey(key)
261311
assertCacheValue(value)
262312

263-
const url = this.#makeValueUrl(key)
264313
let size = 0
265314
/**
266315
* @type {Buffer[] | null}
@@ -269,11 +318,8 @@ module.exports = class SqliteCacheStore {
269318
const store = this
270319

271320
return new Writable({
321+
decodeStrings: true,
272322
write (chunk, encoding, callback) {
273-
if (typeof chunk === 'string') {
274-
chunk = Buffer.from(chunk, encoding)
275-
}
276-
277323
size += chunk.byteLength
278324

279325
if (size < store.#maxEntrySize) {
@@ -285,42 +331,7 @@ module.exports = class SqliteCacheStore {
285331
callback()
286332
},
287333
final (callback) {
288-
const existingValue = store.#findValue(key, true)
289-
if (existingValue) {
290-
// Updating an existing response, let's overwrite it
291-
store.#updateValueQuery.run(
292-
Buffer.concat(body),
293-
value.deleteAt,
294-
value.statusCode,
295-
value.statusMessage,
296-
value.headers ? JSON.stringify(value.headers) : null,
297-
value.etag ? value.etag : null,
298-
value.cacheControlDirectives ? JSON.stringify(value.cacheControlDirectives) : null,
299-
value.cachedAt,
300-
value.staleAt,
301-
value.deleteAt,
302-
existingValue.id
303-
)
304-
} else {
305-
store.#prune()
306-
// New response, let's insert it
307-
store.#insertValueQuery.run(
308-
url,
309-
key.method,
310-
Buffer.concat(body),
311-
value.deleteAt,
312-
value.statusCode,
313-
value.statusMessage,
314-
value.headers ? JSON.stringify(value.headers) : null,
315-
value.etag ? value.etag : null,
316-
value.cacheControlDirectives ? JSON.stringify(value.cacheControlDirectives) : null,
317-
value.vary ? JSON.stringify(value.vary) : null,
318-
value.cachedAt,
319-
value.staleAt,
320-
value.deleteAt
321-
)
322-
}
323-
334+
store.set(key, { ...value, body })
324335
callback()
325336
}
326337
})
@@ -407,10 +418,10 @@ module.exports = class SqliteCacheStore {
407418
return undefined
408419
}
409420

410-
value.vary = JSON.parse(value.vary)
421+
const vary = JSON.parse(value.vary)
411422

412-
for (const header in value.vary) {
413-
if (!headerValueEquals(headers[header], value.vary[header])) {
423+
for (const header in vary) {
424+
if (!headerValueEquals(headers[header], vary[header])) {
414425
matches = false
415426
break
416427
}

test/cache-interceptor/sqlite-cache-store-tests.js

+44-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'use strict'
22

33
const { test, skip } = require('node:test')
4-
const { notEqual, strictEqual } = require('node:assert')
4+
const { notEqual, strictEqual, deepStrictEqual } = require('node:assert')
55
const { rm } = require('node:fs/promises')
66
const { cacheStoreTests, writeBody, compareGetResults } = require('./cache-store-test-utils.js')
77

@@ -179,3 +179,46 @@ test('SqliteCacheStore two writes', async (t) => {
179179
writeBody(writable, body)
180180
}
181181
})
182+
183+
test('SqliteCacheStore write & read', async (t) => {
184+
if (!hasSqlite) {
185+
t.skip()
186+
return
187+
}
188+
189+
const SqliteCacheStore = require('../../lib/cache/sqlite-cache-store.js')
190+
191+
const store = new SqliteCacheStore({
192+
maxCount: 10
193+
})
194+
195+
/**
196+
* @type {import('../../types/cache-interceptor.d.ts').default.CacheKey}
197+
*/
198+
const key = {
199+
origin: 'localhost',
200+
path: '/',
201+
method: 'GET',
202+
headers: {}
203+
}
204+
205+
/**
206+
* @type {import('../../types/cache-interceptor.d.ts').default.CacheValue & { body: Buffer }}
207+
*/
208+
const value = {
209+
statusCode: 200,
210+
statusMessage: '',
211+
headers: { foo: 'bar' },
212+
cacheControlDirectives: { 'max-stale': 0 },
213+
cachedAt: Date.now(),
214+
staleAt: Date.now() + 10000,
215+
deleteAt: Date.now() + 20000,
216+
body: Buffer.from('asd'),
217+
etag: undefined,
218+
vary: undefined
219+
}
220+
221+
store.set(key, value)
222+
223+
deepStrictEqual(store.get(key), value)
224+
})

0 commit comments

Comments
 (0)