Removed the BasePageDao and RoomPageDao.

* We have refactored our code to use PageDao for managing data related to Bookmarks, Notes, and History. With the ability to return Flowable from the Room database, the BasePageDao interface has become unnecessary. Consequently, we have removed BasePageDao and streamlined our code to use PageDao, providing a unified approach for these functionalities. This change reduces code complexity and enhances readability, making the codebase easier to understand and maintain.
This commit is contained in:
MohitMaliFtechiz 2024-06-05 17:32:34 +05:30 committed by Kelson
parent 84e0b742c2
commit cf58340ee8
18 changed files with 78 additions and 109 deletions

View File

@ -106,7 +106,7 @@ class KiwixRoomDatabaseTest {
// test inserting into history database // test inserting into history database
historyRoomDao.saveHistory(historyItem) historyRoomDao.saveHistory(historyItem)
var historyList = historyRoomDao.historyRoomEntity().first() var historyList = historyRoomDao.historyRoomEntity().blockingFirst()
with(historyList.first()) { with(historyList.first()) {
assertThat(historyTitle, equalTo(historyItem.title)) assertThat(historyTitle, equalTo(historyItem.title))
assertThat(zimId, equalTo(historyItem.zimId)) assertThat(zimId, equalTo(historyItem.zimId))
@ -120,7 +120,7 @@ class KiwixRoomDatabaseTest {
// test deleting the history // test deleting the history
historyRoomDao.deleteHistory(listOf(historyItem)) historyRoomDao.deleteHistory(listOf(historyItem))
historyList = historyRoomDao.historyRoomEntity().first() historyList = historyRoomDao.historyRoomEntity().blockingFirst()
assertEquals(historyList.size, 0) assertEquals(historyList.size, 0)
// test deleting all history // test deleting all history
@ -128,10 +128,10 @@ class KiwixRoomDatabaseTest {
historyRoomDao.saveHistory( historyRoomDao.saveHistory(
getHistoryItem(databaseId = 2) getHistoryItem(databaseId = 2)
) )
historyList = historyRoomDao.historyRoomEntity().first() historyList = historyRoomDao.historyRoomEntity().blockingFirst()
assertEquals(historyList.size, 2) assertEquals(historyList.size, 2)
historyRoomDao.deleteAllHistory() historyRoomDao.deleteAllHistory()
historyList = historyRoomDao.historyRoomEntity().first() historyList = historyRoomDao.historyRoomEntity().blockingFirst()
assertEquals(historyList.size, 0) assertEquals(historyList.size, 0)
} }
@ -139,7 +139,7 @@ class KiwixRoomDatabaseTest {
fun testNoteRoomDao() = runBlocking { fun testNoteRoomDao() = runBlocking {
notesRoomDao = db.notesRoomDao() notesRoomDao = db.notesRoomDao()
// delete all the notes from database to properly run the test cases. // delete all the notes from database to properly run the test cases.
notesRoomDao.deleteNotes(notesRoomDao.notes().first() as List<NoteListItem>) notesRoomDao.deleteNotes(notesRoomDao.notes().blockingFirst() as List<NoteListItem>)
val noteItem = getNoteListItem( val noteItem = getNoteListItem(
zimUrl = "http://kiwix.app/MainPage", zimUrl = "http://kiwix.app/MainPage",
noteFilePath = "/storage/emulated/0/Download/Notes/Alpine linux/MainPage.txt" noteFilePath = "/storage/emulated/0/Download/Notes/Alpine linux/MainPage.txt"
@ -147,7 +147,7 @@ class KiwixRoomDatabaseTest {
// Save and retrieve a notes item // Save and retrieve a notes item
notesRoomDao.saveNote(noteItem) notesRoomDao.saveNote(noteItem)
var notesList = notesRoomDao.notes().first() as List<NoteListItem> var notesList = notesRoomDao.notes().blockingFirst() as List<NoteListItem>
with(notesList.first()) { with(notesList.first()) {
assertThat(zimId, equalTo(noteItem.zimId)) assertThat(zimId, equalTo(noteItem.zimId))
assertThat(zimUrl, equalTo(noteItem.zimUrl)) assertThat(zimUrl, equalTo(noteItem.zimUrl))
@ -160,7 +160,7 @@ class KiwixRoomDatabaseTest {
// test deleting the history // test deleting the history
notesRoomDao.deleteNotes(listOf(noteItem)) notesRoomDao.deleteNotes(listOf(noteItem))
notesList = notesRoomDao.notes().first() as List<NoteListItem> notesList = notesRoomDao.notes().blockingFirst() as List<NoteListItem>
assertEquals(notesList.size, 0) assertEquals(notesList.size, 0)
// test deleting all notes // test deleting all notes
@ -171,10 +171,10 @@ class KiwixRoomDatabaseTest {
zimUrl = "http://kiwix.app/Installing" zimUrl = "http://kiwix.app/Installing"
) )
) )
notesList = notesRoomDao.notes().first() as List<NoteListItem> notesList = notesRoomDao.notes().blockingFirst() as List<NoteListItem>
assertEquals(notesList.size, 2) assertEquals(notesList.size, 2)
notesRoomDao.deletePages(notesRoomDao.notes().first()) notesRoomDao.deletePages(notesRoomDao.notes().blockingFirst())
notesList = notesRoomDao.notes().first() as List<NoteListItem> notesList = notesRoomDao.notes().blockingFirst() as List<NoteListItem>
assertEquals(notesList.size, 0) assertEquals(notesList.size, 0)
} }

View File

@ -169,7 +169,8 @@ class ObjectBoxToRoomMigratorTest {
// delete history for testing other edge cases // delete history for testing other edge cases
kiwixRoomDatabase.recentSearchRoomDao().deleteSearchHistory() kiwixRoomDatabase.recentSearchRoomDao().deleteSearchHistory()
kiwixRoomDatabase.historyRoomDao().deleteAllHistory() kiwixRoomDatabase.historyRoomDao().deleteAllHistory()
kiwixRoomDatabase.notesRoomDao().deletePages(kiwixRoomDatabase.notesRoomDao().notes().first()) kiwixRoomDatabase.notesRoomDao()
.deletePages(kiwixRoomDatabase.notesRoomDao().notes().blockingFirst())
box.removeAll() box.removeAll()
} }
@ -190,7 +191,7 @@ class ObjectBoxToRoomMigratorTest {
// migrate data into room database // migrate data into room database
objectBoxToRoomMigrator.migrateHistory(box) objectBoxToRoomMigrator.migrateHistory(box)
// check if data successfully migrated to room // check if data successfully migrated to room
val actual = kiwixRoomDatabase.historyRoomDao().historyRoomEntity().first() val actual = kiwixRoomDatabase.historyRoomDao().historyRoomEntity().blockingFirst()
with(actual.first()) { with(actual.first()) {
assertThat(historyTitle, equalTo(historyItem.title)) assertThat(historyTitle, equalTo(historyItem.title))
assertThat(zimId, equalTo(historyItem.zimId)) assertThat(zimId, equalTo(historyItem.zimId))
@ -206,7 +207,7 @@ class ObjectBoxToRoomMigratorTest {
// Migrate data from empty ObjectBox database // Migrate data from empty ObjectBox database
objectBoxToRoomMigrator.migrateHistory(box) objectBoxToRoomMigrator.migrateHistory(box)
var actualData = kiwixRoomDatabase.historyRoomDao().historyRoomEntity().first() var actualData = kiwixRoomDatabase.historyRoomDao().historyRoomEntity().blockingFirst()
assertTrue(actualData.isEmpty()) assertTrue(actualData.isEmpty())
// Test if data successfully migrated to Room and existing data is preserved // Test if data successfully migrated to Room and existing data is preserved
@ -214,7 +215,7 @@ class ObjectBoxToRoomMigratorTest {
box.put(HistoryEntity(historyItem2)) box.put(HistoryEntity(historyItem2))
// Migrate data into Room database // Migrate data into Room database
objectBoxToRoomMigrator.migrateHistory(box) objectBoxToRoomMigrator.migrateHistory(box)
actualData = kiwixRoomDatabase.historyRoomDao().historyRoomEntity().first() actualData = kiwixRoomDatabase.historyRoomDao().historyRoomEntity().blockingFirst()
assertEquals(2, actualData.size) assertEquals(2, actualData.size)
val existingItem = val existingItem =
actualData.find { actualData.find {
@ -233,7 +234,7 @@ class ObjectBoxToRoomMigratorTest {
kiwixRoomDatabase.historyRoomDao().saveHistory(historyItem) kiwixRoomDatabase.historyRoomDao().saveHistory(historyItem)
box.put(HistoryEntity(historyItem)) box.put(HistoryEntity(historyItem))
objectBoxToRoomMigrator.migrateHistory(box) objectBoxToRoomMigrator.migrateHistory(box)
actualData = kiwixRoomDatabase.historyRoomDao().historyRoomEntity().first() actualData = kiwixRoomDatabase.historyRoomDao().historyRoomEntity().blockingFirst()
assertEquals(1, actualData.size) assertEquals(1, actualData.size)
clearRoomAndBoxStoreDatabases(box) clearRoomAndBoxStoreDatabases(box)
@ -247,7 +248,7 @@ class ObjectBoxToRoomMigratorTest {
} catch (_: Exception) { } catch (_: Exception) {
} }
// Ensure Room database remains empty or unaffected by the invalid data // Ensure Room database remains empty or unaffected by the invalid data
actualData = kiwixRoomDatabase.historyRoomDao().historyRoomEntity().first() actualData = kiwixRoomDatabase.historyRoomDao().historyRoomEntity().blockingFirst()
assertTrue(actualData.isEmpty()) assertTrue(actualData.isEmpty())
// Test large data migration for recent searches // Test large data migration for recent searches
@ -269,7 +270,7 @@ class ObjectBoxToRoomMigratorTest {
val endTime = System.currentTimeMillis() val endTime = System.currentTimeMillis()
val migrationTime = endTime - startTime val migrationTime = endTime - startTime
// Check if data successfully migrated to Room // Check if data successfully migrated to Room
actualData = kiwixRoomDatabase.historyRoomDao().historyRoomEntity().first() actualData = kiwixRoomDatabase.historyRoomDao().historyRoomEntity().blockingFirst()
assertEquals(numEntities, actualData.size) assertEquals(numEntities, actualData.size)
// Assert that the migration completes within a reasonable time frame // Assert that the migration completes within a reasonable time frame
assertTrue("Migration took too long: $migrationTime ms", migrationTime < 20000) assertTrue("Migration took too long: $migrationTime ms", migrationTime < 20000)
@ -298,7 +299,7 @@ class ObjectBoxToRoomMigratorTest {
// migrate data into room database // migrate data into room database
objectBoxToRoomMigrator.migrateNotes(box) objectBoxToRoomMigrator.migrateNotes(box)
// check if data successfully migrated to room // check if data successfully migrated to room
var notesList = kiwixRoomDatabase.notesRoomDao().notes().first() as List<NoteListItem> var notesList = kiwixRoomDatabase.notesRoomDao().notes().blockingFirst() as List<NoteListItem>
with(notesList.first()) { with(notesList.first()) {
assertThat(zimId, equalTo(noteItem.zimId)) assertThat(zimId, equalTo(noteItem.zimId))
assertThat(zimUrl, equalTo(noteItem.zimUrl)) assertThat(zimUrl, equalTo(noteItem.zimUrl))
@ -313,7 +314,7 @@ class ObjectBoxToRoomMigratorTest {
// Migrate data from empty ObjectBox database // Migrate data from empty ObjectBox database
objectBoxToRoomMigrator.migrateNotes(box) objectBoxToRoomMigrator.migrateNotes(box)
notesList = kiwixRoomDatabase.notesRoomDao().notes().first() as List<NoteListItem> notesList = kiwixRoomDatabase.notesRoomDao().notes().blockingFirst() as List<NoteListItem>
assertTrue(notesList.isEmpty()) assertTrue(notesList.isEmpty())
// Test if data successfully migrated to Room and existing data is preserved // Test if data successfully migrated to Room and existing data is preserved
@ -321,7 +322,7 @@ class ObjectBoxToRoomMigratorTest {
box.put(NotesEntity(noteItem)) box.put(NotesEntity(noteItem))
// Migrate data into Room database // Migrate data into Room database
objectBoxToRoomMigrator.migrateNotes(box) objectBoxToRoomMigrator.migrateNotes(box)
notesList = kiwixRoomDatabase.notesRoomDao().notes().first() as List<NoteListItem> notesList = kiwixRoomDatabase.notesRoomDao().notes().blockingFirst() as List<NoteListItem>
assertEquals(noteItem.title, notesList.first().title) assertEquals(noteItem.title, notesList.first().title)
assertEquals(2, notesList.size) assertEquals(2, notesList.size)
val existingItem = val existingItem =
@ -342,7 +343,7 @@ class ObjectBoxToRoomMigratorTest {
box.put(NotesEntity(noteItem1)) box.put(NotesEntity(noteItem1))
// Migrate data into Room database // Migrate data into Room database
objectBoxToRoomMigrator.migrateNotes(box) objectBoxToRoomMigrator.migrateNotes(box)
notesList = kiwixRoomDatabase.notesRoomDao().notes().first() as List<NoteListItem> notesList = kiwixRoomDatabase.notesRoomDao().notes().blockingFirst() as List<NoteListItem>
assertEquals(1, notesList.size) assertEquals(1, notesList.size)
clearRoomAndBoxStoreDatabases(box) clearRoomAndBoxStoreDatabases(box)
@ -356,7 +357,7 @@ class ObjectBoxToRoomMigratorTest {
} catch (_: Exception) { } catch (_: Exception) {
} }
// Ensure Room database remains empty or unaffected by the invalid data // Ensure Room database remains empty or unaffected by the invalid data
notesList = kiwixRoomDatabase.notesRoomDao().notes().first() as List<NoteListItem> notesList = kiwixRoomDatabase.notesRoomDao().notes().blockingFirst() as List<NoteListItem>
assertTrue(notesList.isEmpty()) assertTrue(notesList.isEmpty())
// Test large data migration for recent searches // Test large data migration for recent searches
@ -378,7 +379,7 @@ class ObjectBoxToRoomMigratorTest {
val endTime = System.currentTimeMillis() val endTime = System.currentTimeMillis()
val migrationTime = endTime - startTime val migrationTime = endTime - startTime
// Check if data successfully migrated to Room // Check if data successfully migrated to Room
notesList = kiwixRoomDatabase.notesRoomDao().notes().first() as List<NoteListItem> notesList = kiwixRoomDatabase.notesRoomDao().notes().blockingFirst() as List<NoteListItem>
assertEquals(numEntities, notesList.size) assertEquals(numEntities, notesList.size)
// Assert that the migration completes within a reasonable time frame // Assert that the migration completes within a reasonable time frame
assertTrue("Migration took too long: $migrationTime ms", migrationTime < 20000) assertTrue("Migration took too long: $migrationTime ms", migrationTime < 20000)

View File

@ -22,7 +22,6 @@ import android.content.Context
import androidx.room.Room import androidx.room.Room
import androidx.test.core.app.ApplicationProvider import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.ext.junit.runners.AndroidJUnit4
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.core.IsEqual.equalTo import org.hamcrest.core.IsEqual.equalTo
@ -65,7 +64,7 @@ class HistoryRoomDaoTest {
// Save and retrieve a history item // Save and retrieve a history item
historyRoomDao.saveHistory(historyItem) historyRoomDao.saveHistory(historyItem)
var historyList = historyRoomDao.historyRoomEntity().first() var historyList = historyRoomDao.historyRoomEntity().blockingFirst()
with(historyList.first()) { with(historyList.first()) {
assertThat(historyTitle, equalTo(historyItem.title)) assertThat(historyTitle, equalTo(historyItem.title))
assertThat(zimId, equalTo(historyItem.zimId)) assertThat(zimId, equalTo(historyItem.zimId))
@ -79,26 +78,26 @@ class HistoryRoomDaoTest {
// Test to update the same day history for url // Test to update the same day history for url
historyRoomDao.saveHistory(historyItem) historyRoomDao.saveHistory(historyItem)
historyList = historyRoomDao.historyRoomEntity().first() historyList = historyRoomDao.historyRoomEntity().blockingFirst()
assertEquals(historyList.size, 1) assertEquals(historyList.size, 1)
// Delete the saved history item // Delete the saved history item
historyRoomDao.deleteHistory(listOf(historyItem)) historyRoomDao.deleteHistory(listOf(historyItem))
historyList = historyRoomDao.historyRoomEntity().first() historyList = historyRoomDao.historyRoomEntity().blockingFirst()
assertEquals(historyList.size, 0) assertEquals(historyList.size, 0)
// Save and delete all history items // Save and delete all history items
historyRoomDao.saveHistory(historyItem) historyRoomDao.saveHistory(historyItem)
historyRoomDao.saveHistory(getHistoryItem(databaseId = 2, dateString = "31 May 2024")) historyRoomDao.saveHistory(getHistoryItem(databaseId = 2, dateString = "31 May 2024"))
historyRoomDao.deleteAllHistory() historyRoomDao.deleteAllHistory()
historyList = historyRoomDao.historyRoomEntity().first() historyList = historyRoomDao.historyRoomEntity().blockingFirst()
assertThat(historyList.size, equalTo(0)) assertThat(historyList.size, equalTo(0))
// Save history item with empty fields // Save history item with empty fields
val emptyHistoryUrl = "" val emptyHistoryUrl = ""
val emptyTitle = "" val emptyTitle = ""
historyRoomDao.saveHistory(getHistoryItem(emptyTitle, emptyHistoryUrl, databaseId = 1)) historyRoomDao.saveHistory(getHistoryItem(emptyTitle, emptyHistoryUrl, databaseId = 1))
historyList = historyRoomDao.historyRoomEntity().first() historyList = historyRoomDao.historyRoomEntity().blockingFirst()
assertThat(historyList.size, equalTo(1)) assertThat(historyList.size, equalTo(1))
historyRoomDao.deleteAllHistory() historyRoomDao.deleteAllHistory()
@ -118,13 +117,13 @@ class HistoryRoomDaoTest {
val unicodeTitle = "title \u03A3" // Unicode character for Greek capital letter Sigma val unicodeTitle = "title \u03A3" // Unicode character for Greek capital letter Sigma
val historyItem2 = getHistoryItem(title = unicodeTitle, databaseId = 2) val historyItem2 = getHistoryItem(title = unicodeTitle, databaseId = 2)
historyRoomDao.saveHistory(historyItem2) historyRoomDao.saveHistory(historyItem2)
historyList = historyRoomDao.historyRoomEntity().first() historyList = historyRoomDao.historyRoomEntity().blockingFirst()
assertThat(historyList.first().historyTitle, equalTo("title Σ")) assertThat(historyList.first().historyTitle, equalTo("title Σ"))
// Test deletePages function // Test deletePages function
historyRoomDao.saveHistory(historyItem) historyRoomDao.saveHistory(historyItem)
historyRoomDao.deletePages(listOf(historyItem, historyItem2)) historyRoomDao.deletePages(listOf(historyItem, historyItem2))
historyList = historyRoomDao.historyRoomEntity().first() historyList = historyRoomDao.historyRoomEntity().blockingFirst()
assertThat(historyList.size, equalTo(0)) assertThat(historyList.size, equalTo(0))
} }
} }

View File

@ -64,7 +64,7 @@ class NoteRoomDaoTest {
// Save and retrieve a notes item // Save and retrieve a notes item
notesRoomDao.saveNote(noteItem) notesRoomDao.saveNote(noteItem)
var notesList = notesRoomDao.notes().first() as List<NoteListItem> var notesList = notesRoomDao.notes().blockingFirst() as List<NoteListItem>
with(notesList.first()) { with(notesList.first()) {
assertThat(zimId, equalTo(noteItem.zimId)) assertThat(zimId, equalTo(noteItem.zimId))
assertThat(zimUrl, equalTo(noteItem.zimUrl)) assertThat(zimUrl, equalTo(noteItem.zimUrl))
@ -77,25 +77,25 @@ class NoteRoomDaoTest {
// Test update the existing note // Test update the existing note
notesRoomDao.saveNote(noteItem) notesRoomDao.saveNote(noteItem)
notesList = notesRoomDao.notes().first() as List<NoteListItem> notesList = notesRoomDao.notes().blockingFirst() as List<NoteListItem>
assertEquals(notesList.size, 1) assertEquals(notesList.size, 1)
// Delete the saved note item with all delete methods available in NoteRoomDao. // Delete the saved note item with all delete methods available in NoteRoomDao.
// delete via noteTitle // delete via noteTitle
notesRoomDao.deleteNote(noteItem.title) notesRoomDao.deleteNote(noteItem.title)
notesList = notesRoomDao.notes().first() as List<NoteListItem> notesList = notesRoomDao.notes().blockingFirst() as List<NoteListItem>
assertEquals(notesList.size, 0) assertEquals(notesList.size, 0)
// delete with deletePages method // delete with deletePages method
notesRoomDao.saveNote(noteItem) notesRoomDao.saveNote(noteItem)
notesRoomDao.deletePages(listOf(noteItem)) notesRoomDao.deletePages(listOf(noteItem))
notesList = notesRoomDao.notes().first() as List<NoteListItem> notesList = notesRoomDao.notes().blockingFirst() as List<NoteListItem>
assertEquals(notesList.size, 0) assertEquals(notesList.size, 0)
// delete with list of NoteListItem // delete with list of NoteListItem
notesRoomDao.saveNote(noteItem) notesRoomDao.saveNote(noteItem)
notesRoomDao.deleteNotes(listOf(noteItem)) notesRoomDao.deleteNotes(listOf(noteItem))
notesList = notesRoomDao.notes().first() as List<NoteListItem> notesList = notesRoomDao.notes().blockingFirst() as List<NoteListItem>
assertEquals(notesList.size, 0) assertEquals(notesList.size, 0)
// Save note with empty title // Save note with empty title
@ -106,7 +106,7 @@ class NoteRoomDaoTest {
noteFilePath = "/storage/emulated/0/Download/Notes/Alpine linux/Installing.txt" noteFilePath = "/storage/emulated/0/Download/Notes/Alpine linux/Installing.txt"
) )
) )
notesList = notesRoomDao.notes().first() as List<NoteListItem> notesList = notesRoomDao.notes().blockingFirst() as List<NoteListItem>
assertEquals(notesList.size, 1) assertEquals(notesList.size, 1)
clearNotes() clearNotes()
@ -127,11 +127,11 @@ class NoteRoomDaoTest {
val noteListItem2 = val noteListItem2 =
getNoteListItem(title = unicodeTitle, zimUrl = "http://kiwix.app/Installing") getNoteListItem(title = unicodeTitle, zimUrl = "http://kiwix.app/Installing")
notesRoomDao.saveNote(noteListItem2) notesRoomDao.saveNote(noteListItem2)
notesList = notesRoomDao.notes().first() as List<NoteListItem> notesList = notesRoomDao.notes().blockingFirst() as List<NoteListItem>
assertThat(notesList.first().title, equalTo("title Σ")) assertThat(notesList.first().title, equalTo("title Σ"))
} }
private suspend fun clearNotes() { private suspend fun clearNotes() {
notesRoomDao.deleteNotes(notesRoomDao.notes().first() as List<NoteListItem>) notesRoomDao.deleteNotes(notesRoomDao.notes().blockingFirst() as List<NoteListItem>)
} }
} }

View File

@ -26,12 +26,6 @@ object Libs {
const val kotlinx_coroutines_test: String = "org.jetbrains.kotlinx:kotlinx-coroutines-test:" + const val kotlinx_coroutines_test: String = "org.jetbrains.kotlinx:kotlinx-coroutines-test:" +
Versions.org_jetbrains_kotlinx_kotlinx_coroutines Versions.org_jetbrains_kotlinx_kotlinx_coroutines
/**
* https://github.com/Kotlin/kotlinx.coroutines
*/
const val kotlinx_coroutines_rx2: String = "org.jetbrains.kotlinx:kotlinx-coroutines-rx2:" +
Versions.org_jetbrains_kotlinx_kotlinx_coroutines
/** /**
* https://developer.android.com/testing * https://developer.android.com/testing
*/ */
@ -363,4 +357,6 @@ object Libs {
const val roomCompiler = "androidx.room:room-compiler:" + Versions.roomVersion const val roomCompiler = "androidx.room:room-compiler:" + Versions.roomVersion
const val roomRuntime = "androidx.room:room-runtime:" + Versions.roomVersion const val roomRuntime = "androidx.room:room-runtime:" + Versions.roomVersion
const val roomRxjava2 = "androidx.room:room-rxjava2:" + Versions.roomVersion
} }

View File

@ -204,12 +204,12 @@ class AllProjectConfigurer {
implementation(Libs.fetch) implementation(Libs.fetch)
implementation(Libs.rxandroid) implementation(Libs.rxandroid)
implementation(Libs.rxjava) implementation(Libs.rxjava)
implementation(Libs.kotlinx_coroutines_rx2)
implementation(Libs.preference_ktx) implementation(Libs.preference_ktx)
implementation(Libs.material_show_case_view) implementation(Libs.material_show_case_view)
implementation(Libs.roomKtx) implementation(Libs.roomKtx)
annotationProcessor(Libs.roomCompiler) annotationProcessor(Libs.roomCompiler)
implementation(Libs.roomRuntime) implementation(Libs.roomRuntime)
implementation(Libs.roomRxjava2)
kapt(Libs.roomCompiler) kapt(Libs.roomCompiler)
} }
} }

View File

@ -24,18 +24,17 @@ import androidx.room.Insert
import androidx.room.Query import androidx.room.Query
import androidx.room.TypeConverter import androidx.room.TypeConverter
import androidx.room.Update import androidx.room.Update
import kotlinx.coroutines.flow.Flow import io.reactivex.Flowable
import kotlinx.coroutines.flow.map
import org.kiwix.kiwixmobile.core.dao.entities.HistoryRoomEntity import org.kiwix.kiwixmobile.core.dao.entities.HistoryRoomEntity
import org.kiwix.kiwixmobile.core.page.adapter.Page import org.kiwix.kiwixmobile.core.page.adapter.Page
import org.kiwix.kiwixmobile.core.page.history.adapter.HistoryListItem import org.kiwix.kiwixmobile.core.page.history.adapter.HistoryListItem
@Dao @Dao
abstract class HistoryRoomDao : PageRoomDao { abstract class HistoryRoomDao : PageDao {
@Query("SELECT * FROM HistoryRoomEntity ORDER BY HistoryRoomEntity.timeStamp DESC") @Query("SELECT * FROM HistoryRoomEntity ORDER BY HistoryRoomEntity.timeStamp DESC")
abstract fun historyRoomEntity(): Flow<List<HistoryRoomEntity>> abstract fun historyRoomEntity(): Flowable<List<HistoryRoomEntity>>
fun history(): Flow<List<Page>> = historyRoomEntity().map { fun history(): Flowable<List<Page>> = historyRoomEntity().map {
it.map(HistoryListItem::HistoryItem) it.map(HistoryListItem::HistoryItem)
} }

View File

@ -22,19 +22,18 @@ import androidx.room.Dao
import androidx.room.Insert import androidx.room.Insert
import androidx.room.OnConflictStrategy import androidx.room.OnConflictStrategy
import androidx.room.Query import androidx.room.Query
import kotlinx.coroutines.flow.Flow import io.reactivex.Flowable
import kotlinx.coroutines.flow.map
import org.kiwix.kiwixmobile.core.dao.entities.NotesRoomEntity import org.kiwix.kiwixmobile.core.dao.entities.NotesRoomEntity
import org.kiwix.kiwixmobile.core.page.adapter.Page import org.kiwix.kiwixmobile.core.page.adapter.Page
import org.kiwix.kiwixmobile.core.page.notes.adapter.NoteListItem import org.kiwix.kiwixmobile.core.page.notes.adapter.NoteListItem
@Dao @Dao
abstract class NotesRoomDao : PageRoomDao { abstract class NotesRoomDao : PageDao {
@Query("SELECT * FROM NotesRoomEntity ORDER BY NotesRoomEntity.noteTitle") @Query("SELECT * FROM NotesRoomEntity ORDER BY NotesRoomEntity.noteTitle")
abstract fun notesAsEntity(): Flow<List<NotesRoomEntity>> abstract fun notesAsEntity(): Flowable<List<NotesRoomEntity>>
fun notes(): Flow<List<Page>> = notesAsEntity().map { it.map(::NoteListItem) } fun notes(): Flowable<List<Page>> = notesAsEntity().map { it.map(::NoteListItem) }
override fun pages(): Flow<List<Page>> = notes() override fun pages(): Flowable<List<Page>> = notes()
override fun deletePages(pagesToDelete: List<Page>) = override fun deletePages(pagesToDelete: List<Page>) =
deleteNotes(pagesToDelete as List<NoteListItem>) deleteNotes(pagesToDelete as List<NoteListItem>)

View File

@ -19,18 +19,9 @@
package org.kiwix.kiwixmobile.core.dao package org.kiwix.kiwixmobile.core.dao
import io.reactivex.Flowable import io.reactivex.Flowable
import kotlinx.coroutines.flow.Flow
import org.kiwix.kiwixmobile.core.page.adapter.Page import org.kiwix.kiwixmobile.core.page.adapter.Page
interface PageDao : BasePageDao { interface PageDao {
override fun pages(): Flowable<List<Page>> fun pages(): Flowable<List<Page>>
}
interface PageRoomDao : BasePageDao {
override fun pages(): Flow<List<Page>>
}
interface BasePageDao {
fun pages(): Any
fun deletePages(pagesToDelete: List<Page>) fun deletePages(pagesToDelete: List<Page>)
} }

View File

@ -66,7 +66,7 @@ class BookmarkViewModel @Inject constructor(
state.copy(pageItems = state.pageItems.map { it.copy(isSelected = false) }) state.copy(pageItems = state.pageItems.map { it.copy(isSelected = false) })
override fun createDeletePageDialogEffect(state: BookmarkState, viewModelScope: CoroutineScope) = override fun createDeletePageDialogEffect(state: BookmarkState, viewModelScope: CoroutineScope) =
ShowDeleteBookmarksDialog(effects, state, basePageDao, viewModelScope) ShowDeleteBookmarksDialog(effects, state, pageDao, viewModelScope)
override fun copyWithNewItems( override fun copyWithNewItems(
state: BookmarkState, state: BookmarkState,

View File

@ -22,7 +22,7 @@ import androidx.appcompat.app.AppCompatActivity
import io.reactivex.processors.PublishProcessor import io.reactivex.processors.PublishProcessor
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import org.kiwix.kiwixmobile.core.base.SideEffect import org.kiwix.kiwixmobile.core.base.SideEffect
import org.kiwix.kiwixmobile.core.dao.BasePageDao import org.kiwix.kiwixmobile.core.dao.PageDao
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.cachedComponent import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.cachedComponent
import org.kiwix.kiwixmobile.core.page.bookmark.adapter.LibkiwixBookmarkItem import org.kiwix.kiwixmobile.core.page.bookmark.adapter.LibkiwixBookmarkItem
import org.kiwix.kiwixmobile.core.page.viewmodel.PageState import org.kiwix.kiwixmobile.core.page.viewmodel.PageState
@ -35,7 +35,7 @@ import javax.inject.Inject
data class ShowDeleteBookmarksDialog( data class ShowDeleteBookmarksDialog(
private val effects: PublishProcessor<SideEffect<*>>, private val effects: PublishProcessor<SideEffect<*>>,
private val state: PageState<LibkiwixBookmarkItem>, private val state: PageState<LibkiwixBookmarkItem>,
private val basePageDao: BasePageDao, private val pageDao: PageDao,
private val viewModelScope: CoroutineScope private val viewModelScope: CoroutineScope
) : SideEffect<Unit> { ) : SideEffect<Unit> {
@Inject lateinit var dialogShower: DialogShower @Inject lateinit var dialogShower: DialogShower
@ -43,7 +43,7 @@ data class ShowDeleteBookmarksDialog(
activity.cachedComponent.inject(this) activity.cachedComponent.inject(this)
dialogShower.show( dialogShower.show(
if (state.isInSelectionState) DeleteSelectedBookmarks else DeleteAllBookmarks, if (state.isInSelectionState) DeleteSelectedBookmarks else DeleteAllBookmarks,
{ effects.offer(DeletePageItems(state, basePageDao, viewModelScope)) } { effects.offer(DeletePageItems(state, pageDao, viewModelScope)) }
) )
} }
} }

View File

@ -62,7 +62,7 @@ class HistoryViewModel @Inject constructor(
state: HistoryState, state: HistoryState,
viewModelScope: CoroutineScope viewModelScope: CoroutineScope
) = ) =
ShowDeleteHistoryDialog(effects, state, basePageDao, viewModelScope) ShowDeleteHistoryDialog(effects, state, pageDao, viewModelScope)
override fun deselectAllPages(state: HistoryState): HistoryState = override fun deselectAllPages(state: HistoryState): HistoryState =
state.copy(pageItems = state.pageItems.map { it.copy(isSelected = false) }) state.copy(pageItems = state.pageItems.map { it.copy(isSelected = false) })

View File

@ -22,7 +22,7 @@ import androidx.appcompat.app.AppCompatActivity
import io.reactivex.processors.PublishProcessor import io.reactivex.processors.PublishProcessor
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import org.kiwix.kiwixmobile.core.base.SideEffect import org.kiwix.kiwixmobile.core.base.SideEffect
import org.kiwix.kiwixmobile.core.dao.BasePageDao import org.kiwix.kiwixmobile.core.dao.PageDao
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.cachedComponent import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.cachedComponent
import org.kiwix.kiwixmobile.core.page.history.viewmodel.HistoryState import org.kiwix.kiwixmobile.core.page.history.viewmodel.HistoryState
import org.kiwix.kiwixmobile.core.page.viewmodel.effects.DeletePageItems import org.kiwix.kiwixmobile.core.page.viewmodel.effects.DeletePageItems
@ -34,14 +34,14 @@ import javax.inject.Inject
data class ShowDeleteHistoryDialog( data class ShowDeleteHistoryDialog(
private val effects: PublishProcessor<SideEffect<*>>, private val effects: PublishProcessor<SideEffect<*>>,
private val state: HistoryState, private val state: HistoryState,
private val basePageDao: BasePageDao, private val pageDao: PageDao,
private val viewModelScope: CoroutineScope private val viewModelScope: CoroutineScope
) : SideEffect<Unit> { ) : SideEffect<Unit> {
@Inject lateinit var dialogShower: DialogShower @Inject lateinit var dialogShower: DialogShower
override fun invokeWith(activity: AppCompatActivity) { override fun invokeWith(activity: AppCompatActivity) {
activity.cachedComponent.inject(this) activity.cachedComponent.inject(this)
dialogShower.show(if (state.isInSelectionState) DeleteSelectedHistory else DeleteAllHistory, { dialogShower.show(if (state.isInSelectionState) DeleteSelectedHistory else DeleteAllHistory, {
effects.offer(DeletePageItems(state, basePageDao, viewModelScope)) effects.offer(DeletePageItems(state, pageDao, viewModelScope))
}) })
} }
} }

View File

@ -67,7 +67,7 @@ class NotesViewModel @Inject constructor(
state.copy(pageItems = state.pageItems.map { it.copy(isSelected = false) }) state.copy(pageItems = state.pageItems.map { it.copy(isSelected = false) })
override fun createDeletePageDialogEffect(state: NotesState, viewModelScope: CoroutineScope) = override fun createDeletePageDialogEffect(state: NotesState, viewModelScope: CoroutineScope) =
ShowDeleteNotesDialog(effects, state, basePageDao, viewModelScope) ShowDeleteNotesDialog(effects, state, pageDao, viewModelScope)
override fun onItemClick(page: Page) = override fun onItemClick(page: Page) =
ShowOpenNoteDialog(effects, page, zimReaderContainer) ShowOpenNoteDialog(effects, page, zimReaderContainer)

View File

@ -22,7 +22,7 @@ import androidx.appcompat.app.AppCompatActivity
import io.reactivex.processors.PublishProcessor import io.reactivex.processors.PublishProcessor
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import org.kiwix.kiwixmobile.core.base.SideEffect import org.kiwix.kiwixmobile.core.base.SideEffect
import org.kiwix.kiwixmobile.core.dao.BasePageDao import org.kiwix.kiwixmobile.core.dao.PageDao
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.cachedComponent import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.cachedComponent
import org.kiwix.kiwixmobile.core.page.notes.viewmodel.NotesState import org.kiwix.kiwixmobile.core.page.notes.viewmodel.NotesState
import org.kiwix.kiwixmobile.core.page.viewmodel.effects.DeletePageItems import org.kiwix.kiwixmobile.core.page.viewmodel.effects.DeletePageItems
@ -35,7 +35,7 @@ import javax.inject.Inject
data class ShowDeleteNotesDialog( data class ShowDeleteNotesDialog(
private val effects: PublishProcessor<SideEffect<*>>, private val effects: PublishProcessor<SideEffect<*>>,
private val state: NotesState, private val state: NotesState,
private val basePageDao: BasePageDao, private val pageDao: PageDao,
private val viewModelScope: CoroutineScope private val viewModelScope: CoroutineScope
) : SideEffect<Unit> { ) : SideEffect<Unit> {
@Inject lateinit var dialogShower: DialogShower @Inject lateinit var dialogShower: DialogShower
@ -45,7 +45,7 @@ data class ShowDeleteNotesDialog(
dialogShower.show( dialogShower.show(
if (state.isInSelectionState) DeleteSelectedNotes else DeleteAllNotes, if (state.isInSelectionState) DeleteSelectedNotes else DeleteAllNotes,
{ {
effects.offer(DeletePageItems(state, basePageDao, viewModelScope)) effects.offer(DeletePageItems(state, pageDao, viewModelScope))
} }
) )
} }

View File

@ -26,11 +26,8 @@ import io.reactivex.disposables.Disposable
import io.reactivex.processors.PublishProcessor import io.reactivex.processors.PublishProcessor
import io.reactivex.schedulers.Schedulers import io.reactivex.schedulers.Schedulers
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.rx2.asFlowable
import org.kiwix.kiwixmobile.core.base.SideEffect import org.kiwix.kiwixmobile.core.base.SideEffect
import org.kiwix.kiwixmobile.core.dao.BasePageDao
import org.kiwix.kiwixmobile.core.dao.PageDao import org.kiwix.kiwixmobile.core.dao.PageDao
import org.kiwix.kiwixmobile.core.dao.PageRoomDao
import org.kiwix.kiwixmobile.core.page.adapter.Page import org.kiwix.kiwixmobile.core.page.adapter.Page
import org.kiwix.kiwixmobile.core.page.viewmodel.Action.Exit import org.kiwix.kiwixmobile.core.page.viewmodel.Action.Exit
import org.kiwix.kiwixmobile.core.page.viewmodel.Action.ExitActionModeMenu import org.kiwix.kiwixmobile.core.page.viewmodel.Action.ExitActionModeMenu
@ -47,7 +44,7 @@ import org.kiwix.kiwixmobile.core.search.viewmodel.effects.PopFragmentBackstack
import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil
abstract class PageViewModel<T : Page, S : PageState<T>>( abstract class PageViewModel<T : Page, S : PageState<T>>(
protected val basePageDao: BasePageDao, protected val pageDao: PageDao,
val sharedPreferenceUtil: SharedPreferenceUtil, val sharedPreferenceUtil: SharedPreferenceUtil,
val zimReaderContainer: ZimReaderContainer val zimReaderContainer: ZimReaderContainer
) : ViewModel() { ) : ViewModel() {
@ -75,23 +72,11 @@ abstract class PageViewModel<T : Page, S : PageState<T>>(
.subscribe(state::postValue, Throwable::printStackTrace) .subscribe(state::postValue, Throwable::printStackTrace)
protected fun addDisposablesToCompositeDisposable() { protected fun addDisposablesToCompositeDisposable() {
when (basePageDao) { compositeDisposable.addAll(
is PageDao -> { viewStateReducer(),
compositeDisposable.addAll( pageDao.pages().subscribeOn(Schedulers.io())
viewStateReducer(), .subscribe({ actions.offer(UpdatePages(it)) }, Throwable::printStackTrace)
basePageDao.pages().subscribeOn(Schedulers.io()) )
.subscribe({ actions.offer(UpdatePages(it)) }, Throwable::printStackTrace)
)
}
is PageRoomDao -> {
compositeDisposable.addAll(
viewStateReducer(),
basePageDao.pages().asFlowable().subscribeOn(Schedulers.io())
.subscribe({ actions.offer(UpdatePages(it)) }, Throwable::printStackTrace)
)
}
}
} }
private fun reduce(action: Action, state: S): S = when (action) { private fun reduce(action: Action, state: S): S = when (action) {

View File

@ -23,21 +23,21 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.kiwix.kiwixmobile.core.base.SideEffect import org.kiwix.kiwixmobile.core.base.SideEffect
import org.kiwix.kiwixmobile.core.dao.BasePageDao import org.kiwix.kiwixmobile.core.dao.PageDao
import org.kiwix.kiwixmobile.core.page.adapter.Page import org.kiwix.kiwixmobile.core.page.adapter.Page
import org.kiwix.kiwixmobile.core.page.viewmodel.PageState import org.kiwix.kiwixmobile.core.page.viewmodel.PageState
data class DeletePageItems( data class DeletePageItems(
private val state: PageState<*>, private val state: PageState<*>,
private val basePageDao: BasePageDao, private val pageDao: PageDao,
private val viewModelScope: CoroutineScope private val viewModelScope: CoroutineScope
) : SideEffect<Unit> { ) : SideEffect<Unit> {
override fun invokeWith(activity: AppCompatActivity) { override fun invokeWith(activity: AppCompatActivity) {
viewModelScope.launch(Dispatchers.IO) { viewModelScope.launch(Dispatchers.IO) {
if (state.isInSelectionState) { if (state.isInSelectionState) {
basePageDao.deletePages(state.pageItems.filter(Page::isSelected)) pageDao.deletePages(state.pageItems.filter(Page::isSelected))
} else { } else {
basePageDao.deletePages(state.pageItems) pageDao.deletePages(state.pageItems)
} }
} }
} }

View File

@ -4,12 +4,11 @@ import io.mockk.clearAllMocks
import io.mockk.every import io.mockk.every
import io.mockk.mockk import io.mockk.mockk
import io.reactivex.plugins.RxJavaPlugins import io.reactivex.plugins.RxJavaPlugins
import io.reactivex.processors.PublishProcessor
import io.reactivex.schedulers.Schedulers import io.reactivex.schedulers.Schedulers
import io.reactivex.schedulers.TestScheduler import io.reactivex.schedulers.TestScheduler
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.test.runTest import kotlinx.coroutines.test.runTest
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.BeforeEach
@ -44,8 +43,8 @@ internal class HistoryViewModelTest {
RxJavaPlugins.setIoSchedulerHandler { Schedulers.trampoline() } RxJavaPlugins.setIoSchedulerHandler { Schedulers.trampoline() }
} }
private val itemsFromDb: Flow<List<Page>> = private val itemsFromDb: PublishProcessor<List<Page>> =
flow { } PublishProcessor.create()
@BeforeEach @BeforeEach
fun init() { fun init() {