feat(cache): Cache ScheduleItem

This commit is contained in:
sweetbread 2024-03-28 19:26:56 +03:00 committed by Sweetbread
parent 172f997af6
commit 455a3cae4c
4 changed files with 354 additions and 7 deletions

View File

@ -11,7 +11,9 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import org.json.JSONArray import org.json.JSONArray
import org.json.JSONObject import org.json.JSONObject
import ru.sweetbread.unn.db.cacheScheduleItems
import ru.sweetbread.unn.db.cacheUser import ru.sweetbread.unn.db.cacheUser
import ru.sweetbread.unn.db.loadSchedule
import ru.sweetbread.unn.db.loadUserByBitrixId import ru.sweetbread.unn.db.loadUserByBitrixId
import ru.sweetbread.unn.ui.layout.LoginData import ru.sweetbread.unn.ui.layout.LoginData
import ru.sweetbread.unn.ui.layout.client import ru.sweetbread.unn.ui.layout.client
@ -192,6 +194,22 @@ private suspend fun getMyself(login: String) {
) )
} }
suspend fun getScheduleDay(
type: Type = ME.type,
id: Int = ME.unnId!!,
date: LocalDate
): ArrayList<ScheduleUnit> {
if ((type == ME.type) and (id == ME.unnId!!)) {
val schedule = withContext(Dispatchers.IO) { loadSchedule(date) }
if (schedule.size != 0) {
return schedule
}
}
return getSchedule(type, id, date, date)
}
suspend fun getSchedule( suspend fun getSchedule(
type: Type = ME.type, type: Type = ME.type,
id: Int = ME.unnId!!, id: Int = ME.unnId!!,
@ -269,6 +287,10 @@ suspend fun getSchedule(
) )
) )
} }
if ((type == ME.type) and (id == ME.unnId!!)) {
cacheScheduleItems(out)
}
return out return out
} }
@ -310,11 +332,9 @@ suspend fun getBlogposts(): ArrayList<Post> {
} }
suspend fun getUserByBitrixId(id: Int): User { suspend fun getUserByBitrixId(id: Int): User {
var user: User?
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {
user = loadUserByBitrixId(id) loadUserByBitrixId(id)
} }?.let { return it }
user?.let { return user as User }
val userId = JSONObject(client.get("$vuzapiURL/user/bx/$id") { val userId = JSONObject(client.get("$vuzapiURL/user/bx/$id") {
header("Cookie", "PHPSESSID=$PHPSESSID") header("Cookie", "PHPSESSID=$PHPSESSID")

View File

@ -3,7 +3,20 @@ package ru.sweetbread.unn.db
import androidx.room.Database import androidx.room.Database
import androidx.room.RoomDatabase import androidx.room.RoomDatabase
@Database(entities = [UserDB::class], version = 1) @Database(entities = [
UserDB::class,
BuildingDB::class,
AuditoriumDB::class,
DisciplineDB::class,
KindOfWorkDB::class,
LecturerDB::class,
ScheduleUnitDB::class], version = 1)
abstract class AppDatabase : RoomDatabase() { abstract class AppDatabase : RoomDatabase() {
abstract fun userDao(): UserDao abstract fun userDao(): UserDao
abstract fun scheduleDao(): ScheduleItemDao
abstract fun auditoriumDao(): AuditoriumDao
abstract fun buildingDao(): BuildingDao
abstract fun disciplineDao(): DisciplineDao
abstract fun kindOfWorkDao(): KindOfWorkDao
abstract fun lecturerDao(): LecturerDao
} }

View File

@ -0,0 +1,314 @@
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.PrimaryKey
import androidx.room.Query
import ru.sweetbread.unn.Auditorium
import ru.sweetbread.unn.Building
import ru.sweetbread.unn.Discipline
import ru.sweetbread.unn.KindOfWork
import ru.sweetbread.unn.Lecturer
import ru.sweetbread.unn.LecturerRank
import ru.sweetbread.unn.ScheduleUnit
import ru.sweetbread.unn.ui.layout.db
import java.time.LocalDate
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
)
@Dao
interface BuildingDao {
@Query("SELECT * FROM buildingdb WHERE oid = :oid LIMIT 1")
fun get(oid: Int): BuildingDB
@Insert
fun insert(building: BuildingDB)
@Delete
fun delete(building: BuildingDB)
}
fun cacheBuilding(building: Building) {
try {
db.buildingDao().insert(
BuildingDB(
building.oid,
building.name,
building.gid
)
)
} catch (_: android.database.sqlite.SQLiteConstraintException) {
}
}
fun loadBuilding(oid: Int): Building {
return db.buildingDao().get(oid).let {
Building(
it.name,
it.gid,
it.oid
)
}
}
@Entity
data class AuditoriumDB(
@PrimaryKey val oid: Int,
@ColumnInfo val name: String,
@ColumnInfo val floor: Int?,
@ColumnInfo val buildingOid: Int
)
@Dao
interface AuditoriumDao {
@Query("SELECT * FROM auditoriumdb WHERE oid = :oid LIMIT 1")
fun get(oid: Int): AuditoriumDB
@Insert
fun insert(auditorium: AuditoriumDB)
@Delete
fun delete(auditorium: AuditoriumDB)
}
fun cacheAuditorium(auditorium: Auditorium) {
try {
cacheBuilding(auditorium.building)
db.auditoriumDao().insert(
AuditoriumDB(
auditorium.oid,
auditorium.name,
auditorium.floor,
auditorium.building.oid
)
)
} catch (_: android.database.sqlite.SQLiteConstraintException) {
}
}
fun loadAuditorium(oid: Int): Auditorium {
return db.auditoriumDao().get(oid).let {
Auditorium(
it.name,
it.oid,
it.floor ?: 0,
loadBuilding(it.buildingOid)
)
}
}
@Entity
data class DisciplineDB(
@PrimaryKey val oid: Int,
@ColumnInfo val name: String,
@ColumnInfo val type: Int
)
@Dao
interface DisciplineDao {
@Query("SELECT * FROM disciplinedb WHERE oid = :oid LIMIT 1")
fun get(oid: Int): DisciplineDB
@Insert
fun insert(discipline: DisciplineDB)
@Delete
fun delete(discipline: DisciplineDB)
}
fun cacheDiscipline(discipline: Discipline) {
try {
db.disciplineDao().insert(
DisciplineDB(
discipline.oid,
discipline.name,
discipline.type
)
)
} catch (_: android.database.sqlite.SQLiteConstraintException) {
}
}
fun loadDiscipline(oid: Int): Discipline {
return db.disciplineDao().get(oid).let {
Discipline(
it.name,
it.oid,
it.type
)
}
}
@Entity
data class KindOfWorkDB(
@PrimaryKey val oid: Int,
@ColumnInfo val name: String,
@ColumnInfo val uid: String,
@ColumnInfo val complexity: Int
)
@Dao
interface KindOfWorkDao {
@Query("SELECT * FROM kindofworkdb WHERE oid = :oid LIMIT 1")
fun get(oid: Int): KindOfWorkDB
@Insert
fun insert(kindOfWork: KindOfWorkDB)
@Delete
fun delete(kindOfWork: KindOfWorkDB)
}
fun cacheKindOfWork(kindOfWork: KindOfWork) {
try {
db.kindOfWorkDao().insert(
KindOfWorkDB(
kindOfWork.oid,
kindOfWork.name,
kindOfWork.uid,
kindOfWork.complexity
)
)
} catch (_: android.database.sqlite.SQLiteConstraintException) {
}
}
fun loadKindOfWork(oid: Int): KindOfWork {
return db.kindOfWorkDao().get(oid).let {
KindOfWork(
it.name,
it.oid,
it.uid,
it.complexity
)
}
}
@Entity
data class LecturerDB(
@PrimaryKey val unnId: Int,
@ColumnInfo val name: String,
@ColumnInfo val rank: LecturerRank,
@ColumnInfo val email: String,
@ColumnInfo val uid: String
)
@Dao
interface LecturerDao {
@Query("SELECT * FROM lecturerdb WHERE unnId = :unnId LIMIT 1")
fun get(unnId: Int): LecturerDB
@Insert
fun insert(lecturer: LecturerDB)
@Delete
fun delete(lecturer: LecturerDB)
}
fun cacheLecturer(lecturer: Lecturer) {
try {
db.lecturerDao().insert(
LecturerDB(
lecturer.unnId,
lecturer.name,
lecturer.rank,
lecturer.email,
lecturer.uid
)
)
} catch (_: android.database.sqlite.SQLiteConstraintException) {
}
}
fun loadLecturer(unnId: Int): Lecturer {
return db.lecturerDao().get(unnId).let {
Lecturer(
it.name,
it.rank,
it.email,
it.unnId,
it.uid
)
}
}
@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 lecturerId: Int // TODO: many-to-many
)
@Dao
interface ScheduleItemDao {
@Query("SELECT * FROM scheduleUnitDB WHERE oid = :oid LIMIT 1")
fun getScheduleItem(oid: Int): ScheduleUnitDB?
@Query("SELECT * FROM scheduleUnitDB WHERE date = :date ORDER BY `begin`")
fun getSchedule(date: String): List<ScheduleUnitDB>
@Insert
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])
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) {
}
}
}
fun loadSchedule(date: LocalDate): ArrayList<ScheduleUnit> {
return ArrayList(db.scheduleDao().getSchedule(date.format(DateTimeFormatter.ISO_DATE)).map {
ScheduleUnit(
it.oid,
loadAuditorium(it.auditoriumOid),
LocalDate.parse(it.date, DateTimeFormatter.ISO_DATE),
loadDiscipline(it.disciplineOid),
loadKindOfWork(it.kindOfWorkOid),
arrayListOf(loadLecturer(it.lecturerId)),
it.stream,
LocalTime.parse(it.begin, DateTimeFormatter.ISO_TIME),
LocalTime.parse(it.end, DateTimeFormatter.ISO_TIME)
)
})
}

View File

@ -49,7 +49,7 @@ import ru.sweetbread.unn.Lecturer
import ru.sweetbread.unn.LecturerRank import ru.sweetbread.unn.LecturerRank
import ru.sweetbread.unn.R import ru.sweetbread.unn.R
import ru.sweetbread.unn.ScheduleUnit import ru.sweetbread.unn.ScheduleUnit
import ru.sweetbread.unn.getSchedule import ru.sweetbread.unn.getScheduleDay
import ru.sweetbread.unn.ui.theme.UNNTheme import ru.sweetbread.unn.ui.theme.UNNTheme
import java.time.DayOfWeek import java.time.DayOfWeek
import java.time.LocalDate import java.time.LocalDate
@ -119,7 +119,7 @@ fun ScheduleDay(modifier: Modifier = Modifier, date: LocalDate) {
LaunchedEffect(date != loadedDate) { LaunchedEffect(date != loadedDate) {
scope.launch(Dispatchers.IO) { scope.launch(Dispatchers.IO) {
lessons.clear() lessons.clear()
lessons.addAll(getSchedule(start = date, finish = date)) lessons.addAll(getScheduleDay(date = date))
loadedDate = date loadedDate = date
} }
} }