feat(cache): Add conflict strategy
This commit is contained in:
@@ -10,9 +10,10 @@ import io.ktor.http.parameters
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
import ru.sweetbread.unn.db.cacheScheduleItems
|
||||
import ru.sweetbread.unn.db.cacheSchedule
|
||||
import ru.sweetbread.unn.db.cacheUser
|
||||
import ru.sweetbread.unn.db.loadSchedule
|
||||
import ru.sweetbread.unn.db.loadUserByBitrixId
|
||||
@@ -207,6 +208,7 @@ suspend fun getScheduleDay(
|
||||
|
||||
if ((type == ME.type) and (id == ME.unnId!!)) {
|
||||
val schedule = withContext(Dispatchers.IO) { loadSchedule(date) }
|
||||
Log.d("Schedule", schedule.joinToString())
|
||||
if (schedule.size != 0) {
|
||||
return schedule
|
||||
}
|
||||
@@ -294,7 +296,7 @@ suspend fun getSchedule(
|
||||
}
|
||||
|
||||
if ((type == ME.type) and (id == ME.unnId!!)) {
|
||||
cacheScheduleItems(out)
|
||||
cacheSchedule(out)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
package ru.sweetbread.unn.db
|
||||
|
||||
import android.util.Log
|
||||
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 ru.sweetbread.unn.Auditorium
|
||||
@@ -16,6 +18,7 @@ import ru.sweetbread.unn.LecturerRank
|
||||
import ru.sweetbread.unn.ScheduleUnit
|
||||
import ru.sweetbread.unn.ui.layout.db
|
||||
import java.time.LocalDate
|
||||
import java.time.LocalDateTime
|
||||
import java.time.LocalTime
|
||||
import java.time.format.DateTimeFormatter
|
||||
|
||||
@@ -23,15 +26,16 @@ import java.time.format.DateTimeFormatter
|
||||
data class BuildingDB(
|
||||
@PrimaryKey val oid: Int,
|
||||
@ColumnInfo val name: String,
|
||||
@ColumnInfo val gid: Int
|
||||
@ColumnInfo val gid: Int,
|
||||
@ColumnInfo val expiredAt: String
|
||||
)
|
||||
|
||||
@Dao
|
||||
interface BuildingDao {
|
||||
@Query("SELECT * FROM buildingdb WHERE oid = :oid LIMIT 1")
|
||||
fun get(oid: Int): BuildingDB
|
||||
fun get(oid: Int): BuildingDB?
|
||||
|
||||
@Insert
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
fun insert(building: BuildingDB)
|
||||
|
||||
@Delete
|
||||
@@ -39,20 +43,26 @@ interface BuildingDao {
|
||||
}
|
||||
|
||||
fun cacheBuilding(building: Building) {
|
||||
try {
|
||||
db.buildingDao().insert(
|
||||
BuildingDB(
|
||||
building.oid,
|
||||
building.name,
|
||||
building.gid
|
||||
)
|
||||
db.buildingDao().insert(
|
||||
BuildingDB(
|
||||
building.oid,
|
||||
building.name,
|
||||
building.gid,
|
||||
LocalDateTime.now().plusMonths(1).format(DateTimeFormatter.ISO_DATE_TIME)
|
||||
)
|
||||
} catch (_: android.database.sqlite.SQLiteConstraintException) {
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
fun loadBuilding(oid: Int): Building {
|
||||
return db.buildingDao().get(oid).let {
|
||||
fun loadBuilding(oid: Int): Building? {
|
||||
return db.buildingDao().get(oid)?.let {
|
||||
if (LocalDateTime.parse(
|
||||
it.expiredAt,
|
||||
DateTimeFormatter.ISO_DATE_TIME
|
||||
) > LocalDateTime.now()
|
||||
) {
|
||||
db.buildingDao().delete(it)
|
||||
return null
|
||||
}
|
||||
Building(
|
||||
it.name,
|
||||
it.gid,
|
||||
@@ -66,15 +76,16 @@ data class AuditoriumDB(
|
||||
@PrimaryKey val oid: Int,
|
||||
@ColumnInfo val name: String,
|
||||
@ColumnInfo val floor: Int?,
|
||||
@ColumnInfo val buildingOid: Int
|
||||
@ColumnInfo val buildingOid: Int,
|
||||
@ColumnInfo val expiredAt: String
|
||||
)
|
||||
|
||||
@Dao
|
||||
interface AuditoriumDao {
|
||||
@Query("SELECT * FROM auditoriumdb WHERE oid = :oid LIMIT 1")
|
||||
fun get(oid: Int): AuditoriumDB
|
||||
fun get(oid: Int): AuditoriumDB?
|
||||
|
||||
@Insert
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
fun insert(auditorium: AuditoriumDB)
|
||||
|
||||
@Delete
|
||||
@@ -82,27 +93,34 @@ interface AuditoriumDao {
|
||||
}
|
||||
|
||||
fun cacheAuditorium(auditorium: Auditorium) {
|
||||
try {
|
||||
cacheBuilding(auditorium.building)
|
||||
db.auditoriumDao().insert(
|
||||
AuditoriumDB(
|
||||
auditorium.oid,
|
||||
auditorium.name,
|
||||
auditorium.floor,
|
||||
auditorium.building.oid
|
||||
)
|
||||
cacheBuilding(auditorium.building)
|
||||
db.auditoriumDao().insert(
|
||||
AuditoriumDB(
|
||||
auditorium.oid,
|
||||
auditorium.name,
|
||||
auditorium.floor,
|
||||
auditorium.building.oid,
|
||||
LocalDateTime.now().plusMonths(1).format(DateTimeFormatter.ISO_DATE_TIME)
|
||||
)
|
||||
} catch (_: android.database.sqlite.SQLiteConstraintException) {
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
fun loadAuditorium(oid: Int): Auditorium {
|
||||
return db.auditoriumDao().get(oid).let {
|
||||
Auditorium(
|
||||
fun loadAuditorium(oid: Int): Auditorium? {
|
||||
return db.auditoriumDao().get(oid)?.let {
|
||||
if (LocalDateTime.parse(
|
||||
it.expiredAt,
|
||||
DateTimeFormatter.ISO_DATE_TIME
|
||||
) > LocalDateTime.now()
|
||||
) {
|
||||
db.auditoriumDao().delete(it)
|
||||
return null
|
||||
}
|
||||
val building = loadBuilding(it.buildingOid) ?: return null
|
||||
return Auditorium(
|
||||
it.name,
|
||||
it.oid,
|
||||
it.floor ?: 0,
|
||||
loadBuilding(it.buildingOid)
|
||||
building
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -111,15 +129,16 @@ fun loadAuditorium(oid: Int): Auditorium {
|
||||
data class DisciplineDB(
|
||||
@PrimaryKey val oid: Int,
|
||||
@ColumnInfo val name: String,
|
||||
@ColumnInfo val type: Int
|
||||
@ColumnInfo val type: Int,
|
||||
@ColumnInfo val expiredAt: String
|
||||
)
|
||||
|
||||
@Dao
|
||||
interface DisciplineDao {
|
||||
@Query("SELECT * FROM disciplinedb WHERE oid = :oid LIMIT 1")
|
||||
fun get(oid: Int): DisciplineDB
|
||||
fun get(oid: Int): DisciplineDB?
|
||||
|
||||
@Insert
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
fun insert(discipline: DisciplineDB)
|
||||
|
||||
@Delete
|
||||
@@ -127,21 +146,28 @@ interface DisciplineDao {
|
||||
}
|
||||
|
||||
fun cacheDiscipline(discipline: Discipline) {
|
||||
try {
|
||||
db.disciplineDao().insert(
|
||||
DisciplineDB(
|
||||
discipline.oid,
|
||||
discipline.name,
|
||||
discipline.type
|
||||
)
|
||||
db.disciplineDao().insert(
|
||||
DisciplineDB(
|
||||
discipline.oid,
|
||||
discipline.name,
|
||||
discipline.type,
|
||||
LocalDateTime.now().plusMonths(1).format(DateTimeFormatter.ISO_DATE_TIME)
|
||||
)
|
||||
} catch (_: android.database.sqlite.SQLiteConstraintException) {
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
fun loadDiscipline(oid: Int): Discipline {
|
||||
return db.disciplineDao().get(oid).let {
|
||||
Discipline(
|
||||
fun loadDiscipline(oid: Int): Discipline? {
|
||||
return db.disciplineDao().get(oid)?.let {
|
||||
if (LocalDateTime.parse(
|
||||
it.expiredAt,
|
||||
DateTimeFormatter.ISO_DATE_TIME
|
||||
) > LocalDateTime.now()
|
||||
) {
|
||||
db.disciplineDao().delete(it)
|
||||
return null
|
||||
}
|
||||
|
||||
return Discipline(
|
||||
it.name,
|
||||
it.oid,
|
||||
it.type
|
||||
@@ -154,15 +180,16 @@ data class KindOfWorkDB(
|
||||
@PrimaryKey val oid: Int,
|
||||
@ColumnInfo val name: String,
|
||||
@ColumnInfo val uid: String,
|
||||
@ColumnInfo val complexity: Int
|
||||
@ColumnInfo val complexity: Int,
|
||||
@ColumnInfo val expiredAt: String
|
||||
)
|
||||
|
||||
@Dao
|
||||
interface KindOfWorkDao {
|
||||
@Query("SELECT * FROM kindofworkdb WHERE oid = :oid LIMIT 1")
|
||||
fun get(oid: Int): KindOfWorkDB
|
||||
fun get(oid: Int): KindOfWorkDB?
|
||||
|
||||
@Insert
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
fun insert(kindOfWork: KindOfWorkDB)
|
||||
|
||||
@Delete
|
||||
@@ -170,22 +197,29 @@ interface KindOfWorkDao {
|
||||
}
|
||||
|
||||
fun cacheKindOfWork(kindOfWork: KindOfWork) {
|
||||
try {
|
||||
db.kindOfWorkDao().insert(
|
||||
KindOfWorkDB(
|
||||
kindOfWork.oid,
|
||||
kindOfWork.name,
|
||||
kindOfWork.uid,
|
||||
kindOfWork.complexity
|
||||
)
|
||||
db.kindOfWorkDao().insert(
|
||||
KindOfWorkDB(
|
||||
kindOfWork.oid,
|
||||
kindOfWork.name,
|
||||
kindOfWork.uid,
|
||||
kindOfWork.complexity,
|
||||
LocalDateTime.now().plusMonths(1).format(DateTimeFormatter.ISO_DATE_TIME)
|
||||
)
|
||||
} catch (_: android.database.sqlite.SQLiteConstraintException) {
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
fun loadKindOfWork(oid: Int): KindOfWork {
|
||||
return db.kindOfWorkDao().get(oid).let {
|
||||
KindOfWork(
|
||||
fun loadKindOfWork(oid: Int): KindOfWork? {
|
||||
return db.kindOfWorkDao().get(oid)?.let {
|
||||
if (LocalDateTime.parse(
|
||||
it.expiredAt,
|
||||
DateTimeFormatter.ISO_DATE_TIME
|
||||
) > LocalDateTime.now()
|
||||
) {
|
||||
db.kindOfWorkDao().delete(it)
|
||||
return null
|
||||
}
|
||||
|
||||
return KindOfWork(
|
||||
it.name,
|
||||
it.oid,
|
||||
it.uid,
|
||||
@@ -200,15 +234,16 @@ data class LecturerDB(
|
||||
@ColumnInfo val name: String,
|
||||
@ColumnInfo val rank: LecturerRank,
|
||||
@ColumnInfo val email: String,
|
||||
@ColumnInfo val uid: String
|
||||
@ColumnInfo val uid: String,
|
||||
@ColumnInfo val expiredAt: String
|
||||
)
|
||||
|
||||
@Dao
|
||||
interface LecturerDao {
|
||||
@Query("SELECT * FROM lecturerdb WHERE unnId = :unnId LIMIT 1")
|
||||
fun get(unnId: Int): LecturerDB
|
||||
fun get(unnId: Int): LecturerDB?
|
||||
|
||||
@Insert
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
fun insert(lecturer: LecturerDB)
|
||||
|
||||
@Delete
|
||||
@@ -216,23 +251,30 @@ interface LecturerDao {
|
||||
}
|
||||
|
||||
fun cacheLecturer(lecturer: Lecturer) {
|
||||
try {
|
||||
db.lecturerDao().insert(
|
||||
LecturerDB(
|
||||
lecturer.unnId,
|
||||
lecturer.name,
|
||||
lecturer.rank,
|
||||
lecturer.email,
|
||||
lecturer.uid
|
||||
)
|
||||
db.lecturerDao().insert(
|
||||
LecturerDB(
|
||||
lecturer.unnId,
|
||||
lecturer.name,
|
||||
lecturer.rank,
|
||||
lecturer.email,
|
||||
lecturer.uid,
|
||||
LocalDateTime.now().plusMonths(1).format(DateTimeFormatter.ISO_DATE_TIME)
|
||||
)
|
||||
} catch (_: android.database.sqlite.SQLiteConstraintException) {
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
fun loadLecturer(unnId: Int): Lecturer {
|
||||
return db.lecturerDao().get(unnId).let {
|
||||
Lecturer(
|
||||
fun loadLecturer(unnId: Int): Lecturer? {
|
||||
return db.lecturerDao().get(unnId)?.let {
|
||||
if (LocalDateTime.parse(
|
||||
it.expiredAt,
|
||||
DateTimeFormatter.ISO_DATE_TIME
|
||||
) > LocalDateTime.now()
|
||||
) {
|
||||
db.lecturerDao().delete(it)
|
||||
return null
|
||||
}
|
||||
|
||||
return Lecturer(
|
||||
it.name,
|
||||
it.rank,
|
||||
it.email,
|
||||
@@ -253,62 +295,90 @@ data class ScheduleUnitDB(
|
||||
@ColumnInfo val auditoriumOid: Int,
|
||||
@ColumnInfo val disciplineOid: Int,
|
||||
@ColumnInfo val kindOfWorkOid: Int,
|
||||
@ColumnInfo val lecturerId: Int // TODO: many-to-many
|
||||
@ColumnInfo val lecturerId: Int, // TODO: many-to-many
|
||||
|
||||
@ColumnInfo val expiredAt: String
|
||||
)
|
||||
@Dao
|
||||
interface ScheduleItemDao {
|
||||
@Query("SELECT * FROM scheduleUnitDB WHERE oid = :oid LIMIT 1")
|
||||
fun getScheduleItem(oid: Int): ScheduleUnitDB?
|
||||
fun getSchedule(oid: Int): ScheduleUnitDB?
|
||||
|
||||
@Query("SELECT * FROM scheduleUnitDB WHERE date = :date ORDER BY `begin`")
|
||||
fun getSchedule(date: String): List<ScheduleUnitDB>
|
||||
|
||||
@Insert
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
fun insert(user: ScheduleUnitDB)
|
||||
|
||||
@Delete
|
||||
fun delete(user: ScheduleUnitDB)
|
||||
}
|
||||
|
||||
fun cacheScheduleItems(items: ArrayList<ScheduleUnit>) {
|
||||
for (item in items) {
|
||||
try {
|
||||
cacheAuditorium(item.auditorium)
|
||||
cacheDiscipline(item.discipline)
|
||||
cacheKindOfWork(item.kindOfWork)
|
||||
cacheLecturer(item.lecturers[0])
|
||||
fun cacheSchedule(item: ScheduleUnit) {
|
||||
cacheAuditorium(item.auditorium)
|
||||
cacheDiscipline(item.discipline)
|
||||
cacheKindOfWork(item.kindOfWork)
|
||||
cacheLecturer(item.lecturers[0])
|
||||
|
||||
db.scheduleDao().insert(
|
||||
ScheduleUnitDB(
|
||||
item.oid,
|
||||
item.date.format(DateTimeFormatter.ISO_DATE),
|
||||
item.stream,
|
||||
item.begin.format(DateTimeFormatter.ISO_TIME),
|
||||
item.end.format(DateTimeFormatter.ISO_TIME),
|
||||
item.auditorium.oid,
|
||||
item.discipline.oid,
|
||||
item.kindOfWork.oid,
|
||||
item.lecturers[0].unnId
|
||||
)
|
||||
)
|
||||
} catch (_: android.database.sqlite.SQLiteConstraintException) {
|
||||
}
|
||||
}
|
||||
db.scheduleDao().insert(
|
||||
ScheduleUnitDB(
|
||||
item.oid,
|
||||
item.date.format(DateTimeFormatter.ISO_DATE),
|
||||
item.stream,
|
||||
item.begin.format(DateTimeFormatter.ISO_TIME),
|
||||
item.end.format(DateTimeFormatter.ISO_TIME),
|
||||
item.auditorium.oid,
|
||||
item.discipline.oid,
|
||||
item.kindOfWork.oid,
|
||||
item.lecturers[0].unnId,
|
||||
when {
|
||||
(LocalDate.now() > item.date) -> LocalDateTime.now().plusWeeks(2)
|
||||
(LocalDate.now().plusWeeks(1) > item.date) -> LocalDateTime.now().plusDays(1)
|
||||
(LocalDate.now().plusWeeks(2) > item.date) -> LocalDateTime.now().plusWeeks(1)
|
||||
else -> LocalDateTime.now().plusWeeks(2)
|
||||
}.format(DateTimeFormatter.ISO_DATE_TIME)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fun loadSchedule(date: LocalDate): ArrayList<ScheduleUnit> {
|
||||
return ArrayList(db.scheduleDao().getSchedule(date.format(DateTimeFormatter.ISO_DATE)).map {
|
||||
ScheduleUnit(
|
||||
fun cacheSchedule(items: ArrayList<ScheduleUnit>) {
|
||||
for (item in items)
|
||||
cacheSchedule(item)
|
||||
}
|
||||
|
||||
fun loadSchedule(oid: Int): ScheduleUnit? {
|
||||
db.scheduleDao().getSchedule(oid)?.let {
|
||||
Log.d("load", it.oid.toString())
|
||||
if (LocalDateTime.parse(
|
||||
it.expiredAt,
|
||||
DateTimeFormatter.ISO_DATE_TIME
|
||||
) < LocalDateTime.now()
|
||||
) {
|
||||
Log.d("delete", it.oid.toString())
|
||||
db.scheduleDao().delete(it)
|
||||
return null
|
||||
}
|
||||
|
||||
return ScheduleUnit(
|
||||
it.oid,
|
||||
loadAuditorium(it.auditoriumOid),
|
||||
loadAuditorium(it.auditoriumOid) ?: return null,
|
||||
LocalDate.parse(it.date, DateTimeFormatter.ISO_DATE),
|
||||
loadDiscipline(it.disciplineOid),
|
||||
loadKindOfWork(it.kindOfWorkOid),
|
||||
arrayListOf(loadLecturer(it.lecturerId)),
|
||||
loadDiscipline(it.disciplineOid) ?: return null,
|
||||
loadKindOfWork(it.kindOfWorkOid) ?: return null,
|
||||
arrayListOf(loadLecturer(it.lecturerId) ?: return null),
|
||||
it.stream,
|
||||
LocalTime.parse(it.begin, DateTimeFormatter.ISO_TIME),
|
||||
LocalTime.parse(it.end, DateTimeFormatter.ISO_TIME)
|
||||
)
|
||||
})
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
fun loadSchedule(date: LocalDate): ArrayList<ScheduleUnit> {
|
||||
db.scheduleDao().getSchedule(date.format(DateTimeFormatter.ISO_DATE))
|
||||
.mapNotNull { Log.d("meow", "${it.oid}: ${loadSchedule(it.oid)}") }
|
||||
return ArrayList(
|
||||
db.scheduleDao().getSchedule(date.format(DateTimeFormatter.ISO_DATE))
|
||||
.mapNotNull { loadSchedule(it.oid) }
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user