Loading app/core/src/main/java/com/fsck/k9/mailstore/LocalStore.java +3 −3 Original line number Diff line number Diff line Loading @@ -355,7 +355,7 @@ public class LocalStore { public List<LocalMessage> searchForMessages(LocalSearch search) throws MessagingException { StringBuilder query = new StringBuilder(); List<String> queryArgs = new ArrayList<>(); SqlQueryBuilder.buildWhereClause(account, search.getConditions(), query, queryArgs); SqlQueryBuilder.buildWhereClause(search.getConditions(), query, queryArgs); // Avoid "ambiguous column name" error by prefixing "id" with the message table name String where = SqlQueryBuilder.addPrefixToSelection(new String[] { "id" }, Loading Loading @@ -1008,7 +1008,7 @@ public class LocalStore { public int getUnreadMessageCount(LocalSearch search) throws MessagingException { StringBuilder whereBuilder = new StringBuilder(); List<String> queryArgs = new ArrayList<>(); SqlQueryBuilder.buildWhereClause(account, search.getConditions(), whereBuilder, queryArgs); SqlQueryBuilder.buildWhereClause(search.getConditions(), whereBuilder, queryArgs); String where = whereBuilder.toString(); final String[] selectionArgs = queryArgs.toArray(new String[queryArgs.size()]); Loading Loading @@ -1039,7 +1039,7 @@ public class LocalStore { private int getStarredMessageCount(LocalSearch search) throws MessagingException { StringBuilder whereBuilder = new StringBuilder(); List<String> queryArgs = new ArrayList<>(); SqlQueryBuilder.buildWhereClause(account, search.getConditions(), whereBuilder, queryArgs); SqlQueryBuilder.buildWhereClause(search.getConditions(), whereBuilder, queryArgs); String where = whereBuilder.toString(); final String[] selectionArgs = queryArgs.toArray(new String[queryArgs.size()]); Loading app/core/src/main/java/com/fsck/k9/search/AccountSearchConditions.kt +0 −24 Original line number Diff line number Diff line Loading @@ -79,30 +79,6 @@ class AccountSearchConditions { } } /** * Modify the supplied [LocalSearch] instance to exclude "unwanted" folders. * * Currently the following folders are excluded: * * * Trash * * Spam * * Outbox * * The Inbox will always be included even if one of the special folders is configured to point * to the Inbox. * * @param search * The `LocalSearch` instance to modify. */ fun excludeUnwantedFolders(account: Account, search: LocalSearch) { excludeSpecialFolder(search, account.trashFolderId) excludeSpecialFolder(search, account.spamFolderId) excludeSpecialFolder(search, account.outboxFolderId) account.inboxFolderId?.let { inboxFolderId -> search.or(SearchCondition(SearchField.FOLDER, Attribute.EQUALS, inboxFolderId.toString())) } } private fun excludeSpecialFolder(search: LocalSearch, folderId: Long?) { if (folderId != null) { search.and(SearchField.FOLDER, folderId.toString(), Attribute.NOT_EQUALS) Loading app/core/src/main/java/com/fsck/k9/search/SearchSpecification.java +1 −2 Original line number Diff line number Diff line Loading @@ -71,8 +71,7 @@ public interface SearchSpecification extends Parcelable { NEW_MESSAGE, READ, FLAGGED, DISPLAY_CLASS, SEARCHABLE DISPLAY_CLASS } Loading app/core/src/main/java/com/fsck/k9/search/SqlQueryBuilder.java +17 −58 Original line number Diff line number Diff line Loading @@ -2,85 +2,45 @@ package com.fsck.k9.search; import java.util.List; import com.fsck.k9.DI; import timber.log.Timber; import com.fsck.k9.Account; import com.fsck.k9.search.SearchSpecification.Attribute; import com.fsck.k9.search.SearchSpecification.SearchCondition; import com.fsck.k9.search.SearchSpecification.SearchField; public class SqlQueryBuilder { public static void buildWhereClause(Account account, ConditionsTreeNode node, StringBuilder query, List<String> selectionArgs) { buildWhereClauseInternal(account, node, query, selectionArgs); public static void buildWhereClause(ConditionsTreeNode node, StringBuilder query, List<String> selectionArgs) { buildWhereClauseInternal(node, query, selectionArgs); } private static void buildWhereClauseInternal(Account account, ConditionsTreeNode node, StringBuilder query, List<String> selectionArgs) { private static void buildWhereClauseInternal(ConditionsTreeNode node, StringBuilder query, List<String> selectionArgs) { if (node == null) { query.append("1"); return; } if (node.mLeft == null && node.mRight == null) { AccountSearchConditions accountSearchConditions = DI.get(AccountSearchConditions.class); SearchCondition condition = node.mCondition; switch (condition.field) { case SEARCHABLE: { switch (account.getSearchableFolders()) { case ALL: { // Create temporary LocalSearch object so we can use... LocalSearch tempSearch = new LocalSearch(); // ...the helper methods in Account to create the necessary conditions // to exclude "unwanted" folders. accountSearchConditions.excludeUnwantedFolders(account, tempSearch); buildWhereClauseInternal(account, tempSearch.getConditions(), query, selectionArgs); break; } case DISPLAYABLE: { // Create temporary LocalSearch object so we can use... LocalSearch tempSearch = new LocalSearch(); // ...the helper methods in Account to create the necessary conditions // to limit the selection to displayable, non-special folders. accountSearchConditions.excludeSpecialFolders(account, tempSearch); accountSearchConditions.limitToDisplayableFolders(account, tempSearch); buildWhereClauseInternal(account, tempSearch.getConditions(), query, selectionArgs); break; } case NONE: { // Dummy condition, never select query.append("0"); break; } } break; } case MESSAGE_CONTENTS: { if (condition.field == SearchField.MESSAGE_CONTENTS) { String fulltextQueryString = condition.value; if (condition.attribute != Attribute.CONTAINS) { Timber.e("message contents can only be matched!"); } query.append("messages.id IN (SELECT docid FROM messages_fulltext WHERE fulltext MATCH ?)"); selectionArgs.add(fulltextQueryString); break; } default: { } else { appendCondition(condition, query, selectionArgs); } } } else { query.append("("); buildWhereClauseInternal(account, node.mLeft, query, selectionArgs); buildWhereClauseInternal(node.mLeft, query, selectionArgs); query.append(") "); query.append(node.mValue.name()); query.append(" ("); buildWhereClauseInternal(account, node.mRight, query, selectionArgs); buildWhereClauseInternal(node.mRight, query, selectionArgs); query.append(")"); } } Loading Loading @@ -170,9 +130,8 @@ public class SqlQueryBuilder { columnName = "threads.root"; break; } case MESSAGE_CONTENTS: case SEARCHABLE: { // Special cases handled in buildWhereClauseInternal() case MESSAGE_CONTENTS: { // Special case handled in buildWhereClauseInternal() break; } } Loading app/ui/legacy/src/main/java/com/fsck/k9/ui/messagelist/MessageListLoader.kt +1 −1 Original line number Diff line number Diff line Loading @@ -77,7 +77,7 @@ class MessageListLoader( queryArgs.add(activeMessage.folderId.toString()) } SqlQueryBuilder.buildWhereClause(account, config.search.conditions, query, queryArgs) SqlQueryBuilder.buildWhereClause(config.search.conditions, query, queryArgs) if (selectActive) { query.append(')') Loading Loading
app/core/src/main/java/com/fsck/k9/mailstore/LocalStore.java +3 −3 Original line number Diff line number Diff line Loading @@ -355,7 +355,7 @@ public class LocalStore { public List<LocalMessage> searchForMessages(LocalSearch search) throws MessagingException { StringBuilder query = new StringBuilder(); List<String> queryArgs = new ArrayList<>(); SqlQueryBuilder.buildWhereClause(account, search.getConditions(), query, queryArgs); SqlQueryBuilder.buildWhereClause(search.getConditions(), query, queryArgs); // Avoid "ambiguous column name" error by prefixing "id" with the message table name String where = SqlQueryBuilder.addPrefixToSelection(new String[] { "id" }, Loading Loading @@ -1008,7 +1008,7 @@ public class LocalStore { public int getUnreadMessageCount(LocalSearch search) throws MessagingException { StringBuilder whereBuilder = new StringBuilder(); List<String> queryArgs = new ArrayList<>(); SqlQueryBuilder.buildWhereClause(account, search.getConditions(), whereBuilder, queryArgs); SqlQueryBuilder.buildWhereClause(search.getConditions(), whereBuilder, queryArgs); String where = whereBuilder.toString(); final String[] selectionArgs = queryArgs.toArray(new String[queryArgs.size()]); Loading Loading @@ -1039,7 +1039,7 @@ public class LocalStore { private int getStarredMessageCount(LocalSearch search) throws MessagingException { StringBuilder whereBuilder = new StringBuilder(); List<String> queryArgs = new ArrayList<>(); SqlQueryBuilder.buildWhereClause(account, search.getConditions(), whereBuilder, queryArgs); SqlQueryBuilder.buildWhereClause(search.getConditions(), whereBuilder, queryArgs); String where = whereBuilder.toString(); final String[] selectionArgs = queryArgs.toArray(new String[queryArgs.size()]); Loading
app/core/src/main/java/com/fsck/k9/search/AccountSearchConditions.kt +0 −24 Original line number Diff line number Diff line Loading @@ -79,30 +79,6 @@ class AccountSearchConditions { } } /** * Modify the supplied [LocalSearch] instance to exclude "unwanted" folders. * * Currently the following folders are excluded: * * * Trash * * Spam * * Outbox * * The Inbox will always be included even if one of the special folders is configured to point * to the Inbox. * * @param search * The `LocalSearch` instance to modify. */ fun excludeUnwantedFolders(account: Account, search: LocalSearch) { excludeSpecialFolder(search, account.trashFolderId) excludeSpecialFolder(search, account.spamFolderId) excludeSpecialFolder(search, account.outboxFolderId) account.inboxFolderId?.let { inboxFolderId -> search.or(SearchCondition(SearchField.FOLDER, Attribute.EQUALS, inboxFolderId.toString())) } } private fun excludeSpecialFolder(search: LocalSearch, folderId: Long?) { if (folderId != null) { search.and(SearchField.FOLDER, folderId.toString(), Attribute.NOT_EQUALS) Loading
app/core/src/main/java/com/fsck/k9/search/SearchSpecification.java +1 −2 Original line number Diff line number Diff line Loading @@ -71,8 +71,7 @@ public interface SearchSpecification extends Parcelable { NEW_MESSAGE, READ, FLAGGED, DISPLAY_CLASS, SEARCHABLE DISPLAY_CLASS } Loading
app/core/src/main/java/com/fsck/k9/search/SqlQueryBuilder.java +17 −58 Original line number Diff line number Diff line Loading @@ -2,85 +2,45 @@ package com.fsck.k9.search; import java.util.List; import com.fsck.k9.DI; import timber.log.Timber; import com.fsck.k9.Account; import com.fsck.k9.search.SearchSpecification.Attribute; import com.fsck.k9.search.SearchSpecification.SearchCondition; import com.fsck.k9.search.SearchSpecification.SearchField; public class SqlQueryBuilder { public static void buildWhereClause(Account account, ConditionsTreeNode node, StringBuilder query, List<String> selectionArgs) { buildWhereClauseInternal(account, node, query, selectionArgs); public static void buildWhereClause(ConditionsTreeNode node, StringBuilder query, List<String> selectionArgs) { buildWhereClauseInternal(node, query, selectionArgs); } private static void buildWhereClauseInternal(Account account, ConditionsTreeNode node, StringBuilder query, List<String> selectionArgs) { private static void buildWhereClauseInternal(ConditionsTreeNode node, StringBuilder query, List<String> selectionArgs) { if (node == null) { query.append("1"); return; } if (node.mLeft == null && node.mRight == null) { AccountSearchConditions accountSearchConditions = DI.get(AccountSearchConditions.class); SearchCondition condition = node.mCondition; switch (condition.field) { case SEARCHABLE: { switch (account.getSearchableFolders()) { case ALL: { // Create temporary LocalSearch object so we can use... LocalSearch tempSearch = new LocalSearch(); // ...the helper methods in Account to create the necessary conditions // to exclude "unwanted" folders. accountSearchConditions.excludeUnwantedFolders(account, tempSearch); buildWhereClauseInternal(account, tempSearch.getConditions(), query, selectionArgs); break; } case DISPLAYABLE: { // Create temporary LocalSearch object so we can use... LocalSearch tempSearch = new LocalSearch(); // ...the helper methods in Account to create the necessary conditions // to limit the selection to displayable, non-special folders. accountSearchConditions.excludeSpecialFolders(account, tempSearch); accountSearchConditions.limitToDisplayableFolders(account, tempSearch); buildWhereClauseInternal(account, tempSearch.getConditions(), query, selectionArgs); break; } case NONE: { // Dummy condition, never select query.append("0"); break; } } break; } case MESSAGE_CONTENTS: { if (condition.field == SearchField.MESSAGE_CONTENTS) { String fulltextQueryString = condition.value; if (condition.attribute != Attribute.CONTAINS) { Timber.e("message contents can only be matched!"); } query.append("messages.id IN (SELECT docid FROM messages_fulltext WHERE fulltext MATCH ?)"); selectionArgs.add(fulltextQueryString); break; } default: { } else { appendCondition(condition, query, selectionArgs); } } } else { query.append("("); buildWhereClauseInternal(account, node.mLeft, query, selectionArgs); buildWhereClauseInternal(node.mLeft, query, selectionArgs); query.append(") "); query.append(node.mValue.name()); query.append(" ("); buildWhereClauseInternal(account, node.mRight, query, selectionArgs); buildWhereClauseInternal(node.mRight, query, selectionArgs); query.append(")"); } } Loading Loading @@ -170,9 +130,8 @@ public class SqlQueryBuilder { columnName = "threads.root"; break; } case MESSAGE_CONTENTS: case SEARCHABLE: { // Special cases handled in buildWhereClauseInternal() case MESSAGE_CONTENTS: { // Special case handled in buildWhereClauseInternal() break; } } Loading
app/ui/legacy/src/main/java/com/fsck/k9/ui/messagelist/MessageListLoader.kt +1 −1 Original line number Diff line number Diff line Loading @@ -77,7 +77,7 @@ class MessageListLoader( queryArgs.add(activeMessage.folderId.toString()) } SqlQueryBuilder.buildWhereClause(account, config.search.conditions, query, queryArgs) SqlQueryBuilder.buildWhereClause(config.search.conditions, query, queryArgs) if (selectActive) { query.append(')') Loading