BreweryControlSystem/code/src/database.rs

269 lines
9.2 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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<Vec<Position>, sqlx::Error>{
let rets: Vec<Position> = sqlx::query_as:: <_, Position>("SELECT * FROM `position`").fetch_all(&self.pool).await?;
Ok(rets)
}
pub async fn get_workers(&self) -> Result<Vec<Worker>, sqlx::Error>{
let pre_rets: Vec<WorkerRow> = sqlx::query_as::<_, WorkerRow>("SELECT * FROM `worker`").fetch_all(&self.pool).await?;
let mut rets:Vec<Worker> = 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<Vec<Equipment>,sqlx::Error>{
let pre_rets = sqlx::query_as::<_, EquipmentRow>("SELECT * FROM `equipment`").fetch_all(&self.pool).await?;
let mut rets: Vec<Equipment> = 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<Vec<MaterialCategory>,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<Vec<Material>, 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<bool, sqlx::Error>{
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<bool,sqlx::Error>{
// 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<bool,sqlx::Error>{
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<bool, sqlx::Error>{
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<bool, sqlx::Error>{
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<bool,sqlx::Error>{
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<bool,sqlx::Error>{
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<bool, sqlx::Error>{
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<bool, sqlx::Error>{
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<bool, sqlx::Error>{
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<bool, sqlx::Error>{
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<Worker, sqlx::Error>{
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(())
}