86 lines
2.3 KiB
TypeScript
Raw Normal View History

import process from "node:process"
2024-10-14 00:02:58 +08:00
import type { NewsItem } from "@shared/types"
2024-10-03 23:11:10 +08:00
import type { Database } from "db0"
import type { CacheInfo, CacheRow } from "../types"
2024-10-03 17:24:29 +08:00
export class Cache {
private db
2024-10-03 23:11:10 +08:00
constructor(db: Database) {
2024-10-03 17:24:29 +08:00
this.db = db
2024-10-03 23:11:10 +08:00
}
async init() {
await this.db.prepare(`
2024-10-03 17:24:29 +08:00
CREATE TABLE IF NOT EXISTS cache (
id TEXT PRIMARY KEY,
updated INTEGER,
2024-10-05 17:20:49 +08:00
data TEXT
2024-10-03 17:24:29 +08:00
);
2024-10-03 23:11:10 +08:00
`).run()
2024-10-05 23:55:30 +08:00
logger.success(`init cache table`)
2024-10-03 17:24:29 +08:00
}
2024-10-05 17:20:49 +08:00
async set(key: string, value: NewsItem[]) {
2024-10-03 17:24:29 +08:00
const now = Date.now()
2024-10-04 15:36:03 +08:00
await this.db.prepare(
2024-10-05 17:20:49 +08:00
`INSERT OR REPLACE INTO cache (id, data, updated) VALUES (?, ?, ?)`,
).run(key, JSON.stringify(value), now)
2024-10-05 23:55:30 +08:00
logger.success(`set ${key} cache`)
2024-10-03 17:24:29 +08:00
}
async get(key: string): Promise<CacheInfo | undefined > {
const row = (await this.db.prepare(`SELECT id, data, updated FROM cache WHERE id = ?`).get(key)) as CacheRow | undefined
if (row) {
logger.success(`get ${key} cache`)
return {
id: row.id,
updated: row.updated,
items: JSON.parse(row.data),
}
}
2024-10-03 17:24:29 +08:00
}
async getEntire(keys: string[]): Promise<CacheInfo[]> {
2024-11-03 00:59:44 +08:00
const keysStr = keys.map(k => `id = '${k}'`).join(" or ")
const res = await this.db.prepare(`SELECT id, data, updated FROM cache WHERE ${keysStr}`).all() as any
const rows = (res.results ?? res) as CacheRow[]
2024-11-03 00:59:44 +08:00
/**
* https://developers.cloudflare.com/d1/build-with-d1/d1-client-api/#return-object
* cloudflare d1 .all() will return
* {
* success: boolean
* meta:
* results:
* }
*/
if (rows?.length) {
logger.success(`get entire (...) cache`)
return rows.map(row => ({
2024-11-03 00:59:44 +08:00
id: row.id,
updated: row.updated,
2024-11-03 00:59:44 +08:00
items: JSON.parse(row.data) as NewsItem[],
}))
} else {
return []
2024-11-03 00:59:44 +08:00
}
}
2024-10-03 17:24:29 +08:00
async delete(key: string) {
return await this.db.prepare(`DELETE FROM cache WHERE id = ?`).run(key)
}
}
export async function getCacheTable() {
try {
// 如果没有数据库,这里不会报错,只会在第一次访问的时候报错
const db = useDatabase()
2024-10-31 14:21:11 +08:00
if (process.env.ENABLE_CACHE === "false") return
const cacheTable = new Cache(db)
if (process.env.INIT_TABLE !== "false") await cacheTable.init()
return cacheTable
2024-11-03 00:59:44 +08:00
} catch {
// logger.error("failed to init database ", e)
}
}