112 lines
3.4 KiB
Rust

use tokio_postgres::Client as PgClient;
use std::sync::Arc;
use crate::models::client::{BindingClient, Client};
use crate::storages::traits::ClientRepository;
use async_trait::async_trait;
pub struct PostgresClientRepository {
pub connection: Arc<PgClient>
}
#[async_trait]
impl ClientRepository for PostgresClientRepository {
async fn create(&self, client: BindingClient) -> Result<Client, String> {
let result = self.connection.query(
"INSERT INTO Client(name, surname, middlename, phone) \
VALUES ($1, $2, $3, $4) RETURNING *",
&[&client.name, &client.surname, &client.middlename, &client.phone]
).await;
if let Ok(rows) = &result {
let row = rows.get(0).unwrap();
Ok(Client {
id: row.get("id"),
name: row.get("name"),
surname: row.get("surname"),
middlename: row.get("middlename"),
phone: row.get("phone")
})
} else {
Err(result.unwrap_err().to_string())
}
}
async fn read(&self, id: i32) -> Result<Client, String> {
let result= self.connection.query(
"SELECT * FROM Client WHERE id = $1", &[&id]
).await;
if let Ok(rows) = result {
let row = rows.get(0).ok_or("Client not found".to_owned())?;
Ok(Client {
id: row.get("id"),
name: row.get("name"),
surname: row.get("surname"),
middlename: row.get("middlename"),
phone: row.get("phone")
})
} else {
Err(result.unwrap_err().to_string())
}
}
async fn read_all(&self) -> Result<Vec<Client>, String> {
let result = self.connection.query(
"SELECT * FROM Client", &[]
).await;
if let Ok(rows) = result {
Ok(
rows.into_iter().map(|r| Client {
id: r.get("id"),
name: r.get("name"),
surname: r.get("surname"),
middlename: r.get("middlename"),
phone: r.get("phone")
}).collect()
)
} else {
Err(result.unwrap_err().to_string())
}
}
async fn update(&self, id: i32, client: BindingClient) -> Result<Client, String> {
let result = self.connection.query(
"UPDATE Client SET name = $1, surname = $2, middlename = $3, phone = $4 \
WHERE id = $5 RETURNING *",
&[&client.name, &client.surname, &client.middlename, &client.phone, &id]
).await;
if let Ok(rows) = result {
let row = rows.get(0).unwrap();
Ok(Client {
id: row.get("id"),
name: row.get("name"),
surname: row.get("surname"),
middlename: row.get("middlename"),
phone: row.get("phone")
})
} else {
Err(result.unwrap_err().to_string())
}
}
async fn delete(&self, id: i32) -> Result<(), String> {
let result = self.connection.execute(
"DELETE FROM Client WHERE id = $1",
&[&id]
).await;
if let Ok(rows) = result {
if rows == 0 {
Err("Client not found".to_owned())
} else {
Ok(())
}
} else {
Err(result.unwrap_err().to_string())
}
}
}