Skip to content

Commit

Permalink
streamline
Browse files Browse the repository at this point in the history
  • Loading branch information
BalduinLandolt committed Jun 4, 2024
1 parent 38ead68 commit 2ab9708
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 88 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -221,38 +221,6 @@ object DeleteValueV2 {
}
}

/**
* Requests SPARQL for creating multiple values in a new, empty resource. The resource ''must'' be a new, empty
* resource, i.e. it must have no values. This message is used only internally by Knora, and is not part of the Knora
* v1 API. All pre-update checks must already have been performed before this message is sent. Specifically, the
* sender must ensure that:
*
* - The requesting user has permission to add values to the resource.
* - Each submitted value is consistent with the `knora-base:objectClassConstraint` of the property that is supposed
* to point to it.
* - The resource class has a suitable cardinality for each submitted value.
* - All required values are provided.
* - Redundant values are not submitted.
* - Any custom permissions in values have been validated and correctly formatted.
* - The target resources of link values and standoff links exist, if they are expected to exist.
* - The list nodes referred to by list values exist.
*
* A successful response will be a [[GenerateSparqlToCreateMultipleValuesResponseV2]].
*
* @param resourceIri the IRI of the resource in which values are to be created.
* @param values a map of property IRIs to the values to be added for each property.
* @param creationDate an xsd:dateTimeStamp that will be attached to the values.
* @param requestingUser the user that is creating the values.
*/
case class GenerateSparqlToCreateMultipleValuesRequestV2(
resourceIri: IRI,
values: Map[SmartIri, Seq[GenerateSparqlForValueInNewResourceV2]],
creationDate: Instant,
requestingUser: User,
) {
lazy val flatValues: Iterable[GenerateSparqlForValueInNewResourceV2] = values.values.flatten
} // TODO: can this be removed too?

