use std::fmt;
use crate::{SdkError, wit};
pub struct Connection(pub(crate) wit::PgConnection);
impl fmt::Debug for Connection {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("Connection { ... }")
}
}
impl From<wit::PgConnection> for Connection {
fn from(conn: wit::PgConnection) -> Self {
Self(conn)
}
}
pub struct Transaction {
pub(crate) inner: wit::PgTransaction,
committed_or_rolled_back: bool,
}
impl From<wit::PgTransaction> for Transaction {
fn from(inner: wit::PgTransaction) -> Self {
Self {
inner,
committed_or_rolled_back: false,
}
}
}
impl fmt::Debug for Transaction {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("Transaction { ... }")
}
}
impl Transaction {
pub fn commit(mut self) -> Result<(), SdkError> {
self.committed_or_rolled_back = true;
self.inner.commit().map_err(SdkError::from)
}
pub fn rollback(mut self) -> Result<(), SdkError> {
self.committed_or_rolled_back = true;
self.inner.rollback().map_err(SdkError::from)
}
}
impl Drop for Transaction {
fn drop(&mut self) {
if !self.committed_or_rolled_back {
self.inner.rollback().unwrap()
}
}
}
#[derive(Clone, Copy, Debug)]
pub enum ConnectionLike<'a> {
Connection(&'a Connection),
Transaction(&'a Transaction),
}
impl<'a> From<&'a Connection> for ConnectionLike<'a> {
fn from(connection: &'a Connection) -> Self {
ConnectionLike::Connection(connection)
}
}
impl<'a> From<&'a Transaction> for ConnectionLike<'a> {
fn from(transaction: &'a Transaction) -> Self {
ConnectionLike::Transaction(transaction)
}
}
impl ConnectionLike<'_> {
pub(crate) fn query<'a>(
&'a self,
query: &'a str,
params: (&[wit::PgBoundValue], &[wit::PgValue]),
) -> Result<Vec<wit::PgRow>, SdkError> {
match self {
ConnectionLike::Connection(connection) => connection.0.query(query, params).map_err(SdkError::from),
ConnectionLike::Transaction(transaction) => transaction.inner.query(query, params).map_err(SdkError::from),
}
}
pub(crate) fn execute<'a>(
&'a self,
query: &'a str,
params: (&[wit::PgBoundValue], &[wit::PgValue]),
) -> Result<u64, SdkError> {
match self {
ConnectionLike::Connection(connection) => connection.0.execute(query, params).map_err(SdkError::from),
ConnectionLike::Transaction(transaction) => {
transaction.inner.execute(query, params).map_err(SdkError::from)
}
}
}
}