5.6 KiB
App Database
Source: src/lib/server/db/ (db.ts, migrations.ts, migrations/, queries/)
The app database (profilarr.db) is a SQLite file that stores all application
state: Arr instances, settings, job queue, notifications, sessions, and PCD ops.
It uses a singleton DatabaseManager, migration-based schema management, and
raw SQL query modules with parameter binding. Kysely is not
used here -- it's reserved for the PCD cache (see pcd.md).
Table of Contents
Initialization
The database initializes early in the server startup sequence
(src/hooks.server.ts):
config.init()-- ensure data directories existdb.initialize()-- open SQLite connection, set pragmasrunMigrations()-- apply pending schema changes- Load log settings, initialize PCD manager, start job queue
Three pragmas are set on every connection:
| Pragma | Value | Purpose |
|---|---|---|
foreign_keys |
ON |
Enforce referential integrity |
journal_mode |
WAL |
Write-Ahead Logging for concurrency |
synchronous |
NORMAL |
Balanced performance/safety |
The manager includes HMR recovery for development: isHealthy() runs
SELECT 1 to verify the connection is alive. If the check fails during
initialization (common after Vite hot reloads), the manager closes and
reinitializes the connection.
Transaction support is available via transaction<T>(fn), an async wrapper
that auto-commits on success and auto-rollbacks on error. Raw
beginTransaction(), commit(), and rollback() methods are also exposed.
Schema
src/lib/server/db/schema.sql is a reference snapshot of the current
schema after all migrations have been applied. Its header reads:
DO NOT execute this file directly -- use migrations instead.
The file is useful for understanding the final table structure, reviewing database design, and onboarding new contributors. It is not used at runtime. Migrations are the source of truth for schema changes.
Migrations
Source: src/lib/server/db/migrations/ (sequentially numbered NNN_*.ts)
Runner: src/lib/server/db/migrations.ts
Each migration exports an object matching the Migration interface:
| Field | Required | Purpose |
|---|---|---|
version |
yes | Sequential number (001, 002, ...) |
name |
yes | Human-readable description |
up |
yes | SQL to apply the migration |
down |
no | SQL to roll back (omit if not rollbackable) |
afterUp |
no | Callback for data migrations after schema DDL |
The runner applies pending migrations in version order. Each up block runs
inside a transaction. The afterUp callback runs outside the transaction,
which is useful for data migrations that need the new schema committed first.
A migrations table tracks applied versions with timestamps. The runner
supports up (apply pending), down (roll back to target version), and
fresh (reset and reapply all).
Adding a Migration
- Review
migrations/_template.tsas your starting point. - Number sequentially after the highest existing migration.
- Write the
upSQL. Providedownif the migration is rollbackable. - Add the import and entry in
migrations.tsinsideloadMigrations(). - Test both fresh (
db.fresh()) and incremental application. - Update
schema.sqlto reflect the new state.
Rule: Never modify an already-applied migration. If a migration has a bug, create a new migration to fix it.
Query Layer
Source: src/lib/server/db/queries/
Each module covers one database table and exports a queries object with typed methods.
All use raw SQL with ? parameter binding and typed input/output interfaces.
| Module | Domain |
|---|---|
arrInstances |
Arr instance CRUD |
arrSync |
Sync config and status per instance |
arrCleanupSettings |
Stale config cleanup settings |
arrRenameSettings |
Rename job settings per instance |
authSettings |
Session duration, API key |
sessions |
Session CRUD and cleanup |
jobQueue |
Job queue CRUD, claim, reschedule |
jobRunHistory |
Job execution history |
pcdOps |
PCD operation CRUD and filtering |
pcdOpHistory |
Per-compile op application results |
notificationServices |
Notification service config |
logSettings |
Log level and output settings |
renameRuns |
Rename job run history |
upgradeRuns |
Upgrade job run history |
parsedReleaseCache |
Parser result cache |
patternMatchCache |
Regex match result cache |
githubCache |
GitHub API response cache |
tmdbSettings |
TMDB API key storage |
aiSettings |
AI service settings |
appInfo |
App metadata and setup state |
Query methods follow a consistent pattern: typed input interfaces for
mutations, generic return types for reads, and the singleton db instance
for all operations.