Search treats % and _ as themselves (#296)

The changelog lines for #292, #293 and #295 ride along in this commit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-19 18:12:58 +00:00
parent a21472730e
commit 44afc08b9d
2 changed files with 13 additions and 1 deletions

View File

@@ -1222,8 +1222,13 @@ fn entries_from(
}
let search = match search.map(|q| q.trim().to_lowercase()).filter(|q| !q.is_empty()) {
Some(q) => {
// % and _ as typed, not as wildcards: "100%" matched anything starting 100 (#296).
let q = q.replace('\\', "\\\\").replace('%', "\\%").replace('_', "\\_");
let like = a.p(format!("%{q}%"));
format!("(lower(coalesce(e.title, '')) LIKE {like} OR lower(coalesce(e.description, '')) LIKE {like})")
format!(
"(lower(coalesce(e.title, '')) LIKE {like} ESCAPE '\\' \
OR lower(coalesce(e.description, '')) LIKE {like} ESCAPE '\\')"
)
}
None => "true".into(),
};
@@ -3614,6 +3619,9 @@ mod tests {
assert_eq!(db.count_in(7, Some("f"), Filter::Downloaded, None).await.unwrap(), 1);
assert_eq!(db.count_in(7, Some("f"), Filter::Flagged, None).await.unwrap(), 1);
assert_eq!(db.count_in(7, Some("f"), Filter::All, Some("dive")).await.unwrap(), 2);
for wild in ["%", "_", "\\"] {
assert_eq!(db.count_in(7, Some("f"), Filter::All, Some(wild)).await.unwrap(), 0, "{wild} is only itself");
}
assert_eq!(
db.count_in(7, Some("f"), Filter::All, Some("NOTES two")).await.unwrap(),
1,