1use crate::core::value::Value;
4use std::collections::HashMap;
5
6pub struct Database {
7 db: HashMap<String, Vec<Vec<Value>>>,
8 default_table: Vec<Vec<Value>>,
9}
10
11impl Database {
12 pub fn new() -> Self {
13 Database {
14 db: HashMap::new(),
15 default_table: vec![],
16 }
17 }
18
19 pub fn insert(&mut self, table_name: &str, row: Vec<Value>) {
20 if let Some(table) = self.db.get_mut(table_name) {
21 table.push(row)
22 } else {
23 self.db.insert(table_name.to_string(), vec![row]);
24 }
25 }
26
27 pub fn query(
28 &self,
29 table_name: &str,
30 ) -> impl Iterator<Item = impl Iterator<Item = &Value> + '_> + '_ {
31 let table = self.db.get(table_name).unwrap_or(&self.default_table);
32 table.into_iter().map(|row| row.into_iter())
33 }
34}
35
36#[macro_export]
41macro_rules! db_rel {
42 ($($rel:ident($($args:ident),*));* $(;)?) => {
43 $(
44 fn $rel(db: &Arc<$crate::database::Database>, $($args: impl Into<$crate::prelude::Value>),*) -> impl Clone + $crate::prelude::Goal<$crate::prelude::Substitution<'static>> {
46 let db = db.clone();
47 $(let $args = $args.into();)*
48 move |s: $crate::prelude::Substitution<'static>| {
49 let values = db.query(stringify!($rel));
50 let subs = values
51 .filter_map(|mut value| {
52 let s = s.clone();
53 $(let s = s.unify(&$args, value.next()?)?;)*
54 Some(s)
55 });
56 $crate::prelude::Stream::from_iter(subs)
57 }
58 }
59 )*
60 };
61}
62
63#[macro_export]
65macro_rules! db_facts {
66 ($($db:ident { $($rel:ident($($args:expr),*));* $(;)? })*) => {
67 $( $(
68 $db.insert(stringify!($rel), vec![$($crate::prelude::Value::new($args)),*]);
69 )* )*
70 };
71}