diff --git a/lib/src/doc/clean.rs b/lib/src/doc/clean.rs new file mode 100644 index 00000000..938d0033 --- /dev/null +++ b/lib/src/doc/clean.rs @@ -0,0 +1,45 @@ +use crate::ctx::Context; +use crate::dbs::Options; +use crate::dbs::Statement; +use crate::dbs::Transaction; +use crate::doc::Document; +use crate::err::Error; +use crate::sql::idiom::Idiom; + +impl<'a> Document<'a> { + pub async fn clean( + &mut self, + ctx: &Context<'_>, + opt: &Options, + txn: &Transaction, + _stm: &Statement<'_>, + ) -> Result<(), Error> { + // Get the table + let tb = self.tb(opt, txn).await?; + // This table is schemafull + if tb.full { + // Create a vector to store the keys + let mut keys: Vec = vec![]; + // Loop through all field statements + for fd in self.fd(opt, txn).await?.iter() { + // Loop over this field in the document + for k in self.current.each(&fd.name).into_iter() { + keys.push(k); + } + // Loop over every field in the document + for k in self.current.every().iter() { + if !keys.contains(k) { + match k { + k if k.is_id() => continue, + k if k.is_in() => continue, + k if k.is_out() => continue, + k => self.current.to_mut().del(ctx, opt, txn, k).await?, + } + } + } + } + } + // Carry on + Ok(()) + } +} diff --git a/lib/src/doc/create.rs b/lib/src/doc/create.rs index 8733d416..2e90f5de 100644 --- a/lib/src/doc/create.rs +++ b/lib/src/doc/create.rs @@ -20,6 +20,8 @@ impl<'a> Document<'a> { self.alter(ctx, opt, txn, stm).await?; // Merge fields data self.field(ctx, opt, txn, stm).await?; + // Clean fields data + self.clean(ctx, opt, txn, stm).await?; // Check if allowed self.allow(ctx, opt, txn, stm).await?; // Store index data diff --git a/lib/src/doc/insert.rs b/lib/src/doc/insert.rs index 3fc8a6ee..8c164d1b 100644 --- a/lib/src/doc/insert.rs +++ b/lib/src/doc/insert.rs @@ -24,6 +24,8 @@ impl<'a> Document<'a> { self.merge(ctx, opt, txn, stm).await?; // Merge fields data self.field(ctx, opt, txn, stm).await?; + // Clean fields data + self.clean(ctx, opt, txn, stm).await?; // Check if allowed self.allow(ctx, opt, txn, stm).await?; // Store index data @@ -47,6 +49,8 @@ impl<'a> Document<'a> { self.alter(ctx, opt, txn, stm).await?; // Merge fields data self.field(ctx, opt, txn, stm).await?; + // Clean fields data + self.clean(ctx, opt, txn, stm).await?; // Check if allowed self.allow(ctx, opt, txn, stm).await?; // Store index data diff --git a/lib/src/doc/mod.rs b/lib/src/doc/mod.rs index 41eeda18..242945e3 100644 --- a/lib/src/doc/mod.rs +++ b/lib/src/doc/mod.rs @@ -6,6 +6,7 @@ mod compute; mod allow; mod alter; mod check; +mod clean; mod create; mod delete; mod document; diff --git a/lib/src/doc/relate.rs b/lib/src/doc/relate.rs index b481713a..6f36e665 100644 --- a/lib/src/doc/relate.rs +++ b/lib/src/doc/relate.rs @@ -20,6 +20,8 @@ impl<'a> Document<'a> { self.alter(ctx, opt, txn, stm).await?; // Merge fields data self.field(ctx, opt, txn, stm).await?; + // Clean fields data + self.clean(ctx, opt, txn, stm).await?; // Check if allowed self.allow(ctx, opt, txn, stm).await?; // Store record edges diff --git a/lib/src/doc/update.rs b/lib/src/doc/update.rs index c537bbdc..553392e2 100644 --- a/lib/src/doc/update.rs +++ b/lib/src/doc/update.rs @@ -22,6 +22,8 @@ impl<'a> Document<'a> { self.alter(ctx, opt, txn, stm).await?; // Merge fields data self.field(ctx, opt, txn, stm).await?; + // Clean fields data + self.clean(ctx, opt, txn, stm).await?; // Check if allowed self.allow(ctx, opt, txn, stm).await?; // Store index data diff --git a/lib/src/sql/idiom.rs b/lib/src/sql/idiom.rs index 39b680a1..ee39c3fe 100644 --- a/lib/src/sql/idiom.rs +++ b/lib/src/sql/idiom.rs @@ -6,6 +6,7 @@ use crate::sql::common::commas; use crate::sql::error::IResult; use crate::sql::part::Next; use crate::sql::part::{all, field, first, graph, index, last, part, thing, Part}; +use crate::sql::paths::{ID, IN, OUT}; use crate::sql::value::Value; use nom::branch::alt; use nom::multi::separated_list1; @@ -77,6 +78,18 @@ impl Idiom { .collect::>() .into() } + // Check if this expression an 'id' field + pub(crate) fn is_id(&self) -> bool { + self.0.len() == 1 && self.0[0].eq(&ID[0]) + } + // Check if this expression an 'in' field + pub(crate) fn is_in(&self) -> bool { + self.0.len() == 1 && self.0[0].eq(&IN[0]) + } + // Check if this expression an 'out' field + pub(crate) fn is_out(&self) -> bool { + self.0.len() == 1 && self.0[0].eq(&OUT[0]) + } // Check if this is an expression with multiple yields pub(crate) fn is_multi_yield(&self) -> bool { self.iter().any(Self::split_multi_yield)