discord_cassandra_cpp/cassandra/
prepared.rs1use crate::cassandra::error::*;
2use crate::cassandra::statement::Statement;
3use crate::cassandra::util::{Protected, ProtectedInner, ProtectedWithSession};
4use crate::{cassandra::data_type::ConstDataType, session_scope, 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::{mem, slice, str};
14
15#[derive(Debug)]
18pub struct PreparedStatement<T = session_scope::Bound>(*const _PreparedStatement, Session<T>);
19
20unsafe impl<T: Send> Send for PreparedStatement<T> {}
21unsafe impl<T: Sync> Sync for PreparedStatement<T> {}
22
23impl<T> Drop for PreparedStatement<T> {
24 fn drop(&mut self) {
26 unsafe { cass_prepared_free(self.0) }
27 }
28}
29
30impl<T> ProtectedInner<*const _PreparedStatement> for PreparedStatement<T> {
31 #[inline(always)]
32 fn inner(&self) -> *const _PreparedStatement {
33 self.0
34 }
35}
36
37impl<T> ProtectedWithSession<*const _PreparedStatement, T> for PreparedStatement<T> {
38 #[inline(always)]
39 fn build(inner: *const _PreparedStatement, session: Session<T>) -> 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<T> {
48 &self.1
49 }
50}
51
52impl<T: Clone> PreparedStatement<T> {
53 pub fn bind(&self) -> Statement<T> {
55 unsafe { Statement::build(cass_prepared_bind(self.inner()), self.session().clone()) }
56 }
57
58 pub fn session(&self) -> &Session<T> {
60 ProtectedWithSession::session(self)
61 }
62
63 pub fn parameter_name(&self, index: usize) -> Result<&str> {
65 unsafe {
66 let mut name = mem::zeroed();
67 let mut name_length = mem::zeroed();
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 as usize,
74 ))?)
75 })
76 }
77 }
78
79 pub fn parameter_data_type(&self, index: usize) -> Option<ConstDataType> {
84 unsafe {
85 let inner = cass_prepared_parameter_data_type(self.0, index);
86 if inner.is_null() {
87 None
88 } else {
89 Some(ConstDataType::build(inner))
90 }
91 }
92 }
93
94 pub fn parameter_data_type_by_name(&self, name: &str) -> Option<ConstDataType> {
99 unsafe {
100 let name_ptr = name.as_ptr() as *const c_char;
101 let inner = cass_prepared_parameter_data_type_by_name_n(self.0, name_ptr, name.len());
102 if inner.is_null() {
103 None
104 } else {
105 Some(ConstDataType::build(inner))
106 }
107 }
108 }
109}