]> git.seodisparate.com - EN605.607.81.SP22_ASDM_Project/commitdiff
Refactor db_handler to use struct to split up code
authorStephen Seo <seo.disparate@gmail.com>
Tue, 29 Mar 2022 06:02:20 +0000 (15:02 +0900)
committerStephen Seo <seo.disparate@gmail.com>
Tue, 29 Mar 2022 06:03:08 +0000 (15:03 +0900)
Also refactored the GetID send value type.

back_end/src/db_handler.rs
back_end/src/json_handlers.rs

index 14cf0e479199051f331bb9341a85a68be2afc79e..f41efe70a8e06dd1c76449ece37e161b07ecb194 100644 (file)
@@ -4,9 +4,11 @@ use std::thread;
 use rand::{thread_rng, Rng};
 use rusqlite::Connection;
 
+pub type GetIDSenderType = (u32, Option<bool>);
+
 #[derive(Clone, Debug)]
 pub enum DBHandlerRequest {
-    GetID(SyncSender<u32>),
+    GetID(SyncSender<GetIDSenderType>),
 }
 
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
@@ -15,6 +17,71 @@ enum DBFirstRun {
     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> {
     if let Ok(conn) = Connection::open(sqlite_path) {
         conn.execute("PRAGMA foreign_keys = ON;", [])
@@ -67,70 +134,25 @@ pub fn start_db_handler_thread(
     sqlite_path: String,
     shutdown_tx: SyncSender<()>,
 ) {
+    let mut handler = DBHandler {
+        rx,
+        sqlite_path,
+        shutdown_tx,
+    };
     thread::spawn(move || {
         // 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 {
             println!("ERROR: Failed init sqlite db connection");
-            shutdown_tx.send(()).ok();
+            handler.shutdown_tx.send(()).ok();
             return;
         }
 
         'outer: loop {
-            let rx_recv_result = rx.recv();
-            if let Err(e) = rx_recv_result {
-                println!("Failed to get DBHandlerRequest: {:?}", e);
-                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();
-                }
+            if handler.handle_request() {
+                handler.shutdown_tx.send(()).ok();
+                break 'outer;
             }
-
-            // Pair up players
-            // TODO
-        } // loop end
+        }
     });
 }
index acd01ebaad454904f22cd9a4e2bd57c715056181..792019504e2f64e27983dd687fb019324d2ac6fb 100644 (file)
@@ -1,4 +1,4 @@
-use crate::db_handler::DBHandlerRequest;
+use crate::db_handler::{DBHandlerRequest, GetIDSenderType};
 
 use std::{
     sync::mpsc::{sync_channel, SyncSender},
@@ -27,11 +27,11 @@ pub fn handle_json(
 }
 
 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() {
         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!(
             "{{\"type\":\"pairing_response\", \"id\": \"{}\", \"status\": \"waiting\"}}",
             pid