init
This commit is contained in:
@@ -8,9 +8,11 @@ import androidx.room.Room
|
||||
import androidx.room.RoomDatabase
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
import cc.n0th1ng.tripmoney.data.dao.CategoryDao
|
||||
import cc.n0th1ng.tripmoney.data.dao.ExchangeRateDao
|
||||
import cc.n0th1ng.tripmoney.data.dao.ExpenseDao
|
||||
import cc.n0th1ng.tripmoney.data.dao.TripDao
|
||||
import cc.n0th1ng.tripmoney.data.entity.Category
|
||||
import cc.n0th1ng.tripmoney.data.entity.ExchangeRate
|
||||
import cc.n0th1ng.tripmoney.data.entity.Expense
|
||||
import cc.n0th1ng.tripmoney.data.entity.Trip
|
||||
import cc.n0th1ng.tripmoney.utils.Icons
|
||||
@@ -26,11 +28,12 @@ import java.time.LocalDateTime
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Database(entities = [Trip::class, Expense::class, Category::class], version = 1)
|
||||
@Database(entities = [Trip::class, Expense::class, Category::class, ExchangeRate::class], version = 1)
|
||||
abstract class TripDatabase : RoomDatabase() {
|
||||
abstract fun tripDao(): TripDao
|
||||
abstract fun expenseDao(): ExpenseDao
|
||||
abstract fun categoryDao(): CategoryDao
|
||||
abstract fun exchangeRateDao(): ExchangeRateDao
|
||||
}
|
||||
|
||||
|
||||
@@ -74,6 +77,12 @@ object DatabaseModule {
|
||||
fun provideCategoryDao(database: TripDatabase): CategoryDao {
|
||||
return database.categoryDao()
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideExchangeRateDao(database: TripDatabase): ExchangeRateDao {
|
||||
return database.exchangeRateDao()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package cc.n0th1ng.tripmoney.data.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.Query
|
||||
import androidx.room.Transaction
|
||||
import androidx.room.Upsert
|
||||
import cc.n0th1ng.tripmoney.data.entity.Category
|
||||
import cc.n0th1ng.tripmoney.data.entity.ExchangeRate
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@Dao
|
||||
interface ExchangeRateDao {
|
||||
@Upsert
|
||||
suspend fun insert(exchangeRate: ExchangeRate)
|
||||
|
||||
@Query("SELECT * FROM exchange_rate WHERE id = :id")
|
||||
suspend fun getById(id: String): ExchangeRate?
|
||||
|
||||
@Query("DELETE FROM exchange_rate WHERE DATE(date) < :cutoffDate")
|
||||
suspend fun deleteOldRates(cutoffDate: String)
|
||||
}
|
||||
@@ -16,6 +16,7 @@ interface TripDao {
|
||||
@Query(
|
||||
"""
|
||||
SELECT * FROM trip
|
||||
ORDER BY DATE(trip.start_date) DESC
|
||||
"""
|
||||
)
|
||||
fun tripsPaged(): PagingSource<Int, Trip>
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
package cc.n0th1ng.tripmoney.data.entity
|
||||
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
|
||||
@Entity("exchange_rate")
|
||||
data class ExchangeRate(
|
||||
@PrimaryKey
|
||||
val id: String,
|
||||
val base: String,
|
||||
val target: String,
|
||||
val rate: Double,
|
||||
val date: String
|
||||
) {
|
||||
companion object {
|
||||
fun buildKey(base: String, target: String, date: String): String {
|
||||
return "${base}_${target}_${date}"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package cc.n0th1ng.tripmoney.data.repository
|
||||
|
||||
import android.os.Build
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.annotation.WorkerThread
|
||||
import cc.n0th1ng.tripmoney.data.dao.CategoryDao
|
||||
import cc.n0th1ng.tripmoney.data.dao.ExchangeRateDao
|
||||
import cc.n0th1ng.tripmoney.data.entity.Category
|
||||
import cc.n0th1ng.tripmoney.data.entity.ExchangeRate
|
||||
import cc.n0th1ng.tripmoney.service.ExchangeService
|
||||
import cc.n0th1ng.tripmoney.utils.Currencies
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import java.time.LocalDate
|
||||
import javax.inject.Inject
|
||||
|
||||
class ExchangeRateRepository @Inject constructor(
|
||||
private val exchangeRateDao: ExchangeRateDao,
|
||||
private val exchangeService: ExchangeService
|
||||
) {
|
||||
|
||||
@WorkerThread
|
||||
suspend fun save(exchangeRate: ExchangeRate) {
|
||||
exchangeRateDao.insert(exchangeRate)
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.O)
|
||||
suspend fun getRate(base: Currencies, target: Currencies, date: LocalDate): Double {
|
||||
val id = ExchangeRate.buildKey(base.name, target.name, date.toString())
|
||||
val cachedRate = exchangeRateDao.getById(id)
|
||||
return if (cachedRate != null) {
|
||||
cachedRate.rate
|
||||
} else {
|
||||
val rate = exchangeService.getRate(base, target, date)
|
||||
exchangeRateDao.insert(
|
||||
ExchangeRate(
|
||||
id = id,
|
||||
base = base.name,
|
||||
target = target.name,
|
||||
rate = rate,
|
||||
date = date.toString()
|
||||
)
|
||||
)
|
||||
clearOldRates()
|
||||
rate
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.O)
|
||||
private suspend fun clearOldRates(daysToKeep: Int = 180) {
|
||||
val cutoffDate = LocalDate.now().minusDays(daysToKeep.toLong()).toString()
|
||||
exchangeRateDao.deleteOldRates(cutoffDate)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user