extern crate odbc_api;
use odbc_api::Environment;
extern crate r2d2;
#[macro_use]
extern crate lazy_static;
extern crate crossbeam_queue;
extern crate thiserror;
pub use odbc_api::*;
#[cfg(feature = "rocket_pooling")]
extern crate rocket_sync_db_pools;
#[cfg(feature = "rocket_pooling")]
use rocket_sync_db_pools::{Config, PoolResult, Poolable};
#[cfg(feature = "rocket_pooling")]
extern crate rocket;
#[cfg(feature = "rocket_pooling")]
use rocket::{Build, Rocket};
use std::sync::Arc;
mod pool;
use pool::{ODBCConnection, SharedPool};
#[derive(Clone)]
pub struct ODBCConnectionManager {
pub(crate) shared: Arc<SharedPool>,
}
lazy_static! {
static ref ENV: Environment = Environment::new().unwrap();
}
impl ODBCConnectionManager {
pub fn new<S: Into<String>>(connection_string: S, limit: u32) -> ODBCConnectionManager {
ODBCConnectionManager {
shared: SharedPool::new_arc(connection_string.into(), limit),
}
}
pub fn aquire(&self) -> ODBCConnection {
self.shared.aquire().unwrap()
}
}
impl r2d2::ManageConnection for ODBCConnectionManager {
type Connection = ODBCConnection;
type Error = pool::OdbcError;
fn connect(&self) -> std::result::Result<Self::Connection, Self::Error> {
self.shared.aquire()
}
fn is_valid(&self, conn: &mut Self::Connection) -> std::result::Result<(), Self::Error> {
#[cfg(feature = "hfsql")]
conn.execute("SELECT CURRENT_DATE FROM DUAL;", ())?;
#[cfg(not(feature = "hfsql"))]
conn.execute("SELECT 1;", ())?;
Ok(())
}
fn has_broken(&self, _conn: &mut Self::Connection) -> bool {
false
}
}
#[cfg(feature = "rocket_pooling")]
impl Poolable for ODBCConnection {
type Manager = ODBCConnectionManager;
type Error = std::convert::Infallible;
fn pool(db_name: &str, rocket: &Rocket<Build>) -> PoolResult<Self> {
let config = Config::from(db_name, rocket)?;
let manager = ODBCConnectionManager::new(&config.url, config.pool_size);
Ok(r2d2::Pool::builder()
.max_size(config.pool_size)
.build(manager)?)
}
}