use crate::connection::{ConnectOptions, LogSettings};
use crate::error::Error;
use futures_core::future::BoxFuture;
use log::LevelFilter;
use std::fmt::{self, Debug, Formatter};
use std::str::FromStr;
use std::time::Duration;
use crate::odbc::OdbcConnection;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct OdbcBufferSettings {
pub batch_size: usize,
pub max_column_size: Option<usize>,
}
impl Default for OdbcBufferSettings {
fn default() -> Self {
Self {
batch_size: 64,
max_column_size: None,
}
}
}
#[derive(Clone)]
pub struct OdbcConnectOptions {
pub(crate) conn_str: String,
pub(crate) log_settings: LogSettings,
pub(crate) buffer_settings: OdbcBufferSettings,
}
impl OdbcConnectOptions {
pub fn connection_string(&self) -> &str {
&self.conn_str
}
pub fn buffer_settings(&mut self, settings: OdbcBufferSettings) -> &mut Self {
self.buffer_settings = settings;
self
}
pub fn batch_size(&mut self, batch_size: usize) -> &mut Self {
assert!(batch_size > 0, "batch_size must be greater than 0");
self.buffer_settings.batch_size = batch_size;
self
}
pub fn max_column_size(&mut self, max_column_size: Option<usize>) -> &mut Self {
if let Some(size) = max_column_size {
assert!(size > 0, "max_column_size must be greater than 0");
}
self.buffer_settings.max_column_size = max_column_size;
self
}
pub fn buffer_settings_ref(&self) -> &OdbcBufferSettings {
&self.buffer_settings
}
}
impl Debug for OdbcConnectOptions {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.debug_struct("OdbcConnectOptions")
.field("conn_str", &"<redacted>")
.field("buffer_settings", &self.buffer_settings)
.finish()
}
}
impl FromStr for OdbcConnectOptions {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut t = s.trim();
if let Some(rest) = t.strip_prefix("odbc:") {
t = rest;
}
let conn_str = if t.contains('=') {
t.to_string()
} else {
format!("DSN={}", t)
};
Ok(Self {
conn_str,
log_settings: LogSettings::default(),
buffer_settings: OdbcBufferSettings::default(),
})
}
}
impl ConnectOptions for OdbcConnectOptions {
type Connection = OdbcConnection;
fn connect(&self) -> BoxFuture<'_, Result<Self::Connection, Error>>
where
Self::Connection: Sized,
{
Box::pin(OdbcConnection::establish(self))
}
fn log_statements(&mut self, level: LevelFilter) -> &mut Self {
self.log_settings.log_statements(level);
self
}
fn log_slow_statements(&mut self, level: LevelFilter, duration: Duration) -> &mut Self {
self.log_settings.log_slow_statements(level, duration);
self
}
}