FreshRSSDabatabase.kt 2.81 KB
Newer Older
Christophe Henry's avatar
Christophe Henry committed
1
package fr.chenry.android.freshrss.store.database
Christophe Henry's avatar
Christophe Henry committed
2

Christophe Henry's avatar
Christophe Henry committed
3
import android.database.sqlite.SQLiteConstraintException
Christophe Henry's avatar
Christophe Henry committed
4 5 6
import androidx.room.*
import fr.chenry.android.freshrss.FreshRSSApplication
import fr.chenry.android.freshrss.R
Christophe Henry's avatar
Christophe Henry committed
7 8 9 10
import fr.chenry.android.freshrss.store.api.models.StreamId
import fr.chenry.android.freshrss.store.database.models.*
import fr.chenry.android.freshrss.store.database.models.ReadStatus.READ
import fr.chenry.android.freshrss.store.database.models.ReadStatus.UNREAD
Christophe Henry's avatar
Christophe Henry committed
11 12 13 14
import fr.chenry.android.freshrss.utils.getOrDefault
import nl.komponents.kovenant.task
import kotlin.reflect.KProperty

Christophe Henry's avatar
Christophe Henry committed
15 16
@Database(version = 1, entities = [Account::class, Article::class], exportSchema = false)
@TypeConverters(Converters::class)
Christophe Henry's avatar
Christophe Henry committed
17 18 19 20 21 22
abstract class FreshRSSDabatabase: RoomDatabase() {
    private val authTokensDelegate = AuthTokensDelegate()
    var account: Account by authTokensDelegate
    val authTokensExistInDB get() = authTokensDelegate.isInitialized

    protected abstract fun getAuthTokensDAO(): AuthTokensDAO
Christophe Henry's avatar
Christophe Henry committed
23 24 25 26 27 28 29 30 31
    protected abstract fun getArticlesDAO(): ArticlesDAO

    fun getArticleByStreamId(streamId: StreamId) = getArticlesDAO().getByStreamId(streamId)
    fun getArticleById(id: ItemId) = getArticlesDAO().getById(id)
    fun getArticleByStreamIdAndUnread(streamId: StreamId) =
        getArticlesDAO().getByStreamIdAndUnread(streamId, ReadStatus.UNREAD.name)
    fun upsertArticle(article: Article) =
        try {getArticlesDAO().update(article)} catch(_: SQLiteConstraintException) {getArticlesDAO().insert(article)}
    fun insertArticle(article: Article) = getArticlesDAO().forceInsert(article)
Christophe Henry's avatar
Christophe Henry committed
32 33 34 35 36 37 38

    companion object {
        private val dbName by lazy {
            "${FreshRSSApplication.context.getString(R.string.app_name).toLowerCase()}.db"
        }
        val instance by lazy {
            val instance =
Christophe Henry's avatar
Christophe Henry committed
39 40 41
                Room.databaseBuilder(FreshRSSApplication.context, FreshRSSDabatabase::class.java, dbName)
                    .fallbackToDestructiveMigration()
                    .build()
Christophe Henry's avatar
Christophe Henry committed
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
            instance.authTokensDelegate.fetchAuthtokensFromDB()
            instance
        }
    }

    inner class AuthTokensDelegate {
        private lateinit var cachedAccount: Account
        val isInitialized
            get() = ::cachedAccount.isInitialized

        operator fun getValue(thisRef: Any?, property: KProperty<*>): Account = cachedAccount

        operator fun setValue(thisRef: Any?, property: KProperty<*>, value: Account) {
            cachedAccount = value
            task { getAuthTokensDAO().insert(account) }.getOrDefault(Unit)
        }

        fun fetchAuthtokensFromDB() {
            if(!isInitialized) {
                val authTokensFromDB = task {getAuthTokensDAO().getAuthTokens()[0]}.getOrDefault(null)
                if(authTokensFromDB != null) cachedAccount = authTokensFromDB
            }
        }
    }
Christophe Henry's avatar
Christophe Henry committed
66
}