use sqlx::{pool::PoolConnection, prelude::*, query, query_as, query_file, SqliteConnection, SqlitePool}; use tokio::stream::StreamExt; pub mod types; pub struct DbPool { pool: SqlitePool, } impl DbPool { pub async fn new() -> Self { // std::env::set_var("DATABASE_URL", ); let pool = SqlitePool::new("sqlite:db.sqlite").await.unwrap(); let mut conn = pool.acquire().await.unwrap(); query_file!("src/setup.sql") .execute(&mut conn) .await .unwrap(); Self { pool } } pub async fn acquire(&self) -> DbConnection { DbConnection::new(self.pool.acquire().await.unwrap()) } } // impl Drop for DbPool { // fn drop(&mut self) { // tokio::runtime::Handle::current().block_on(future) // } // } pub struct DbConnection { conn: PoolConnection, } use uuid::Uuid; // TODO: return Results intead of crashing impl DbConnection { fn new(conn: PoolConnection) -> Self { Self { conn } } pub async fn add_user(&mut self, name: T) -> Uuid { let uuid = Uuid::new_v4(); // println!("{:?}", uuid.as_bytes().to_vec()); self.conn .execute(query!( "INSERT INTO Users(uuid, name) VALUES(?, ?)", uuid.as_bytes().to_vec(), name.to_string() )) .await .unwrap(); // Server crashes if uuids collide uuid } pub async fn users(&mut self) -> Vec { query_as::<_, types::User>("SELECT UUID, Name FROM Users") .fetch_all(&mut self.conn) .await .unwrap() } pub async fn create_lobby(&mut self) -> u32 { let id = rand::random(); self.conn .execute(query!( "INSERT INTO Lobbies(id) VALUES(?)", id as i32 )) .await .unwrap(); // Server crashes if ids collide id } pub async fn join_lobby(&mut self, user: Uuid, lobby: u32) { self.conn .execute(query!( "INSERT INTO UsersInLobbies(UserId, LobbyId) VALUES(?, ?)", user.as_bytes().to_vec(), lobby as i32 )) .await .unwrap(); // Server crashes if ids collide } pub async fn close(self) { self.conn.close().await.unwrap(); } }