From 15df57900b72db3faf09c798f2cb33a8ca2bc87f Mon Sep 17 00:00:00 2001 From: iequidoo Date: Mon, 4 Mar 2024 15:28:51 -0300 Subject: [PATCH] feat: Try SQLite FTS5 (#5052) --- src/context.rs | 16 ++++++++++++++-- src/sql/migrations.rs | 18 ++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/context.rs b/src/context.rs index 08e18c658..0286fc10a 100644 --- a/src/context.rs +++ b/src/context.rs @@ -1099,12 +1099,14 @@ impl Context { .query_map( "SELECT m.id AS id FROM msgs m + INNER JOIN msgs_search ms + ON m.id=ms.rowid LEFT JOIN contacts ct ON m.from_id=ct.id WHERE m.chat_id=? AND m.hidden=0 AND ct.blocked=0 - AND txt LIKE ? + AND ms.txt LIKE ? ORDER BY m.timestamp,m.id;", (chat_id, str_like_in_text), |row| row.get::<_, MsgId>("id"), @@ -1132,6 +1134,8 @@ impl Context { .query_map( "SELECT m.id AS id FROM msgs m + INNER JOIN msgs_search ms + ON m.id=ms.rowid LEFT JOIN contacts ct ON m.from_id=ct.id LEFT JOIN chats c @@ -1140,7 +1144,7 @@ impl Context { AND m.hidden=0 AND c.blocked!=1 AND ct.blocked=0 - AND m.txt LIKE ? + AND ms.txt LIKE ? ORDER BY m.id DESC LIMIT 1000", (str_like_in_text,), |row| row.get::<_, MsgId>("id"), @@ -1537,6 +1541,8 @@ mod tests { msg2.set_text("barbaz".to_string()); send_msg(&alice, chat.id, &mut msg2).await?; + alice.send_text(chat.id, "Δ-Chat").await; + // Global search with a part of text finds the message. let res = alice.search_msgs(None, "ob").await?; assert_eq!(res.len(), 1); @@ -1549,6 +1555,12 @@ mod tests { assert_eq!(res.first(), Some(&msg2.id)); assert_eq!(res.get(1), Some(&msg1.id)); + // Search is case-insensitive. + for chat_id in [None, Some(chat.id)] { + let res = alice.search_msgs(chat_id, "δ-chat").await?; + assert_eq!(res.len(), 1); + } + // Global search with longer text does not find any message. let res = alice.search_msgs(None, "foobarbaz").await?; assert!(res.is_empty()); diff --git a/src/sql/migrations.rs b/src/sql/migrations.rs index 8e9685957..abec47210 100644 --- a/src/sql/migrations.rs +++ b/src/sql/migrations.rs @@ -911,6 +911,24 @@ CREATE INDEX msgs_status_updates_index2 ON msgs_status_updates (uid); .await?; } + if dbversion < 111 { + sql.execute_migration( + "CREATE VIRTUAL TABLE msgs_search USING fts5(txt, content='msgs', content_rowid='id'); \ + CREATE TRIGGER msgs_search_insert AFTER INSERT ON msgs BEGIN \ + INSERT INTO msgs_search (rowid, txt) VALUES (new.id, new.txt); \ + END; \ + CREATE TRIGGER msgs_search_delete AFTER DELETE ON msgs BEGIN \ + INSERT INTO msgs_search (msgs_search, rowid, txt) VALUES ('delete', old.id, old.txt); \ + END; \ + CREATE TRIGGER msgs_search_update AFTER UPDATE ON msgs BEGIN \ + INSERT INTO msgs_search (msgs_search, rowid, txt) VALUES ('delete', old.id, old.txt); \ + INSERT INTO msgs_search (rowid, txt) VALUES (new.id, new.txt); \ + END; \ + INSERT INTO msgs_search (msgs_search) VALUES ('rebuild');", + 111, + ).await?; + } + let new_version = sql .get_raw_config_int(VERSION_CFG) .await?