Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 303c1ee8 authored by cketti's avatar cketti
Browse files

Extract generation of SQL queries for searches to SqlQueryBuilder

parent 5778d135
Loading
Loading
Loading
Loading
+10 −59
Original line number Diff line number Diff line
@@ -85,10 +85,9 @@ import com.fsck.k9.mail.store.LocalStore.LocalFolder;
import com.fsck.k9.provider.EmailProvider;
import com.fsck.k9.provider.EmailProvider.MessageColumns;
import com.fsck.k9.provider.EmailProvider.SpecialColumns;
import com.fsck.k9.search.ConditionsTreeNode;
import com.fsck.k9.search.LocalSearch;
import com.fsck.k9.search.SearchSpecification;
import com.fsck.k9.search.SearchSpecification.SearchCondition;
import com.fsck.k9.search.SqlQueryBuilder;
import com.handmark.pulltorefresh.library.PullToRefreshBase;
import com.handmark.pulltorefresh.library.PullToRefreshListView;

@@ -2667,11 +2666,18 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick

        StringBuilder query = new StringBuilder();
        List<String> queryArgs = new ArrayList<String>();
        buildQuery(account, mSearch.getConditions(), query, queryArgs);
        SqlQueryBuilder.buildWhereClause(account, mSearch.getConditions(), query, queryArgs);

        String selection = query.toString();
        String[] selectionArgs = queryArgs.toArray(new String[0]);

        String sortOrder = buildSortOrder();

        return new CursorLoader(getActivity(), uri, projection, selection, selectionArgs,
                sortOrder);
    }

    private String buildSortOrder() {
        String sortColumn = MessageColumns.ID;
        switch (mSortType) {
            case SORT_ARRIVAL: {
@@ -2715,62 +2721,7 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick

        String sortOrder = sortColumn + sortDirection + ", " + secondarySort +
                MessageColumns.ID + " DESC";

        return new CursorLoader(getActivity(), uri, projection, selection, selectionArgs,
                sortOrder);
    }

    private void buildQuery(Account account, ConditionsTreeNode node, StringBuilder query,
            List<String> selectionArgs) {

        if (node == null) {
            return;
        }

        if (node.mLeft == null && node.mRight == null) {
            SearchCondition condition = node.mCondition;
            switch (condition.field) {
                case FOLDER: {
                    String folderName;
                    //TODO: Fix the search condition used by the Unified Inbox
                    if (LocalSearch.GENERIC_INBOX_NAME.equals(condition.value) ||
                            "1".equals(condition.value)) {
                        folderName = account.getInboxFolderName();
                    } else {
                        folderName = condition.value;
                    }
                    long folderId = getFolderId(account, folderName);
                    query.append("folder_id = ?");
                    selectionArgs.add(Long.toString(folderId));
                    break;
                }
                default: {
                    query.append(condition.toString());
                }
            }
        } else {
            query.append("(");
            buildQuery(account, node.mLeft, query, selectionArgs);
            query.append(") ");
            query.append(node.mValue.name());
            query.append(" (");
            buildQuery(account, node.mRight, query, selectionArgs);
            query.append(")");
        }
    }

    private long getFolderId(Account account, String folderName) {
        long folderId = 0;
        try {
            LocalFolder folder = (LocalFolder) getFolder(folderName, account).folder;
            folder.open(OpenMode.READ_ONLY);
            folderId = folder.getId();
        } catch (MessagingException e) {
            //FIXME
            e.printStackTrace();
        }

        return folderId;
        return sortOrder;
    }

    @Override
+10 −19
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ import com.fsck.k9.activity.Search;
import com.fsck.k9.controller.MessageRemovalListener;
import com.fsck.k9.controller.MessageRetrievalListener;
import com.fsck.k9.helper.HtmlConverter;
import com.fsck.k9.helper.StringUtils;
import com.fsck.k9.helper.Utility;
import com.fsck.k9.mail.Address;
import com.fsck.k9.mail.Body;
@@ -71,9 +72,8 @@ import com.fsck.k9.mail.store.LockableDatabase.WrappedException;
import com.fsck.k9.mail.store.StorageManager.StorageProvider;
import com.fsck.k9.provider.AttachmentProvider;
import com.fsck.k9.provider.EmailProvider;
import com.fsck.k9.search.ConditionsTreeNode;
import com.fsck.k9.search.LocalSearch;
import com.fsck.k9.search.SearchSpecification.Searchfield;
import com.fsck.k9.search.SqlQueryBuilder;

/**
 * <pre>
@@ -960,32 +960,23 @@ public class LocalStore extends Store implements Serializable {
    public Message[] searchForMessages(MessageRetrievalListener retrievalListener,
                                        LocalSearch search) throws MessagingException {

        // update some references in the search that have to be bound to this one store
        for (ConditionsTreeNode node : search.getLeafSet()) {
            if (node.mCondition.field == Searchfield.FOLDER) {
                // TODO find better solution
                if (isFolderId(node.mCondition.value)) {
                    continue;
                }
        StringBuilder query = new StringBuilder();
        List<String> queryArgs = new ArrayList<String>();
        SqlQueryBuilder.buildWhereClause(mAccount, search.getConditions(), query, queryArgs);

                if (node.mCondition.value.equals(LocalSearch.GENERIC_INBOX_NAME)) {
                    node.mCondition.value = mAccount.getInboxFolderName();
                }
                node.mCondition.value = String.valueOf(getFolderId(node.mCondition.value));
            }
        }
        String where = query.toString();
        String[] selectionArgs = queryArgs.toArray(EMPTY_STRING_ARRAY);

        // build sql query
        ConditionsTreeNode conditions = search.getConditions();
        String sqlQuery = "SELECT " + GET_MESSAGES_COLS + "FROM messages WHERE " +
                "((empty IS NULL OR empty != 1) AND deleted = 0)" +
                ((conditions != null) ? " AND (" + conditions + ")" : "") + " ORDER BY date DESC";
                ((!StringUtils.isNullOrEmpty(where)) ? " AND (" + where + ")" : "") +
                " ORDER BY date DESC";

        if (K9.DEBUG) {
            Log.d(K9.LOG_TAG, "Query = " + sqlQuery);
        }

        return getMessages(retrievalListener, null, sqlQuery, new String[] {});
        return getMessages(retrievalListener, null, sqlQuery, selectionArgs);
    }

    /*
+0 −12
Original line number Diff line number Diff line
@@ -239,18 +239,6 @@ public class ConditionsTreeNode implements Parcelable {
        return mCondition;
    }


    /**
     * This will traverse the tree inorder and call toString recursively resulting
     * in a valid SQL where clause.
     */
    @Override
    public String toString() {
        return (mLeft == null ? "" : "(" + mLeft + ")")
                + " " + ( mCondition == null ? mValue.name() : mCondition ) + " "
                + (mRight == null ? "" : "(" + mRight + ")") ;
    }

    /**
     * Get a set of all the leaves in the tree.
     * @return Set of all the leaves.
+1 −0
Original line number Diff line number Diff line
@@ -112,6 +112,7 @@ public class LocalSearch implements SearchSpecification {
    public void addAccountUuid(String uuid) {
        if (uuid.equals(ALL_ACCOUNTS)) {
            mAccountUuids.clear();
            return;
        }
        mAccountUuids.add(uuid);
    }
+26 −54
Original line number Diff line number Diff line
@@ -35,40 +35,17 @@ public interface SearchSpecification extends Parcelable {
    // ATTRIBUTE enum
    ///////////////////////////////////////////////////////////////
    public enum Attribute {
        CONTAINS(false), EQUALS(false), STARTSWITH(false), ENDSWITH(false),
        NOT_CONTAINS(true), NOT_EQUALS(true), NOT_STARTSWITH(true), NOT_ENDSWITH(true);
        CONTAINS,
        NOT_CONTAINS,

        private boolean mNegation;
        EQUALS,
        NOT_EQUALS,

        private Attribute(boolean negation) {
            this.mNegation = negation;
        }

        public String formQuery(String value) {
            String queryPart = "";

            switch (this) {
            case NOT_CONTAINS:
            case CONTAINS:
                queryPart = "'%"+value+"%'";
                break;
            case NOT_EQUALS:
            case EQUALS:
                queryPart = "'"+value+"'";
                break;
            case NOT_STARTSWITH:
            case STARTSWITH:
                queryPart = "'%"+value+"'";
                break;
            case NOT_ENDSWITH:
            case ENDSWITH:
                queryPart = "'"+value+"%'";
                break;
            default: queryPart = "'"+value+"'";
            }
        STARTSWITH,
        NOT_STARTSWITH,

            return (mNegation ? " NOT LIKE " : " LIKE ") + queryPart;
        }
        ENDSWITH,
        NOT_ENDSWITH
    }

    ///////////////////////////////////////////////////////////////
@@ -87,21 +64,21 @@ public interface SearchSpecification extends Parcelable {
     *
     */
    public enum Searchfield {
        SUBJECT("subject"), DATE("date"), UID("uid"), FLAG("flags"),
        SENDER("sender_list"), TO("to_list"), CC("cc_list"), FOLDER("folder_id"),
        BCC("bcc_list"), REPLY_TO("reply_to_list"), MESSAGE("text_content"),
        ATTACHMENT_COUNT("attachment_count"), DELETED("deleted"), THREAD_ROOT("thread_root"),
        ID("id");

        private String dbName;

        private Searchfield(String dbName) {
            this.dbName = dbName;
        }

        public String getDatabaseName() {
            return dbName;
        }
        SUBJECT,
        DATE,
        UID,
        FLAG,
        SENDER,
        TO,
        CC,
        FOLDER,
        BCC,
        REPLY_TO,
        MESSAGE_CONTENTS,
        ATTACHMENT_COUNT,
        DELETED,
        THREAD_ROOT,
        ID
    }


@@ -118,9 +95,9 @@ public interface SearchSpecification extends Parcelable {
     * @author dzan
     */
    public class SearchCondition implements Parcelable {
        public String value;
        public Attribute attribute;
        public Searchfield field;
        public final String value;
        public final Attribute attribute;
        public final Searchfield field;

        public SearchCondition(Searchfield field, Attribute attribute, String value) {
            this.value = value;
@@ -143,11 +120,6 @@ public interface SearchSpecification extends Parcelable {
            return field.toString() + attribute.toString();
        }

        @Override
        public String toString() {
            return field.getDatabaseName() + attribute.formQuery(value);
        }

        @Override
        public boolean equals(Object o) {
            if (o instanceof SearchCondition) {
Loading