Refactor db_handler to use struct to split up code
Also refactored the GetID send value type.
This commit is contained in:
parent
ec7f664c81
commit
40b2333767
2 changed files with 82 additions and 60 deletions
|
@ -4,9 +4,11 @@ use std::thread;
|
||||||
use rand::{thread_rng, Rng};
|
use rand::{thread_rng, Rng};
|
||||||
use rusqlite::Connection;
|
use rusqlite::Connection;
|
||||||
|
|
||||||
|
pub type GetIDSenderType = (u32, Option<bool>);
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum DBHandlerRequest {
|
pub enum DBHandlerRequest {
|
||||||
GetID(SyncSender<u32>),
|
GetID(SyncSender<GetIDSenderType>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||||
|
@ -15,6 +17,71 @@ enum DBFirstRun {
|
||||||
NotFirstRun,
|
NotFirstRun,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct DBHandler {
|
||||||
|
rx: Receiver<DBHandlerRequest>,
|
||||||
|
sqlite_path: String,
|
||||||
|
shutdown_tx: SyncSender<()>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DBHandler {
|
||||||
|
/// Returns true if should break out of outer loop
|
||||||
|
fn handle_request(&mut self) -> bool {
|
||||||
|
let rx_recv_result = self.rx.recv();
|
||||||
|
if let Err(e) = rx_recv_result {
|
||||||
|
println!("Failed to get DBHandlerRequest: {:?}", e);
|
||||||
|
self.shutdown_tx.send(()).ok();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
let db_request = rx_recv_result.unwrap();
|
||||||
|
match db_request {
|
||||||
|
DBHandlerRequest::GetID(player_tx) => {
|
||||||
|
// got request to create new player, create new player
|
||||||
|
let mut player_id: u32 = thread_rng().gen();
|
||||||
|
let conn_result = init_conn(&self.sqlite_path, DBFirstRun::NotFirstRun);
|
||||||
|
if let Err(e) = conn_result {
|
||||||
|
println!("Failed to get sqlite db connection: {:?}", e);
|
||||||
|
self.shutdown_tx.send(()).ok();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
let conn = conn_result.unwrap();
|
||||||
|
loop {
|
||||||
|
let stmt_result = conn.prepare("SELECT id FROM players WHERE id = ?;");
|
||||||
|
if let Err(e) = stmt_result {
|
||||||
|
println!("Failed to create sqlite statement: {:?}", e);
|
||||||
|
self.shutdown_tx.send(()).ok();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
let mut stmt = stmt_result.unwrap();
|
||||||
|
match stmt.query_row([player_id], |_row| Ok(())) {
|
||||||
|
Ok(_) => {
|
||||||
|
player_id = thread_rng().gen();
|
||||||
|
}
|
||||||
|
Err(_) => break,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let insert_result = conn.execute(
|
||||||
|
"INSERT INTO players (id, date_added) VALUES (?, datetime());",
|
||||||
|
[player_id],
|
||||||
|
);
|
||||||
|
if let Err(e) = insert_result {
|
||||||
|
println!("Failed to insert into sqlite db: {:?}", e);
|
||||||
|
self.shutdown_tx.send(()).ok();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
let send_result = player_tx.send((player_id, None));
|
||||||
|
if let Err(e) = send_result {
|
||||||
|
println!("Failed to send back player id: {:?}", e);
|
||||||
|
self.shutdown_tx.send(()).ok();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
send_result.unwrap();
|
||||||
|
} // DBHandlerRequest::GetID(player_tx)
|
||||||
|
} // match db_request
|
||||||
|
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn init_conn(sqlite_path: &str, first_run: DBFirstRun) -> Result<Connection, String> {
|
fn init_conn(sqlite_path: &str, first_run: DBFirstRun) -> Result<Connection, String> {
|
||||||
if let Ok(conn) = Connection::open(sqlite_path) {
|
if let Ok(conn) = Connection::open(sqlite_path) {
|
||||||
conn.execute("PRAGMA foreign_keys = ON;", [])
|
conn.execute("PRAGMA foreign_keys = ON;", [])
|
||||||
|
@ -67,70 +134,25 @@ pub fn start_db_handler_thread(
|
||||||
sqlite_path: String,
|
sqlite_path: String,
|
||||||
shutdown_tx: SyncSender<()>,
|
shutdown_tx: SyncSender<()>,
|
||||||
) {
|
) {
|
||||||
|
let mut handler = DBHandler {
|
||||||
|
rx,
|
||||||
|
sqlite_path,
|
||||||
|
shutdown_tx,
|
||||||
|
};
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
// temporarily get conn which should initialize on first setup of db
|
// temporarily get conn which should initialize on first setup of db
|
||||||
if let Ok(_conn) = init_conn(&sqlite_path, DBFirstRun::FirstRun) {
|
if let Ok(_conn) = init_conn(&handler.sqlite_path, DBFirstRun::FirstRun) {
|
||||||
} else {
|
} else {
|
||||||
println!("ERROR: Failed init sqlite db connection");
|
println!("ERROR: Failed init sqlite db connection");
|
||||||
shutdown_tx.send(()).ok();
|
handler.shutdown_tx.send(()).ok();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
'outer: loop {
|
'outer: loop {
|
||||||
let rx_recv_result = rx.recv();
|
if handler.handle_request() {
|
||||||
if let Err(e) = rx_recv_result {
|
handler.shutdown_tx.send(()).ok();
|
||||||
println!("Failed to get DBHandlerRequest: {:?}", e);
|
break 'outer;
|
||||||
shutdown_tx.send(()).ok();
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
let db_request = rx_recv_result.unwrap();
|
}
|
||||||
match db_request {
|
|
||||||
DBHandlerRequest::GetID(player_tx) => {
|
|
||||||
// got request to create new player, create new player
|
|
||||||
let mut player_id: u32 = thread_rng().gen();
|
|
||||||
let conn_result = init_conn(&sqlite_path, DBFirstRun::NotFirstRun);
|
|
||||||
if let Err(e) = conn_result {
|
|
||||||
println!("Failed to get sqlite db connection: {:?}", e);
|
|
||||||
shutdown_tx.send(()).ok();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
let conn = conn_result.unwrap();
|
|
||||||
loop {
|
|
||||||
let stmt_result = conn.prepare("SELECT id FROM players WHERE id = ?;");
|
|
||||||
if let Err(e) = stmt_result {
|
|
||||||
println!("Failed to create sqlite statement: {:?}", e);
|
|
||||||
shutdown_tx.send(()).ok();
|
|
||||||
break 'outer;
|
|
||||||
}
|
|
||||||
let mut stmt = stmt_result.unwrap();
|
|
||||||
match stmt.query_row([player_id], |_row| Ok(())) {
|
|
||||||
Ok(_) => {
|
|
||||||
player_id = thread_rng().gen();
|
|
||||||
}
|
|
||||||
Err(_) => break,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let insert_result = conn.execute(
|
|
||||||
"INSERT INTO players (id, date_added) VALUES (?, datetime());",
|
|
||||||
[player_id],
|
|
||||||
);
|
|
||||||
if let Err(e) = insert_result {
|
|
||||||
println!("Failed to insert into sqlite db: {:?}", e);
|
|
||||||
shutdown_tx.send(()).ok();
|
|
||||||
break 'outer;
|
|
||||||
}
|
|
||||||
let send_result = player_tx.send(player_id);
|
|
||||||
if let Err(e) = send_result {
|
|
||||||
println!("Failed to send back player id: {:?}", e);
|
|
||||||
shutdown_tx.send(()).ok();
|
|
||||||
break 'outer;
|
|
||||||
}
|
|
||||||
send_result.unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pair up players
|
|
||||||
// TODO
|
|
||||||
} // loop end
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::db_handler::DBHandlerRequest;
|
use crate::db_handler::{DBHandlerRequest, GetIDSenderType};
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
sync::mpsc::{sync_channel, SyncSender},
|
sync::mpsc::{sync_channel, SyncSender},
|
||||||
|
@ -27,11 +27,11 @@ pub fn handle_json(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_pairing_request(tx: SyncSender<DBHandlerRequest>) -> Result<String, String> {
|
fn handle_pairing_request(tx: SyncSender<DBHandlerRequest>) -> Result<String, String> {
|
||||||
let (player_tx, player_rx) = sync_channel::<u32>(1);
|
let (player_tx, player_rx) = sync_channel::<GetIDSenderType>(1);
|
||||||
if tx.send(DBHandlerRequest::GetID(player_tx)).is_err() {
|
if tx.send(DBHandlerRequest::GetID(player_tx)).is_err() {
|
||||||
return Err("{\"type\":\"pairing_response\", \"status\":\"internal_error\"}".into());
|
return Err("{\"type\":\"pairing_response\", \"status\":\"internal_error\"}".into());
|
||||||
}
|
}
|
||||||
if let Ok(pid) = player_rx.recv_timeout(Duration::from_secs(5)) {
|
if let Ok((pid, is_cyan_opt)) = player_rx.recv_timeout(Duration::from_secs(5)) {
|
||||||
Ok(format!(
|
Ok(format!(
|
||||||
"{{\"type\":\"pairing_response\", \"id\": \"{}\", \"status\": \"waiting\"}}",
|
"{{\"type\":\"pairing_response\", \"id\": \"{}\", \"status\": \"waiting\"}}",
|
||||||
pid
|
pid
|
||||||
|
|
Loading…
Reference in a new issue