Fixed primary key-related (nullability) issues in DB schema
This commit is contained in:
@ -56,6 +56,7 @@ object GroupAssignments : UUIDTable("grpAssgmts") {
|
|||||||
val name = varchar("name", 50)
|
val name = varchar("name", 50)
|
||||||
val assignment = text("assignment")
|
val assignment = text("assignment")
|
||||||
val deadline = datetime("deadline")
|
val deadline = datetime("deadline")
|
||||||
|
val globalCriterion = reference("global_crit", GroupAssignmentCriteria.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
object GroupAssignmentCriteria : UUIDTable("grpAsCr") {
|
object GroupAssignmentCriteria : UUIDTable("grpAsCr") {
|
||||||
@ -70,6 +71,7 @@ object SoloAssignments : UUIDTable("soloAssgmts") {
|
|||||||
val name = varchar("name", 50)
|
val name = varchar("name", 50)
|
||||||
val assignment = text("assignment")
|
val assignment = text("assignment")
|
||||||
val deadline = datetime("deadline")
|
val deadline = datetime("deadline")
|
||||||
|
val globalCriterion = reference("global_crit", SoloAssignmentCriteria.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
object SoloAssignmentCriteria : UUIDTable("soloAsCr") {
|
object SoloAssignmentCriteria : UUIDTable("soloAsCr") {
|
||||||
@ -86,7 +88,7 @@ object PeerEvaluations : UUIDTable("peerEvals") {
|
|||||||
|
|
||||||
object GroupFeedbacks : CompositeIdTable("grpFdbks") {
|
object GroupFeedbacks : CompositeIdTable("grpFdbks") {
|
||||||
val assignmentId = reference("group_assignment_id", GroupAssignments.id)
|
val assignmentId = reference("group_assignment_id", GroupAssignments.id)
|
||||||
val criterionId = reference("criterion_id", GroupAssignmentCriteria.id).nullable()
|
val criterionId = reference("criterion_id", GroupAssignmentCriteria.id)
|
||||||
val groupId = reference("group_id", Groups.id)
|
val groupId = reference("group_id", Groups.id)
|
||||||
val feedback = text("feedback")
|
val feedback = text("feedback")
|
||||||
val grade = varchar("grade", 32)
|
val grade = varchar("grade", 32)
|
||||||
@ -96,7 +98,7 @@ object GroupFeedbacks : CompositeIdTable("grpFdbks") {
|
|||||||
|
|
||||||
object IndividualFeedbacks : CompositeIdTable("indivFdbks") {
|
object IndividualFeedbacks : CompositeIdTable("indivFdbks") {
|
||||||
val assignmentId = reference("group_assignment_id", GroupAssignments.id)
|
val assignmentId = reference("group_assignment_id", GroupAssignments.id)
|
||||||
val criterionId = reference("criterion_id", GroupAssignmentCriteria.id).nullable()
|
val criterionId = reference("criterion_id", GroupAssignmentCriteria.id)
|
||||||
val groupId = reference("group_id", Groups.id)
|
val groupId = reference("group_id", Groups.id)
|
||||||
val studentId = reference("student_id", Students.id)
|
val studentId = reference("student_id", Students.id)
|
||||||
val feedback = text("feedback")
|
val feedback = text("feedback")
|
||||||
@ -107,7 +109,7 @@ object IndividualFeedbacks : CompositeIdTable("indivFdbks") {
|
|||||||
|
|
||||||
object SoloFeedbacks : CompositeIdTable("soloFdbks") {
|
object SoloFeedbacks : CompositeIdTable("soloFdbks") {
|
||||||
val assignmentId = reference("solo_assignment_id", SoloAssignments.id)
|
val assignmentId = reference("solo_assignment_id", SoloAssignments.id)
|
||||||
val criterionId = reference("criterion_id", SoloAssignmentCriteria.id).nullable()
|
val criterionId = reference("criterion_id", SoloAssignmentCriteria.id)
|
||||||
val studentId = reference("student_id", Students.id)
|
val studentId = reference("student_id", Students.id)
|
||||||
val feedback = text("feedback")
|
val feedback = text("feedback")
|
||||||
val grade = varchar("grade", 32)
|
val grade = varchar("grade", 32)
|
||||||
|
@ -3,7 +3,10 @@ package com.jaytux.grader.data
|
|||||||
import MigrationUtils
|
import MigrationUtils
|
||||||
import org.jetbrains.exposed.sql.Database
|
import org.jetbrains.exposed.sql.Database
|
||||||
import org.jetbrains.exposed.sql.SchemaUtils
|
import org.jetbrains.exposed.sql.SchemaUtils
|
||||||
|
import org.jetbrains.exposed.sql.and
|
||||||
|
import org.jetbrains.exposed.sql.selectAll
|
||||||
import org.jetbrains.exposed.sql.transactions.transaction
|
import org.jetbrains.exposed.sql.transactions.transaction
|
||||||
|
import org.jetbrains.exposed.sql.update
|
||||||
|
|
||||||
object Database {
|
object Database {
|
||||||
val db by lazy {
|
val db by lazy {
|
||||||
|
@ -60,6 +60,7 @@ class GroupAssignment(id: EntityID<UUID>) : Entity<UUID>(id) {
|
|||||||
var name by GroupAssignments.name
|
var name by GroupAssignments.name
|
||||||
var assignment by GroupAssignments.assignment
|
var assignment by GroupAssignments.assignment
|
||||||
var deadline by GroupAssignments.deadline
|
var deadline by GroupAssignments.deadline
|
||||||
|
var globalCriterion by GroupAssignmentCriterion referencedOn GroupAssignments.globalCriterion
|
||||||
|
|
||||||
val criteria by GroupAssignmentCriterion referrersOn GroupAssignmentCriteria.assignmentId
|
val criteria by GroupAssignmentCriterion referrersOn GroupAssignmentCriteria.assignmentId
|
||||||
}
|
}
|
||||||
@ -98,6 +99,7 @@ class SoloAssignment(id: EntityID<UUID>) : Entity<UUID>(id) {
|
|||||||
var name by SoloAssignments.name
|
var name by SoloAssignments.name
|
||||||
var assignment by SoloAssignments.assignment
|
var assignment by SoloAssignments.assignment
|
||||||
var deadline by SoloAssignments.deadline
|
var deadline by SoloAssignments.deadline
|
||||||
|
var globalCriterion by SoloAssignmentCriterion referencedOn SoloAssignments.globalCriterion
|
||||||
|
|
||||||
val criteria by SoloAssignmentCriterion referrersOn SoloAssignmentCriteria.assignmentId
|
val criteria by SoloAssignmentCriterion referrersOn SoloAssignmentCriteria.assignmentId
|
||||||
}
|
}
|
||||||
|
@ -475,7 +475,7 @@ class GroupAssignmentState(val assignment: GroupAssignment) {
|
|||||||
private val _task = mutableStateOf(assignment.assignment); val task = _task.immutable()
|
private val _task = mutableStateOf(assignment.assignment); val task = _task.immutable()
|
||||||
private val _deadline = mutableStateOf(assignment.deadline); val deadline = _deadline.immutable()
|
private val _deadline = mutableStateOf(assignment.deadline); val deadline = _deadline.immutable()
|
||||||
val criteria = RawDbState {
|
val criteria = RawDbState {
|
||||||
assignment.criteria.orderBy(GroupAssignmentCriteria.name to SortOrder.ASC).toList()
|
assignment.criteria.orderBy(GroupAssignmentCriteria.name to SortOrder.ASC).filter { it.id != assignment.globalCriterion.id }
|
||||||
}
|
}
|
||||||
val feedback = RawDbState { loadFeedback() }
|
val feedback = RawDbState { loadFeedback() }
|
||||||
|
|
||||||
@ -494,7 +494,7 @@ class GroupAssignmentState(val assignment: GroupAssignment) {
|
|||||||
private fun Transaction.loadFeedback(): List<Pair<Group, LocalGFeedback>> {
|
private fun Transaction.loadFeedback(): List<Pair<Group, LocalGFeedback>> {
|
||||||
val allCrit = GroupAssignmentCriterion.find {
|
val allCrit = GroupAssignmentCriterion.find {
|
||||||
GroupAssignmentCriteria.assignmentId eq assignment.id
|
GroupAssignmentCriteria.assignmentId eq assignment.id
|
||||||
}
|
}.filter { it.id != assignment.globalCriterion.id }
|
||||||
|
|
||||||
return Group.find {
|
return Group.find {
|
||||||
(Groups.editionId eq assignment.edition.id)
|
(Groups.editionId eq assignment.edition.id)
|
||||||
@ -502,16 +502,19 @@ class GroupAssignmentState(val assignment: GroupAssignment) {
|
|||||||
val forGroup = (GroupFeedbacks innerJoin Groups).selectAll().where {
|
val forGroup = (GroupFeedbacks innerJoin Groups).selectAll().where {
|
||||||
(GroupFeedbacks.assignmentId eq assignment.id) and (Groups.id eq group.id)
|
(GroupFeedbacks.assignmentId eq assignment.id) and (Groups.id eq group.id)
|
||||||
}.map { row ->
|
}.map { row ->
|
||||||
val crit = row[GroupFeedbacks.criterionId]?.let { GroupAssignmentCriterion[it] }
|
val crit = GroupAssignmentCriterion[row[GroupFeedbacks.criterionId]]
|
||||||
val fdbk = row[GroupFeedbacks.feedback]
|
val fdbk = row[GroupFeedbacks.feedback]
|
||||||
val grade = row[GroupFeedbacks.grade]
|
val grade = row[GroupFeedbacks.grade]
|
||||||
|
|
||||||
crit to FeedbackEntry(fdbk, grade)
|
crit to FeedbackEntry(fdbk, grade)
|
||||||
}
|
}
|
||||||
|
|
||||||
val global = forGroup.firstOrNull { it.first == null }?.second
|
val global = forGroup.firstOrNull { it.first.id == assignment.globalCriterion.id }?.second
|
||||||
val byCrit_ = forGroup.map { it.first?.let { k -> LocalCriterionFeedback(k, it.second) } }
|
val byCrit_ = forGroup
|
||||||
.filterNotNull().associateBy { it.criterion.id }
|
.filter{ it.first.id != assignment.globalCriterion.id }
|
||||||
|
.map { LocalCriterionFeedback(it.first, it.second) }
|
||||||
|
.associateBy { it.criterion.id }
|
||||||
|
|
||||||
val byCrit = allCrit.map { c ->
|
val byCrit = allCrit.map { c ->
|
||||||
byCrit_[c.id] ?: LocalCriterionFeedback(c, null)
|
byCrit_[c.id] ?: LocalCriterionFeedback(c, null)
|
||||||
}
|
}
|
||||||
@ -527,16 +530,19 @@ class GroupAssignmentState(val assignment: GroupAssignment) {
|
|||||||
(IndividualFeedbacks.assignmentId eq assignment.id) and
|
(IndividualFeedbacks.assignmentId eq assignment.id) and
|
||||||
(GroupStudents.studentId eq student.id) and (Groups.id eq group.id)
|
(GroupStudents.studentId eq student.id) and (Groups.id eq group.id)
|
||||||
}.map { row ->
|
}.map { row ->
|
||||||
val crit = row[IndividualFeedbacks.criterionId]?.let { id -> GroupAssignmentCriterion[id] }
|
val crit = GroupAssignmentCriterion[row[IndividualFeedbacks.criterionId]]
|
||||||
val fdbk = row[IndividualFeedbacks.feedback]
|
val fdbk = row[IndividualFeedbacks.feedback]
|
||||||
val grade = row[IndividualFeedbacks.grade]
|
val grade = row[IndividualFeedbacks.grade]
|
||||||
|
|
||||||
crit to FeedbackEntry(fdbk, grade)
|
crit to FeedbackEntry(fdbk, grade)
|
||||||
}
|
}
|
||||||
|
|
||||||
val global = forSt.firstOrNull { it.first == null }?.second
|
val global = forSt.firstOrNull { it.first == assignment.globalCriterion.id }?.second
|
||||||
val byCrit_ = forSt.map { it.first?.let { k -> LocalCriterionFeedback(k, it.second) } }
|
val byCrit_ = forSt
|
||||||
.filterNotNull().associateBy { it.criterion.id }
|
.filter { it.first != assignment.globalCriterion.id }
|
||||||
|
.map { LocalCriterionFeedback(it.first, it.second) }
|
||||||
|
.associateBy { it.criterion.id }
|
||||||
|
|
||||||
val byCrit = allCrit.map { c ->
|
val byCrit = allCrit.map { c ->
|
||||||
byCrit_[c.id] ?: LocalCriterionFeedback(c, null)
|
byCrit_[c.id] ?: LocalCriterionFeedback(c, null)
|
||||||
}
|
}
|
||||||
@ -556,7 +562,7 @@ class GroupAssignmentState(val assignment: GroupAssignment) {
|
|||||||
it[groupId] = group.id
|
it[groupId] = group.id
|
||||||
it[this.feedback] = msg
|
it[this.feedback] = msg
|
||||||
it[this.grade] = grd
|
it[this.grade] = grd
|
||||||
it[criterionId] = criterion?.id
|
it[criterionId] = criterion?.id ?: assignment.globalCriterion.id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
feedback.refresh(); autofill.refresh()
|
feedback.refresh(); autofill.refresh()
|
||||||
@ -570,7 +576,7 @@ class GroupAssignmentState(val assignment: GroupAssignment) {
|
|||||||
it[studentId] = student.id
|
it[studentId] = student.id
|
||||||
it[this.feedback] = msg
|
it[this.feedback] = msg
|
||||||
it[this.grade] = grd
|
it[this.grade] = grd
|
||||||
it[criterionId] = criterion?.id
|
it[criterionId] = criterion?.id ?: assignment.globalCriterion.id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
feedback.refresh(); autofill.refresh()
|
feedback.refresh(); autofill.refresh()
|
||||||
@ -628,7 +634,7 @@ class SoloAssignmentState(val assignment: SoloAssignment) {
|
|||||||
private val _task = mutableStateOf(assignment.assignment); val task = _task.immutable()
|
private val _task = mutableStateOf(assignment.assignment); val task = _task.immutable()
|
||||||
private val _deadline = mutableStateOf(assignment.deadline); val deadline = _deadline.immutable()
|
private val _deadline = mutableStateOf(assignment.deadline); val deadline = _deadline.immutable()
|
||||||
val criteria = RawDbState {
|
val criteria = RawDbState {
|
||||||
assignment.criteria.orderBy(SoloAssignmentCriteria.name to SortOrder.ASC).toList()
|
assignment.criteria.orderBy(SoloAssignmentCriteria.name to SortOrder.ASC).filter { it.id != assignment.globalCriterion.id }
|
||||||
}
|
}
|
||||||
val feedback = RawDbState { loadFeedback() }
|
val feedback = RawDbState { loadFeedback() }
|
||||||
|
|
||||||
@ -641,22 +647,25 @@ class SoloAssignmentState(val assignment: SoloAssignment) {
|
|||||||
private fun Transaction.loadFeedback(): List<Pair<Student, FullFeedback>> {
|
private fun Transaction.loadFeedback(): List<Pair<Student, FullFeedback>> {
|
||||||
val allCrit = SoloAssignmentCriterion.find {
|
val allCrit = SoloAssignmentCriterion.find {
|
||||||
SoloAssignmentCriteria.assignmentId eq assignment.id
|
SoloAssignmentCriteria.assignmentId eq assignment.id
|
||||||
}
|
}.filter { it.id != assignment.globalCriterion.id }
|
||||||
|
|
||||||
return editionCourse.second.soloStudents.sortAsc(Students.name).map { student ->
|
return editionCourse.second.soloStudents.sortAsc(Students.name).map { student ->
|
||||||
val forStudent = (IndividualFeedbacks innerJoin Students).selectAll().where {
|
val forStudent = (IndividualFeedbacks innerJoin Students).selectAll().where {
|
||||||
(IndividualFeedbacks.assignmentId eq assignment.id) and (Students.id eq student.id)
|
(IndividualFeedbacks.assignmentId eq assignment.id) and (Students.id eq student.id)
|
||||||
}.map { row ->
|
}.map { row ->
|
||||||
val crit = row[IndividualFeedbacks.criterionId]?.let { SoloAssignmentCriterion[it] }
|
val crit = SoloAssignmentCriterion[row[IndividualFeedbacks.criterionId]]
|
||||||
val fdbk = row[IndividualFeedbacks.feedback]
|
val fdbk = row[IndividualFeedbacks.feedback]
|
||||||
val grade = row[IndividualFeedbacks.grade]
|
val grade = row[IndividualFeedbacks.grade]
|
||||||
|
|
||||||
crit to LocalFeedback(fdbk, grade)
|
crit to LocalFeedback(fdbk, grade)
|
||||||
}
|
}
|
||||||
|
|
||||||
val global = forStudent.firstOrNull { it.first == null }?.second
|
val global = forStudent.firstOrNull { it.first == assignment.globalCriterion.id }?.second
|
||||||
val byCrit_ = forStudent.map { it.first?.let { k -> Pair(k, it.second) } }
|
val byCrit_ = forStudent
|
||||||
.filterNotNull().associateBy { it.first.id }
|
.filter { it.first != assignment.globalCriterion.id }
|
||||||
|
.map { Pair(it.first, it.second) }
|
||||||
|
.associateBy { it.first.id }
|
||||||
|
|
||||||
val byCrit = allCrit.map { c ->
|
val byCrit = allCrit.map { c ->
|
||||||
byCrit_[c.id] ?: Pair(c, null)
|
byCrit_[c.id] ?: Pair(c, null)
|
||||||
}
|
}
|
||||||
@ -672,7 +681,7 @@ class SoloAssignmentState(val assignment: SoloAssignment) {
|
|||||||
it[studentId] = student.id
|
it[studentId] = student.id
|
||||||
it[this.feedback] = msg ?: ""
|
it[this.feedback] = msg ?: ""
|
||||||
it[this.grade] = grd ?: ""
|
it[this.grade] = grd ?: ""
|
||||||
it[criterionId] = criterion?.id
|
it[criterionId] = criterion?.id ?: assignment.globalCriterion.id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
feedback.refresh(); autofill.refresh()
|
feedback.refresh(); autofill.refresh()
|
||||||
|
@ -20,6 +20,7 @@ kotlinx-coroutines-swing = { group = "org.jetbrains.kotlinx", name = "kotlinx-co
|
|||||||
exposed-core = { group = "org.jetbrains.exposed", name = "exposed-core", version.ref = "exposed" }
|
exposed-core = { group = "org.jetbrains.exposed", name = "exposed-core", version.ref = "exposed" }
|
||||||
exposed-dao = { group = "org.jetbrains.exposed", name = "exposed-dao", version.ref = "exposed" }
|
exposed-dao = { group = "org.jetbrains.exposed", name = "exposed-dao", version.ref = "exposed" }
|
||||||
exposed-jdbc = { group = "org.jetbrains.exposed", name = "exposed-jdbc", version.ref = "exposed" }
|
exposed-jdbc = { group = "org.jetbrains.exposed", name = "exposed-jdbc", version.ref = "exposed" }
|
||||||
|
exposed-migration = { group = "org.jetbrains.exposed", name = "exposed-migration", version.ref = "exposed" }
|
||||||
exposed-kotlin-datetime = { group = "org.jetbrains.exposed", name = "exposed-kotlin-datetime", version.ref = "exposed" }
|
exposed-kotlin-datetime = { group = "org.jetbrains.exposed", name = "exposed-kotlin-datetime", version.ref = "exposed" }
|
||||||
sqlite = { group = "org.xerial", name = "sqlite-jdbc", version = "3.34.0" }
|
sqlite = { group = "org.xerial", name = "sqlite-jdbc", version = "3.34.0" }
|
||||||
sl4j = { group = "org.slf4j", name = "slf4j-simple", version = "2.0.12" }
|
sl4j = { group = "org.slf4j", name = "slf4j-simple", version = "2.0.12" }
|
||||||
@ -33,4 +34,4 @@ rtfield = { group = "com.mohamedrejeb.richeditor", name = "richeditor-compose",
|
|||||||
[plugins]
|
[plugins]
|
||||||
composeMultiplatform = { id = "org.jetbrains.compose", version.ref = "compose-multiplatform" }
|
composeMultiplatform = { id = "org.jetbrains.compose", version.ref = "compose-multiplatform" }
|
||||||
composeCompiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
|
composeCompiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
|
||||||
kotlinMultiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
|
kotlinMultiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
|
||||||
|
Reference in New Issue
Block a user