uses tips from diesel.rs guide for application integration
This commit is contained in:
Binary file not shown.
@@ -6,35 +6,24 @@ extern crate serde_derive;
|
|||||||
|
|
||||||
use diesel::prelude::*;
|
use diesel::prelude::*;
|
||||||
use diesel::r2d2::{self, ConnectionManager};
|
use diesel::r2d2::{self, ConnectionManager};
|
||||||
|
// Convenience re-export, maybe DbApi should me move here instead ??
|
||||||
|
pub use diesel::query_dsl::RunQueryDsl;
|
||||||
|
|
||||||
pub mod models;
|
mod models;
|
||||||
pub mod schema;
|
mod schema;
|
||||||
|
|
||||||
|
pub use models::Item;
|
||||||
|
pub use models::Player;
|
||||||
|
|
||||||
pub type DbConnection = SqliteConnection;
|
pub type DbConnection = SqliteConnection;
|
||||||
pub type Pool = r2d2::Pool<ConnectionManager<DbConnection>>;
|
pub type Pool = r2d2::Pool<ConnectionManager<DbConnection>>;
|
||||||
pub type QueryResult<T> = Result<T, diesel::result::Error>;
|
pub type QueryResult<T> = Result<T, diesel::result::Error>;
|
||||||
pub type ActionResult = QueryResult<bool>;
|
pub type ActionResult = QueryResult<bool>;
|
||||||
|
|
||||||
pub use models::Item;
|
|
||||||
pub use models::Player;
|
|
||||||
|
|
||||||
impl Player {
|
impl Player {
|
||||||
/// Query the list of all players
|
/// Query the list of all players
|
||||||
pub fn fetch_list(conn: &SqliteConnection) -> QueryResult<Vec<Self>> {
|
pub fn fetch_list(conn: &SqliteConnection) -> QueryResult<Vec<Self>> {
|
||||||
use schema::players::dsl::*;
|
Ok( schema::players::table.load::<Self>(conn)? )
|
||||||
Ok( players
|
|
||||||
.load::<Self>(conn)?
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Query the list of items belonging to player
|
|
||||||
pub fn fetch_loot(player_id: i32, conn: &SqliteConnection) -> QueryResult<Vec<Item>> {
|
|
||||||
use schema::looted::dsl::*;
|
|
||||||
Ok( looted
|
|
||||||
.filter(owner_id.eq(player_id))
|
|
||||||
.select((id, name, base_price))
|
|
||||||
.load::<Item>(conn)?
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn action_claim_object(player_id: i32, item_id: i32, conn: &DbConnection) -> ActionResult {
|
pub fn action_claim_object(player_id: i32, item_id: i32, conn: &DbConnection) -> ActionResult {
|
||||||
@@ -48,8 +37,8 @@ impl Player {
|
|||||||
|
|
||||||
|
|
||||||
pub fn create_pool() -> Pool {
|
pub fn create_pool() -> Pool {
|
||||||
dbg!(dotenv::dotenv().ok());
|
|
||||||
let connspec = std::env::var("DATABASE_URL").expect("DATABASE_URL");
|
let connspec = std::env::var("DATABASE_URL").expect("DATABASE_URL");
|
||||||
|
dbg!( &connspec );
|
||||||
let manager = ConnectionManager::<DbConnection>::new(connspec);
|
let manager = ConnectionManager::<DbConnection>::new(connspec);
|
||||||
r2d2::Pool::builder()
|
r2d2::Pool::builder()
|
||||||
.build(manager)
|
.build(manager)
|
||||||
@@ -58,23 +47,5 @@ pub fn create_pool() -> Pool {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
|
||||||
|
|
||||||
fn with_db<F>(f: F) -> ()
|
|
||||||
where
|
|
||||||
F: Fn(&SqliteConnection) -> (),
|
|
||||||
{
|
|
||||||
let conn = establish_connection().unwrap();
|
|
||||||
conn.test_transaction::<_, diesel::result::Error, _>(|| {
|
|
||||||
f(&conn);
|
|
||||||
Ok(())
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn database_connection() {
|
|
||||||
use crate::establish_connection;
|
|
||||||
let conn = establish_connection();
|
|
||||||
assert_eq!(conn.is_ok(), true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,64 @@
|
|||||||
use crate::*;
|
use diesel::prelude::*;
|
||||||
|
use diesel::dsl::{Eq, Filter, Select};
|
||||||
|
use crate::schema::{looted, items};
|
||||||
|
|
||||||
|
/// Represents a unique item in inventory
|
||||||
|
///
|
||||||
|
/// It is also used as a public representation of Loot, since owner
|
||||||
|
/// information is implicit.
|
||||||
|
/// Or maybe this is a little too confusing ??
|
||||||
#[derive(Debug, Queryable, Serialize)]
|
#[derive(Debug, Queryable, Serialize)]
|
||||||
pub struct Item {
|
pub struct Item {
|
||||||
id: i32,
|
id: i32,
|
||||||
name: String,
|
name: String,
|
||||||
base_value: i32,
|
base_price: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
type ItemColumns = ( looted::id, looted::name, looted::base_price, );
|
||||||
|
type OwnedBy = Select<OwnedLoot, ItemColumns>;
|
||||||
|
const ITEM_COLUMNS: ItemColumns = ( looted::id, looted::name, looted::base_price, );
|
||||||
|
|
||||||
|
impl Item {
|
||||||
|
/// Insert this item inside the Looted table.
|
||||||
|
///
|
||||||
|
/// This adds a copy of the item into the group chest,
|
||||||
|
/// to be claimed by players or sold.
|
||||||
|
/// Returns the id of the looted item (differs from the original id)
|
||||||
|
pub fn to_looted(self) -> Result<i32, ()>{
|
||||||
|
// Copy data inside a new Loot
|
||||||
|
// Set the owner id to 0 (group)
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Public proxy for Loot::owned_by that selects only Item fields
|
||||||
|
pub fn owned_by(player: i32) -> OwnedBy {
|
||||||
|
Loot::owned_by(player)
|
||||||
|
.select(ITEM_COLUMNS)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Represents an item that has been looted
|
||||||
|
#[derive(Debug, Queryable, Serialize)]
|
||||||
|
struct Loot {
|
||||||
|
id: i32,
|
||||||
|
name: String,
|
||||||
|
base_value: i32,
|
||||||
|
owner: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
type WithOwner = Eq<looted::owner_id, i32>;
|
||||||
|
type OwnedLoot = Filter<looted::table, WithOwner>;
|
||||||
|
|
||||||
|
impl Loot {
|
||||||
|
/// A filter on Loot that is owned by given player
|
||||||
|
fn owned_by(id: i32) -> OwnedLoot {
|
||||||
|
looted::table
|
||||||
|
.filter(looted::owner_id.eq(id))
|
||||||
|
}
|
||||||
|
/// Delete the item, returning the gained wealth
|
||||||
|
fn sell(_modifier: i8) -> Result<i32, ()> {
|
||||||
|
// Calculate sell value : base_value / 2 * modifier
|
||||||
|
// Delete recording of loot
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
use crate::schema::players;
|
use crate::schema::players;
|
||||||
use crate::serde_derive::Serialize;
|
|
||||||
use crate::*;
|
|
||||||
|
|
||||||
/// Representation of a player in database
|
/// Representation of a player in database
|
||||||
#[derive(Debug, Queryable, Serialize)]
|
#[derive(Debug, Queryable, Serialize)]
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use actix_web::{web, web::Json, Error, HttpResponse, Result};
|
use actix_web::{web, web::Json, Error, HttpResponse, Result};
|
||||||
use futures::Future;
|
use futures::Future;
|
||||||
|
|
||||||
use lootalot_db::{Pool, DbConnection, QueryResult, ActionResult};
|
use lootalot_db::{RunQueryDsl, Pool, DbConnection, QueryResult, ActionResult};
|
||||||
use lootalot_db::{Item, Player};
|
use lootalot_db::{Item, Player};
|
||||||
|
|
||||||
/// A wrapper providing an API over the database
|
/// A wrapper providing an API over the database
|
||||||
@@ -49,7 +49,7 @@ pub struct AsPlayer<'q> {
|
|||||||
impl<'q> AsPlayer<'q> {
|
impl<'q> AsPlayer<'q> {
|
||||||
/// Fetch the content of a player's chest
|
/// Fetch the content of a player's chest
|
||||||
pub fn loot(self) -> QueryResult<Vec<Item>> {
|
pub fn loot(self) -> QueryResult<Vec<Item>> {
|
||||||
Player::fetch_loot(self.id, self.conn)
|
dbg!( Ok( Item::owned_by(self.id).load(self.conn)? ) )
|
||||||
}
|
}
|
||||||
/// Put a claim on a specific item
|
/// Put a claim on a specific item
|
||||||
pub fn claim(self, item: i32) -> ActionResult {
|
pub fn claim(self, item: i32) -> ActionResult {
|
||||||
|
|||||||
Reference in New Issue
Block a user