use super::{
as_handle::AsHandle, drop_handle, error::IntoResult, logging::log_diagnostics, Connection,
Error,
};
use log::debug;
use odbc_sys::{
AttrOdbcVersion, EnvironmentAttribute, HDbc, HEnv, Handle, HandleType, SQLAllocHandle,
SQLSetEnvAttr, SqlReturn,
};
use std::ptr::null_mut;
#[derive(Debug)]
pub struct Environment {
handle: HEnv,
}
unsafe impl Send for Environment {}
unsafe impl Sync for Environment {}
unsafe impl AsHandle for Environment {
fn as_handle(&self) -> Handle {
self.handle as Handle
}
fn handle_type(&self) -> HandleType {
HandleType::Env
}
}
impl Drop for Environment {
fn drop(&mut self) {
unsafe {
drop_handle(self.handle as Handle, HandleType::Env);
}
}
}
impl Environment {
pub unsafe fn new() -> Result<Self, Error> {
let mut handle = null_mut();
let (handle, info) = match SQLAllocHandle(HandleType::Env, null_mut(), &mut handle) {
SqlReturn::ERROR => return Err(Error::NoDiagnostics),
SqlReturn::SUCCESS => (handle, false),
SqlReturn::SUCCESS_WITH_INFO => (handle, true),
other => panic!(
"Unexpected Return value for allocating ODBC Environment: {:?}",
other
),
};
debug!("ODBC Environment created.");
let env = Environment {
handle: handle as HEnv,
};
if info {
log_diagnostics(&env);
}
Ok(env)
}
pub fn declare_version(&self, version: AttrOdbcVersion) -> Result<(), Error> {
unsafe {
SQLSetEnvAttr(
self.handle,
EnvironmentAttribute::OdbcVersion,
version.into(),
0,
)
.into_result(self)
}
}
pub fn allocate_connection(&self) -> Result<Connection, Error> {
let mut handle = null_mut();
unsafe {
SQLAllocHandle(HandleType::Dbc, self.as_handle(), &mut handle).into_result(self)?;
Ok(Connection::new(handle as HDbc))
}
}
pub fn as_raw(&self) -> HEnv {
self.handle
}
}