From 9d424a8f0b854dd79f10b8809ba62c8d90036f90 Mon Sep 17 00:00:00 2001 From: Ian Macdonald Date: Tue, 20 Jun 2023 18:36:32 +0200 Subject: [PATCH] Enable FTS5 full-text searches. Session uses SQLite FTS5 tables that allow full-text searching, but also includes code that renders this type of advanced search inoperable. This patch restores the functionality, allowing the use of prefix queries (e.g. 'lin*'), Boolean operators (AND, OR and NOT), initial token queries (e.g. '^Linux') and NEAR groups. Operators must appear in upper case, so 'AND' is a Boolean operator, but 'and' is a search for the literal word 'and'. Note that whitespace implies a Boolean AND, so 'linux AND applications' is syntactically equivalent to 'linux applications', either of which searches for any message containing both words in any order, and not necessarily appearing contiguously. To search for the contiguous expression 'linux applications', surround it with double quotes: '"linux applications"'. Parentheses may be used to change operator precedence and build complex expressions. The BNF for the FTS query syntax is this: ``` := string [*] := + := NEAR ( ... [, N] ) := [ [-] :] [^] := [ [-] :] := [ [-] :] ( ) := AND := OR := NOT := colname := { colname1 colname2 ... } ``` For more information, please see: https://www.sqlite.org/fts5.html#full_text_query_syntax --- ts/util/cleanSearchTerm.ts | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/ts/util/cleanSearchTerm.ts b/ts/util/cleanSearchTerm.ts index 32e7f5dd3a1..3f24fd9f86a 100644 --- a/ts/util/cleanSearchTerm.ts +++ b/ts/util/cleanSearchTerm.ts @@ -1,22 +1,4 @@ export function cleanSearchTerm(searchTerm: string) { - const lowercase = searchTerm.toLowerCase(); - const withoutSpecialCharacters = lowercase.replace(/([!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~])/g, ' '); - const whiteSpaceNormalized = withoutSpecialCharacters.replace(/\s+/g, ' '); - const byToken = whiteSpaceNormalized.split(' '); - // be aware that a user typing Note To Self will have an issue when the `not` part of it is typed as the not word is reserved - const withoutSpecialTokens = byToken.filter( - token => - token && - token !== 'and' && - token !== 'or' && - token !== 'not' && - token !== ')' && - token !== '(' && - token !== '+' && - token !== ',' && - token !== 'near' - ); - const withWildcards = withoutSpecialTokens.map(token => `${token}*`); - - return withWildcards.join(' ').trim(); + const whiteSpaceNormalized = searchTerm.replace(/\s+/g, ' '); + return whiteSpaceNormalized.trim(); }