use sqlx::mysql::MySqlPoolOptions; use sqlx::mysql::MySqlPool; use dotenvy::dotenv_override; use std::collections::HashMap; use std::env; // use crate::schema::equipment::dsl::*; // use crate::schema::worker::dsl::*; use crate::models::*; use anyhow::anyhow; pub struct DBOperator{ pool: MySqlPool, } impl DBOperator{ pub async fn new() -> Self{ dotenv_override().ok(); let db_url = env::var("DATABASE_URL").expect("DATABASE_URL установи!"); Self{pool: MySqlPool::connect(&db_url).await.unwrap()} } pub async fn get_position(&self) -> Result, sqlx::Error>{ let rets: Vec = sqlx::query_as:: <_, Position>("SELECT * FROM `position`").fetch_all(&self.pool).await?; Ok(rets) } pub async fn get_workers(&self) -> Result, sqlx::Error>{ let pre_rets: Vec = sqlx::query_as::<_, WorkerRow>("SELECT * FROM `worker`").fetch_all(&self.pool).await?; let mut rets:Vec = Vec::new(); let pos = self.get_position().await.unwrap(); for worker in pre_rets{ let mut ppos = Position::default(); for position in pos.clone(){ if position.id == worker.position_id{ ppos = position.clone(); break; } } rets.push(Worker{ id: worker.id, full_name: worker.full_name, hire_date: worker.hire_date, position: ppos, is_fired: worker.is_fired }); } Ok(rets) } pub async fn get_equipment(&self) -> Result,sqlx::Error>{ let pre_rets = sqlx::query_as::<_, EquipmentRow>("SELECT * FROM `equipment`").fetch_all(&self.pool).await?; let mut rets: Vec = Vec::new(); let workers = self.get_workers().await?; for eq in pre_rets{ let mut pworker = Worker::default(); for worker in workers.clone(){ if worker.id == eq.worker_id{ pworker = worker.clone(); break; } } rets.push(Equipment { id: eq.id, name: eq.name, inv_number: eq.inv_number, maintenance_date: eq.maintenance_date, worker: pworker }); } Ok(rets) } pub async fn get_mcat(&self) -> Result,sqlx::Error>{ let rets = sqlx::query_as::<_, MaterialCategory>("SELECT * FROM `material_category`").fetch_all(&self.pool).await?; Ok(rets) } pub async fn get_materials(&self) -> Result, sqlx::Error>{ let mats = sqlx::query_as::<_,MaterialRow>("SELECT * FROM `material`").fetch_all(&self.pool).await?; let cats = self.get_mcat().await?; let cat_map : HashMap<_, MaterialCategory> = cats .into_iter() .map(|cat| (cat.id, cat)) .collect(); let mut rets = Vec::with_capacity(mats.len()); for mat in mats{ let cat = cat_map .get(&mat.category_id) .expect("Никто не знает как, но БД не смогла связать материал с его категорией. Заставьте разраба это починить.") .clone(); rets.push(Material{ id: mat.id, name: mat.name, quantity: mat.quantity, category: cat, }); } Ok(rets) } pub async fn check_worker(&self, worker: Worker) -> Result{ let ret = sqlx::query(&format!("SELECT * FROM `worker` WHERE full_name = {}, position_id = {}, hire_date = {}", worker.full_name, worker.position.id, worker.hire_date.to_string())).fetch_all(&self.pool).await?; if ret.len() > 0{ return Ok(true) } Ok(false) } pub async fn add_worker(&self, worker: Worker) -> Result{ // sqlx::query!("INSERT INTO Brewery.worker (id, position_id, hire_date, is_fired, full_name) VALUES(0, ?, ?, ?, ?);",worker.position.id, worker.hire_date ,worker.is_fired,worker.full_name) match sqlx::query("INSERT INTO Brewery.worker (id, position_id, hire_date, is_fired, full_name) VALUES(0, ?, ?, ?, ?);") .bind(worker.position.id) .bind(worker.hire_date) .bind(worker.is_fired) .bind(worker.full_name) .execute(&self.pool) .await { Ok(_) =>{ return Ok(true) }, Err(_) =>{ Ok(false) } } } pub async fn add_position(&self, position: Position) -> Result{ match sqlx::query("INSERT INTO Brewery.`position` (id, name, wage) VALUES(0, ?, ?);") .bind(position.name) .bind(position.wage) .execute(&self.pool) .await{ Ok(_)=>{ Ok(true) }, Err(_)=>{ Ok(false) } } } pub async fn add_material_category(&self, mat_cat: MaterialCategory) -> Result{ match sqlx::query("INSERT INTO Brewery.`material_category` (id, name) VALUES (0, ?)") .bind(mat_cat.name) .execute(&self.pool) .await{ Ok(_)=>{ Ok(true) }, Err(_)=>{ Ok(false) } } } pub async fn add_material(&self, mat: MaterialRow) -> Result{ match sqlx::query("INSERT INTO Brewery.material (id, name, quantity, category_id) VALUES(0, ?, ?, ?);") .bind(mat.name) .bind(mat.quantity) .bind(mat.category_id) .execute(&self.pool) .await{ Ok(_)=>{ Ok(true) }, Err(_)=>{ Ok(false) } } } pub async fn delete_position(&self, position: Position) -> Result{ match sqlx::query("DELETE FROM Brewery.`position` WHERE id = ?;") .bind(position.id) .execute(&self.pool) .await{ Ok(_)=>{ Ok(true) }, Err(_)=>{ Ok(false) } } } pub async fn delete_material_category(&self, mat_cat: MaterialCategory) -> Result{ match sqlx::query("DELETE FROM Brewery.`material_category` WHERE id = ?;") .bind(mat_cat.id) .execute(&self.pool) .await{ Ok(_) =>{ Ok(true) }, Err(_)=>{ Ok(false) } } } pub async fn delete_material(&self, mat: MaterialRow) -> Result{ match sqlx::query("DELETE FROM Brewery.`material` WHERE id = ?;") .bind(mat.id) .execute(&self.pool) .await{ Ok(_) =>{ Ok(true) }, Err(_)=>{ Ok(false) } } } pub async fn update_worker(&self, worker: Worker) -> Result{ match sqlx::query("UPDATE Brewery.worker SET position_id=?, hire_date=?, is_fired=?, full_name=? WHERE id=?;") .bind(worker.position.id) .bind(worker.hire_date) .bind(worker.is_fired) .bind(worker.full_name) .bind(worker.id) .execute(&self.pool) .await{ Ok(_) =>{ Ok(true) }, Err(_)=>{ Ok(false) } } } pub async fn update_material_category(&self, mat_cat: MaterialCategory) -> Result{ match sqlx::query("UPDATE Brewery.`material_category` SET name=? WHERE id=?;") .bind(mat_cat.name) .bind(mat_cat.id) .execute(&self.pool) .await{ Ok(_) =>{ Ok(true) }, Err(_)=>{ Ok(false) } } } pub async fn update_material(&self, mat: MaterialRow) -> Result{ match sqlx::query("UPDATE Brewery.material SET name=?, quantity=?, category_id=? WHERE id=?;") .bind(mat.name) .bind(mat.quantity) .bind(mat.category_id) .bind(mat.id) .execute(&self.pool) .await{ Ok(_) =>{ Ok(true) }, Err(_)=>{ Ok(false) } } } pub async fn get_worker_by_id(&self, worker_id:i32) -> Result{ let preret = sqlx::query_as::<_, WorkerRow>("SELECT * FROM `worker` WHERE id = ?;").bind(worker_id).fetch_all(&self.pool).await?; let poses = self.get_position().await?; let ret = Ok(Worker{ id: preret[0].id, full_name: preret[0].full_name.clone(), hire_date: preret[0].hire_date, is_fired: preret[0].is_fired, position: poses.iter().find(|&pos| &pos.id == &preret[0].position_id).unwrap().clone(), }); ret } } pub async fn estabilish_connection() -> Result<(), sqlx::Error>{ dotenv_override().ok(); let db_url = env::var("DATABASE_URL").expect("DATABASE_URL установи!"); let _pool = MySqlPoolOptions::new() .max_connections(5) .connect(&db_url).await?; Ok(()) }