Skip to main content
Glama
db.ts3.54 kB
import Database from 'better-sqlite3'; import { existsSync, unlinkSync } from 'fs'; export interface DatabaseIntegrityResult { ok: boolean; errors: string[]; } /** * Check database integrity using SQLite's integrity_check pragma. */ export function checkDatabaseIntegrity(db: Database.Database): DatabaseIntegrityResult { try { const result = db.pragma('integrity_check') as { integrity_check: string }[]; const errors = result .map(row => row.integrity_check) .filter(msg => msg !== 'ok'); return { ok: errors.length === 0, errors }; } catch (e) { return { ok: false, errors: [(e as Error).message] }; } } /** * Attempt to recover a corrupted database by creating a fresh one. * Returns true if recovery was needed and performed. */ function handleCorruptedDatabase(path: string, error: Error): void { console.error(`[Database] CRITICAL: Database corruption detected at ${path}`); console.error(`[Database] Error: ${error.message}`); // Check for WAL files const walPath = `${path}-wal`; const shmPath = `${path}-shm`; console.error('[Database] Attempting recovery by removing corrupted files...'); try { if (existsSync(path)) { unlinkSync(path); console.error(`[Database] Removed corrupted database: ${path}`); } if (existsSync(walPath)) { unlinkSync(walPath); console.error(`[Database] Removed WAL file: ${walPath}`); } if (existsSync(shmPath)) { unlinkSync(shmPath); console.error(`[Database] Removed SHM file: ${shmPath}`); } console.error('[Database] Recovery complete. A fresh database will be created.'); } catch (cleanupError) { console.error(`[Database] Failed to clean up corrupted files: ${(cleanupError as Error).message}`); throw new Error(`Database is corrupted and cleanup failed. Please manually delete: ${path}, ${walPath}, ${shmPath}`); } } export function initDB(path: string): Database.Database { console.error(`[Database] Opening database: ${path}`); let db: Database.Database; try { db = new Database(path); } catch (e) { const error = e as Error; // If we can't even open the database, it's likely corrupted if (error.message.includes('SQLITE_CORRUPT') || error.message.includes('malformed')) { handleCorruptedDatabase(path, error); // Try again with fresh database db = new Database(path); } else { throw e; } } // Set pragmas db.pragma('journal_mode = WAL'); db.pragma('foreign_keys = ON'); // Run integrity check on existing databases const integrity = checkDatabaseIntegrity(db); if (!integrity.ok) { console.error('[Database] Integrity check failed:'); integrity.errors.forEach(err => console.error(` - ${err}`)); // Close the corrupted database db.close(); // Handle the corruption handleCorruptedDatabase(path, new Error(integrity.errors.join(', '))); // Create fresh database db = new Database(path); db.pragma('journal_mode = WAL'); db.pragma('foreign_keys = ON'); console.error('[Database] Fresh database created after corruption recovery'); } else { console.error('[Database] Integrity check passed'); } return db; }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Mnehmos/rpg-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server