use crate::ctx::{Context, MutableContext};
use crate::dbs::Options;
use crate::dbs::Statement;
use crate::dbs::Workable;
use crate::doc::Document;
use crate::doc::Permitted::*;
use crate::err::Error;
use crate::sql::data::Data;
use crate::sql::operator::Operator;
use crate::sql::paths::EDGE;
use crate::sql::paths::IN;
use crate::sql::paths::OUT;
use crate::sql::value::Value;
use reblessive::tree::Stk;
use std::sync::Arc;
impl Document {
pub(super) async fn generate_record_id(
&mut self,
stk: &mut Stk,
ctx: &Context,
opt: &Options,
stm: &Statement<'_>,
) -> Result<(), Error> {
if let Some(tb) = &self.gen {
if let Workable::Normal = &self.extras {
let id = match stm.data() {
Some(data) => match data.rid(stk, ctx, opt).await? {
Some(id) => id.generate(tb, false)?,
None => tb.generate(),
},
None => tb.generate(),
};
if id.is_range() {
return Err(Error::IdInvalid {
value: id.to_string(),
});
}
self.id = Some(Arc::new(id));
}
else if let Workable::Insert(_) = &self.extras {
}
else if let Workable::Relate(_, _, _) = &self.extras {
}
}
Ok(())
}
pub(super) async fn clear_record_data(
&mut self,
_ctx: &Context,
_opt: &Options,
_stm: &Statement<'_>,
) -> Result<(), Error> {
self.current.doc.to_mut().clear()
}
pub(super) async fn default_record_data(
&mut self,
_ctx: &Context,
_opt: &Options,
_stm: &Statement<'_>,
) -> Result<(), Error> {
let rid = self.id()?;
self.current.doc.to_mut().def(&rid);
if let Workable::Relate(l, r, _) = &self.extras {
self.current.doc.to_mut().put(&*EDGE, Value::Bool(true));
match (self.initial.doc.pick(&*IN), self.is_new()) {
(Value::Thing(id), false) if id.eq(l) => {
self.current.doc.to_mut().put(&*IN, l.clone().into());
}
(_, true) => {
self.current.doc.to_mut().put(&*IN, l.clone().into());
}
(v, _) => {
return Err(Error::InOverride {
value: v.to_string(),
})
}
}
match (self.initial.doc.pick(&*OUT), self.is_new()) {
(Value::Thing(id), false) if id.eq(r) => {
self.current.doc.to_mut().put(&*OUT, r.clone().into());
}
(_, true) => {
self.current.doc.to_mut().put(&*OUT, r.clone().into());
}
(v, _) => {
return Err(Error::OutOverride {
value: v.to_string(),
})
}
}
}
if self.initial.doc.pick(&*EDGE).is_true() {
self.current.doc.to_mut().put(&*EDGE, Value::Bool(true));
self.current.doc.to_mut().put(&*IN, self.initial.doc.pick(&*IN));
self.current.doc.to_mut().put(&*OUT, self.initial.doc.pick(&*OUT));
}
Ok(())
}
pub(super) async fn process_merge_data(
&mut self,
stk: &mut Stk,
ctx: &Context,
opt: &Options,
_stm: &Statement<'_>,
) -> Result<(), Error> {
let rid = self.id()?;
self.current.doc.to_mut().def(&rid);
match self.reduced(stk, ctx, opt, Current).await? {
true => {
if let Workable::Insert(v) = &self.extras {
let v = v.compute(stk, ctx, opt, Some(&self.current_reduced)).await?;
self.current.doc.to_mut().merge(v)?;
}
if let Workable::Relate(_, _, Some(v)) = &self.extras {
let v = v.compute(stk, ctx, opt, Some(&self.current_reduced)).await?;
self.current.doc.to_mut().merge(v)?;
}
}
false => {
if let Workable::Insert(v) = &self.extras {
let v = v.compute(stk, ctx, opt, Some(&self.current)).await?;
self.current.doc.to_mut().merge(v)?;
}
if let Workable::Relate(_, _, Some(v)) = &self.extras {
let v = v.compute(stk, ctx, opt, Some(&self.current)).await?;
self.current.doc.to_mut().merge(v)?;
}
}
};
self.current.doc.to_mut().def(&rid);
Ok(())
}
pub(super) async fn process_record_data(
&mut self,
stk: &mut Stk,
ctx: &Context,
opt: &Options,
stm: &Statement<'_>,
) -> Result<(), Error> {
let rid = self.id()?;
self.current.doc.to_mut().def(&rid);
if let Some(v) = stm.data() {
match v {
Data::PatchExpression(data) => {
let current = match self.reduced(stk, ctx, opt, Current).await? {
true => &self.current_reduced,
false => &self.current,
};
let data = data.compute(stk, ctx, opt, Some(current)).await?;
self.current.doc.to_mut().patch(data)?
}
Data::MergeExpression(data) => {
let current = match self.reduced(stk, ctx, opt, Current).await? {
true => &self.current_reduced,
false => &self.current,
};
let data = data.compute(stk, ctx, opt, Some(current)).await?;
self.current.doc.to_mut().merge(data)?
}
Data::ReplaceExpression(data) => {
let current = match self.reduced(stk, ctx, opt, Current).await? {
true => &self.current_reduced,
false => &self.current,
};
let data = data.compute(stk, ctx, opt, Some(current)).await?;
self.current.doc.to_mut().replace(data)?
}
Data::ContentExpression(data) => {
let current = match self.reduced(stk, ctx, opt, Current).await? {
true => &self.current_reduced,
false => &self.current,
};
let data = data.compute(stk, ctx, opt, Some(current)).await?;
self.current.doc.to_mut().replace(data)?
}
Data::UnsetExpression(i) => {
for i in i.iter() {
self.current.doc.to_mut().cut(i);
}
}
Data::SetExpression(x) => match self.reduced(stk, ctx, opt, Current).await? {
true => {
for x in x.iter() {
#[rustfmt::skip]
let v = x.2.compute(stk, ctx, opt, Some(&self.current_reduced)).await?;
match &x.1 {
#[rustfmt::skip]
Operator::Equal => match v {
Value::None => {
self.current_reduced.doc.to_mut().del(stk, ctx, opt, &x.0).await?;
self.current.doc.to_mut().del(stk, ctx, opt, &x.0).await?;
},
_ => {
self.current_reduced.doc.to_mut().set(stk, ctx, opt, &x.0, v.clone()).await?;
self.current.doc.to_mut().set(stk, ctx, opt, &x.0, v).await?;
},
},
#[rustfmt::skip]
Operator::Inc => {
self.current_reduced.doc.to_mut().increment(stk, ctx, opt, &x.0, v.clone()).await?;
self.current.doc.to_mut().increment(stk, ctx, opt, &x.0, v).await?;
}
#[rustfmt::skip]
Operator::Dec => {
self.current_reduced.doc.to_mut().decrement(stk, ctx, opt, &x.0, v.clone()).await?;
self.current.doc.to_mut().decrement(stk, ctx, opt, &x.0, v).await?;
}
#[rustfmt::skip]
Operator::Ext => {
self.current_reduced.doc.to_mut().extend(stk, ctx, opt, &x.0, v.clone()).await?;
self.current.doc.to_mut().extend(stk, ctx, opt, &x.0, v).await?;
}
#[rustfmt::skip]
o => { return Err(fail!("Unexpected operator in SET clause: {o:?}")); }
}
}
}
false => {
for x in x.iter() {
#[rustfmt::skip]
let v = x.2.compute(stk, ctx, opt, Some(&self.current)).await?;
match &x.1 {
#[rustfmt::skip]
Operator::Equal => match v {
Value::None => self.current.doc.to_mut().del(stk, ctx, opt, &x.0).await?,
_ => self.current.doc.to_mut().set(stk, ctx, opt, &x.0, v).await?,
},
#[rustfmt::skip]
Operator::Inc => self.current.doc.to_mut().increment(stk, ctx, opt, &x.0, v).await?,
#[rustfmt::skip]
Operator::Dec => self.current.doc.to_mut().decrement(stk, ctx, opt, &x.0, v).await?,
#[rustfmt::skip]
Operator::Ext => self.current.doc.to_mut().extend(stk, ctx, opt, &x.0, v).await?,
#[rustfmt::skip]
o => { return Err(fail!("Unexpected operator in SET clause: {o:?}")); }
}
}
}
},
Data::UpdateExpression(x) => {
let mut ctx = MutableContext::new(ctx);
if let Workable::Insert(value) = &self.extras {
ctx.add_value("input", value.clone());
}
if let Workable::Relate(_, _, Some(value)) = &self.extras {
ctx.add_value("input", value.clone());
}
let ctx = ctx.freeze();
match self.reduced(stk, &ctx, opt, Current).await? {
true => {
for x in x.iter() {
#[rustfmt::skip]
let v = x.2.compute(stk, &ctx, opt, Some(&self.current_reduced)).await?;
match &x.1 {
#[rustfmt::skip]
Operator::Equal => match v {
Value::None => {
self.current_reduced.doc.to_mut().del(stk, &ctx, opt, &x.0).await?;
self.current.doc.to_mut().del(stk, &ctx, opt, &x.0).await?;
},
_ => {
self.current_reduced.doc.to_mut().set(stk, &ctx, opt, &x.0, v.clone()).await?;
self.current.doc.to_mut().set(stk, &ctx, opt, &x.0, v).await?;
},
},
#[rustfmt::skip]
Operator::Inc => {
self.current_reduced.doc.to_mut().increment(stk, &ctx, opt, &x.0, v.clone()).await?;
self.current.doc.to_mut().increment(stk, &ctx, opt, &x.0, v).await?;
}
#[rustfmt::skip]
Operator::Dec => {
self.current_reduced.doc.to_mut().decrement(stk, &ctx, opt, &x.0, v.clone()).await?;
self.current.doc.to_mut().decrement(stk, &ctx, opt, &x.0, v).await?;
}
#[rustfmt::skip]
Operator::Ext => {
self.current_reduced.doc.to_mut().extend(stk, &ctx, opt, &x.0, v.clone()).await?;
self.current.doc.to_mut().extend(stk, &ctx, opt, &x.0, v).await?;
}
#[rustfmt::skip]
o => { return Err(fail!("Unexpected operator in UPDATE clause: {o:?}")); }
}
}
}
false => {
for x in x.iter() {
#[rustfmt::skip]
let v = x.2.compute(stk, &ctx, opt, Some(&self.current)).await?;
match &x.1 {
#[rustfmt::skip]
Operator::Equal => match v {
Value::None => self.current.doc.to_mut().del(stk, &ctx, opt, &x.0).await?,
_ => self.current.doc.to_mut().set(stk, &ctx, opt, &x.0, v).await?,
},
#[rustfmt::skip]
Operator::Inc => self.current.doc.to_mut().increment(stk, &ctx, opt, &x.0, v).await?,
#[rustfmt::skip]
Operator::Dec => self.current.doc.to_mut().decrement(stk, &ctx, opt, &x.0, v).await?,
#[rustfmt::skip]
Operator::Ext => self.current.doc.to_mut().extend(stk, &ctx, opt, &x.0, v).await?,
#[rustfmt::skip]
o => { return Err(fail!("Unexpected operator in UPDATE clause: {o:?}")); }
}
}
}
}
}
x => return Err(fail!("Unexpected data clause type: {x:?}")),
};
};
self.current.doc.to_mut().def(&rid);
Ok(())
}
}