Skip to main content

monoio_pg/
client.rs

1use crate::connection::Connection;
2use crate::error::Result;
3use bytes::Bytes;
4use std::sync::Arc;
5
6pub struct Client {
7    connection: Connection,
8}
9
10impl Client {
11    pub async fn connect(
12        addr: &str,
13        user: &str,
14        password: Option<&str>,
15        database: Option<&str>,
16    ) -> Result<Self> {
17        let connection = Connection::connect(addr, user, password, database).await?;
18        Ok(Self { connection })
19    }
20
21    pub async fn execute(&mut self, query: &str) -> Result<()> {
22        self.connection.execute(query).await
23    }
24
25    pub async fn query(&mut self, query: &str) -> Result<Vec<Row>> {
26        self.connection.query(query).await
27    }
28}
29
30#[derive(Debug, Clone)]
31pub struct Column {
32    pub name: String,
33    pub table_oid: u32,
34    pub column_id: i16,
35    pub type_oid: u32,
36    pub type_len: i16,
37    pub type_mod: i32,
38    pub format: i16,
39}
40
41use postgres_types::{FromSql, Type};
42
43pub struct Row {
44    pub columns: Arc<Vec<Column>>,
45    pub data: Vec<Option<Bytes>>,
46}
47
48impl Row {
49    pub fn get<'a, T: FromSql<'a>>(&'a self, index: usize) -> Result<T> {
50        let col = self.columns.get(index).ok_or_else(|| {
51            crate::error::Error::Parse(format!("Column index {} out of bounds", index))
52        })?;
53        let bytes = self.get_raw(index);
54
55        let ty = Type::from_oid(col.type_oid).unwrap_or(Type::UNKNOWN);
56
57        match bytes {
58            Some(b) => T::from_sql(&ty, b).map_err(|e| crate::error::Error::Parse(e.to_string())),
59            None => T::from_sql_null(&ty).map_err(|e| crate::error::Error::Parse(e.to_string())),
60        }
61    }
62
63    pub fn get_raw(&self, index: usize) -> Option<&Bytes> {
64        self.data.get(index).and_then(|opt| opt.as_ref())
65    }
66}