feat(internal): Implement a stats table in the app database

This commit is contained in:
Nishant Mishra
2025-07-09 20:59:37 +05:30
parent ed21c09d86
commit 023f127181
6 changed files with 139 additions and 8 deletions

View File

@@ -1,22 +1,30 @@
/*
* Copyright (c) 2025 Nishant Mishra
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.nsh07.pomodoro.data
import android.content.Context
interface AppContainer {
val appPreferencesRepository: AppPreferenceRepository
val appStatRepository: AppStatRepository
val appTimerRepository: AppTimerRepository
}
class DefaultAppContainer(context: Context) : AppContainer {
override val appPreferencesRepository: AppPreferenceRepository by lazy {
AppPreferenceRepository(
AppDatabase.getDatabase(context).preferenceDao()
)
AppPreferenceRepository(AppDatabase.getDatabase(context).preferenceDao())
}
override val appTimerRepository: AppTimerRepository by lazy {
AppTimerRepository()
override val appStatRepository: AppStatRepository by lazy {
AppStatRepository(AppDatabase.getDatabase(context).statDao())
}
override val appTimerRepository: AppTimerRepository by lazy { AppTimerRepository() }
}

View File

@@ -1,3 +1,10 @@
/*
* Copyright (c) 2025 Nishant Mishra
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.nsh07.pomodoro.data
import android.content.Context
@@ -6,12 +13,13 @@ import androidx.room.Room
import androidx.room.RoomDatabase
@Database(
entities = [IntPreference::class],
entities = [IntPreference::class, Stat::class],
version = 1
)
abstract class AppDatabase : RoomDatabase() {
abstract fun preferenceDao(): PreferenceDao
abstract fun statDao(): StatDao
companion object {

View File

@@ -1,13 +1,20 @@
/*
* Copyright (c) 2025 Nishant Mishra
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.nsh07.pomodoro.data
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.OnConflictStrategy.Companion.REPLACE
import androidx.room.Query
@Dao
interface PreferenceDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
@Insert(onConflict = REPLACE)
suspend fun insertIntPreference(preference: IntPreference)
@Query("DELETE FROM int_preference")

View File

@@ -0,0 +1,19 @@
/*
* Copyright (c) 2025 Nishant Mishra
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.nsh07.pomodoro.data
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "stat")
data class Stat(
@PrimaryKey
val date: String,
val focusTime: Int,
val breakTime: Int
)

View File

@@ -0,0 +1,35 @@
/*
* Copyright (c) 2025 Nishant Mishra
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.nsh07.pomodoro.data
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy.Companion.REPLACE
import androidx.room.Query
import kotlinx.coroutines.flow.Flow
@Dao
interface StatDao {
@Insert(onConflict = REPLACE)
suspend fun insertStat(stat: Stat)
@Query("UPDATE stat SET focusTime = focusTime + :focusTime WHERE date = :date")
suspend fun addFocusTime(date: String, focusTime: Int)
@Query("UPDATE stat SET breakTime = breakTime + :breakTime WHERE date = :date")
suspend fun addBreakTime(date: String, breakTime: Int)
@Query("SELECT * FROM stat WHERE date = :date")
fun getStat(date: String): Flow<Stat?>
@Query("SELECT * FROM stat")
fun getStats(): Flow<List<Stat>>
@Query("SELECT EXISTS (SELECT * FROM stat WHERE date = :date)")
suspend fun statExists(date: String): Boolean
}

View File

@@ -0,0 +1,54 @@
/*
* Copyright (c) 2025 Nishant Mishra
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.nsh07.pomodoro.data
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.withContext
import java.time.LocalDate
interface StatRepository {
suspend fun addFocusTime(focusTime: Int)
suspend fun addBreakTime(breakTime: Int)
fun getTodayStat(): Flow<Stat?>
fun getAllStats(): Flow<List<Stat>>
}
class AppStatRepository(
private val statDao: StatDao,
private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO
) : StatRepository {
override suspend fun addFocusTime(focusTime: Int) = withContext(ioDispatcher) {
val currentDate = LocalDate.now().toString()
if (statDao.statExists(currentDate)) {
statDao.addFocusTime(currentDate, focusTime)
} else {
statDao.insertStat(Stat(currentDate, focusTime, 0))
}
}
override suspend fun addBreakTime(breakTime: Int) = withContext(ioDispatcher) {
val currentDate = LocalDate.now().toString()
if (statDao.statExists(currentDate)) {
statDao.addBreakTime(currentDate, breakTime)
} else {
statDao.insertStat(Stat(currentDate, 0, breakTime))
}
}
override fun getTodayStat(): Flow<Stat?> {
val currentDate = LocalDate.now().toString()
return statDao.getStat(currentDate)
}
override fun getAllStats(): Flow<List<Stat>> = statDao.getStats()
}