use nodedb_types::error::{ErrorDetails, NodeDbError, NodeDbResult};
use nodedb_types::result::QueryResult;
use super::super::pool::{Pool, PoolConfig};
pub struct NativeClient {
pub(super) pool: Pool,
}
impl NativeClient {
pub fn new(config: PoolConfig) -> Self {
Self {
pool: Pool::new(config),
}
}
pub fn connect(addr: &str) -> Self {
Self::new(PoolConfig {
addr: addr.to_string(),
..Default::default()
})
}
pub async fn query(&self, sql: &str) -> NodeDbResult<QueryResult> {
let mut conn = self.pool.acquire().await?;
match conn.execute_sql(sql).await {
Ok(r) => Ok(r),
Err(e) if is_connection_error(&e) => {
drop(conn);
let mut conn = self.pool.acquire().await?;
conn.execute_sql(sql).await
}
Err(e) => Err(e),
}
}
pub async fn ddl(&self, sql: &str) -> NodeDbResult<QueryResult> {
let mut conn = self.pool.acquire().await?;
match conn.execute_ddl(sql).await {
Ok(r) => Ok(r),
Err(e) if is_connection_error(&e) => {
drop(conn);
let mut conn = self.pool.acquire().await?;
conn.execute_ddl(sql).await
}
Err(e) => Err(e),
}
}
pub async fn begin(&self) -> NodeDbResult<()> {
let mut conn = self.pool.acquire().await?;
conn.begin().await
}
pub async fn commit(&self) -> NodeDbResult<()> {
let mut conn = self.pool.acquire().await?;
conn.commit().await
}
pub async fn rollback(&self) -> NodeDbResult<()> {
let mut conn = self.pool.acquire().await?;
conn.rollback().await
}
pub async fn set_parameter(&self, key: &str, value: &str) -> NodeDbResult<()> {
let mut conn = self.pool.acquire().await?;
conn.set_parameter(key, value).await
}
pub async fn show_parameter(&self, key: &str) -> NodeDbResult<String> {
let mut conn = self.pool.acquire().await?;
conn.show_parameter(key).await
}
pub async fn ping(&self) -> NodeDbResult<()> {
let mut conn = self.pool.acquire().await?;
conn.ping().await
}
}
pub(super) fn is_connection_error(e: &NodeDbError) -> bool {
matches!(
e.details(),
ErrorDetails::SyncConnectionFailed | ErrorDetails::Storage { .. }
)
}