Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 05543214 authored by cketti's avatar cketti
Browse files

Move more code from FolderRepository to MessageStore

parent 78966353
Loading
Loading
Loading
Loading
+27 −52
Original line number Diff line number Diff line
@@ -2,10 +2,8 @@ package com.fsck.k9.mailstore

import android.database.sqlite.SQLiteDatabase
import androidx.core.content.contentValuesOf
import androidx.core.database.getStringOrNull
import com.fsck.k9.Account
import com.fsck.k9.Account.FolderMode
import com.fsck.k9.helper.map
import com.fsck.k9.mail.FolderClass
import com.fsck.k9.mail.FolderType as RemoteFolderType

@@ -21,13 +19,6 @@ class FolderRepository(
            .thenByDescending { it.isInTopGroup }
            .thenBy(String.CASE_INSENSITIVE_ORDER) { it.folder.name }

    fun getRemoteFolders(): List<RemoteFolder> {
        val folders = localStoreProvider.getInstance(account).getPersonalNamespaces(false)
        return folders
            .filterNot { it.isLocalOnly }
            .map { RemoteFolder(it.databaseId, it.serverId, it.name, it.type.toFolderType()) }
    }

    fun getDisplayFolders(displayMode: FolderMode?): List<DisplayFolder> {
        val database = localStoreProvider.getInstance(account).database
        val displayFolders = database.execute(false) { db ->
@@ -70,49 +61,37 @@ class FolderRepository(
        }
    }

    fun getRemoteFolders(): List<RemoteFolder> {
        val messageStore = messageStoreManager.getMessageStore(account)
        return messageStore.getFolders(excludeLocalOnly = true) { folder ->
            RemoteFolder(
                id = folder.id,
                serverId = folder.serverId,
                name = folder.name,
                type = folder.type.toFolderType()
            )
        }
    }

    fun getRemoteFolderDetails(): List<RemoteFolderDetails> {
        val database = localStoreProvider.getInstance(account).database
        return database.execute(false) { db ->
            db.query(
                "folders",
                arrayOf(
                    "id",
                    "server_id",
                    "name",
                    "type",
                    "top_group",
                    "integrate",
                    "poll_class",
                    "display_class",
                    "notify_class",
                    "push_class"
                ),
                "local_only = 0",
                null,
                null,
                null,
                null
            ).use { cursor ->
                cursor.map {
                    val id = cursor.getLong(0)
        val messageStore = messageStoreManager.getMessageStore(account)
        return messageStore.getFolders(excludeLocalOnly = true) { folder ->
            RemoteFolderDetails(
                folder = RemoteFolder(
                            id = id,
                            serverId = cursor.getString(1),
                            name = cursor.getString(2),
                            type = cursor.getString(3).toFolderType().toFolderType()
                    id = folder.id,
                    serverId = folder.serverId,
                    name = folder.name,
                    type = folder.type.toFolderType()
                ),
                        isInTopGroup = cursor.getInt(4) == 1,
                        isIntegrate = cursor.getInt(5) == 1,
                        syncClass = cursor.getStringOrNull(6).toFolderClass(),
                        displayClass = cursor.getStringOrNull(7).toFolderClass(),
                        notifyClass = cursor.getStringOrNull(8).toFolderClass(),
                        pushClass = cursor.getStringOrNull(9).toFolderClass()
                isInTopGroup = folder.isInTopGroup,
                isIntegrate = folder.isIntegrate,
                syncClass = folder.syncClass,
                displayClass = folder.displayClass,
                notifyClass = folder.notifyClass,
                pushClass = folder.pushClass
            )
        }
    }
        }
    }

    fun getFolderServerId(folderId: Long): String? {
        val messageStore = messageStoreManager.getMessageStore(account)
@@ -239,10 +218,6 @@ class FolderRepository(
        RemoteFolderType.ARCHIVE -> FolderType.ARCHIVE
    }

    private fun String?.toFolderClass(): FolderClass {
        return this?.let { FolderClass.valueOf(this) } ?: FolderClass.NO_CLASS
    }

    fun setIncludeInUnifiedInbox(folderId: Long, includeInUnifiedInbox: Boolean) {
        val localStore = localStoreProvider.getInstance(account)
        val folder = localStore.getFolder(folderId)
+8 −0
Original line number Diff line number Diff line
@@ -60,4 +60,12 @@ interface MessageStore {
     * @return The value returned by [mapper] or `null` if the folder wasn't found.
     */
    fun <T> getFolder(folderId: Long, mapper: FolderMapper<T>): T?

    /**
     * Retrieve folders.
     *
     * @param mapper A function to map the values read from the store to a domain-specific object.
     * @return A list of values returned by [mapper].
     */
    fun <T> getFolders(excludeLocalOnly: Boolean, mapper: FolderMapper<T>): List<T>
}
+4 −0
Original line number Diff line number Diff line
@@ -42,4 +42,8 @@ class K9MessageStore(private val localStore: LocalStore) : MessageStore {
    override fun <T> getFolder(folderId: Long, mapper: FolderMapper<T>): T? {
        return retrieveFolderOperations.getFolder(folderId, mapper)
    }

    override fun <T> getFolders(excludeLocalOnly: Boolean, mapper: FolderMapper<T>): List<T> {
        return retrieveFolderOperations.getFolders(excludeLocalOnly, mapper)
    }
}
+28 −13
Original line number Diff line number Diff line
package com.fsck.k9.storage.messages

import android.database.Cursor
import com.fsck.k9.helper.map
import com.fsck.k9.mail.FolderClass
import com.fsck.k9.mail.FolderType
import com.fsck.k9.mailstore.FolderDetailsAccessor
@@ -13,19 +14,7 @@ internal class RetrieveFolderOperations(private val lockableDatabase: LockableDa
        return lockableDatabase.execute(false) { db ->
            db.query(
                "folders",
                arrayOf(
                    "id",
                    "name",
                    "type",
                    "server_id",
                    "local_only",
                    "top_group",
                    "integrate",
                    "poll_class",
                    "display_class",
                    "notify_class",
                    "push_class"
                ),
                FOLDER_COLUMNS,
                "id = ?",
                arrayOf(folderId.toString()),
                null,
@@ -41,6 +30,18 @@ internal class RetrieveFolderOperations(private val lockableDatabase: LockableDa
            }
        }
    }

    fun <T> getFolders(excludeLocalOnly: Boolean = false, mapper: FolderMapper<T>): List<T> {
        val selection = if (excludeLocalOnly) "local_only = 0" else null
        return lockableDatabase.execute(false) { db ->
            db.query("folders", FOLDER_COLUMNS, selection, null, null, null, "id").use { cursor ->
                val cursorFolderAccessor = CursorFolderAccessor(cursor)
                cursor.map {
                    mapper.map(cursorFolderAccessor)
                }
            }
        }
    }
}

private class CursorFolderAccessor(val cursor: Cursor) : FolderDetailsAccessor {
@@ -77,3 +78,17 @@ private class CursorFolderAccessor(val cursor: Cursor) : FolderDetailsAccessor {
    override val pushClass: FolderClass
        get() = FolderClass.valueOf(cursor.getString(10))
}

private val FOLDER_COLUMNS = arrayOf(
    "id",
    "name",
    "type",
    "server_id",
    "local_only",
    "top_group",
    "integrate",
    "poll_class",
    "display_class",
    "notify_class",
    "push_class"
)
+56 −0
Original line number Diff line number Diff line
@@ -50,4 +50,60 @@ class RetrieveFolderOperationsTest : RobolectricTest() {

        assertThat(result).isNull()
    }

    @Test
    fun `get folders should return all fields`() {
        val folderId = sqliteDatabase.createFolder(
            name = "Folder Name",
            type = "inbox",
            serverId = "uid",
            isLocalOnly = false,
            integrate = true,
            inTopGroup = true,
            displayClass = "FIRST_CLASS",
            syncClass = "FIRST_CLASS",
            notifyClass = "NO_CLASS",
            pushClass = "NO_CLASS"
        )

        val result = retrieveFolderOperations.getFolders { folder ->
            assertThat(folder.id).isEqualTo(folderId)
            assertThat(folder.name).isEqualTo("Folder Name")
            assertThat(folder.type).isEqualTo(FolderType.INBOX)
            assertThat(folder.serverId).isEqualTo("uid")
            assertThat(folder.isLocalOnly).isEqualTo(false)
            assertThat(folder.isIntegrate).isEqualTo(true)
            assertThat(folder.isInTopGroup).isEqualTo(true)
            assertThat(folder.displayClass).isEqualTo(FolderClass.FIRST_CLASS)
            assertThat(folder.syncClass).isEqualTo(FolderClass.FIRST_CLASS)
            assertThat(folder.notifyClass).isEqualTo(FolderClass.NO_CLASS)
            assertThat(folder.pushClass).isEqualTo(FolderClass.NO_CLASS)
            true
        }

        assertThat(result).isEqualTo(listOf(true))
    }

    @Test
    fun `get folders with excludeLocalOnly should only return remote folders`() {
        val (folderId1, _, folderId3) = listOf(
            sqliteDatabase.createFolder(name = "Folder 1", isLocalOnly = false),
            sqliteDatabase.createFolder(name = "Folder 2", isLocalOnly = true),
            sqliteDatabase.createFolder(name = "Folder 3", isLocalOnly = false)
        )

        val result = retrieveFolderOperations.getFolders(excludeLocalOnly = true) { folder ->
            folder.id to folder.name
        }

        assertThat(result.map { it.first }).isEqualTo(listOf(folderId1, folderId3))
        assertThat(result.map { it.second }).isEqualTo(listOf("Folder 1", "Folder 3"))
    }

    @Test
    fun `get folders with empty store should return empty list`() {
        val result = retrieveFolderOperations.getFolders { "failed" }

        assertThat(result).isEmpty()
    }
}