ref: db
This commit is contained in:
@@ -7,9 +7,9 @@ import android.content.Context
|
|||||||
import ru.sweetbread.unn.core.AuthRepository
|
import ru.sweetbread.unn.core.AuthRepository
|
||||||
import ru.sweetbread.unn.core.CredentialsStore
|
import ru.sweetbread.unn.core.CredentialsStore
|
||||||
import ru.sweetbread.unn.core.SessionManager
|
import ru.sweetbread.unn.core.SessionManager
|
||||||
|
import ru.sweetbread.unn.core.db.AppDatabase
|
||||||
import ru.sweetbread.unn.core.network.PortalApi
|
import ru.sweetbread.unn.core.network.PortalApi
|
||||||
import ru.sweetbread.unn.core.network.createHttpClient
|
import ru.sweetbread.unn.core.network.createHttpClient
|
||||||
import ru.sweetbread.unn.db.AppDatabase
|
|
||||||
import ru.sweetbread.unn.feature.news.NewsRepository
|
import ru.sweetbread.unn.feature.news.NewsRepository
|
||||||
import ru.sweetbread.unn.feature.profile.UserRepository
|
import ru.sweetbread.unn.feature.profile.UserRepository
|
||||||
import ru.sweetbread.unn.feature.schedule.ScheduleRepository
|
import ru.sweetbread.unn.feature.schedule.ScheduleRepository
|
||||||
|
|||||||
+15
-2
@@ -1,11 +1,24 @@
|
|||||||
// Copyright (c) 2026 Gleb Zaharov. License: GPLv3 (see LICENSE).
|
// Copyright (c) 2026 Gleb Zaharov. License: GPLv3 (see LICENSE).
|
||||||
|
|
||||||
package ru.sweetbread.unn.db
|
package ru.sweetbread.unn.core.db
|
||||||
|
|
||||||
import androidx.room.Database
|
import androidx.room.Database
|
||||||
import androidx.room.RoomDatabase
|
import androidx.room.RoomDatabase
|
||||||
import ru.sweetbread.unn.core.db.NewsDao
|
import ru.sweetbread.unn.core.db.dao.AuditoriumDao
|
||||||
|
import ru.sweetbread.unn.core.db.dao.BuildingDao
|
||||||
|
import ru.sweetbread.unn.core.db.dao.DisciplineDao
|
||||||
|
import ru.sweetbread.unn.core.db.dao.KindOfWorkDao
|
||||||
|
import ru.sweetbread.unn.core.db.dao.LecturerDao
|
||||||
|
import ru.sweetbread.unn.core.db.dao.NewsDao
|
||||||
|
import ru.sweetbread.unn.core.db.dao.ScheduleItemDao
|
||||||
|
import ru.sweetbread.unn.core.db.dao.UserDao
|
||||||
|
import ru.sweetbread.unn.core.db.entity.AuditoriumDB
|
||||||
|
import ru.sweetbread.unn.core.db.entity.BuildingDB
|
||||||
|
import ru.sweetbread.unn.core.db.entity.DisciplineDB
|
||||||
|
import ru.sweetbread.unn.core.db.entity.KindOfWorkDB
|
||||||
|
import ru.sweetbread.unn.core.db.entity.LecturerDB
|
||||||
import ru.sweetbread.unn.core.db.entity.NewsDB
|
import ru.sweetbread.unn.core.db.entity.NewsDB
|
||||||
|
import ru.sweetbread.unn.core.db.entity.ScheduleUnitDB
|
||||||
import ru.sweetbread.unn.core.db.entity.UserDB
|
import ru.sweetbread.unn.core.db.entity.UserDB
|
||||||
|
|
||||||
@Database(entities = [
|
@Database(entities = [
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
// Copyright (c) 2026 Gleb Zaharov. License: GPLv3 (see LICENSE).
|
||||||
|
|
||||||
|
package ru.sweetbread.unn.core.db.dao
|
||||||
|
|
||||||
|
import androidx.room.Dao
|
||||||
|
import androidx.room.Delete
|
||||||
|
import androidx.room.Insert
|
||||||
|
import androidx.room.OnConflictStrategy
|
||||||
|
import androidx.room.Query
|
||||||
|
import ru.sweetbread.unn.core.db.entity.AuditoriumDB
|
||||||
|
|
||||||
|
@Dao
|
||||||
|
interface AuditoriumDao {
|
||||||
|
@Query("SELECT * FROM auditoriumdb WHERE oid = :oid LIMIT 1")
|
||||||
|
suspend fun get(oid: Int): AuditoriumDB?
|
||||||
|
|
||||||
|
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||||
|
suspend fun insert(auditoriums: List<AuditoriumDB>)
|
||||||
|
|
||||||
|
@Delete
|
||||||
|
fun delete(auditorium: AuditoriumDB)
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
// Copyright (c) 2026 Gleb Zaharov. License: GPLv3 (see LICENSE).
|
||||||
|
|
||||||
|
package ru.sweetbread.unn.core.db.dao
|
||||||
|
|
||||||
|
import androidx.room.Dao
|
||||||
|
import androidx.room.Delete
|
||||||
|
import androidx.room.Insert
|
||||||
|
import androidx.room.OnConflictStrategy
|
||||||
|
import androidx.room.Query
|
||||||
|
import ru.sweetbread.unn.core.db.entity.BuildingDB
|
||||||
|
|
||||||
|
@Dao
|
||||||
|
interface BuildingDao {
|
||||||
|
@Query("SELECT * FROM buildingdb WHERE oid = :oid LIMIT 1")
|
||||||
|
suspend fun get(oid: Int): BuildingDB?
|
||||||
|
|
||||||
|
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||||
|
suspend fun insert(buildings: List<BuildingDB>)
|
||||||
|
|
||||||
|
@Delete
|
||||||
|
fun delete(building: BuildingDB)
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
// Copyright (c) 2026 Gleb Zaharov. License: GPLv3 (see LICENSE).
|
||||||
|
|
||||||
|
package ru.sweetbread.unn.core.db.dao
|
||||||
|
|
||||||
|
import androidx.room.Dao
|
||||||
|
import androidx.room.Delete
|
||||||
|
import androidx.room.Insert
|
||||||
|
import androidx.room.OnConflictStrategy
|
||||||
|
import androidx.room.Query
|
||||||
|
import ru.sweetbread.unn.core.db.entity.DisciplineDB
|
||||||
|
|
||||||
|
@Dao
|
||||||
|
interface DisciplineDao {
|
||||||
|
@Query("SELECT * FROM disciplinedb WHERE oid = :oid LIMIT 1")
|
||||||
|
suspend fun get(oid: Int): DisciplineDB?
|
||||||
|
|
||||||
|
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||||
|
suspend fun insert(disciplines: List<DisciplineDB>)
|
||||||
|
|
||||||
|
@Delete
|
||||||
|
fun delete(discipline: DisciplineDB)
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
// Copyright (c) 2026 Gleb Zaharov. License: GPLv3 (see LICENSE).
|
||||||
|
|
||||||
|
package ru.sweetbread.unn.core.db.dao
|
||||||
|
|
||||||
|
import androidx.room.Dao
|
||||||
|
import androidx.room.Delete
|
||||||
|
import androidx.room.Insert
|
||||||
|
import androidx.room.OnConflictStrategy
|
||||||
|
import androidx.room.Query
|
||||||
|
import ru.sweetbread.unn.core.db.entity.KindOfWorkDB
|
||||||
|
|
||||||
|
@Dao
|
||||||
|
interface KindOfWorkDao {
|
||||||
|
@Query("SELECT * FROM kindofworkdb WHERE oid = :oid LIMIT 1")
|
||||||
|
suspend fun get(oid: Int): KindOfWorkDB?
|
||||||
|
|
||||||
|
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||||
|
suspend fun insert(kindOfWork: List<KindOfWorkDB>)
|
||||||
|
|
||||||
|
@Delete
|
||||||
|
fun delete(kindOfWork: KindOfWorkDB)
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
// Copyright (c) 2026 Gleb Zaharov. License: GPLv3 (see LICENSE).
|
||||||
|
|
||||||
|
package ru.sweetbread.unn.core.db.dao
|
||||||
|
|
||||||
|
import androidx.room.Dao
|
||||||
|
import androidx.room.Delete
|
||||||
|
import androidx.room.Insert
|
||||||
|
import androidx.room.OnConflictStrategy
|
||||||
|
import androidx.room.Query
|
||||||
|
import ru.sweetbread.unn.core.db.entity.LecturerDB
|
||||||
|
|
||||||
|
@Dao
|
||||||
|
interface LecturerDao {
|
||||||
|
@Query("SELECT * FROM lecturerdb WHERE unnId = :unnId LIMIT 1")
|
||||||
|
suspend fun get(unnId: Int): LecturerDB?
|
||||||
|
|
||||||
|
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||||
|
suspend fun insert(lecturers: List<LecturerDB>)
|
||||||
|
|
||||||
|
@Delete
|
||||||
|
fun delete(lecturer: LecturerDB)
|
||||||
|
}
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
// Copyright (c) 2026 Gleb Zaharov. License: GPLv3 (see LICENSE).
|
// Copyright (c) 2026 Gleb Zaharov. License: GPLv3 (see LICENSE).
|
||||||
|
|
||||||
package ru.sweetbread.unn.core.db
|
package ru.sweetbread.unn.core.db.dao
|
||||||
|
|
||||||
import androidx.paging.PagingSource
|
import androidx.paging.PagingSource
|
||||||
import androidx.room.Dao
|
import androidx.room.Dao
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
// Copyright (c) 2026 Gleb Zaharov. License: GPLv3 (see LICENSE).
|
||||||
|
|
||||||
|
package ru.sweetbread.unn.core.db.dao
|
||||||
|
|
||||||
|
import androidx.room.Dao
|
||||||
|
import androidx.room.Delete
|
||||||
|
import androidx.room.Insert
|
||||||
|
import androidx.room.OnConflictStrategy
|
||||||
|
import androidx.room.Query
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import ru.sweetbread.unn.core.db.entity.ScheduleUnitDB
|
||||||
|
|
||||||
|
@Dao
|
||||||
|
interface ScheduleItemDao {
|
||||||
|
@Query("SELECT * FROM scheduleUnitDB WHERE oid = :oid LIMIT 1")
|
||||||
|
suspend fun getSchedule(oid: Int): ScheduleUnitDB?
|
||||||
|
|
||||||
|
@Query("SELECT * FROM scheduleUnitDB WHERE date = :date ORDER BY `begin`")
|
||||||
|
suspend fun getSchedule(date: String): List<ScheduleUnitDB>
|
||||||
|
|
||||||
|
@Query("SELECT * FROM scheduleUnitDB WHERE date = :date ORDER BY `begin`")
|
||||||
|
fun getScheduleFlow(date: String): Flow<List<ScheduleUnitDB>>
|
||||||
|
|
||||||
|
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||||
|
suspend fun insert(units: List<ScheduleUnitDB>)
|
||||||
|
|
||||||
|
@Delete
|
||||||
|
suspend fun delete(unit: ScheduleUnitDB)
|
||||||
|
|
||||||
|
@Query("DELETE FROM scheduleUnitDB WHERE date = :date")
|
||||||
|
suspend fun deleteByDate(date: String)
|
||||||
|
|
||||||
|
@Query("SELECT * FROM scheduleUnitDB WHERE date = :date ORDER BY `begin`")
|
||||||
|
fun observe(date: String): Flow<List<ScheduleUnitDB>>
|
||||||
|
|
||||||
|
@Query("SELECT * FROM scheduleUnitDB")
|
||||||
|
suspend fun getAll(): List<ScheduleUnitDB>
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
// Copyright (c) 2026 Gleb Zaharov. License: GPLv3 (see LICENSE).
|
||||||
|
|
||||||
|
package ru.sweetbread.unn.core.db.dao
|
||||||
|
|
||||||
|
import androidx.room.Dao
|
||||||
|
import androidx.room.Delete
|
||||||
|
import androidx.room.Insert
|
||||||
|
import androidx.room.Query
|
||||||
|
import ru.sweetbread.unn.core.db.entity.UserDB
|
||||||
|
|
||||||
|
@Dao
|
||||||
|
interface UserDao {
|
||||||
|
@Query("SELECT * FROM userDB WHERE userId = :userId LIMIT 1")
|
||||||
|
suspend fun get(userId: Int): UserDB?
|
||||||
|
|
||||||
|
@Insert
|
||||||
|
suspend fun insert(user: UserDB)
|
||||||
|
|
||||||
|
@Delete
|
||||||
|
fun delete(user: UserDB)
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
// Copyright (c) 2026 Gleb Zaharov. License: GPLv3 (see LICENSE).
|
||||||
|
|
||||||
|
package ru.sweetbread.unn.core.db.entity
|
||||||
|
|
||||||
|
import androidx.room.ColumnInfo
|
||||||
|
import androidx.room.Entity
|
||||||
|
import androidx.room.PrimaryKey
|
||||||
|
import androidx.room.withTransaction
|
||||||
|
import ru.sweetbread.unn.api.Auditorium
|
||||||
|
import ru.sweetbread.unn.core.db.AppDatabase
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
import java.time.format.DateTimeFormatter
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
data class AuditoriumDB(
|
||||||
|
@PrimaryKey val oid: Int,
|
||||||
|
@ColumnInfo val name: String,
|
||||||
|
@ColumnInfo val floor: Int?,
|
||||||
|
@ColumnInfo val buildingOid: Int,
|
||||||
|
@ColumnInfo val updatedAt: String
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
suspend fun AuditoriumDB.toModel(db: AppDatabase): Auditorium? {
|
||||||
|
return Auditorium(
|
||||||
|
name,
|
||||||
|
oid,
|
||||||
|
floor ?: 0,
|
||||||
|
db.buildingDao().get(buildingOid)?.toModel() ?: return null
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Auditorium.toEntity() = AuditoriumDB(
|
||||||
|
oid,
|
||||||
|
name,
|
||||||
|
floor,
|
||||||
|
building.oid,
|
||||||
|
LocalDateTime.now().format(DateTimeFormatter.ISO_DATE_TIME)
|
||||||
|
)
|
||||||
|
|
||||||
|
suspend fun cacheAuditorium(db: AppDatabase, auditoriums: List<Auditorium>) {
|
||||||
|
db.withTransaction {
|
||||||
|
db.buildingDao().insert(
|
||||||
|
auditoriums.map { it.building }.map { it.toEntity() }
|
||||||
|
)
|
||||||
|
|
||||||
|
db.auditoriumDao().insert(
|
||||||
|
auditoriums.map { it.toEntity() }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
// Copyright (c) 2026 Gleb Zaharov. License: GPLv3 (see LICENSE).
|
||||||
|
|
||||||
|
package ru.sweetbread.unn.core.db.entity
|
||||||
|
|
||||||
|
import androidx.room.ColumnInfo
|
||||||
|
import androidx.room.Entity
|
||||||
|
import androidx.room.PrimaryKey
|
||||||
|
import ru.sweetbread.unn.api.Building
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
import java.time.format.DateTimeFormatter
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
data class BuildingDB(
|
||||||
|
@PrimaryKey val oid: Int,
|
||||||
|
@ColumnInfo val name: String,
|
||||||
|
@ColumnInfo val gid: Int,
|
||||||
|
@ColumnInfo val updatedAt: String
|
||||||
|
)
|
||||||
|
|
||||||
|
fun BuildingDB.toModel() = Building(name, gid, oid)
|
||||||
|
fun Building.toEntity() = BuildingDB(oid, name, gid, LocalDateTime.now().format(DateTimeFormatter.ISO_DATE_TIME))
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
// Copyright (c) 2026 Gleb Zaharov. License: GPLv3 (see LICENSE).
|
||||||
|
|
||||||
|
package ru.sweetbread.unn.core.db.entity
|
||||||
|
|
||||||
|
import androidx.room.ColumnInfo
|
||||||
|
import androidx.room.Entity
|
||||||
|
import androidx.room.PrimaryKey
|
||||||
|
import ru.sweetbread.unn.api.Discipline
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
import java.time.format.DateTimeFormatter
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
data class DisciplineDB(
|
||||||
|
@PrimaryKey val oid: Int,
|
||||||
|
@ColumnInfo val name: String,
|
||||||
|
@ColumnInfo val type: Int,
|
||||||
|
@ColumnInfo val updatedAt: String
|
||||||
|
)
|
||||||
|
|
||||||
|
fun DisciplineDB.toModel() = Discipline(name, oid, type)
|
||||||
|
fun Discipline.toEntity() = DisciplineDB(oid, name, type, LocalDateTime.now().format(
|
||||||
|
DateTimeFormatter.ISO_DATE_TIME))
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
// Copyright (c) 2026 Gleb Zaharov. License: GPLv3 (see LICENSE).
|
||||||
|
|
||||||
|
package ru.sweetbread.unn.core.db.entity
|
||||||
|
|
||||||
|
import androidx.room.ColumnInfo
|
||||||
|
import androidx.room.Entity
|
||||||
|
import androidx.room.PrimaryKey
|
||||||
|
import ru.sweetbread.unn.api.KindOfWork
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
import java.time.format.DateTimeFormatter
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
data class KindOfWorkDB(
|
||||||
|
@PrimaryKey val oid: Int,
|
||||||
|
@ColumnInfo val name: String,
|
||||||
|
@ColumnInfo val uid: String,
|
||||||
|
@ColumnInfo val complexity: Int,
|
||||||
|
@ColumnInfo val updatedAt: String
|
||||||
|
)
|
||||||
|
|
||||||
|
fun KindOfWorkDB.toModel() = KindOfWork(name, oid, uid, complexity)
|
||||||
|
fun KindOfWork.toEntity() = KindOfWorkDB(
|
||||||
|
oid,
|
||||||
|
name,
|
||||||
|
uid,
|
||||||
|
complexity,
|
||||||
|
LocalDateTime.now().format(DateTimeFormatter.ISO_DATE_TIME)
|
||||||
|
)
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
// Copyright (c) 2026 Gleb Zaharov. License: GPLv3 (see LICENSE).
|
||||||
|
|
||||||
|
package ru.sweetbread.unn.core.db.entity
|
||||||
|
|
||||||
|
import androidx.room.ColumnInfo
|
||||||
|
import androidx.room.Entity
|
||||||
|
import androidx.room.PrimaryKey
|
||||||
|
import ru.sweetbread.unn.api.Lecturer
|
||||||
|
import ru.sweetbread.unn.api.LecturerRank
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
import java.time.format.DateTimeFormatter
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
data class LecturerDB(
|
||||||
|
@PrimaryKey val unnId: Int,
|
||||||
|
@ColumnInfo val name: String,
|
||||||
|
@ColumnInfo val rank: LecturerRank,
|
||||||
|
@ColumnInfo val email: String,
|
||||||
|
@ColumnInfo val uid: String,
|
||||||
|
@ColumnInfo val updatedAt: String
|
||||||
|
)
|
||||||
|
|
||||||
|
fun LecturerDB.toModel() = Lecturer(name, rank, email, unnId, uid)
|
||||||
|
fun Lecturer.toEntity() = LecturerDB(
|
||||||
|
unnId,
|
||||||
|
name,
|
||||||
|
rank,
|
||||||
|
email,
|
||||||
|
uid,
|
||||||
|
LocalDateTime.now().format(DateTimeFormatter.ISO_DATE_TIME)
|
||||||
|
)
|
||||||
@@ -18,6 +18,7 @@ data class NewsDB(
|
|||||||
@ColumnInfo val authorId: Int
|
@ColumnInfo val authorId: Int
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
suspend fun NewsDB.toModel(userRepo: UserRepository): News = News(
|
suspend fun NewsDB.toModel(userRepo: UserRepository): News = News(
|
||||||
id,
|
id,
|
||||||
LocalDateTime.parse(publishedAt, DateTimeFormatter.ISO_DATE_TIME),
|
LocalDateTime.parse(publishedAt, DateTimeFormatter.ISO_DATE_TIME),
|
||||||
|
|||||||
@@ -0,0 +1,70 @@
|
|||||||
|
// Copyright (c) 2026 Gleb Zaharov. License: GPLv3 (see LICENSE).
|
||||||
|
|
||||||
|
package ru.sweetbread.unn.core.db.entity
|
||||||
|
|
||||||
|
import androidx.room.ColumnInfo
|
||||||
|
import androidx.room.Entity
|
||||||
|
import androidx.room.PrimaryKey
|
||||||
|
import androidx.room.withTransaction
|
||||||
|
import ru.sweetbread.unn.api.ScheduleUnit
|
||||||
|
import ru.sweetbread.unn.core.db.AppDatabase
|
||||||
|
import java.time.LocalDate
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
import java.time.LocalTime
|
||||||
|
import java.time.format.DateTimeFormatter
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
data class ScheduleUnitDB(
|
||||||
|
@PrimaryKey val oid: Int,
|
||||||
|
@ColumnInfo val date: String,
|
||||||
|
@ColumnInfo val stream: String,
|
||||||
|
@ColumnInfo val begin: String,
|
||||||
|
@ColumnInfo val end: String,
|
||||||
|
|
||||||
|
@ColumnInfo val auditoriumOid: Int,
|
||||||
|
@ColumnInfo val disciplineOid: Int,
|
||||||
|
@ColumnInfo val kindOfWorkOid: Int,
|
||||||
|
@ColumnInfo val lecturersId: String,
|
||||||
|
|
||||||
|
@ColumnInfo val updatedAt: String
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
suspend fun ScheduleUnitDB.toModel(db: AppDatabase): ScheduleUnit? {
|
||||||
|
return ScheduleUnit(
|
||||||
|
oid,
|
||||||
|
db.auditoriumDao().get(auditoriumOid)?.toModel(db) ?: return null,
|
||||||
|
LocalDate.parse(date, DateTimeFormatter.ISO_DATE),
|
||||||
|
db.disciplineDao().get(disciplineOid)?.toModel() ?: return null,
|
||||||
|
db.kindOfWorkDao().get(kindOfWorkOid)?.toModel() ?: return null,
|
||||||
|
lecturersId.split(",").map { db.lecturerDao().get(it.toInt())?.toModel() ?: return null },
|
||||||
|
stream,
|
||||||
|
LocalTime.parse(begin, DateTimeFormatter.ISO_TIME),
|
||||||
|
LocalTime.parse(end, DateTimeFormatter.ISO_TIME),
|
||||||
|
LocalDateTime.parse(updatedAt, DateTimeFormatter.ISO_DATE_TIME),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun ScheduleUnit.toEntity() = ScheduleUnitDB(
|
||||||
|
oid,
|
||||||
|
date.format(DateTimeFormatter.ISO_DATE),
|
||||||
|
stream,
|
||||||
|
begin.format(DateTimeFormatter.ISO_TIME),
|
||||||
|
end.format(DateTimeFormatter.ISO_TIME),
|
||||||
|
auditorium.oid,
|
||||||
|
discipline.oid,
|
||||||
|
kindOfWork.oid,
|
||||||
|
lecturers.map { it.unnId }.joinToString(","),
|
||||||
|
LocalDateTime.now().format(DateTimeFormatter.ISO_DATE_TIME)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
suspend fun cacheSchedule(db: AppDatabase, units: List<ScheduleUnit>) {
|
||||||
|
db.withTransaction {
|
||||||
|
cacheAuditorium(db, units.map { it.auditorium })
|
||||||
|
db.disciplineDao().insert(units.map { it.discipline.toEntity() })
|
||||||
|
db.kindOfWorkDao().insert(units.map { it.kindOfWork.toEntity() })
|
||||||
|
db.lecturerDao().insert(units.flatMap { it.lecturers }.map { it.toEntity() })
|
||||||
|
db.scheduleDao().insert(units.map { it.toEntity() })
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
-1
@@ -29,6 +29,7 @@ data class UserDB(
|
|||||||
@ColumnInfo val updatedAt: String
|
@ColumnInfo val updatedAt: String
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
fun User.toEntity(): UserDB = UserDB(
|
fun User.toEntity(): UserDB = UserDB(
|
||||||
userId,
|
userId,
|
||||||
if (this.instanceOf(Student::class)) (this as Student).uns else null,
|
if (this.instanceOf(Student::class)) (this as Student).uns else null,
|
||||||
@@ -45,7 +46,7 @@ fun User.toEntity(): UserDB = UserDB(
|
|||||||
)
|
)
|
||||||
|
|
||||||
fun UserDB.toModel(): User {
|
fun UserDB.toModel(): User {
|
||||||
var user = User(
|
val user = User(
|
||||||
userId,
|
userId,
|
||||||
type,
|
type,
|
||||||
email,
|
email,
|
||||||
@@ -1,269 +0,0 @@
|
|||||||
// Copyright (c) 2026 Gleb Zaharov. License: GPLv3 (see LICENSE).
|
|
||||||
|
|
||||||
package ru.sweetbread.unn.db
|
|
||||||
|
|
||||||
import androidx.room.ColumnInfo
|
|
||||||
import androidx.room.Dao
|
|
||||||
import androidx.room.Delete
|
|
||||||
import androidx.room.Entity
|
|
||||||
import androidx.room.Insert
|
|
||||||
import androidx.room.OnConflictStrategy
|
|
||||||
import androidx.room.PrimaryKey
|
|
||||||
import androidx.room.Query
|
|
||||||
import androidx.room.withTransaction
|
|
||||||
import kotlinx.coroutines.flow.Flow
|
|
||||||
import ru.sweetbread.unn.api.Auditorium
|
|
||||||
import ru.sweetbread.unn.api.Building
|
|
||||||
import ru.sweetbread.unn.api.Discipline
|
|
||||||
import ru.sweetbread.unn.api.KindOfWork
|
|
||||||
import ru.sweetbread.unn.api.Lecturer
|
|
||||||
import ru.sweetbread.unn.api.LecturerRank
|
|
||||||
import ru.sweetbread.unn.api.ScheduleUnit
|
|
||||||
import java.time.LocalDate
|
|
||||||
import java.time.LocalDateTime
|
|
||||||
import java.time.LocalTime
|
|
||||||
import java.time.format.DateTimeFormatter
|
|
||||||
|
|
||||||
@Entity
|
|
||||||
data class BuildingDB(
|
|
||||||
@PrimaryKey val oid: Int,
|
|
||||||
@ColumnInfo val name: String,
|
|
||||||
@ColumnInfo val gid: Int,
|
|
||||||
@ColumnInfo val updatedAt: String
|
|
||||||
)
|
|
||||||
|
|
||||||
@Dao
|
|
||||||
interface BuildingDao {
|
|
||||||
@Query("SELECT * FROM buildingdb WHERE oid = :oid LIMIT 1")
|
|
||||||
suspend fun get(oid: Int): BuildingDB?
|
|
||||||
|
|
||||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
|
||||||
suspend fun insert(buildings: List<BuildingDB>)
|
|
||||||
|
|
||||||
@Delete
|
|
||||||
fun delete(building: BuildingDB)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun BuildingDB.toModel() = Building(name, gid, oid)
|
|
||||||
fun Building.toEntity() = BuildingDB(oid, name, gid, LocalDateTime.now().format(DateTimeFormatter.ISO_DATE_TIME))
|
|
||||||
|
|
||||||
|
|
||||||
@Entity
|
|
||||||
data class AuditoriumDB(
|
|
||||||
@PrimaryKey val oid: Int,
|
|
||||||
@ColumnInfo val name: String,
|
|
||||||
@ColumnInfo val floor: Int?,
|
|
||||||
@ColumnInfo val buildingOid: Int,
|
|
||||||
@ColumnInfo val updatedAt: String
|
|
||||||
)
|
|
||||||
|
|
||||||
@Dao
|
|
||||||
interface AuditoriumDao {
|
|
||||||
@Query("SELECT * FROM auditoriumdb WHERE oid = :oid LIMIT 1")
|
|
||||||
suspend fun get(oid: Int): AuditoriumDB?
|
|
||||||
|
|
||||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
|
||||||
suspend fun insert(auditoriums: List<AuditoriumDB>)
|
|
||||||
|
|
||||||
@Delete
|
|
||||||
fun delete(auditorium: AuditoriumDB)
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun AuditoriumDB.toModel(db: AppDatabase): Auditorium? {
|
|
||||||
return Auditorium(
|
|
||||||
name,
|
|
||||||
oid,
|
|
||||||
floor ?: 0,
|
|
||||||
db.buildingDao().get(buildingOid)?.toModel() ?: return null
|
|
||||||
)
|
|
||||||
}
|
|
||||||
fun Auditorium.toEntity() = AuditoriumDB(
|
|
||||||
oid,
|
|
||||||
name,
|
|
||||||
floor,
|
|
||||||
building.oid,
|
|
||||||
LocalDateTime.now().format(DateTimeFormatter.ISO_DATE_TIME)
|
|
||||||
)
|
|
||||||
|
|
||||||
suspend fun cacheAuditorium(db: AppDatabase, auditoriums: List<Auditorium>) {
|
|
||||||
db.withTransaction {
|
|
||||||
db.buildingDao().insert(
|
|
||||||
auditoriums.map { it.building }.map { it.toEntity() }
|
|
||||||
)
|
|
||||||
|
|
||||||
db.auditoriumDao().insert(
|
|
||||||
auditoriums.map { it.toEntity() }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Entity
|
|
||||||
data class DisciplineDB(
|
|
||||||
@PrimaryKey val oid: Int,
|
|
||||||
@ColumnInfo val name: String,
|
|
||||||
@ColumnInfo val type: Int,
|
|
||||||
@ColumnInfo val updatedAt: String
|
|
||||||
)
|
|
||||||
|
|
||||||
@Dao
|
|
||||||
interface DisciplineDao {
|
|
||||||
@Query("SELECT * FROM disciplinedb WHERE oid = :oid LIMIT 1")
|
|
||||||
suspend fun get(oid: Int): DisciplineDB?
|
|
||||||
|
|
||||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
|
||||||
suspend fun insert(disciplines: List<DisciplineDB>)
|
|
||||||
|
|
||||||
@Delete
|
|
||||||
fun delete(discipline: DisciplineDB)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun DisciplineDB.toModel() = Discipline(name, oid, type)
|
|
||||||
fun Discipline.toEntity() = DisciplineDB(oid, name, type, LocalDateTime.now().format(DateTimeFormatter.ISO_DATE_TIME))
|
|
||||||
|
|
||||||
|
|
||||||
@Entity
|
|
||||||
data class KindOfWorkDB(
|
|
||||||
@PrimaryKey val oid: Int,
|
|
||||||
@ColumnInfo val name: String,
|
|
||||||
@ColumnInfo val uid: String,
|
|
||||||
@ColumnInfo val complexity: Int,
|
|
||||||
@ColumnInfo val updatedAt: String
|
|
||||||
)
|
|
||||||
|
|
||||||
@Dao
|
|
||||||
interface KindOfWorkDao {
|
|
||||||
@Query("SELECT * FROM kindofworkdb WHERE oid = :oid LIMIT 1")
|
|
||||||
suspend fun get(oid: Int): KindOfWorkDB?
|
|
||||||
|
|
||||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
|
||||||
suspend fun insert(kindOfWork: List<KindOfWorkDB>)
|
|
||||||
|
|
||||||
@Delete
|
|
||||||
fun delete(kindOfWork: KindOfWorkDB)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun KindOfWorkDB.toModel() = KindOfWork(name, oid, uid, complexity)
|
|
||||||
fun KindOfWork.toEntity() = KindOfWorkDB(
|
|
||||||
oid,
|
|
||||||
name,
|
|
||||||
uid,
|
|
||||||
complexity,
|
|
||||||
LocalDateTime.now().format(DateTimeFormatter.ISO_DATE_TIME)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@Entity
|
|
||||||
data class LecturerDB(
|
|
||||||
@PrimaryKey val unnId: Int,
|
|
||||||
@ColumnInfo val name: String,
|
|
||||||
@ColumnInfo val rank: LecturerRank,
|
|
||||||
@ColumnInfo val email: String,
|
|
||||||
@ColumnInfo val uid: String,
|
|
||||||
@ColumnInfo val updatedAt: String
|
|
||||||
)
|
|
||||||
|
|
||||||
@Dao
|
|
||||||
interface LecturerDao {
|
|
||||||
@Query("SELECT * FROM lecturerdb WHERE unnId = :unnId LIMIT 1")
|
|
||||||
suspend fun get(unnId: Int): LecturerDB?
|
|
||||||
|
|
||||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
|
||||||
suspend fun insert(lecturers: List<LecturerDB>)
|
|
||||||
|
|
||||||
@Delete
|
|
||||||
fun delete(lecturer: LecturerDB)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun LecturerDB.toModel() = Lecturer(name, rank, email, unnId, uid)
|
|
||||||
fun Lecturer.toEntity() = LecturerDB(
|
|
||||||
unnId,
|
|
||||||
name,
|
|
||||||
rank,
|
|
||||||
email,
|
|
||||||
uid,
|
|
||||||
LocalDateTime.now().format(DateTimeFormatter.ISO_DATE_TIME)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@Entity
|
|
||||||
data class ScheduleUnitDB(
|
|
||||||
@PrimaryKey val oid: Int,
|
|
||||||
@ColumnInfo val date: String,
|
|
||||||
@ColumnInfo val stream: String,
|
|
||||||
@ColumnInfo val begin: String,
|
|
||||||
@ColumnInfo val end: String,
|
|
||||||
|
|
||||||
@ColumnInfo val auditoriumOid: Int,
|
|
||||||
@ColumnInfo val disciplineOid: Int,
|
|
||||||
@ColumnInfo val kindOfWorkOid: Int,
|
|
||||||
@ColumnInfo val lecturersId: String,
|
|
||||||
|
|
||||||
@ColumnInfo val updatedAt: String
|
|
||||||
)
|
|
||||||
@Dao
|
|
||||||
interface ScheduleItemDao {
|
|
||||||
@Query("SELECT * FROM scheduleUnitDB WHERE oid = :oid LIMIT 1")
|
|
||||||
suspend fun getSchedule(oid: Int): ScheduleUnitDB?
|
|
||||||
|
|
||||||
@Query("SELECT * FROM scheduleUnitDB WHERE date = :date ORDER BY `begin`")
|
|
||||||
suspend fun getSchedule(date: String): List<ScheduleUnitDB>
|
|
||||||
|
|
||||||
@Query("SELECT * FROM scheduleUnitDB WHERE date = :date ORDER BY `begin`")
|
|
||||||
fun getScheduleFlow(date: String): Flow<List<ScheduleUnitDB>>
|
|
||||||
|
|
||||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
|
||||||
suspend fun insert(units: List<ScheduleUnitDB>)
|
|
||||||
|
|
||||||
@Delete
|
|
||||||
suspend fun delete(unit: ScheduleUnitDB)
|
|
||||||
|
|
||||||
@Query("DELETE FROM scheduleUnitDB WHERE date = :date")
|
|
||||||
suspend fun deleteByDate(date: String)
|
|
||||||
|
|
||||||
@Query("SELECT * FROM scheduleUnitDB WHERE date = :date ORDER BY `begin`")
|
|
||||||
fun observe(date: String): Flow<List<ScheduleUnitDB>>
|
|
||||||
|
|
||||||
@Query("SELECT * FROM scheduleUnitDB")
|
|
||||||
suspend fun getAll(): List<ScheduleUnitDB>
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun ScheduleUnitDB.toModel(db: AppDatabase): ScheduleUnit? {
|
|
||||||
return ScheduleUnit(
|
|
||||||
oid,
|
|
||||||
db.auditoriumDao().get(auditoriumOid)?.toModel(db) ?: return null,
|
|
||||||
LocalDate.parse(date, DateTimeFormatter.ISO_DATE),
|
|
||||||
db.disciplineDao().get(disciplineOid)?.toModel() ?: return null,
|
|
||||||
db.kindOfWorkDao().get(kindOfWorkOid)?.toModel() ?: return null,
|
|
||||||
lecturersId.split(",").map { db.lecturerDao().get(it.toInt())?.toModel() ?: return null },
|
|
||||||
stream,
|
|
||||||
LocalTime.parse(begin, DateTimeFormatter.ISO_TIME),
|
|
||||||
LocalTime.parse(end, DateTimeFormatter.ISO_TIME),
|
|
||||||
LocalDateTime.parse(updatedAt, DateTimeFormatter.ISO_DATE_TIME),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
fun ScheduleUnit.toEntity() = ScheduleUnitDB(
|
|
||||||
oid,
|
|
||||||
date.format(DateTimeFormatter.ISO_DATE),
|
|
||||||
stream,
|
|
||||||
begin.format(DateTimeFormatter.ISO_TIME),
|
|
||||||
end.format(DateTimeFormatter.ISO_TIME),
|
|
||||||
auditorium.oid,
|
|
||||||
discipline.oid,
|
|
||||||
kindOfWork.oid,
|
|
||||||
lecturers.map { it.unnId }.joinToString(","),
|
|
||||||
LocalDateTime.now().format(DateTimeFormatter.ISO_DATE_TIME)
|
|
||||||
)
|
|
||||||
|
|
||||||
suspend fun cacheSchedule(db: AppDatabase, units: List<ScheduleUnit>) {
|
|
||||||
db.withTransaction {
|
|
||||||
cacheAuditorium(db, units.map { it.auditorium })
|
|
||||||
db.disciplineDao().insert(units.map { it.discipline.toEntity() })
|
|
||||||
db.kindOfWorkDao().insert(units.map { it.kindOfWork.toEntity() })
|
|
||||||
db.lecturerDao().insert(units.flatMap { it.lecturers }.map { it.toEntity() })
|
|
||||||
db.scheduleDao().insert(units.map { it.toEntity() })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//fun loadSchedule(db: AppDatabase, date: LocalDate): List<ScheduleUnit> =
|
|
||||||
// db.scheduleDao().getSchedule(date.format(DateTimeFormatter.ISO_DATE))
|
|
||||||
// .mapNotNull { it.toModel(db) }
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
// Copyright (c) 2026 Gleb Zaharov. License: GPLv3 (see LICENSE).
|
|
||||||
|
|
||||||
package ru.sweetbread.unn.db
|
|
||||||
|
|
||||||
import androidx.room.Dao
|
|
||||||
import androidx.room.Delete
|
|
||||||
import androidx.room.Insert
|
|
||||||
import androidx.room.Query
|
|
||||||
import ru.sweetbread.unn.core.db.entity.UserDB
|
|
||||||
|
|
||||||
@Dao
|
|
||||||
interface UserDao {
|
|
||||||
@Query("SELECT * FROM userDB WHERE userId = :userId LIMIT 1")
|
|
||||||
suspend fun get(userId: Int): UserDB?
|
|
||||||
|
|
||||||
@Insert
|
|
||||||
suspend fun insert(user: UserDB)
|
|
||||||
|
|
||||||
@Delete
|
|
||||||
fun delete(user: UserDB)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//fun cacheUser(user: User) {
|
|
||||||
// try {
|
|
||||||
// cacheDb.userDao().insert(
|
|
||||||
// UserDB(
|
|
||||||
// user.userId,
|
|
||||||
// user.unnId,
|
|
||||||
// user.type,
|
|
||||||
// user.email,
|
|
||||||
// user.nameRu,
|
|
||||||
// user.nameEn,
|
|
||||||
// user.isMale,
|
|
||||||
// user.birthday.format(DateTimeFormatter.ISO_LOCAL_DATE),
|
|
||||||
// user.avatar.original,
|
|
||||||
// user.avatar.thumbnail,
|
|
||||||
// user.avatar.small,
|
|
||||||
// LocalDateTime.now().plusDays(1).format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
|
|
||||||
// )
|
|
||||||
// )
|
|
||||||
// } catch (_: android.database.sqlite.SQLiteConstraintException) {
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//fun loadUserByBitrixId(bitrixId: Int): User? {
|
|
||||||
// val user = cacheDb.userDao().getUserById(bitrixId)
|
|
||||||
// Log.d("UserDB", user?.nameEn ?: "None")
|
|
||||||
// if (user == null) return null
|
|
||||||
// if (LocalDateTime.parse(
|
|
||||||
// user.expiredAt,
|
|
||||||
// DateTimeFormatter.ISO_LOCAL_DATE_TIME
|
|
||||||
// ) < LocalDateTime.now()
|
|
||||||
// ) {
|
|
||||||
// cacheDb.userDao().delete(user)
|
|
||||||
// return null
|
|
||||||
// } else {
|
|
||||||
// return User(
|
|
||||||
// user.unnId,
|
|
||||||
// user.userId,
|
|
||||||
// user.type,
|
|
||||||
// user.email,
|
|
||||||
// user.nameRu,
|
|
||||||
// user.nameEn,
|
|
||||||
// user.isMale,
|
|
||||||
// LocalDate.parse(user.birthday, DateTimeFormatter.ISO_LOCAL_DATE),
|
|
||||||
// AvatarSet(
|
|
||||||
// user.origAvatar,
|
|
||||||
// user.thumbAvatar,
|
|
||||||
// user.smallAvatar
|
|
||||||
// )
|
|
||||||
// )
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
@@ -11,10 +11,10 @@ import androidx.paging.PagingState
|
|||||||
import androidx.paging.RemoteMediator
|
import androidx.paging.RemoteMediator
|
||||||
import androidx.room.withTransaction
|
import androidx.room.withTransaction
|
||||||
import kotlinx.io.IOException
|
import kotlinx.io.IOException
|
||||||
|
import ru.sweetbread.unn.core.db.AppDatabase
|
||||||
import ru.sweetbread.unn.core.db.entity.NewsDB
|
import ru.sweetbread.unn.core.db.entity.NewsDB
|
||||||
import ru.sweetbread.unn.core.db.entity.toEntity
|
import ru.sweetbread.unn.core.db.entity.toEntity
|
||||||
import ru.sweetbread.unn.core.network.PortalApi
|
import ru.sweetbread.unn.core.network.PortalApi
|
||||||
import ru.sweetbread.unn.db.AppDatabase
|
|
||||||
import ru.sweetbread.unn.feature.profile.UserRepository
|
import ru.sweetbread.unn.feature.profile.UserRepository
|
||||||
import ru.sweetbread.unn.model.News
|
import ru.sweetbread.unn.model.News
|
||||||
|
|
||||||
|
|||||||
@@ -10,9 +10,9 @@ import androidx.paging.map
|
|||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
import ru.sweetbread.unn.core.SessionManager
|
import ru.sweetbread.unn.core.SessionManager
|
||||||
|
import ru.sweetbread.unn.core.db.AppDatabase
|
||||||
import ru.sweetbread.unn.core.db.entity.toModel
|
import ru.sweetbread.unn.core.db.entity.toModel
|
||||||
import ru.sweetbread.unn.core.network.PortalApi
|
import ru.sweetbread.unn.core.network.PortalApi
|
||||||
import ru.sweetbread.unn.db.AppDatabase
|
|
||||||
import ru.sweetbread.unn.feature.profile.UserRepository
|
import ru.sweetbread.unn.feature.profile.UserRepository
|
||||||
import ru.sweetbread.unn.model.News
|
import ru.sweetbread.unn.model.News
|
||||||
|
|
||||||
|
|||||||
@@ -3,10 +3,10 @@
|
|||||||
package ru.sweetbread.unn.feature.profile
|
package ru.sweetbread.unn.feature.profile
|
||||||
|
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
|
import ru.sweetbread.unn.core.db.AppDatabase
|
||||||
import ru.sweetbread.unn.core.db.entity.toEntity
|
import ru.sweetbread.unn.core.db.entity.toEntity
|
||||||
import ru.sweetbread.unn.core.db.entity.toModel
|
import ru.sweetbread.unn.core.db.entity.toModel
|
||||||
import ru.sweetbread.unn.core.network.PortalApi
|
import ru.sweetbread.unn.core.network.PortalApi
|
||||||
import ru.sweetbread.unn.db.AppDatabase
|
|
||||||
import ru.sweetbread.unn.model.User
|
import ru.sweetbread.unn.model.User
|
||||||
|
|
||||||
class UserRepository (
|
class UserRepository (
|
||||||
|
|||||||
@@ -7,10 +7,10 @@ import kotlinx.coroutines.flow.Flow
|
|||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
import ru.sweetbread.unn.api.ScheduleUnit
|
import ru.sweetbread.unn.api.ScheduleUnit
|
||||||
import ru.sweetbread.unn.core.SessionManager
|
import ru.sweetbread.unn.core.SessionManager
|
||||||
|
import ru.sweetbread.unn.core.db.AppDatabase
|
||||||
|
import ru.sweetbread.unn.core.db.entity.cacheSchedule
|
||||||
|
import ru.sweetbread.unn.core.db.entity.toModel
|
||||||
import ru.sweetbread.unn.core.network.PortalApi
|
import ru.sweetbread.unn.core.network.PortalApi
|
||||||
import ru.sweetbread.unn.db.AppDatabase
|
|
||||||
import ru.sweetbread.unn.db.cacheSchedule
|
|
||||||
import ru.sweetbread.unn.db.toModel
|
|
||||||
import java.time.LocalDate
|
import java.time.LocalDate
|
||||||
import java.time.LocalDateTime
|
import java.time.LocalDateTime
|
||||||
import java.time.format.DateTimeFormatter
|
import java.time.format.DateTimeFormatter
|
||||||
|
|||||||
Reference in New Issue
Block a user