use crate::store::Store;
use crate::AsyncStore;
use oxilite_core::job::run_async;
use oxilite_core::registry::{SchemaGraph, SchemaRole};
use oxilite_core::shapes::ShapeIndex;
use oxilite_core::{encoding, ops, AsyncBackend, Result, SyncBackend};
use oxrdf::{GraphName, GraphNameRef, NamedNode};
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct Registration {
pub iri: Option<NamedNode>,
pub version: Option<String>,
pub sha256: Option<String>,
pub imports: Vec<NamedNode>,
pub active: bool,
}
impl Registration {
pub fn new() -> Self {
Self {
active: true,
..Default::default()
}
}
pub fn with_iri(mut self, iri: NamedNode) -> Self {
self.iri = Some(iri);
self
}
pub fn with_version(mut self, version: impl Into<String>) -> Self {
self.version = Some(version.into());
self
}
pub fn with_sha256(mut self, sha256: impl Into<String>) -> Self {
self.sha256 = Some(sha256.into());
self
}
pub fn with_imports(mut self, imports: impl IntoIterator<Item = NamedNode>) -> Self {
self.imports = imports.into_iter().collect();
self
}
pub fn inactive(mut self) -> Self {
self.active = false;
self
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct RegisteredGraph {
pub graph: GraphName,
pub role: SchemaRole,
pub registration: Registration,
pub loaded_at: f64,
}
fn now() -> f64 {
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.map_or(0.0, |d| d.as_secs_f64())
}
fn to_row(graph: i64, role: SchemaRole, r: &Registration) -> SchemaGraph {
SchemaGraph {
graph,
role,
iri: r.iri.as_ref().map(|n| n.as_str().to_owned()),
version: r.version.clone(),
sha256: r.sha256.clone(),
imports: r.imports.iter().map(|n| n.as_str().to_owned()).collect(),
active: r.active,
loaded_at: now(),
}
}
fn from_row(row: SchemaGraph, graph: GraphName) -> RegisteredGraph {
RegisteredGraph {
graph,
role: row.role,
registration: Registration {
iri: row.iri.and_then(|s| NamedNode::new(s).ok()),
version: row.version,
sha256: row.sha256,
imports: row
.imports
.into_iter()
.filter_map(|s| NamedNode::new(s).ok())
.collect(),
active: row.active,
},
loaded_at: row.loaded_at,
}
}
impl<B: SyncBackend + Send + Sync + 'static> Store<B> {
pub fn register_schema_graph<'a>(
&self,
graph: impl Into<GraphNameRef<'a>>,
role: SchemaRole,
registration: &Registration,
) -> Result<()> {
let graph = graph.into();
let id = encoding::graph_id(graph);
self.run(ops::register_schema_graph_job(
&to_row(id, role, registration),
graph,
self.caps(),
))?;
self.reload_stats()
}
pub fn schema_graphs(&self) -> Result<Vec<RegisteredGraph>> {
Ok(self
.run(ops::schema_graphs_job(self.caps()))?
.into_iter()
.map(|(row, name)| from_row(row, name))
.collect())
}
pub fn set_schema_graph_active<'a>(
&self,
graph: impl Into<GraphNameRef<'a>>,
active: bool,
) -> Result<bool> {
let id = encoding::graph_id(graph.into());
let changed = self.run(ops::set_schema_graph_active_job(id, active))?;
self.reload_stats()?;
Ok(changed)
}
pub fn unregister_schema_graph<'a>(&self, graph: impl Into<GraphNameRef<'a>>) -> Result<bool> {
let id = encoding::graph_id(graph.into());
let removed = self.run(ops::unregister_schema_graph_job(id))?;
self.reload_stats()?;
Ok(removed)
}
pub fn drop_schema_graph<'a>(&self, graph: impl Into<GraphNameRef<'a>>) -> Result<u64> {
let id = encoding::graph_id(graph.into());
let removed = self.run(ops::drop_schema_graph_job(id))?;
self.reload_stats()?;
Ok(removed)
}
pub fn shape_index(&self) -> Result<ShapeIndex> {
self.run(ops::shape_index_job(self.caps()))
}
}
impl<B: AsyncBackend> AsyncStore<B> {
pub async fn register_schema_graph<'a>(
&self,
graph: impl Into<GraphNameRef<'a>>,
role: SchemaRole,
registration: &Registration,
) -> Result<()> {
let graph = graph.into();
let id = encoding::graph_id(graph);
run_async(
&self.backend,
ops::register_schema_graph_job(&to_row(id, role, registration), graph, self.caps()),
)
.await?;
self.reload_stats().await
}
pub async fn schema_graphs(&self) -> Result<Vec<RegisteredGraph>> {
Ok(
run_async(&self.backend, ops::schema_graphs_job(self.caps()))
.await?
.into_iter()
.map(|(row, name)| from_row(row, name))
.collect(),
)
}
pub async fn set_schema_graph_active<'a>(
&self,
graph: impl Into<GraphNameRef<'a>>,
active: bool,
) -> Result<bool> {
let id = encoding::graph_id(graph.into());
let changed =
run_async(&self.backend, ops::set_schema_graph_active_job(id, active)).await?;
self.reload_stats().await?;
Ok(changed)
}
pub async fn unregister_schema_graph<'a>(
&self,
graph: impl Into<GraphNameRef<'a>>,
) -> Result<bool> {
let id = encoding::graph_id(graph.into());
let removed = run_async(&self.backend, ops::unregister_schema_graph_job(id)).await?;
self.reload_stats().await?;
Ok(removed)
}
pub async fn drop_schema_graph<'a>(&self, graph: impl Into<GraphNameRef<'a>>) -> Result<u64> {
let id = encoding::graph_id(graph.into());
let removed = run_async(&self.backend, ops::drop_schema_graph_job(id)).await?;
self.reload_stats().await?;
Ok(removed)
}
pub async fn shape_index(&self) -> Result<ShapeIndex> {
run_async(&self.backend, ops::shape_index_job(self.caps())).await
}
}