Ensure undefined fields are removed in schemafull mode
This commit is contained in:
parent
59d7e733eb
commit
6c5ddbf70f
7 changed files with 69 additions and 0 deletions
45
lib/src/doc/clean.rs
Normal file
45
lib/src/doc/clean.rs
Normal file
|
@ -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<Idiom> = 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(())
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -6,6 +6,7 @@ mod compute;
|
|||
mod allow;
|
||||
mod alter;
|
||||
mod check;
|
||||
mod clean;
|
||||
mod create;
|
||||
mod delete;
|
||||
mod document;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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::<Vec<_>>()
|
||||
.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)
|
||||
|
|
Loading…
Reference in a new issue