parent
17a3ae728d
commit
a5c49a73b1
@ -0,0 +1,150 @@ |
||||
//! Utilities for I/O from the store
|
||||
|
||||
use crate::error::invalid_input_error; |
||||
use crate::io::{DatasetFormat, DatasetSerializer, GraphFormat, GraphSerializer}; |
||||
use crate::model::{GraphNameRef, Quad, Triple}; |
||||
use crate::store::numeric_encoder::WriteEncoder; |
||||
use crate::store::storage::StorageLike; |
||||
use oxiri::Iri; |
||||
use rio_api::parser::{QuadsParser, TriplesParser}; |
||||
use rio_turtle::{NQuadsParser, NTriplesParser, TriGParser, TurtleError, TurtleParser}; |
||||
use rio_xml::{RdfXmlError, RdfXmlParser}; |
||||
use std::collections::HashMap; |
||||
use std::io; |
||||
use std::io::{BufRead, Write}; |
||||
|
||||
pub(crate) fn load_graph<S: StorageLike>( |
||||
storage: &S, |
||||
reader: impl BufRead, |
||||
format: GraphFormat, |
||||
to_graph_name: GraphNameRef<'_>, |
||||
base_iri: Option<&str>, |
||||
) -> Result<(), StoreOrParseError<S::Error>> { |
||||
let base_iri = if let Some(base_iri) = base_iri { |
||||
Some(Iri::parse(base_iri.into()).map_err(invalid_input_error)?) |
||||
} else { |
||||
None |
||||
}; |
||||
match format { |
||||
GraphFormat::NTriples => { |
||||
load_from_triple_parser(storage, NTriplesParser::new(reader), to_graph_name) |
||||
} |
||||
GraphFormat::Turtle => { |
||||
load_from_triple_parser(storage, TurtleParser::new(reader, base_iri), to_graph_name) |
||||
} |
||||
GraphFormat::RdfXml => { |
||||
load_from_triple_parser(storage, RdfXmlParser::new(reader, base_iri), to_graph_name) |
||||
} |
||||
} |
||||
} |
||||
|
||||
fn load_from_triple_parser<S: StorageLike, P: TriplesParser>( |
||||
storage: &S, |
||||
mut parser: P, |
||||
to_graph_name: GraphNameRef<'_>, |
||||
) -> Result<(), StoreOrParseError<S::Error>> |
||||
where |
||||
StoreOrParseError<S::Error>: From<P::Error>, |
||||
{ |
||||
let mut bnode_map = HashMap::default(); |
||||
let to_graph_name = storage |
||||
.encode_graph_name(to_graph_name) |
||||
.map_err(StoreOrParseError::Store)?; |
||||
parser.parse_all(&mut move |t| { |
||||
let quad = storage |
||||
.encode_rio_triple_in_graph(t, to_graph_name, &mut bnode_map) |
||||
.map_err(StoreOrParseError::Store)?; |
||||
storage.insert(&quad).map_err(StoreOrParseError::Store)?; |
||||
Ok(()) |
||||
}) |
||||
} |
||||
|
||||
pub fn dump_graph( |
||||
triples: impl Iterator<Item = Result<Triple, io::Error>>, |
||||
writer: impl Write, |
||||
format: GraphFormat, |
||||
) -> Result<(), io::Error> { |
||||
let mut writer = GraphSerializer::from_format(format).triple_writer(writer)?; |
||||
for triple in triples { |
||||
writer.write(&triple?)?; |
||||
} |
||||
writer.finish() |
||||
} |
||||
|
||||
pub(crate) fn load_dataset<S: StorageLike>( |
||||
store: &S, |
||||
reader: impl BufRead, |
||||
format: DatasetFormat, |
||||
base_iri: Option<&str>, |
||||
) -> Result<(), StoreOrParseError<S::Error>> { |
||||
let base_iri = if let Some(base_iri) = base_iri { |
||||
Some(Iri::parse(base_iri.into()).map_err(invalid_input_error)?) |
||||
} else { |
||||
None |
||||
}; |
||||
match format { |
||||
DatasetFormat::NQuads => load_from_quad_parser(store, NQuadsParser::new(reader)), |
||||
DatasetFormat::TriG => load_from_quad_parser(store, TriGParser::new(reader, base_iri)), |
||||
} |
||||
} |
||||
|
||||
fn load_from_quad_parser<S: StorageLike, P: QuadsParser>( |
||||
store: &S, |
||||
mut parser: P, |
||||
) -> Result<(), StoreOrParseError<S::Error>> |
||||
where |
||||
StoreOrParseError<S::Error>: From<P::Error>, |
||||
{ |
||||
let mut bnode_map = HashMap::default(); |
||||
parser.parse_all(&mut move |q| { |
||||
let quad = store |
||||
.encode_rio_quad(q, &mut bnode_map) |
||||
.map_err(StoreOrParseError::Store)?; |
||||
store.insert(&quad).map_err(StoreOrParseError::Store)?; |
||||
Ok(()) |
||||
}) |
||||
} |
||||
|
||||
pub fn dump_dataset( |
||||
quads: impl Iterator<Item = Result<Quad, io::Error>>, |
||||
writer: impl Write, |
||||
format: DatasetFormat, |
||||
) -> Result<(), io::Error> { |
||||
let mut writer = DatasetSerializer::from_format(format).quad_writer(writer)?; |
||||
for quad in quads { |
||||
writer.write(&quad?)?; |
||||
} |
||||
writer.finish() |
||||
} |
||||
|
||||
pub(crate) enum StoreOrParseError<S> { |
||||
Store(S), |
||||
Parse(io::Error), |
||||
} |
||||
|
||||
impl<S> From<TurtleError> for StoreOrParseError<S> { |
||||
fn from(error: TurtleError) -> Self { |
||||
Self::Parse(error.into()) |
||||
} |
||||
} |
||||
|
||||
impl<S> From<RdfXmlError> for StoreOrParseError<S> { |
||||
fn from(error: RdfXmlError) -> Self { |
||||
Self::Parse(error.into()) |
||||
} |
||||
} |
||||
|
||||
impl<S> From<io::Error> for StoreOrParseError<S> { |
||||
fn from(error: io::Error) -> Self { |
||||
Self::Parse(error) |
||||
} |
||||
} |
||||
|
||||
impl From<StoreOrParseError<io::Error>> for io::Error { |
||||
fn from(error: StoreOrParseError<io::Error>) -> Self { |
||||
match error { |
||||
StoreOrParseError::Store(error) => error, |
||||
StoreOrParseError::Parse(error) => error, |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue