From 44973b8e788f8d324e5ce030b28ecdc21872e325 Mon Sep 17 00:00:00 2001 From: Loris Sauter Date: Fri, 6 Oct 2023 14:36:32 +0200 Subject: [PATCH] WiP: Fixing removing of task types, yet broken --- .../rest/types/template/tasks/ApiTaskType.kt | 14 +++++-- .../model/template/task/DbTaskTemplate.kt | 2 - .../data/model/template/task/DbTaskType.kt | 9 ++++- .../kotlin/dev/dres/mgmt/TemplateManager.kt | 38 ++++++++++++++++++- 4 files changed, 55 insertions(+), 8 deletions(-) diff --git a/backend/src/main/kotlin/dev/dres/api/rest/types/template/tasks/ApiTaskType.kt b/backend/src/main/kotlin/dev/dres/api/rest/types/template/tasks/ApiTaskType.kt index 081aa29b..b98874b4 100644 --- a/backend/src/main/kotlin/dev/dres/api/rest/types/template/tasks/ApiTaskType.kt +++ b/backend/src/main/kotlin/dev/dres/api/rest/types/template/tasks/ApiTaskType.kt @@ -1,23 +1,26 @@ package dev.dres.api.rest.types.template.tasks +import com.fasterxml.jackson.annotation.JsonIgnore import com.fasterxml.jackson.annotation.JsonIgnoreProperties import com.fasterxml.jackson.databind.DeserializationFeature import com.fasterxml.jackson.databind.ObjectMapper import dev.dres.api.rest.types.template.tasks.options.* import dev.dres.data.model.template.task.DbTaskType +import io.javalin.openapi.OpenApiIgnore import java.nio.file.Files import java.nio.file.Path import java.nio.file.StandardOpenOption +typealias TaskTypeId = String + /** * The RESTful API equivalent of a [DbTaskType]. * - * @author Ralph Gasser - * @author Loris Sauter + * @author Ralph Gasser & Loris Sauter * @version 1.1.0 */ data class ApiTaskType( - val id: String?, + val id: TaskTypeId? = null, val name: String, val duration: Long, val targetOption: ApiTargetOption, @@ -46,4 +49,9 @@ data class ApiTaskType( ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false).readValue(it, ApiTaskType::class.java) } } + + val taskTypeId: TaskTypeId + @JsonIgnore + @OpenApiIgnore + get() = this.id ?: "N/A" } diff --git a/backend/src/main/kotlin/dev/dres/data/model/template/task/DbTaskTemplate.kt b/backend/src/main/kotlin/dev/dres/data/model/template/task/DbTaskTemplate.kt index b2a18da8..6bb58124 100644 --- a/backend/src/main/kotlin/dev/dres/data/model/template/task/DbTaskTemplate.kt +++ b/backend/src/main/kotlin/dev/dres/data/model/template/task/DbTaskTemplate.kt @@ -7,10 +7,8 @@ import dev.dres.data.model.template.DbEvaluationTemplate import dev.dres.data.model.media.DbMediaCollection import dev.dres.data.model.template.team.DbTeam import dev.dres.data.model.run.interfaces.TaskRun -import dev.dres.data.model.template.TemplateId import jetbrains.exodus.entitystore.Entity import kotlinx.dnq.* -import kotlinx.dnq.link.OnDeletePolicy import kotlinx.dnq.query.* import kotlinx.dnq.simple.min import java.lang.IllegalStateException diff --git a/backend/src/main/kotlin/dev/dres/data/model/template/task/DbTaskType.kt b/backend/src/main/kotlin/dev/dres/data/model/template/task/DbTaskType.kt index aeddf4f6..e0b97399 100644 --- a/backend/src/main/kotlin/dev/dres/data/model/template/task/DbTaskType.kt +++ b/backend/src/main/kotlin/dev/dres/data/model/template/task/DbTaskType.kt @@ -1,6 +1,8 @@ package dev.dres.data.model.template.task import dev.dres.api.rest.types.template.tasks.ApiTaskType +import dev.dres.api.rest.types.template.tasks.TaskTypeId +import dev.dres.data.model.PersistentEntity import dev.dres.data.model.template.DbEvaluationTemplate import dev.dres.data.model.template.task.options.* import dev.dres.data.model.template.task.options.DbConfiguredOption @@ -15,7 +17,7 @@ import kotlinx.dnq.simple.min * @author Luca Rossetto & Ralph Gasser * @version 2.0.0 */ -class DbTaskType(entity: Entity) : XdEntity(entity) { +class DbTaskType(entity: Entity) : PersistentEntity(entity) { /** Combination of [DbTaskType] name / competition must be unique. */ companion object: XdNaturalEntityType() { override val compositeIndices = listOf( @@ -23,6 +25,11 @@ class DbTaskType(entity: Entity) : XdEntity(entity) { ) } + /** The [TaskTypeId] of this [DbTaskType]. */ + var taskTypeId: TaskTypeId + get() = this.id + set(value) { this.id = value } + /** The name of this [DbTaskType]. */ var name by xdRequiredStringProp(unique = false, trimmed = false) diff --git a/backend/src/main/kotlin/dev/dres/mgmt/TemplateManager.kt b/backend/src/main/kotlin/dev/dres/mgmt/TemplateManager.kt index c63b4e3e..8b8f5193 100644 --- a/backend/src/main/kotlin/dev/dres/mgmt/TemplateManager.kt +++ b/backend/src/main/kotlin/dev/dres/mgmt/TemplateManager.kt @@ -11,6 +11,9 @@ import dev.dres.data.model.template.DbEvaluationTemplate import dev.dres.data.model.template.TemplateId import dev.dres.data.model.template.task.* import dev.dres.data.model.template.task.options.DbConfiguredOption +import dev.dres.data.model.template.task.options.DbHintOption +import dev.dres.data.model.template.task.options.DbSubmissionOption +import dev.dres.data.model.template.task.options.DbTaskOption import dev.dres.data.model.template.team.DbTeam import dev.dres.data.model.template.team.DbTeamGroup import dev.dres.data.model.template.team.TeamId @@ -92,9 +95,40 @@ object TemplateManager { dbEvaluationTemplate.modified = DateTime.now() /* Update task type information. */ - val taskTypes = apiEvaluationTemplate.taskTypes.map { it.name }.toTypedArray() + + /* Update task type information: Remove deleted types. */ + val typesIds = apiEvaluationTemplate.taskTypes.mapNotNull { it.id }.toTypedArray() + val typesToDeleteQuery = DbTaskType.query( + DbTaskType::evaluation eq dbEvaluationTemplate and not( + DbTaskType::id.containsIn(*typesIds) + ) + ) + val hintOptsToDelIds = typesToDeleteQuery.toList().map { + it.hints.toList().map { hint -> hint.entityId } + }.flatten().toTypedArray() + val submissionOptsToDelIds = typesToDeleteQuery.toList().map{ + it.submission.toList().map{target -> target.entityId} + }.flatten().toTypedArray() + val taskOptsToDelIds = typesToDeleteQuery.toList().map{ + it.options.toList().map{target -> target.entityId} + }.flatten().toTypedArray() + val configOptsToDelIds = typesToDeleteQuery.toList().map{ + it.configurations.toList().map{target -> target.entityId} + }.flatten().toTypedArray() + + /* + DbTaskTemplate has children relationships with both, DbHint and DbTaskTarget. + Despite being written in the documentation, for some reason the .removeAll above does not + delete the children, hence we have to take care of it ourselves. + https://jetbrains.github.io/xodus-dnq/properties.html + */ + DbHintOption.all().toList().filter{hintOptsToDelIds.contains(it.entityId)}.forEach { it.delete() } + DbSubmissionOption.all().toList().filter{submissionOptsToDelIds.contains(it.entityId)}.forEach{it.delete()} + DbTaskOption.all().toList().filter{taskOptsToDelIds.contains(it.entityId)}.forEach{it.delete()} + DbConfiguredOption.all().toList().filter{configOptsToDelIds.contains(it.entityId)}.forEach{it.delete()} + dbEvaluationTemplate.taskTypes.removeAll( - DbTaskType.query(DbTaskType::evaluation eq dbEvaluationTemplate and not(DbTaskType::name.containsIn(*taskTypes))) + typesToDeleteQuery ) for (apiTaskType in apiEvaluationTemplate.taskTypes) { val taskType =