cassandra_cpp/cassandra/
statement.rs

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