pub mod memory;
#[cfg(feature = "sled-backend")]
pub mod sled;
#[cfg(feature = "rocksdb-backend")]
pub mod rocksdb;
#[cfg(feature = "sqlite-backend")]
pub mod sqlite;
use crate::{Result, Triple, TripleId};
pub trait StorageBackend: Send + Sync {
fn put(&self, id: &TripleId, triple: &Triple) -> Result<()>;
fn get(&self, id: &TripleId) -> Result<Option<Triple>>;
fn delete(&self, id: &TripleId) -> Result<bool>;
fn exists(&self, id: &TripleId) -> Result<bool> {
Ok(self.get(id)?.is_some())
}
fn iter_all(&self) -> Result<Vec<Triple>>;
fn count(&self) -> usize;
fn size_bytes(&self) -> usize;
fn apply_batch(&self, items: &[(&TripleId, &Triple)]) -> Result<()> {
for (id, triple) in items {
self.put(id, triple)?;
}
Ok(())
}
fn flush(&self) -> Result<()> {
Ok(())
}
fn close(&self) -> Result<()> {
Ok(())
}
fn as_any(&self) -> &dyn std::any::Any;
}
pub use memory::MemoryBackend;
#[cfg(feature = "sled-backend")]
pub use self::sled::SledBackend;
#[cfg(feature = "rocksdb-backend")]
pub use self::rocksdb::RocksBackend;
#[cfg(feature = "sqlite-backend")]
pub use self::sqlite::SqliteBackend;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_memory_backend_implements_storage_backend() {
let backend = MemoryBackend::new();
fn accepts_backend<T: StorageBackend>(_: &T) {}
accepts_backend(&backend);
}
#[test]
fn test_memory_backend_basic_operations() {
use crate::{NodeId, Predicate, Triple, Value};
let backend = MemoryBackend::new();
assert_eq!(backend.count(), 0);
let subject = NodeId::blank();
let predicate = Predicate::named("test:predicate");
let object = Value::String("test".into());
let triple = Triple::new(subject.clone(), predicate.clone(), object);
let id = triple.id();
backend.put(&id, &triple).unwrap();
assert_eq!(backend.count(), 1);
assert!(backend.exists(&id).unwrap());
let retrieved = backend.get(&id).unwrap();
assert!(retrieved.is_some());
let deleted = backend.delete(&id).unwrap();
assert!(deleted);
assert_eq!(backend.count(), 0);
assert!(!backend.exists(&id).unwrap());
}
#[test]
fn test_memory_backend_iter_all() {
use crate::{NodeId, Predicate, Triple, Value};
let backend = MemoryBackend::new();
for i in 0..5 {
let triple = Triple::new(
NodeId::blank(),
Predicate::named(format!("pred:{}", i)),
Value::Integer(i),
);
backend.put(&triple.id(), &triple).unwrap();
}
let all = backend.iter_all().unwrap();
assert_eq!(all.len(), 5);
}
#[test]
fn test_memory_backend_size() {
let backend = MemoryBackend::new();
let initial_size = backend.size_bytes();
let _ = initial_size;
}
#[test]
fn test_default_flush_and_close() {
let backend = MemoryBackend::new();
assert!(backend.flush().is_ok());
assert!(backend.close().is_ok());
}
}