more helper functions

main
Ziyang Hu 2 years ago
parent 1ddfbef091
commit a86e553f6a

@ -20,6 +20,7 @@ use crate::relation::value;
/// `[Int, Text]`: inverted index for depth info
/// `[Null, Text, Int, Int, Text]` inverted index for related tables
/// `[Null, Int, Text, Int, Text]` inverted index for related tables
/// `[True, Int]` table info, value is key
pub trait Environment<'t, T: AsRef<[u8]>> where Self: Sized {
fn get_next_storage_id(&mut self, in_root: bool) -> Result<i64>;
@ -32,6 +33,7 @@ pub trait Environment<'t, T: AsRef<[u8]>> where Self: Sized {
data.push_value(val);
self.define_data(name, data, in_root)
}
fn get_table_info(&self, id: i64, in_root: bool) -> Result<Option<Tuple<T>>>;
fn resolve(&self, name: &str) -> Result<Option<Tuple<T>>>;
fn resolve_related_tables(&self, name: &str) -> Result<Vec<(String, Tuple<SlicePtr>)>>;
fn resolve_param(&self, name: &str) -> Result<Value>;
@ -54,7 +56,7 @@ pub trait Environment<'t, T: AsRef<[u8]>> where Self: Sized {
}
fn delete_defined(&mut self, name: &str, in_root: bool) -> Result<()>;
fn define_data(&mut self, name: &str, data: OwnTuple, in_root: bool) -> Result<()>;
fn define_raw_key(&mut self, key: OwnTuple, in_root: bool) -> Result<()>;
fn define_raw_key(&mut self, key: OwnTuple, value: Option<OwnTuple>, in_root: bool) -> Result<()>;
fn encode_definable_key(&self, name: &str, in_root: bool) -> OwnTuple {
let depth_code = if in_root { 0 } else { self.get_stack_depth() as i64 };
let mut tuple = Tuple::with_null_prefix();
@ -111,7 +113,7 @@ pub trait Environment<'t, T: AsRef<[u8]>> where Self: Sized {
}
let (keys_typing, vals_typing) = self.parse_cols(pairs.next().unwrap())?;
if keys_typing.to_string() != "()" {
if keys_typing.to_string() != "{}" {
return Err(CozoError::LogicError("Cannot have keys in assoc".to_string()));
}
@ -259,11 +261,16 @@ pub trait Environment<'t, T: AsRef<[u8]>> where Self: Sized {
pair.into_inner().next().unwrap(), in_root,
)?;
if need_id {
let id = self.get_next_storage_id(in_root)?;
tuple = tuple.insert_values_at(0, &[in_root.into(),
(self.get_next_storage_id(in_root)?).into()]);
id.into()]);
let mut id_key = Tuple::with_null_prefix();
id_key.push_bool(true);
id_key.push_int(id);
self.define_raw_key(id_key, Some(tuple.clone()), in_root).unwrap();
}
for t in assoc_defs {
self.define_raw_key(t, in_root).unwrap();
self.define_raw_key(t, None, in_root).unwrap();
}
self.define_data(&name, tuple, in_root)
}
@ -765,6 +772,23 @@ impl<'a, 't> Environment<'t, SlicePtr> for Session<'a, 't> {
ikey.push_value(&name);
ikey.push_int(self.stack_depth as i64);
let data = self.txn.get(false, &self.temp_cf, &ikey)?
.ok_or_else(|| CozoError::LogicError("Bad format for ikey".to_string()))?;
let data = Tuple::new(data);
match data.data_kind()? {
DataKind::Node |
DataKind::Edge |
DataKind::Assoc |
DataKind::Index => {
let id = data.get_int(1).ok_or_else(|| CozoError::LogicError("Bad table index".to_string()))?;
let mut rkey = Tuple::with_null_prefix();
rkey.push_bool(true);
rkey.push_int(id);
self.txn.del(false, &self.temp_cf, rkey)?;
}
_ => {}
}
self.txn.del(false, &self.temp_cf, cur)?;
self.txn.del(false, &self.temp_cf, ikey)?;
}
@ -806,6 +830,19 @@ impl<'a, 't> Environment<'t, SlicePtr> for Session<'a, 't> {
self.params.insert(name.to_string(), val);
}
fn get_table_info(&self, id: i64, in_root: bool) -> Result<Option<Tuple<SlicePtr>>> {
let mut key = Tuple::with_null_prefix();
key.push_bool(true);
key.push_int(id);
if in_root {
let data = self.txn.get(true, &self.perm_cf, key)?;
Ok(data.map(Tuple::new))
} else {
let data = self.txn.get(false, &self.temp_cf, key)?;
Ok(data.map(Tuple::new))
}
}
fn resolve(&self, name: &str) -> Result<Option<Tuple<SlicePtr>>> {
let mut tuple = Tuple::with_null_prefix();
tuple.push_str(name);
@ -904,11 +941,25 @@ impl<'a, 't> Environment<'t, SlicePtr> for Session<'a, 't> {
Ok(())
}
fn define_raw_key(&mut self, key: OwnTuple, in_root: bool) -> Result<()> {
fn define_raw_key(&mut self, key: OwnTuple, value: Option<OwnTuple>, in_root: bool) -> Result<()> {
if in_root {
self.txn.put(true, &self.perm_cf, key, "")?;
match value {
None => {
self.txn.put(true, &self.perm_cf, key, "")?;
}
Some(v) => {
self.txn.put(true, &self.perm_cf, key, &v)?;
}
}
} else {
self.txn.put(false, &self.temp_cf, key, "")?;
match value {
None => {
self.txn.put(false, &self.temp_cf, key, "")?;
}
Some(v) => {
self.txn.put(false, &self.temp_cf, key, &v)?;
}
}
}
Ok(())
}

@ -8,8 +8,18 @@ use crate::error::{CozoError, Result};
use crate::parser::Rule;
use crate::parser::text_identifier::build_name_in_def;
use crate::relation::data::DataKind;
use crate::relation::typing::Typing;
use crate::relation::value::Value;
/// # key layouts
///
/// * Node
/// * `[table_id, keys]`
/// * Edge
/// * `[table_id, fst_table_id, fst_keys, is_forward, snd_keys, other_keys]` twice, the backward has no data
/// * Associate
/// * Same as the main one
impl<'a, 't> Session<'a, 't> {
pub fn run_mutation(&mut self, pair: Pair<Rule>) -> Result<()> {
let mut pairs = pair.into_inner();
@ -61,30 +71,31 @@ impl<'a, 'b, 't> MutationManager<'a, 'b, 't> {
fn new(sess: &'a Session<'b, 't>, default_tbl: Option<String>) -> Self {
Self { sess, cache: BTreeMap::new(), default_tbl }
}
fn add(&mut self, val_map: BTreeMap<Cow<str>, Value>) -> Result<()> {
let tbl_name = match val_map.get("_type") {
Some(Value::Text(t)) => t as &str,
Some(_) => return Err(LogicError("Table kind must be text".to_string())),
None => match &self.default_tbl {
Some(v) => v as &str,
None => return Err(LogicError("Cannot determine table kind".to_string()))
}
};
match self.cache.get(tbl_name) {
fn get_table_info(&mut self, tbl_name: Cow<str>) -> Result<()> {
match self.cache.get(tbl_name.as_ref()) {
None => {
match self.sess.resolve(tbl_name)? {
match self.sess.resolve(&tbl_name)? {
None => return Err(CozoError::UndefinedType(tbl_name.to_string())),
Some(tpl) => {
println!("Found tuple {:?}", tpl);
match tpl.data_kind()? {
DataKind::Node => {
println!("Found node {:?}", tpl);
let key_extractor = Typing::try_from(tpl.get_text(2)
.ok_or_else(|| CozoError::BadDataFormat(tpl.data.as_ref().to_vec()))?.as_ref())?;
let val_extractor = Typing::try_from(tpl.get_text(2)
.ok_or_else(|| CozoError::BadDataFormat(tpl.data.as_ref().to_vec()))?.as_ref())?;
println!("Found node {:?}, {:?}", key_extractor, val_extractor);
}
DataKind::Edge => {
println!("Found edge {:?}", tpl);
let other_key_extractor = Typing::try_from(tpl.get_text(6)
.ok_or_else(|| CozoError::BadDataFormat(tpl.data.as_ref().to_vec()))?.as_ref())?;
let val_extractor = Typing::try_from(tpl.get_text(7)
.ok_or_else(|| CozoError::BadDataFormat(tpl.data.as_ref().to_vec()))?.as_ref())?;
println!("Found edge {:?}, {:?}", other_key_extractor, val_extractor);
}
_ => return Err(LogicError("Cannot insert into non-tables".to_string()))
}
let related = self.sess.resolve_related_tables(tbl_name)?;
let related = self.sess.resolve_related_tables(&tbl_name)?;
for t in related {
println!("Found assoc {:?}", t);
}
@ -96,6 +107,18 @@ impl<'a, 'b, 't> MutationManager<'a, 'b, 't> {
}
Ok(())
}
fn add(&mut self, val_map: BTreeMap<Cow<str>, Value>) -> Result<()> {
let tbl_name = match val_map.get("_type") {
Some(Value::Text(t)) => t.clone(),
Some(_) => return Err(LogicError("Table kind must be text".to_string())),
None => match &self.default_tbl {
Some(v) => v.clone().into(),
None => return Err(LogicError("Cannot determine table kind".to_string()))
}
};
self.get_table_info(tbl_name);
Ok(())
}
}
#[cfg(test)]
@ -148,7 +171,8 @@ mod tests {
let s = r#"
insert [
{id: 1, name: "Jack"},
{id: 2, name: "Joe", habits: ["Balls"]}
{id: 2, name: "Joe", habits: ["Balls"], _type: "Person"},
{_type: "Friend", _src: 1, _dst: 2, relation: "mate"}
] as Person;
"#;
let p = Parser::parse(Rule::file, s).unwrap().next().unwrap();

@ -4,7 +4,7 @@ use thiserror::Error;
use cozorocks::BridgeError;
use crate::parser::Rule;
use crate::relation::data::DataKind;
use crate::relation::value::{StaticValue, Value};
use crate::relation::value::{StaticValue};
#[derive(Error, Debug)]
pub enum CozoError {

@ -138,8 +138,8 @@ typing = _{ simple_type | nullable_type | homogeneous_list_type | unnamed_tuple_
simple_type = { ident }
nullable_type = { "?" ~ (simple_type | homogeneous_list_type | unnamed_tuple_type | named_tuple_type) }
homogeneous_list_type = { "[" ~ typing ~ "]"}
unnamed_tuple_type = { "(" ~ typing ~ ("," ~ typing)* ~ ")" }
named_tuple_type = { "{" ~ named_type_pair ~ ("," ~ named_type_pair)* ~ "}" }
unnamed_tuple_type = { "(" ~ (typing ~ ",")* ~ typing? ~ ")" }
named_tuple_type = { "{" ~ (named_type_pair ~ ",")* ~ named_type_pair? ~ "}" }
named_type_pair = { (name_in_def | string) ~ ":" ~ typing }

@ -46,7 +46,9 @@ impl Display for Typing {
let collected = n.iter().map(|(k, v)|
format!(r##""{}":{}"##, k, v)).collect::<Vec<_>>();
let joined = collected.join(",");
write!(f, "({})", joined)
write!(f, "{{")?;
write!(f, "{}", joined)?;
write!(f, "}}")
}
}
}

Loading…
Cancel
Save