mirror of
https://github.com/moparisthebest/k-9
synced 2025-02-07 10:40:11 -05:00
Add threading support to content provider
This commit is contained in:
parent
05a2571570
commit
95b39c71d2
@ -30,8 +30,6 @@ import com.fsck.k9.activity.setup.FolderSettings;
|
|||||||
import com.fsck.k9.activity.setup.Prefs;
|
import com.fsck.k9.activity.setup.Prefs;
|
||||||
import com.fsck.k9.fragment.MessageListFragment;
|
import com.fsck.k9.fragment.MessageListFragment;
|
||||||
import com.fsck.k9.fragment.MessageListFragment.MessageListFragmentListener;
|
import com.fsck.k9.fragment.MessageListFragment.MessageListFragmentListener;
|
||||||
import com.fsck.k9.helper.Utility;
|
|
||||||
import com.fsck.k9.mail.Flag;
|
|
||||||
import com.fsck.k9.mail.Message;
|
import com.fsck.k9.mail.Message;
|
||||||
import com.fsck.k9.mail.store.StorageManager;
|
import com.fsck.k9.mail.store.StorageManager;
|
||||||
import com.fsck.k9.search.LocalSearch;
|
import com.fsck.k9.search.LocalSearch;
|
||||||
@ -95,6 +93,7 @@ public class MessageList extends K9FragmentActivity implements MessageListFragme
|
|||||||
private boolean mSingleFolderMode;
|
private boolean mSingleFolderMode;
|
||||||
private boolean mSingleAccountMode;
|
private boolean mSingleAccountMode;
|
||||||
private boolean mIsRemote;
|
private boolean mIsRemote;
|
||||||
|
private boolean mThreadViewEnabled = true; //TODO: this should be a setting
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
@ -116,7 +115,8 @@ public class MessageList extends K9FragmentActivity implements MessageListFragme
|
|||||||
|
|
||||||
if (mMessageListFragment == null) {
|
if (mMessageListFragment == null) {
|
||||||
FragmentTransaction ft = fragmentManager.beginTransaction();
|
FragmentTransaction ft = fragmentManager.beginTransaction();
|
||||||
mMessageListFragment = MessageListFragment.newInstance(mSearch, mIsRemote);
|
mMessageListFragment = MessageListFragment.newInstance(mSearch, mThreadViewEnabled,
|
||||||
|
mIsRemote);
|
||||||
ft.add(R.id.message_list_container, mMessageListFragment);
|
ft.add(R.id.message_list_container, mMessageListFragment);
|
||||||
ft.commit();
|
ft.commit();
|
||||||
}
|
}
|
||||||
@ -585,7 +585,7 @@ public class MessageList extends K9FragmentActivity implements MessageListFragme
|
|||||||
tmpSearch.addAccountUuids(mSearch.getAccountUuids());
|
tmpSearch.addAccountUuids(mSearch.getAccountUuids());
|
||||||
tmpSearch.and(Searchfield.SENDER, senderAddress, Attribute.CONTAINS);
|
tmpSearch.and(Searchfield.SENDER, senderAddress, Attribute.CONTAINS);
|
||||||
|
|
||||||
MessageListFragment fragment = MessageListFragment.newInstance(tmpSearch, false);
|
MessageListFragment fragment = MessageListFragment.newInstance(tmpSearch, false, false);
|
||||||
|
|
||||||
addMessageListFragment(fragment);
|
addMessageListFragment(fragment);
|
||||||
}
|
}
|
||||||
@ -634,7 +634,7 @@ public class MessageList extends K9FragmentActivity implements MessageListFragme
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void remoteSearch(String searchAccount, String searchFolder, String queryString) {
|
public void remoteSearch(String searchAccount, String searchFolder, String queryString) {
|
||||||
MessageListFragment fragment = MessageListFragment.newInstance(mSearch, true);
|
MessageListFragment fragment = MessageListFragment.newInstance(mSearch, false, true);
|
||||||
|
|
||||||
addMessageListFragment(fragment);
|
addMessageListFragment(fragment);
|
||||||
}
|
}
|
||||||
@ -669,10 +669,11 @@ public class MessageList extends K9FragmentActivity implements MessageListFragme
|
|||||||
@Override
|
@Override
|
||||||
public void showThread(Account account, String folderName, long threadRootId) {
|
public void showThread(Account account, String folderName, long threadRootId) {
|
||||||
LocalSearch tmpSearch = new LocalSearch();
|
LocalSearch tmpSearch = new LocalSearch();
|
||||||
tmpSearch.addAccountUuids(mSearch.getAccountUuids());
|
tmpSearch.addAccountUuid(account.getUuid());
|
||||||
tmpSearch.and(Searchfield.THREAD_ROOT, String.valueOf(threadRootId), Attribute.EQUALS);
|
tmpSearch.and(Searchfield.THREAD_ROOT, String.valueOf(threadRootId), Attribute.EQUALS);
|
||||||
|
tmpSearch.or(new SearchCondition(Searchfield.ID, Attribute.EQUALS, String.valueOf(threadRootId)));
|
||||||
|
|
||||||
MessageListFragment fragment = MessageListFragment.newInstance(tmpSearch, false);
|
MessageListFragment fragment = MessageListFragment.newInstance(tmpSearch, false, false);
|
||||||
addMessageListFragment(fragment);
|
addMessageListFragment(fragment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package com.fsck.k9.fragment;
|
|||||||
|
|
||||||
import java.text.DateFormat;
|
import java.text.DateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
@ -99,7 +100,7 @@ import com.handmark.pulltorefresh.library.PullToRefreshListView;
|
|||||||
public class MessageListFragment extends SherlockFragment implements OnItemClickListener,
|
public class MessageListFragment extends SherlockFragment implements OnItemClickListener,
|
||||||
ConfirmationDialogFragmentListener, LoaderCallbacks<Cursor> {
|
ConfirmationDialogFragmentListener, LoaderCallbacks<Cursor> {
|
||||||
|
|
||||||
private static final String[] PROJECTION = {
|
private static final String[] THREADED_PROJECTION = {
|
||||||
MessageColumns.ID,
|
MessageColumns.ID,
|
||||||
MessageColumns.UID,
|
MessageColumns.UID,
|
||||||
MessageColumns.INTERNAL_DATE,
|
MessageColumns.INTERNAL_DATE,
|
||||||
@ -114,7 +115,9 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick
|
|||||||
MessageColumns.PREVIEW,
|
MessageColumns.PREVIEW,
|
||||||
MessageColumns.THREAD_ROOT,
|
MessageColumns.THREAD_ROOT,
|
||||||
MessageColumns.THREAD_PARENT,
|
MessageColumns.THREAD_PARENT,
|
||||||
SpecialColumns.ACCOUNT_UUID
|
SpecialColumns.ACCOUNT_UUID,
|
||||||
|
|
||||||
|
MessageColumns.THREAD_COUNT,
|
||||||
};
|
};
|
||||||
|
|
||||||
private static final int ID_COLUMN = 0;
|
private static final int ID_COLUMN = 0;
|
||||||
@ -132,12 +135,18 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick
|
|||||||
private static final int THREAD_ROOT_COLUMN = 12;
|
private static final int THREAD_ROOT_COLUMN = 12;
|
||||||
private static final int THREAD_PARENT_COLUMN = 13;
|
private static final int THREAD_PARENT_COLUMN = 13;
|
||||||
private static final int ACCOUNT_UUID_COLUMN = 14;
|
private static final int ACCOUNT_UUID_COLUMN = 14;
|
||||||
|
private static final int THREAD_COUNT_COLUMN = 15;
|
||||||
|
|
||||||
|
private static final String[] PROJECTION = Arrays.copyOf(THREADED_PROJECTION,
|
||||||
|
THREAD_COUNT_COLUMN);
|
||||||
|
|
||||||
|
|
||||||
public static MessageListFragment newInstance(LocalSearch search, boolean remoteSearch) {
|
public static MessageListFragment newInstance(LocalSearch search, boolean threadedList,
|
||||||
|
boolean remoteSearch) {
|
||||||
MessageListFragment fragment = new MessageListFragment();
|
MessageListFragment fragment = new MessageListFragment();
|
||||||
Bundle args = new Bundle();
|
Bundle args = new Bundle();
|
||||||
args.putParcelable(ARG_SEARCH, search);
|
args.putParcelable(ARG_SEARCH, search);
|
||||||
|
args.putBoolean(ARG_THREADED_LIST, threadedList);
|
||||||
args.putBoolean(ARG_REMOTE_SEARCH, remoteSearch);
|
args.putBoolean(ARG_REMOTE_SEARCH, remoteSearch);
|
||||||
fragment.setArguments(args);
|
fragment.setArguments(args);
|
||||||
return fragment;
|
return fragment;
|
||||||
@ -285,6 +294,7 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick
|
|||||||
private static final int ACTIVITY_CHOOSE_FOLDER_COPY = 2;
|
private static final int ACTIVITY_CHOOSE_FOLDER_COPY = 2;
|
||||||
|
|
||||||
private static final String ARG_SEARCH = "searchObject";
|
private static final String ARG_SEARCH = "searchObject";
|
||||||
|
private static final String ARG_THREADED_LIST = "threadedList";
|
||||||
private static final String ARG_REMOTE_SEARCH = "remoteSearch";
|
private static final String ARG_REMOTE_SEARCH = "remoteSearch";
|
||||||
private static final String STATE_LIST_POSITION = "listPosition";
|
private static final String STATE_LIST_POSITION = "listPosition";
|
||||||
|
|
||||||
@ -384,10 +394,7 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick
|
|||||||
|
|
||||||
private DateFormat mTimeFormat;
|
private DateFormat mTimeFormat;
|
||||||
|
|
||||||
//TODO: make this a setting
|
private boolean mThreadedList;
|
||||||
private boolean mThreadViewEnabled = true;
|
|
||||||
|
|
||||||
private long mThreadId;
|
|
||||||
|
|
||||||
|
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
@ -631,21 +638,22 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick
|
|||||||
Cursor cursor = (Cursor) parent.getItemAtPosition(position);
|
Cursor cursor = (Cursor) parent.getItemAtPosition(position);
|
||||||
if (mSelectedCount > 0) {
|
if (mSelectedCount > 0) {
|
||||||
toggleMessageSelect(position);
|
toggleMessageSelect(position);
|
||||||
// } else if (message.threadCount > 1) {
|
|
||||||
// Folder folder = message.message.getFolder();
|
|
||||||
// long rootId = ((LocalMessage) message.message).getRootId();
|
|
||||||
// mFragmentListener.showThread(folder.getAccount(), folder.getName(), rootId);
|
|
||||||
} else {
|
} else {
|
||||||
Account account = getAccountFromCursor(cursor);
|
Account account = getAccountFromCursor(cursor);
|
||||||
|
|
||||||
long folderId = cursor.getLong(FOLDER_ID_COLUMN);
|
long folderId = cursor.getLong(FOLDER_ID_COLUMN);
|
||||||
String folderName = getFolderNameById(account, folderId);
|
String folderName = getFolderNameById(account, folderId);
|
||||||
|
|
||||||
MessageReference ref = new MessageReference();
|
if (mThreadedList && cursor.getInt(THREAD_COUNT_COLUMN) > 1) {
|
||||||
ref.accountUuid = account.getUuid();
|
long rootId = cursor.getLong(THREAD_ROOT_COLUMN);
|
||||||
ref.folderName = folderName;
|
mFragmentListener.showThread(account, folderName, rootId);
|
||||||
ref.uid = cursor.getString(UID_COLUMN);
|
} else {
|
||||||
onOpenMessage(ref);
|
MessageReference ref = new MessageReference();
|
||||||
|
ref.accountUuid = account.getUuid();
|
||||||
|
ref.folderName = folderName;
|
||||||
|
ref.uid = cursor.getString(UID_COLUMN);
|
||||||
|
onOpenMessage(ref);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -710,6 +718,7 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick
|
|||||||
private void decodeArguments() {
|
private void decodeArguments() {
|
||||||
Bundle args = getArguments();
|
Bundle args = getArguments();
|
||||||
|
|
||||||
|
mThreadedList = args.getBoolean(ARG_THREADED_LIST, false);
|
||||||
mRemoteSearch = args.getBoolean(ARG_REMOTE_SEARCH, false);
|
mRemoteSearch = args.getBoolean(ARG_REMOTE_SEARCH, false);
|
||||||
mSearch = args.getParcelable(ARG_SEARCH);
|
mSearch = args.getParcelable(ARG_SEARCH);
|
||||||
mTitle = mSearch.getName();
|
mTitle = mSearch.getName();
|
||||||
@ -1580,7 +1589,7 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick
|
|||||||
subject = getString(R.string.general_no_subject);
|
subject = getString(R.string.general_no_subject);
|
||||||
}
|
}
|
||||||
|
|
||||||
int threadCount = 0; //TODO: get thread count from cursor
|
int threadCount = (mThreadedList) ? cursor.getInt(THREAD_COUNT_COLUMN) : 0;
|
||||||
|
|
||||||
String flagList = cursor.getString(FLAGS_COLUMN);
|
String flagList = cursor.getString(FLAGS_COLUMN);
|
||||||
String[] flags = flagList.split(",");
|
String[] flags = flagList.split(",");
|
||||||
@ -1641,7 +1650,7 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Thread count
|
// Thread count
|
||||||
if (mThreadId == -1 && threadCount > 1) {
|
if (threadCount > 1) {
|
||||||
holder.threadCount.setText(Integer.toString(threadCount));
|
holder.threadCount.setText(Integer.toString(threadCount));
|
||||||
holder.threadCount.setVisibility(View.VISIBLE);
|
holder.threadCount.setVisibility(View.VISIBLE);
|
||||||
} else {
|
} else {
|
||||||
@ -2633,7 +2642,15 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick
|
|||||||
String accountUuid = mAccountUuids[id];
|
String accountUuid = mAccountUuids[id];
|
||||||
Account account = mPreferences.getAccount(accountUuid);
|
Account account = mPreferences.getAccount(accountUuid);
|
||||||
|
|
||||||
Uri uri = Uri.withAppendedPath(EmailProvider.CONTENT_URI, "account/" + accountUuid + "/messages");
|
Uri uri;
|
||||||
|
String[] projection;
|
||||||
|
if (mThreadedList) {
|
||||||
|
uri = Uri.withAppendedPath(EmailProvider.CONTENT_URI, "account/" + accountUuid + "/messages/threaded");
|
||||||
|
projection = THREADED_PROJECTION;
|
||||||
|
} else {
|
||||||
|
uri = Uri.withAppendedPath(EmailProvider.CONTENT_URI, "account/" + accountUuid + "/messages");
|
||||||
|
projection = PROJECTION;
|
||||||
|
}
|
||||||
|
|
||||||
StringBuilder query = new StringBuilder();
|
StringBuilder query = new StringBuilder();
|
||||||
List<String> queryArgs = new ArrayList<String>();
|
List<String> queryArgs = new ArrayList<String>();
|
||||||
@ -2642,7 +2659,7 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick
|
|||||||
String selection = query.toString();
|
String selection = query.toString();
|
||||||
String[] selectionArgs = queryArgs.toArray(new String[0]);
|
String[] selectionArgs = queryArgs.toArray(new String[0]);
|
||||||
|
|
||||||
return new CursorLoader(getActivity(), uri, PROJECTION, selection, selectionArgs,
|
return new CursorLoader(getActivity(), uri, projection, selection, selectionArgs,
|
||||||
MessageColumns.DATE + " DESC");
|
MessageColumns.DATE + " DESC");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,9 +38,6 @@ import android.net.Uri;
|
|||||||
* TODO:
|
* TODO:
|
||||||
* - modify MessagingController (or LocalStore?) to call ContentResolver.notifyChange() to trigger
|
* - modify MessagingController (or LocalStore?) to call ContentResolver.notifyChange() to trigger
|
||||||
* notifications when the underlying data changes.
|
* notifications when the underlying data changes.
|
||||||
* - add support for message threading
|
|
||||||
* - add support for search views
|
|
||||||
* - add support for querying multiple accounts (e.g. "Unified Inbox")
|
|
||||||
* - add support for account list and folder list
|
* - add support for account list and folder list
|
||||||
*/
|
*/
|
||||||
public class EmailProvider extends ContentProvider {
|
public class EmailProvider extends ContentProvider {
|
||||||
@ -56,18 +53,42 @@ public class EmailProvider extends ContentProvider {
|
|||||||
*/
|
*/
|
||||||
private static final int MESSAGE_BASE = 0;
|
private static final int MESSAGE_BASE = 0;
|
||||||
private static final int MESSAGES = MESSAGE_BASE;
|
private static final int MESSAGES = MESSAGE_BASE;
|
||||||
//private static final int MESSAGES_THREADED = MESSAGE_BASE + 1;
|
private static final int MESSAGES_THREADED = MESSAGE_BASE + 1;
|
||||||
//private static final int MESSAGES_THREAD = MESSAGE_BASE + 2;
|
//private static final int MESSAGES_THREAD = MESSAGE_BASE + 2;
|
||||||
|
|
||||||
|
|
||||||
private static final String MESSAGES_TABLE = "messages";
|
private static final String MESSAGES_TABLE = "messages";
|
||||||
|
|
||||||
|
private static final String[] MESSAGES_COLUMNS = {
|
||||||
|
MessageColumns.ID,
|
||||||
|
MessageColumns.UID,
|
||||||
|
MessageColumns.INTERNAL_DATE,
|
||||||
|
MessageColumns.SUBJECT,
|
||||||
|
MessageColumns.DATE,
|
||||||
|
MessageColumns.MESSAGE_ID,
|
||||||
|
MessageColumns.SENDER_LIST,
|
||||||
|
MessageColumns.TO_LIST,
|
||||||
|
MessageColumns.CC_LIST,
|
||||||
|
MessageColumns.BCC_LIST,
|
||||||
|
MessageColumns.REPLY_TO_LIST,
|
||||||
|
MessageColumns.FLAGS,
|
||||||
|
MessageColumns.ATTACHMENT_COUNT,
|
||||||
|
MessageColumns.FOLDER_ID,
|
||||||
|
MessageColumns.PREVIEW,
|
||||||
|
MessageColumns.THREAD_ROOT,
|
||||||
|
MessageColumns.THREAD_PARENT,
|
||||||
|
InternalMessageColumns.DELETED,
|
||||||
|
InternalMessageColumns.EMPTY,
|
||||||
|
InternalMessageColumns.TEXT_CONTENT,
|
||||||
|
InternalMessageColumns.HTML_CONTENT,
|
||||||
|
InternalMessageColumns.MIME_TYPE
|
||||||
|
};
|
||||||
|
|
||||||
static {
|
static {
|
||||||
UriMatcher matcher = sUriMatcher;
|
UriMatcher matcher = sUriMatcher;
|
||||||
|
|
||||||
matcher.addURI(AUTHORITY, "account/*/messages", MESSAGES);
|
matcher.addURI(AUTHORITY, "account/*/messages", MESSAGES);
|
||||||
//matcher.addURI(AUTHORITY, "account/*/messages/threaded", MESSAGES_THREADED);
|
matcher.addURI(AUTHORITY, "account/*/messages/threaded", MESSAGES_THREADED);
|
||||||
//matcher.addURI(AUTHORITY, "account/*/thread/#", MESSAGES_THREAD);
|
//matcher.addURI(AUTHORITY, "account/*/thread/#", MESSAGES_THREAD);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,6 +114,7 @@ public class EmailProvider extends ContentProvider {
|
|||||||
public static final String PREVIEW = "preview";
|
public static final String PREVIEW = "preview";
|
||||||
public static final String THREAD_ROOT = "thread_root";
|
public static final String THREAD_ROOT = "thread_root";
|
||||||
public static final String THREAD_PARENT = "thread_parent";
|
public static final String THREAD_PARENT = "thread_parent";
|
||||||
|
public static final String THREAD_COUNT = "thread_count";
|
||||||
}
|
}
|
||||||
|
|
||||||
private interface InternalMessageColumns extends MessageColumns {
|
private interface InternalMessageColumns extends MessageColumns {
|
||||||
@ -129,7 +151,8 @@ public class EmailProvider extends ContentProvider {
|
|||||||
ContentResolver contentResolver = getContext().getContentResolver();
|
ContentResolver contentResolver = getContext().getContentResolver();
|
||||||
Cursor cursor = null;
|
Cursor cursor = null;
|
||||||
switch (match) {
|
switch (match) {
|
||||||
case MESSAGES: {
|
case MESSAGES:
|
||||||
|
case MESSAGES_THREADED: {
|
||||||
List<String> segments = uri.getPathSegments();
|
List<String> segments = uri.getPathSegments();
|
||||||
String accountUuid = segments.get(1);
|
String accountUuid = segments.get(1);
|
||||||
|
|
||||||
@ -145,8 +168,15 @@ public class EmailProvider extends ContentProvider {
|
|||||||
|
|
||||||
String[] dbProjection = dbColumnNames.toArray(new String[0]);
|
String[] dbProjection = dbColumnNames.toArray(new String[0]);
|
||||||
|
|
||||||
cursor = getMessages(accountUuid, dbProjection, selection, selectionArgs,
|
if (match == MESSAGES) {
|
||||||
sortOrder);
|
cursor = getMessages(accountUuid, dbProjection, selection, selectionArgs,
|
||||||
|
sortOrder);
|
||||||
|
} else if (match == MESSAGES_THREADED) {
|
||||||
|
cursor = getThreadedMessages(accountUuid, dbProjection, selection,
|
||||||
|
selectionArgs, sortOrder);
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException("Not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
cursor.setNotificationUri(contentResolver, uri);
|
cursor.setNotificationUri(contentResolver, uri);
|
||||||
|
|
||||||
@ -206,6 +236,78 @@ public class EmailProvider extends ContentProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected Cursor getThreadedMessages(String accountUuid, final String[] projection,
|
||||||
|
final String selection, final String[] selectionArgs, final String sortOrder) {
|
||||||
|
|
||||||
|
Account account = getAccount(accountUuid);
|
||||||
|
LockableDatabase database = getDatabase(account);
|
||||||
|
|
||||||
|
try {
|
||||||
|
return database.execute(false, new DbCallback<Cursor>() {
|
||||||
|
@Override
|
||||||
|
public Cursor doDbWork(SQLiteDatabase db) throws WrappedException,
|
||||||
|
UnavailableStorageException {
|
||||||
|
|
||||||
|
StringBuilder query = new StringBuilder();
|
||||||
|
query.append("SELECT ");
|
||||||
|
boolean first = true;
|
||||||
|
for (String columnName : projection) {
|
||||||
|
if (!first) {
|
||||||
|
query.append(",");
|
||||||
|
} else {
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MessageColumns.DATE.equals(columnName)) {
|
||||||
|
query.append("MAX(m.date) AS " + MessageColumns.DATE);
|
||||||
|
} else if (MessageColumns.THREAD_COUNT.equals(columnName)) {
|
||||||
|
query.append("COUNT(h.id) AS " + MessageColumns.THREAD_COUNT);
|
||||||
|
} else {
|
||||||
|
query.append("m.");
|
||||||
|
query.append(columnName);
|
||||||
|
query.append(" AS ");
|
||||||
|
query.append(columnName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
query.append(
|
||||||
|
" FROM messages h JOIN messages m " +
|
||||||
|
"ON (h.id = m.thread_root OR h.id = m.id) " +
|
||||||
|
"WHERE " +
|
||||||
|
"(h.deleted = 0 AND m.deleted = 0 AND " +
|
||||||
|
"(m.empty IS NULL OR m.empty != 1) AND " +
|
||||||
|
"h.thread_root IS NULL) ");
|
||||||
|
|
||||||
|
if (!StringUtils.isNullOrEmpty(selection)) {
|
||||||
|
query.append("AND (");
|
||||||
|
query.append(addPrefixToSelection(MESSAGES_COLUMNS, "h.", selection));
|
||||||
|
query.append(") ");
|
||||||
|
}
|
||||||
|
|
||||||
|
query.append("GROUP BY h.id");
|
||||||
|
|
||||||
|
if (!StringUtils.isNullOrEmpty(sortOrder)) {
|
||||||
|
query.append(" ORDER BY ");
|
||||||
|
query.append(sortOrder);
|
||||||
|
}
|
||||||
|
|
||||||
|
return db.rawQuery(query.toString(), selectionArgs);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (UnavailableStorageException e) {
|
||||||
|
throw new RuntimeException("Storage not available", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String addPrefixToSelection(String[] columnNames, String prefix, String selection) {
|
||||||
|
String result = selection;
|
||||||
|
for (String columnName : columnNames) {
|
||||||
|
result = result.replaceAll("\\b" + columnName + "\\b", prefix + columnName);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
private Account getAccount(String accountUuid) {
|
private Account getAccount(String accountUuid) {
|
||||||
if (mPreferences == null) {
|
if (mPreferences == null) {
|
||||||
Context appContext = getContext().getApplicationContext();
|
Context appContext = getContext().getApplicationContext();
|
||||||
|
@ -176,7 +176,8 @@ public class LocalSearch implements SearchSpecification {
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
return mConditions.and(node);
|
mConditions = mConditions.and(node);
|
||||||
|
return mConditions;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -212,7 +213,8 @@ public class LocalSearch implements SearchSpecification {
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
return mConditions.or(node);
|
mConditions = mConditions.or(node);
|
||||||
|
return mConditions;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -90,7 +90,8 @@ public interface SearchSpecification extends Parcelable {
|
|||||||
SUBJECT("subject"), DATE("date"), UID("uid"), FLAG("flags"),
|
SUBJECT("subject"), DATE("date"), UID("uid"), FLAG("flags"),
|
||||||
SENDER("sender_list"), TO("to_list"), CC("cc_list"), FOLDER("folder_id"),
|
SENDER("sender_list"), TO("to_list"), CC("cc_list"), FOLDER("folder_id"),
|
||||||
BCC("bcc_list"), REPLY_TO("reply_to_list"), MESSAGE("text_content"),
|
BCC("bcc_list"), REPLY_TO("reply_to_list"), MESSAGE("text_content"),
|
||||||
ATTACHMENT_COUNT("attachment_count"), DELETED("deleted"), THREAD_ROOT("thread_root");
|
ATTACHMENT_COUNT("attachment_count"), DELETED("deleted"), THREAD_ROOT("thread_root"),
|
||||||
|
ID("id");
|
||||||
|
|
||||||
private String dbName;
|
private String dbName;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user