Last active
November 29, 2024 16:45
-
-
Save maietta/83865a64e459d63ae21a04e30636cbd0 to your computer and use it in GitHub Desktop.
In-Memory Key Value Store with Bun's SQLite implementation.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Database } from "bun:sqlite"; | |
export class InMemoryKeyValueStore { | |
private static instance: InMemoryKeyValueStore | null = null; | |
private db: Database; | |
// Private constructor to initialize the SQLite database | |
private constructor() { | |
this.db = new Database(":memory:"); // In-memory SQLite database | |
this.initializeDatabase(); | |
} | |
// Singleton pattern to ensure only one instance exists | |
public static getInstance(): InMemoryKeyValueStore { | |
if (InMemoryKeyValueStore.instance === null) { | |
InMemoryKeyValueStore.instance = new InMemoryKeyValueStore(); | |
} | |
return InMemoryKeyValueStore.instance; | |
} | |
// Initialize the key-value store table | |
private initializeDatabase(): void { | |
const createTableQuery = ` | |
CREATE TABLE IF NOT EXISTS InMemoryKeyValueStore ( | |
key TEXT PRIMARY KEY, | |
value TEXT | |
); | |
`; | |
this.db.run(createTableQuery); | |
} | |
// Set a value for a given key | |
public set(key: string, value: any): void { | |
const serializedValue = JSON.stringify(value); // Convert to JSON string | |
const insertOrUpdateQuery = ` | |
INSERT INTO InMemoryKeyValueStore (key, value) | |
VALUES (?, ?) | |
ON CONFLICT(key) DO UPDATE SET value = excluded.value; | |
`; | |
this.db.run(insertOrUpdateQuery, [key, serializedValue]); | |
} | |
// Get a value for a given key | |
public get<T = any>(key: string): T | null { | |
const selectQuery = `SELECT value FROM InMemoryKeyValueStore WHERE key = ?;`; | |
const row = this.db.query(selectQuery).get(key) as { value: string } | undefined; | |
if (row && row.value) { | |
try { | |
return JSON.parse(row.value) as T; // Parse JSON string | |
} catch { | |
console.error(`Failed to parse value for key "${key}"`); | |
return null; | |
} | |
} | |
return null; | |
} | |
// Delete a key from the store | |
public delete(key: string): void { | |
const deleteQuery = `DELETE FROM InMemoryKeyValueStore WHERE key = ?;`; | |
this.db.run(deleteQuery, [key]); | |
} | |
// Retrieve all keys in the store | |
public getAllKeys(): string[] { | |
const selectQuery = `SELECT key FROM InMemoryKeyValueStore;`; | |
const rows = this.db.query(selectQuery).all() as { key: string }[]; | |
return rows.map(row => row.key); | |
} | |
// Clear the store | |
public clear(): void { | |
const clearQuery = `DELETE FROM InMemoryKeyValueStore;`; | |
this.db.run(clearQuery); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const store = InMemoryKeyValueStore.getInstance(); | |
// Set some key-value pairs | |
store.set("user:1", { name: "Alice", age: 30 }); | |
store.set("user:2", { name: "Bob", age: 25 }); | |
store.set("appConfig", { theme: "dark", language: "en" }); | |
// Retrieve values | |
const user1 = store.get("user:1"); | |
console.log("User 1:", user1); // { name: "Alice", age: 30 } | |
const appConfig = store.get("appConfig"); | |
console.log("App Config:", appConfig); // { theme: "dark", language: "en" } | |
// Delete a key | |
store.delete("user:2"); | |
// Get all keys | |
const keys = store.getAllKeys(); | |
console.log("All keys:", keys); // ["user:1", "appConfig"] | |
// Clear the store | |
store.clear(); | |
console.log("Keys after clear:", store.getAllKeys()); // [] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment