Skip to content

Commit

Permalink
GH-5024 Fix 'nuclear' delete bug in RDF4JTemplate.delete(IRI, List) (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
hmottestad authored Jul 9, 2024
2 parents 5ed5bad + 8ed93eb commit dd47bfc
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,9 @@ public void delete(IRI start, List<PropertyPath> propertyPaths) {
Variable p2 = SparqlBuilder.var("p2_" + i);
Variable s2 = SparqlBuilder.var("s2_" + i);
q.delete(target.has(p1, o1), s2.has(p2, target))
.where(toIri(start).has(p, target).optional(), target.has(p1, o1).optional(),
.where(
toIri(start).has(p, target),
target.has(p1, o1).optional(),
s2.has(p2, target).optional());
}
update(q.getQueryString()).execute();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public class EX {
public static final IRI sunflowers = SimpleValueFactory.getInstance().createIRI(base, "sunflowers");
public static final IRI potatoEaters = SimpleValueFactory.getInstance().createIRI(base, "potatoEaters");
public static final IRI guernica = SimpleValueFactory.getInstance().createIRI(base, "guernica");
public static final IRI homeAddress = SimpleValueFactory.getInstance().createIRI(base, "homeAddress");

public static IRI of(String localName) {
return SimpleValueFactory.getInstance().createIRI(base, localName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,14 @@
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: BSD-3-Clause
*******************************************************************************/
******************************************************************************/

package org.eclipse.rdf4j.spring.support;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;

import java.util.List;
import java.util.Set;

Expand All @@ -20,13 +24,20 @@
import org.eclipse.rdf4j.model.impl.SimpleValueFactory;
import org.eclipse.rdf4j.model.vocabulary.FOAF;
import org.eclipse.rdf4j.model.vocabulary.RDF;
import org.eclipse.rdf4j.query.BindingSet;
import org.eclipse.rdf4j.sparqlbuilder.constraint.propertypath.builder.PropertyPathBuilder;
import org.eclipse.rdf4j.sparqlbuilder.rdf.Rdf;
import org.eclipse.rdf4j.spring.RDF4JSpringTestBase;
import org.eclipse.rdf4j.spring.dao.exception.IncorrectResultSetSizeException;
import org.eclipse.rdf4j.spring.dao.support.opbuilder.UpdateExecutionBuilder;
import org.eclipse.rdf4j.spring.dao.support.sparql.NamedSparqlSupplier;
import org.eclipse.rdf4j.spring.domain.dao.ArtistDao;
import org.eclipse.rdf4j.spring.domain.dao.PaintingDao;
import org.eclipse.rdf4j.spring.domain.model.Artist;
import org.eclipse.rdf4j.spring.domain.model.EX;
import org.eclipse.rdf4j.spring.domain.model.Painting;
import org.eclipse.rdf4j.spring.util.QueryResultUtils;
import org.eclipse.rdf4j.spring.util.TypeMappingUtils;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
Expand All @@ -40,6 +51,13 @@ public class RDF4JTemplateTests extends RDF4JSpringTestBase {
@Autowired
private RDF4JTemplate rdf4JTemplate;

// used for checks
@Autowired
private ArtistDao artistDao;

@Autowired
PaintingDao paintingDao;

@Test
public void testUpdate1() {
UpdateExecutionBuilder updateBuilder = rdf4JTemplate.update(
Expand Down Expand Up @@ -427,6 +445,62 @@ public void testAssociate_deleteOutgoing() {

}

@Test
public void testDeleteWithPropertyPaths() {
int triplesBeforeDelete = countTriples();
Artist picasso = artistDao.getById(EX.Picasso);
assertNotNull(picasso);
Painting guernica = paintingDao.getById(EX.guernica);
assertNotNull(guernica);
rdf4JTemplate.delete(EX.Picasso, List.of(PropertyPathBuilder.of(EX.creatorOf).build()));
assertThrows(IncorrectResultSetSizeException.class, () -> artistDao.getById(EX.Picasso));
assertThrows(IncorrectResultSetSizeException.class, () -> paintingDao.getById(EX.guernica));
assertEquals(triplesBeforeDelete - 8, countTriples());
}

@Test
public void testDeleteWithDisjunctivePropertyPaths() {
int triplesBeforeDelete = countTriples();
Artist picasso = artistDao.getById(EX.Picasso);
assertNotNull(picasso);
Painting guernica = paintingDao.getById(EX.guernica);
assertNotNull(guernica);
rdf4JTemplate.delete(EX.Picasso, List.of(PropertyPathBuilder.of(EX.creatorOf).or(EX.homeAddress).build()));
assertThrows(IncorrectResultSetSizeException.class, () -> artistDao.getById(EX.Picasso));
assertThrows(IncorrectResultSetSizeException.class, () -> paintingDao.getById(EX.guernica));
assertEquals(triplesBeforeDelete - 11, countTriples());
}

@Test
public void testDeleteWithMultiplePropertyPaths() {
int triplesBeforeDelete = countTriples();
Artist picasso = artistDao.getById(EX.Picasso);
assertNotNull(picasso);
Painting guernica = paintingDao.getById(EX.guernica);
assertNotNull(guernica);
rdf4JTemplate.delete(EX.Picasso,
List.of(PropertyPathBuilder.of(EX.creatorOf).build(), PropertyPathBuilder.of(EX.homeAddress).build()));
assertThrows(IncorrectResultSetSizeException.class, () -> artistDao.getById(EX.Picasso));
assertThrows(IncorrectResultSetSizeException.class, () -> paintingDao.getById(EX.guernica));
assertEquals(triplesBeforeDelete - 11, countTriples());
}

@Test
public void testDeleteWithLongerPropertyPaths() {
int triplesBeforeDelete = countTriples();
Artist picasso = artistDao.getById(EX.Picasso);
assertNotNull(picasso);
Painting guernica = paintingDao.getById(EX.guernica);
assertNotNull(guernica);
// deletes guernica and the home address, but not picasso
rdf4JTemplate.delete(EX.guernica,
List.of(PropertyPathBuilder.of(EX.creatorOf).inv().then(EX.homeAddress).build()));
picasso = artistDao.getById(EX.Picasso);
assertNotNull(picasso);
assertThrows(IncorrectResultSetSizeException.class, () -> paintingDao.getById(EX.guernica));
assertEquals(triplesBeforeDelete - 8, countTriples());
}

@Test
public void testAssociate() {
IRI me = EX.of("me");
Expand Down Expand Up @@ -464,4 +538,14 @@ public void testAssociate() {
.size());

}

private int countTriples() {
return this.rdf4JTemplate
.tupleQuery("SELECT (count(*) AS ?count) WHERE { ?a ?b ?c }")
.evaluateAndConvert()
.toSingletonOfWholeResult(result -> {
BindingSet bs = result.next();
return TypeMappingUtils.toInt(QueryResultUtils.getValue(bs, "count"));
});
}
}

0 comments on commit dd47bfc

Please sign in to comment.