-- Migration 005: Add full-text search using FTS5 -- -- Creates FTS5 virtual table for full-text search of notes. -- Since note content is stored in external files (not in the database), -- the FTS index must be maintained by application code, not SQL triggers. -- -- Requirements: -- - SQLite compiled with FTS5 support -- - Application code handles index synchronization -- -- Features: -- - Full-text search on note content -- - Porter stemming for better English search results -- - Unicode normalization for international characters -- - rowid matches notes.id for efficient lookups -- Create FTS5 virtual table for note search -- Using porter stemmer for better English search results -- Unicode61 tokenizer for international character support -- Note: slug is UNINDEXED (not searchable, just for result display) CREATE VIRTUAL TABLE IF NOT EXISTS notes_fts USING fts5( slug UNINDEXED, -- Slug for result linking (not searchable) title, -- First line of note (searchable, high weight) content, -- Full markdown content (searchable) tokenize='porter unicode61' ); -- Create delete trigger to remove from FTS when note is deleted -- This is the only trigger we can use since deletion doesn't require file access CREATE TRIGGER IF NOT EXISTS notes_fts_delete AFTER DELETE ON notes BEGIN DELETE FROM notes_fts WHERE rowid = OLD.id; END; -- Note: INSERT and UPDATE triggers cannot be used because they would need -- to read content from external files, which SQLite triggers cannot do. -- The application code in starpunk/notes.py handles FTS updates for -- create and update operations. -- Initial index population: -- After this migration runs, the FTS index must be populated with existing notes. -- This happens automatically on application startup via starpunk/search.py:rebuild_fts_index() -- or can be triggered manually if needed.