Add new FolderDao upsert method

This commit is contained in:
Shinokuni 2024-05-04 18:13:19 +02:00
parent e9536e99ed
commit 052c83cb35
3 changed files with 109 additions and 0 deletions

View File

@ -91,4 +91,5 @@ dependencies {
testImplementation(libs.bundles.kointest)
implementation(libs.bundles.coroutines)
androidTestImplementation(libs.coroutines.test)
}

View File

@ -0,0 +1,72 @@
package com.readrops.db.dao
import android.content.Context
import androidx.room.Room
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.readrops.db.Database
import com.readrops.db.entities.Folder
import com.readrops.db.entities.account.Account
import com.readrops.db.entities.account.AccountType
import junit.framework.TestCase.assertFalse
import junit.framework.TestCase.assertTrue
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.test.runTest
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class NewFolderDaoTest {
private lateinit var database: Database
private lateinit var account: Account
@Before
fun before() = runTest {
val context = ApplicationProvider.getApplicationContext<Context>()
database = Room.inMemoryDatabaseBuilder(context, Database::class.java).build()
account = Account(accountType = AccountType.LOCAL).apply {
id = database.newAccountDao().insert(this).toInt()
}
repeat(2) { time ->
database.newFolderDao().insert(
Folder(
name = "Folder $time",
remoteId = "folder_$time",
accountId = account.id
)
)
}
}
@After
fun after() {
database.close()
}
@Test
fun upsertFoldersTest() = runTest {
val remoteFolders = listOf(
// updated folder
Folder(name = "New Folder 0", remoteId = "folder_0", accountId = account.id),
// removed folder
//Folder(name = "Folder 1", remoteId = "folder_1"),
// new inserted Folder
Folder(name = "Folder 2", remoteId = "folder_2", accountId = account.id)
)
database.newFolderDao().upsertFolders(remoteFolders, account)
val allFolders = database.newFolderDao().selectFolders(account.id).first()
assertTrue(allFolders.any { it.name == "New Folder 0" })
assertFalse(allFolders.any { it.remoteId == "folder_1" })
assertTrue(allFolders.any { it.remoteId == "folder_2" })
}
}

View File

@ -2,7 +2,9 @@ package com.readrops.db.dao.newdao
import androidx.room.Dao
import androidx.room.Query
import androidx.room.Transaction
import com.readrops.db.entities.Folder
import com.readrops.db.entities.account.Account
import com.readrops.db.pojo.FolderWithFeed
import kotlinx.coroutines.flow.Flow
@ -29,4 +31,38 @@ interface NewFolderDao : NewBaseDao<Folder> {
@Query("Select * From Folder Where name = :name And account_id = :accountId")
suspend fun selectFolderByName(name: String, accountId: Int): Folder?
@Query("Select remoteId From Folder Where account_id = :accountId")
suspend fun selectFolderRemoteIds(accountId: Int): List<String>
@Query("Update Folder set name = :name Where remoteId = :remoteId And account_id = :accountId")
suspend fun updateFolderName(name: String, remoteId: String, accountId: Int)
@Query("Delete From Folder Where remoteId in (:ids) And account_id = :accountId")
suspend fun deleteByIds(ids: List<String>, accountId: Int)
/**
* Insert, update and delete folders
*
* @param folders folders to insert or update
* @param account owner of the feeds
* @return the list of the inserted folders ids
*/
@Transaction
suspend fun upsertFolders(folders: List<Folder>, account: Account): List<Long> {
val localFolderIds = selectFolderRemoteIds(account.id)
val foldersToInsert = folders.filter { folder -> localFolderIds.none { localFolderId -> folder.remoteId == localFolderId } }
val foldersToDelete = localFolderIds.filter { localFolderId -> folders.none { folder -> localFolderId == folder.remoteId } }
// folders to update
folders.filter { folder -> localFolderIds.any { localFolderId -> folder.remoteId == localFolderId} }
.forEach { updateFolderName(it.name!!, it.remoteId!!, account.id) }
if (foldersToDelete.isNotEmpty()) {
deleteByIds(foldersToDelete, account.id)
}
return insert(foldersToInsert)
}
}