1
0
mirror of https://github.com/moparisthebest/k-9 synced 2025-02-25 15:11:52 -05:00

Avoid full table scan when creating the threaded message list

This commit is contained in:
cketti 2013-01-11 03:59:38 +01:00
parent 1df88ea153
commit 3ec623c174

View File

@ -385,6 +385,7 @@ public class EmailProvider extends ContentProvider {
UnavailableStorageException {
StringBuilder query = new StringBuilder();
query.append("SELECT ");
boolean first = true;
for (String columnName : projection) {
@ -394,24 +395,62 @@ public class EmailProvider extends ContentProvider {
first = false;
}
if (MessageColumns.DATE.equals(columnName)) {
query.append("MAX(m.date) AS " + MessageColumns.DATE);
if (MessageColumns.ID.equals(columnName)) {
query.append("u." + MessageColumns.ID + " AS " + MessageColumns.ID);
} else if (MessageColumns.DATE.equals(columnName)) {
query.append("MAX(date) AS " + MessageColumns.DATE);
} else if (SpecialColumns.THREAD_COUNT.equals(columnName)) {
query.append("COUNT(h.id) AS " + SpecialColumns.THREAD_COUNT);
} else if (SpecialColumns.FOLDER_NAME.equals(columnName)) {
query.append("f." + SpecialColumns.FOLDER_NAME + " AS " +
SpecialColumns.FOLDER_NAME);
} else if (SpecialColumns.INTEGRATE.equals(columnName)) {
query.append("f." + SpecialColumns.INTEGRATE + " AS " +
SpecialColumns.INTEGRATE);
query.append("COUNT(g) AS " + SpecialColumns.THREAD_COUNT);
} else {
query.append(columnName);
}
}
query.append(" FROM (");
createThreadedSubQuery(projection, selection, selectionArgs, "t1.id = t2.id", query);
query.append(" UNION ALL ");
createThreadedSubQuery(projection, selection, selectionArgs, "t1.id = t2.root", query);
query.append(") u GROUP BY g");
if (!StringUtils.isNullOrEmpty(sortOrder)) {
query.append(" ORDER BY ");
query.append(SqlQueryBuilder.addPrefixToSelection(MESSAGES_COLUMNS,
"u.", sortOrder));
}
// We need the selection arguments twice. Once for each sub query.
String[] args = new String[selectionArgs.length * 2];
System.arraycopy(selectionArgs, 0, args, 0, selectionArgs.length);
System.arraycopy(selectionArgs, 0, args, selectionArgs.length, selectionArgs.length);
return db.rawQuery(query.toString(), args);
}
});
} catch (UnavailableStorageException e) {
throw new RuntimeException("Storage not available", e);
}
}
private void createThreadedSubQuery(String[] projection, String selection,
String[] selectionArgs, String join, StringBuilder query) {
query.append("SELECT h." + MessageColumns.ID + " AS g");
for (String columnName : projection) {
if (SpecialColumns.THREAD_COUNT.equals(columnName)) {
// Skip
} else if (SpecialColumns.FOLDER_NAME.equals(columnName) ||
SpecialColumns.INTEGRATE.equals(columnName)) {
query.append("," + columnName);
} else if (ThreadColumns.ROOT.equals(columnName)) {
// Always return the thread ID of the root message (even for the root
// message itself)
query.append("CASE WHEN t2." + ThreadColumns.ROOT + " IS NULL THEN " +
query.append(",CASE WHEN t2." + ThreadColumns.ROOT + " IS NULL THEN " +
"t2." + ThreadColumns.ID + " ELSE t2." + ThreadColumns.ROOT +
" END AS " + ThreadColumns.ROOT);
} else {
query.append("m.");
query.append(",m.");
query.append(columnName);
query.append(" AS ");
query.append(columnName);
@ -421,7 +460,9 @@ public class EmailProvider extends ContentProvider {
query.append(
" FROM messages h " +
"LEFT JOIN threads t1 ON (t1.message_id = h.id) " +
"LEFT JOIN threads t2 ON (t1.id = t2.id OR t1.id = t2.root) " +
"JOIN threads t2 ON (");
query.append(join);
query.append(") " +
"LEFT JOIN messages m ON (m.id = t2.message_id) ");
if (Utility.arrayContainsAny(projection, (Object[]) FOLDERS_COLUMNS)) {
@ -440,21 +481,6 @@ public class EmailProvider extends ContentProvider {
"h.", selection));
query.append(")");
}
query.append("GROUP BY h.id");
if (!StringUtils.isNullOrEmpty(sortOrder)) {
query.append(" ORDER BY ");
query.append(SqlQueryBuilder.addPrefixToSelection(MESSAGES_COLUMNS,
"m.", sortOrder));
}
return db.rawQuery(query.toString(), selectionArgs);
}
});
} catch (UnavailableStorageException e) {
throw new RuntimeException("Storage not available", e);
}
}
protected Cursor getThread(String accountUuid, final String[] projection, final String threadId,