Expand description
SQLite database layer for scalable storage of audio samples, analysis caches, and scan metadata. Replaces JSON file persistence for data that can grow to millions of rows.
Structs§
- Audio
Query Params - Parameters for paginated audio sample queries.
- Audio
Query Result - Result of a paginated query.
- Audio
Sample Row - A single row returned from a paginated query, with analysis data inline.
- Audio
Stats Result - Aggregate stats for a scan.
- Cache
Stat - Stats for a single cache table.
- Database
- SQLite with WAL: multiple connections can serve read-heavy queries concurrently.
writeis the only handle used for schema migrations and code paths that need the writer mutex; never mix it into the read round-robin — doing so serialized everydb_query_*IPC with every other read/write on that mutex (spinners across tabs when one query held the slot).readis a pool of read-only file handles;Database::read_connround-robins only here (always at least one afterDatabase::open). - DawQuery
Result - DawRow
- DawStats
Result - Aggregate DAW stats from
Database::daw_stats: library totals (deduped bypath) whenscan_idis omitted or empty; otherwise that scan only. - Filter
Stats Result - Filtered aggregate stats — count + size + per-type breakdown reflecting the active search/filter. One round-trip: COUNT + SUM + GROUP BY in SQL.
- Midi
Query Result - PdfQuery
Result - PdfRow
- PdfStats
Result - Plugin
Query Result - Plugin
Row - Preset
Query Result - Preset
Row - Preset
Stats Result - Aggregate preset stats from
Database::preset_stats: library totals (deduped bypath, MIDI formats excluded) whenscan_idis omitted or empty; otherwise that scan only. - Scan
Info - Scan metadata (no samples).
- TopFolder
Row - One row for heatmap dashboard “top folders” (matches
heatmap-dashboard.jsfolder keys). - Unified
Scan RunRow - One row persisted for the last unified home-tree scan (SQLite
unified_scan_run.idis always 1).
Constants§
- AUDIO_
LIBRARY_ 🔒IDS - Canonical inventory: one row per
path(highestidwins — newest insert for that path). Materialized inaudio_library(migration v14) so library queries avoidGROUP BY pathon hot paths. - DAW_
LIBRARY_ 🔒IDS - Same semantics as
MAX(id) GROUP BY path, materialized indaw_library(migration v16). - FTS_
INVENTORY_ 🔒MATCH_ COUNT_ CAP - Exact FTS match counts above this force a bounded count and skip heavy aggregates (GROUP BY / size histogram over every hit) — common substrings like “loop” can match hundreds of thousands of library rows. Shared by audio, presets, MIDI, and PDF inventory queries.
- LATEST_
DAW_ 🔒SCAN_ ID_ SQL - Latest complete DAW scan that has at least one
daw_projectsrow. Empty scans remain in history but must not shadow prior results. Uses child-row presence (notproject_count) so streaming scans still resolve after finalize quirks. - MIDI_
LIBRARY_ 🔒IDS - PDF_
LIBRARY_ 🔒IDS - PLUGIN_
LIBRARY_ 🔒IDS - Materialized in
plugin_library(migration v17) — same semantics as other*_librarytables. - PLUGIN_
LIBRARY_ 🔒IDS_ QUALIFIED - PRESET_
LIBRARY_ 🔒IDS - Migration v15 — same semantics as
MAX(id) GROUP BY path, maintained on insert and deletes. - SCHEMA_
VERSION 🔒 - Current schema version — bump when adding migrations.
- SQLITE_
CACHE_ 🔒KIB_ PRIMARY - Primary SQLite handle (migrations,
write_conn): large page cache + mmap. - SQLITE_
MMAP_ 🔒BYTES_ PRIMARY - SQLITE_
PROGRESS_ 🔒HANDLER_ OPS - Check interval for the progress handler — every N virtual-machine opcodes. 1000 is ~50µs on modern hardware; low enough for responsive cancellation, high enough to avoid measurable overhead on normal queries.
- SQLITE_
QUERY_ 🔒TIMEOUT_ SECS - Per-query timeout for read-pool connections. The SQLite progress handler fires every
SQLITE_PROGRESS_HANDLER_OPSVM opcodes; if wall-clock time since the query started exceeds this limit the query is interrupted (SQLITE_INTERRUPT). - SQLITE_
READ_ 🔒POOL_ AUTO_ CAP - Cap on extra connections when [
sqliteReadPoolExtra] pref is"auto". Keep modest: explicit0–32extra still opens1 + extrareaders — RSS scales withread_pool_cache_kib/read_pool_mmap_bytes(budget-split, not fixed per handle). - SQLITE_
READ_ 🔒POOL_ EXTRA_ MAX - Max explicit extra connections from preferences (
0= one reader + writer; see README).
Statics§
- GLOBAL_
DB 🔒 - INIT_
GLOBAL_ 🔒MUTEX - Serializes
Database::open+ migrations on the on-disk file. Without this, many threads can pass theGLOBAL_DBempty check at once and runmigrate()in parallel against the same path, which triggers SQLitedatabase is locked(seen on multi-core CI runners). - REGEXP_
FUNC_ 🔒CACHE
Functions§
- backfill_
contentless_ 🔒fts - Backfill FTS5 contentless shadow tables from primary tables for rows missing from FTS.
Migration v9 created empty FTS tables; existing
audio_samples(etc.) rows were never indexed, soMATCHreturned no hits while the base tables still showed full library counts. - classify_
fts_ 🔒name_ path_ search - FTS-backed tabs (name + path): returns
(fts_match, like_pat, regex_pat)— at most one of the three isSome. MirrorsAudioQueryParams::search_regexsemantics. - classify_
plugins_ 🔒search - Plugins tab (name, manufacturer, path):
(regex_pat, like_pat)— whenregex_patisSome, useREGEXPon all three columns; otherwiselike_patis fuzzy interleaved or invalid-regex fallback (same binding shape). - dbstat_
bytes_ 🔒for_ scan_ group - Approximate on-disk bytes for btree objects (table + indexes) for
scan_table+item_table. Uses SQLitedbstatwhen available. ReturnsNoneifdbstatis not compiled in (caller splits DB file size by row count). - default_
limit 🔒 - default_
sort_ 🔒key - default_
true 🔒 - fts_
phrase 🔒 - Convert a user search string into an FTS5 phrase query for the trigram
tokenizer. Returns
Nonefor empty/whitespace input. The result is wrapped in double quotes (phrase match) with internal quotes doubled per FTS5 syntax. Trigram tokenizer indexes substrings, so"foo"matches any row containing “foo” as a substring in any indexed column. Returns an FTS5 phrase for trigram MATCH, or None if the search is empty or too short (trigram needs ≥3 chars). Callers must fall back to LIKE for 1–2 char searches. - global
- Get the global database reference.
- global_
initialized - Returns true after a successful
init_global(including concurrent test runners). - init_
global - Initialize the global database. Call once at startup.
- init_
sqlite_ 🔒connection_ pragmas - install_
regexp_ 🔒function - now_
epoch_ 🔒ms - Milliseconds since
std::time::UNIX_EPOCH(monotonic enough for timeout purposes). - open_
db_ 🔒connection_ with_ pragmas - open_
read_ 🔒connection - Open a read-pool connection with a progress-handler query timeout.
The returned
Arc<AtomicU64>must be stored alongside the connection and reset (viareset_query_deadline) each time the connection is acquired from the pool. - parse_
plugin_ 🔒status_ filter - Comma-separated
update,current,unknown— matcheskvr_cache+ frontendpluginStatusCategory. - parse_
sqlite_ 🔒read_ pool_ extra_ pref - Resolves [
performance.sqliteReadPoolExtra]:"auto"→sqlite_read_pool_auto, else0..=32. - read_
pool_ 🔒cache_ kib - ~512 MiB total page-cache budget split across all read-pool connections (e.g.
extra = 32→ 33 readers × ~15.5 MiB each). Caps each reader at 32 MiB when the pool is small. - read_
pool_ 🔒mmap_ bytes - ~512 MiB total mmap cap split across read-pool connections; each reader at most 64 MiB.
- regexp_
pattern_ 🔒cache - regexp_
user_ 🔒matches - SQLite
regexp(pattern, haystack)— matches JSnew RegExp(pattern, 'i')(case-insensitive). - reset_
query_ 🔒deadline - Reset the query-start timestamp so the progress handler measures from now.
- short_
like 🔒 - Build a LIKE pattern for short searches (1–2 chars) where FTS5 trigram can’t help. Returns None for empty input.
- sqlite_
read_ 🔒pool_ auto
Type Aliases§
- Analysis
Batch Row - One row for
Database::batch_update_analysis: path, BPM, musical key, LUFS.