feat: Add full-text search with FTS5
Implements FTS5-based full-text search for notes as specified in ADR-034. Changes: - Created migration 005_add_fts5_search.sql with FTS5 virtual table - Created starpunk/search.py module with search functions - Integrated FTS index updates into create_note() and update_note() - DELETE trigger automatically removes notes from FTS index - INSERT/UPDATE handled by application code (files not in DB) Features: - Porter stemming for better English search - Unicode normalization for international characters - Relevance ranking with snippets - Graceful degradation if FTS5 unavailable - Helper function to rebuild index if needed Note: Initial FTS index population needs to be added to app startup. Part of v1.1.0 (Phase 3). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -286,6 +286,17 @@ def create_note(
|
||||
# Create Note object
|
||||
note = Note.from_row(row, data_dir)
|
||||
|
||||
# 9. UPDATE FTS INDEX (if available)
|
||||
try:
|
||||
from starpunk.search import update_fts_index, has_fts_table
|
||||
db_path = Path(current_app.config["DATABASE_PATH"])
|
||||
if has_fts_table(db_path):
|
||||
update_fts_index(db, note_id, slug, content)
|
||||
db.commit()
|
||||
except Exception as e:
|
||||
# FTS update failure should not prevent note creation
|
||||
current_app.logger.warning(f"Failed to update FTS index for note {slug}: {e}")
|
||||
|
||||
return note
|
||||
|
||||
|
||||
@@ -676,7 +687,19 @@ def update_note(
|
||||
f"Failed to update note: {existing_note.slug}",
|
||||
)
|
||||
|
||||
# 6. RETURN UPDATED NOTE
|
||||
# 6. UPDATE FTS INDEX (if available and content changed)
|
||||
if content is not None:
|
||||
try:
|
||||
from starpunk.search import update_fts_index, has_fts_table
|
||||
db_path = Path(current_app.config["DATABASE_PATH"])
|
||||
if has_fts_table(db_path):
|
||||
update_fts_index(db, existing_note.id, existing_note.slug, content)
|
||||
db.commit()
|
||||
except Exception as e:
|
||||
# FTS update failure should not prevent note update
|
||||
current_app.logger.warning(f"Failed to update FTS index for note {existing_note.slug}: {e}")
|
||||
|
||||
# 7. RETURN UPDATED NOTE
|
||||
updated_note = get_note(slug=existing_note.slug, load_content=True)
|
||||
|
||||
return updated_note
|
||||
|
||||
Reference in New Issue
Block a user