code-style fix, fix db code structure

This commit is contained in:
2026-02-14 13:43:21 +03:00
parent 7dd3358dac
commit 49b5100987
10 changed files with 60 additions and 36 deletions

View File

@@ -2,9 +2,9 @@ package ru.fincode.tsudesk.core.database
import androidx.room.Database import androidx.room.Database
import androidx.room.RoomDatabase import androidx.room.RoomDatabase
import ru.fincode.tsudesk.core.database.schedule.ScheduleDao
import ru.fincode.tsudesk.core.database.schedule.LessonCacheEntity import ru.fincode.tsudesk.core.database.schedule.LessonCacheEntity
import ru.fincode.tsudesk.core.database.schedule.ScheduleCacheEntity import ru.fincode.tsudesk.core.database.schedule.ScheduleCacheEntity
import ru.fincode.tsudesk.core.database.schedule.ScheduleDao
@Database( @Database(
entities = [ entities = [

View File

@@ -0,0 +1,15 @@
package ru.fincode.tsudesk.core.database.builder
import android.content.Context
import androidx.room.Room
import ru.fincode.tsudesk.core.database.AppDatabase
object AppDatabaseBuilder {
private const val DB_NAME = "tsudesk.db"
fun build(context: Context): AppDatabase =
Room.databaseBuilder(context, AppDatabase::class.java, DB_NAME)
.fallbackToDestructiveMigration()
.build()
}

View File

@@ -1,13 +1,13 @@
package ru.fincode.tsudesk.core.database.di package ru.fincode.tsudesk.core.database.di
import android.content.Context import android.content.Context
import androidx.room.Room
import dagger.Module import dagger.Module
import dagger.Provides import dagger.Provides
import dagger.hilt.InstallIn import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent import dagger.hilt.components.SingletonComponent
import ru.fincode.tsudesk.core.database.AppDatabase import ru.fincode.tsudesk.core.database.AppDatabase
import ru.fincode.tsudesk.core.database.builder.AppDatabaseBuilder
import ru.fincode.tsudesk.core.database.schedule.ScheduleDao import ru.fincode.tsudesk.core.database.schedule.ScheduleDao
import javax.inject.Singleton import javax.inject.Singleton
@@ -15,16 +15,12 @@ import javax.inject.Singleton
@InstallIn(SingletonComponent::class) @InstallIn(SingletonComponent::class)
object DatabaseModule { object DatabaseModule {
private const val DB_NAME = "tsudesk.db"
@Provides @Provides
@Singleton @Singleton
fun provideAppDatabase(@ApplicationContext context: Context): AppDatabase = fun provideAppDatabase(@ApplicationContext context: Context): AppDatabase =
Room.databaseBuilder(context, AppDatabase::class.java, DB_NAME) AppDatabaseBuilder.build(context)
.fallbackToDestructiveMigration()
.build()
@Provides @Provides
fun provideScheduleCacheDao(db: AppDatabase): ScheduleDao = fun provideScheduleDao(db: AppDatabase): ScheduleDao =
db.scheduleCacheDao() db.scheduleCacheDao()
} }

View File

@@ -6,4 +6,8 @@ object ScheduleDbConstants {
const val COL_SCHEDULE_KEY = "scheduleKey" const val COL_SCHEDULE_KEY = "scheduleKey"
const val COL_KEY = "key" const val COL_KEY = "key"
const val GROUP_PRE_KEY = "group:"
const val TEACHER_PRE_KEY = "teacher:"
} }

View File

@@ -0,0 +1,13 @@
package ru.fincode.tsudesk.core.database.schedule
object Query {
const val SELECT_LESSON_BY_KEY_QUERY =
"SELECT * FROM lesson_cache WHERE scheduleKey = :key"
const val SELECT_SCHEDULE_BY_KEY_QUERY =
"SELECT * FROM schedule_cache WHERE `key` = :key LIMIT 1"
const val DELETE_LESSON_BY_GROUP_KEY_QUERY =
"DELETE FROM lesson_cache WHERE scheduleKey = :key"
}

View File

@@ -6,48 +6,40 @@ import androidx.room.Insert
import androidx.room.OnConflictStrategy import androidx.room.OnConflictStrategy
import androidx.room.Query import androidx.room.Query
import androidx.room.Transaction import androidx.room.Transaction
import ru.fincode.tsudesk.core.database.schedule.Query.DELETE_LESSON_BY_GROUP_KEY_QUERY
import ru.fincode.tsudesk.core.database.schedule.Query.SELECT_LESSON_BY_KEY_QUERY
import ru.fincode.tsudesk.core.database.schedule.Query.SELECT_SCHEDULE_BY_KEY_QUERY
@Dao @Dao
interface ScheduleDao { interface ScheduleDao {
@Insert(onConflict = OnConflictStrategy.REPLACE) @Insert(onConflict = OnConflictStrategy.Companion.REPLACE)
suspend fun upsertSchedule(schedule: ScheduleCacheEntity) suspend fun upsertSchedule(schedule: ScheduleCacheEntity)
@Insert(onConflict = OnConflictStrategy.REPLACE) @Insert(onConflict = OnConflictStrategy.Companion.REPLACE)
suspend fun insertLessons(lessons: List<LessonCacheEntity>) suspend fun insertLessons(lessons: List<LessonCacheEntity>)
@Query(SELECT_SCHEDULE_BY_KEY_QUERY)
@Query("SELECT * FROM schedule_cache WHERE `key` = :key LIMIT 1")
suspend fun getSchedule(key: String): ScheduleCacheEntity? suspend fun getSchedule(key: String): ScheduleCacheEntity?
@Query("SELECT * FROM lesson_cache WHERE scheduleKey = :key") @Query(SELECT_LESSON_BY_KEY_QUERY)
suspend fun getLessons(key: String): List<LessonCacheEntity> suspend fun getLessons(key: String): List<LessonCacheEntity>
// Bulk delete уроков по ключу — самый простой/эффективный путь в Room это @Query @Query(DELETE_LESSON_BY_GROUP_KEY_QUERY)
@Query("DELETE FROM lesson_cache WHERE scheduleKey = :key")
suspend fun deleteLessonsByKey(key: String) suspend fun deleteLessonsByKey(key: String)
// Удаление schedule_cache без SQL: типобезопасно
@Delete @Delete
suspend fun deleteSchedule(entity: ScheduleCacheEntity) suspend fun deleteSchedule(entity: ScheduleCacheEntity)
/**
* Обновить кэш расписания (header + lessons) атомарно.
*/
@Transaction @Transaction
suspend fun replaceSchedule( suspend fun replaceSchedule(
key: String, key: String, schedule: ScheduleCacheEntity, lessons: List<LessonCacheEntity>
schedule: ScheduleCacheEntity,
lessons: List<LessonCacheEntity>
) { ) {
upsertSchedule(schedule) upsertSchedule(schedule)
deleteLessonsByKey(key) deleteLessonsByKey(key)
insertLessons(lessons) insertLessons(lessons)
} }
/**
* Полная очистка кэша по ключу без прямого DELETE для schedule_cache.
*/
@Transaction @Transaction
suspend fun clearSchedule(key: String) { suspend fun clearSchedule(key: String) {
deleteLessonsByKey(key) deleteLessonsByKey(key)

View File

@@ -19,7 +19,7 @@ class ScheduleRepositoryImpl @Inject constructor(
override suspend fun loadScheduleByGroup(number: String): NetworkResult<ScheduleEntity> { override suspend fun loadScheduleByGroup(number: String): NetworkResult<ScheduleEntity> {
val result = remote.loadScheduleByGroup(number).map(mapper::invoke) val result = remote.loadScheduleByGroup(number).map(mapper::invoke)
if (result is NetworkResult.Success) { if (result is NetworkResult.Success) {
local.save(ScheduleCacheKey.group(number), result.data) local.saveSchedule(ScheduleCacheKey.group(number), result.data)
} }
return result return result
} }
@@ -27,7 +27,7 @@ class ScheduleRepositoryImpl @Inject constructor(
override suspend fun loadScheduleByTeacher(name: String): NetworkResult<ScheduleEntity> { override suspend fun loadScheduleByTeacher(name: String): NetworkResult<ScheduleEntity> {
val result = remote.loadScheduleByTeacher(name).map(mapper::invoke) val result = remote.loadScheduleByTeacher(name).map(mapper::invoke)
if (result is NetworkResult.Success) { if (result is NetworkResult.Success) {
local.save(ScheduleCacheKey.teacher(name), result.data) local.saveSchedule(ScheduleCacheKey.teacher(name), result.data)
} }
return result return result
} }

View File

@@ -3,7 +3,7 @@ package ru.fincode.tsudesk.feature.schedule.data.datasource
import ru.fincode.tsudesk.feature.schedule.domain.model.ScheduleEntity import ru.fincode.tsudesk.feature.schedule.domain.model.ScheduleEntity
interface ScheduleLocalDataSource { interface ScheduleLocalDataSource {
suspend fun save(key: String, schedule: ScheduleEntity) suspend fun saveSchedule(key: String, schedule: ScheduleEntity)
suspend fun load(key: String): ScheduleEntity? suspend fun loadSchedule(key: String): ScheduleEntity?
suspend fun clear(key: String) suspend fun removeSchedule(key: String)
} }

View File

@@ -11,18 +11,18 @@ class ScheduleLocalDataSourceImpl @Inject constructor(
private val dao: ScheduleDao private val dao: ScheduleDao
) : ScheduleLocalDataSource { ) : ScheduleLocalDataSource {
override suspend fun save(key: String, schedule: ScheduleEntity) { override suspend fun saveSchedule(key: String, schedule: ScheduleEntity) {
val (scheduleCache, lessonsCache) = schedule.toCache(key) val (scheduleCache, lessonsCache) = schedule.toCache(key)
dao.replaceSchedule(key, scheduleCache, lessonsCache) dao.replaceSchedule(key, scheduleCache, lessonsCache)
} }
override suspend fun load(key: String): ScheduleEntity? { override suspend fun loadSchedule(key: String): ScheduleEntity? {
val schedule = dao.getSchedule(key) ?: return null val schedule = dao.getSchedule(key) ?: return null
val lessons = dao.getLessons(key) val lessons = dao.getLessons(key)
return schedule.toDomain(lessons) return schedule.toDomain(lessons)
} }
override suspend fun clear(key: String) { override suspend fun removeSchedule(key: String) {
dao.deleteLessonsByKey(key) dao.deleteLessonsByKey(key)
} }
} }

View File

@@ -2,13 +2,17 @@ package ru.fincode.tsudesk.feature.schedule.data.mapper
import ru.fincode.tsudesk.core.database.schedule.LessonCacheEntity import ru.fincode.tsudesk.core.database.schedule.LessonCacheEntity
import ru.fincode.tsudesk.core.database.schedule.ScheduleCacheEntity import ru.fincode.tsudesk.core.database.schedule.ScheduleCacheEntity
import ru.fincode.tsudesk.core.database.schedule.ScheduleDbConstants.GROUP_PRE_KEY
import ru.fincode.tsudesk.core.database.schedule.ScheduleDbConstants.TEACHER_PRE_KEY
import ru.fincode.tsudesk.feature.schedule.domain.model.LessonEntity import ru.fincode.tsudesk.feature.schedule.domain.model.LessonEntity
import ru.fincode.tsudesk.feature.schedule.domain.model.ScheduleEntity import ru.fincode.tsudesk.feature.schedule.domain.model.ScheduleEntity
object ScheduleCacheKey { object ScheduleCacheKey {
fun group(number: String) = "group:$number" fun group(number: String) = "$GROUP_PRE_KEY$number"
fun teacher(name: String) = "teacher:$name" fun teacher(name: String) = "$TEACHER_PRE_KEY$name"
} }