cassandra_cpp/cassandra/
prepared.rs

1use crate::cassandra::error::*;
2use crate::cassandra::statement::Statement;
3use crate::cassandra::util::{Protected, ProtectedInner, ProtectedWithSession};
4use crate::{cassandra::data_type::ConstDataType, Session};
5
6use crate::cassandra_sys::cass_prepared_bind;
7use crate::cassandra_sys::cass_prepared_free;
8use crate::cassandra_sys::cass_prepared_parameter_data_type;
9use crate::cassandra_sys::cass_prepared_parameter_data_type_by_name_n;
10use crate::cassandra_sys::cass_prepared_parameter_name;
11use crate::cassandra_sys::CassPrepared as _PreparedStatement;
12use std::os::raw::c_char;
13use std::{slice, str};
14
15/// A statement that has been prepared against at least one Cassandra node.
16/// Instances of this class should not be created directly, but through Session.prepare().
17#[derive(Debug)]
18pub struct PreparedStatement(*const _PreparedStatement, Session);
19
20unsafe impl Send for PreparedStatement {}
21unsafe impl Sync for PreparedStatement {}
22
23impl Drop for PreparedStatement {
24    /// Frees a prepared statement
25    fn drop(&mut self) {
26        unsafe { cass_prepared_free(self.0) }
27    }
28}
29
30impl ProtectedInner<*const _PreparedStatement> for PreparedStatement {
31    #[inline(always)]
32    fn inner(&self) -> *const _PreparedStatement {
33        self.0
34    }
35}
36
37impl ProtectedWithSession<*const _PreparedStatement> for PreparedStatement {
38    #[inline(always)]
39    fn build(inner: *const _PreparedStatement, session: Session) -> Self {
40        if inner.is_null() {
41            panic!("Unexpected null pointer")
42        };
43        PreparedStatement(inner, session)
44    }
45
46    #[inline(always)]
47    fn session(&self) -> &Session {
48        &self.1
49    }
50}
51
52impl PreparedStatement {
53    /// Creates a bound statement from a pre-prepared statement.
54    pub fn bind(&self) -> Statement {
55        unsafe { Statement::build(cass_prepared_bind(self.inner()), self.session().clone()) }
56    }
57
58    /// Returns the session of which this prepared statement is bound to.
59    pub fn session(&self) -> &Session {
60        ProtectedWithSession::session(self)
61    }
62
63    /// Gets the name of a parameter at the specified index.
64    pub fn parameter_name(&self, index: usize) -> Result<&str> {
65        let mut name = std::ptr::null();
66        let mut name_length = 0;
67        unsafe {
68            cass_prepared_parameter_name(self.0, index, &mut name, &mut name_length)
69                .to_result(())
70                .and_then(|_| {
71                    Ok(str::from_utf8(slice::from_raw_parts(
72                        name as *const u8,
73                        name_length,
74                    ))?)
75                })
76        }
77    }
78
79    /// Gets the data type of a parameter at the specified index.
80    ///
81    /// Returns a reference to the data type of the parameter.
82    pub fn parameter_data_type(&self, index: usize) -> ConstDataType {
83        unsafe { ConstDataType::build(cass_prepared_parameter_data_type(self.0, index)) }
84    }
85
86    /// Gets the data type of a parameter for the specified name.
87    ///
88    /// Returns a reference to the data type of the parameter.
89    pub fn parameter_data_type_by_name(&self, name: &str) -> ConstDataType {
90        unsafe {
91            let name_ptr = name.as_ptr() as *const c_char;
92            ConstDataType::build(cass_prepared_parameter_data_type_by_name_n(
93                self.0,
94                name_ptr,
95                name.len(),
96            ))
97        }
98    }
99}