cassandra_protocol/query/
batch_query_builder.rs

1use crate::consistency::Consistency;
2use crate::error::{Error as CError, Result as CResult};
3use crate::frame::message_batch::{BatchQuery, BatchQuerySubj, BatchType, BodyReqBatch};
4use crate::query::{PreparedQuery, QueryValues};
5use crate::types::{CInt, CLong};
6
7pub type QueryBatch = BodyReqBatch;
8
9#[derive(Debug)]
10pub struct BatchQueryBuilder {
11    batch_type: BatchType,
12    queries: Vec<BatchQuery>,
13    consistency: Consistency,
14    serial_consistency: Option<Consistency>,
15    timestamp: Option<CLong>,
16    keyspace: Option<String>,
17    now_in_seconds: Option<CInt>,
18}
19
20impl Default for BatchQueryBuilder {
21    fn default() -> Self {
22        BatchQueryBuilder {
23            batch_type: BatchType::Logged,
24            queries: vec![],
25            consistency: Consistency::One,
26            serial_consistency: None,
27            timestamp: None,
28            keyspace: None,
29            now_in_seconds: None,
30        }
31    }
32}
33
34impl BatchQueryBuilder {
35    pub fn new() -> BatchQueryBuilder {
36        Default::default()
37    }
38
39    #[must_use]
40    pub fn with_batch_type(mut self, batch_type: BatchType) -> Self {
41        self.batch_type = batch_type;
42        self
43    }
44
45    /// Add a query (non-prepared one)
46    #[must_use]
47    pub fn add_query<T: Into<String>>(mut self, query: T, values: QueryValues) -> Self {
48        self.queries.push(BatchQuery {
49            subject: BatchQuerySubj::QueryString(query.into()),
50            values,
51        });
52        self
53    }
54
55    /// Add a query (prepared one)
56    #[must_use]
57    pub fn add_query_prepared(mut self, query: &PreparedQuery, values: QueryValues) -> Self {
58        self.queries.push(BatchQuery {
59            subject: BatchQuerySubj::PreparedId(query.id.clone()),
60            values,
61        });
62        self
63    }
64
65    #[must_use]
66    pub fn clear_queries(mut self) -> Self {
67        self.queries = vec![];
68        self
69    }
70
71    #[must_use]
72    pub fn with_consistency(mut self, consistency: Consistency) -> Self {
73        self.consistency = consistency;
74        self
75    }
76
77    #[must_use]
78    pub fn with_serial_consistency(mut self, serial_consistency: Consistency) -> Self {
79        self.serial_consistency = Some(serial_consistency);
80        self
81    }
82
83    #[must_use]
84    pub fn with_timestamp(mut self, timestamp: CLong) -> Self {
85        self.timestamp = Some(timestamp);
86        self
87    }
88
89    #[must_use]
90    pub fn with_keyspace(mut self, keyspace: String) -> Self {
91        self.keyspace = Some(keyspace);
92        self
93    }
94
95    #[must_use]
96    pub fn with_now_in_seconds(mut self, now_in_seconds: CInt) -> Self {
97        self.now_in_seconds = Some(now_in_seconds);
98        self
99    }
100
101    pub fn build(self) -> CResult<BodyReqBatch> {
102        let with_names_for_values = self.queries.iter().all(|q| q.values.has_names());
103
104        if !with_names_for_values {
105            let some_names_for_values = self.queries.iter().any(|q| q.values.has_names());
106
107            if some_names_for_values {
108                return Err(CError::General(String::from(
109                    "Inconsistent query values - mixed \
110                     with and without names values",
111                )));
112            }
113        }
114
115        Ok(BodyReqBatch {
116            batch_type: self.batch_type,
117            queries: self.queries,
118            consistency: self.consistency,
119            serial_consistency: self.serial_consistency,
120            timestamp: self.timestamp,
121            keyspace: self.keyspace,
122            now_in_seconds: self.now_in_seconds,
123        })
124    }
125}