discord_cassandra_cpp/cassandra/
statement.rs

1use crate::cassandra::batch::CustomPayload;
2use crate::cassandra::collection::List;
3use crate::cassandra::collection::Map;
4// use decimal::d128;
5use crate::cassandra::collection::Set;
6use crate::cassandra::consistency::Consistency;
7use crate::cassandra::error::*;
8use crate::cassandra::future::CassFuture;
9use crate::cassandra::inet::Inet;
10use crate::cassandra::policy::retry::RetryPolicy;
11use crate::cassandra::result::CassResult;
12use crate::cassandra::tuple::Tuple;
13use crate::cassandra::user_type::UserType;
14use crate::cassandra::util::{Protected, ProtectedInner, ProtectedWithSession};
15use crate::cassandra::uuid::Uuid;
16use crate::{session_scope, Session};
17
18use crate::cassandra_sys::cass_false;
19use crate::cassandra_sys::cass_session_execute;
20use crate::cassandra_sys::cass_statement_add_key_index;
21use crate::cassandra_sys::cass_statement_bind_bool;
22use crate::cassandra_sys::cass_statement_bind_bool_by_name_n;
23use crate::cassandra_sys::cass_statement_bind_bytes;
24use crate::cassandra_sys::cass_statement_bind_bytes_by_name_n;
25use crate::cassandra_sys::cass_statement_bind_collection;
26use crate::cassandra_sys::cass_statement_bind_collection_by_name_n;
27use crate::cassandra_sys::cass_statement_bind_decimal;
28use crate::cassandra_sys::cass_statement_bind_decimal_by_name_n;
29use crate::cassandra_sys::cass_statement_bind_double;
30use crate::cassandra_sys::cass_statement_bind_double_by_name_n;
31use crate::cassandra_sys::cass_statement_bind_float;
32use crate::cassandra_sys::cass_statement_bind_float_by_name_n;
33use crate::cassandra_sys::cass_statement_bind_inet;
34use crate::cassandra_sys::cass_statement_bind_inet_by_name_n;
35use crate::cassandra_sys::cass_statement_bind_int16;
36use crate::cassandra_sys::cass_statement_bind_int16_by_name_n;
37use crate::cassandra_sys::cass_statement_bind_int32;
38use crate::cassandra_sys::cass_statement_bind_int32_by_name_n;
39use crate::cassandra_sys::cass_statement_bind_int64;
40use crate::cassandra_sys::cass_statement_bind_int64_by_name_n;
41use crate::cassandra_sys::cass_statement_bind_int8;
42use crate::cassandra_sys::cass_statement_bind_int8_by_name_n;
43use crate::cassandra_sys::cass_statement_bind_null;
44use crate::cassandra_sys::cass_statement_bind_null_by_name_n;
45use crate::cassandra_sys::cass_statement_bind_string_by_name_n;
46use crate::cassandra_sys::cass_statement_bind_string_n;
47use crate::cassandra_sys::cass_statement_bind_tuple;
48use crate::cassandra_sys::cass_statement_bind_tuple_by_name_n;
49use crate::cassandra_sys::cass_statement_bind_uint32;
50use crate::cassandra_sys::cass_statement_bind_uint32_by_name_n;
51use crate::cassandra_sys::cass_statement_bind_user_type;
52use crate::cassandra_sys::cass_statement_bind_user_type_by_name_n;
53use crate::cassandra_sys::cass_statement_bind_uuid;
54use crate::cassandra_sys::cass_statement_bind_uuid_by_name_n;
55use crate::cassandra_sys::cass_statement_free;
56use crate::cassandra_sys::cass_statement_new_n;
57use crate::cassandra_sys::cass_statement_set_consistency;
58use crate::cassandra_sys::cass_statement_set_custom_payload;
59use crate::cassandra_sys::cass_statement_set_is_idempotent;
60use crate::cassandra_sys::cass_statement_set_keyspace_n;
61use crate::cassandra_sys::cass_statement_set_paging_size;
62use crate::cassandra_sys::cass_statement_set_paging_state;
63use crate::cassandra_sys::cass_statement_set_paging_state_token;
64use crate::cassandra_sys::cass_statement_set_request_timeout;
65use crate::cassandra_sys::cass_statement_set_retry_policy;
66use crate::cassandra_sys::cass_statement_set_serial_consistency;
67use crate::cassandra_sys::cass_statement_set_timestamp;
68use crate::cassandra_sys::cass_true;
69use crate::cassandra_sys::CassStatement as _Statement;
70use crate::cassandra_sys::CASS_UINT64_MAX;
71
72use std::os::raw::c_char;
73use time::Duration;
74
75#[derive(Debug)]
76struct StatementInner(*mut _Statement);
77
78impl StatementInner {
79    fn new(query: &str, parameter_count: usize) -> Self {
80        let query_ptr = query.as_ptr() as *const c_char;
81        Self(unsafe { cass_statement_new_n(query_ptr, query.len(), parameter_count) })
82    }
83}
84
85/// A statement object is an executable query. It represents either a regular
86/// (adhoc) statement or a prepared statement. It maintains the queries' parameter
87/// values along with query options (consistency level, paging state, etc.)
88///
89/// <b>Note:</b> Parameters for regular queries are not supported by the binary protocol
90/// version 1.
91#[derive(Debug)]
92pub struct Statement<T = session_scope::Bound>(StatementInner, Session<T>);
93
94// The underlying C type has no thread-local state, but does not support access
95// from multiple threads: https://datastax.github.io/cpp-driver/topics/#thread-safety
96unsafe impl Send for StatementInner {}
97
98impl ProtectedInner<*mut _Statement> for StatementInner {
99    #[inline(always)]
100    fn inner(&self) -> *mut _Statement {
101        self.0
102    }
103}
104
105impl Protected<*mut _Statement> for StatementInner {
106    #[inline(always)]
107    fn build(inner: *mut _Statement) -> Self {
108        if inner.is_null() {
109            panic!("Unexpected null pointer")
110        };
111        Self(inner)
112    }
113}
114
115impl<T> ProtectedInner<*mut _Statement> for Statement<T> {
116    #[inline(always)]
117    fn inner(&self) -> *mut _Statement {
118        self.0.inner()
119    }
120}
121
122impl<T> ProtectedWithSession<*mut _Statement, T> for Statement<T> {
123    #[inline(always)]
124    fn build(inner: *mut _Statement, session: Session<T>) -> Self {
125        Statement(StatementInner::build(inner), session)
126    }
127
128    #[inline(always)]
129    fn session(&self) -> &Session<T> {
130        &self.1
131    }
132}
133
134// statement,
135//  key,
136//  i % 2 == 0,
137//  i as f32 / 2.0f32,
138//  i as f64 / 200.0,
139//  i as i32 * 10,
140//  i as i64 * 100);
141
142impl Drop for StatementInner {
143    /// Frees a statement instance. Statements can be immediately freed after
144    /// being prepared, executed or added to a batch.
145    fn drop(&mut self) {
146        unsafe { cass_statement_free(self.0) }
147    }
148}
149
150/// All Rust types that can be bound to a cassandra statement
151/// //FIXME not yet implemented
152// pub enum CassBindable {
153//
154// }
155/// Any rust type that can have a default bind implementation
156pub trait BindRustType<S, T> {
157    /// binds a rust type to C* by index
158    fn bind(&mut self, index: usize, value: T) -> Result<&mut Statement<S>>;
159    /// binds a rust type to C* by name
160    fn bind_by_name(&mut self, col: &str, value: T) -> Result<&mut Statement<S>>;
161}
162
163impl<S> BindRustType<S, bool> for Statement<S> {
164    fn bind(&mut self, index: usize, value: bool) -> Result<&mut Self> {
165        self.bind_bool(index, value)
166    }
167
168    fn bind_by_name(&mut self, col: &str, value: bool) -> Result<&mut Self> {
169        self.bind_bool_by_name(col, value)
170    }
171}
172
173impl<S> BindRustType<S, f32> for Statement<S> {
174    fn bind(&mut self, index: usize, value: f32) -> Result<&mut Self> {
175        self.bind_float(index, value)
176    }
177
178    fn bind_by_name(&mut self, col: &str, value: f32) -> Result<&mut Self> {
179        self.bind_float_by_name(col, value)
180    }
181}
182
183impl<S> BindRustType<S, f64> for Statement<S> {
184    fn bind(&mut self, index: usize, value: f64) -> Result<&mut Self> {
185        self.bind_double(index, value)
186    }
187
188    fn bind_by_name(&mut self, col: &str, value: f64) -> Result<&mut Self> {
189        self.bind_double_by_name(col, value)
190    }
191}
192
193impl<S> BindRustType<S, i8> for Statement<S> {
194    fn bind(&mut self, index: usize, value: i8) -> Result<&mut Self> {
195        self.bind_int8(index, value)
196    }
197
198    fn bind_by_name(&mut self, col: &str, value: i8) -> Result<&mut Self> {
199        self.bind_int8_by_name(col, value)
200    }
201}
202
203impl<S> BindRustType<S, i16> for Statement<S> {
204    fn bind(&mut self, index: usize, value: i16) -> Result<&mut Self> {
205        self.bind_int16(index, value)
206    }
207
208    fn bind_by_name(&mut self, col: &str, value: i16) -> Result<&mut Self> {
209        self.bind_int16_by_name(col, value)
210    }
211}
212
213impl<S> BindRustType<S, i32> for Statement<S> {
214    fn bind(&mut self, index: usize, value: i32) -> Result<&mut Self> {
215        self.bind_int32(index, value)
216    }
217
218    fn bind_by_name(&mut self, col: &str, value: i32) -> Result<&mut Self> {
219        self.bind_int32_by_name(col, value)
220    }
221}
222
223impl<S> BindRustType<S, i64> for Statement<S> {
224    fn bind(&mut self, index: usize, value: i64) -> Result<&mut Self> {
225        self.bind_int64(index, value)
226    }
227
228    fn bind_by_name(&mut self, col: &str, value: i64) -> Result<&mut Self> {
229        self.bind_int64_by_name(col, value)
230    }
231}
232
233impl<S> BindRustType<S, u32> for Statement<S> {
234    fn bind(&mut self, index: usize, value: u32) -> Result<&mut Self> {
235        self.bind_uint32(index, value)
236    }
237
238    fn bind_by_name(&mut self, col: &str, value: u32) -> Result<&mut Self> {
239        self.bind_uint32_by_name(col, value)
240    }
241}
242
243impl<S> BindRustType<S, &'_ str> for Statement<S> {
244    fn bind(&mut self, index: usize, value: &str) -> Result<&mut Self> {
245        self.bind_string(index, value)
246    }
247
248    fn bind_by_name(&mut self, col: &str, value: &str) -> Result<&mut Self> {
249        self.bind_string_by_name(col, value)
250    }
251}
252
253impl<S> BindRustType<S, Set> for Statement<S> {
254    fn bind(&mut self, index: usize, value: Set) -> Result<&mut Self> {
255        self.bind_set(index, value)
256    }
257
258    fn bind_by_name(&mut self, col: &str, value: Set) -> Result<&mut Self> {
259        self.bind_set_by_name(col, value)
260    }
261}
262
263impl<S> BindRustType<S, List> for Statement<S> {
264    fn bind(&mut self, index: usize, value: List) -> Result<&mut Self> {
265        self.bind_list(index, value)
266    }
267
268    fn bind_by_name(&mut self, col: &str, value: List) -> Result<&mut Self> {
269        self.bind_list_by_name(col, value)
270    }
271}
272
273impl<S> BindRustType<S, Uuid> for Statement<S> {
274    fn bind(&mut self, index: usize, value: Uuid) -> Result<&mut Self> {
275        self.bind_uuid(index, value)
276    }
277
278    fn bind_by_name(&mut self, col: &str, value: Uuid) -> Result<&mut Self> {
279        self.bind_uuid_by_name(col, value)
280    }
281}
282
283impl<S> BindRustType<S, uuid::Uuid> for Statement<S> {
284    fn bind(&mut self, index: usize, value: uuid::Uuid) -> Result<&mut Self> {
285        self.bind_uuid(index, value.into())
286    }
287
288    fn bind_by_name(&mut self, col: &str, value: uuid::Uuid) -> Result<&mut Self> {
289        self.bind_uuid_by_name(col, value.into())
290    }
291}
292
293impl<S> BindRustType<S, Inet> for Statement<S> {
294    fn bind(&mut self, index: usize, value: Inet) -> Result<&mut Self> {
295        self.bind_inet(index, value)
296    }
297
298    fn bind_by_name(&mut self, col: &str, value: Inet) -> Result<&mut Self> {
299        self.bind_inet_by_name(col, value)
300    }
301}
302
303impl<S> BindRustType<S, Map> for Statement<S> {
304    fn bind(&mut self, index: usize, value: Map) -> Result<&mut Self> {
305        self.bind_map(index, value)
306    }
307
308    fn bind_by_name(&mut self, col: &str, value: Map) -> Result<&mut Self> {
309        self.bind_map_by_name(col, value)
310    }
311}
312
313impl<S> BindRustType<S, Tuple> for Statement<S> {
314    fn bind(&mut self, index: usize, value: Tuple) -> Result<&mut Self> {
315        self.bind_tuple(index, value)
316    }
317
318    fn bind_by_name(&mut self, col: &str, value: Tuple) -> Result<&mut Self> {
319        self.bind_tuple_by_name(col, value)
320    }
321}
322
323impl<S> BindRustType<S, &UserType> for Statement<S> {
324    fn bind(&mut self, index: usize, value: &UserType) -> Result<&mut Self> {
325        self.bind_user_type(index, value)
326    }
327
328    fn bind_by_name(&mut self, col: &str, value: &UserType) -> Result<&mut Self> {
329        self.bind_user_type_by_name(col, value)
330    }
331}
332
333impl<S> BindRustType<S, Vec<u8>> for Statement<S> {
334    fn bind(&mut self, index: usize, value: Vec<u8>) -> Result<&mut Self> {
335        self.bind_bytes(index, value)
336    }
337
338    fn bind_by_name(&mut self, col: &str, value: Vec<u8>) -> Result<&mut Self> {
339        self.bind_bytes_by_name(col, value)
340    }
341}
342
343impl<T> Statement<T> {
344    /// Creates a new query statement.
345    pub(crate) fn new(session: Session<T>, query: &str, parameter_count: usize) -> Self {
346        Statement(StatementInner::new(query, parameter_count), session)
347    }
348
349    /// Returns the session of which this statement is bound to.
350    pub fn session(&self) -> &Session<T> {
351        ProtectedWithSession::session(self)
352    }
353
354    /// Executes the statement.
355    pub async fn execute(self) -> Result<CassResult> {
356        let (statement, session) = (self.0, self.1);
357        let fut = {
358            let execute = unsafe { cass_session_execute(session.inner(), statement.inner()) };
359            <CassFuture<CassResult, T>>::build(session, execute)
360        };
361        fut.await
362    }
363
364    //    ///Binds an arbitrary CassBindable type to a cassandra statement
365    //    ///FIXME not yet implemented
366    //    pub fn bind(&mut self, params: Vec<CassBindable>) {
367    //        let _ = params;
368    //        unimplemented!();
369    //    }
370
371    /// Adds a key index specifier to this a statement.
372    /// When using token-aware routing, this can be used to tell the driver which
373    /// parameters within a non-prepared, parameterized statement are part of
374    /// the partition key.
375    ///
376    /// Use consecutive calls for composite partition keys.
377    ///
378    /// This is not necessary for prepared statements, as the key
379    /// parameters are determined in the metadata processed in the prepare phase.
380    pub fn add_key_index(&mut self, index: usize) -> Result<&mut Self> {
381        unsafe { cass_statement_add_key_index(self.inner(), index).to_result(self) }
382    }
383
384    /// Sets the statement's keyspace for use with token-aware routing.
385    ///
386    /// This is not necessary for prepared statements, as the keyspace
387    /// is determined in the metadata processed in the prepare phase.
388    pub fn set_keyspace(&mut self, keyspace: String) -> Result<&mut Self> {
389        unsafe {
390            let keyspace_ptr = keyspace.as_ptr() as *const c_char;
391            cass_statement_set_keyspace_n(self.inner(), keyspace_ptr, keyspace.len())
392                .to_result(self)
393        }
394    }
395
396    /// Sets the statement's consistency level.
397    ///
398    /// <b>Default:</b> CASS_CONSISTENCY_LOCAL_ONE
399    pub fn set_consistency(&mut self, consistency: Consistency) -> Result<&mut Self> {
400        unsafe { cass_statement_set_consistency(self.inner(), consistency.inner()).to_result(self) }
401    }
402
403    /// Sets the statement's serial consistency level.
404    ///
405    /// <b>Default:</b> Not set
406    pub fn set_serial_consistency(&mut self, serial_consistency: Consistency) -> Result<&mut Self> {
407        unsafe {
408            cass_statement_set_serial_consistency(self.inner(), serial_consistency.inner())
409                .to_result(self)
410        }
411    }
412
413    /// Sets the statement's page size.
414    ///
415    /// <b>Default:</b> -1 (Disabled)
416    pub fn set_paging_size(&mut self, page_size: i32) -> Result<&mut Self> {
417        unsafe { cass_statement_set_paging_size(self.inner(), page_size).to_result(self) }
418    }
419
420    /// Sets the statement's paging state. This can be used to get the next page of
421    /// data in a multi-page query.
422    pub fn set_paging_state(&mut self, result: CassResult) -> Result<&mut Self> {
423        unsafe { cass_statement_set_paging_state(self.inner(), result.inner()).to_result(self) }
424    }
425
426    /// Sets the statement's paging state.  This can be used to get the next page of
427    /// data in a multi-page query.
428    ///
429    /// <b>Warning:</b> The paging state should not be exposed to or come from
430    /// untrusted environments. The paging state could be spoofed and potentially
431    /// used to gain access to other data.
432    pub fn set_paging_state_token(&mut self, paging_state: &[u8]) -> Result<&mut Self> {
433        unsafe {
434            cass_statement_set_paging_state_token(
435                self.inner(),
436                paging_state.as_ptr() as *const i8,
437                paging_state.len(),
438            )
439            .to_result(self)
440        }
441    }
442
443    /// Sets the statement's timestamp.
444    pub fn set_timestamp(&mut self, timestamp: i64) -> Result<&mut Self> {
445        unsafe { cass_statement_set_timestamp(self.inner(), timestamp).to_result(self) }
446    }
447
448    /// Sets the statement's timeout for waiting for a response from a node.
449    /// Some(Duration::milliseconds(0)) sets no timeout, and None disables it
450    /// (to use the cluster-level request timeout).
451    pub fn set_statement_request_timeout(&mut self, timeout: Option<Duration>) -> &mut Self {
452        unsafe {
453            let timeout_millis = match timeout {
454                None => CASS_UINT64_MAX as u64,
455                Some(time) => time.whole_milliseconds() as u64,
456            };
457            cass_statement_set_request_timeout(self.inner(), timeout_millis);
458        }
459        self
460    }
461
462    /// Sets the statement's retry policy.
463    pub fn set_retry_policy(&mut self, retry_policy: RetryPolicy) -> Result<&mut Self> {
464        unsafe {
465            cass_statement_set_retry_policy(self.inner(), retry_policy.inner()).to_result(self)
466        }
467    }
468
469    /// Sets the statement's custom payload.
470    pub fn set_custom_payload(&mut self, payload: CustomPayload) -> Result<&mut Self> {
471        unsafe { cass_statement_set_custom_payload(self.inner(), payload.inner()).to_result(self) }
472    }
473
474    /// Binds null to a query or bound statement at the specified index.
475    pub fn bind_null(&mut self, index: usize) -> Result<&mut Self> {
476        unsafe { cass_statement_bind_null(self.inner(), index).to_result(self) }
477    }
478
479    /// Binds a null to all the values with the specified name.
480    ///
481    /// This can only be used with statements created by
482    /// cass_prepared_bind().
483    pub fn bind_null_by_name(&mut self, name: &str) -> Result<&mut Self> {
484        unsafe {
485            let name_ptr = name.as_ptr() as *const c_char;
486            cass_statement_bind_null_by_name_n(self.inner(), name_ptr, name.len()).to_result(self)
487        }
488    }
489
490    /// Binds a "tinyint" to a query or bound statement at the specified index.
491    pub fn bind_int8(&mut self, index: usize, value: i8) -> Result<&mut Self> {
492        unsafe { cass_statement_bind_int8(self.inner(), index, value).to_result(self) }
493    }
494
495    /// Binds a "tinyint" to all the values with the specified name.
496    pub fn bind_int8_by_name(&mut self, name: &str, value: i8) -> Result<&mut Self> {
497        unsafe {
498            let name_ptr = name.as_ptr() as *const c_char;
499            cass_statement_bind_int8_by_name_n(self.inner(), name_ptr, name.len(), value)
500                .to_result(self)
501        }
502    }
503
504    /// Binds an "smallint" to a query or bound statement at the specified index.
505    pub fn bind_int16(&mut self, index: usize, value: i16) -> Result<&mut Self> {
506        unsafe { cass_statement_bind_int16(self.inner(), index, value).to_result(self) }
507    }
508
509    /// Binds a "smallint" to all the values with the specified name.
510    pub fn bind_int16_by_name(&mut self, name: &str, value: i16) -> Result<&mut Self> {
511        unsafe {
512            let name_ptr = name.as_ptr() as *const c_char;
513            cass_statement_bind_int16_by_name_n(self.inner(), name_ptr, name.len(), value)
514                .to_result(self)
515        }
516    }
517
518    /// Binds an "int" to a query or bound statement at the specified index.
519    pub fn bind_int32(&mut self, index: usize, value: i32) -> Result<&mut Self> {
520        unsafe { cass_statement_bind_int32(self.inner(), index, value).to_result(self) }
521    }
522
523    /// Binds an "int" to all the values with the specified name.
524    pub fn bind_int32_by_name(&mut self, name: &str, value: i32) -> Result<&mut Self> {
525        unsafe {
526            let name_ptr = name.as_ptr() as *const c_char;
527            cass_statement_bind_int32_by_name_n(self.inner(), name_ptr, name.len(), value)
528                .to_result(self)
529        }
530    }
531
532    /// Binds a "date" to a query or bound statement at the specified index.
533    pub fn bind_uint32(&mut self, index: usize, value: u32) -> Result<&mut Self> {
534        unsafe { cass_statement_bind_uint32(self.inner(), index, value).to_result(self) }
535    }
536
537    /// Binds a "date" to all the values with the specified name.
538    ///
539    /// This can only be used with statements created by
540    /// cass_prepared_bind().
541    pub fn bind_uint32_by_name(&mut self, name: &str, value: u32) -> Result<&mut Self> {
542        unsafe {
543            let name_ptr = name.as_ptr() as *const c_char;
544            cass_statement_bind_uint32_by_name_n(self.inner(), name_ptr, name.len(), value)
545                .to_result(self)
546        }
547    }
548
549    /// Binds a "bigint", "counter", "timestamp" or "time" to a query or
550    /// bound statement at the specified index.
551    pub fn bind_int64(&mut self, index: usize, value: i64) -> Result<&mut Self> {
552        unsafe { cass_statement_bind_int64(self.inner(), index, value).to_result(self) }
553    }
554
555    /// Binds a "bigint", "counter", "timestamp" or "time" to all values
556    /// with the specified name.
557    pub fn bind_int64_by_name(&mut self, name: &str, value: i64) -> Result<&mut Self> {
558        unsafe {
559            let name_ptr = name.as_ptr() as *const c_char;
560            cass_statement_bind_int64_by_name_n(self.inner(), name_ptr, name.len(), value)
561                .to_result(self)
562        }
563    }
564
565    /// Binds a "float" to a query or bound statement at the specified index.
566    pub fn bind_float(&mut self, index: usize, value: f32) -> Result<&mut Self> {
567        unsafe { cass_statement_bind_float(self.inner(), index, value).to_result(self) }
568    }
569
570    /// Binds a "float" to all the values with the specified name.
571    ///
572    /// This can only be used with statements created by
573    /// cass_prepared_bind().
574    pub fn bind_float_by_name(&mut self, name: &str, value: f32) -> Result<&mut Self> {
575        unsafe {
576            let name_ptr = name.as_ptr() as *const c_char;
577            cass_statement_bind_float_by_name_n(self.inner(), name_ptr, name.len(), value)
578                .to_result(self)
579        }
580    }
581
582    /// Binds a "double" to a query or bound statement at the specified index.
583    pub fn bind_double(&mut self, index: usize, value: f64) -> Result<&mut Self> {
584        unsafe { cass_statement_bind_double(self.inner(), index, value).to_result(self) }
585    }
586
587    /// Binds a "double" to all the values with the specified name.
588    ///
589    /// This can only be used with statements created by
590    /// cass_prepared_bind().
591    pub fn bind_double_by_name(&mut self, name: &str, value: f64) -> Result<&mut Self> {
592        unsafe {
593            let name_ptr = name.as_ptr() as *const c_char;
594            cass_statement_bind_double_by_name_n(self.inner(), name_ptr, name.len(), value)
595                .to_result(self)
596        }
597    }
598
599    /// Binds a "boolean" to a query or bound statement at the specified index.
600    pub fn bind_bool(&mut self, index: usize, value: bool) -> Result<&mut Self> {
601        unsafe {
602            cass_statement_bind_bool(
603                self.inner(),
604                index,
605                if value { cass_true } else { cass_false },
606            )
607            .to_result(self)
608        }
609    }
610
611    /// Binds a "boolean" to all the values with the specified name.
612    ///
613    /// This can only be used with statements created by
614    /// cass_prepared_bind().
615    pub fn bind_bool_by_name(&mut self, name: &str, value: bool) -> Result<&mut Self> {
616        unsafe {
617            let name_ptr = name.as_ptr() as *const c_char;
618            cass_statement_bind_bool_by_name_n(
619                self.inner(),
620                name_ptr,
621                name.len(),
622                if value { cass_true } else { cass_false },
623            )
624            .to_result(self)
625        }
626    }
627
628    /// Binds an "ascii", "text" or "varchar" to a query or bound statement
629    /// at the specified index.
630    pub fn bind_string(&mut self, index: usize, value: &str) -> Result<&mut Self> {
631        unsafe {
632            let value_ptr = value.as_ptr() as *const c_char;
633            cass_statement_bind_string_n(self.inner(), index, value_ptr, value.len())
634                .to_result(self)
635        }
636    }
637
638    /// Binds an "ascii", "text" or "varchar" to all the values
639    /// with the specified name.
640    ///
641    /// This can only be used with statements created by
642    /// cass_prepared_bind().
643    pub fn bind_string_by_name(&mut self, name: &str, value: &str) -> Result<&mut Self> {
644        unsafe {
645            let name_ptr = name.as_ptr() as *const c_char;
646            let value_ptr = value.as_ptr() as *const c_char;
647
648            cass_statement_bind_string_by_name_n(
649                self.inner(),
650                name_ptr,
651                name.len(),
652                value_ptr,
653                value.len(),
654            )
655            .to_result(self)
656        }
657    }
658
659    /// Binds a "blob", "varint" or "custom" to a query or bound statement at the specified index.
660    pub fn bind_bytes(&mut self, index: usize, value: Vec<u8>) -> Result<&mut Self> {
661        unsafe {
662            cass_statement_bind_bytes(self.inner(), index, value.as_ptr(), value.len())
663                .to_result(self)
664        }
665    }
666
667    /// Binds a "blob", "varint" or "custom" to all the values with the
668    /// specified name.
669    ///
670    /// This can only be used with statements created by
671    /// cass_prepared_bind().
672    pub fn bind_bytes_by_name(&mut self, name: &str, mut value: Vec<u8>) -> Result<&mut Self> {
673        unsafe {
674            let name_ptr = name.as_ptr() as *const c_char;
675            cass_statement_bind_bytes_by_name_n(
676                self.inner(),
677                name_ptr,
678                name.len(),
679                value.as_mut_ptr(),
680                value.len(),
681            )
682            .to_result(self)
683        }
684    }
685
686    /// Binds a "uuid" or "timeuuid" to a query or bound statement at the specified index.
687    pub fn bind_uuid(&mut self, index: usize, value: Uuid) -> Result<&mut Self> {
688        unsafe { cass_statement_bind_uuid(self.inner(), index, value.inner()).to_result(self) }
689    }
690
691    /// Binds a "uuid" or "timeuuid" to all the values
692    /// with the specified name.
693    ///
694    /// This can only be used with statements created by
695    /// cass_prepared_bind().
696    pub fn bind_uuid_by_name(&mut self, name: &str, value: Uuid) -> Result<&mut Self> {
697        unsafe {
698            let name_ptr = name.as_ptr() as *const c_char;
699            cass_statement_bind_uuid_by_name_n(self.inner(), name_ptr, name.len(), value.inner())
700                .to_result(self)
701        }
702    }
703
704    /// Binds an "inet" to a query or bound statement at the specified index.
705    pub fn bind_inet(&mut self, index: usize, value: Inet) -> Result<&mut Self> {
706        unsafe { cass_statement_bind_inet(self.inner(), index, value.inner()).to_result(self) }
707    }
708
709    /// Binds an "inet" to all the values with the specified name.
710    pub fn bind_inet_by_name(&mut self, name: &str, value: Inet) -> Result<&mut Self> {
711        unsafe {
712            let name_ptr = name.as_ptr() as *const c_char;
713            cass_statement_bind_inet_by_name_n(self.inner(), name_ptr, name.len(), value.inner())
714                .to_result(self)
715        }
716    }
717
718    //  ///Bind a "decimal" to a query or bound statement at the specified index.
719    //    pub fn bind_decimal(&self,
720    //                                index: i32,
721    //                                value: d128)
722    //                                -> Result<&mut Self, CassError> {
723    //            unsafe {
724    //                CassError::build(
725    //                    cass_statement_bind_decimal(
726    //                        self.inner(),
727    //                        index,
728    //                        value
729    //                    )
730    //                ).wrap(&mut self)
731    //            }
732    //        }
733
734    // Binds a "decimal" to all the values with the specified name.
735    //
736    // This can only be used with statements created by
737    // cass_prepared_bind().
738    //    pub fn bind_decimal_by_name<'a>(&'a self,
739    //                                    name: &str,
740    //                                    value: String)
741    //                                    -> Result<&'a Self, CassError> {
742    //        unsafe {
743    //            let name = CString::new(name).unwrap();
744    //            CassError::build(
745    //            cass_statement_bind_decimal_by_name(
746    //                self.inner(),
747    //                name.as_ptr(),
748    //                value
749    //            )
750    //        ).wrap(&self)
751    //        }
752    //    }
753
754    /// Bind a "map" to a query or bound statement at the specified index.
755    pub fn bind_map(&mut self, index: usize, map: Map) -> Result<&mut Self> {
756        unsafe { cass_statement_bind_collection(self.inner(), index, map.inner()).to_result(self) }
757    }
758
759    /// Bind a "map" to all the values with the
760    /// specified name.
761    ///
762    /// This can only be used with statements created by
763    /// cass_prepared_bind().
764    pub fn bind_map_by_name(&mut self, name: &str, map: Map) -> Result<&mut Self> {
765        unsafe {
766            let name_ptr = name.as_ptr() as *const c_char;
767            cass_statement_bind_collection_by_name_n(
768                self.inner(),
769                name_ptr,
770                name.len(),
771                map.inner(),
772            )
773            .to_result(self)
774        }
775    }
776    /// Bind a "set" to a query or bound statement at the specified index.
777    pub fn bind_set(&mut self, index: usize, collection: Set) -> Result<&mut Self> {
778        unsafe {
779            cass_statement_bind_collection(self.inner(), index, collection.inner()).to_result(self)
780        }
781    }
782
783    /// Bind a "set" to all the values with the
784    /// specified name.
785    ///
786    /// This can only be used with statements created by
787    /// cass_prepared_bind().
788    pub fn bind_set_by_name(&mut self, name: &str, collection: Set) -> Result<&mut Self> {
789        unsafe {
790            let name_ptr = name.as_ptr() as *const c_char;
791            cass_statement_bind_collection_by_name_n(
792                self.inner(),
793                name_ptr,
794                name.len(),
795                collection.inner(),
796            )
797            .to_result(self)
798        }
799    }
800
801    /// Bind a "list" to a query or bound statement at the specified index.
802    pub fn bind_list(&mut self, index: usize, collection: List) -> Result<&mut Self> {
803        unsafe {
804            cass_statement_bind_collection(self.inner(), index, collection.inner()).to_result(self)
805        }
806    }
807
808    /// Bind a "list" to all the values with the
809    /// specified name.
810    ///
811    /// This can only be used with statements created by
812    /// cass_prepared_bind().
813    pub fn bind_list_by_name(&mut self, name: &str, collection: List) -> Result<&mut Self> {
814        unsafe {
815            let name_ptr = name.as_ptr() as *const c_char;
816            cass_statement_bind_collection_by_name_n(
817                self.inner(),
818                name_ptr,
819                name.len(),
820                collection.inner(),
821            )
822            .to_result(self)
823        }
824    }
825
826    /// Bind a "tuple" to a query or bound statement at the specified index.
827    pub fn bind_tuple(&mut self, index: usize, value: Tuple) -> Result<&mut Self> {
828        unsafe { cass_statement_bind_tuple(self.inner(), index, value.inner()).to_result(self) }
829    }
830
831    /// Bind a "tuple" to all the values with the specified name.
832    ///
833    /// This can only be used with statements created by
834    /// cass_prepared_bind().
835    pub fn bind_tuple_by_name(&mut self, name: &str, value: Tuple) -> Result<&mut Self> {
836        unsafe {
837            let name_ptr = name.as_ptr() as *const c_char;
838            cass_statement_bind_tuple_by_name_n(self.inner(), name_ptr, name.len(), value.inner())
839                .to_result(self)
840        }
841    }
842
843    /// Bind a user defined type to a query or bound statement at the
844    /// specified index.
845    pub fn bind_user_type(&mut self, index: usize, value: &UserType) -> Result<&mut Self> {
846        unsafe { cass_statement_bind_user_type(self.inner(), index, value.inner()).to_result(self) }
847    }
848
849    /// Bind a user defined type to a query or bound statement with the
850    /// specified name.
851    pub fn bind_user_type_by_name(&mut self, name: &str, value: &UserType) -> Result<&mut Self> {
852        unsafe {
853            let name_ptr = name.as_ptr() as *const c_char;
854            cass_statement_bind_user_type_by_name_n(
855                self.inner(),
856                name_ptr,
857                name.len(),
858                value.inner(),
859            )
860            .to_result(self)
861        }
862    }
863
864    /// Sets whether the statement is idempotent. Idempotent statements are able to be automatically
865    /// retried after timeouts/errors and can be speculatively executed.
866    ///
867    /// Default: false
868    pub fn set_is_idempotent(&mut self, is_idempotent: bool) -> Result<&mut Self> {
869        unsafe {
870            cass_statement_set_is_idempotent(
871                self.inner(),
872                if is_idempotent { cass_true } else { cass_false },
873            )
874            .to_result(self)
875        }
876    }
877}