Language Room migration completed

This commit is contained in:
Gouri Panda 2023-01-04 22:17:07 +05:30 committed by Kelson
parent 6ce88c0e77
commit 2aa87e9487
12 changed files with 237 additions and 15 deletions

View File

@ -0,0 +1,97 @@
/*
* Kiwix Android
* Copyright (c) 2023 Kiwix <android.kiwix.org>
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package org.kiwix.kiwixmobile.data.local.dao
import android.content.Context
import androidx.room.Room
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import io.mockk.mockk
import kotlinx.coroutines.runBlocking
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.junit.runner.RunWith
import org.kiwix.kiwixmobile.core.dao.LanguageRoomDao
import org.kiwix.kiwixmobile.core.dao.entities.LanguageRoomEntity
import org.kiwix.kiwixmobile.core.data.local.KiwixRoomDatabase
import org.kiwix.kiwixmobile.core.zim_manager.Language
import java.io.IOException
@RunWith(AndroidJUnit4::class)
class LanguageRoomDaoTest {
private lateinit var languageRoomDao: LanguageRoomDao
private lateinit var db: KiwixRoomDatabase
@Test
@Throws(IOException::class)
fun test_inserting_a_language() = runBlocking {
val context = ApplicationProvider.getApplicationContext<Context>()
db = Room.inMemoryDatabaseBuilder(
context, KiwixRoomDatabase::class.java
).build()
languageRoomDao = db.languageRoomDao()
val language: Language = mockk()
languageRoomDao.insert(LanguageRoomEntity(language))
Assertions.assertEquals(1, languageRoomDao.languages().count())
}
@Test
@Throws(IOException::class)
fun test_inserting_multiple_language() = runBlocking {
val context = ApplicationProvider.getApplicationContext<Context>()
db = Room.inMemoryDatabaseBuilder(
context, KiwixRoomDatabase::class.java
).build()
languageRoomDao = db.languageRoomDao()
val language: Language = mockk()
val language2: Language = mockk()
val language3: Language = mockk()
val language4: Language = mockk()
val language5: Language = mockk()
val languageLists = listOf(
language, language2, language3, language4, language5
)
languageRoomDao.insert(languageLists)
Assertions.assertEquals(5, languageRoomDao.languages().count())
}
@Test
@Throws(IOException::class)
fun test_deleting_multiple_language() = runBlocking {
val context = ApplicationProvider.getApplicationContext<Context>()
db = Room.inMemoryDatabaseBuilder(
context, KiwixRoomDatabase::class.java
).build()
languageRoomDao = db.languageRoomDao()
val language: Language = mockk()
val language2: Language = mockk()
val language3: Language = mockk()
val language4: Language = mockk()
val language5: Language = mockk()
val languageLists = listOf(
language, language2, language3, language4, language5
)
languageRoomDao.insert(languageLists)
languageRoomDao.deleteLanguages()
Assertions.assertEquals(0, languageRoomDao.languages().count())
}
}

View File

@ -23,7 +23,7 @@ import androidx.lifecycle.ViewModel
import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.CompositeDisposable
import io.reactivex.processors.PublishProcessor import io.reactivex.processors.PublishProcessor
import org.kiwix.kiwixmobile.core.base.SideEffect import org.kiwix.kiwixmobile.core.base.SideEffect
import org.kiwix.kiwixmobile.core.dao.NewLanguagesDao import org.kiwix.kiwixmobile.core.dao.LanguageRoomDao
import org.kiwix.kiwixmobile.language.adapter.LanguageListItem.LanguageItem import org.kiwix.kiwixmobile.language.adapter.LanguageListItem.LanguageItem
import org.kiwix.kiwixmobile.language.viewmodel.Action.Filter import org.kiwix.kiwixmobile.language.viewmodel.Action.Filter
import org.kiwix.kiwixmobile.language.viewmodel.Action.SaveAll import org.kiwix.kiwixmobile.language.viewmodel.Action.SaveAll
@ -35,7 +35,7 @@ import org.kiwix.kiwixmobile.language.viewmodel.State.Saving
import javax.inject.Inject import javax.inject.Inject
class LanguageViewModel @Inject constructor( class LanguageViewModel @Inject constructor(
private val languageDao: NewLanguagesDao private val languageRoomDao: LanguageRoomDao
) : ViewModel() { ) : ViewModel() {
val state = MutableLiveData<State>().apply { value = Loading } val state = MutableLiveData<State>().apply { value = Loading }
@ -49,7 +49,7 @@ class LanguageViewModel @Inject constructor(
actions.map { reduce(it, state.value!!) } actions.map { reduce(it, state.value!!) }
.distinctUntilChanged() .distinctUntilChanged()
.subscribe(state::postValue, Throwable::printStackTrace), .subscribe(state::postValue, Throwable::printStackTrace),
languageDao.languages().filter { it.isNotEmpty() } languageRoomDao.languages().filter { it.isNotEmpty() }
.subscribe( .subscribe(
{ actions.offer(UpdateLanguages(it)) }, { actions.offer(UpdateLanguages(it)) },
Throwable::printStackTrace Throwable::printStackTrace
@ -93,7 +93,7 @@ class LanguageViewModel @Inject constructor(
private fun saveAll(currentState: Content): State { private fun saveAll(currentState: Content): State {
effects.offer( effects.offer(
SaveLanguagesAndFinish( SaveLanguagesAndFinish(
currentState.items, languageDao currentState.items, languageRoomDao
) )
) )
return Saving return Saving

View File

@ -21,16 +21,16 @@ import androidx.appcompat.app.AppCompatActivity
import io.reactivex.Flowable import io.reactivex.Flowable
import io.reactivex.schedulers.Schedulers import io.reactivex.schedulers.Schedulers
import org.kiwix.kiwixmobile.core.base.SideEffect import org.kiwix.kiwixmobile.core.base.SideEffect
import org.kiwix.kiwixmobile.core.dao.NewLanguagesDao import org.kiwix.kiwixmobile.core.dao.LanguageRoomDao
import org.kiwix.kiwixmobile.core.zim_manager.Language import org.kiwix.kiwixmobile.core.zim_manager.Language
data class SaveLanguagesAndFinish( data class SaveLanguagesAndFinish(
val languages: List<Language>, val languages: List<Language>,
val languageDao: NewLanguagesDao val languageRoomDao: LanguageRoomDao
) : SideEffect<Unit> { ) : SideEffect<Unit> {
override fun invokeWith(activity: AppCompatActivity) { override fun invokeWith(activity: AppCompatActivity) {
Flowable.fromCallable { languageDao.insert(languages) } Flowable.fromCallable { languageRoomDao.insert(languages) }
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.subscribe({ .subscribe({
activity.onBackPressed() activity.onBackPressed()

View File

@ -35,8 +35,8 @@ import org.kiwix.kiwixmobile.core.R
import org.kiwix.kiwixmobile.core.StorageObserver import org.kiwix.kiwixmobile.core.StorageObserver
import org.kiwix.kiwixmobile.core.base.SideEffect import org.kiwix.kiwixmobile.core.base.SideEffect
import org.kiwix.kiwixmobile.core.dao.FetchDownloadDao import org.kiwix.kiwixmobile.core.dao.FetchDownloadDao
import org.kiwix.kiwixmobile.core.dao.LanguageRoomDao
import org.kiwix.kiwixmobile.core.dao.NewBookDao import org.kiwix.kiwixmobile.core.dao.NewBookDao
import org.kiwix.kiwixmobile.core.dao.NewLanguagesDao
import org.kiwix.kiwixmobile.core.data.DataSource import org.kiwix.kiwixmobile.core.data.DataSource
import org.kiwix.kiwixmobile.core.data.remote.KiwixService import org.kiwix.kiwixmobile.core.data.remote.KiwixService
import org.kiwix.kiwixmobile.core.downloader.model.DownloadModel import org.kiwix.kiwixmobile.core.downloader.model.DownloadModel
@ -77,10 +77,11 @@ import java.util.Locale
import java.util.concurrent.TimeUnit.MILLISECONDS import java.util.concurrent.TimeUnit.MILLISECONDS
import javax.inject.Inject import javax.inject.Inject
@Suppress("LongParameterList")
class ZimManageViewModel @Inject constructor( class ZimManageViewModel @Inject constructor(
private val downloadDao: FetchDownloadDao, private val downloadDao: FetchDownloadDao,
private val bookDao: NewBookDao, private val bookDao: NewBookDao,
private val languageDao: NewLanguagesDao, private val languageRoomDao: LanguageRoomDao,
private val storageObserver: StorageObserver, private val storageObserver: StorageObserver,
private val kiwixService: KiwixService, private val kiwixService: KiwixService,
private val context: Application, private val context: Application,
@ -143,7 +144,7 @@ class ZimManageViewModel @Inject constructor(
val downloads = downloadDao.downloads() val downloads = downloadDao.downloads()
val booksFromDao = books() val booksFromDao = books()
val networkLibrary = PublishProcessor.create<LibraryNetworkEntity>() val networkLibrary = PublishProcessor.create<LibraryNetworkEntity>()
val languages = languageDao.languages() val languages = languageRoomDao.languages()
return arrayOf( return arrayOf(
updateBookItems(), updateBookItems(),
checkFileSystemForBooksOnRequest(booksFromDao), checkFileSystemForBooksOnRequest(booksFromDao),
@ -301,7 +302,7 @@ class ZimManageViewModel @Inject constructor(
.map { it.sortedBy(Language::language) } .map { it.sortedBy(Language::language) }
.filter(List<Language>::isNotEmpty) .filter(List<Language>::isNotEmpty)
.subscribe( .subscribe(
languageDao::insert, languageRoomDao::insert,
Throwable::printStackTrace Throwable::printStackTrace
) )

View File

@ -0,0 +1,63 @@
/*
* Kiwix Android
* Copyright (c) 2023 Kiwix <android.kiwix.org>
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package org.kiwix.kiwixmobile.core.dao
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.Query
import androidx.room.Transaction
import androidx.room.TypeConverter
import io.reactivex.Flowable
import org.kiwix.kiwixmobile.core.dao.entities.LanguageRoomEntity
import org.kiwix.kiwixmobile.core.zim_manager.Language
import java.util.Locale
@Dao
abstract class LanguageRoomDao {
@Query("SELECT * FROM LanguageRoomEntity")
abstract fun languageEntityList(): Flowable<List<LanguageRoomEntity>>
fun languages(): Flowable<List<Language>> = languageEntityList().map {
it.map(LanguageRoomEntity::toLanguageModel)
}
@Query("DELETE FROM LanguageRoomEntity")
abstract fun deleteLanguages()
@Insert
abstract fun insert(languageRoomEntity: LanguageRoomEntity)
@Transaction
open fun insert(languages: List<Language>) {
deleteLanguages()
languages.map {
insert(LanguageRoomEntity(it))
}
}
}
class StringToLocalConverterDao {
@TypeConverter
fun convertToDatabaseValue(entityProperty: Locale?): String =
entityProperty?.isO3Language ?: Locale.ENGLISH.isO3Language
@TypeConverter
fun convertToEntityProperty(databaseValue: String?): Locale =
databaseValue?.let(::Locale) ?: Locale.ENGLISH
}

View File

@ -28,6 +28,7 @@ import org.kiwix.kiwixmobile.core.zim_manager.Language
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Singleton import javax.inject.Singleton
@Deprecated("Replaced with the Room")
@Singleton @Singleton
class NewLanguagesDao @Inject constructor(private val box: Box<LanguageEntity>) { class NewLanguagesDao @Inject constructor(private val box: Box<LanguageEntity>) {
fun languages() = box.asFlowable() fun languages() = box.asFlowable()

View File

@ -25,6 +25,7 @@ import io.objectbox.converter.PropertyConverter
import org.kiwix.kiwixmobile.core.zim_manager.Language import org.kiwix.kiwixmobile.core.zim_manager.Language
import java.util.Locale import java.util.Locale
@Deprecated("Replaced with the Room")
@Entity @Entity
data class LanguageEntity( data class LanguageEntity(
@Id var id: Long = 0, @Id var id: Long = 0,

View File

@ -0,0 +1,44 @@
/*
* Kiwix Android
* Copyright (c) 2023 Kiwix <android.kiwix.org>
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package org.kiwix.kiwixmobile.core.dao.entities
import androidx.room.Entity
import androidx.room.PrimaryKey
import org.kiwix.kiwixmobile.core.zim_manager.Language
import java.util.Locale
@Entity
data class LanguageRoomEntity(
@PrimaryKey(autoGenerate = true)
var id: Long = 0,
val locale: Locale = Locale.ENGLISH,
val active: Boolean = false,
val occurencesOfLanguage: Int = 0
) {
constructor(language: Language) : this(
0,
Locale(language.languageCode),
language.active,
language.occurencesOfLanguage
)
fun toLanguageModel() =
Language(locale, active, occurencesOfLanguage, id)
}

View File

@ -23,9 +23,9 @@ import io.reactivex.Flowable
import io.reactivex.Scheduler import io.reactivex.Scheduler
import io.reactivex.Single import io.reactivex.Single
import org.kiwix.kiwixmobile.core.dao.HistoryDao import org.kiwix.kiwixmobile.core.dao.HistoryDao
import org.kiwix.kiwixmobile.core.dao.LanguageRoomDao
import org.kiwix.kiwixmobile.core.dao.NewBookDao import org.kiwix.kiwixmobile.core.dao.NewBookDao
import org.kiwix.kiwixmobile.core.dao.NewBookmarksDao import org.kiwix.kiwixmobile.core.dao.NewBookmarksDao
import org.kiwix.kiwixmobile.core.dao.NewLanguagesDao
import org.kiwix.kiwixmobile.core.dao.NewRecentSearchRoomDao import org.kiwix.kiwixmobile.core.dao.NewRecentSearchRoomDao
import org.kiwix.kiwixmobile.core.dao.NotesRoomDao import org.kiwix.kiwixmobile.core.dao.NotesRoomDao
import org.kiwix.kiwixmobile.core.di.qualifiers.IO import org.kiwix.kiwixmobile.core.di.qualifiers.IO
@ -56,7 +56,7 @@ class Repository @Inject internal constructor(
private val bookmarksDao: NewBookmarksDao, private val bookmarksDao: NewBookmarksDao,
private val historyDao: HistoryDao, private val historyDao: HistoryDao,
private val notesRoomDao: NotesRoomDao, private val notesRoomDao: NotesRoomDao,
private val languageDao: NewLanguagesDao, private val languageRoomDao: LanguageRoomDao,
private val recentSearchDao: NewRecentSearchRoomDao, private val recentSearchDao: NewRecentSearchRoomDao,
private val zimReaderContainer: ZimReaderContainer private val zimReaderContainer: ZimReaderContainer
) : DataSource { ) : DataSource {
@ -86,7 +86,7 @@ class Repository @Inject internal constructor(
.subscribeOn(io) .subscribeOn(io)
override fun saveLanguages(languages: List<Language>) = override fun saveLanguages(languages: List<Language>) =
Completable.fromAction { languageDao.insert(languages) } Completable.fromAction { languageRoomDao.insert(languages) }
.subscribeOn(io) .subscribeOn(io)
override fun saveHistory(history: HistoryItem) = override fun saveHistory(history: HistoryItem) =

View File

@ -22,18 +22,27 @@ import android.content.Context
import androidx.room.Database import androidx.room.Database
import androidx.room.Room import androidx.room.Room
import androidx.room.RoomDatabase import androidx.room.RoomDatabase
import androidx.room.TypeConverters
import io.objectbox.BoxStore import io.objectbox.BoxStore
import io.objectbox.kotlin.boxFor import io.objectbox.kotlin.boxFor
import org.kiwix.kiwixmobile.core.dao.LanguageRoomDao
import org.kiwix.kiwixmobile.core.dao.NewRecentSearchRoomDao import org.kiwix.kiwixmobile.core.dao.NewRecentSearchRoomDao
import org.kiwix.kiwixmobile.core.dao.NotesRoomDao import org.kiwix.kiwixmobile.core.dao.NotesRoomDao
import org.kiwix.kiwixmobile.core.dao.StringToLocalConverterDao
import org.kiwix.kiwixmobile.core.dao.entities.LanguageRoomEntity
import org.kiwix.kiwixmobile.core.dao.entities.NotesRoomEntity import org.kiwix.kiwixmobile.core.dao.entities.NotesRoomEntity
import org.kiwix.kiwixmobile.core.dao.entities.RecentSearchRoomEntity import org.kiwix.kiwixmobile.core.dao.entities.RecentSearchRoomEntity
@Suppress("UnnecessaryAbstractClass") @Suppress("UnnecessaryAbstractClass")
@Database(entities = [RecentSearchRoomEntity::class, NotesRoomEntity::class], version = 2) @Database(
entities = [RecentSearchRoomEntity::class, NotesRoomEntity::class, LanguageRoomEntity::class],
version = 3
)
@TypeConverters(StringToLocalConverterDao::class)
abstract class KiwixRoomDatabase : RoomDatabase() { abstract class KiwixRoomDatabase : RoomDatabase() {
abstract fun newRecentSearchRoomDao(): NewRecentSearchRoomDao abstract fun newRecentSearchRoomDao(): NewRecentSearchRoomDao
abstract fun noteRoomDao(): NotesRoomDao abstract fun noteRoomDao(): NotesRoomDao
abstract fun languageRoomDao(): LanguageRoomDao
companion object { companion object {
private var db: KiwixRoomDatabase? = null private var db: KiwixRoomDatabase? = null

View File

@ -28,6 +28,7 @@ import org.kiwix.kiwixmobile.core.CoreApp
import org.kiwix.kiwixmobile.core.StorageObserver import org.kiwix.kiwixmobile.core.StorageObserver
import org.kiwix.kiwixmobile.core.dao.FetchDownloadDao import org.kiwix.kiwixmobile.core.dao.FetchDownloadDao
import org.kiwix.kiwixmobile.core.dao.HistoryDao import org.kiwix.kiwixmobile.core.dao.HistoryDao
import org.kiwix.kiwixmobile.core.dao.LanguageRoomDao
import org.kiwix.kiwixmobile.core.dao.NewBookDao import org.kiwix.kiwixmobile.core.dao.NewBookDao
import org.kiwix.kiwixmobile.core.dao.NewBookmarksDao import org.kiwix.kiwixmobile.core.dao.NewBookmarksDao
import org.kiwix.kiwixmobile.core.dao.NewLanguagesDao import org.kiwix.kiwixmobile.core.dao.NewLanguagesDao
@ -93,6 +94,7 @@ interface CoreComponent {
fun noteDao(): NewNoteDao fun noteDao(): NewNoteDao
fun newLanguagesDao(): NewLanguagesDao fun newLanguagesDao(): NewLanguagesDao
fun recentSearchDao(): NewRecentSearchDao fun recentSearchDao(): NewRecentSearchDao
fun languageRoomDao(): LanguageRoomDao
fun recentSearchRoomDao(): NewRecentSearchRoomDao fun recentSearchRoomDao(): NewRecentSearchRoomDao
fun noteRoomDao(): NotesRoomDao fun noteRoomDao(): NotesRoomDao
fun newBookmarksDao(): NewBookmarksDao fun newBookmarksDao(): NewBookmarksDao

View File

@ -92,4 +92,8 @@ open class DatabaseModule {
@Singleton @Singleton
@Provides @Provides
fun provideNoteRoomDao(db: KiwixRoomDatabase) = db.noteRoomDao() fun provideNoteRoomDao(db: KiwixRoomDatabase) = db.noteRoomDao()
@Singleton
@Provides
fun provideLanguageRoomDao(db: KiwixRoomDatabase) = db.languageRoomDao()
} }