UNPKG

mastercache

Version:

Multi-tier cache module for Node.js. Redis, Upstash, CloudfareKV, File, in-memory and others drivers

88 lines (70 loc) 2.57 kB
import type { Knex } from 'knex'; import { DatabaseDriver } from '../database'; import type { CreateDriverResult, DatabaseAdapter, KnexConfig } from '../../../types/main'; /** * Knex adapter for the DatabaseDriver */ export class KnexAdapter implements DatabaseAdapter { #connection: Knex; #tableName!: string; constructor(config: KnexConfig) { this.#connection = config.connection; } setTableName(tableName: string): void { this.#tableName = tableName; } async get(key: string): Promise<{ value: string; expiresAt: number | null } | undefined> { const result = await this.#connection .from(this.#tableName) .select(['value', 'expires_at']) .where('key', key) .first(); if (!result) return; return { value: result.value, expiresAt: result.expires_at }; } async delete(key: string): Promise<boolean> { const result = await this.#connection.from(this.#tableName).where('key', key).delete(); return result > 0; } async deleteMany(keys: string[]): Promise<number> { return await this.#connection.from(this.#tableName).whereIn('key', keys).delete(); } async disconnect(): Promise<void> { await this.#connection.destroy(); } async createTableIfNotExists(): Promise<void> { const hasTable = await this.#connection.schema.hasTable(this.#tableName); if (hasTable) return; await this.#connection.schema.createTable(this.#tableName, (table) => { table.string('key', 255).notNullable().primary(); table.text('value', 'longtext'); table.timestamp('expires_at').nullable(); }); } async pruneExpiredEntries(): Promise<void> { await this.#connection.from(this.#tableName).where('expires_at', '<', new Date()).delete(); } async clear(prefix: string): Promise<void> { await this.#connection.from(this.#tableName).where('key', 'like', `${prefix}%`).delete(); } async set(row: { key: string; value: any; expiresAt: Date | null }): Promise<void> { await this.#connection .from(this.#tableName) .insert({ key: row.key, value: row.value, expires_at: row.expiresAt }) .onConflict('key') .merge(['value', 'expires_at']); } } /** * Create a knex driver * You will need to install the underlying database package (mysql2, pg, sqlite3, etc) */ export function knexDriver(options: KnexConfig): CreateDriverResult<DatabaseDriver> { return { options, factory: (config: KnexConfig) => { const adapter = new KnexAdapter(config); return new DatabaseDriver(adapter, config); }, }; }