Add Room database, create tables and DAO for schedule
This commit is contained in:
@@ -43,7 +43,9 @@ android {
|
|||||||
jvmTarget = jvm.toString()
|
jvmTarget = jvm.toString()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
kapt {
|
||||||
|
correctErrorTypes = true
|
||||||
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation(libs.core.ktx)
|
implementation(libs.core.ktx)
|
||||||
implementation(libs.androidx.appcompat)
|
implementation(libs.androidx.appcompat)
|
||||||
@@ -51,7 +53,7 @@ dependencies {
|
|||||||
implementation(libs.androidx.activity)
|
implementation(libs.androidx.activity)
|
||||||
implementation(libs.androidx.constraintlayout)
|
implementation(libs.androidx.constraintlayout)
|
||||||
|
|
||||||
kapt(libs.hiltcompiler)
|
kapt(libs.hilt.compiler)
|
||||||
implementation(libs.hiltandroid)
|
implementation(libs.hiltandroid)
|
||||||
|
|
||||||
implementation(libs.okhttp)
|
implementation(libs.okhttp)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
plugins {
|
plugins {
|
||||||
alias(libs.plugins.android.library)
|
alias(libs.plugins.android.library)
|
||||||
alias(libs.plugins.kotlin.android)
|
alias(libs.plugins.kotlin.android)
|
||||||
|
alias(libs.plugins.kotlin.kapt)
|
||||||
}
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
@@ -16,8 +17,7 @@ android {
|
|||||||
release {
|
release {
|
||||||
isMinifyEnabled = false
|
isMinifyEnabled = false
|
||||||
proguardFiles(
|
proguardFiles(
|
||||||
getDefaultProguardFile("proguard-android-optimize.txt"),
|
getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro"
|
||||||
"proguard-rules.pro"
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -30,7 +30,14 @@ android {
|
|||||||
jvmTarget = jvm.toString()
|
jvmTarget = jvm.toString()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
kapt {
|
||||||
|
correctErrorTypes = true
|
||||||
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation(libs.core.ktx)
|
implementation(libs.core.ktx)
|
||||||
|
implementation(libs.room.runtime)
|
||||||
|
implementation(libs.room.ktx)
|
||||||
|
kapt(libs.room.compiler)
|
||||||
|
implementation(libs.hiltandroid)
|
||||||
|
kapt(libs.hilt.compiler)
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package ru.fincode.tsudesk.core.database
|
||||||
|
|
||||||
|
import androidx.room.Database
|
||||||
|
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.ScheduleCacheEntity
|
||||||
|
|
||||||
|
@Database(
|
||||||
|
entities = [
|
||||||
|
// schedule feature
|
||||||
|
ScheduleCacheEntity::class,
|
||||||
|
LessonCacheEntity::class,
|
||||||
|
|
||||||
|
// future:
|
||||||
|
// NewsEntity::class,
|
||||||
|
// GradeEntity::class,
|
||||||
|
],
|
||||||
|
version = 1,
|
||||||
|
exportSchema = false
|
||||||
|
)
|
||||||
|
abstract class AppDatabase : RoomDatabase() {
|
||||||
|
abstract fun scheduleCacheDao(): ScheduleDao
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package ru.fincode.tsudesk.core.database.di
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.room.Room
|
||||||
|
import dagger.Module
|
||||||
|
import dagger.Provides
|
||||||
|
import dagger.hilt.InstallIn
|
||||||
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
|
import dagger.hilt.components.SingletonComponent
|
||||||
|
import ru.fincode.tsudesk.core.database.AppDatabase
|
||||||
|
import ru.fincode.tsudesk.core.database.schedule.ScheduleDao
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
@Module
|
||||||
|
@InstallIn(SingletonComponent::class)
|
||||||
|
object DatabaseModule {
|
||||||
|
|
||||||
|
private const val DB_NAME = "tsudesk.db"
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
fun provideAppDatabase(@ApplicationContext context: Context): AppDatabase =
|
||||||
|
Room.databaseBuilder(context, AppDatabase::class.java, DB_NAME)
|
||||||
|
.fallbackToDestructiveMigration()
|
||||||
|
.build()
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
fun provideScheduleCacheDao(db: AppDatabase): ScheduleDao =
|
||||||
|
db.scheduleCacheDao()
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package ru.fincode.tsudesk.core.database.schedule
|
||||||
|
|
||||||
|
object ScheduleDbConstants {
|
||||||
|
const val SCHEDULE_TABLE = "schedule_cache"
|
||||||
|
const val LESSON_TABLE = "lesson_cache"
|
||||||
|
|
||||||
|
const val COL_SCHEDULE_KEY = "scheduleKey"
|
||||||
|
const val COL_KEY = "key"
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package ru.fincode.tsudesk.core.database.schedule
|
||||||
|
|
||||||
|
import androidx.room.Entity
|
||||||
|
import androidx.room.Index
|
||||||
|
import androidx.room.PrimaryKey
|
||||||
|
import ru.fincode.tsudesk.core.database.schedule.ScheduleDbConstants.COL_SCHEDULE_KEY
|
||||||
|
import ru.fincode.tsudesk.core.database.schedule.ScheduleDbConstants.LESSON_TABLE
|
||||||
|
|
||||||
|
@Entity(
|
||||||
|
tableName = LESSON_TABLE, indices = [Index(value = [COL_SCHEDULE_KEY])]
|
||||||
|
)
|
||||||
|
data class LessonCacheEntity(
|
||||||
|
@PrimaryKey(autoGenerate = true) val id: Long = 0,
|
||||||
|
|
||||||
|
val scheduleKey: String,
|
||||||
|
val date: String,
|
||||||
|
val time: String,
|
||||||
|
val name: String,
|
||||||
|
val typeName: String,
|
||||||
|
val room: String,
|
||||||
|
val teacher: String,
|
||||||
|
val groupId: String,
|
||||||
|
val type: String
|
||||||
|
)
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package ru.fincode.tsudesk.core.database.schedule
|
||||||
|
|
||||||
|
import androidx.room.Entity
|
||||||
|
import androidx.room.PrimaryKey
|
||||||
|
import ru.fincode.tsudesk.core.database.schedule.ScheduleDbConstants.SCHEDULE_TABLE
|
||||||
|
|
||||||
|
@Entity(tableName = SCHEDULE_TABLE)
|
||||||
|
data class ScheduleCacheEntity(
|
||||||
|
@PrimaryKey
|
||||||
|
val key: String, // "group:220631" | "teacher:ФИО"
|
||||||
|
val timestamp: Long
|
||||||
|
)
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
package ru.fincode.tsudesk.core.database.schedule
|
||||||
|
|
||||||
|
import androidx.room.Dao
|
||||||
|
import androidx.room.Delete
|
||||||
|
import androidx.room.Insert
|
||||||
|
import androidx.room.OnConflictStrategy
|
||||||
|
import androidx.room.Query
|
||||||
|
import androidx.room.Transaction
|
||||||
|
|
||||||
|
@Dao
|
||||||
|
interface ScheduleDao {
|
||||||
|
|
||||||
|
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||||
|
suspend fun upsertSchedule(schedule: ScheduleCacheEntity)
|
||||||
|
|
||||||
|
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||||
|
suspend fun insertLessons(lessons: List<LessonCacheEntity>)
|
||||||
|
|
||||||
|
|
||||||
|
@Query("SELECT * FROM schedule_cache WHERE `key` = :key LIMIT 1")
|
||||||
|
suspend fun getSchedule(key: String): ScheduleCacheEntity?
|
||||||
|
|
||||||
|
@Query("SELECT * FROM lesson_cache WHERE scheduleKey = :key")
|
||||||
|
suspend fun getLessons(key: String): List<LessonCacheEntity>
|
||||||
|
|
||||||
|
// Bulk delete уроков по ключу — самый простой/эффективный путь в Room это @Query
|
||||||
|
@Query("DELETE FROM lesson_cache WHERE scheduleKey = :key")
|
||||||
|
suspend fun deleteLessonsByKey(key: String)
|
||||||
|
|
||||||
|
// Удаление schedule_cache без SQL: типобезопасно
|
||||||
|
@Delete
|
||||||
|
suspend fun deleteSchedule(entity: ScheduleCacheEntity)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Обновить кэш расписания (header + lessons) атомарно.
|
||||||
|
*/
|
||||||
|
@Transaction
|
||||||
|
suspend fun replaceSchedule(
|
||||||
|
key: String,
|
||||||
|
schedule: ScheduleCacheEntity,
|
||||||
|
lessons: List<LessonCacheEntity>
|
||||||
|
) {
|
||||||
|
upsertSchedule(schedule)
|
||||||
|
deleteLessonsByKey(key)
|
||||||
|
insertLessons(lessons)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Полная очистка кэша по ключу без прямого DELETE для schedule_cache.
|
||||||
|
*/
|
||||||
|
@Transaction
|
||||||
|
suspend fun clearSchedule(key: String) {
|
||||||
|
deleteLessonsByKey(key)
|
||||||
|
val header = getSchedule(key) ?: return
|
||||||
|
deleteSchedule(header)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -36,7 +36,7 @@ android {
|
|||||||
dependencies {
|
dependencies {
|
||||||
implementation(libs.core.ktx)
|
implementation(libs.core.ktx)
|
||||||
|
|
||||||
kapt(libs.hiltcompiler)
|
kapt(libs.hilt.compiler)
|
||||||
implementation(libs.hiltandroid)
|
implementation(libs.hiltandroid)
|
||||||
|
|
||||||
api(libs.retrofit)
|
api(libs.retrofit)
|
||||||
|
|||||||
@@ -19,8 +19,7 @@ android {
|
|||||||
release {
|
release {
|
||||||
isMinifyEnabled = false
|
isMinifyEnabled = false
|
||||||
proguardFiles(
|
proguardFiles(
|
||||||
getDefaultProguardFile("proguard-android-optimize.txt"),
|
getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro"
|
||||||
"proguard-rules.pro"
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -40,8 +39,9 @@ dependencies {
|
|||||||
implementation(libs.androidx.appcompat)
|
implementation(libs.androidx.appcompat)
|
||||||
implementation(libs.material)
|
implementation(libs.material)
|
||||||
|
|
||||||
kapt(libs.hiltcompiler)
|
kapt(libs.hilt.compiler)
|
||||||
implementation(libs.hiltandroid)
|
implementation(libs.hiltandroid)
|
||||||
|
|
||||||
implementation(project(":core:network"))
|
implementation(project(":core:network"))
|
||||||
|
implementation(project(":core:database"))
|
||||||
}
|
}
|
||||||
@@ -2,22 +2,33 @@ package ru.fincode.tsudesk.feature.schedule.data
|
|||||||
|
|
||||||
import ru.fincode.tsudesk.core.network.model.NetworkResult
|
import ru.fincode.tsudesk.core.network.model.NetworkResult
|
||||||
import ru.fincode.tsudesk.core.network.model.map
|
import ru.fincode.tsudesk.core.network.model.map
|
||||||
|
import ru.fincode.tsudesk.feature.schedule.data.datasource.ScheduleLocalDataSource
|
||||||
import ru.fincode.tsudesk.feature.schedule.data.datasource.ScheduleRemoteDataSource
|
import ru.fincode.tsudesk.feature.schedule.data.datasource.ScheduleRemoteDataSource
|
||||||
import ru.fincode.tsudesk.feature.schedule.data.mapper.ScheduleDtoToDomainMapper
|
import ru.fincode.tsudesk.feature.schedule.data.mapper.ScheduleCacheKey
|
||||||
|
import ru.fincode.tsudesk.feature.schedule.data.mapper.ScheduleNetworkMapper
|
||||||
import ru.fincode.tsudesk.feature.schedule.domain.model.ScheduleEntity
|
import ru.fincode.tsudesk.feature.schedule.domain.model.ScheduleEntity
|
||||||
import ru.fincode.tsudesk.feature.schedule.domain.repository.ScheduleRepository
|
import ru.fincode.tsudesk.feature.schedule.domain.repository.ScheduleRepository
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class ScheduleRepositoryImpl @Inject constructor(
|
class ScheduleRepositoryImpl @Inject constructor(
|
||||||
private val remote: ScheduleRemoteDataSource,
|
private val remote: ScheduleRemoteDataSource,
|
||||||
private val mapper: ScheduleDtoToDomainMapper
|
private val local: ScheduleLocalDataSource,
|
||||||
|
private val mapper: ScheduleNetworkMapper
|
||||||
) : ScheduleRepository {
|
) : ScheduleRepository {
|
||||||
|
|
||||||
override suspend fun loadScheduleByGroup(number: String): NetworkResult<ScheduleEntity> =
|
override suspend fun loadScheduleByGroup(number: String): NetworkResult<ScheduleEntity> {
|
||||||
remote.loadScheduleByGroup(number).map(mapper::invoke)
|
val result = remote.loadScheduleByGroup(number).map(mapper::invoke)
|
||||||
|
if (result is NetworkResult.Success) {
|
||||||
override suspend fun loadScheduleByTeacher(name: String): NetworkResult<ScheduleEntity> =
|
local.save(ScheduleCacheKey.group(number), result.data)
|
||||||
remote.loadScheduleByTeacher(name).map(mapper::invoke)
|
}
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override suspend fun loadScheduleByTeacher(name: String): NetworkResult<ScheduleEntity> {
|
||||||
|
val result = remote.loadScheduleByTeacher(name).map(mapper::invoke)
|
||||||
|
if (result is NetworkResult.Success) {
|
||||||
|
local.save(ScheduleCacheKey.teacher(name), result.data)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,9 +2,8 @@ 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 getScheduleByGroup(groupNumber: String): ScheduleEntity?
|
suspend fun save(key: String, schedule: ScheduleEntity)
|
||||||
suspend fun getScheduleByTeacher(teacherName: String): ScheduleEntity?
|
suspend fun load(key: String): ScheduleEntity?
|
||||||
suspend fun saveSchedule(entity: ScheduleEntity)
|
suspend fun clear(key: String)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
package ru.fincode.tsudesk.feature.schedule.data.local;
|
|
||||||
|
|
||||||
public class ScheduleDaoFacade {
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package ru.fincode.tsudesk.feature.schedule.data.local
|
||||||
|
|
||||||
|
import ru.fincode.tsudesk.core.database.schedule.ScheduleDao
|
||||||
|
import ru.fincode.tsudesk.feature.schedule.data.datasource.ScheduleLocalDataSource
|
||||||
|
import ru.fincode.tsudesk.feature.schedule.data.mapper.toCache
|
||||||
|
import ru.fincode.tsudesk.feature.schedule.data.mapper.toDomain
|
||||||
|
import ru.fincode.tsudesk.feature.schedule.domain.model.ScheduleEntity
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class ScheduleLocalDataSourceImpl @Inject constructor(
|
||||||
|
private val dao: ScheduleDao
|
||||||
|
) : ScheduleLocalDataSource {
|
||||||
|
|
||||||
|
override suspend fun save(key: String, schedule: ScheduleEntity) {
|
||||||
|
val (scheduleCache, lessonsCache) = schedule.toCache(key)
|
||||||
|
dao.replaceSchedule(key, scheduleCache, lessonsCache)
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun load(key: String): ScheduleEntity? {
|
||||||
|
val schedule = dao.getSchedule(key) ?: return null
|
||||||
|
val lessons = dao.getLessons(key)
|
||||||
|
return schedule.toDomain(lessons)
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun clear(key: String) {
|
||||||
|
dao.deleteLessonsByKey(key)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,7 +7,7 @@ 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
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class ScheduleDtoToDomainMapper @Inject constructor() {
|
class ScheduleNetworkMapper @Inject constructor() {
|
||||||
|
|
||||||
operator fun invoke(dto: ScheduleDto, meta: NetworkMeta): ScheduleEntity =
|
operator fun invoke(dto: ScheduleDto, meta: NetworkMeta): ScheduleEntity =
|
||||||
ScheduleEntity(
|
ScheduleEntity(
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
package ru.fincode.tsudesk.feature.schedule.data.mapper
|
||||||
|
|
||||||
|
import ru.fincode.tsudesk.core.database.schedule.LessonCacheEntity
|
||||||
|
import ru.fincode.tsudesk.core.database.schedule.ScheduleCacheEntity
|
||||||
|
import ru.fincode.tsudesk.feature.schedule.domain.model.LessonEntity
|
||||||
|
import ru.fincode.tsudesk.feature.schedule.domain.model.ScheduleEntity
|
||||||
|
|
||||||
|
|
||||||
|
object ScheduleCacheKey {
|
||||||
|
fun group(number: String) = "group:$number"
|
||||||
|
fun teacher(name: String) = "teacher:$name"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun ScheduleEntity.toCache(
|
||||||
|
key: String
|
||||||
|
): Pair<ScheduleCacheEntity, List<LessonCacheEntity>> {
|
||||||
|
|
||||||
|
val scheduleCache = ScheduleCacheEntity(
|
||||||
|
key = key,
|
||||||
|
timestamp = timestamp
|
||||||
|
)
|
||||||
|
|
||||||
|
val lessonsCache = lessons.map { lesson ->
|
||||||
|
LessonCacheEntity(
|
||||||
|
scheduleKey = key,
|
||||||
|
date = lesson.date,
|
||||||
|
time = lesson.time,
|
||||||
|
name = lesson.name,
|
||||||
|
typeName = lesson.typeName,
|
||||||
|
room = lesson.room,
|
||||||
|
teacher = lesson.teacher,
|
||||||
|
groupId = lesson.groupId,
|
||||||
|
type = lesson.type
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return scheduleCache to lessonsCache
|
||||||
|
}
|
||||||
|
|
||||||
|
fun ScheduleCacheEntity.toDomain(
|
||||||
|
lessons: List<LessonCacheEntity>
|
||||||
|
): ScheduleEntity =
|
||||||
|
ScheduleEntity(
|
||||||
|
lessons = lessons.map { it.toDomain() },
|
||||||
|
timestamp = timestamp
|
||||||
|
)
|
||||||
|
|
||||||
|
private fun LessonCacheEntity.toDomain(): LessonEntity =
|
||||||
|
LessonEntity(
|
||||||
|
date = date,
|
||||||
|
time = time,
|
||||||
|
name = name,
|
||||||
|
typeName = typeName,
|
||||||
|
room = room,
|
||||||
|
teacher = teacher,
|
||||||
|
groupId = groupId,
|
||||||
|
type = type
|
||||||
|
)
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package ru.fincode.tsudesk.feature.schedule.di
|
||||||
|
|
||||||
|
import dagger.Binds
|
||||||
|
import dagger.Module
|
||||||
|
import dagger.hilt.InstallIn
|
||||||
|
import dagger.hilt.components.SingletonComponent
|
||||||
|
import ru.fincode.tsudesk.feature.schedule.data.datasource.ScheduleLocalDataSource
|
||||||
|
import ru.fincode.tsudesk.feature.schedule.data.local.ScheduleLocalDataSourceImpl
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
@Module
|
||||||
|
@InstallIn(SingletonComponent::class)
|
||||||
|
abstract class ScheduleLocalModule {
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
@Singleton
|
||||||
|
abstract fun bindScheduleLocalDataSource(
|
||||||
|
impl: ScheduleLocalDataSourceImpl
|
||||||
|
): ScheduleLocalDataSource
|
||||||
|
}
|
||||||
@@ -49,15 +49,12 @@ retrofitMoshi = { group = "com.squareup.retrofit2", name = "converter-moshi", ve
|
|||||||
converter-gson = { module = "com.squareup.retrofit2:converter-gson", version.ref = "retrofit" }
|
converter-gson = { module = "com.squareup.retrofit2:converter-gson", version.ref = "retrofit" }
|
||||||
# DI: Hilt
|
# DI: Hilt
|
||||||
hiltandroid = { module = "com.google.dagger:hilt-android", version.ref = "hilt" }
|
hiltandroid = { module = "com.google.dagger:hilt-android", version.ref = "hilt" }
|
||||||
hiltcompiler = { module = "com.google.dagger:hilt-compiler", version.ref = "hilt" }
|
hilt-compiler = { module = "com.google.dagger:hilt-compiler", version.ref = "hilt" }
|
||||||
core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
|
core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
|
||||||
# DB: Room
|
# DB: Room
|
||||||
room-runtime = { group = "androidx.room", name = "room-runtime", version.ref = "room" }
|
room-runtime = { group = "androidx.room", name = "room-runtime", version.ref = "room" }
|
||||||
room-ktx = { group = "androidx.room", name = "room-ktx", version.ref = "room" }
|
room-ktx = { group = "androidx.room", name = "room-ktx", version.ref = "room" }
|
||||||
room-compiler = { group = "androidx.room", name = "room-compiler", version.ref = "room" }
|
room-compiler = { group = "androidx.room", name = "room-compiler", version.ref = "room" }
|
||||||
junit = { group = "junit", name = "junit", version.ref = "junit" }
|
|
||||||
androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
|
|
||||||
androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
|
|
||||||
|
|
||||||
[plugins]
|
[plugins]
|
||||||
hilt = { id = "com.google.dagger.hilt.android", version.ref = "hilt" }
|
hilt = { id = "com.google.dagger.hilt.android", version.ref = "hilt" }
|
||||||
|
|||||||
Reference in New Issue
Block a user