Feature: Add unset clause for update statement (#2004)
This commit is contained in:
parent
3a2d8c22e3
commit
11543f7d67
3 changed files with 87 additions and 1 deletions
|
@ -63,6 +63,11 @@ impl<'a> Document<'a> {
|
|||
}
|
||||
}
|
||||
}
|
||||
Data::UnsetExpression(i) => {
|
||||
for i in i.iter() {
|
||||
self.current.to_mut().del(ctx, opt, txn, &i).await?
|
||||
}
|
||||
}
|
||||
Data::UpdateExpression(x) => {
|
||||
// Duplicate context
|
||||
let mut ctx = Context::new(ctx);
|
||||
|
|
|
@ -22,6 +22,7 @@ use std::fmt::{self, Display, Formatter};
|
|||
pub enum Data {
|
||||
EmptyExpression,
|
||||
SetExpression(Vec<(Idiom, Operator, Value)>),
|
||||
UnsetExpression(Vec<Idiom>),
|
||||
PatchExpression(Value),
|
||||
MergeExpression(Value),
|
||||
ReplaceExpression(Value),
|
||||
|
@ -84,6 +85,11 @@ impl Display for Data {
|
|||
v.iter().map(|args| Fmt::new(args, |(l, o, r), f| write!(f, "{l} {o} {r}",)))
|
||||
)
|
||||
),
|
||||
Self::UnsetExpression(v) => write!(
|
||||
f,
|
||||
"UNSET {}",
|
||||
Fmt::comma_separated(v.iter().map(|args| Fmt::new(args, |l, f| write!(f, "{l}",))))
|
||||
),
|
||||
Self::PatchExpression(v) => write!(f, "PATCH {v}"),
|
||||
Self::MergeExpression(v) => write!(f, "MERGE {v}"),
|
||||
Self::ReplaceExpression(v) => write!(f, "REPLACE {v}"),
|
||||
|
@ -111,7 +117,7 @@ impl Display for Data {
|
|||
}
|
||||
|
||||
pub fn data(i: &str) -> IResult<&str, Data> {
|
||||
alt((set, patch, merge, replace, content))(i)
|
||||
alt((set, unset, patch, merge, replace, content))(i)
|
||||
}
|
||||
|
||||
fn set(i: &str) -> IResult<&str, Data> {
|
||||
|
@ -128,6 +134,13 @@ fn set(i: &str) -> IResult<&str, Data> {
|
|||
Ok((i, Data::SetExpression(v)))
|
||||
}
|
||||
|
||||
fn unset(i: &str) -> IResult<&str, Data> {
|
||||
let (i, _) = tag_no_case("UNSET")(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
let (i, v) = separated_list1(commas, idiom)(i)?;
|
||||
Ok((i, Data::UnsetExpression(v)))
|
||||
}
|
||||
|
||||
fn patch(i: &str) -> IResult<&str, Data> {
|
||||
let (i, _) = tag_no_case("PATCH")(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
|
@ -222,6 +235,24 @@ mod tests {
|
|||
assert_eq!("SET field = true, other.field = false", format!("{}", out));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unset_statement() {
|
||||
let sql = "UNSET field";
|
||||
let res = data(sql);
|
||||
assert!(res.is_ok());
|
||||
let out = res.unwrap().1;
|
||||
assert_eq!("UNSET field", format!("{}", out));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unset_statement_multiple_fields() {
|
||||
let sql = "UNSET field, other.field";
|
||||
let res = data(sql);
|
||||
assert!(res.is_ok());
|
||||
let out = res.unwrap().1;
|
||||
assert_eq!("UNSET field, other.field", format!("{}", out));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn patch_statement() {
|
||||
let sql = "PATCH [{ field: true }]";
|
||||
|
|
|
@ -55,6 +55,9 @@ impl ser::Serializer for Serializer {
|
|||
"SetExpression" => {
|
||||
Ok(Data::SetExpression(value.serialize(IdiomOperatorValueVecSerializer.wrap())?))
|
||||
}
|
||||
"UnsetExpression" => {
|
||||
Ok(Data::UnsetExpression(value.serialize(IdiomVecSerializer.wrap())?))
|
||||
}
|
||||
"PatchExpression" => {
|
||||
Ok(Data::PatchExpression(value.serialize(ser::value::Serializer.wrap())?))
|
||||
}
|
||||
|
@ -83,6 +86,46 @@ impl ser::Serializer for Serializer {
|
|||
}
|
||||
}
|
||||
|
||||
struct IdiomVecSerializer;
|
||||
|
||||
impl ser::Serializer for IdiomVecSerializer {
|
||||
type Ok = Vec<Idiom>;
|
||||
type Error = Error;
|
||||
|
||||
type SerializeSeq = SerializeIdiomVec;
|
||||
type SerializeTuple = Impossible<Vec<Idiom>, Error>;
|
||||
type SerializeTupleStruct = Impossible<Vec<Idiom>, Error>;
|
||||
type SerializeTupleVariant = Impossible<Vec<Idiom>, Error>;
|
||||
type SerializeMap = Impossible<Vec<Idiom>, Error>;
|
||||
type SerializeStruct = Impossible<Vec<Idiom>, Error>;
|
||||
type SerializeStructVariant = Impossible<Vec<Idiom>, Error>;
|
||||
|
||||
const EXPECTED: &'static str = "an `Vec<Idiom>`";
|
||||
|
||||
fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Error> {
|
||||
Ok(SerializeIdiomVec(Vec::with_capacity(len.unwrap_or_default())))
|
||||
}
|
||||
}
|
||||
|
||||
struct SerializeIdiomVec(Vec<Idiom>);
|
||||
|
||||
impl serde::ser::SerializeSeq for SerializeIdiomVec {
|
||||
type Ok = Vec<Idiom>;
|
||||
type Error = Error;
|
||||
|
||||
fn serialize_element<T>(&mut self, value: &T) -> Result<(), Self::Error>
|
||||
where
|
||||
T: Serialize + ?Sized,
|
||||
{
|
||||
self.0.push(Idiom(value.serialize(ser::part::vec::Serializer.wrap())?));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn end(self) -> Result<Self::Ok, Self::Error> {
|
||||
Ok(self.0)
|
||||
}
|
||||
}
|
||||
|
||||
type IdiomOperatorValueTuple = (Idiom, Operator, Value);
|
||||
|
||||
struct IdiomOperatorValueVecSerializer;
|
||||
|
@ -352,6 +395,13 @@ mod tests {
|
|||
assert_eq!(data, serialized);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unset_expression() {
|
||||
let data = Data::UnsetExpression(vec![Default::default()]);
|
||||
let serialized = data.serialize(Serializer.wrap()).unwrap();
|
||||
assert_eq!(data, serialized);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn patch_expression() {
|
||||
let data = Data::PatchExpression(Default::default());
|
||||
|
|
Loading…
Reference in a new issue