На маленьком плоту сквозь бури, дождь и грозы

Взяв только сны и грёзы, и детскую мечту
Я тихо уплыву, лишь в дом проникнет полночь
Чтоб рифмами наполнить мир, в котором я живу
master
Алексей Алексей 2026-06-03 19:23:50 +10:00
parent 748b06b421
commit 14c9038df2
4 changed files with 419 additions and 273 deletions

1
code/Cargo.lock generated
View File

@ -742,6 +742,7 @@ name = "code"
version = "0.1.0"
dependencies = [
"anyhow",
"bigdecimal",
"chrono",
"dotenvy",
"eframe",

View File

@ -5,6 +5,7 @@ edition = "2024"
[dependencies]
anyhow = "1.0.102"
bigdecimal = "0.4.10"
chrono = { version = "0.4.44", features = ["serde"] }
dotenvy = "0.15.7"
eframe = "0.34.2"

View File

@ -1,4 +1,4 @@
use std::{collections::HashMap, ops::Deref, sync::Arc};
use std::{collections::HashMap, ops::Deref, str::FromStr, sync::Arc};
use crate::{
database::DBOperator,
@ -153,11 +153,28 @@ impl Default for MainTabViewer {
rt,
is_dark_theme: true,
interface_scale_ratio: 1.2,
equipment_modal_state: ModalWinState {
is_open: false,
can_finish: false,
data: HashMap::from([
("id".to_owned(), String::new()),
("inv_number".to_owned(), String::new()),
("maintenance_date".to_owned(), String::new()),
("worker_id".to_owned(), String::new()),
]),
status: ModalStatus::Add,
},
}
}
}
impl MainTabViewer {
fn show_equipment(&mut self, ui: &mut egui::Ui) {
ui.horizontal(|ui| {
if ui.button("Добавить").clicked() {}
if ui.button("Редактировать").clicked() {}
if ui.button("Удалить").clicked() {}
});
let mut table = TableBuilder::new(ui)
.striped(true)
.resizable(false)
@ -167,6 +184,7 @@ impl MainTabViewer {
.column(Column::auto())
.column(Column::auto())
.column(Column::auto())
.sense(egui::Sense::click())
.header(30.0, |mut header| {
header.col(|ui| {
ui.heading("ID");
@ -202,6 +220,9 @@ impl MainTabViewer {
row.col(|ui| {
ui.label(eq.maintenance_date.date_naive().to_string());
});
if row.response().double_clicked() {
println!("I love Paris!");
}
});
}
});
@ -278,7 +299,7 @@ impl egui_dock::TabViewer for MainTabViewer {
struct WorkerTabViewer {
db_oper: DBOperator,
workers: Arc<RwLock<Option<Vec<Worker>>>>,
positions: Arc<RwLock<Option<Vec<Position>>>>,
positions: Arc<RwLock<Vec<Position>>>,
show_worker_add_modal: bool,
show_worker_edit_modal: bool,
show_position_add_modal: bool,
@ -297,21 +318,10 @@ struct WorkerTabViewer {
edit_worker_is_fired: bool,
edit_worker_position: Position,
equipment_modal_state: ModalWinState {
is_open: false,
can_finish: false,
data: HashMap::from([
("id".to_owned(), String::new()),
("inv_number".to_owned(), String::new()),
("maintenance_date".to_owned(), String::new()),
("worker_id".to_owned(), String::new()),
]),
status: ModalStatus::Add
},
rt: tokio::runtime::Runtime,
show_position_delete_modal: bool,
delete_position: Position,
process_position_state: ModalWinState,
}
impl WorkerTabViewer {
@ -322,10 +332,10 @@ impl WorkerTabViewer {
)));
}
fn update_positions(&mut self) {
self.positions = Arc::new(RwLock::new(Option::Some(
self.positions = Arc::new(RwLock::new(
self.rt
.block_on(async { self.db_oper.get_position().await.unwrap() }),
)));
));
}
fn show_worker(&mut self, ui: &mut egui::Ui) {
@ -559,90 +569,118 @@ impl WorkerTabViewer {
fn show_position(&mut self, ui: &mut egui::Ui) {
ui.horizontal(|ui| {
if ui.button("Добавить").clicked() {
self.show_position_add_modal = true;
}
if ui.button("Удалить").clicked() {
self.show_position_delete_modal = true;
self.delete_position = self.positions.read().clone().unwrap()[0].clone();
self.update_positions();
self.update_workers();
// self.show_position_add_modal = true;
self.process_position_state.is_open = true;
self.process_position_state.status = ModalStatus::Add;
self.process_position_state
.data
.insert("id".into(), "0".to_string());
self.process_position_state
.data
.insert("name".into(), String::new());
self.process_position_state
.data
.insert("wage".into(), String::from("0"));
}
if ui.button("Обновить").clicked() {
self.update_positions();
}
});
for eq in self.positions.read().clone().unwrap().iter() {
ui.push_id(&eq.name, |ui| {
egui::CollapsingHeader::new(&eq.name)
.default_open(false)
.show(ui, |ui| {
ui.horizontal(|ui| {
ui.monospace("Оклад:");
ui.label(format!("${}", eq.wage));
TableBuilder::new(ui)
.column(Column::auto())
.column(Column::auto())
.column(Column::auto())
.sense(egui::Sense::click())
.header(30.0, |mut header| {
header.col(|ui| {
ui.heading("Название");
});
header.col(|ui| {
ui.heading("Оклад");
});
})
.body(|mut body| {
body.ui_mut().style_mut().interaction.selectable_labels = false;
for pos in self.positions.read().clone().iter() {
body.row(20.0, |mut row| {
row.col(|ui| {
ui.label(pos.name.clone());
});
row.col(|ui| {
ui.label(format!("${}", pos.wage));
});
row.col(|ui| {
let resp = ui.add(egui::Button::new("Удалить"));
if resp.clicked() {
self.process_position_state.is_open = true;
self.process_position_state.status = ModalStatus::Remove;
self.process_position_state
.data
.insert("id".into(), pos.id.to_string());
self.process_position_state
.data
.insert("name".into(), pos.name.clone());
self.process_position_state
.data
.insert("wage".into(), pos.wage.to_string());
}
});
if row.response().double_clicked() {
self.process_position_state.is_open = true;
self.process_position_state.status = ModalStatus::Edit;
self.process_position_state
.data
.insert("id".into(), pos.id.to_string());
self.process_position_state
.data
.insert("name".into(), pos.name.clone());
self.process_position_state
.data
.insert("wage".into(), pos.wage.to_string());
}
});
}
if self.show_position_add_modal {
egui::Modal::new("add_position".into()).show(ui.ctx(), |ui| {
});
if self.process_position_state.is_open {
egui::Modal::new(egui::Id::new("process_worker_pos_modal")).show(ui.ctx(), |ui| {
if ui.button("Закрыть").clicked() {
self.show_position_add_modal = false;
self.process_position_state.is_open = false;
}
let mut size = ui.spacing().interact_size;
size.x = 200.0;
egui::Grid::new("add_pos_grid").show(ui, |ui| {
if self.process_position_state.status != ModalStatus::Remove {
egui::Grid::new("process_worker_pos_grid").show(ui, |ui| {
ui.label("Название");
ui.add_sized(size, |ui: &mut egui::Ui| {
ui.text_edit_singleline(&mut self.add_position_name)
});
let mut name = self.process_position_state.data.get_mut("name").unwrap();
let mut spacing = ui.spacing().interact_size;
spacing.x = 150.0;
ui.add_sized(spacing, |ui: &mut egui::Ui| ui.text_edit_singleline(name));
ui.end_row();
ui.label("Оклад");
ui.text_edit_singleline(&mut self.add_position_wage);
ui.end_row();
let mut wage = self.process_position_state.data.get_mut("wage").unwrap();
ui.text_edit_singleline(wage);
});
let resp = ui.add_enabled(
self.add_position_name.len() > 0 && self.add_position_wage.len() > 0,
egui::Button::new("Добавить"),
);
if resp.clicked() {
self.rt.block_on(async {
self.db_oper
.add_position(Position {
id: 0,
name: self.add_position_name.clone(),
wage: BigDecimal::from(
self.add_position_wage.trim().parse::<i32>().unwrap(),
),
})
.await
.ok();
});
self.update_positions();
self.show_position_add_modal = false;
} else {
ui.label("Вы уверены, что хотите удалить:");
ui.label(format!(
"{}?",
self.process_position_state.data["name"].clone()
));
}
});
let btext: String;
match self.process_position_state.status {
ModalStatus::Add => {
btext = String::from("Добавить");
self.process_position_state.can_finish = true;
}
if self.show_position_delete_modal {
egui::Modal::new("delete_position".into()).show(ui.ctx(), |ui| {
if ui.button("Закрыть").clicked() {
self.show_position_delete_modal = false;
ModalStatus::Edit => {
btext = String::from("Сохранить");
self.process_position_state.can_finish = true;
}
egui::ComboBox::from_label("Должность")
.selected_text(&self.delete_position.name)
.show_ui(ui, |ui| {
self.rt.block_on(async {
for pos in self.positions.read().clone().unwrap().iter() {
ui.selectable_value(
&mut self.delete_position,
pos.clone(),
&pos.name,
);
}
});
});
let can_delete = self
ModalStatus::Remove => {
self.process_position_state.can_finish = self
.workers
.read()
.clone()
@ -652,21 +690,61 @@ impl WorkerTabViewer {
.iter()
.len()
== 0;
if !can_delete {
ui.label(
egui::RichText::new("Есть сотрудники с этой должностью")
.color(egui::Color32::YELLOW),
);
btext = String::from("Удалить");
}
let resp = ui.add_enabled(can_delete, egui::Button::new("Удалить"));
if resp.clicked() {
}
let button = ui.add_enabled(
self.process_position_state.can_finish,
egui::Button::new(btext),
);
if button.clicked() {
match self.process_position_state.status {
ModalStatus::Add => {
let pos = self.process_position_state.data.clone();
self.rt.block_on(async {
self.db_oper
.delete_position(self.delete_position.clone())
.await
.unwrap();
.add_position(Position {
id: pos["id"].parse::<i32>().unwrap(),
name: pos["name"].clone(),
wage: bigdecimal::BigDecimal::from_str(
pos["wage"].as_str(),
)
.unwrap(),
})
.await;
})
}
ModalStatus::Edit => {
let pos = self.process_position_state.data.clone();
self.rt.block_on(async {
self.db_oper
.update_position(Position {
id: pos["id"].parse::<i32>().unwrap(),
name: pos["name"].clone(),
wage: bigdecimal::BigDecimal::from_str(
pos["wage"].as_str(),
)
.unwrap(),
})
.await;
})
}
ModalStatus::Remove => {
let pos = self.process_position_state.data.clone();
self.rt.block_on(async {
self.db_oper
.delete_position(Position {
id: pos["id"].parse::<i32>().unwrap(),
name: String::new(),
wage: BigDecimal::from(0),
})
.await;
});
}
}
self.update_positions();
self.process_position_state.is_open = false;
}
});
}
}
@ -700,13 +778,29 @@ impl Default for WorkerTabViewer {
fn default() -> Self {
let rt = tokio::runtime::Runtime::new().unwrap();
let db_oper = rt.block_on(async { DBOperator::new().await });
let positions = Arc::new(RwLock::new(
rt.block_on(async { db_oper.get_position().await.unwrap() }),
));
let mut pos_map: HashMap<String, String> = HashMap::new();
pos_map.extend(|| -> Vec<(String, String)> {
let pos = positions.read()[0].clone();
vec![
("id".to_string(), pos.id.to_string()),
("name".to_string(), pos.name.clone()),
("wage".to_string(), pos.wage.to_string()),
]
}());
Self {
process_position_state: ModalWinState {
is_open: false,
can_finish: false,
data: pos_map,
status: ModalStatus::Add,
},
workers: Arc::new(RwLock::new(Option::Some(
rt.block_on(async { db_oper.get_workers().await.unwrap() }),
))),
positions: Arc::new(RwLock::new(Option::Some(
rt.block_on(async { db_oper.get_position().await.unwrap() }),
))),
positions: positions,
show_worker_add_modal: false,
show_worker_edit_modal: false,
show_position_add_modal: false,
@ -762,10 +856,6 @@ impl MaterialTabViewer {
self.process_material_state.is_open = true;
self.process_material_state.status = ModalStatus::Add;
}
if ui.button("Редактировать").clicked() {
self.process_material_state.is_open = true;
self.process_material_state.status = ModalStatus::Edit;
}
if ui.button("Удалить").clicked() {
self.process_material_state.is_open = true;
self.process_material_state.status = ModalStatus::Remove;
@ -784,11 +874,8 @@ impl MaterialTabViewer {
.column(Column::auto())
.column(Column::auto())
.column(Column::auto())
.column(Column::auto())
.sense(egui::Sense::click())
.header(20.0, |mut header| {
header.col(|ui| {
ui.heading("ID");
});
header.col(|ui| {
ui.heading("Название");
});
@ -800,12 +887,10 @@ impl MaterialTabViewer {
});
})
.body(|mut body| {
body.ui_mut().style_mut().interaction.selectable_labels = false;
self.rt.block_on(async {
for mat in self.mats.read().clone().iter() {
body.row(30.0, |mut row| {
row.col(|ui| {
ui.label(mat.id.to_string());
});
row.col(|ui| {
ui.label(&mat.name);
});
@ -815,6 +900,22 @@ impl MaterialTabViewer {
row.col(|ui| {
ui.label(mat.quantity.to_string());
});
if row.response().double_clicked() {
self.process_material_state.is_open = true;
self.process_material_state.status = ModalStatus::Edit;
self.process_material_state
.data
.insert("id".into(), mat.id.to_string());
self.process_material_state
.data
.insert("name".into(), mat.name.to_string());
self.process_material_state
.data
.insert("category_id".into(), mat.category.id.to_string());
self.process_material_state
.data
.insert("quantity".into(), mat.quantity.to_string());
}
});
}
})
@ -1068,10 +1169,6 @@ impl MaterialTabViewer {
self.process_mcat_state.is_open = true;
self.process_mcat_state.status = ModalStatus::Add;
}
if ui.button("Редактировать").clicked() {
self.process_mcat_state.is_open = true;
self.process_mcat_state.status = ModalStatus::Edit;
}
if ui.button("Удалить").clicked() {
self.process_mcat_state.is_open = true;
self.process_mcat_state.status = ModalStatus::Remove;
@ -1197,6 +1294,7 @@ impl MaterialTabViewer {
.striped(true)
.column(Column::auto())
.column(Column::auto())
.sense(egui::Sense::click())
.header(20.0, |mut header| {
header.col(|ui| {
ui.heading("ID");
@ -1215,6 +1313,16 @@ impl MaterialTabViewer {
row.col(|ui| {
ui.label(&mcat.name);
});
if row.response().double_clicked() {
self.process_mcat_state.is_open = true;
self.process_mcat_state.status = ModalStatus::Edit;
self.process_mcat_state
.data
.insert("id".into(), mcat.id.to_string());
self.process_mcat_state
.data
.insert("name".into(), mcat.name.clone());
}
});
}
});
@ -1316,7 +1424,7 @@ impl egui_dock::TabViewer for RecipeTabViewer {
self.show_recipe_detail(ui);
}
_ => {
ui.label("Hello!");
ui.label("Помогите!!");
}
}
}

View File

@ -1,6 +1,5 @@
use sqlx::mysql::MySqlPoolOptions;
use sqlx::mysql::MySqlPool;
use sqlx::mysql::MySqlPoolOptions;
use dotenvy::dotenv_override;
use std::collections::HashMap;
@ -17,15 +16,20 @@ 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()}
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?;
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 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 {
@ -36,12 +40,20 @@ impl DBOperator{
break;
}
}
rets.push(Worker{ id: worker.id, full_name: worker.full_name, hire_date: worker.hire_date, position: ppos, is_fired: worker.is_fired });
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 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 {
@ -52,21 +64,29 @@ impl DBOperator{
break;
}
}
rets.push(Equipment { id: eq.id, name: eq.name, inv_number: eq.inv_number, maintenance_date: eq.maintenance_date, worker: pworker });
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?;
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 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 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
@ -81,12 +101,18 @@ impl DBOperator{
});
}
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?;
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)
return Ok(true);
}
Ok(false)
}
@ -112,80 +138,70 @@ impl DBOperator{
.bind(position.name)
.bind(position.wage)
.execute(&self.pool)
.await{
Ok(_)=>{
Ok(true)
},
Err(_)=>{
Ok(false)
.await
{
Ok(_) => Ok(true),
Err(_) => Ok(false),
}
}
}
pub async fn add_material_category(&self, mat_cat: MaterialCategory) -> Result<bool, sqlx::Error>{
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)
}
.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, ?, ?, ?);")
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)
}
.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)
.await
{
Ok(_) => Ok(true),
Err(_) => Ok(false),
}
}
}
pub async fn delete_material_category(&self, mat_cat: MaterialCategory) -> Result<bool,sqlx::Error>{
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)
}
.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)
}
.await
{
Ok(_) => Ok(true),
Err(_) => Ok(false),
}
}
@ -206,71 +222,91 @@ impl DBOperator{
}
}
}
pub async fn update_material_category(&self, mat_cat: MaterialCategory) -> Result<bool, sqlx::Error>{
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)
}
.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=?;")
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)
}
.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 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(),
position: poses
.iter()
.find(|&pos| &pos.id == &preret[0].position_id)
.unwrap()
.clone(),
});
ret
}
pub async fn update_position(&self, pos: Position) -> Result<bool, sqlx::Error> {
match sqlx::query("UPDATE Brewery.position SET name=?, wage=? WHERE id=?")
.bind(pos.name)
.bind(pos.wage)
.bind(pos.id)
.execute(&self.pool)
.await
{
Ok(_) => Ok(true),
Err(_) => Ok(false),
}
macro_rules! insert_fn {
($expr:expr, $datatype:ty, $fn_name:ident) => {
pub async fn $fn_name{
match sqlx::query(stringify!($expr))
}
};
}
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?;
.connect(&db_url)
.await?;
Ok(())
}
macro_rules! add_get {
($fn_name:ident, $table:ident) => {
pub async fn $fn_name(&self, $id: i32) -> Result<bool, sqlx::Error> {
match sqlx::query("UPDATE `$table` SET WHERE id = ?")
.bind($id)
.execute(&self.pool)
.await
{
Ok(_) => Ok(true),
Err(e) => Err(e),
}
}
};
}