cql3_parser/
update.rs

1use crate::begin_batch::BeginBatch;
2use crate::common::{FQName, Operand, RelationElement, TtlTimestamp};
3use crate::delete::IndexedColumn;
4use itertools::Itertools;
5use std::fmt::{Display, Formatter};
6
7/// data for `Update` statements
8#[derive(PartialEq, Debug, Clone)]
9pub struct Update {
10    /// if present then statement starts with BEGIN BATCH
11    pub begin_batch: Option<BeginBatch>,
12    /// the table name to update
13    pub table_name: FQName,
14    /// if present then the TTL Timestamp for the update
15    pub using_ttl: Option<TtlTimestamp>,
16    /// the column assignments for the update.
17    pub assignments: Vec<AssignmentElement>,
18    /// the where clause
19    pub where_clause: Vec<RelationElement>,
20    /// if present a list of key,values for the `IF` clause
21    pub if_clause: Vec<RelationElement>,
22    /// if true and `if_clause` is NONE then  `IF EXISTS` is added to the statement
23    pub if_exists: bool,
24}
25
26impl Display for Update {
27    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
28        write!(
29            f,
30            "{}UPDATE {}{} SET {} WHERE {}{}",
31            self.begin_batch
32                .as_ref()
33                .map_or("".to_string(), |x| x.to_string()),
34            self.table_name,
35            self.using_ttl
36                .as_ref()
37                .map_or("".to_string(), |x| x.to_string()),
38            self.assignments.iter().map(|a| a.to_string()).join(", "),
39            self.where_clause.iter().join(" AND "),
40            if !self.if_clause.is_empty() {
41                format!(" IF {}", self.if_clause.iter().join(" AND "))
42            } else if self.if_exists {
43                " IF EXISTS".to_string()
44            } else {
45                "".to_string()
46            }
47        )
48    }
49}
50
51/// defines an assignment element comprising the column, the value, and an optional +/- value operator.
52#[derive(PartialEq, Debug, Clone)]
53pub struct AssignmentElement {
54    /// the column to set the value for.
55    pub name: IndexedColumn,
56    /// the column value
57    pub value: Operand,
58    /// an optional +/- value
59    pub operator: Option<AssignmentOperator>,
60}
61
62impl Display for AssignmentElement {
63    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
64        match &self.operator {
65            Some(x) => write!(f, "{} = {}{}", self.name, self.value, x),
66            None => write!(f, "{} = {}", self.name, self.value),
67        }
68    }
69}
70
71/// Defines the optional +/- value for an assignment
72#[derive(PartialEq, Debug, Clone)]
73pub enum AssignmentOperator {
74    Plus(Operand),
75    Minus(Operand),
76}
77
78impl Display for AssignmentOperator {
79    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
80        match self {
81            AssignmentOperator::Plus(op) => write!(f, " + {}", op),
82            AssignmentOperator::Minus(op) => write!(f, " - {}", op),
83        }
84    }
85}