#[cfg(target_arch = "wasm32")]
use std::path::Path;
#[cfg(not(target_arch = "wasm32"))]
use std::sync::Arc;
use crate::{Fact, Result, Triple};
#[cfg(not(target_arch = "wasm32"))]
use redb::Database;
#[cfg(not(target_arch = "wasm32"))]
pub mod disk;
pub mod memory;
pub mod property;
#[cfg(not(target_arch = "wasm32"))]
pub mod schema;
#[cfg(not(target_arch = "wasm32"))]
pub mod varint_key;
pub type HexastoreIter = Box<dyn Iterator<Item = Triple>>;
pub trait Hexastore: Send {
fn insert(&mut self, triple: &Triple) -> Result<bool>;
fn delete(&mut self, triple: &Triple) -> Result<bool>;
fn insert_fact(&mut self, fact: Fact<'_>) -> Result<Triple>;
fn query(
&self,
subject_id: Option<u64>,
predicate_id: Option<u64>,
object_id: Option<u64>,
) -> HexastoreIter;
fn iter(&self) -> HexastoreIter {
self.query(None, None, None)
}
fn resolve_str(&self, id: u64) -> Result<Option<String>>;
fn resolve_id(&self, value: &str) -> Result<Option<u64>>;
fn intern(&mut self, value: &str) -> Result<u64>;
fn dictionary_size(&self) -> Result<u64>;
fn set_node_property(&mut self, id: u64, value: &str) -> Result<()>;
fn get_node_property(&self, id: u64) -> Result<Option<String>>;
fn set_edge_property(&mut self, s: u64, p: u64, o: u64, value: &str) -> Result<()>;
fn get_edge_property(&self, s: u64, p: u64, o: u64) -> Result<Option<String>>;
fn set_node_property_binary(&mut self, id: u64, value: &[u8]) -> Result<()> {
let json_str = std::str::from_utf8(value)
.map_err(|e| crate::Error::Other(format!("invalid UTF-8: {}", e)))?;
self.set_node_property(id, json_str)
}
fn get_node_property_binary(&self, id: u64) -> Result<Option<Vec<u8>>> {
self.get_node_property(id)
.map(|opt| opt.map(|s| s.into_bytes()))
}
fn set_edge_property_binary(&mut self, s: u64, p: u64, o: u64, value: &[u8]) -> Result<()> {
let json_str = std::str::from_utf8(value)
.map_err(|e| crate::Error::Other(format!("invalid UTF-8: {}", e)))?;
self.set_edge_property(s, p, o, json_str)
}
fn get_edge_property_binary(&self, s: u64, p: u64, o: u64) -> Result<Option<Vec<u8>>> {
self.get_edge_property(s, p, o)
.map(|opt| opt.map(|s| s.into_bytes()))
}
fn delete_node_properties(&mut self, _id: u64) -> Result<()> {
Ok(())
}
fn batch_insert(&mut self, triples: &[Triple]) -> Result<usize> {
let mut count = 0;
for triple in triples {
if self.insert(triple)? {
count += 1;
}
}
Ok(count)
}
fn batch_delete(&mut self, triples: &[Triple]) -> Result<usize> {
let mut count = 0;
for triple in triples {
if self.delete(triple)? {
count += 1;
}
}
Ok(count)
}
fn batch_set_node_properties(&mut self, props: &[(u64, &str)]) -> Result<()> {
for (id, value) in props {
self.set_node_property(*id, value)?;
}
Ok(())
}
fn batch_set_edge_properties(&mut self, props: &[((u64, u64, u64), &str)]) -> Result<()> {
for ((s, p, o), value) in props {
self.set_edge_property(*s, *p, *o, value)?;
}
Ok(())
}
fn batch_insert_facts(&mut self, facts: &[Fact<'_>]) -> Result<Vec<Triple>> {
let mut results = Vec::with_capacity(facts.len());
for fact in facts {
results.push(self.insert_fact(*fact)?);
}
Ok(results)
}
fn bulk_intern(&mut self, values: &[&str]) -> Result<Vec<u64>> {
let mut ids = Vec::with_capacity(values.len());
for v in values {
ids.push(self.intern(v)?);
}
Ok(ids)
}
fn after_write_commit(&self) {}
}
#[cfg(not(target_arch = "wasm32"))]
pub fn open_store(db: Arc<Database>) -> Result<Box<dyn Hexastore + Send>> {
Ok(Box::new(disk::DiskHexastore::new(db)?))
}
#[cfg(target_arch = "wasm32")]
pub fn open_store<P: AsRef<Path>>(_path: P) -> Result<Box<dyn Hexastore + Send>> {
Ok(Box::new(memory::MemoryHexastore::new()))
}