Skip to main content

synapse_core/
store.rs

1use anyhow::Result;
2use oxigraph::model::*;
3use oxigraph::store::Store;
4use std::collections::HashMap;
5use std::path::PathBuf;
6use std::sync::RwLock;
7
8pub struct SynapseStore {
9    pub store: Store,
10    pub namespace: String,
11    // Mapping for gRPC compatibility (ID <-> URI)
12    pub id_to_uri: RwLock<HashMap<u32, String>>,
13    pub uri_to_id: RwLock<HashMap<String, u32>>,
14    pub next_id: std::sync::atomic::AtomicU32,
15}
16
17impl SynapseStore {
18    pub fn open(namespace: &str, storage_path: &str) -> Result<Self> {
19        let path = PathBuf::from(storage_path).join(namespace);
20        let store = Store::open(path)?;
21        
22        Ok(Self {
23            store,
24            namespace: namespace.to_string(),
25            id_to_uri: RwLock::new(HashMap::new()),
26            uri_to_id: RwLock::new(HashMap::new()),
27            next_id: std::sync::atomic::AtomicU32::new(1),
28        })
29    }
30
31    pub fn get_or_create_id(&self, uri: &str) -> u32 {
32        {
33            let map = self.uri_to_id.read().unwrap();
34            if let Some(&id) = map.get(uri) {
35                return id;
36            }
37        }
38        
39        let mut uri_map = self.uri_to_id.write().unwrap();
40        let mut id_map = self.id_to_uri.write().unwrap();
41        
42        if let Some(&id) = uri_map.get(uri) {
43            return id;
44        }
45        
46        let id = self.next_id.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
47        uri_map.insert(uri.to_string(), id);
48        id_map.insert(id, uri.to_string());
49        id
50    }
51
52    pub fn get_uri(&self, id: u32) -> Option<String> {
53        self.id_to_uri.read().unwrap().get(&id).cloned()
54    }
55
56    pub fn ingest_triples(&self, triples: Vec<(String, String, String)>) -> Result<(u32, u32)> {
57        let mut added = 0;
58        
59        for (s, p, o) in triples {
60            let subject_uri = self.ensure_uri(&s);
61            let predicate_uri = self.ensure_uri(&p);
62            let object_uri = self.ensure_uri(&o);
63            
64            let subject = Subject::NamedNode(NamedNode::new_unchecked(&subject_uri));
65            let predicate = NamedNode::new_unchecked(&predicate_uri);
66            let object = Term::NamedNode(NamedNode::new_unchecked(&object_uri));
67            
68            let quad = Quad::new(subject, predicate, object, GraphName::DefaultGraph);
69            if self.store.insert(&quad)? {
70                added += 1;
71            }
72        }
73
74        Ok((added, 0))
75    }
76
77    fn ensure_uri(&self, s: &str) -> String {
78        if s.starts_with("http") {
79            s.to_string()
80        } else {
81            format!("http://synapse.os/{}", s)
82        }
83    }
84}