1use anyhow::{Result, anyhow};
20use ast::Arena;
21use mangle_ast as ast;
22
23mod tablestore;
24pub use tablestore::{TableConfig, TableStoreImpl, TableStoreSchema};
25
26#[cfg(feature = "edge")]
29#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Hash)]
30pub enum Value {
31 Number(i64),
32 String(String),
33 Null, }
35
36#[cfg(feature = "edge")]
37impl std::fmt::Display for Value {
38 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
39 match self {
40 Value::Number(n) => write!(f, "{n}"),
41 Value::String(s) => write!(f, "{s:?}"),
42 Value::Null => write!(f, "null"),
43 }
44 }
45}
46
47#[cfg(feature = "edge")]
49pub trait Store {
50 fn scan(&self, relation: &str) -> Result<Box<dyn Iterator<Item = Vec<Value>> + '_>>;
53
54 fn scan_delta(&self, relation: &str) -> Result<Box<dyn Iterator<Item = Vec<Value>> + '_>>;
56
57 fn scan_next_delta(&self, relation: &str) -> Result<Box<dyn Iterator<Item = Vec<Value>> + '_>>;
59
60 fn scan_index(
62 &self,
63 relation: &str,
64 col_idx: usize,
65 key: &Value,
66 ) -> Result<Box<dyn Iterator<Item = Vec<Value>> + '_>>;
67
68 fn scan_delta_index(
70 &self,
71 relation: &str,
72 col_idx: usize,
73 key: &Value,
74 ) -> Result<Box<dyn Iterator<Item = Vec<Value>> + '_>>;
75
76 fn insert(&mut self, relation: &str, tuple: Vec<Value>) -> Result<bool>;
79
80 fn merge_deltas(&mut self);
82
83 fn create_relation(&mut self, relation: &str);
85
86 fn retract(&mut self, relation: &str, tuple: &[Value]) -> Result<bool>;
89
90 fn clear(&mut self, relation: &str);
92
93 fn relation_names(&self) -> Vec<String>;
95}
96
97#[cfg(feature = "server")]
99pub trait Host {
100 fn scan_start(&mut self, rel_id: i32) -> i32;
101 fn scan_delta_start(&mut self, rel_id: i32) -> i32;
102 fn scan_index_start(&mut self, rel_id: i32, col_idx: i32, val: i64) -> i32;
103 fn scan_aggregate_start(&mut self, rel_id: i32, description: Vec<i32>) -> i32;
104 fn scan_next(&mut self, iter_id: i32) -> i32;
105 fn get_col(&mut self, tuple_ptr: i32, col_idx: i32) -> i64;
106 fn insert(&mut self, rel_id: i32, val: i64);
107 fn merge_deltas(&mut self) -> i32;
109 fn debuglog(&mut self, val: i64);
110}
111
112pub trait Receiver<'a> {
115 fn next(&self, item: &'a ast::Atom<'a>) -> Result<()>;
116}
117
118impl<'a, Closure: Fn(&'a ast::Atom<'a>) -> Result<()>> Receiver<'a> for Closure {
119 fn next(&self, item: &'a ast::Atom<'a>) -> Result<()> {
120 (*self)(item)
121 }
122}
123
124pub trait ReadOnlyFactStore<'a> {
126 fn arena(&'a self) -> &'a Arena;
127
128 fn contains<'src>(&'a self, src: &'src Arena, fact: &'src ast::Atom<'src>) -> Result<bool>;
129
130 fn get<'query, R: Receiver<'a>>(
133 &'a self,
134 query_sym: ast::PredicateIndex,
135 query_args: &'query [&'query ast::BaseTerm<'query>],
136 cb: &R,
137 ) -> Result<()>;
138
139 fn predicates(&'a self) -> Vec<ast::PredicateIndex>;
142
143 fn estimate_fact_count(&self) -> u32;
145}
146
147pub trait FactStore<'a>: ReadOnlyFactStore<'a> {
150 fn add<'src>(&'a self, src: &'src Arena, fact: &'src ast::Atom<'src>) -> Result<bool>;
153
154 fn merge<'src, S>(&'a self, src: &'src Arena, store: &'src S)
156 where
157 S: ReadOnlyFactStore<'src>;
158}
159
160pub fn get_all_facts<'a, S, R: Receiver<'a>>(store: &'a S, cb: &R) -> Result<()>
162where
163 S: ReadOnlyFactStore<'a> + 'a,
164{
165 let arena = Arena::new_with_global_interner();
166 let preds = store.predicates();
167
168 for pred in preds {
169 arena.copy_predicate_sym(store.arena(), pred);
170 store.get(pred, arena.new_query(pred).args, cb)?;
171 }
172 Ok(())
173}