#![allow(non_camel_case_types)]
#![allow(dead_code)]
#![allow(missing_copy_implementations)]
use crate::cassandra::custom_payload::CustomPayloadResponse;
use crate::cassandra::error::*;
use crate::cassandra::future::CassFuture;
use crate::cassandra::metrics::SessionMetrics;
use crate::cassandra::prepared::PreparedStatement;
use crate::cassandra::result::CassResult;
use crate::cassandra::schema::schema_meta::SchemaMeta;
use crate::cassandra::statement::Statement;
use crate::cassandra::util::{Protected, ProtectedInner};
use crate::{cassandra::batch::Batch, BatchType};
use crate::cassandra_sys::cass_session_execute;
use crate::cassandra_sys::cass_session_execute_batch;
use crate::cassandra_sys::cass_session_free;
use crate::cassandra_sys::cass_session_get_metrics;
use crate::cassandra_sys::cass_session_get_schema_meta;
use crate::cassandra_sys::cass_session_new;
use crate::cassandra_sys::cass_session_prepare_n;
use crate::cassandra_sys::CassSession as _Session;
use std::mem;
use std::os::raw::c_char;
use std::sync::Arc;
#[derive(Debug, Eq, PartialEq)]
pub struct SessionInner(*mut _Session);
unsafe impl Send for SessionInner {}
unsafe impl Sync for SessionInner {}
impl SessionInner {
fn new(inner: *mut _Session) -> Arc<Self> {
Arc::new(Self(inner))
}
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct Session(pub Arc<SessionInner>);
impl ProtectedInner<*mut _Session> for SessionInner {
fn inner(&self) -> *mut _Session {
self.0
}
}
impl ProtectedInner<*mut _Session> for Session {
fn inner(&self) -> *mut _Session {
self.0.inner()
}
}
impl Protected<*mut _Session> for Session {
fn build(inner: *mut _Session) -> Self {
if inner.is_null() {
panic!("Unexpected null pointer")
};
Session(SessionInner::new(inner))
}
}
impl Drop for SessionInner {
fn drop(&mut self) {
unsafe { cass_session_free(self.0) }
}
}
impl Default for Session {
fn default() -> Session {
Session::new()
}
}
impl Session {
pub(crate) fn new() -> Session {
unsafe { Session(SessionInner::new(cass_session_new())) }
}
pub async fn prepare(&self, query: impl AsRef<str>) -> Result<PreparedStatement> {
let query = query.as_ref();
let prepare_future = {
let query_ptr = query.as_ptr() as *const c_char;
CassFuture::build(self.clone(), unsafe {
cass_session_prepare_n(self.inner(), query_ptr, query.len())
})
};
prepare_future.await
}
pub fn statement(&self, query: impl AsRef<str>) -> Statement {
let query = query.as_ref();
let param_count = query.matches('?').count();
Statement::new(self.clone(), query, param_count)
}
pub fn execute_batch(&self, batch: &Batch) -> CassFuture<CassResult> {
let inner_future = unsafe { cass_session_execute_batch(self.inner(), batch.inner()) };
<CassFuture<CassResult>>::build(self.clone(), inner_future)
}
pub fn execute_batch_with_payloads(
&self,
batch: &Batch,
) -> CassFuture<(CassResult, CustomPayloadResponse)> {
let inner_future = unsafe { cass_session_execute_batch(self.inner(), batch.inner()) };
<CassFuture<(CassResult, CustomPayloadResponse)>>::build(self.clone(), inner_future)
}
pub async fn execute(&self, query: impl AsRef<str>) -> Result<CassResult> {
let statement = self.statement(query);
statement.execute().await
}
pub fn batch(&self, batch_type: BatchType) -> Batch {
Batch::new(batch_type, self.clone())
}
pub fn execute_with_payloads(
&self,
statement: &Statement,
) -> CassFuture<(CassResult, CustomPayloadResponse)> {
let inner_future = unsafe { cass_session_execute(self.inner(), statement.inner()) };
<CassFuture<(CassResult, CustomPayloadResponse)>>::build(self.clone(), inner_future)
}
pub fn get_schema_meta(&self) -> SchemaMeta {
unsafe { SchemaMeta::build(cass_session_get_schema_meta(self.inner())) }
}
pub fn get_metrics(&self) -> SessionMetrics {
unsafe {
let mut metrics = mem::zeroed();
cass_session_get_metrics(self.inner(), &mut metrics);
SessionMetrics::build(&metrics)
}
}
}