2023-04-09 12:07:33 +00:00
|
|
|
use egui::{Context, Ui};
|
|
|
|
use sqlx::mysql::MySqlQueryResult;
|
|
|
|
use std::error::Error;
|
|
|
|
use tokio::sync::mpsc::{channel, Receiver, Sender};
|
|
|
|
use tokio::sync::oneshot;
|
|
|
|
|
|
|
|
use crate::backend::backend_manager::Communication;
|
|
|
|
use crate::backend::database_handler::QueryResult;
|
|
|
|
|
2023-04-15 17:02:23 +00:00
|
|
|
use super::window_manager::{CSQLWindow, ExitStatus};
|
|
|
|
|
2023-04-09 12:07:33 +00:00
|
|
|
pub struct DBTransactionWindow {
|
|
|
|
sender: Sender<Communication>,
|
|
|
|
log_history: Vec<QueryResult>,
|
|
|
|
logs_receiver: Option<Receiver<QueryResult>>,
|
|
|
|
is_log_finished_receiver: Option<oneshot::Receiver<bool>>,
|
2023-04-15 17:02:23 +00:00
|
|
|
is_log_finished: bool,
|
|
|
|
is_finished: bool,
|
2023-04-09 12:07:33 +00:00
|
|
|
final_result_receiver: Option<oneshot::Receiver<QueryResult>>,
|
|
|
|
working_table_index: usize,
|
|
|
|
}
|
|
|
|
impl DBTransactionWindow {
|
|
|
|
pub fn default(
|
|
|
|
sender: Sender<Communication>,
|
|
|
|
working_table_index: usize,
|
|
|
|
) -> DBTransactionWindow {
|
|
|
|
DBTransactionWindow {
|
|
|
|
sender,
|
|
|
|
log_history: vec![],
|
2023-04-15 17:02:23 +00:00
|
|
|
is_finished: false,
|
2023-04-09 12:07:33 +00:00
|
|
|
logs_receiver: None,
|
|
|
|
final_result_receiver: None,
|
|
|
|
is_log_finished_receiver: None,
|
2023-04-15 17:02:23 +00:00
|
|
|
is_log_finished: false,
|
2023-04-09 12:07:33 +00:00
|
|
|
working_table_index,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-04-15 17:02:23 +00:00
|
|
|
impl CSQLWindow for DBTransactionWindow {
|
|
|
|
fn refresh(
|
|
|
|
&mut self,
|
|
|
|
ctx: &Context,
|
|
|
|
ui: &mut Ui,
|
|
|
|
frame: &mut eframe::Frame,
|
|
|
|
) -> Option<ExitStatus> {
|
2023-04-09 12:07:33 +00:00
|
|
|
egui::Window::new("Database Transactions")
|
|
|
|
.id(egui::Id::new("Database Transactions"))
|
|
|
|
.resizable(false)
|
|
|
|
.collapsible(true)
|
|
|
|
.title_bar(true)
|
|
|
|
.movable(false)
|
|
|
|
.scroll2([false, true])
|
|
|
|
.enabled(true)
|
2023-04-09 12:07:46 +00:00
|
|
|
.fixed_size(egui::Vec2::new(
|
|
|
|
frame.info().window_info.size.x / 1.3,
|
|
|
|
frame.info().window_info.size.y / 1.5,
|
|
|
|
))
|
2023-04-09 12:07:33 +00:00
|
|
|
.anchor(egui::Align2::CENTER_CENTER, egui::Vec2::ZERO)
|
|
|
|
.show(ctx, |ui| {
|
|
|
|
self.log();
|
2023-04-15 17:02:23 +00:00
|
|
|
self.ui(ctx, ui, frame);
|
2023-04-09 12:07:33 +00:00
|
|
|
});
|
2023-04-15 17:02:23 +00:00
|
|
|
|
|
|
|
if self.is_finished {
|
|
|
|
return Some(ExitStatus::Ok);
|
|
|
|
}
|
|
|
|
None
|
2023-04-09 12:07:33 +00:00
|
|
|
}
|
2023-04-15 17:02:23 +00:00
|
|
|
}
|
|
|
|
impl DBTransactionWindow {
|
2023-04-09 12:07:33 +00:00
|
|
|
pub fn log(&mut self) {
|
2023-04-15 17:02:23 +00:00
|
|
|
if let Some(finish_receiver) = self.final_result_receiver.as_mut() {
|
|
|
|
if let Ok(result) = finish_receiver.try_recv() {
|
|
|
|
if result.result.is_ok() {
|
|
|
|
self.is_finished = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-04-09 12:07:33 +00:00
|
|
|
if self.logs_receiver.is_some() {
|
|
|
|
if let Ok(log) = self.logs_receiver.as_mut().unwrap().try_recv() {
|
|
|
|
self.log_history.push(log);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if self.is_log_finished_receiver.is_some() {
|
|
|
|
if let Ok(finished) = self.is_log_finished_receiver.as_mut().unwrap().try_recv() {
|
2023-04-15 17:02:23 +00:00
|
|
|
self.is_log_finished = finished;
|
|
|
|
println!("FINISHED QUERYING!!!");
|
2023-04-09 12:07:33 +00:00
|
|
|
}
|
|
|
|
}
|
2023-04-09 12:07:46 +00:00
|
|
|
if self.is_log_finished_receiver.is_none() && self.logs_receiver.is_none() {
|
|
|
|
let (log_sender, log_receiver) = channel(2);
|
|
|
|
let (finished_sender, finished_receiver) = oneshot::channel();
|
|
|
|
self.is_log_finished_receiver = Some(finished_receiver);
|
|
|
|
self.logs_receiver = Some(log_receiver);
|
|
|
|
self.sender
|
|
|
|
.try_send(Communication::StartInserting(
|
|
|
|
self.working_table_index,
|
|
|
|
log_sender,
|
|
|
|
finished_sender,
|
|
|
|
))
|
|
|
|
.unwrap_or_else(|_| println!("Failed to send startInserting"));
|
|
|
|
}
|
2023-04-09 12:07:33 +00:00
|
|
|
}
|
2023-04-15 17:02:23 +00:00
|
|
|
pub fn ui(&mut self, ctx: &Context, ui: &mut Ui, frame: &mut eframe::Frame) {
|
|
|
|
ui.add_enabled_ui(self.is_log_finished, |ui| {
|
2023-04-09 12:07:46 +00:00
|
|
|
ui.horizontal(|ui| {
|
|
|
|
if ui.button("Roll back").clicked() {
|
|
|
|
if self.final_result_receiver.is_none() {
|
|
|
|
let (sender, receiver) = oneshot::channel();
|
|
|
|
self.final_result_receiver = Some(receiver);
|
|
|
|
self.sender
|
|
|
|
.try_send(Communication::TryRollBack(sender))
|
|
|
|
.unwrap_or_else(|_| println!("failed sending TryCommit receiver"));
|
|
|
|
}
|
2023-04-09 12:07:33 +00:00
|
|
|
}
|
2023-04-09 12:07:46 +00:00
|
|
|
if ui.button("Commit").clicked() {
|
|
|
|
if self.final_result_receiver.is_none() {
|
|
|
|
let (sender, receiver) = oneshot::channel();
|
|
|
|
self.final_result_receiver = Some(receiver);
|
|
|
|
self.sender
|
|
|
|
.try_send(Communication::TryCommit(sender))
|
|
|
|
.unwrap_or_else(|_| println!("failed sending TryCommit receiver"));
|
|
|
|
}
|
2023-04-09 12:07:33 +00:00
|
|
|
}
|
2023-04-09 12:07:46 +00:00
|
|
|
});
|
2023-04-09 12:07:33 +00:00
|
|
|
});
|
|
|
|
/* DB Output Stuff */
|
2023-04-15 17:02:23 +00:00
|
|
|
egui::ScrollArea::vertical()
|
2023-04-09 12:07:33 +00:00
|
|
|
.auto_shrink([false; 2])
|
2023-04-09 12:07:46 +00:00
|
|
|
.stick_to_bottom(true)
|
2023-04-09 12:07:33 +00:00
|
|
|
.show(ui, |ui| {
|
2023-04-09 12:07:46 +00:00
|
|
|
let mut table = egui_extras::TableBuilder::new(ui)
|
|
|
|
.striped(true)
|
|
|
|
.resizable(true)
|
|
|
|
.cell_layout(egui::Layout::left_to_right(egui::Align::LEFT))
|
2023-04-15 17:02:23 +00:00
|
|
|
.column(
|
|
|
|
egui_extras::Column::remainder()
|
|
|
|
.clip(true)
|
|
|
|
.at_most(frame.info().window_info.size.x / 1.3 / 2.0),
|
|
|
|
)
|
2023-04-09 12:07:46 +00:00
|
|
|
.stick_to_bottom(true)
|
2023-04-15 17:02:23 +00:00
|
|
|
.column(
|
|
|
|
egui_extras::Column::remainder()
|
|
|
|
.clip(true)
|
|
|
|
.at_most(frame.info().window_info.size.x / 1.3 / 2.0),
|
|
|
|
)
|
2023-04-09 12:07:46 +00:00
|
|
|
.stick_to_bottom(true);
|
|
|
|
|
|
|
|
table
|
|
|
|
.header(20.0, |mut header| {
|
|
|
|
header.col(|ui| {
|
|
|
|
ui.strong("Query");
|
|
|
|
});
|
|
|
|
header.col(|ui| {
|
|
|
|
ui.strong("Result");
|
2023-04-09 12:07:33 +00:00
|
|
|
});
|
|
|
|
})
|
2023-04-09 12:07:46 +00:00
|
|
|
.body(|mut body| {
|
|
|
|
body.rows(15.0, self.log_history.len(), |row_index, mut row| {
|
|
|
|
let log = self.log_history.get(row_index).unwrap();
|
|
|
|
row.col(|ui| {
|
|
|
|
ui.label(&log.query);
|
|
|
|
});
|
|
|
|
row.col(|ui| {
|
|
|
|
match &log.result {
|
|
|
|
Ok(rows) => {
|
|
|
|
ui.style_mut().visuals.override_text_color =
|
|
|
|
Some(egui::Color32::LIGHT_GREEN);
|
|
|
|
ui.label(format!(
|
|
|
|
"Success! Rows affected: {}",
|
|
|
|
rows.rows_affected()
|
|
|
|
));
|
|
|
|
}
|
|
|
|
Err(e) => {
|
|
|
|
ui.style_mut().visuals.override_text_color =
|
|
|
|
Some(egui::Color32::LIGHT_RED);
|
|
|
|
ui.label(format!("Error! {}", e));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ui.reset_style();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
ui.scroll_to_cursor(Some(egui::Align::BOTTOM));
|
2023-04-09 12:07:33 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
2023-04-15 17:02:23 +00:00
|
|
|
|
|
|
|
pub struct OptionsDBTransactionWindow {
|
|
|
|
substitute_zero_dates_for_NULL: bool,
|
|
|
|
remove_id_field_from_insert: bool,
|
|
|
|
}
|