case class GenerateSparqlForValueInNewResourceV2(
valueContent: ValueContentV2,
customValueIri: Option[SmartIri],
Expand All @@ -261,22 +229,6 @@ case class GenerateSparqlForValueInNewResourceV2(
permissions: String,
)

/**
* Represents a response to a [[GenerateSparqlToCreateMultipleValuesRequestV2]], providing a string that can be
* included in the `INSERT DATA` clause of a SPARQL update operation to create the requested values.
*
* @param insertSparql a string containing statements that must be inserted into the INSERT clause of the SPARQL
* update that will create the values.
* @param unverifiedValues a map of property IRIs to [[UnverifiedValueV2]] objects describing
* the values that should have been created.
* @param hasStandoffLink `true` if the property `knora-base:hasStandoffLinkToValue` was automatically added.
*/
case class GenerateSparqlToCreateMultipleValuesResponseV2(
insertSparql: String,
unverifiedValues: Map[SmartIri, Seq[UnverifiedValueV2]],
hasStandoffLink: Boolean,
)

/**
* Provides information about the deletion of a resource or value.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,12 @@ final case class CreateResourceV2Handler(
} yield previewOfCreatedResource
}

private case class GenerateSparqlToCreateMultipleValuesResponseV2(
insertSparql: String,
unverifiedValues: Map[SmartIri, Seq[UnverifiedValueV2]],
hasStandoffLink: Boolean,
)

/**
* Generates a [[SparqlTemplateResourceToCreate]] describing SPARQL for creating a resource and its values.
* This method does pre-update checks that have to be done for each new resource individually, even when
Expand Down Expand Up @@ -445,12 +451,10 @@ final case class CreateResourceV2Handler(

// Ask the values responder for SPARQL for generating the values.
sparqlForValuesResponse <- generateSparqlToCreateMultipleValuesV2(
GenerateSparqlToCreateMultipleValuesRequestV2(
resourceIri = resourceIri,
values = valuesWithValidatedPermissions,
creationDate = creationDate,
requestingUser = requestingUser,
),
resourceIri = resourceIri,
values = valuesWithValidatedPermissions,
creationDate = creationDate,
requestingUser = requestingUser,
)
} yield ResourceReadyToCreate(
sparqlTemplateResourceToCreate = SparqlTemplateResourceToCreate(
Expand Down Expand Up @@ -859,39 +863,36 @@ final case class CreateResourceV2Handler(
}
}

/**
* Generates SPARQL for creating multiple values.
*
* @param createMultipleValuesRequest the request to create multiple values.
* @return a [[GenerateSparqlToCreateMultipleValuesResponseV2]] containing the generated SPARQL and information
* about the values to be created.
*/
private def generateSparqlToCreateMultipleValuesV2(
createMultipleValuesRequest: GenerateSparqlToCreateMultipleValuesRequestV2,
resourceIri: IRI,
values: Map[SmartIri, Seq[GenerateSparqlForValueInNewResourceV2]],
creationDate: Instant,
requestingUser: User,
): Task[GenerateSparqlToCreateMultipleValuesResponseV2] =
for {
// Generate SPARQL to create links and LinkValues for standoff links in text values.
sparqlForStandoffLinks <-
generateInsertSparqlForStandoffLinksInMultipleValues(
createMultipleValuesRequest,
resourceIri = resourceIri,
values = values,
creationDate = creationDate,
)

// Generate SPARQL for each value.
sparqlForPropertyValueFutures =
createMultipleValuesRequest.values.map {
case (propertyIri: SmartIri, valuesToCreate: Seq[GenerateSparqlForValueInNewResourceV2]) =>
val values = valuesToCreate.zipWithIndex.map {
case (valueToCreate: GenerateSparqlForValueInNewResourceV2, valueHasOrder: Int) =>
generateInsertSparqlWithUnverifiedValue(
resourceIri = createMultipleValuesRequest.resourceIri,
propertyIri = propertyIri,
valueToCreate = valueToCreate,
valueHasOrder = valueHasOrder,
resourceCreationDate = createMultipleValuesRequest.creationDate,
requestingUser = createMultipleValuesRequest.requestingUser,
)
}
propertyIri -> ZIO.collectAll(values)
values.map { case (propertyIri: SmartIri, valuesToCreate: Seq[GenerateSparqlForValueInNewResourceV2]) =>
val values = valuesToCreate.zipWithIndex.map {
case (valueToCreate: GenerateSparqlForValueInNewResourceV2, valueHasOrder: Int) =>
generateInsertSparqlWithUnverifiedValue(
resourceIri = resourceIri,
propertyIri = propertyIri,
valueToCreate = valueToCreate,
valueHasOrder = valueHasOrder,
resourceCreationDate = creationDate,
requestingUser = requestingUser,
)
}
propertyIri -> ZIO.collectAll(values)
}

sparqlForPropertyValues <- ZioHelper.sequence(sparqlForPropertyValueFutures)
Expand Down Expand Up @@ -1021,22 +1022,18 @@ final case class CreateResourceV2Handler(
),
)

/**
* When processing a request to create multiple values, generates SPARQL for standoff links in text values.
*
* @param createMultipleValuesRequest the request to create multiple values.
* @return SPARQL INSERT statements.
*/
private def generateInsertSparqlForStandoffLinksInMultipleValues(
createMultipleValuesRequest: GenerateSparqlToCreateMultipleValuesRequestV2,
resourceIri: IRI,
values: Map[SmartIri, Seq[GenerateSparqlForValueInNewResourceV2]],
creationDate: Instant,
): Task[Option[String]] = {
// To create LinkValues for the standoff links in the values to be created, we need to compute
// the initial reference count of each LinkValue. This is equal to the number of TextValues in the resource
// that have standoff links to a particular target resource.

// First, get the standoff link targets from all the text values to be created.
val standoffLinkTargetsPerTextValue: Vector[Set[IRI]] =
createMultipleValuesRequest.flatValues.foldLeft(Vector.empty[Set[IRI]]) {
values.values.flatten.foldLeft(Vector.empty[Set[IRI]]) {
case (standoffLinkTargetsAcc: Vector[Set[IRI]], createValueV2: GenerateSparqlForValueInNewResourceV2) =>
createValueV2.valueContent match {
case textValueContentV2: TextValueContentV2
Expand Down Expand Up @@ -1068,7 +1065,7 @@ final case class CreateResourceV2Handler(
val standoffLinkUpdatesFutures: Seq[Task[SparqlTemplateLinkUpdate]] = initialReferenceCounts.toSeq.map {
case (targetIri, initialReferenceCount) =>
for {
newValueIri <- makeUnusedValueIri(createMultipleValuesRequest.resourceIri)
newValueIri <- makeUnusedValueIri(resourceIri)
} yield SparqlTemplateLinkUpdate(
linkPropertyIri = OntologyConstants.KnoraBase.HasStandoffLinkTo.toSmartIri,
directLinkExists = false,
Expand All @@ -1091,9 +1088,9 @@ final case class CreateResourceV2Handler(
sparqlInsert =
sparql.v2.txt
.generateInsertStatementsForStandoffLinks(
resourceIri = createMultipleValuesRequest.resourceIri,
resourceIri = resourceIri,
linkUpdates = standoffLinkUpdates,
creationDate = createMultipleValuesRequest.creationDate,
creationDate = creationDate,
)
.toString()
} yield Some(sparqlInsert)
Expand Down

0 comments on commit 2ab9708

Please sign in to comment.