/** * Change the state of a flag for a list of messages. * * <p>The goal of this method is to be fast. Currently this means using as few SQL UPDATE * statements as possible. * * @param messageIds A list of primary keys in the "messages" table. * @param flag The flag to change. This must be a flag with a separate column in the database. * @param newState {@code true}, if the flag should be set. {@code false}, otherwise. * @throws MessagingException */ public void setFlag(final List<Long> messageIds, final Flag flag, final boolean newState) throws MessagingException { final ContentValues cv = new ContentValues(); cv.put(getColumnNameForFlag(flag), newState); doBatchSetSelection( new BatchSetSelection() { @Override public int getListSize() { return messageIds.size(); } @Override public String getListItem(int index) { return Long.toString(messageIds.get(index)); } @Override public void doDbWork(SQLiteDatabase db, String selectionSet, String[] selectionArgs) throws UnavailableStorageException { db.update("messages", cv, "empty = 0 AND id" + selectionSet, selectionArgs); } @Override public void postDbWork() { notifyChange(); } }, FLAG_UPDATE_BATCH_SIZE); }
/** * Change the state of a flag for a list of threads. * * <p>The goal of this method is to be fast. Currently this means using as few SQL UPDATE * statements as possible. * * @param threadRootIds A list of root thread IDs. * @param flag The flag to change. This must be a flag with a separate column in the database. * @param newState {@code true}, if the flag should be set. {@code false}, otherwise. * @throws MessagingException */ public void setFlagForThreads(final List<Long> threadRootIds, Flag flag, final boolean newState) throws MessagingException { final String flagColumn = getColumnNameForFlag(flag); doBatchSetSelection( new BatchSetSelection() { @Override public int getListSize() { return threadRootIds.size(); } @Override public String getListItem(int index) { return Long.toString(threadRootIds.get(index)); } @Override public void doDbWork(SQLiteDatabase db, String selectionSet, String[] selectionArgs) throws UnavailableStorageException { db.execSQL( "UPDATE messages SET " + flagColumn + " = " + ((newState) ? "1" : "0") + " WHERE id IN (" + "SELECT m.id FROM threads t " + "LEFT JOIN messages m ON (t.message_id = m.id) " + "WHERE m.empty = 0 AND m.deleted = 0 " + "AND t.root" + selectionSet + ")", selectionArgs); } @Override public void postDbWork() { notifyChange(); } }, THREAD_FLAG_UPDATE_BATCH_SIZE); }
/** * Get folder name and UID for the supplied messages. * * @param messageIds A list of primary keys in the "messages" table. * @param threadedList If this is {@code true}, {@code messageIds} contains the thread IDs of the * messages at the root of a thread. In that case return UIDs for all messages in these * threads. If this is {@code false} only the UIDs for messages in {@code messageIds} are * returned. * @return The list of UIDs for the messages grouped by folder name. * @throws MessagingException */ public Map<String, List<String>> getFoldersAndUids( final List<Long> messageIds, final boolean threadedList) throws MessagingException { final Map<String, List<String>> folderMap = new HashMap<>(); doBatchSetSelection( new BatchSetSelection() { @Override public int getListSize() { return messageIds.size(); } @Override public String getListItem(int index) { return Long.toString(messageIds.get(index)); } @Override public void doDbWork(SQLiteDatabase db, String selectionSet, String[] selectionArgs) throws UnavailableStorageException { if (threadedList) { String sql = "SELECT m.uid, f.name " + "FROM threads t " + "LEFT JOIN messages m ON (t.message_id = m.id) " + "LEFT JOIN folders f ON (m.folder_id = f.id) " + "WHERE m.empty = 0 AND m.deleted = 0 " + "AND t.root" + selectionSet; getDataFromCursor(db.rawQuery(sql, selectionArgs)); } else { String sql = "SELECT m.uid, f.name " + "FROM messages m " + "LEFT JOIN folders f ON (m.folder_id = f.id) " + "WHERE m.empty = 0 AND m.id" + selectionSet; getDataFromCursor(db.rawQuery(sql, selectionArgs)); } } private void getDataFromCursor(Cursor cursor) { try { while (cursor.moveToNext()) { String uid = cursor.getString(0); String folderName = cursor.getString(1); List<String> uidList = folderMap.get(folderName); if (uidList == null) { uidList = new ArrayList<>(); folderMap.put(folderName, uidList); } uidList.add(uid); } } finally { cursor.close(); } } @Override public void postDbWork() { notifyChange(); } }, UID_CHECK_BATCH_SIZE); return folderMap; }