From 455a3cae4c31be5eabc0f3f5583bb6eab4fd2fe7 Mon Sep 17 00:00:00 2001 From: sweetbread Date: Thu, 28 Mar 2024 19:26:56 +0300 Subject: [PATCH] feat(cache): Cache ScheduleItem --- app/src/main/java/ru/sweetbread/unn/API.kt | 28 +- app/src/main/java/ru/sweetbread/unn/db/DB.kt | 15 +- .../java/ru/sweetbread/unn/db/Schedule.kt | 314 ++++++++++++++++++ .../ru/sweetbread/unn/ui/composes/Schedule.kt | 4 +- 4 files changed, 354 insertions(+), 7 deletions(-) create mode 100644 app/src/main/java/ru/sweetbread/unn/db/Schedule.kt diff --git a/app/src/main/java/ru/sweetbread/unn/API.kt b/app/src/main/java/ru/sweetbread/unn/API.kt index 7e1edc4..4c37385 100644 --- a/app/src/main/java/ru/sweetbread/unn/API.kt +++ b/app/src/main/java/ru/sweetbread/unn/API.kt @@ -11,7 +11,9 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import org.json.JSONArray import org.json.JSONObject +import ru.sweetbread.unn.db.cacheScheduleItems import ru.sweetbread.unn.db.cacheUser +import ru.sweetbread.unn.db.loadSchedule import ru.sweetbread.unn.db.loadUserByBitrixId import ru.sweetbread.unn.ui.layout.LoginData 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 { + + 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( type: Type = ME.type, id: Int = ME.unnId!!, @@ -269,6 +287,10 @@ suspend fun getSchedule( ) ) } + + if ((type == ME.type) and (id == ME.unnId!!)) { + cacheScheduleItems(out) + } return out } @@ -310,11 +332,9 @@ suspend fun getBlogposts(): ArrayList { } suspend fun getUserByBitrixId(id: Int): User { - var user: User? withContext(Dispatchers.IO) { - user = loadUserByBitrixId(id) - } - user?.let { return user as User } + loadUserByBitrixId(id) + }?.let { return it } val userId = JSONObject(client.get("$vuzapiURL/user/bx/$id") { header("Cookie", "PHPSESSID=$PHPSESSID") diff --git a/app/src/main/java/ru/sweetbread/unn/db/DB.kt b/app/src/main/java/ru/sweetbread/unn/db/DB.kt index 2dbdbf7..c71429a 100644 --- a/app/src/main/java/ru/sweetbread/unn/db/DB.kt +++ b/app/src/main/java/ru/sweetbread/unn/db/DB.kt @@ -3,7 +3,20 @@ package ru.sweetbread.unn.db import androidx.room.Database 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 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 } diff --git a/app/src/main/java/ru/sweetbread/unn/db/Schedule.kt b/app/src/main/java/ru/sweetbread/unn/db/Schedule.kt new file mode 100644 index 0000000..9da3a94 --- /dev/null +++ b/app/src/main/java/ru/sweetbread/unn/db/Schedule.kt @@ -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 + + @Insert + fun insert(user: ScheduleUnitDB) + + @Delete + fun delete(user: ScheduleUnitDB) +} + +fun cacheScheduleItems(items: ArrayList) { + 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 { + 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) + ) + }) + +} \ No newline at end of file diff --git a/app/src/main/java/ru/sweetbread/unn/ui/composes/Schedule.kt b/app/src/main/java/ru/sweetbread/unn/ui/composes/Schedule.kt index 07f3f02..7654061 100644 --- a/app/src/main/java/ru/sweetbread/unn/ui/composes/Schedule.kt +++ b/app/src/main/java/ru/sweetbread/unn/ui/composes/Schedule.kt @@ -49,7 +49,7 @@ import ru.sweetbread.unn.Lecturer import ru.sweetbread.unn.LecturerRank import ru.sweetbread.unn.R import ru.sweetbread.unn.ScheduleUnit -import ru.sweetbread.unn.getSchedule +import ru.sweetbread.unn.getScheduleDay import ru.sweetbread.unn.ui.theme.UNNTheme import java.time.DayOfWeek import java.time.LocalDate @@ -119,7 +119,7 @@ fun ScheduleDay(modifier: Modifier = Modifier, date: LocalDate) { LaunchedEffect(date != loadedDate) { scope.launch(Dispatchers.IO) { lessons.clear() - lessons.addAll(getSchedule(start = date, finish = date)) + lessons.addAll(getScheduleDay(date = date)) loadedDate = date } }