[backend/core] Fix negated search parameters when match:words is used

This commit is contained in:
Laura Hausmann 2025-01-10 07:55:40 +01:00
parent 77fef1e63e
commit 1d418b1c0c
No known key found for this signature in database
GPG key ID: D044E84C5BE01605

View file

@ -271,37 +271,21 @@ public static class QueryableFtsExtensions
Justification = "Projectable chain must have consistent visibility")] Justification = "Projectable chain must have consistent visibility")]
internal static bool FtsQueryPreEscaped( internal static bool FtsQueryPreEscaped(
this Note note, string query, bool negated, CaseFilterType caseSensitivity, MatchFilterType matchType this Note note, string query, bool negated, CaseFilterType caseSensitivity, MatchFilterType matchType
) => matchType.Equals(MatchFilterType.Substring) ) => negated
? caseSensitivity.Equals(CaseFilterType.Sensitive) ? matchType.Equals(MatchFilterType.Substring)
? negated ? FtsQueryMatchSubstringPreEscaped(note.Text, query, negated, caseSensitivity)
? !EF.Functions.Like(note.Text!, "%" + query + "%", @"\") && FtsQueryMatchSubstringPreEscaped(note.Cw, query, negated, caseSensitivity)
&& !EF.Functions.Like(note.Cw!, "%" + query + "%", @"\") && FtsQueryMatchSubstringPreEscaped(note.CombinedAltText, query, negated, caseSensitivity)
&& !EF.Functions.Like(note.CombinedAltText!, "%" + query + "%", @"\") : FtsQueryMatchWordPreEscaped(note.Text, query, negated, caseSensitivity)
: EF.Functions.Like(note.Text!, "%" + query + "%", @"\") && FtsQueryMatchWordPreEscaped(note.Cw, query, negated, caseSensitivity)
|| EF.Functions.Like(note.Cw!, "%" + query + "%", @"\") && FtsQueryMatchWordPreEscaped(note.CombinedAltText, query, negated, caseSensitivity)
|| EF.Functions.Like(note.CombinedAltText!, "%" + query + "%", @"\") : matchType.Equals(MatchFilterType.Substring)
: negated ? FtsQueryMatchSubstringPreEscaped(note.Text, query, negated, caseSensitivity)
? !EF.Functions.ILike(note.Text!, "%" + query + "%", @"\") || FtsQueryMatchSubstringPreEscaped(note.Cw, query, negated, caseSensitivity)
&& !EF.Functions.ILike(note.Cw!, "%" + query + "%", @"\") || FtsQueryMatchSubstringPreEscaped(note.CombinedAltText, query, negated, caseSensitivity)
&& !EF.Functions.ILike(note.CombinedAltText!, "%" + query + "%", @"\") : FtsQueryMatchWordPreEscaped(note.Text, query, negated, caseSensitivity)
: EF.Functions.ILike(note.Text!, "%" + query + "%", @"\") || FtsQueryMatchWordPreEscaped(note.Cw, query, negated, caseSensitivity)
|| EF.Functions.ILike(note.Cw!, "%" + query + "%", @"\") || FtsQueryMatchWordPreEscaped(note.CombinedAltText, query, negated, caseSensitivity);
|| EF.Functions.ILike(note.CombinedAltText!, "%" + query + "%", @"\")
: caseSensitivity.Equals(CaseFilterType.Sensitive)
? negated
? !Regex.IsMatch(note.Text!, "\\y" + query + "\\y")
&& !Regex.IsMatch(note.Cw!, "\\y" + query + "\\y")
&& !Regex.IsMatch(note.CombinedAltText!, "\\y" + query + "\\y")
: Regex.IsMatch(note.Text!, "\\y" + query + "\\y")
|| Regex.IsMatch(note.Cw!, "\\y" + query + "\\y")
|| Regex.IsMatch(note.CombinedAltText!, "\\y" + query + "\\y")
: negated
? !Regex.IsMatch(note.Text!, "\\y" + query + "\\y", RegexOptions.IgnoreCase)
&& !Regex.IsMatch(note.Cw!, "\\y" + query + "\\y", RegexOptions.IgnoreCase)
&& !Regex.IsMatch(note.CombinedAltText!, "\\y" + query + "\\y", RegexOptions.IgnoreCase)
: Regex.IsMatch(note.Text!, "\\y" + query + "\\y", RegexOptions.IgnoreCase)
|| Regex.IsMatch(note.Cw!, "\\y" + query + "\\y", RegexOptions.IgnoreCase)
|| Regex.IsMatch(note.CombinedAltText!, "\\y" + query + "\\y", RegexOptions.IgnoreCase);
[Projectable] [Projectable]
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global", [SuppressMessage("ReSharper", "MemberCanBePrivate.Global",
@ -337,4 +321,30 @@ public static class QueryableFtsExtensions
this Note note, IEnumerable<string> words, CaseFilterType caseSensitivity, MatchFilterType matchType this Note note, IEnumerable<string> words, CaseFilterType caseSensitivity, MatchFilterType matchType
) => words.Select(p => PreEscapeFtsQuery(p, matchType)) ) => words.Select(p => PreEscapeFtsQuery(p, matchType))
.Any(p => note.FtsQueryPreEscaped(p, false, caseSensitivity, matchType)); .Any(p => note.FtsQueryPreEscaped(p, false, caseSensitivity, matchType));
[Projectable]
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global",
Justification = "Projectable chain must have consistent visibility")]
internal static bool FtsQueryMatchSubstringPreEscaped(
string? match, string query, bool negated, CaseFilterType caseSensitivity
) => caseSensitivity.Equals(CaseFilterType.Sensitive)
? negated
? !EF.Functions.Like(match!, "%" + query + "%", @"\")
: EF.Functions.Like(match!, "%" + query + "%", @"\")
: negated
? !EF.Functions.ILike(match!, "%" + query + "%", @"\")
: EF.Functions.ILike(match!, "%" + query + "%", @"\");
[Projectable]
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global",
Justification = "Projectable chain must have consistent visibility")]
internal static bool FtsQueryMatchWordPreEscaped(
string? match, string query, bool negated, CaseFilterType caseSensitivity
) => caseSensitivity.Equals(CaseFilterType.Sensitive)
? negated
? match == null || !Regex.IsMatch(match, "\\y" + query + "\\y")
: match != null && Regex.IsMatch(match, "\\y" + query + "\\y")
: negated
? match == null || !Regex.IsMatch(match, "\\y" + query + "\\y", RegexOptions.IgnoreCase)
: match != null && Regex.IsMatch(match, "\\y" + query + "\\y", RegexOptions.IgnoreCase);
} }