use super::{OxirsQueryResults, RdfStore};
use crate::model::{NamedNode, Quad};
use crate::Result;
use std::sync::Arc;
use tokio::sync::RwLock;
use tokio::task;
pub struct AsyncRdfStore {
store: Arc<RwLock<RdfStore>>,
}
impl AsyncRdfStore {
pub fn new(store: RdfStore) -> Self {
Self {
store: Arc::new(RwLock::new(store)),
}
}
pub async fn store(&self) -> tokio::sync::RwLockReadGuard<'_, RdfStore> {
self.store.read().await
}
pub async fn store_mut(&self) -> tokio::sync::RwLockWriteGuard<'_, RdfStore> {
self.store.write().await
}
pub async fn query_async(&self, sparql: &str) -> Result<OxirsQueryResults> {
let sparql = sparql.to_string();
let store = self.store.clone();
task::spawn_blocking(move || {
let store = futures::executor::block_on(store.read());
store.query(&sparql)
})
.await
.map_err(|e| crate::OxirsError::Io(format!("Task error: {}", e)))?
}
pub async fn insert_quad_async(&self, quad: Quad) -> Result<bool> {
let mut store = self.store.write().await;
store.insert_quad(quad)
}
pub async fn remove_quad_async(&self, quad: &Quad) -> Result<bool> {
let mut store = self.store.write().await;
store.remove_quad(quad)
}
pub async fn len_async(&self) -> Result<usize> {
let store = self.store.read().await;
store.len()
}
pub async fn is_empty_async(&self) -> Result<bool> {
let store = self.store.read().await;
store.is_empty()
}
pub async fn clear_async(&self) -> Result<()> {
let mut store = self.store.write().await;
store.clear()
}
pub async fn quads_async(&self) -> Result<Vec<Quad>> {
let store = self.store.read().await;
store.quads()
}
pub async fn graphs_async(&self) -> Result<Vec<NamedNode>> {
let store = self.store.read().await;
store.graphs()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::model::*;
#[tokio::test]
async fn test_async_store_creation() {
let store = RdfStore::new().expect("store creation should succeed");
let _async_store = AsyncRdfStore::new(store);
}
#[tokio::test]
async fn test_async_insert_and_query() {
let store = RdfStore::new().expect("store creation should succeed");
let async_store = AsyncRdfStore::new(store);
let quad = Quad::new(
NamedNode::new("http://example.org/s").expect("valid IRI"),
NamedNode::new("http://example.org/p").expect("valid IRI"),
NamedNode::new("http://example.org/o").expect("valid IRI"),
GraphName::DefaultGraph,
);
async_store
.insert_quad_async(quad)
.await
.expect("async operation should succeed");
let count = async_store
.len_async()
.await
.expect("async operation should succeed");
assert_eq!(count, 1);
}
#[tokio::test]
async fn test_async_query() {
let store = RdfStore::new().expect("store creation should succeed");
let async_store = AsyncRdfStore::new(store);
let quad = Quad::new(
NamedNode::new("http://example.org/s").expect("valid IRI"),
NamedNode::new("http://example.org/p").expect("valid IRI"),
NamedNode::new("http://example.org/o").expect("valid IRI"),
GraphName::DefaultGraph,
);
async_store
.insert_quad_async(quad)
.await
.expect("async operation should succeed");
let _results = async_store
.query_async("SELECT * WHERE { ?s ?p ?o }")
.await
.expect("operation should succeed");
}
}