use std::error::Error;
use bb8_postgres::bb8::Pool;
use bb8_postgres::PostgresConnectionManager;
use bb8_postgres::tokio_postgres::{GenericClient, NoTls, Row};
use paperclip::actix::Apiv2Schema;
use serde::{Deserialize, Serialize};
const GET_USER_BY_TELEGRAM_ID: &str = "SELECT employee.id, employee.name, employee.dept_id, employee.post_id, employee.telegram_name, employee.telegram_id FROM rec23.employee employee WHERE employee.telegram_id = $1";
const GET_USER_BY_TELEGRAM_NAME: &str = "SELECT employee.id, employee.name, employee.dept_id, employee.post_id, employee.telegram_name, employee.telegram_id FROM rec23.employee employee WHERE employee.telegram_name = $1";
const GET_USER_BY_ID: &str = "SELECT employee.id, employee.name, employee.dept_id, employee.post_id, employee.telegram_name, employee.telegram_id FROM rec23.employee employee WHERE employee.id = $1";
const GET_DEFAULT_ASSIGNEE_EMP_ID: &str = "SELECT assignee_emp.default_emp_id FROM rec23.assignee_emp assignee_emp WHERE assignee_emp.assignee_id = $1";
const WRITE_TO_DATABASE: &str = "UPDATE rec23.employee SET telegram_id = $2 WHERE id = $1";
const GET: &str = "SELECT id, name, dept_id, post_id, telegram_name, telegram_id FROM rec23.employee";
const DELETE: &str = "DELETE FROM rec23.employee WHERE id = $1";
const UPDATE_TELEGRAM_NAME: &str = "UPDATE rec23.employee SET telegram_id = NULL, telegram_name = $2 WHERE id = $1";
const UPDATE_DEPT: &str = "UPDATE rec23.employee SET dept_id = $2, post_id = $3 WHERE id = $1";
#[derive(Serialize, Deserialize, Apiv2Schema)]
pub struct User {
pub id: i32,
pub name: String,
pub dept_id: Option<i32>,
pub post_id: Option<i32>,
pub telegram_name: Option<String>,
pub telegram_id: Option<i32>
}
impl User {
pub async fn get(pool: &Pool<PostgresConnectionManager<NoTls>>) -> Result<Vec<Self>, Box<dyn Error + Sync + Send>> {
let connection = pool.get().await?;
let rows = connection.query(GET, &[]).await?;
Ok(rows.iter().map(|row|Self::convert_from_row(row)).collect())
}
pub async fn get_user_by_telegram_id(telegram_id: i32, pool: &Pool<PostgresConnectionManager<NoTls>>) -> Result<Option<Self>, Box<dyn Error + Sync + Send>> {
let connection = pool.get().await?;
let client = connection.client();
let row = client.query_opt(GET_USER_BY_TELEGRAM_ID, &[&telegram_id]).await?;
let user = match row {
Some(row) => Some(Self::convert_from_row(&row)),
None => None,
};
Ok(user)
}
pub async fn get_user_by_telegram_name(telegram_name: String, pool: &Pool<PostgresConnectionManager<NoTls>>) -> Result<Option<Self>, Box<dyn Error + Sync + Send>> {
let connection = pool.get().await?;
let client = connection.client();
let row = client.query_opt(GET_USER_BY_TELEGRAM_NAME, &[&telegram_name]).await?;
let user = match row {
Some(row) => Some(Self::convert_from_row(&row)),
None => None,
};
Ok(user)
}
pub async fn get_user_by_id(id: i32, pool: &Pool<PostgresConnectionManager<NoTls>>) -> Result<Option<Self>, Box<dyn Error + Sync + Send>> {
let connection = pool.get().await?;
let client = connection.client();
return match client.query_opt(GET_USER_BY_ID, &[&id]).await? {
Some(value) => Ok(Some(Self::convert_from_row(&value))),
None => Ok(None)
};
}
pub fn convert_from_row(row: &Row) -> Self {
Self {
id: row.get("id"),
name: row.get("name"),
dept_id: row.get("dept_id"),
post_id: row.get("post_id"),
telegram_name: row.get("telegram_name"),
telegram_id: row.get("telegram_id"),
}
}
pub async fn get_default_assignee_emp_id(self, pool: &Pool<PostgresConnectionManager<NoTls>>) -> Result<Option<i32>, Box<dyn Error + Sync + Send>> {
let connection = pool.get().await?;
let client = connection.client();
let row = match client.query_opt(GET_DEFAULT_ASSIGNEE_EMP_ID, &[&self.id]).await? {
Some(row) => row,
None => return Ok(None)
};
Ok(Some(row.get(0)))
}
pub async fn write_to_database(&self, pool: &Pool<PostgresConnectionManager<NoTls>>)->Result<(), Box<dyn Error+Send+Sync>>{
let connection = pool.get().await?;
connection.execute(WRITE_TO_DATABASE, &[&self.id, &self.telegram_id]).await?;
Ok(())
}
pub async fn delete(id: i32, pool: &Pool<PostgresConnectionManager<NoTls>>)->Result<(), Box<dyn Error+Send+Sync>>{
let connection = pool.get().await?;
connection.execute(DELETE, &[&id]).await?;
Ok(())
}
pub async fn update_telegram_tag(&self, pool: &Pool<PostgresConnectionManager<NoTls>>)->Result<(), Box<dyn Error+Send+Sync>>{
let connection = pool.get().await?;
connection.execute(UPDATE_TELEGRAM_NAME, &[&self.id, &self.telegram_name]).await?;
Ok(())
}
pub async fn update_dept(&self, pool: &Pool<PostgresConnectionManager<NoTls>>)->Result<(), Box<dyn Error+Send+Sync>>{
let connection = pool.get().await?;
connection.execute(UPDATE_DEPT, &[&self.id, &self.dept_id, &self.post_id]).await?;
Ok(())
}
}