diff --git a/k9mail/src/main/java/com/fsck/k9/mailstore/migrations/FullTextIndexer.kt b/k9mail/src/main/java/com/fsck/k9/mailstore/migrations/FullTextIndexer.kt new file mode 100644 index 00000000000..8104b989a81 --- /dev/null +++ b/k9mail/src/main/java/com/fsck/k9/mailstore/migrations/FullTextIndexer.kt @@ -0,0 +1,52 @@ +package com.fsck.k9.mailstore.migrations + + +import android.content.ContentValues +import android.database.sqlite.SQLiteDatabase +import com.fsck.k9.mail.FetchProfile +import com.fsck.k9.mail.MessagingException +import com.fsck.k9.mailstore.LocalFolder +import com.fsck.k9.mailstore.LocalStore +import timber.log.Timber + + +internal class FullTextIndexer(val localStore: LocalStore, val database: SQLiteDatabase) { + private val fulltextCreator = localStore.messageFulltextCreator + private val fetchProfile = FetchProfile().apply { add(FetchProfile.Item.BODY) } + + fun indexAllMessages() { + try { + val folders = localStore.getPersonalNamespaces(true) + for (folder in folders) { + indexFolder(folder) + } + } catch (e: MessagingException) { + Timber.e(e, "error indexing fulltext - skipping rest, fts index is incomplete!") + } + } + + private fun indexFolder(folder: LocalFolder) { + val messageUids = folder.allMessageUids + for (messageUid in messageUids) { + indexMessage(folder, messageUid) + } + } + + private fun indexMessage(folder: LocalFolder, messageUid: String?) { + val localMessage = folder.getMessage(messageUid) + folder.fetch(listOf(localMessage), fetchProfile, null) + + val fulltext = fulltextCreator.createFulltext(localMessage) + if (fulltext.isNullOrEmpty()) { + Timber.d("no fulltext for msg id %d :(", localMessage.databaseId) + } else { + Timber.d("fulltext for msg id %d is %d chars long", localMessage.databaseId, fulltext.length) + + val values = ContentValues().apply { + put("docid", localMessage.databaseId) + put("fulltext", fulltext) + } + database.insert("messages_fulltext", null, values) + } + } +} diff --git a/k9mail/src/main/java/com/fsck/k9/mailstore/migrations/MigrationTo55.java b/k9mail/src/main/java/com/fsck/k9/mailstore/migrations/MigrationTo55.java index ca2cda2fa47..b0addeb2ce7 100644 --- a/k9mail/src/main/java/com/fsck/k9/mailstore/migrations/MigrationTo55.java +++ b/k9mail/src/main/java/com/fsck/k9/mailstore/migrations/MigrationTo55.java @@ -1,54 +1,11 @@ package com.fsck.k9.mailstore.migrations; -import java.util.Collections; -import java.util.List; - -import android.content.ContentValues; import android.database.sqlite.SQLiteDatabase; -import android.text.TextUtils; -import timber.log.Timber; - -import com.fsck.k9.mail.FetchProfile; -import com.fsck.k9.mail.MessagingException; -import com.fsck.k9.mailstore.LocalFolder; -import com.fsck.k9.mailstore.LocalMessage; -import com.fsck.k9.mailstore.LocalStore; -import com.fsck.k9.message.extractors.MessageFulltextCreator; class MigrationTo55 { - static void createFtsSearchTable(SQLiteDatabase db, MigrationsHelper migrationsHelper) { + static void createFtsSearchTable(SQLiteDatabase db) { db.execSQL("CREATE VIRTUAL TABLE messages_fulltext USING fts4 (fulltext)"); - - LocalStore localStore = migrationsHelper.getLocalStore(); - MessageFulltextCreator fulltextCreator = localStore.getMessageFulltextCreator(); - - try { - List folders = localStore.getPersonalNamespaces(true); - ContentValues cv = new ContentValues(); - FetchProfile fp = new FetchProfile(); - fp.add(FetchProfile.Item.BODY); - for (LocalFolder folder : folders) { - List messageUids = folder.getAllMessageUids(); - for (String messageUid : messageUids) { - LocalMessage localMessage = folder.getMessage(messageUid); - folder.fetch(Collections.singletonList(localMessage), fp, null); - - String fulltext = fulltextCreator.createFulltext(localMessage); - if (!TextUtils.isEmpty(fulltext)) { - Timber.d("fulltext for msg id %d is %d chars long", localMessage.getDatabaseId(), fulltext.length()); - cv.clear(); - cv.put("docid", localMessage.getDatabaseId()); - cv.put("fulltext", fulltext); - db.insert("messages_fulltext", null, cv); - } else { - Timber.d("no fulltext for msg id %d :(", localMessage.getDatabaseId()); - } - } - } - } catch (MessagingException e) { - Timber.e(e, "error indexing fulltext - skipping rest, fts index is incomplete!"); - } } } diff --git a/k9mail/src/main/java/com/fsck/k9/mailstore/migrations/Migrations.java b/k9mail/src/main/java/com/fsck/k9/mailstore/migrations/Migrations.java index 03397c3e4a7..ccdd965df92 100644 --- a/k9mail/src/main/java/com/fsck/k9/mailstore/migrations/Migrations.java +++ b/k9mail/src/main/java/com/fsck/k9/mailstore/migrations/Migrations.java @@ -3,10 +3,13 @@ import android.database.sqlite.SQLiteDatabase; +import com.fsck.k9.mailstore.LocalStore; + public class Migrations { @SuppressWarnings("fallthrough") public static void upgradeDatabase(SQLiteDatabase db, MigrationsHelper migrationsHelper) { + boolean shouldBuildFtsTable = false; switch (db.getVersion()) { case 29: MigrationTo30.addDeletedColumn(db); @@ -63,7 +66,8 @@ public static void upgradeDatabase(SQLiteDatabase db, MigrationsHelper migration case 53: MigrationTo54.addPreviewTypeColumn(db); case 54: - MigrationTo55.createFtsSearchTable(db, migrationsHelper); + MigrationTo55.createFtsSearchTable(db); + shouldBuildFtsTable = true; case 55: MigrationTo56.cleanUpFtsTable(db); case 56: @@ -78,5 +82,15 @@ public static void upgradeDatabase(SQLiteDatabase db, MigrationsHelper migration case 60: MigrationTo61.removeErrorsFolder(db); } + + if (shouldBuildFtsTable) { + buildFtsTable(db, migrationsHelper); + } + } + + private static void buildFtsTable(SQLiteDatabase db, MigrationsHelper migrationsHelper) { + LocalStore localStore = migrationsHelper.getLocalStore(); + FullTextIndexer fullTextIndexer = new FullTextIndexer(localStore, db); + fullTextIndexer.indexAllMessages(); } }