Compare commits

..

3 Commits

11 changed files with 860 additions and 789 deletions

1538
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -15,4 +15,5 @@ log = "0.4.17"
mysql = "23.0.1" mysql = "23.0.1"
sprintf = "0.1.3" sprintf = "0.1.3"
termsize = "0.1.6" termsize = "0.1.6"
thiserror = "2.0.12"
time = "0.3.20" time = "0.3.20"

View File

@ -9,15 +9,23 @@ use crate::{
use super::command::{Cli, Commands}; use super::command::{Cli, Commands};
pub fn process_args(args: Cli, db: Db) { use thiserror::Error;
#[derive(Debug, Error)]
enum CommandError {
#[error("Empty search provided.")]
EmptySearch(),
}
pub fn process_args(args: Cli, db: Db) -> Result<(), Box<dyn std::error::Error>> {
match args.mode { match args.mode {
Commands::Merch { search } => { Commands::Merch { search } => {
let mut merchant_service: MerchantService = container::get_merchant_service(db); let mut merchant_service: MerchantService = container::get_merchant_service(db);
merchant_service.get_merchant(&search.unwrap()); merchant_service.get_merchant(&search.ok_or(CommandError::EmptySearch())?);
} }
Commands::Schema { search } => { Commands::Schema { search } => {
let mut schema_service: SchemaService = container::get_schema_service(db); let mut schema_service: SchemaService = container::get_schema_service(db);
schema_service.get_columns(&search.unwrap()) schema_service.get_columns(&search.ok_or(CommandError::EmptySearch())?)
} }
Commands::Filter { Commands::Filter {
filter_id, filter_id,
@ -29,7 +37,7 @@ pub fn process_args(args: Cli, db: Db) {
if config { if config {
filter_service.get_filter_configs(&filter_id) filter_service.get_filter_configs(&filter_id)
} else if log { } else if log {
filter_service.get_filter_log(&filter_id) filter_service.get_filter_log(&filter_id, all)
} else { } else {
filter_service.get_filter(&filter_id, all) filter_service.get_filter(&filter_id, all)
} }
@ -47,4 +55,6 @@ pub fn process_args(args: Cli, db: Db) {
} }
} }
} }
Ok(())
} }

View File

@ -1,35 +1,50 @@
use core::fmt;
use mysql::{Opts, Pool, PooledConn}; use mysql::{Opts, Pool, PooledConn};
use std::{ use std::{
env, env,
error::Error,
path::PathBuf, path::PathBuf,
sync::{Arc, Mutex}, sync::{Arc, Mutex},
}; };
use directories::BaseDirs; use directories::BaseDirs;
#[derive(Debug)]
struct InitError(String);
impl fmt::Display for InitError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
impl Error for InitError {}
#[derive(Debug)] #[derive(Debug)]
pub struct Db { pub struct Db {
pool: Arc<Mutex<Pool>>, pool: Arc<Mutex<Pool>>,
} }
impl Db { impl Db {
pub fn initialize(env: String) -> Result<Self, mysql::Error> { pub fn initialize(env: String) -> Result<Self, Box<dyn std::error::Error>> {
let base_dir: BaseDirs = match BaseDirs::new() { let base_dir: BaseDirs = BaseDirs::new()
Some(dirs) => dirs, .ok_or_else(|| Box::new(InitError("No config folder found.".to_string())))?;
None => panic!("No config folder found."),
};
let config_file_path: PathBuf = base_dir.config_dir().join("rcc/").join(env); let config_file_path: PathBuf = base_dir.config_dir().join("rcc/").join(env);
match dotenv::from_path(config_file_path.as_path()) { dotenv::from_path(config_file_path.as_path()).map_err(|_| {
Ok(env) => env, Box::new(InitError(format!(
Err(_) => panic!("Could not load .env file {:?}", config_file_path.as_path()), "Failed to load dotenv file '{}'",
}; config_file_path.display()
)))
})?;
let location: String = env::var("LOCATION").unwrap_or_else(|_| "localhost".to_string()); let location: String = env::var("LOCATION").unwrap_or_else(|_| "localhost".to_string());
let user: String = env::var("USERNAME").unwrap(); let user: String = env::var("USERNAME")
.map_err(|_| Box::new(InitError("Missing USERNAME in dotenv file.".to_string())))?;
let port: String = env::var("PORT").unwrap_or_else(|_| "3306".to_string()); let port: String = env::var("PORT").unwrap_or_else(|_| "3306".to_string());
let password: String = env::var("PASSWORD").unwrap(); let password: String = env::var("PASSWORD")
.map_err(|_| Box::new(InitError("Missing PASSWORD in dotenv file.".to_string())))?;
let db_name: String = env::var("DB").unwrap_or_else(|_| "efulfilment".to_string()); let db_name: String = env::var("DB").unwrap_or_else(|_| "efulfilment".to_string());
let url: String = format!( let url: String = format!(
"mysql://{}:{}@{}:{}/{}", "mysql://{}:{}@{}:{}/{}",
@ -45,7 +60,7 @@ impl Db {
} }
pub fn get_connection(&self) -> Result<PooledConn, mysql::Error> { pub fn get_connection(&self) -> Result<PooledConn, mysql::Error> {
let pool = self.pool.lock().unwrap(); let pool = self.pool.lock()?;
pool.get_conn() pool.get_conn()
} }
} }

View File

@ -15,7 +15,6 @@ fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
let env: &String = &Cli::parse().env.unwrap_or("local".to_string()); let env: &String = &Cli::parse().env.unwrap_or("local".to_string());
let db: Db = Db::initialize(env.to_string())?; let db: Db = Db::initialize(env.to_string())?;
controller::process_args(args, db); controller::process_args(args, db)?;
Ok(()) Ok(())
} }

View File

@ -15,8 +15,7 @@ impl FileRepo {
pub fn find_page(&mut self, file_id: &usize) -> Result<Vec<Page>, mysql::Error> { pub fn find_page(&mut self, file_id: &usize) -> Result<Vec<Page>, mysql::Error> {
let mut connection: mysql::PooledConn = self.db_pool.get_connection()?; let mut connection: mysql::PooledConn = self.db_pool.get_connection()?;
let stat = connection let stat = connection
.prep("SELECT m_id, description, file FROM global_data.effi_file_mapping WHERE file_id = :file_id") .prep("SELECT m_id, description, file FROM global_data.effi_file_mapping WHERE file_id = :file_id")?;
.unwrap();
connection.exec_map( connection.exec_map(
stat, stat,

View File

@ -22,8 +22,7 @@ impl FilterRepo {
FROM filter f FROM filter f
JOIN global_data.filter_modules fm ON fm.filter_module_id = f.filter_module_id JOIN global_data.filter_modules fm ON fm.filter_module_id = f.filter_module_id
WHERE f.filter_id = :filter_id WHERE f.filter_id = :filter_id
") ")?;
.unwrap();
let params = params! {"filter_id" => filter_id}; let params = params! {"filter_id" => filter_id};
connection.exec_map( connection.exec_map(
@ -52,8 +51,7 @@ impl FilterRepo {
JOIN global_data.effi_user t2 on t1.upd_user = t2.user_id JOIN global_data.effi_user t2 on t1.upd_user = t2.user_id
WHERE t1.filter_id = :filter_id WHERE t1.filter_id = :filter_id
", ",
) )?;
.unwrap();
connection.exec_map( connection.exec_map(
stat, stat,
@ -70,15 +68,13 @@ impl FilterRepo {
pub fn find_filter_log(&mut self, filter_id: &usize) -> Result<Vec<FilterLog>, mysql::Error> { pub fn find_filter_log(&mut self, filter_id: &usize) -> Result<Vec<FilterLog>, mysql::Error> {
let mut connection: PooledConn = self.db.get_connection()?; let mut connection: PooledConn = self.db.get_connection()?;
let stat = connection let stat = connection.prep(
.prep(
" "
SELECT t1.run_ts, t1.error_code, t1.error_msg, t1.mysql_error SELECT t1.run_ts, t1.error_code, t1.error_msg, t1.mysql_error
FROM filter_run_error_log t1 FROM filter_run_error_log t1
WHERE t1.filter_id = :filter_id WHERE t1.filter_id = :filter_id
", ",
) )?;
.unwrap();
connection.exec_map( connection.exec_map(
stat, stat,

View File

@ -17,8 +17,7 @@ impl JobRepo {
pub fn find_by_id(&mut self, job_id: &usize) -> Result<Vec<Job>, mysql::Error> { pub fn find_by_id(&mut self, job_id: &usize) -> Result<Vec<Job>, mysql::Error> {
let mut connection: mysql::PooledConn = self.db.get_connection()?; let mut connection: mysql::PooledConn = self.db.get_connection()?;
let stat = connection let stat = connection.prep(
.prep(
"SELECT "SELECT
jm.file_name, jm.description jm.file_name, jm.description
FROM jobs j FROM jobs j
@ -26,8 +25,7 @@ impl JobRepo {
WHERE WHERE
j.job_id = :job_id j.job_id = :job_id
", ",
) )?;
.unwrap();
connection.exec_map( connection.exec_map(
stat, stat,
@ -41,8 +39,7 @@ impl JobRepo {
pub fn find_log(&mut self, job_id: &usize) -> Result<Vec<JobLog>, mysql::Error> { pub fn find_log(&mut self, job_id: &usize) -> Result<Vec<JobLog>, mysql::Error> {
let mut connection: mysql::PooledConn = self.db.get_connection()?; let mut connection: mysql::PooledConn = self.db.get_connection()?;
let stat = connection let stat = connection.prep(
.prep(
" "
SELECT jea.content, jea.upd_ts SELECT jea.content, jea.upd_ts
FROM jobs j FROM jobs j
@ -51,8 +48,7 @@ impl JobRepo {
WHERE WHERE
j.job_id = :job_id j.job_id = :job_id
", ",
) )?;
.unwrap();
connection.exec_map(stat, params! {"job_id" => job_id}, |(content, upd_ts)| { connection.exec_map(stat, params! {"job_id" => job_id}, |(content, upd_ts)| {
JobLog { content, upd_ts } JobLog { content, upd_ts }

View File

@ -14,8 +14,7 @@ impl MerchantRepo {
pub fn find_by_name_or_id(&mut self, search: &str) -> Result<Vec<Merchant>, mysql::Error> { pub fn find_by_name_or_id(&mut self, search: &str) -> Result<Vec<Merchant>, mysql::Error> {
let mut connection = self.db_pool.get_connection()?; let mut connection = self.db_pool.get_connection()?;
let stat = connection let stat = connection
.prep("SELECT m_name, m_id FROM global_data.merchant WHERE m_id = :search OR m_name LIKE :search2;") .prep("SELECT m_name, m_id FROM global_data.merchant WHERE m_id = :search OR m_name LIKE :search2;")?;
.unwrap();
let search_like = format!("%{}%", search); let search_like = format!("%{}%", search);

View File

@ -14,8 +14,7 @@ impl SchemaRepo {
pub fn find_by_column(&mut self, column_name: &str) -> Result<Vec<Schema>, mysql::Error> { pub fn find_by_column(&mut self, column_name: &str) -> Result<Vec<Schema>, mysql::Error> {
let mut connection: mysql::PooledConn = self.db.get_connection()?; let mut connection: mysql::PooledConn = self.db.get_connection()?;
let stat = connection let stat = connection
.prep("SELECT TABLE_NAME, COLUMN_NAME, COLUMN_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE column_name LIKE :c_name") .prep("SELECT TABLE_NAME, COLUMN_NAME, COLUMN_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE column_name LIKE :c_name")?;
.unwrap();
connection.exec_map( connection.exec_map(
stat, stat,

View File

@ -73,7 +73,7 @@ impl FilterService {
}; };
} }
pub fn get_filter_log(&mut self, filter_id: &usize) { pub fn get_filter_log(&mut self, filter_id: &usize, all: bool) {
let result = self.repo.find_filter_log(filter_id); let result = self.repo.find_filter_log(filter_id);
match result { match result {
Ok(filter_log) => { Ok(filter_log) => {
@ -89,12 +89,21 @@ impl FilterService {
match filter_log.error_code.as_str() { match filter_log.error_code.as_str() {
"WARNING" => { "WARNING" => {
println!("{}", filter_log.error_msg.yellow()); println!("{}", filter_log.error_msg.yellow());
if all {
println!("{}", filter_log.mysql_error.yellow());
}
} }
"ERROR" => { "ERROR" => {
println!("{}", filter_log.error_msg.red()); println!("{}", filter_log.error_msg.red());
if all {
println!("{}", filter_log.mysql_error.red());
}
} }
"DEBUG" => { "DEBUG" => {
println!("{}", filter_log.error_msg.green()); println!("{}", filter_log.error_msg.green());
if all {
println!("{}", filter_log.error_msg.green())
}
} }
_ => { _ => {
println!("{}", filter_log.error_msg); println!("{}", filter_log.error_msg);