use crate::cassandra::batch::CustomPayload;
use crate::cassandra::collection::List;
use crate::cassandra::collection::Map;
use crate::cassandra::collection::Set;
use crate::cassandra::consistency::Consistency;
use crate::cassandra::error::*;
use crate::cassandra::inet::Inet;
use crate::cassandra::policy::retry::RetryPolicy;
use crate::cassandra::result::CassResult;
use crate::cassandra::tuple::Tuple;
use crate::cassandra::user_type::UserType;
use crate::cassandra::util::Protected;
use crate::cassandra::uuid::Uuid;
use crate::cassandra_sys::cass_false;
use crate::cassandra_sys::cass_statement_add_key_index;
use crate::cassandra_sys::cass_statement_bind_bool;
use crate::cassandra_sys::cass_statement_bind_bool_by_name;
use crate::cassandra_sys::cass_statement_bind_bytes;
use crate::cassandra_sys::cass_statement_bind_bytes_by_name;
use crate::cassandra_sys::cass_statement_bind_collection;
use crate::cassandra_sys::cass_statement_bind_collection_by_name;
use crate::cassandra_sys::cass_statement_bind_decimal;
use crate::cassandra_sys::cass_statement_bind_decimal_by_name;
use crate::cassandra_sys::cass_statement_bind_double;
use crate::cassandra_sys::cass_statement_bind_double_by_name;
use crate::cassandra_sys::cass_statement_bind_float;
use crate::cassandra_sys::cass_statement_bind_float_by_name;
use crate::cassandra_sys::cass_statement_bind_inet;
use crate::cassandra_sys::cass_statement_bind_inet_by_name;
use crate::cassandra_sys::cass_statement_bind_int16;
use crate::cassandra_sys::cass_statement_bind_int16_by_name;
use crate::cassandra_sys::cass_statement_bind_int32;
use crate::cassandra_sys::cass_statement_bind_int32_by_name;
use crate::cassandra_sys::cass_statement_bind_int64;
use crate::cassandra_sys::cass_statement_bind_int64_by_name;
use crate::cassandra_sys::cass_statement_bind_int8;
use crate::cassandra_sys::cass_statement_bind_int8_by_name;
use crate::cassandra_sys::cass_statement_bind_null;
use crate::cassandra_sys::cass_statement_bind_null_by_name;
use crate::cassandra_sys::cass_statement_bind_string;
use crate::cassandra_sys::cass_statement_bind_string_by_name;
use crate::cassandra_sys::cass_statement_bind_tuple;
use crate::cassandra_sys::cass_statement_bind_tuple_by_name;
use crate::cassandra_sys::cass_statement_bind_uint32;
use crate::cassandra_sys::cass_statement_bind_uint32_by_name;
use crate::cassandra_sys::cass_statement_bind_user_type;
use crate::cassandra_sys::cass_statement_bind_user_type_by_name;
use crate::cassandra_sys::cass_statement_bind_uuid;
use crate::cassandra_sys::cass_statement_bind_uuid_by_name;
use crate::cassandra_sys::cass_statement_free;
use crate::cassandra_sys::cass_statement_new;
use crate::cassandra_sys::cass_statement_set_consistency;
use crate::cassandra_sys::cass_statement_set_custom_payload;
use crate::cassandra_sys::cass_statement_set_keyspace;
use crate::cassandra_sys::cass_statement_set_paging_size;
use crate::cassandra_sys::cass_statement_set_paging_state;
use crate::cassandra_sys::cass_statement_set_paging_state_token;
use crate::cassandra_sys::cass_statement_set_request_timeout;
use crate::cassandra_sys::cass_statement_set_retry_policy;
use crate::cassandra_sys::cass_statement_set_serial_consistency;
use crate::cassandra_sys::cass_statement_set_timestamp;
use crate::cassandra_sys::cass_true;
use crate::cassandra_sys::CassStatement as _Statement;
use crate::cassandra_sys::CASS_UINT64_MAX;
use std::ffi::CString;
use time::Duration;
#[derive(Debug)]
pub struct Statement(*mut _Statement);
unsafe impl Send for Statement {}
impl Protected<*mut _Statement> for Statement {
fn inner(&self) -> *mut _Statement {
self.0
}
fn build(inner: *mut _Statement) -> Self {
if inner.is_null() {
panic!("Unexpected null pointer")
};
Statement(inner)
}
}
#[macro_export]
macro_rules! stmt {
( $( $x:expr ),*) => {
{
$(
let query = $x;
let param_count = query.matches("?").count();
let statement = $crate::Statement::new(query, param_count);
)*
statement
}
};
}
impl Drop for Statement {
fn drop(&mut self) {
unsafe { self.free() }
}
}
pub trait BindRustType<T> {
fn bind(&mut self, index: usize, value: T) -> Result<&mut Statement>;
fn bind_by_name(&mut self, col: &str, value: T) -> Result<&mut Statement>;
}
impl BindRustType<bool> for Statement {
fn bind(&mut self, index: usize, value: bool) -> Result<&mut Self> {
self.bind_bool(index, value)
}
fn bind_by_name(&mut self, col: &str, value: bool) -> Result<&mut Self> {
self.bind_bool_by_name(col, value)
}
}
impl BindRustType<f32> for Statement {
fn bind(&mut self, index: usize, value: f32) -> Result<&mut Self> {
self.bind_float(index, value)
}
fn bind_by_name(&mut self, col: &str, value: f32) -> Result<&mut Self> {
self.bind_float_by_name(col, value)
}
}
impl BindRustType<f64> for Statement {
fn bind(&mut self, index: usize, value: f64) -> Result<&mut Self> {
self.bind_double(index, value)
}
fn bind_by_name(&mut self, col: &str, value: f64) -> Result<&mut Self> {
self.bind_double_by_name(col, value)
}
}
impl BindRustType<i8> for Statement {
fn bind(&mut self, index: usize, value: i8) -> Result<&mut Self> {
self.bind_int8(index, value)
}
fn bind_by_name(&mut self, col: &str, value: i8) -> Result<&mut Self> {
self.bind_int8_by_name(col, value)
}
}
impl BindRustType<i16> for Statement {
fn bind(&mut self, index: usize, value: i16) -> Result<&mut Self> {
self.bind_int16(index, value)
}
fn bind_by_name(&mut self, col: &str, value: i16) -> Result<&mut Self> {
self.bind_int16_by_name(col, value)
}
}
impl BindRustType<i32> for Statement {
fn bind(&mut self, index: usize, value: i32) -> Result<&mut Self> {
self.bind_int32(index, value)
}
fn bind_by_name(&mut self, col: &str, value: i32) -> Result<&mut Self> {
self.bind_int32_by_name(col, value)
}
}
impl BindRustType<i64> for Statement {
fn bind(&mut self, index: usize, value: i64) -> Result<&mut Self> {
self.bind_int64(index, value)
}
fn bind_by_name(&mut self, col: &str, value: i64) -> Result<&mut Self> {
self.bind_int64_by_name(col, value)
}
}
impl BindRustType<u32> for Statement {
fn bind(&mut self, index: usize, value: u32) -> Result<&mut Self> {
self.bind_uint32(index, value)
}
fn bind_by_name(&mut self, col: &str, value: u32) -> Result<&mut Self> {
self.bind_uint32_by_name(col, value)
}
}
impl<'a> BindRustType<&'a str> for Statement {
fn bind(&mut self, index: usize, value: &str) -> Result<&mut Self> {
self.bind_string(index, value)
}
fn bind_by_name(&mut self, col: &str, value: &str) -> Result<&mut Self> {
self.bind_string_by_name(col, value)
}
}
impl BindRustType<Set> for Statement {
fn bind(&mut self, index: usize, value: Set) -> Result<&mut Self> {
self.bind_set(index, value)
}
fn bind_by_name(&mut self, col: &str, value: Set) -> Result<&mut Self> {
self.bind_set_by_name(col, value)
}
}
impl BindRustType<List> for Statement {
fn bind(&mut self, index: usize, value: List) -> Result<&mut Self> {
self.bind_list(index, value)
}
fn bind_by_name(&mut self, col: &str, value: List) -> Result<&mut Self> {
self.bind_list_by_name(col, value)
}
}
impl BindRustType<Uuid> for Statement {
fn bind(&mut self, index: usize, value: Uuid) -> Result<&mut Self> {
self.bind_uuid(index, value)
}
fn bind_by_name(&mut self, col: &str, value: Uuid) -> Result<&mut Self> {
self.bind_uuid_by_name(col, value)
}
}
impl BindRustType<Inet> for Statement {
fn bind(&mut self, index: usize, value: Inet) -> Result<&mut Self> {
self.bind_inet(index, value)
}
fn bind_by_name(&mut self, col: &str, value: Inet) -> Result<&mut Self> {
self.bind_inet_by_name(col, value)
}
}
impl BindRustType<Map> for Statement {
fn bind(&mut self, index: usize, value: Map) -> Result<&mut Self> {
self.bind_map(index, value)
}
fn bind_by_name(&mut self, col: &str, value: Map) -> Result<&mut Self> {
self.bind_map_by_name(col, value)
}
}
impl BindRustType<Tuple> for Statement {
fn bind(&mut self, index: usize, value: Tuple) -> Result<&mut Self> {
self.bind_tuple(index, value)
}
fn bind_by_name(&mut self, col: &str, value: Tuple) -> Result<&mut Self> {
self.bind_tuple_by_name(col, value)
}
}
impl BindRustType<&UserType> for Statement {
fn bind(&mut self, index: usize, value: &UserType) -> Result<&mut Self> {
self.bind_user_type(index, value)
}
fn bind_by_name(&mut self, col: &str, value: &UserType) -> Result<&mut Self> {
self.bind_user_type_by_name(col, value)
}
}
impl BindRustType<Vec<u8>> for Statement {
fn bind(&mut self, index: usize, value: Vec<u8>) -> Result<&mut Self> {
self.bind_bytes(index, value)
}
fn bind_by_name(&mut self, col: &str, value: Vec<u8>) -> Result<&mut Self> {
self.bind_bytes_by_name(col, value)
}
}
impl Statement {
pub fn new(query: &str, parameter_count: usize) -> Self {
unsafe {
let query_cstr = CString::new(query).expect("must be utf8");
Statement(cass_statement_new(query_cstr.as_ptr(), parameter_count))
}
}
unsafe fn free(&mut self) {
cass_statement_free(self.0)
}
pub fn add_key_index(&mut self, index: usize) -> Result<&mut Self> {
unsafe { cass_statement_add_key_index(self.0, index).to_result(self) }
}
pub fn set_keyspace(&mut self, keyspace: String) -> Result<&mut Self> {
unsafe {
let keyspace_cstr = CString::new(keyspace)?;
cass_statement_set_keyspace(self.0, keyspace_cstr.as_ptr()).to_result(self)
}
}
pub fn set_consistency(&mut self, consistency: Consistency) -> Result<&mut Self> {
unsafe { cass_statement_set_consistency(self.0, consistency.inner()).to_result(self) }
}
pub fn set_serial_consistency(&mut self, serial_consistency: Consistency) -> Result<&mut Self> {
unsafe {
cass_statement_set_serial_consistency(self.0, serial_consistency.inner())
.to_result(self)
}
}
pub fn set_paging_size(&mut self, page_size: i32) -> Result<&mut Self> {
unsafe { cass_statement_set_paging_size(self.0, page_size).to_result(self) }
}
pub fn set_paging_state(&mut self, result: CassResult) -> Result<&mut Self> {
unsafe { cass_statement_set_paging_state(self.0, result.inner()).to_result(self) }
}
pub fn set_paging_state_token(&mut self, paging_state: &str) -> Result<&mut Self> {
unsafe {
cass_statement_set_paging_state_token(
self.0,
paging_state.as_ptr() as *const i8,
paging_state.len(),
)
.to_result(self)
}
}
pub fn set_timestamp(&mut self, timestamp: i64) -> Result<&mut Self> {
unsafe { cass_statement_set_timestamp(self.0, timestamp).to_result(self) }
}
pub fn set_statement_request_timeout(&mut self, timeout: Option<Duration>) -> &mut Self {
unsafe {
let timeout_millis = match timeout {
None => CASS_UINT64_MAX as u64,
Some(time) => time.num_milliseconds() as u64,
};
cass_statement_set_request_timeout(self.0, timeout_millis);
}
self
}
pub fn set_retry_policy(&mut self, retry_policy: RetryPolicy) -> Result<&mut Self> {
unsafe { cass_statement_set_retry_policy(self.0, retry_policy.inner()).to_result(self) }
}
pub fn set_custom_payload(&mut self, payload: CustomPayload) -> Result<&mut Self> {
unsafe { cass_statement_set_custom_payload(self.0, payload.inner()).to_result(self) }
}
pub fn bind_null(&mut self, index: usize) -> Result<&mut Self> {
unsafe { cass_statement_bind_null(self.0, index).to_result(self) }
}
pub fn bind_null_by_name(&mut self, name: &str) -> Result<&mut Self> {
unsafe {
let name_cstr = CString::new(name)?;
cass_statement_bind_null_by_name(self.0, name_cstr.as_ptr()).to_result(self)
}
}
pub fn bind_int8(&mut self, index: usize, value: i8) -> Result<&mut Self> {
unsafe { cass_statement_bind_int8(self.0, index, value).to_result(self) }
}
pub fn bind_int8_by_name(&mut self, name: &str, value: i8) -> Result<&mut Self> {
unsafe {
let name_cstr = CString::new(name)?;
cass_statement_bind_int8_by_name(self.0, name_cstr.as_ptr(), value).to_result(self)
}
}
pub fn bind_int16(&mut self, index: usize, value: i16) -> Result<&mut Self> {
unsafe { cass_statement_bind_int16(self.0, index, value).to_result(self) }
}
pub fn bind_int16_by_name(&mut self, name: &str, value: i16) -> Result<&mut Self> {
unsafe {
let name_cstr = CString::new(name)?;
cass_statement_bind_int16_by_name(self.0, name_cstr.as_ptr(), value).to_result(self)
}
}
pub fn bind_int32(&mut self, index: usize, value: i32) -> Result<&mut Self> {
unsafe { cass_statement_bind_int32(self.0, index, value).to_result(self) }
}
pub fn bind_int32_by_name(&mut self, name: &str, value: i32) -> Result<&mut Self> {
unsafe {
let name_cstr = CString::new(name)?;
cass_statement_bind_int32_by_name(self.0, name_cstr.as_ptr(), value).to_result(self)
}
}
pub fn bind_uint32(&mut self, index: usize, value: u32) -> Result<&mut Self> {
unsafe { cass_statement_bind_uint32(self.0, index, value).to_result(self) }
}
pub fn bind_uint32_by_name(&mut self, name: &str, value: u32) -> Result<&mut Self> {
unsafe {
let name_cstr = CString::new(name)?;
cass_statement_bind_uint32_by_name(self.0, name_cstr.as_ptr(), value).to_result(self)
}
}
pub fn bind_int64(&mut self, index: usize, value: i64) -> Result<&mut Self> {
unsafe { cass_statement_bind_int64(self.0, index, value).to_result(self) }
}
pub fn bind_int64_by_name(&mut self, name: &str, value: i64) -> Result<&mut Self> {
unsafe {
let name_cstr = CString::new(name)?;
cass_statement_bind_int64_by_name(self.0, name_cstr.as_ptr(), value).to_result(self)
}
}
pub fn bind_float(&mut self, index: usize, value: f32) -> Result<&mut Self> {
unsafe { cass_statement_bind_float(self.0, index, value).to_result(self) }
}
pub fn bind_float_by_name(&mut self, name: &str, value: f32) -> Result<&mut Self> {
unsafe {
let name_cstr = CString::new(name)?;
cass_statement_bind_float_by_name(self.0, name_cstr.as_ptr(), value).to_result(self)
}
}
pub fn bind_double(&mut self, index: usize, value: f64) -> Result<&mut Self> {
unsafe { cass_statement_bind_double(self.0, index, value).to_result(self) }
}
pub fn bind_double_by_name(&mut self, name: &str, value: f64) -> Result<&mut Self> {
unsafe {
let name_cstr = CString::new(name)?;
cass_statement_bind_double_by_name(self.0, name_cstr.as_ptr(), value).to_result(self)
}
}
pub fn bind_bool(&mut self, index: usize, value: bool) -> Result<&mut Self> {
unsafe {
cass_statement_bind_bool(self.0, index, if value { cass_true } else { cass_false })
.to_result(self)
}
}
pub fn bind_bool_by_name(&mut self, name: &str, value: bool) -> Result<&mut Self> {
unsafe {
let name_cstr = CString::new(name)?;
cass_statement_bind_bool_by_name(
self.0,
name_cstr.as_ptr(),
if value { cass_true } else { cass_false },
)
.to_result(self)
}
}
pub fn bind_string(&mut self, index: usize, value: &str) -> Result<&mut Self> {
unsafe {
let value_cstr = CString::new(value)?;
cass_statement_bind_string(self.0, index, value_cstr.as_ptr()).to_result(self)
}
}
pub fn bind_string_by_name(&mut self, name: &str, value: &str) -> Result<&mut Self> {
unsafe {
let name_cstr = CString::new(name)?;
let value_cstr = CString::new(value)?;
cass_statement_bind_string_by_name(self.0, name_cstr.as_ptr(), value_cstr.as_ptr())
.to_result(self)
}
}
pub fn bind_bytes(&mut self, index: usize, value: Vec<u8>) -> Result<&mut Self> {
unsafe {
cass_statement_bind_bytes(self.0, index, value.as_ptr(), value.len()).to_result(self)
}
}
pub fn bind_bytes_by_name(&mut self, name: &str, mut value: Vec<u8>) -> Result<&mut Self> {
unsafe {
let name_cstr = CString::new(name)?;
cass_statement_bind_bytes_by_name(
self.0,
name_cstr.as_ptr(),
value.as_mut_ptr(),
value.len(),
)
.to_result(self)
}
}
pub fn bind_uuid(&mut self, index: usize, value: Uuid) -> Result<&mut Self> {
unsafe { cass_statement_bind_uuid(self.0, index, value.inner()).to_result(self) }
}
pub fn bind_uuid_by_name(&mut self, name: &str, value: Uuid) -> Result<&mut Self> {
unsafe {
let name_cstr = CString::new(name)?;
cass_statement_bind_uuid_by_name(self.0, name_cstr.as_ptr(), value.inner())
.to_result(self)
}
}
pub fn bind_inet(&mut self, index: usize, value: Inet) -> Result<&mut Self> {
unsafe { cass_statement_bind_inet(self.0, index, value.inner()).to_result(self) }
}
pub fn bind_inet_by_name(&mut self, name: &str, value: Inet) -> Result<&mut Self> {
unsafe {
let name_cstr = CString::new(name)?;
cass_statement_bind_inet_by_name(self.0, name_cstr.as_ptr(), value.inner())
.to_result(self)
}
}
pub fn bind_map(&mut self, index: usize, map: Map) -> Result<&mut Self> {
unsafe { cass_statement_bind_collection(self.0, index, map.inner()).to_result(self) }
}
pub fn bind_map_by_name(&mut self, name: &str, map: Map) -> Result<&mut Self> {
unsafe {
let name_cstr = CString::new(name)?;
cass_statement_bind_collection_by_name(self.0, name_cstr.as_ptr(), map.inner())
.to_result(self)
}
}
pub fn bind_set(&mut self, index: usize, collection: Set) -> Result<&mut Self> {
unsafe { cass_statement_bind_collection(self.0, index, collection.inner()).to_result(self) }
}
pub fn bind_set_by_name(&mut self, name: &str, collection: Set) -> Result<&mut Self> {
unsafe {
let name_cstr = CString::new(name)?;
cass_statement_bind_collection_by_name(self.0, name_cstr.as_ptr(), collection.inner())
.to_result(self)
}
}
pub fn bind_list(&mut self, index: usize, collection: List) -> Result<&mut Self> {
unsafe { cass_statement_bind_collection(self.0, index, collection.inner()).to_result(self) }
}
pub fn bind_list_by_name(&mut self, name: &str, collection: List) -> Result<&mut Self> {
unsafe {
let name_cstr = CString::new(name)?;
cass_statement_bind_collection_by_name(self.0, name_cstr.as_ptr(), collection.inner())
.to_result(self)
}
}
pub fn bind_tuple(&mut self, index: usize, value: Tuple) -> Result<&mut Self> {
unsafe { cass_statement_bind_tuple(self.0, index, value.inner()).to_result(self) }
}
pub fn bind_tuple_by_name(&mut self, name: &str, value: Tuple) -> Result<&mut Self> {
unsafe {
let name_cstr = CString::new(name)?;
cass_statement_bind_tuple_by_name(self.0, name_cstr.as_ptr(), value.inner())
.to_result(self)
}
}
pub fn bind_user_type(&mut self, index: usize, value: &UserType) -> Result<&mut Self> {
unsafe { cass_statement_bind_user_type(self.0, index, value.inner()).to_result(self) }
}
pub fn bind_user_type_by_name(&mut self, name: &str, value: &UserType) -> Result<&mut Self> {
unsafe {
let name_cstr = CString::new(name)?;
cass_statement_bind_user_type_by_name(self.0, name_cstr.as_ptr(), value.inner())
.to_result(self)
}
}
}