use rusqlite::{Connection, params, ToSql}; use std::sync::Mutex; use json::{JsonValue, array}; use crate::router::clear_rate::Live; pub struct SQLite { engine: Mutex, sleep_duration: u64 } impl SQLite { pub fn new(path: &str, setup: fn(&SQLite)) -> SQLite { let conn = Connection::open(path).unwrap(); conn.execute("PRAGMA foreign_keys = ON;", ()).unwrap(); let instance = SQLite { engine: Mutex::new(conn), sleep_duration: 10 }; setup(&instance); instance } pub fn lock_and_exec(&self, command: &str, args: &[&dyn ToSql]) { loop { match self.engine.lock() { Ok(conn) => { conn.execute(command, args).unwrap(); return; } Err(_) => { std::thread::sleep(std::time::Duration::from_millis(self.sleep_duration)); } } } } pub fn lock_and_select(&self, command: &str, args: &[&dyn ToSql]) -> Result { loop { match self.engine.lock() { Ok(conn) => { let mut stmt = conn.prepare(command)?; return stmt.query_row(args, |row| { match row.get::(0) { Ok(val) => Ok(val.to_string()), Err(_) => row.get(0) } }); } Err(_) => { std::thread::sleep(std::time::Duration::from_millis(self.sleep_duration)); } } } } pub fn lock_and_select_all(&self, command: &str, args: &[&dyn ToSql]) -> Result { loop { match self.engine.lock() { Ok(conn) => { let mut stmt = conn.prepare(command)?; let map = stmt.query_map(args, |row| { match row.get::(0) { Ok(val) => Ok(val.to_string()), Err(_) => row.get(0) } })?; let mut rv = array![]; for val in map { let res = val?; match res.clone().parse::() { Ok(v) => rv.push(v).unwrap(), Err(_) => rv.push(res).unwrap() }; } return Ok(rv); } Err(_) => { std::thread::sleep(std::time::Duration::from_millis(self.sleep_duration)); } } } } pub fn get_live_data(&self, id: i64) -> Result { loop { match self.engine.lock() { Ok(conn) => { let mut stmt = conn.prepare("SELECT * FROM lives WHERE live_id=?1")?; return Ok(stmt.query_row(params!(id), |row| { Ok(Live { live_id: row.get(0)?, normal_failed: row.get(1)?, normal_pass: row.get(2)?, hard_failed: row.get(3)?, hard_pass: row.get(4)?, expert_failed: row.get(5)?, expert_pass: row.get(6)?, master_failed: row.get(7)?, master_pass: row.get(8)?, }) })?); } Err(_) => { std::thread::sleep(std::time::Duration::from_millis(self.sleep_duration)); } } } } pub fn create_store_v2(&self, table: &str) { self.lock_and_exec(table, params!()); } }