11package com.fsck.k9.storage.migrations
22
33import android.database.sqlite.SQLiteDatabase
4+ import androidx.annotation.VisibleForTesting
45import com.fsck.k9.mail.AuthType
56import com.fsck.k9.mail.AuthenticationFailedException
67import com.fsck.k9.mail.ServerSettings
@@ -10,6 +11,7 @@ import com.fsck.k9.mail.ssl.TrustedSocketFactory
1011import com.fsck.k9.mail.store.imap.ImapClientInfo
1112import com.fsck.k9.mail.store.imap.ImapStore
1213import com.fsck.k9.mail.store.imap.ImapStoreConfig
14+ import com.fsck.k9.mail.store.imap.ImapStoreFactory
1315import com.fsck.k9.mail.store.imap.ImapStoreSettings
1416import com.fsck.k9.mail.store.imap.ImapStoreSettings.autoDetectNamespace
1517import com.fsck.k9.mail.store.imap.ImapStoreSettings.pathPrefix
@@ -19,6 +21,8 @@ import net.thunderbird.core.android.account.LegacyAccount
1921import net.thunderbird.core.common.mail.Protocols
2022import net.thunderbird.core.logging.Logger
2123import net.thunderbird.core.logging.legacy.Log
24+ import okio.IOException
25+ import org.intellij.lang.annotations.Language
2226import org.koin.core.component.KoinComponent
2327import org.koin.core.component.inject
2428import org.koin.core.qualifier.named
@@ -29,6 +33,7 @@ internal class MigrationTo90(
2933 private val db : SQLiteDatabase ,
3034 private val migrationsHelper : MigrationsHelper ,
3135 private val logger : Logger = Log ,
36+ private val imapStoreFactory : ImapStoreFactory = ImapStore .Companion ,
3237) : KoinComponent {
3338 private val trustedSocketFactory: TrustedSocketFactory by inject()
3439 private val clientInfoAppName: String by inject(named(" ClientInfoAppName" ))
@@ -44,35 +49,33 @@ internal class MigrationTo90(
4449 return
4550 }
4651
47- logger.verbose(TAG ) { " started db migration to version 107 to account ${account.uuid} " }
52+ logger.verbose(TAG ) { " started db migration to version 90 to account ${account.uuid} " }
4853
4954 val imapStore = createImapStore(account)
5055
5156 try {
5257 logger.verbose(TAG ) { " fetching IMAP prefix" }
5358 imapStore.fetchImapPrefix()
54- } catch (e: AuthenticationFailedException ) {
55- logger.warn(TAG , e) { " failed to fetch IMAP prefix." }
56- return
57- }
58-
59- val imapPrefix = imapStore.combinedPrefix
60-
61- if (imapPrefix?.isNotBlank() == true ) {
62- logger.verbose(TAG ) { " Imap Prefix ($imapPrefix ) detected, updating folder's server_id" }
63- val query = """
64- |UPDATE folders
65- | SET server_id = REPLACE(server_id, '$imapPrefix ', '')
66- |WHERE
67- | server_id LIKE '$imapPrefix %'
68- """ .trimMargin()
59+ val imapPrefix = imapStore.combinedPrefix
60+
61+ if (imapPrefix?.isNotBlank() == true ) {
62+ logger.verbose(TAG ) { " Imap Prefix ($imapPrefix ) detected, updating folder's server_id" }
63+ val query = buildQuery(imapPrefix)
64+ db.execSQL(query)
65+ } else {
66+ logger.verbose(TAG ) { " No Imap Prefix detected, skipping db migration" }
67+ }
6968
70- db.execSQL(query)
71- } else {
72- logger.verbose(TAG ) { " No Imap Prefix detected, skipping db migration" }
69+ logger.verbose(TAG ) { " completed db migration to version 90 for account ${account.uuid} " }
70+ } catch (e: AuthenticationFailedException ) {
71+ logger.warn(TAG , e) {
72+ " failed to fetch IMAP prefix due to authentication error. skipping db migration"
73+ }
74+ } catch (e: IOException ) {
75+ logger.warn(TAG , e) {
76+ " failed to fetch IMAP prefix due to network error. skipping db migration"
77+ }
7378 }
74-
75- logger.verbose(TAG ) { " completed db migration to version 107 for account ${account.uuid} " }
7679 }
7780
7881 private fun createImapStore (account : LegacyAccount ): ImapStore {
@@ -87,7 +90,7 @@ internal class MigrationTo90(
8790 null
8891 }
8992
90- return ImapStore .create(
93+ return imapStoreFactory .create(
9194 serverSettings = serverSettings,
9295 config = createImapStoreConfig(account),
9396 trustedSocketFactory = trustedSocketFactory,
@@ -119,4 +122,18 @@ internal class MigrationTo90(
119122 override fun clientInfo () = ImapClientInfo (appName = clientInfoAppName, appVersion = clientInfoAppVersion)
120123 }
121124 }
125+
126+ @Language(" RoomSql" )
127+ @VisibleForTesting
128+ internal fun buildQuery (imapPrefix : String ): String {
129+ return """
130+ |UPDATE folders
131+ | SET server_id = REPLACE(server_id, '$imapPrefix ', '')
132+ |WHERE
133+ | server_id IS NOT NULL
134+ | AND server_id LIKE '$imapPrefix %'
135+ | AND type <> 'outbox'
136+ | AND local_only <> 1
137+ """ .trimMargin()
138+ }
122139}
0 commit comments