forked from agzam/vyatsu-schedule
init
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
package agzam.vyatsu.data.local
|
||||
|
||||
import androidx.room.Database
|
||||
import androidx.room.RoomDatabase
|
||||
|
||||
@Database(
|
||||
entities = [
|
||||
GroupEntity::class,
|
||||
ScheduleEntity::class,
|
||||
PreferenceEntity::class
|
||||
],
|
||||
version = 1,
|
||||
exportSchema = false
|
||||
)
|
||||
abstract class AppDatabase : RoomDatabase() {
|
||||
abstract fun groupDao(): GroupDao
|
||||
abstract fun scheduleDao(): ScheduleDao
|
||||
abstract fun preferencesDao(): PreferencesDao
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package agzam.vyatsu.data.local
|
||||
|
||||
import agzam.vyatsu.domain.model.Day
|
||||
import com.squareup.moshi.JsonClass
|
||||
import java.time.LocalDate
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class DayDto(
|
||||
val date: String,
|
||||
val slots: List<SlotDto> = emptyList()
|
||||
) {
|
||||
fun toDomain(): Day = Day(
|
||||
date = LocalDate.parse(date),
|
||||
intervals = slots.map { it.toDomain() }
|
||||
)
|
||||
|
||||
companion object {
|
||||
fun fromDomain(d: Day): DayDto = DayDto(
|
||||
date = d.date.toString(),
|
||||
slots = d.intervals.map { SlotDto.fromDomain(it) }
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package agzam.vyatsu.data.local
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@Dao
|
||||
interface GroupDao {
|
||||
@Query("SELECT * FROM groups ORDER BY name")
|
||||
fun observeAll(): Flow<List<GroupEntity>>
|
||||
|
||||
@Query("SELECT * FROM groups WHERE id = :id")
|
||||
suspend fun getById(id: String): GroupEntity?
|
||||
|
||||
@Query("SELECT * FROM groups WHERE faculty = :faculty ORDER BY name")
|
||||
suspend fun getByFaculty(faculty: String): List<GroupEntity>
|
||||
|
||||
@Query("SELECT DISTINCT faculty FROM groups ORDER BY faculty")
|
||||
suspend fun getFaculties(): List<String>
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
suspend fun insertAll(groups: List<GroupEntity>)
|
||||
|
||||
@Query("SELECT MAX(lastSyncedAt) FROM groups")
|
||||
suspend fun maxSyncedAt(): Long?
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package agzam.vyatsu.data.local
|
||||
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
|
||||
@Entity(tableName = "groups")
|
||||
data class GroupEntity(
|
||||
@PrimaryKey val id: String,
|
||||
val name: String,
|
||||
val faculty: String,
|
||||
val autumnFirst: String,
|
||||
val autumnSecond: String,
|
||||
val springFirst: String,
|
||||
val springSecond: String,
|
||||
val lastSyncedAt: Long
|
||||
)
|
||||
@@ -0,0 +1,38 @@
|
||||
package agzam.vyatsu.data.local
|
||||
|
||||
import agzam.vyatsu.domain.model.Lesson
|
||||
import agzam.vyatsu.domain.model.LessonType
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class LessonDto(
|
||||
val raw: String = "",
|
||||
val room: String? = null,
|
||||
val group: String? = null,
|
||||
val subgroup: String? = null,
|
||||
val subject: String? = null,
|
||||
val type: String = "",
|
||||
val teacher: String? = null
|
||||
) {
|
||||
fun toDomain(): Lesson = Lesson(
|
||||
raw = raw,
|
||||
room = room?.takeIf { it.isNotBlank() },
|
||||
group = group?.takeIf { it.isNotBlank() },
|
||||
subgroup = subgroup?.takeIf { it.isNotBlank() },
|
||||
subject = subject?.takeIf { it.isNotBlank() },
|
||||
type = runCatching { LessonType.valueOf(type) }.getOrDefault(LessonType.OTHER),
|
||||
teacher = teacher?.takeIf { it.isNotBlank() }
|
||||
)
|
||||
|
||||
companion object {
|
||||
fun fromDomain(l: Lesson): LessonDto = LessonDto(
|
||||
raw = l.raw,
|
||||
room = l.room,
|
||||
group = l.group,
|
||||
subgroup = l.subgroup,
|
||||
subject = l.subject,
|
||||
type = l.type.name,
|
||||
teacher = l.teacher
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package agzam.vyatsu.data.local
|
||||
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
|
||||
@Entity(tableName = "preferences")
|
||||
data class PreferenceEntity(
|
||||
@PrimaryKey val key: String,
|
||||
val value: String
|
||||
)
|
||||
@@ -0,0 +1,18 @@
|
||||
package agzam.vyatsu.data.local
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Query
|
||||
|
||||
@Dao
|
||||
interface PreferencesDao {
|
||||
@Query("SELECT value FROM preferences WHERE key = 'selectedGroupId'")
|
||||
suspend fun selectedGroupId(): String?
|
||||
|
||||
@Query(
|
||||
"INSERT OR REPLACE INTO preferences(key, value) VALUES('selectedGroupId', :groupId)"
|
||||
)
|
||||
suspend fun setSelectedGroup(groupId: String)
|
||||
|
||||
@Query("DELETE FROM preferences WHERE key = 'selectedGroupId'")
|
||||
suspend fun clearSelectedGroup()
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package agzam.vyatsu.data.local
|
||||
|
||||
import agzam.vyatsu.domain.model.Day
|
||||
import com.squareup.moshi.Moshi
|
||||
import com.squareup.moshi.Types
|
||||
|
||||
class ScheduleCodec(moshi: Moshi) {
|
||||
private val type: java.lang.reflect.Type =
|
||||
Types.newParameterizedType(List::class.java, DayDto::class.java)
|
||||
private val adapter = moshi.adapter<List<DayDto>>(type)
|
||||
|
||||
fun toJson(days: List<Day>): String {
|
||||
val dto = days.map { DayDto.fromDomain(it) }
|
||||
return adapter.toJson(dto)
|
||||
}
|
||||
|
||||
fun fromJson(json: String): List<Day> {
|
||||
return try {
|
||||
val dto = adapter.fromJson(json) ?: return emptyList()
|
||||
dto.map { it.toDomain() }
|
||||
} catch (t: Throwable) {
|
||||
emptyList()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package agzam.vyatsu.data.local
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@Dao
|
||||
interface ScheduleDao {
|
||||
@Query("SELECT * FROM schedules WHERE groupId = :groupId")
|
||||
fun observe(groupId: String): Flow<ScheduleEntity?>
|
||||
|
||||
@Query("SELECT * FROM schedules WHERE groupId = :groupId")
|
||||
suspend fun get(groupId: String): ScheduleEntity?
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
suspend fun upsert(entity: ScheduleEntity)
|
||||
|
||||
@Query("DELETE FROM schedules WHERE groupId = :groupId")
|
||||
suspend fun delete(groupId: String)
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package agzam.vyatsu.data.local
|
||||
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
|
||||
@Entity(tableName = "schedules")
|
||||
data class ScheduleEntity(
|
||||
@PrimaryKey val groupId: String,
|
||||
val season: String,
|
||||
val dateRangeFirst: String,
|
||||
val dateRangeSecond: String,
|
||||
val weeksJson: String,
|
||||
val lastSyncedAt: Long
|
||||
)
|
||||
@@ -0,0 +1,26 @@
|
||||
package agzam.vyatsu.data.local
|
||||
|
||||
import agzam.vyatsu.domain.model.TimeSlot
|
||||
import com.squareup.moshi.JsonClass
|
||||
import java.time.LocalTime
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class SlotDto(
|
||||
val start: String,
|
||||
val end: String,
|
||||
val lessons: List<LessonDto> = emptyList()
|
||||
) {
|
||||
fun toDomain(): TimeSlot = TimeSlot(
|
||||
start = LocalTime.parse(start),
|
||||
end = LocalTime.parse(end),
|
||||
lessons = lessons.map { it.toDomain() }
|
||||
)
|
||||
|
||||
companion object {
|
||||
fun fromDomain(s: TimeSlot): SlotDto = SlotDto(
|
||||
start = s.start.toString(),
|
||||
end = s.end.toString(),
|
||||
lessons = s.lessons.map { LessonDto.fromDomain(it) }
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user