diff --git a/lootalot_db/db.sqlite3 b/lootalot_db/db.sqlite3 index da9f626..62ac4b2 100644 Binary files a/lootalot_db/db.sqlite3 and b/lootalot_db/db.sqlite3 differ diff --git a/lootalot_db/src/lib.rs b/lootalot_db/src/lib.rs index 49de386..75c65cb 100644 --- a/lootalot_db/src/lib.rs +++ b/lootalot_db/src/lib.rs @@ -7,33 +7,42 @@ extern crate serde_derive; use diesel::prelude::*; use diesel::r2d2::{self, ConnectionManager}; -pub fn establish_connection() -> Result { - dotenv::dotenv().ok(); - let database_url = std::env::var("DATABASE_URL").expect("DATABASE_URL must be set !"); - SqliteConnection::establish(&database_url) - .map_err(|e| format!("Error connecting to {} : {:?}", database_url, e)) -} - pub mod models; pub mod schema; +pub type DbConnection = SqliteConnection; +pub type Pool = r2d2::Pool>; +pub type QueryResult = Result; + +pub use models::Item; pub use models::Player; impl Player { - pub fn fetch_list( - conn: &SqliteConnection, - ) -> Result, diesel::result::Error> { + pub fn fetch_list(conn: &SqliteConnection) -> QueryResult> { use schema::players::dsl::*; - Ok(players.load::(conn)?) + Ok(players.load::(conn)?) + } + + pub fn fetch_chest(player: i32, conn: &SqliteConnection) -> QueryResult> { + let owned = { + use schema::looted::dsl::*; + looted.filter(player_id.eq(player)).select(item_id).load::(conn)? + }; + dbg!(&owned); + let chest = { + use schema::items::dsl::*; + items.filter(id.eq_any(owned)).load::(conn)? + }; + dbg!(&chest); + Ok(chest) } } -pub type Pool = r2d2::Pool>; pub fn create_pool() -> Pool { dotenv::dotenv().ok(); let connspec = std::env::var("DATABASE_URL").expect("DATABASE_URL"); - let manager = ConnectionManager::::new(connspec); + let manager = ConnectionManager::::new(connspec); r2d2::Pool::builder() .build(manager) .expect("Failed to create pool.") diff --git a/lootalot_db/src/models/item.rs b/lootalot_db/src/models/item.rs new file mode 100644 index 0000000..6c52198 --- /dev/null +++ b/lootalot_db/src/models/item.rs @@ -0,0 +1,8 @@ +use crate::*; + +#[derive(Debug, Queryable, Serialize)] +pub struct Item { + id: i32, + name: String, + base_value: i32, +} diff --git a/lootalot_db/src/models/mod.rs b/lootalot_db/src/models/mod.rs new file mode 100644 index 0000000..912833a --- /dev/null +++ b/lootalot_db/src/models/mod.rs @@ -0,0 +1,5 @@ +mod item; +mod player; + +pub use item::Item; +pub use player::Player; diff --git a/lootalot_db/src/models.rs b/lootalot_db/src/models/player.rs similarity index 100% rename from lootalot_db/src/models.rs rename to lootalot_db/src/models/player.rs diff --git a/src/main.rs b/src/main.rs index 4c7b58d..6655fdf 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,10 +14,31 @@ mod api { use futures::Future; use super::Pool; - use lootalot_db::Player; - struct Item; + use lootalot_db::Player as PlayerData; + use lootalot_db::{Item, QueryResult, DbConnection}; - pub fn players_list(pool: web::Data) -> impl Future { + // Wrapper for database queries. + //fn db_query(q: fn(...)) -> impl Future { + // + //} + + struct Player(i32); + + impl Player { + + /// Fetch all players from db + fn fetch_list(conn: &DbConnection) -> QueryResult> { + PlayerData::fetch_list(conn) + } + /// Fetch the content of a player's chest + fn chest(self, conn: &DbConnection) -> QueryResult> { + PlayerData::fetch_chest(self.0, conn) + } + } + + pub fn players_list( + pool: web::Data + ) -> impl Future { web::block(move || { let conn = pool.get().unwrap(); println!("Waiting for player list..."); @@ -35,9 +56,19 @@ mod api { }) } - fn chest_content(_id: i32) -> Result>> { - let items: Vec = Vec::new(); - Ok(Json(items)) + pub fn chest_content( + player_id: web::Path, + pool: web::Data + ) -> impl Future { + web::block(move || { + let conn = pool.get().unwrap(); + dbg!("Fetching chest content..."); + Player(*player_id).chest(&conn) + }) + .then(|res| match res { + Ok(items) => HttpResponse::Ok().json(items), + Err(_) => HttpResponse::InternalServerError().finish(), + }) } fn put_request(_player_id: i32, _item_id: i32) -> Result> { @@ -64,6 +95,7 @@ fn main() -> std::io::Result<()> { App::new() .data(pool.clone()) .route("/players", web::get().to_async(api::players_list)) + .route("/loot/{player_id}", web::get().to_async(api::chest_content)) .service(fs::Files::new("/", www_root.clone()).index_file("index.html")) }) .bind("127.0.0.1:8088")?