|
|
@ -1,49 +1,102 @@
|
|
|
|
use cozorocks::SlicePtr;
|
|
|
|
use std::collections::BTreeMap;
|
|
|
|
|
|
|
|
use cozorocks::{SlicePtr, StatusCode};
|
|
|
|
use crate::db::engine::{Session};
|
|
|
|
use crate::db::engine::{Session};
|
|
|
|
use crate::relation::table::{Table};
|
|
|
|
use crate::relation::table::{Table};
|
|
|
|
use crate::relation::tuple::{Tuple};
|
|
|
|
use crate::relation::tuple::{Tuple};
|
|
|
|
use crate::relation::typing::Typing;
|
|
|
|
use crate::relation::typing::Typing;
|
|
|
|
use crate::relation::value::Value;
|
|
|
|
use crate::relation::value::Value;
|
|
|
|
use crate::error::Result;
|
|
|
|
use crate::error::{CozoError, Result};
|
|
|
|
use crate::relation::data::DataKind;
|
|
|
|
use crate::relation::data::DataKind;
|
|
|
|
|
|
|
|
|
|
|
|
pub trait Environment<T: AsRef<[u8]>> {
|
|
|
|
pub trait Environment<T: AsRef<[u8]>> {
|
|
|
|
|
|
|
|
fn get_stack_depth(&self) -> i32;
|
|
|
|
fn push_env(&mut self);
|
|
|
|
fn push_env(&mut self);
|
|
|
|
fn pop_env(&mut self) -> Result<()>;
|
|
|
|
fn pop_env(&mut self) -> Result<()>;
|
|
|
|
fn define_variable(&mut self, name: &str, val: &Value, in_root: bool) -> Result<()>;
|
|
|
|
fn define_variable(&mut self, name: &str, val: &Value, in_root: bool) -> Result<()> {
|
|
|
|
fn define_type_alias(&mut self, name: &str, typ: &Typing, in_root: bool) -> Result<()>;
|
|
|
|
let mut data = Tuple::with_data_prefix(DataKind::Value);
|
|
|
|
fn define_table(&mut self, table: &Table, in_root: bool) -> Result<()>;
|
|
|
|
data.push_value(val);
|
|
|
|
fn resolve(&self, name: &str) -> Result<Option<Tuple<T>>>;
|
|
|
|
self.define_data(name, data, in_root)
|
|
|
|
fn delete_defined(&mut self, name: &str, in_root: bool) -> Result<()>;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn define_type_alias(&mut self, name: &str, typ: &Typing, in_root: bool) -> Result<()> {
|
|
|
|
|
|
|
|
let mut data = Tuple::with_data_prefix(DataKind::TypeAlias);
|
|
|
|
|
|
|
|
data.push_str(typ.to_string());
|
|
|
|
|
|
|
|
self.define_data(name, data, in_root)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl<'a> Session<'a> {
|
|
|
|
fn define_table(&mut self, table: &Table, in_root: bool) -> Result<()> {
|
|
|
|
|
|
|
|
todo!()
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
fn resolve(&self, name: &str) -> Result<Option<Tuple<T>>>;
|
|
|
|
|
|
|
|
fn delete_defined(&mut self, name: &str, in_root: bool) -> Result<()>;
|
|
|
|
|
|
|
|
fn define_data(&mut self, name: &str, data: Tuple<Vec<u8>>, in_root: bool) -> Result<()>;
|
|
|
|
fn encode_definable_key(&self, name: &str, in_root: bool) -> Tuple<Vec<u8>> {
|
|
|
|
fn encode_definable_key(&self, name: &str, in_root: bool) -> Tuple<Vec<u8>> {
|
|
|
|
let depth_code = if in_root { 0 } else { self.stack_depth as i64 };
|
|
|
|
let depth_code = if in_root { 0 } else { self.get_stack_depth() as i64 };
|
|
|
|
let mut tuple = Tuple::with_null_prefix();
|
|
|
|
let mut tuple = Tuple::with_null_prefix();
|
|
|
|
tuple.push_str(name);
|
|
|
|
tuple.push_str(name);
|
|
|
|
tuple.push_int(depth_code);
|
|
|
|
tuple.push_int(depth_code);
|
|
|
|
tuple
|
|
|
|
tuple
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn define_data(&mut self, name: &str, data: Tuple<Vec<u8>>, in_root: bool) -> Result<()> {
|
|
|
|
pub struct MemoryEnv {
|
|
|
|
let key = self.encode_definable_key(name, in_root);
|
|
|
|
root: BTreeMap<String, Tuple<Vec<u8>>>,
|
|
|
|
if in_root {
|
|
|
|
stack: Vec<BTreeMap<String, Tuple<Vec<u8>>>>,
|
|
|
|
self.txn.put(true, &self.perm_cf, key, data)?;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
|
|
|
|
let mut ikey = Tuple::with_null_prefix();
|
|
|
|
impl Default for MemoryEnv {
|
|
|
|
ikey.push_int(self.stack_depth as i64);
|
|
|
|
fn default() -> Self {
|
|
|
|
ikey.push_str(name);
|
|
|
|
MemoryEnv { root: BTreeMap::default(), stack: vec![BTreeMap::default()] }
|
|
|
|
self.txn.put(false, &self.temp_cf, key, data)?;
|
|
|
|
}
|
|
|
|
self.txn.put(false, &self.temp_cf, ikey, "")?;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
impl Environment<Tuple<Vec<u8>>> for MemoryEnv {
|
|
|
|
|
|
|
|
fn get_stack_depth(&self) -> i32 {
|
|
|
|
|
|
|
|
-(self.stack.len() as i32)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn push_env(&mut self) {
|
|
|
|
|
|
|
|
self.stack.push(BTreeMap::default());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn pop_env(&mut self) -> Result<()> {
|
|
|
|
|
|
|
|
if self.stack.len() > 1 {
|
|
|
|
|
|
|
|
self.stack.pop();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn define_variable(&mut self, name: &str, val: &Value, in_root: bool) -> Result<()> {
|
|
|
|
|
|
|
|
todo!()
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn define_type_alias(&mut self, name: &str, typ: &Typing, in_root: bool) -> Result<()> {
|
|
|
|
|
|
|
|
todo!()
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn define_table(&mut self, table: &Table, in_root: bool) -> Result<()> {
|
|
|
|
|
|
|
|
todo!()
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn resolve(&self, name: &str) -> Result<Option<Tuple<Tuple<Vec<u8>>>>> {
|
|
|
|
|
|
|
|
todo!()
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn delete_defined(&mut self, name: &str, in_root: bool) -> Result<()> {
|
|
|
|
|
|
|
|
todo!()
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn define_data(&mut self, name: &str, data: Tuple<Vec<u8>>, in_root: bool) -> Result<()> {
|
|
|
|
|
|
|
|
todo!()
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
impl<'a> Environment<SlicePtr> for Session<'a> {
|
|
|
|
impl<'a> Environment<SlicePtr> for Session<'a> {
|
|
|
|
|
|
|
|
fn get_stack_depth(&self) -> i32 {
|
|
|
|
|
|
|
|
self.stack_depth
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn push_env(&mut self) {
|
|
|
|
fn push_env(&mut self) {
|
|
|
|
self.stack_depth -= 1;
|
|
|
|
self.stack_depth -= 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -76,48 +129,29 @@ impl<'a> Environment<SlicePtr> for Session<'a> {
|
|
|
|
Ok(())
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn define_variable(&mut self, name: &str, val: &Value, in_root: bool) -> Result<()> {
|
|
|
|
|
|
|
|
let mut data = Tuple::with_data_prefix(DataKind::Value);
|
|
|
|
|
|
|
|
data.push_value(val);
|
|
|
|
|
|
|
|
self.define_data(name, data, in_root)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn define_type_alias(&mut self, name: &str, typ: &Typing, in_root: bool) -> Result<()> {
|
|
|
|
|
|
|
|
let mut data = Tuple::with_data_prefix(DataKind::TypeAlias);
|
|
|
|
|
|
|
|
data.push_str(typ.to_string());
|
|
|
|
|
|
|
|
self.define_data(name, data, in_root)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn define_table(&mut self, table: &Table, in_root: bool) -> Result<()> {
|
|
|
|
|
|
|
|
todo!()
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn resolve(&self, name: &str) -> Result<Option<Tuple<SlicePtr>>> {
|
|
|
|
fn resolve(&self, name: &str) -> Result<Option<Tuple<SlicePtr>>> {
|
|
|
|
let mut tuple = Tuple::with_null_prefix();
|
|
|
|
let mut tuple = Tuple::with_null_prefix();
|
|
|
|
tuple.push_str(name);
|
|
|
|
tuple.push_str(name);
|
|
|
|
let it = self.txn.iterator(false, &self.temp_cf);
|
|
|
|
let it = self.txn.iterator(false, &self.temp_cf);
|
|
|
|
it.seek(&tuple);
|
|
|
|
it.seek(&tuple);
|
|
|
|
Ok(match it.pair() {
|
|
|
|
if let Some((tk, vk)) = it.pair() {
|
|
|
|
None => {
|
|
|
|
|
|
|
|
None
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
Some((tk, vk)) => {
|
|
|
|
|
|
|
|
let k = Tuple::new(tk);
|
|
|
|
let k = Tuple::new(tk);
|
|
|
|
if k.starts_with(&tuple) {
|
|
|
|
if k.starts_with(&tuple) {
|
|
|
|
println!("Resolved to key {:?}", k);
|
|
|
|
return Ok(Some(Tuple::new(vk)));
|
|
|
|
Some(Tuple::new(vk))
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
|
|
|
|
None
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
let root_key = self.encode_definable_key(name, true);
|
|
|
|
|
|
|
|
match self.txn.get(true, &self.perm_cf, root_key) {
|
|
|
|
|
|
|
|
Ok(root_res) => Ok(Some(Tuple::new(root_res))),
|
|
|
|
|
|
|
|
Err(e) if e.status.code == StatusCode::kNotFound => Ok(None),
|
|
|
|
|
|
|
|
Err(e) => Err(CozoError::Bridge(e))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn delete_defined(&mut self, name: &str, in_root: bool) -> Result<()> {
|
|
|
|
fn delete_defined(&mut self, name: &str, in_root: bool) -> Result<()> {
|
|
|
|
let key = self.encode_definable_key(name, in_root);
|
|
|
|
let key = self.encode_definable_key(name, in_root);
|
|
|
|
if in_root {
|
|
|
|
if in_root {
|
|
|
|
self.txn.del(true, &self.perm_cf, key)?;
|
|
|
|
self.txn.del(true, &self.perm_cf, key)?;
|
|
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
let it = self.txn.iterator(false, &self.temp_cf);
|
|
|
|
let it = self.txn.iterator(false, &self.temp_cf);
|
|
|
|
it.seek(&key);
|
|
|
|
it.seek(&key);
|
|
|
@ -129,7 +163,6 @@ impl<'a> Environment<SlicePtr> for Session<'a> {
|
|
|
|
ikey.push_value(&found_key_tuple.get(0).unwrap());
|
|
|
|
ikey.push_value(&found_key_tuple.get(0).unwrap());
|
|
|
|
self.txn.del(false, &self.temp_cf, found_key_tuple)?;
|
|
|
|
self.txn.del(false, &self.temp_cf, found_key_tuple)?;
|
|
|
|
self.txn.del(false, &self.temp_cf, ikey)?;
|
|
|
|
self.txn.del(false, &self.temp_cf, ikey)?;
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -137,4 +170,18 @@ impl<'a> Environment<SlicePtr> for Session<'a> {
|
|
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn define_data(&mut self, name: &str, data: Tuple<Vec<u8>>, in_root: bool) -> Result<()> {
|
|
|
|
|
|
|
|
let key = self.encode_definable_key(name, in_root);
|
|
|
|
|
|
|
|
if in_root {
|
|
|
|
|
|
|
|
self.txn.put(true, &self.perm_cf, key, data)?;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
let mut ikey = Tuple::with_null_prefix();
|
|
|
|
|
|
|
|
ikey.push_int(self.stack_depth as i64);
|
|
|
|
|
|
|
|
ikey.push_str(name);
|
|
|
|
|
|
|
|
self.txn.put(false, &self.temp_cf, key, data)?;
|
|
|
|
|
|
|
|
self.txn.put(false, &self.temp_cf, ikey, "")?;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|