sparql_service/srdf_data/
rdf_data.rs1use super::RdfDataError;
2use colored::*;
3use iri_s::IriS;
4use oxigraph::sparql::Query as OxQuery;
5use oxigraph::sparql::QueryResults;
6use oxigraph::store::Store;
7use oxrdf::{
8 BlankNode as OxBlankNode, Literal as OxLiteral, NamedNode as OxNamedNode, Subject as OxSubject,
9 Term as OxTerm, Triple as OxTriple,
10};
11use oxrdfio::RdfFormat;
12use prefixmap::PrefixMap;
13use sparesults::QuerySolution as SparQuerySolution;
14use srdf::FocusRDF;
15use srdf::Query;
16use srdf::QuerySolution;
17use srdf::QuerySolutions;
18use srdf::RDFFormat;
19use srdf::Rdf;
20use srdf::ReaderMode;
21use srdf::SRDFBuilder;
22use srdf::SRDFGraph;
23use srdf::SRDFSparql;
24use srdf::Sparql;
25use srdf::VarName;
26use srdf::RDF_TYPE_STR;
27use std::fmt::Debug;
28use std::io;
29use std::str::FromStr;
30
31#[derive(Clone)]
34pub struct RdfData {
35 focus: Option<OxTerm>,
37
38 endpoints: Vec<SRDFSparql>,
40
41 graph: Option<SRDFGraph>,
43
44 store: Option<Store>,
46}
47
48impl Debug for RdfData {
49 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
50 f.debug_struct("RdfData")
51 .field("endpoints", &self.endpoints)
52 .field("graph", &self.graph)
53 .finish()
54 }
55}
56
57impl RdfData {
58 pub fn new() -> RdfData {
59 RdfData {
60 endpoints: Vec::new(),
61 graph: None,
62 store: None,
63 focus: None,
64 }
65 }
66
67 pub fn check_store(&mut self) -> Result<(), RdfDataError> {
71 if let Some(graph) = &self.graph {
72 if self.store.is_none() {
73 let store = Store::new()?;
74 store.bulk_loader().load_quads(graph.quads())?;
75 self.store = Some(store)
76 }
77 }
78 Ok(())
79 }
80
81 pub fn from_graph(graph: SRDFGraph) -> Result<RdfData, RdfDataError> {
83 let store = Store::new()?;
84 store.bulk_loader().load_quads(graph.quads())?;
85 Ok(RdfData {
86 endpoints: Vec::new(),
87 graph: Some(graph),
88 store: Some(store),
89 focus: None,
90 })
91 }
92
93 pub fn clean_all(&mut self) {
95 self.endpoints = Vec::new();
96 self.graph = None
97 }
98
99 pub fn graph(&self) -> Option<&SRDFGraph> {
101 self.graph.as_ref()
102 }
103
104 pub fn clean_graph(&mut self) {
106 self.graph = None
107 }
108
109 pub fn merge_from_reader<R: io::Read>(
111 &mut self,
112 read: R,
113 format: &RDFFormat,
114 base: Option<&str>,
115 reader_mode: &ReaderMode,
116 ) -> Result<(), RdfDataError> {
117 match &mut self.graph {
118 Some(ref mut graph) => graph
119 .merge_from_reader(read, format, base, reader_mode)
120 .map_err(|e| RdfDataError::SRDFGraphError { err: e }),
121 None => {
122 let mut graph = SRDFGraph::new();
123 graph
124 .merge_from_reader(read, format, base, reader_mode)
125 .map_err(|e| RdfDataError::SRDFGraphError { err: e })?;
126 self.graph = Some(graph);
127 Ok(())
128 }
129 }
130 }
131
132 pub fn from_endpoint(endpoint: SRDFSparql) -> RdfData {
134 RdfData {
135 endpoints: vec![endpoint],
136 graph: None,
137 store: None,
138 focus: None,
139 }
140 }
141
142 pub fn add_endpoint(&mut self, endpoint: SRDFSparql) {
144 self.endpoints.push(endpoint);
146 }
147
148 pub fn prefixmap_in_memory(&self) -> PrefixMap {
150 self.graph
151 .as_ref()
152 .map(|g| g.prefixmap())
153 .unwrap_or_default()
154 }
155
156 pub fn show_blanknode(&self, bn: &OxBlankNode) -> String {
157 let str: String = format!("{}", bn);
158 format!("{}", str.green())
159 }
160
161 pub fn show_literal(&self, lit: &OxLiteral) -> String {
162 let str: String = format!("{}", lit);
163 format!("{}", str.red())
164 }
165
166 pub fn serialize<W: io::Write>(
167 &self,
168 format: &RDFFormat,
169 writer: &mut W,
170 ) -> Result<(), RdfDataError> {
171 if let Some(graph) = &self.graph {
172 graph
173 .serialize(format, writer)
174 .map_err(|e| RdfDataError::Serializing {
175 format: *format,
176 error: format!("{e}"),
177 })?
178 }
179 for e in self.endpoints.iter() {
180 writeln!(writer, "Endpoint {}", e.iri())?
181 }
182 Ok(())
183 }
184}
185
186impl Default for RdfData {
187 fn default() -> Self {
188 Self::new()
189 }
190}
191
192impl Rdf for RdfData {
193 type IRI = OxNamedNode;
194 type BNode = OxBlankNode;
195 type Literal = OxLiteral;
196 type Subject = OxSubject;
197 type Term = OxTerm;
198 type Triple = OxTriple;
199 type Err = RdfDataError;
200
201 fn prefixmap(&self) -> std::option::Option<PrefixMap> {
202 self.graph.as_ref().map(|g| g.prefixmap())
203 }
204
205 fn qualify_iri(&self, node: &Self::IRI) -> String {
206 let iri = IriS::from_str(node.as_str()).unwrap();
207 if let Some(graph) = &self.graph {
208 graph.prefixmap().qualify(&iri)
209 } else {
210 for e in self.endpoints.iter() {
211 if let Some(qualified) = e.prefixmap().qualify_optional(&iri) {
212 return qualified;
213 }
214 }
215 format!("<{node}>")
216 }
217 }
218
219 fn qualify_subject(&self, subj: &Self::Subject) -> String {
220 match subj {
221 OxSubject::BlankNode(bn) => self.show_blanknode(bn),
222 OxSubject::NamedNode(n) => self.qualify_iri(n),
223 OxSubject::Triple(_) => unimplemented!(),
225 }
226 }
227
228 fn qualify_term(&self, term: &Self::Term) -> String {
229 match term {
230 OxTerm::BlankNode(bn) => self.show_blanknode(bn),
231 OxTerm::Literal(lit) => self.show_literal(lit),
232 OxTerm::NamedNode(n) => self.qualify_iri(n),
233 OxTerm::Triple(_) => unimplemented!(),
235 }
236 }
237
238 fn resolve_prefix_local(
239 &self,
240 prefix: &str,
241 local: &str,
242 ) -> Result<IriS, prefixmap::PrefixMapError> {
243 if let Some(graph) = self.graph() {
244 let iri = graph.prefixmap().resolve_prefix_local(prefix, local)?;
245 Ok(iri.clone())
246 } else {
247 for e in self.endpoints.iter() {
248 if let Ok(iri) = e.prefixmap().resolve_prefix_local(prefix, local) {
249 return Ok(iri.clone());
250 }
251 }
252 Err(prefixmap::PrefixMapError::PrefixNotFound {
253 prefix: prefix.to_string(),
254 prefixmap: PrefixMap::new(),
255 })
256 }
257 }
258}
259
260impl Sparql for RdfData {
261 fn query_select(&self, query_str: &str) -> Result<QuerySolutions<RdfData>, RdfDataError>
262 where
263 Self: Sized,
264 {
265 let mut sols: QuerySolutions<RdfData> = QuerySolutions::empty();
266 let query = OxQuery::parse(query_str, None)?;
267 if let Some(store) = &self.store {
268 let new_sol = store.query(query)?;
269 let sol = cnv_query_results(new_sol)?;
270 sols.extend(sol)
271 }
272 for endpoint in &self.endpoints {
273 let new_sols = endpoint.query_select(query_str)?;
274 let new_sols_converted: Vec<QuerySolution<RdfData>> =
275 new_sols.iter().map(cnv_sol).collect();
276 sols.extend(new_sols_converted)
277 }
278 Ok(sols)
279 }
280
281 fn query_ask(&self, _query: &str) -> Result<bool, Self::Err> {
282 todo!()
283 }
284}
285
286fn cnv_sol(sol: &QuerySolution<SRDFSparql>) -> QuerySolution<RdfData> {
287 sol.convert(|t| t.clone())
288}
289
290fn cnv_query_results(
291 query_results: QueryResults,
292) -> Result<Vec<QuerySolution<RdfData>>, RdfDataError> {
293 let mut results = Vec::new();
294 if let QueryResults::Solutions(solutions) = query_results {
295 for solution in solutions {
296 let result = cnv_query_solution(solution?);
297 results.push(result)
298 }
299 }
300 Ok(results)
301}
302
303fn cnv_query_solution(qs: SparQuerySolution) -> QuerySolution<RdfData> {
304 let mut variables = Vec::new();
305 let mut values = Vec::new();
306 for v in qs.variables() {
307 let varname = VarName::new(v.as_str());
308 variables.push(varname);
309 }
310 for t in qs.values() {
311 let term = t.clone();
312 values.push(term)
313 }
314 QuerySolution::new(variables, values)
315}
316
317fn _cnv_rdf_format(rdf_format: RDFFormat) -> RdfFormat {
318 match rdf_format {
319 RDFFormat::NTriples => RdfFormat::NTriples,
320 RDFFormat::Turtle => RdfFormat::Turtle,
321 RDFFormat::RDFXML => RdfFormat::RdfXml,
322 RDFFormat::TriG => RdfFormat::TriG,
323 RDFFormat::N3 => RdfFormat::N3,
324 RDFFormat::NQuads => RdfFormat::NQuads,
325 }
326}
327
328fn _rdf_type() -> OxNamedNode {
329 OxNamedNode::new_unchecked(RDF_TYPE_STR)
330}
331
332impl Query for RdfData {
333 fn triples(&self) -> Result<impl Iterator<Item = Self::Triple>, Self::Err> {
334 let endpoints_triples = self.endpoints.iter().flat_map(Query::triples).flatten();
335 let graph_triples = self.graph.iter().flat_map(Query::triples).flatten();
336 Ok(endpoints_triples.chain(graph_triples))
337 }
338}
339
340impl FocusRDF for RdfData {
341 fn set_focus(&mut self, focus: &Self::Term) {
342 self.focus = Some(focus.clone())
343 }
344
345 fn get_focus(&self) -> &Option<Self::Term> {
346 &self.focus
347 }
348}
349
350impl SRDFBuilder for RdfData {
351 fn empty() -> Self {
352 todo!()
353 }
354
355 fn add_base(&mut self, _base: &Option<IriS>) -> Result<(), Self::Err> {
356 todo!()
357 }
358
359 fn add_prefix(&mut self, _alias: &str, _iri: &IriS) -> Result<(), Self::Err> {
360 todo!()
361 }
362
363 fn add_prefix_map(&mut self, _prefix_map: PrefixMap) -> Result<(), Self::Err> {
364 todo!()
365 }
366
367 fn add_triple<S, P, O>(&mut self, _subj: S, _pred: P, _obj: O) -> Result<(), Self::Err>
368 where
369 S: Into<Self::Subject>,
370 P: Into<Self::IRI>,
371 O: Into<Self::Term>,
372 {
373 todo!()
374 }
375
376 fn remove_triple<S, P, O>(&mut self, _subj: S, _pred: P, _obj: O) -> Result<(), Self::Err>
377 where
378 S: Into<Self::Subject>,
379 P: Into<Self::IRI>,
380 O: Into<Self::Term>,
381 {
382 todo!()
383 }
384
385 fn add_type<S, T>(&mut self, _node: S, _type_: T) -> Result<(), Self::Err>
386 where
387 S: Into<Self::Subject>,
388 T: Into<Self::Term>,
389 {
390 todo!()
391 }
392
393 fn serialize<W: std::io::Write>(
394 &self,
395 format: &RDFFormat,
396 writer: &mut W,
397 ) -> Result<(), Self::Err> {
398 if let Some(graph) = &self.graph {
399 graph.serialize(format, writer)?;
400 Ok::<(), Self::Err>(())
401 } else {
402 Ok(())
403 }?;
404 for endpoint in &self.endpoints {
405 writeln!(writer, "Endpoint {}", endpoint.iri())?;
406 }
407 Ok(())
408 }
409
410 fn add_bnode(&mut self) -> Result<Self::BNode, Self::Err> {
411 match self.graph {
412 Some(ref mut graph) => {
413 let bnode = graph.add_bnode()?;
414 Ok(bnode)
415 }
416 None => Err(RdfDataError::BNodeNoGraph),
417 }
418 }
419}