Files
tools/publish/src/rdf/materialize.rs
T

134 lines
4.5 KiB
Rust
Raw Normal View History

2026-06-23 21:55:52 -04:00
use oxigraph::model::{Dataset, GraphName, NamedOrBlankNode, NamedOrBlankNodeRef, Quad, Term};
use oxigraph::sparql::{QueryResults, SparqlEvaluator};
use oxigraph::store::Store;
use crate::error;
use crate::rdf::vocab::owl;
pub fn same_as(store: Store) -> error::Result<Store> {
let additional_quads = store
.quads_for_pattern(None, Some(owl::SAME_AS), None, None)
.filter_map(Result::ok)
.fold(Dataset::new(), |mut new_dataset, alias| {
if let NamedOrBlankNode::NamedNode(x) = alias.subject
&& let Term::NamedNode(y) = alias.object
{
for mut quad in store.quads_for_pattern(
Some(NamedOrBlankNodeRef::NamedNode(x.as_ref())),
None,
None,
None,
).filter_map(Result::ok) {
quad.subject = NamedOrBlankNode::NamedNode(y.clone());
new_dataset.insert(quad.as_ref());
}
for mut quad in store.quads_for_pattern(
Some(NamedOrBlankNodeRef::NamedNode(y.as_ref())),
None,
None,
None,
).filter_map(Result::ok) {
quad.subject = NamedOrBlankNode::NamedNode(x.clone());
new_dataset.insert(quad.as_ref());
}
}
new_dataset
});
let old_size = store.len()?;
store.extend(&additional_quads)?;
let new_size = store.len()?;
if new_size > old_size {
same_as(store)
} else {
Ok(store)
}
}
pub fn super_classes(dataset: &mut Dataset) {
let query = SparqlEvaluator::new()
.parse_query(
r#"PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
CONSTRUCT {
?item a ?parent
} WHERE {
?item a ?class .
?class rdfs:subClassOf ?parent .
}"#,
)
.expect("Unable to parse superclass query");
let mut additional_quads = Dataset::new();
if let QueryResults::Graph(graph) = query.on_queryable_dataset(&*dataset).execute().unwrap()
{
additional_quads.extend(graph.filter_map(Result::ok).map(|triple| {
Quad::new(
triple.subject,
triple.predicate,
triple.object,
GraphName::DefaultGraph,
)
}));
}
let old_size = dataset.len();
dataset.extend(&additional_quads);
let new_size = dataset.len();
if new_size > old_size {
super_classes(dataset)
}
}
/*fn iri_information(dataset: &Dataset) -> HashMap<NamedNode, IriInformation> {
let query = SparqlEvaluator::new()
.parse_query(
r#"PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX gl: <https://graphofliberty.org/2026/04/ont/>
SELECT DISTINCT ?class ?subject ?label ?comment ?read_only {
VALUES ?class { rdf:Property rdfs:Class }
?subject a ?class .
OPTIONAL {
?subject rdfs:label ?label
FILTER (langMATCHES(LANG(?label), "en") || !hasLANG(?label))
}
OPTIONAL {
?subject rdfs:comment ?comment
FILTER (langMATCHES(LANG(?label), "en") || !hasLANG(?comment))
}
OPTIONAL { ?subject gl:readOnly ?read_only }
}"#,
)
.expect("Unable to parse property query");
let mut results = HashMap::new();
if let QueryResults::Solutions(solutions) =
query.on_queryable_dataset(dataset).execute().unwrap()
{
for solution in solutions.filter_map(Result::ok) {
let type_ = solution.get("class").and_then(crate::rdf::ontology::term_to_named_node);
let subject = solution.get("subject").and_then(crate::rdf::ontology::term_to_named_node);
let label = solution.get("label").and_then(crate::rdf::ontology::term_to_string);
let comment = solution.get("comment").and_then(crate::rdf::ontology::term_to_string);
let read_only = solution
.get("read_only")
.and_then(crate::rdf::ontology::term_to_boolean)
.unwrap_or(false);
if let Some(subject) = subject && let Some(type_) = type_ {
let info = IriInformation {
type_: type_.clone(),
label: label.map(String::from),
comment: comment.map(String::from),
read_only,
};
results.insert(subject.to_owned(), info);
}
}
}
results
}*/