use anyhow::bail;
use bms_dtos::MetadataDb;
use tokio_postgres::{Client, Config, NoTls, Row};
type Result<T> = core::result::Result<T, anyhow::Error>;
pub struct AphomieDbClient {
db_client: Client,
}
impl AphomieDbClient {
pub async fn new(host: Option<&str>, port: Option<u16>) -> Result<Self> {
let host = if let Some(v) = host { v } else { "localhost" };
let port = if let Some(v) = port { v } else { 5432 };
let mut config = Config::new();
config
.user("dat7")
.password("dat7")
.dbname("dat7")
.host(host)
.port(port);
let (db_client, connection) = config.connect(NoTls).await?;
tokio::spawn(async move {
if let Err(e) = connection.await {
eprintln!("connection error: {}", e);
}
});
Ok(Self { db_client })
}
pub async fn insert_metadata(&self, metadata: &MetadataDb) -> Result<Vec<MetadataDb>> {
insert_metadata(
&self.db_client,
&metadata.log_id,
&metadata.source,
&metadata.unit,
)
.await
.map(|v| v.iter().map(|r| MetadataDb::from(r)).collect())
}
pub async fn get_metadata_by_source(&self, source: &str) -> Result<Vec<MetadataDb>> {
get_metadata_by_source(&self.db_client, source)
.await
.map(|v| v.iter().map(|r| MetadataDb::from(r)).collect())
}
pub async fn get_all_metadata(&self) -> Result<Vec<MetadataDb>> {
get_all_metadata(&self.db_client)
.await
.map(|v| v.iter().map(|r| MetadataDb::from(r)).collect())
}
}
async fn insert_metadata(
client: &Client,
log_id: &i64,
source: &str,
unit: &str,
) -> Result<Vec<Row>> {
let stmt = "INSERT INTO metadata (log_id, source, unit) VALUES ($1, $2, $3) RETURNING *;";
match client.query(stmt, &[log_id, &source, &unit]).await {
Ok(v) => Ok(v),
Err(e) => {
bail!("error querying database: {e}");
}
}
}
async fn get_metadata_by_source(client: &Client, source: &str) -> Result<Vec<Row>> {
let stmt = "SELECT * FROM metadata WHERE source = $1;";
match client.query(stmt, &[&source]).await {
Ok(v) => Ok(v),
Err(e) => {
bail!("error querying database: {e}");
}
}
}
async fn get_all_metadata(client: &Client) -> Result<Vec<Row>> {
let stmt = "SELECT * FROM metadata;";
match client.query(stmt, &[]).await {
Ok(v) => Ok(v),
Err(e) => {
bail!("error querying database: {e}");
}
}
}