use crate::pool::{ODBCConnection, OdbcError};
use crate::ENV;
use crossbeam_queue::ArrayQueue;
pub use odbc_api::*;
use std::sync::{Arc, Mutex, RwLock};
pub(crate) struct SharedPool {
pub(crate) pool: Mutex<ArrayQueue<odbc_api::force_send_sync::Send<Connection<'static>>>>,
pub(crate) connection_string: RwLock<String>,
}
impl SharedPool {
pub(crate) fn new_arc(connection_string: String, limit: u32) -> Arc<Self> {
let pool = Self {
pool: Mutex::new(ArrayQueue::new(limit as usize)),
connection_string: RwLock::new(connection_string),
};
Arc::new(pool)
}
pub(crate) fn aquire(self: &Arc<Self>) -> Result<ODBCConnection, OdbcError> {
let pool = self
.pool
.lock()
.map_err(|p| OdbcError::LockError { msg: p.to_string() })?;
if let Some(connection) = pool.pop() {
return Ok(ODBCConnection::new(Arc::clone(self), connection));
}
let conn_str = self
.connection_string
.read()
.map_err(|p| OdbcError::LockError { msg: p.to_string() })?;
let env = &ENV;
let conn = env.connect_with_connection_string(conn_str.as_str())?;
let connection = unsafe { conn.promote_to_send() };
Ok(ODBCConnection::new(Arc::clone(self), connection))
}
}