Skip to content

Instantly share code, notes, and snippets.

@maietta
Last active November 29, 2024 16:45
Show Gist options
  • Save maietta/83865a64e459d63ae21a04e30636cbd0 to your computer and use it in GitHub Desktop.
Save maietta/83865a64e459d63ae21a04e30636cbd0 to your computer and use it in GitHub Desktop.
In-Memory Key Value Store with Bun's SQLite implementation.
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);
}
}
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