fix(store): escape FTS5 special characters in search_text()

- FTS5 crashes on dots (IP addresses) and hyphens (dates)
- Add regex to strip non-alphanumeric chars before FTS5 MATCH
- Fixes: fts5 syntax error near '.' and no such column: 05

Files changed: src/store.py
This commit is contained in:
2026-05-27 17:54:51 +02:00
parent 021fd0e328
commit 6b0cf5889f

View File

@@ -6,6 +6,7 @@ Keine externen Abhängigkeiten außer sqlite3 (stdlib).
import json import json
import sqlite3 import sqlite3
import os import os
import re
from pathlib import Path from pathlib import Path
from typing import List, Optional, Dict, Any from typing import List, Optional, Dict, Any
from uuid import UUID from uuid import UUID
@@ -158,7 +159,12 @@ class EngramStore:
def search_text(self, query: str, limit: int = 10) -> List[Engram]: def search_text(self, query: str, limit: int = 10) -> List[Engram]:
"""Full-Text-Suche über Engramm-Inhalt via SQLite FTS5 (OR-Verknüpfung).""" """Full-Text-Suche über Engramm-Inhalt via SQLite FTS5 (OR-Verknüpfung)."""
# FTS5-Syntax: Wörter mit OR verbinden für bessere Ergebnisse # FTS5-Syntax: Wörter mit OR verbinden für bessere Ergebnisse
words = [w.strip() for w in query.replace("'", "''").split() if w.strip()] words = []
for word in query.split():
# Nur alphanumerische Zeichen als FTS5-Tokens akzeptieren
clean_word = re.sub(r'[^a-zA-Z0-9]+', '', word)
if clean_word:
words.append(clean_word)
safe_query = " OR ".join(words) if len(words) > 1 else (words[0] if words else "*") safe_query = " OR ".join(words) if len(words) > 1 else (words[0] if words else "*")
sql = """ sql = """
SELECT e.* FROM engrams e SELECT e.* FROM engrams e