Skip to content

Commit a3418a6

Browse files
committed
refactor: migrate from ConjunctiveGraph to Dataset for RDF quadstore handling
1 parent a55cdec commit a3418a6

16 files changed

Lines changed: 79 additions & 141 deletions

.gitignore

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,4 @@ nosetests.xml
3535

3636
# Virtuoso lock files
3737
tests/test_dataset_db/*
38-
tests/test_provenance_db/*
39-
40-
.claude/
41-
CLAUDE.md
42-
icon_oc_positive_animated.html
38+
tests/test_provenance_db/*

docker-compose.dev.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ services:
55
dockerfile: Dockerfile.dev
66
ports:
77
- "5000:5000"
8-
- "6379:6379" # Redis port for development
8+
- "6381:6379"
99
environment:
1010
# Application Configuration
1111
- FLASK_ENV=demo

heritrace/editor.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from heritrace.extensions import SPARQLWrapperWithRetry
66
from rdflib import Graph, Literal, URIRef
77
from rdflib_ocdm.counter_handler.counter_handler import CounterHandler
8-
from rdflib_ocdm.ocdm_graph import OCDMConjunctiveGraph, OCDMGraph
8+
from rdflib_ocdm.ocdm_graph import OCDMDataset, OCDMGraph
99
from rdflib_ocdm.reader import Reader
1010
from rdflib_ocdm.storer import Storer
1111
from SPARQLWrapper import JSON
@@ -30,7 +30,7 @@ def __init__(
3030
self.c_time = self.to_posix_timestamp(c_time)
3131
self.dataset_is_quadstore = dataset_is_quadstore
3232
self.g_set = (
33-
OCDMConjunctiveGraph(self.counter_handler)
33+
OCDMDataset(self.counter_handler)
3434
if self.dataset_is_quadstore
3535
else OCDMGraph(self.counter_handler)
3636
)

heritrace/routes/entity.py

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
render_template, request, url_for)
99
from flask_babel import gettext
1010
from flask_login import current_user, login_required
11-
from rdflib import RDF, XSD, ConjunctiveGraph, Graph, Literal, URIRef
11+
from rdflib import RDF, XSD, Dataset, Graph, Literal, URIRef
1212
from SPARQLWrapper import JSON
1313
from time_agnostic_library.agnostic_entity import AgnosticEntity
1414

@@ -186,13 +186,19 @@ def about(subject):
186186
abort(404)
187187

188188
if data_graph:
189-
triples = list(data_graph.triples((None, None, None)))
190-
subject_classes = [o for s, p, o in data_graph.triples((URIRef(subject), RDF.type, None))]
189+
# For Dataset (quadstore), we need to use quads() instead of triples()
190+
if isinstance(data_graph, Dataset):
191+
# Convert quads to triples by extracting only s, p, o
192+
triples = [(s, p, o) for s, p, o, g in data_graph.quads((None, None, None))]
193+
subject_classes = [o for s, p, o, g in data_graph.quads((URIRef(subject), RDF.type, None))]
194+
subject_triples = [(s, p, o) for s, p, o, g in data_graph.quads((URIRef(subject), None, None))]
195+
else:
196+
triples = list(data_graph.triples((None, None, None)))
197+
subject_classes = [o for s, p, o in data_graph.triples((URIRef(subject), RDF.type, None))]
198+
subject_triples = list(data_graph.triples((URIRef(subject), None, None)))
191199

192200
highest_priority_class = get_highest_priority_class(subject_classes)
193-
entity_shape = determine_shape_for_entity_triples(
194-
list(data_graph.triples((URIRef(subject), None, None)))
195-
)
201+
entity_shape = determine_shape_for_entity_triples(subject_triples)
196202

197203
(
198204
can_be_added,
@@ -432,7 +438,7 @@ def create_nested_entity(
432438
editor: Editor, entity_uri, entity_data, graph_uri=None
433439
):
434440
form_fields = get_form_fields()
435-
441+
436442
editor.create(
437443
entity_uri,
438444
URIRef("http://www.w3.org/1999/02/22-rdf-syntax-ns#type"),
@@ -1388,7 +1394,7 @@ def restore_version(entity_uri, timestamp):
13881394

13891395

13901396
def compute_graph_differences(
1391-
current_graph: Graph | ConjunctiveGraph, historical_graph: Graph | ConjunctiveGraph
1397+
current_graph: Graph | Dataset, historical_graph: Graph | Dataset
13921398
):
13931399
if get_dataset_is_quadstore():
13941400
current_data = set(current_graph.quads())

heritrace/utils/display_rules_utils.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
from heritrace.extensions import (get_custom_filter, get_display_rules,
66
get_form_fields, get_sparql)
7-
from rdflib import ConjunctiveGraph, Graph, Literal, URIRef
7+
from rdflib import Dataset, Graph, Literal, URIRef
88
from rdflib.plugins.sparql.algebra import translateQuery
99
from rdflib.plugins.sparql.parser import parseQuery
1010
from SPARQLWrapper import JSON
@@ -629,7 +629,7 @@ def process_ordering(
629629
grouped_triples,
630630
display_name,
631631
fetched_values_map,
632-
historical_snapshot: ConjunctiveGraph | Graph | None = None,
632+
historical_snapshot: Dataset | Graph | None = None,
633633
):
634634
def get_ordered_sequence(order_results):
635635
order_map = {}

heritrace/utils/filters.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from flask_babel import format_datetime, gettext, lazy_gettext
1111
from heritrace.apis.orcid import format_orcid_attribution, is_orcid_url
1212
from heritrace.apis.zenodo import format_zenodo_source, is_zenodo_url
13-
from rdflib import ConjunctiveGraph, Graph
13+
from rdflib import Dataset, Graph
1414
from SPARQLWrapper import JSON
1515

1616

@@ -91,7 +91,7 @@ def human_readable_class(self, entity_key):
9191
return format_uri_as_readable(class_uri)
9292

9393
def human_readable_entity(
94-
self, uri: str, entity_key: tuple[str, str | None], graph: Graph | ConjunctiveGraph = None
94+
self, uri: str, entity_key: tuple[str, str | None], graph: Graph | Dataset = None
9595
) -> str:
9696
"""Convert an entity URI to human-readable format using display rules.
9797
@@ -123,7 +123,7 @@ def human_readable_entity(
123123
return uri
124124

125125
def get_fetch_uri_display(
126-
self, uri: str, rule: dict, graph: Graph | ConjunctiveGraph = None
126+
self, uri: str, rule: dict, graph: Graph | Dataset = None
127127
) -> str | None:
128128
"""Get a display value for an entity URI using fetchUriDisplay rules.
129129

heritrace/utils/sparql_utils.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from concurrent.futures import ProcessPoolExecutor, as_completed
44
from typing import List
55

6-
from rdflib import RDF, ConjunctiveGraph, Graph, Literal, URIRef
6+
from rdflib import RDF, Dataset, Graph, Literal, URIRef
77
from rdflib.plugins.sparql.algebra import translateUpdate
88
from rdflib.plugins.sparql.parser import parseUpdate
99
from SPARQLWrapper import JSON
@@ -482,7 +482,7 @@ def get_catalog_data(
482482
}
483483

484484

485-
def fetch_data_graph_for_subject(subject: str) -> Graph | ConjunctiveGraph:
485+
def fetch_data_graph_for_subject(subject: str) -> Graph | Dataset:
486486
"""
487487
Fetch all triples/quads associated with a subject from the dataset.
488488
Handles both triplestore and quadstore cases appropriately.
@@ -491,9 +491,9 @@ def fetch_data_graph_for_subject(subject: str) -> Graph | ConjunctiveGraph:
491491
subject (str): The URI of the subject to fetch data for
492492
493493
Returns:
494-
Graph|ConjunctiveGraph: A graph containing all triples/quads for the subject
494+
Graph|Dataset: A graph containing all triples/quads for the subject
495495
"""
496-
g = ConjunctiveGraph() if get_dataset_is_quadstore() else Graph()
496+
g = Dataset() if get_dataset_is_quadstore() else Graph()
497497
sparql = get_sparql()
498498

499499
if is_virtuoso():
@@ -593,17 +593,17 @@ def extract_quads(quads):
593593

594594
def fetch_current_state_with_related_entities(
595595
provenance: dict,
596-
) -> Graph | ConjunctiveGraph:
596+
) -> Graph | Dataset:
597597
"""
598598
Fetch the current state of an entity and all its related entities known from provenance.
599599
600600
Args:
601601
provenance (dict): Dictionary containing provenance metadata for main entity and related entities
602602
603603
Returns:
604-
ConjunctiveGraph: A graph containing the current state of all entities
604+
Dataset: A graph containing the current state of all entities
605605
"""
606-
combined_graph = ConjunctiveGraph() if get_dataset_is_quadstore() else Graph()
606+
combined_graph = Dataset() if get_dataset_is_quadstore() else Graph()
607607

608608
# Fetch state for all entities mentioned in provenance
609609
for entity_uri in provenance.keys():
@@ -746,7 +746,7 @@ def process_deleted_entity(result: dict, sortable_properties: list) -> dict | No
746746
return None
747747

748748
last_valid_time = convert_to_datetime(last_valid_snapshot_time, stringify=True)
749-
last_valid_state: ConjunctiveGraph = state[entity_uri][last_valid_time]
749+
last_valid_state: Dataset = state[entity_uri][last_valid_time]
750750

751751
entity_types = [
752752
str(o)

poetry.lock

Lines changed: 9 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ python = "^3.10,<3.14"
1212
flask = "^2.3.3"
1313
sparqlwrapper = "^2.0.0"
1414
pyyaml = "^6.0.1"
15-
flask-babel = "^3.1.0"
15+
flask-babel = "^4.0.0"
1616
validators = "0.20.0"
1717
requests = "^2.31.0"
1818
flask-wtf = "^1.1.1"
@@ -21,7 +21,7 @@ setuptools = "^68.2.2"
2121
docker = "^7.1.0"
2222
requests-oauthlib = "^2.0.0"
2323
flask-login = "^0.6.3"
24-
rdflib-ocdm = "^1.0.4"
24+
rdflib-ocdm = "^1.0.7"
2525
pyopenssl = "^24.3.0"
2626
time-agnostic-library = "^5.0.5"
2727

tests/integration/test_editor_integration.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
# Import the editor module
1414
from heritrace.editor import Editor
1515
from rdflib import RDF, XSD, Literal, URIRef
16-
from rdflib_ocdm.ocdm_graph import OCDMConjunctiveGraph, OCDMGraph
16+
from rdflib_ocdm.ocdm_graph import OCDMDataset, OCDMGraph
1717
from tests.test_config import TestConfig
1818

1919

@@ -63,7 +63,7 @@ def reset_editor_after_test(editor: Editor):
6363
yield
6464
# Reset editor state
6565
editor.g_set = (
66-
OCDMConjunctiveGraph(editor.counter_handler)
66+
OCDMDataset(editor.counter_handler)
6767
if editor.dataset_is_quadstore
6868
else OCDMGraph(editor.counter_handler)
6969
)

0 commit comments

Comments
 (0)