data class Grade(
val studentId: UUID,
val value: Int? = null,
val date: LocalDate? = null,
)
data class Course(
val name: String,
val grades: List<Grade> = emptyList(),
val id: UUID? = UUID.randomUUID()
)
object CourseTable : IdTable<UUID>("courses") {
override val id = uuid("id").entityId().uniqueIndex()
val name = varchar("name", 512)
}
object GradeTable : IdTable<UUID>("grades") {
override val id = uuid("id").entityId().uniqueIndex()
val value = integer("value").nullable()
val date = date("date").nullable()
val course: Column<EntityID<UUID>> =
reference("course", CourseTable)
val student: Column<EntityID<UUID>> =
reference("students", StudentTable)
}
fun UpdateBuilder<Number>.save(course: Course) {
this[CourseTable.id] = course.id ?: UUID.randomUUID()
this[CourseTable.name] = course.name
}
fun ResultRow.toCourse() = Course(
id = this[CourseTable.id].value,
name = this[CourseTable.name]
)
fun Course.addGrade(grade: Grade) {
check(id != null)
GradeTable.insert {
it[id] = UUID.randomUUID()
it[value] = grade.value
it[date] = grade.date
it[course] = this@addGrade.id
it[student] = grade.studentId
}
}
fun readCourse(id: UUID? = null): List<Course> {
val query = (CourseTable innerJoin GradeTable)
.selectAll()
id?.let {
query.andWhere {
CourseTable.id eq it
}
}
return query.groupBy { it[CourseTable.id] }
.map {
val grades = it.value.map {
Grade(
it[GradeTable.student].value,
it[GradeTable.value],
it[GradeTable.date])}
Course(
it.value[0][CourseTable.name],
grades,
it.key.value)}
fun setGrade(courseId: UUID, studentId: UUID, newValue: Int) {
GradeTable.update({
GradeTable.course eq courseId and
(GradeTable.student eq studentId)
}) {
it[value] = newValue
it[date] = LocalDate.now()
}
}
val courses = listOf("Math", "Phys", "History").map {
Course(it)
}
CourseTable.batchInsert(courses) {
save(it)
}
INSERT INTO COURSES (ID, "NAME") VALUES ('...', 'Math')
INSERT INTO COURSES (ID, "NAME") VALUES ('...', 'Phys')
INSERT INTO COURSES (ID, "NAME") VALUES ('...', 'History')
dbCourse.map { course ->
dbStudents.map { student ->
check(student.id != null)
course.addGrade(Grade(student.id))
}
}
INSERT INTO GRADES (COURSE, "DATE", ID, STUDENTS, "VALUE")
VALUES ('969bd1a9-c11a-433c-a0e8-a5d0afdd3af7', NULL,
'6a4334f1-1354-44ba-b85d-35a15d1fc691',
'a15a8387-ff26-497a-af7f-044ff5749343', NULL)
val pennyId = dbStudents.find { it.name == "Penny" }?.id!!
val mathId = dbCourse.find { it.name == "Math" }?.id!!
setGrade(mathId, pennyId, 5)
UPDATE GRADES SET "VALUE"=5, "DATE"='2023-05-01'
WHERE (GRADES.COURSE = '969bd1a9-c11a-433c-a0e8-a5d0afdd3af7')
AND (GRADES.STUDENTS = 'a15a8387-ff26-497a-af7f-044ff5749343')
println(readCourse(mathId))
SELECT COURSES.ID, COURSES."NAME", GRADES.ID,
GRADES."VALUE", GRADES."DATE", GRADES.COURSE, GRADES.STUDENTS
FROM COURSES INNER JOIN GRADES
ON COURSES.ID = GRADES.COURSE
WHERE COURSES.ID = '969bd1a9-c11a-433c-a0e8-a5d0afdd3af7'