diff --git a/src/config.ts b/src/config.ts index cce1ce2..246bf5a 100644 --- a/src/config.ts +++ b/src/config.ts @@ -144,9 +144,25 @@ const Conf = { local(path: string): string { return mergePaths(Conf.localDomain, path); }, + /** URL to send Sentry errors to. */ get sentryDsn() { return Deno.env.get('SENTRY_DSN'); }, + /** SQLite settings. */ + sqlite: { + /** + * Number of bytes to use for memory-mapped IO. + * https://www.sqlite.org/pragma.html#pragma_mmap_size + */ + get mmapSize(): number { + const value = Deno.env.get('SQLITE_MMAP_SIZE'); + if (value) { + return Number(value); + } else { + return 1024 * 1024 * 1024; + } + }, + }, }; const optionalBooleanSchema = z diff --git a/src/db.ts b/src/db.ts index 43d7f04..58576e5 100644 --- a/src/db.ts +++ b/src/db.ts @@ -1,7 +1,7 @@ import fs from 'node:fs/promises'; import path from 'node:path'; -import { DenoSqlite3, DenoSqliteDialect, FileMigrationProvider, Kysely, Migrator } from '@/deps.ts'; +import { DenoSqlite3, DenoSqliteDialect, FileMigrationProvider, Kysely, Migrator, sql } from '@/deps.ts'; import { Conf } from '@/config.ts'; interface DittoDB { @@ -55,12 +55,27 @@ interface UnattachedMediaRow { uploaded_at: Date; } +const sqlite = new DenoSqlite3(Conf.dbPath); + +setPragmas(sqlite, { + synchronous: 'normal', + temp_store: 'memory', + mmap_size: Conf.sqlite.mmapSize, +}); + const db = new Kysely({ dialect: new DenoSqliteDialect({ - database: new DenoSqlite3(Conf.dbPath), + database: sqlite, }), }); +function setPragmas(db: DenoSqlite3, pragmas: Record) { + for (const [pragma, value] of Object.entries(pragmas)) { + db.prepare(`PRAGMA ${pragma} = ${value}`).run(); + console.log(`PRAGMA ${pragma} = ${db.prepare(`PRAGMA ${pragma}`).value()}`); + } +} + const migrator = new Migrator({ db, provider: new FileMigrationProvider({