use crate::bind_params::BindParameters;
use crate::client::ClientRef;
use crate::db_value::ToDbValue;
use crate::error::Error;
use crate::messages::ExecuteMessage;
use crate::messages::FetchMessage;
use crate::metadata::Metadata;
use crate::response::Response;
use crate::row::RowData;
use crate::statement::CachedStatement;
#[derive(Clone)]
pub(crate) struct StatementHolder {
client_ref: ClientRef,
statement: CachedStatement,
}
impl StatementHolder {
pub(crate) fn out_metadata(&self) -> &Vec<Metadata> {
self.statement.out_metadata()
}
fn base_execute(
&mut self,
params: BindParameters,
) -> Result<Response, Error> {
let mut client = self.client_ref.lock().unwrap();
let mut message = ExecuteMessage::new(&mut self.statement, params);
let response = client
.process_message_with_ref(&mut message, Some(&self.client_ref))?;
if self.statement.requires_define() {
self.statement.clear_requires_define();
}
Ok(response)
}
pub(crate) fn execute(
&mut self,
params: &[&dyn ToDbValue],
) -> Result<Response, Error> {
let binding = [params];
let params: BindParameters = binding.as_slice().into();
self.statement.check_binds(¶ms)?;
self.base_execute(params)
}
pub fn execute_batch(
&mut self,
params: BindParameters,
) -> Result<Response, Error> {
self.statement.check_binds(¶ms)?;
if params.num_rows() > 1 && self.statement.requires_single_execute() {
let mut initial_resp = self.base_execute(params.slice(0, 1))?;
let mut final_resp =
self.base_execute(params.slice(1, params.num_rows() - 1))?;
final_resp.transfer_info(&mut initial_resp);
Ok(final_resp)
} else {
self.base_execute(params)
}
}
pub(crate) fn execute_named(
&mut self,
named_params: &[(&str, &dyn ToDbValue)],
) -> Result<Response, Error> {
let checked_params = self.statement.check_named_binds(named_params)?;
let binding = [checked_params.as_slice()];
let params: BindParameters = binding.as_slice().into();
self.statement.check_binds(¶ms)?;
self.base_execute(params)
}
pub(crate) fn fetch(
&self,
last_row: Option<RowData>,
) -> Result<Response, Error> {
let mut message = FetchMessage::new(&self.statement, last_row);
self.client_ref
.lock()
.unwrap()
.process_message_with_ref(&mut message, Some(&self.client_ref))
}
pub(crate) fn new(
client_ref: ClientRef,
statement: CachedStatement,
) -> StatementHolder {
StatementHolder {
client_ref,
statement,
}
}
pub(crate) fn sql(&self) -> &str {
self.statement.sql()
}
}
impl Drop for StatementHolder {
fn drop(&mut self) {
let mut client = self.client_ref.lock().unwrap();
client.return_statement(&self.statement);
}
}