mod conn_impl;
pub(crate) use conn_impl::ConnImpl;
pub(crate) use conn_impl::ConnImplStatus;
use crate::bind_params::BindParameters;
use crate::config::Config;
use crate::cursor::Cursor;
use crate::db_value::ToDbValue;
use crate::end_user_security_context::EndUserSecurityContext;
use crate::error::Error;
use crate::exec_result::ExecResult;
use crate::ora_version::OracleVersion;
use crate::pool::PoolContentsRef;
use crate::row::Row;
use crate::statement::Statement;
pub struct Connection {
conn_impl: Option<ConnImpl>,
pool_contents_ref: Option<PoolContentsRef>,
}
impl Connection {
fn get_impl(&self) -> Result<&ConnImpl, Error> {
if let Some(conn_impl) = &self.conn_impl {
Ok(conn_impl)
} else {
Err(Error::not_connected())
}
}
pub fn close(&mut self) -> Result<(), Error> {
if let Some(pool_contents_ref) = self.pool_contents_ref.take() {
let mut pool_contents = pool_contents_ref.lock().unwrap();
let mut conn_impl = self.conn_impl.take().unwrap();
conn_impl.clear_end_user_security_context()?;
conn_impl.set_returned_to_pool();
pool_contents.return_connection(conn_impl);
Ok(())
} else if let Some(mut conn_impl) = self.conn_impl.take() {
conn_impl.close()
} else {
Err(Error::not_connected())
}
}
pub(crate) fn connect(config: Config) -> Result<Connection, Error> {
let conn_impl = ConnImpl::connect(config)?;
Ok(Connection {
conn_impl: Some(conn_impl),
pool_contents_ref: None,
})
}
pub(crate) fn create_pooled(
conn_impl: ConnImpl,
pool_contents_ref: &PoolContentsRef,
) -> Connection {
Connection {
conn_impl: Some(conn_impl),
pool_contents_ref: Some(pool_contents_ref.clone()),
}
}
pub fn call_timeout(&self) -> Result<Option<std::time::Duration>, Error> {
self.get_impl()?.get_call_timeout()
}
pub fn change_password(
&self,
old_password: &str,
new_password: &str,
) -> Result<(), Error> {
self.get_impl()?.change_password(old_password, new_password)
}
pub fn clear_end_user_security_context(&self) -> Result<(), Error> {
self.get_impl()?.clear_end_user_security_context()
}
pub fn commit(&self) -> Result<(), Error> {
self.get_impl()?.commit()
}
pub fn db_domain(&self) -> Result<&str, Error> {
Ok(self.get_impl()?.get_db_domain())
}
pub fn db_name(&self) -> Result<&str, Error> {
Ok(self.get_impl()?.get_db_name())
}
pub fn execute(
&self,
sql: &str,
params: &[&dyn ToDbValue],
) -> Result<ExecResult, Error> {
self.get_impl()?.execute(sql, params)
}
pub fn execute_batch<'a>(
&self,
sql: &str,
params: impl Into<BindParameters<'a>>,
) -> Result<ExecResult, Error> {
self.get_impl()?.execute_batch(sql, params.into())
}
pub fn execute_named(
&self,
sql: &str,
params: &[(&str, &dyn ToDbValue)],
) -> Result<ExecResult, Error> {
self.get_impl()?.execute_named(sql, params)
}
pub fn instance_name(&self) -> Result<&str, Error> {
Ok(self.get_impl()?.get_instance_name())
}
pub fn last_warning(&self) -> Result<Option<String>, Error> {
Ok(self.get_impl()?.get_last_warning())
}
pub fn max_identifier_length(&self) -> Result<usize, Error> {
Ok(self.get_impl()?.get_max_identifier_length())
}
pub fn max_open_cursors(&self) -> Result<usize, Error> {
Ok(self.get_impl()?.get_max_open_cursors())
}
pub fn ping(&self) -> Result<(), Error> {
self.get_impl()?.ping()
}
pub fn query(
&self,
sql: &str,
params: &[&dyn ToDbValue],
) -> Result<Cursor, Error> {
self.get_impl()?.query(sql, params)
}
#[cfg(feature = "arrow")]
pub fn query_arrow<'a>(
&self,
sql: &str,
params: impl Into<BindParameters<'a>>,
) -> Result<arrow_array::RecordBatch, Error> {
self.get_impl()?.query_arrow(sql, params.into())
}
pub fn query_named(
&self,
sql: &str,
params: &[(&str, &dyn ToDbValue)],
) -> Result<Cursor, Error> {
self.get_impl()?.query_named(sql, params)
}
pub fn query_row(
&self,
sql: &str,
params: &[&dyn ToDbValue],
) -> Result<Row, Error> {
self.get_impl()?.query_row(sql, params)
}
pub fn query_row_named(
&self,
sql: &str,
params: &[(&str, &dyn ToDbValue)],
) -> Result<Row, Error> {
self.get_impl()?.query_row_named(sql, params)
}
pub fn rollback(&self) -> Result<(), Error> {
self.get_impl()?.rollback()
}
pub fn serial_num(&self) -> Result<usize, Error> {
Ok(self.get_impl()?.get_serial_num())
}
pub fn service_name(&self) -> Result<&str, Error> {
Ok(self.get_impl()?.get_service_name())
}
pub fn session_id(&self) -> Result<usize, Error> {
Ok(self.get_impl()?.get_session_id())
}
pub fn set_action(&self, action: &str) -> Result<(), Error> {
self.get_impl()?.set_pending_action(action);
Ok(())
}
pub fn set_call_timeout(
&self,
duration: Option<std::time::Duration>,
) -> Result<(), Error> {
self.get_impl()?.set_call_timeout(duration)
}
pub fn set_client_identifier(
&self,
client_identifier: &str,
) -> Result<(), Error> {
self.get_impl()?
.set_pending_client_identifier(client_identifier);
Ok(())
}
pub fn set_client_info(&self, client_info: &str) -> Result<(), Error> {
self.get_impl()?.set_pending_client_info(client_info);
Ok(())
}
pub fn set_end_user_security_context(
&self,
context: EndUserSecurityContext,
) -> Result<(), Error> {
self.get_impl()?.set_end_user_security_context(context)
}
pub fn set_db_op(&self, db_op: &str) -> Result<(), Error> {
self.get_impl()?.set_pending_db_op(db_op);
Ok(())
}
pub fn set_module(&self, db_op: &str) -> Result<(), Error> {
self.get_impl()?.set_pending_module(db_op);
Ok(())
}
pub fn statement<'sql>(
&self,
sql: &'sql str,
) -> Result<Statement<'sql>, Error> {
Ok(self.get_impl()?.statement(sql))
}
pub fn version(&self) -> Result<OracleVersion, Error> {
Ok(self.get_impl()?.get_server_version())
}
}
impl Drop for Connection {
fn drop(&mut self) {
let _ = self.close();
}
}