use common::{error, version};
use error::{Error, ErrorKind, Result};
use odpi::constants::{DPI_MAJOR_VERSION, DPI_MINOR_VERSION};
use odpi::externs;
use odpi::opaque::ODPIContext;
use odpi::structs::{
ODPICommonCreateParams, ODPIConnCreateParams, ODPIErrorInfo, ODPIPoolCreateParams,
ODPISubscrCreateParams, ODPIVersionInfo,
};
use slog::Logger;
use std::convert::TryFrom;
use std::ptr::{self, Unique};
use util::ODPIStr;
pub mod params;
use self::params::{CommonCreate, ConnCreate, PoolCreate, SubscrCreate};
#[derive(Clone, Setters)]
pub struct Context {
inner: Unique<ODPIContext>,
#[set = "pub"]
stdout: Option<Logger>,
#[set = "pub"]
stderr: Option<Logger>,
}
impl Context {
#[doc(hidden)]
pub fn inner(&self) -> *mut ODPIContext {
self.inner.as_ptr()
}
pub fn create() -> Result<Self> {
let mut ctxt = ptr::null_mut();
let mut err: ODPIErrorInfo = Default::default();
try_dpi!(
externs::dpiContext_create(DPI_MAJOR_VERSION, DPI_MINOR_VERSION, &mut ctxt, &mut err),
Ok(TryFrom::try_from(ctxt)?),
"dpiContext_create".to_string()
)
}
#[cfg(feature = "trace")]
pub fn get_client_version(&self) -> Result<version::Info> {
logperf!(
self.base_get_client_version(),
self.stdout,
"get_client_version"
)
}
#[cfg(not(feature = "trace"))]
pub fn get_client_version(&self) -> Result<version::Info> {
self.base_get_client_version()
}
fn base_get_client_version(&self) -> Result<version::Info> {
let mut version_info: ODPIVersionInfo = Default::default();
try_dpi!(
externs::dpiContext_getClientVersion(self.inner.as_ptr(), &mut version_info),
Ok(version_info.into()),
ErrorKind::Context("dpiContext_getClientVersion".to_string())
)
}
pub fn get_error(&self) -> error::Info {
let mut error_info: ODPIErrorInfo = Default::default();
unsafe {
externs::dpiContext_getError(self.inner.as_ptr(), &mut error_info);
error_info.into()
}
}
pub fn init_common_create_params(&self) -> Result<CommonCreate> {
let mut ccp: ODPICommonCreateParams = Default::default();
try_dpi!(
externs::dpiContext_initCommonCreateParams(self.inner.as_ptr(), &mut ccp),
{
let mut driver_name = String::from(env!("CARGO_PKG_NAME"));
driver_name.push(' ');
driver_name.push_str(env!("CARGO_PKG_VERSION"));
let driver_name_s: ODPIStr = TryFrom::try_from(driver_name)?;
ccp.driver_name = driver_name_s.ptr();
ccp.driver_name_length = driver_name_s.len();
Ok(ccp.into())
},
ErrorKind::Context("dpiContext_initCommonCreateParams".to_string())
)
}
pub fn init_conn_create_params(&self) -> Result<ConnCreate> {
let mut conn: ODPIConnCreateParams = Default::default();
try_dpi!(
externs::dpiContext_initConnCreateParams(self.inner.as_ptr(), &mut conn),
Ok(ConnCreate::new(conn)),
ErrorKind::Context("dpiContext_initConnCreateParams".to_string())
)
}
pub fn init_pool_create_params(&self) -> Result<PoolCreate> {
let mut pool: ODPIPoolCreateParams = Default::default();
try_dpi!(
externs::dpiContext_initPoolCreateParams(self.inner.as_ptr(), &mut pool),
Ok(PoolCreate::new(pool)),
ErrorKind::Context("dpiContext_initPoolCreateParams".to_string())
)
}
pub fn init_subscr_create_params(&self) -> Result<SubscrCreate> {
let mut subscr: ODPISubscrCreateParams = Default::default();
try_dpi!(
externs::dpiContext_initSubscrCreateParams(self.inner.as_ptr(), &mut subscr),
Ok(SubscrCreate::new(subscr)),
ErrorKind::Context("dpiContext_initSubscrCreateParams".to_string())
)
}
}
impl TryFrom<*mut ODPIContext> for Context {
type Error = Error;
fn try_from(inner: *mut ODPIContext) -> Result<Self> {
let ctxt = Unique::new(inner).ok_or_else(|| ErrorKind::Context("try_from".to_string()))?;
Ok(Self {
inner: ctxt,
stdout: None,
stderr: None,
})
}
}
impl Drop for Context {
fn drop(&mut self) {
if !self.inner.as_ptr().is_null() {
unsafe {
externs::dpiContext_destroy(self.inner.as_ptr());
}
}
}
}