import type Database from 'better-sqlite3'; export function tuneConnection(handle: Database.Database, reader = false): void { handle.pragma(`cache_size = -${reader ? 32768 : 131072}`); // MEMORY also puts VACUUM's transient database in RAM. Disk-backed temps // keep migrations and large sorts from growing with the entire database. handle.pragma('temp_store = FILE'); // mmap is opt-in because the controller data directory can be a network mount. const mmapMiB = Number(process.env.EC_SQLITE_MMAP_MB ?? 0); if (Number.isSafeInteger(mmapMiB) && mmapMiB >= 0 && mmapMiB <= 32768) { handle.pragma(`mmap_size = ${mmapMiB * 1024 * 1024}`); } if (!reader) handle.pragma('journal_size_limit = 67108864'); } /** Startup needs two page caches during VACUUM, plus buffers for legacy files. */ export function tuneMigrationConnection(handle: Database.Database): void { handle.pragma('cache_size = -16384'); handle.pragma('temp_store = FILE'); handle.pragma('mmap_size = 0'); handle.pragma('journal_size_limit = 67108864'); } export function migrationStep(name: string, work: () => T): T { const started = Date.now(); console.info(`[database] migration starting: ${name}`); try { const result = work(); console.info(`[database] migration finished: ${name}`, { elapsedMs: Date.now() - started, rssMiB: Math.round(process.memoryUsage().rss / 1048576) }); return result; } catch (error) { console.error(`[database] migration failed: ${name}`, error); throw error; } }