diff --git a/app/src/main/java/eu/faircode/email/BoundaryCallbackMessages.java b/app/src/main/java/eu/faircode/email/BoundaryCallbackMessages.java index b3399d2114..f5fa2b2358 100644 --- a/app/src/main/java/eu/faircode/email/BoundaryCallbackMessages.java +++ b/app/src/main/java/eu/faircode/email/BoundaryCallbackMessages.java @@ -194,8 +194,6 @@ public class BoundaryCallbackMessages extends PagedList.BoundaryCallback plus = new ArrayList<>(); List minus = new ArrayList<>(); List opt = new ArrayList<>(); - StringBuilder sb = new StringBuilder(); + StringBuilder all = new StringBuilder(); for (String w : search.trim().split("\\s+")) { - if (sb.length() > 0) - sb.append(' '); + if (all.length() > 0) + all.append(' '); if (w.length() > 1 && w.startsWith("+")) { plus.add(w.substring(1)); - sb.append(w.substring(1)); + all.append(w.substring(1)); } else if (w.length() > 1 && w.startsWith("-")) { minus.add(w.substring(1)); - sb.append(w.substring(1)); + all.append(w.substring(1)); } else if (w.length() > 1 && w.startsWith("?")) { opt.add(w.substring(1)); - sb.append(w.substring(1)); + all.append(w.substring(1)); } else { word.add(w); - sb.append(w); + all.append(w); } } - if (plus.size() + minus.size() + opt.size() > 0) { - search = sb.toString(); - Log.i("SEARCH word=" + TextUtils.join(",", word)); - Log.i("SEARCH plus=" + TextUtils.join(",", plus)); - Log.i("SEARCH minus=" + TextUtils.join(",", minus)); - Log.i("SEARCH opt=" + TextUtils.join(",", opt)); - Log.i("SEARCH full=" + search); - } + if (plus.size() + minus.size() + opt.size() > 0) + search = all.toString(); // Yahoo! does not support keyword search, but uses the flags $Forwarded $Junk $NotJunk boolean hasKeywords = false; diff --git a/app/src/main/java/eu/faircode/email/FragmentDialogSearch.java b/app/src/main/java/eu/faircode/email/FragmentDialogSearch.java index 8608e71892..bb16890e02 100644 --- a/app/src/main/java/eu/faircode/email/FragmentDialogSearch.java +++ b/app/src/main/java/eu/faircode/email/FragmentDialogSearch.java @@ -334,10 +334,6 @@ public class FragmentDialogSearch extends FragmentDialogBase { Log.unexpectedError(getParentFragmentManager(), ex); } }.execute(getContext(), getViewLifecycleOwner(), getArguments(), "search:raw"); - else if (criteria.isExpression() && folder > 0) - FragmentMessages.search( - getContext(), getViewLifecycleOwner(), getParentFragmentManager(), - account, folder, true, criteria); else FragmentMessages.search( getContext(), getViewLifecycleOwner(), getParentFragmentManager(), diff --git a/app/src/main/java/eu/faircode/email/FtsDbHelper.java b/app/src/main/java/eu/faircode/email/FtsDbHelper.java index d82864c442..f722c1c789 100644 --- a/app/src/main/java/eu/faircode/email/FtsDbHelper.java +++ b/app/src/main/java/eu/faircode/email/FtsDbHelper.java @@ -111,29 +111,61 @@ public class FtsDbHelper extends SQLiteOpenHelper { SQLiteDatabase db, Long account, Long folder, BoundaryCallbackMessages.SearchCriteria criteria) { - StringBuilder sb = new StringBuilder(); - for (String or : criteria.query.split(",")) { - if (sb.length() > 0) - sb.append(" OR "); - boolean first = true; - sb.append("("); - for (String and : or.trim().split("\\s+")) { - if (first) - first = false; - else - sb.append(" AND "); + List word = new ArrayList<>(); + List plus = new ArrayList<>(); + List minus = new ArrayList<>(); + List opt = new ArrayList<>(); + StringBuilder all = new StringBuilder(); + for (String w : criteria.query.trim().split("\\s+")) { + if (all.length() > 0) + all.append(' '); - // Escape quotes - String term = and.replaceAll("\"", "\"\""); - - // Quote search term - sb.append("\"").append(term).append("\""); + if (w.length() > 1 && w.startsWith("+")) { + plus.add(w.substring(1)); + all.append(w.substring(1)); + } else if (w.length() > 1 && w.startsWith("-")) { + minus.add(w.substring(1)); + all.append(w.substring(1)); + } else if (w.length() > 1 && w.startsWith("?")) { + opt.add(w.substring(1)); + all.append(w.substring(1)); + } else { + word.add(w); + all.append(w); } - sb.append(")"); } - String search = sb.toString(); + StringBuilder sb = new StringBuilder(); + if (plus.size() + minus.size() + opt.size() > 0) { + if (word.size() > 0) + sb.append(escape(TextUtils.join(" ", word))); + + for (String p : plus) { + if (sb.length() > 0) + sb.append(" AND "); + sb.append(escape(p)); + } + + for (String m : minus) { + if (sb.length() > 0) + sb.append(" NOT "); + sb.append(escape(m)); + } + + if (sb.length() > 0) { + sb.insert(0, '('); + sb.append(')'); + } + + for (String o : opt) { + if (sb.length() > 0) + sb.append(" OR "); + sb.append(escape(o)); + } + } + + String search = (sb.length() > 0 ? sb.toString() : escape(criteria.query)); String select = ""; if (account != null) @@ -159,6 +191,10 @@ public class FtsDbHelper extends SQLiteOpenHelper { return result; } + private static String escape(String word) { + return "\"" + word.replaceAll("\"", "\"\"") + "\""; + } + static Cursor getIds(SQLiteDatabase db) { return db.query( "message", new String[]{"rowid"},