cassandra_proto/query/
batch_query_builder.rs

1use super::{QueryFlags, QueryValues};
2use crate::consistency::Consistency;
3use crate::error::{Error as CError, Result as CResult};
4use crate::frame::frame_batch::{BatchQuery, BatchQuerySubj, BatchType, BodyReqBatch};
5use crate::types::{CBytesShort, CStringLong};
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<i64>,
16}
17
18impl BatchQueryBuilder {
19  pub fn new() -> BatchQueryBuilder {
20    BatchQueryBuilder {
21      batch_type: BatchType::Logged,
22      queries: vec![],
23      consistency: Consistency::One,
24      serial_consistency: None,
25      timestamp: None,
26    }
27  }
28
29  pub fn batch_type(mut self, batch_type: BatchType) -> Self {
30    self.batch_type = batch_type;
31    self
32  }
33
34  /// Add a query (non-prepared one)
35  pub fn add_query<T: Into<String>>(mut self, query: T, values: QueryValues) -> Self {
36    self.queries.push(BatchQuery {
37      is_prepared: false,
38      subject: BatchQuerySubj::QueryString(CStringLong::new(query.into())),
39      values,
40    });
41    self
42  }
43
44  /// Add a query (prepared one)
45  pub fn add_query_prepared(mut self, query_id: CBytesShort, values: QueryValues) -> Self {
46    self.queries.push(BatchQuery {
47      is_prepared: true,
48      subject: BatchQuerySubj::PreparedId(query_id),
49      values,
50    });
51    self
52  }
53
54  pub fn clear_queries(mut self) -> Self {
55    self.queries = vec![];
56    self
57  }
58
59  pub fn consistency(mut self, consistency: Consistency) -> Self {
60    self.consistency = consistency;
61    self
62  }
63
64  pub fn serial_consistency(mut self, serial_consistency: Option<Consistency>) -> Self {
65    self.serial_consistency = serial_consistency;
66    self
67  }
68
69  pub fn timestamp(mut self, timestamp: Option<i64>) -> Self {
70    self.timestamp = timestamp;
71    self
72  }
73
74  pub fn finalize(self) -> CResult<BodyReqBatch> {
75    let mut flags = vec![];
76
77    if self.serial_consistency.is_some() {
78      flags.push(QueryFlags::WithSerialConsistency);
79    }
80
81    if self.timestamp.is_some() {
82      flags.push(QueryFlags::WithDefaultTimestamp);
83    }
84
85    let with_names_for_values = self.queries.iter().all(|q| q.values.with_names());
86
87    if !with_names_for_values {
88      let some_names_for_values = self.queries.iter().any(|q| q.values.with_names());
89
90      if some_names_for_values {
91        return Err(CError::General(String::from(
92          "Inconsistent query values - mixed \
93           with and without names values",
94        )));
95      }
96    }
97
98    if with_names_for_values {
99      flags.push(QueryFlags::WithNamesForValues);
100    }
101
102    Ok(BodyReqBatch {
103      batch_type: self.batch_type,
104      queries: self.queries,
105      query_flags: flags,
106      consistency: self.consistency,
107      serial_consistency: self.serial_consistency,
108      timestamp: self.timestamp,
109    })
110  }
111}