|
|
|
@ -1,5 +1,6 @@
|
|
|
|
|
use std::collections::BTreeMap;
|
|
|
|
|
use crate::env::{Env, LayeredEnv};
|
|
|
|
|
use std::fmt::{Debug, Display, Formatter, Write};
|
|
|
|
|
use crate::env::{Env};
|
|
|
|
|
use crate::value::Value;
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Eq, PartialEq, Clone)]
|
|
|
|
@ -37,175 +38,12 @@ pub enum BaseType {
|
|
|
|
|
Crs,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub struct StructuredEnvItem {
|
|
|
|
|
map: BTreeMap<String, Structured>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pub struct StructuredEnv {
|
|
|
|
|
stack: Vec<StructuredEnvItem>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
impl StructuredEnv {
|
|
|
|
|
pub fn new() -> Self {
|
|
|
|
|
let mut root = StructuredEnvItem { map: BTreeMap::new() };
|
|
|
|
|
define_base_types(&mut root);
|
|
|
|
|
Self { stack: vec![root] }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn root(&self) -> &StructuredEnvItem {
|
|
|
|
|
&self.stack[0]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn root_mut(&mut self) -> &mut StructuredEnvItem {
|
|
|
|
|
&mut self.stack[0]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn cur(&self) -> &StructuredEnvItem {
|
|
|
|
|
self.stack.last().unwrap()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn cur_mut(&mut self) -> &mut StructuredEnvItem {
|
|
|
|
|
self.stack.last_mut().unwrap()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn push(&mut self) {
|
|
|
|
|
self.stack.push(StructuredEnvItem { map: BTreeMap::new() })
|
|
|
|
|
}
|
|
|
|
|
pub fn pop(&mut self) -> bool {
|
|
|
|
|
if self.stack.len() <= 1 {
|
|
|
|
|
false
|
|
|
|
|
} else {
|
|
|
|
|
self.stack.pop();
|
|
|
|
|
true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn get_next_table_id(&self, local: bool) -> TableId {
|
|
|
|
|
let mut id = 0;
|
|
|
|
|
let persistence = if local { Persistence::Local } else { Persistence::Global };
|
|
|
|
|
for env in &self.stack {
|
|
|
|
|
for item in env.map.values() {
|
|
|
|
|
if let Some(TableId(p, eid)) = item.storage_id() {
|
|
|
|
|
if p == persistence {
|
|
|
|
|
id = id.max(eid);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
TableId(persistence, id + 1)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl LayeredEnv<Structured> for StructuredEnv {
|
|
|
|
|
fn root_define(&mut self, name: String, value: Structured) -> Option<Structured> {
|
|
|
|
|
self.root_mut().define(name, value)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn root_define_new(&mut self, name: String, value: Structured) -> bool {
|
|
|
|
|
self.root_mut().define_new(name, value)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn root_resolve(&self, name: &str) -> Option<&Structured> {
|
|
|
|
|
self.root().resolve(name)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn root_resolve_mut(&mut self, name: &str) -> Option<&mut Structured> {
|
|
|
|
|
self.root_mut().resolve_mut(name)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn root_undef(&mut self, name: &str) -> Option<Structured> {
|
|
|
|
|
self.root_mut().undef(name)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Env<Structured> for StructuredEnv {
|
|
|
|
|
fn define(&mut self, name: String, value: Structured) -> Option<Structured> {
|
|
|
|
|
self.stack.last_mut().unwrap().define(name, value)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn define_new(&mut self, name: String, value: Structured) -> bool {
|
|
|
|
|
self.stack.last_mut().unwrap().define_new(name, value)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn resolve(&self, name: &str) -> Option<&Structured> {
|
|
|
|
|
let mut res = None;
|
|
|
|
|
for item in self.stack.iter().rev() {
|
|
|
|
|
res = item.resolve(name);
|
|
|
|
|
if res.is_some() {
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
res
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn resolve_mut(&mut self, name: &str) -> Option<&mut Structured> {
|
|
|
|
|
let mut res = None;
|
|
|
|
|
for item in self.stack.iter_mut().rev() {
|
|
|
|
|
res = item.resolve_mut(name);
|
|
|
|
|
if res.is_some() {
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
res
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn undef(&mut self, name: &str) -> Option<Structured> {
|
|
|
|
|
let mut res = None;
|
|
|
|
|
for item in self.stack.iter_mut().rev() {
|
|
|
|
|
res = item.undef(name);
|
|
|
|
|
if res.is_some() {
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
res
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Env<Structured> for StructuredEnvItem {
|
|
|
|
|
fn define(&mut self, name: String, value: Structured) -> Option<Structured> {
|
|
|
|
|
let old = self.map.remove(&name);
|
|
|
|
|
self.map.insert(name, value);
|
|
|
|
|
old
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn define_new(&mut self, name: String, value: Structured) -> bool {
|
|
|
|
|
if let std::collections::btree_map::Entry::Vacant(e) = self.map.entry(name) {
|
|
|
|
|
e.insert(value);
|
|
|
|
|
true
|
|
|
|
|
} else {
|
|
|
|
|
false
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn resolve(&self, name: &str) -> Option<&Structured> {
|
|
|
|
|
self.map.get(name)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn resolve_mut(&mut self, name: &str) -> Option<&mut Structured> {
|
|
|
|
|
self.map.get_mut(name)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn undef(&mut self, name: &str) -> Option<Structured> {
|
|
|
|
|
self.map.remove(name)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
impl Default for StructuredEnv {
|
|
|
|
|
fn default() -> Self {
|
|
|
|
|
StructuredEnv::new()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, PartialEq, Clone)]
|
|
|
|
|
pub struct Col {
|
|
|
|
|
pub name: String,
|
|
|
|
|
pub typ: Typing,
|
|
|
|
|
pub default: Option<Value<'static>>,
|
|
|
|
|
pub default: Value<'static>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, PartialEq, Eq, Ord, PartialOrd, Clone, Copy)]
|
|
|
|
@ -229,6 +67,7 @@ pub struct ColumnId(TableId, usize);
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, PartialEq, Clone)]
|
|
|
|
|
pub struct Node {
|
|
|
|
|
pub status: StorageStatus,
|
|
|
|
|
pub id: TableId,
|
|
|
|
|
pub keys: Vec<Col>,
|
|
|
|
|
pub cols: Vec<Col>,
|
|
|
|
@ -239,6 +78,7 @@ pub struct Node {
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, PartialEq, Clone)]
|
|
|
|
|
pub struct Edge {
|
|
|
|
|
pub status: StorageStatus,
|
|
|
|
|
pub src: TableId,
|
|
|
|
|
pub dst: TableId,
|
|
|
|
|
pub id: TableId,
|
|
|
|
@ -248,6 +88,7 @@ pub struct Edge {
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, PartialEq, Clone)]
|
|
|
|
|
pub struct Columns {
|
|
|
|
|
pub status: StorageStatus,
|
|
|
|
|
pub attached: TableId,
|
|
|
|
|
pub id: TableId,
|
|
|
|
|
pub cols: Vec<Col>,
|
|
|
|
@ -255,13 +96,14 @@ pub struct Columns {
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, PartialEq, Clone)]
|
|
|
|
|
pub struct Index {
|
|
|
|
|
pub status: StorageStatus,
|
|
|
|
|
pub id: TableId,
|
|
|
|
|
pub attached: TableId,
|
|
|
|
|
pub cols: Vec<String>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Eq, PartialEq, Clone)]
|
|
|
|
|
#[derive(Eq, PartialEq, Clone)]
|
|
|
|
|
pub enum Typing {
|
|
|
|
|
Any,
|
|
|
|
|
Base(BaseType),
|
|
|
|
@ -271,23 +113,84 @@ pub enum Typing {
|
|
|
|
|
NamedTuple(BTreeMap<String, Typing>),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Display for Typing {
|
|
|
|
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
|
|
|
|
match self {
|
|
|
|
|
Typing::Any => f.write_str("Any")?,
|
|
|
|
|
Typing::Base(b) => {
|
|
|
|
|
match b {
|
|
|
|
|
BaseType::Bool => f.write_str("Bool")?,
|
|
|
|
|
BaseType::Int => f.write_str("Int")?,
|
|
|
|
|
BaseType::UInt => f.write_str("UInt")?,
|
|
|
|
|
BaseType::Float => f.write_str("Float")?,
|
|
|
|
|
BaseType::String => f.write_str("String")?,
|
|
|
|
|
BaseType::BitArr => f.write_str("BitArr")?,
|
|
|
|
|
BaseType::U8Arr => f.write_str("U8Arr")?,
|
|
|
|
|
BaseType::I8Arr => f.write_str("I8Arr")?,
|
|
|
|
|
BaseType::I16Arr => f.write_str("I16Arr")?,
|
|
|
|
|
BaseType::U16Arr => f.write_str("U16Arr")?,
|
|
|
|
|
BaseType::I32Arr => f.write_str("I32Arr")?,
|
|
|
|
|
BaseType::U32Arr => f.write_str("U32Arr")?,
|
|
|
|
|
BaseType::I64Arr => f.write_str("I64Arr")?,
|
|
|
|
|
BaseType::U64Arr => f.write_str("U64Arr")?,
|
|
|
|
|
BaseType::F16Arr => f.write_str("F16Arr")?,
|
|
|
|
|
BaseType::F32Arr => f.write_str("F32Arr")?,
|
|
|
|
|
BaseType::F64Arr => f.write_str("F64Arr")?,
|
|
|
|
|
BaseType::C32Arr => f.write_str("C32Arr")?,
|
|
|
|
|
BaseType::C64Arr => f.write_str("C64Arr")?,
|
|
|
|
|
BaseType::C128Arr => f.write_str("C128Arr")?,
|
|
|
|
|
BaseType::Uuid => f.write_str("Uuid")?,
|
|
|
|
|
BaseType::Timestamp => f.write_str("Timestamp")?,
|
|
|
|
|
BaseType::Datetime => f.write_str("Datetime")?,
|
|
|
|
|
BaseType::Timezone => f.write_str("Timezone")?,
|
|
|
|
|
BaseType::Date => f.write_str("Date")?,
|
|
|
|
|
BaseType::Time => f.write_str("Time")?,
|
|
|
|
|
BaseType::Duration => f.write_str("Duration")?,
|
|
|
|
|
BaseType::BigInt => f.write_str("BigInt")?,
|
|
|
|
|
BaseType::BigDecimal => f.write_str("BigDecimal")?,
|
|
|
|
|
BaseType::Inet => f.write_str("Inet")?,
|
|
|
|
|
BaseType::Crs => f.write_str("Crs")?
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
Typing::HList(l) => {
|
|
|
|
|
f.write_char('[')?;
|
|
|
|
|
Display::fmt(l, f)?;
|
|
|
|
|
f.write_char(']')?;
|
|
|
|
|
}
|
|
|
|
|
Typing::Nullable(d) => {
|
|
|
|
|
f.write_char('?')?;
|
|
|
|
|
Display::fmt(d, f)?;
|
|
|
|
|
}
|
|
|
|
|
Typing::Tuple(_) => todo!(),
|
|
|
|
|
Typing::NamedTuple(_) => todo!()
|
|
|
|
|
}
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Debug for Typing {
|
|
|
|
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
|
|
|
|
Display::fmt(self, f)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, PartialEq, Clone)]
|
|
|
|
|
pub enum Structured {
|
|
|
|
|
Typing(Typing),
|
|
|
|
|
Node(Node, StorageStatus),
|
|
|
|
|
Edge(Edge, StorageStatus),
|
|
|
|
|
Columns(Columns, StorageStatus),
|
|
|
|
|
Index(Index, StorageStatus),
|
|
|
|
|
Node(Node),
|
|
|
|
|
Edge(Edge),
|
|
|
|
|
Columns(Columns),
|
|
|
|
|
Index(Index),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Structured {
|
|
|
|
|
fn storage_id(&self) -> Option<TableId> {
|
|
|
|
|
pub fn storage_id(&self) -> Option<TableId> {
|
|
|
|
|
match self {
|
|
|
|
|
Structured::Typing(_) => None,
|
|
|
|
|
Structured::Node(n, _) => Some(n.id),
|
|
|
|
|
Structured::Edge(e, _) => Some(e.id),
|
|
|
|
|
Structured::Columns(c, _) => Some(c.id),
|
|
|
|
|
Structured::Index(i, _) => Some(i.id)
|
|
|
|
|
Structured::Node(n) => Some(n.id),
|
|
|
|
|
Structured::Edge(e) => Some(e.id),
|
|
|
|
|
Structured::Columns(c) => Some(c.id),
|
|
|
|
|
Structured::Index(i) => Some(i.id)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|