Compare commits

2 Commits

Author SHA1 Message Date
ed3ac2abcb adds notifications table and models 2019-10-19 21:59:17 +02:00
2248e25aec split player module 2019-10-19 21:44:10 +02:00
8 changed files with 180 additions and 111 deletions

View File

@@ -0,0 +1 @@
DROP TABLE notifications;

View File

@@ -0,0 +1,6 @@
CREATE TABLE notifications (
id INTEGER PRIMARY KEY NOT NULL,
player_id INTEGER NOT NULL,
text VARCHAR NOT NULL,
FOREIGN KEY (player_id) REFERENCES players(id)
);

View File

@@ -124,16 +124,8 @@ mod tests {
let manager = models::player::Players(&conn); let manager = models::player::Players(&conn);
manager.add("Player1", 0.0)?; manager.add("Player1", 0.0)?;
manager.add("Player2", 0.0)?; manager.add("Player2", 0.0)?;
crate::LootManager(&conn, 0).add_from(&crate::Item { crate::LootManager(&conn, 0).add("Epee", 30)?;
id: 0, crate::LootManager(&conn, 1).add("Arc", 20)?;
name: "Epee".to_string(),
base_price: 30,
})?;
crate::LootManager(&conn, 1).add_from(&crate::Item {
id: 0,
name: "Arc".to_string(),
base_price: 20,
})?;
Ok(conn) Ok(conn)
} }

View File

@@ -124,6 +124,14 @@ impl<'q> LootManager<'q> {
.first(self.0)?) .first(self.0)?)
} }
pub(crate) fn add<S: Into<String>>(self, name: S, base_price: i32) -> QueryResult<Item> {
self.add_from(&Item {
id: 0,
name: name.into(),
base_price,
})
}
/// Adds a copy of the given item inside player chest /// Adds a copy of the given item inside player chest
pub fn add_from(self, item: &Item) -> QueryResult<Item> { pub fn add_from(self, item: &Item) -> QueryResult<Item> {
let new_item = NewLoot { let new_item = NewLoot {

View File

@@ -0,0 +1,112 @@
use crate::schema::players;
use crate::{DbConnection, QueryResult};
use diesel::prelude::*;
mod notification;
pub mod wealth;
pub use wealth::Wealth;
/// Representation of a player in database
#[derive(Identifiable, Queryable, Serialize, Deserialize, Debug)]
pub struct Player {
/// DB Identitier
pub id: i32,
/// Full name of the character
pub name: String,
/// Amount of gold coins owed to the group.
/// Taking a looted items will increase the debt by it's sell value
pub debt: i32,
/// Count of copper pieces
pub cp: i32,
/// Count of silver pieces
pub sp: i32,
/// Count of gold pieces
pub gp: i32,
/// Count of platinum pieces
pub pp: i32,
}
/// Manager for players
pub struct Players<'q>(pub &'q DbConnection);
impl<'q> Players<'q> {
/// Get all players from database
pub fn all(&self) -> QueryResult<Vec<Player>> {
players::table.load(self.0)
}
/// Find a player by id
pub fn find(&self, id: i32) -> QueryResult<Player> {
players::table.find(id).first(self.0)
}
/// Add a new player with name and starting wealth
pub fn add(&self, name: &str, wealth: f64) -> QueryResult<Player> {
diesel::insert_into(players::table)
.values(&NewPlayer::create(name, wealth))
.execute(self.0)?;
players::table.order(players::dsl::id.desc()).first(self.0)
}
/// Notify all players of an event
pub fn notifiy_all<S: Into<String>>(&self, text: S) -> QueryResult<()> {
Err(diesel::result::Error::NotFound)
}
/// Notify a single player of an event
pub fn notify<S: Into<String>>(&self, id: i32, text: S) -> QueryResult<()> {
Err(diesel::result::Error::NotFound)
}
}
/// Wrapper for action of a single player
pub struct AsPlayer<'q>(pub &'q DbConnection, pub i32);
impl<'q> AsPlayer<'q> {
/// Updates this player's wealth, returning the difference
pub fn update_wealth(&self, value_in_gp: f64) -> QueryResult<Wealth> {
use crate::schema::players::dsl::*;
let current_wealth = players
.find(self.1)
.select((cp, sp, gp, pp))
.first::<Wealth>(self.0)?;
let updated_wealth = Wealth::from_gp(current_wealth.to_gp() + value_in_gp);
diesel::update(players)
.filter(id.eq(self.1))
.set(&updated_wealth)
.execute(self.0)?;
Ok(updated_wealth - current_wealth)
}
/// Updates this player's debt
pub fn update_debt(&self, value_in_gp: i32) -> QueryResult<()> {
diesel::update(players::table.find(self.1))
.set(players::dsl::debt.eq(players::dsl::debt + value_in_gp))
.execute(self.0)?;
Ok(())
}
}
/// Representation of a new player record
#[derive(Insertable)]
#[table_name = "players"]
struct NewPlayer<'a> {
name: &'a str,
cp: i32,
sp: i32,
gp: i32,
pp: i32,
}
impl<'a> NewPlayer<'a> {
fn create(name: &'a str, wealth_in_gp: f64) -> Self {
let (cp, sp, gp, pp) = Wealth::from_gp(wealth_in_gp).as_tuple();
Self {
name,
cp,
sp,
gp,
pp,
}
}
}

View File

@@ -0,0 +1,35 @@
use diesel::prelude::*;
use crate::{
DbConnection,
schema::notifications,
models::player::Player,
};
#[derive(Identifiable, Queryable, Associations, Serialize, Debug)]
#[belongs_to(Player)]
struct Notification {
pub id: i32,
pub player_id: i32,
pub text: String,
}
impl Notification {
fn add<'a, S: Into<&'a str>>(conn: &DbConnection, id: i32, text: S) -> QueryResult<Notification> {
diesel::insert_into(notifications::table)
.values(&NewNotification {
player_id: id,
text: text.into(),
})
.execute(conn)?;
notifications::table
.order(notifications::dsl::id.desc())
.first(conn)
}
}
#[derive(Insertable)]
#[table_name="notifications"]
struct NewNotification<'a> {
player_id: i32,
text: &'a str,
}

View File

@@ -1,80 +1,4 @@
use crate::schema::players; use crate::schema::players;
use crate::{DbConnection, QueryResult};
use diesel::prelude::*;
/// Representation of a player in database
#[derive(Identifiable, Queryable, Serialize, Deserialize, Debug)]
pub struct Player {
/// DB Identitier
pub id: i32,
/// Full name of the character
pub name: String,
/// Amount of gold coins owed to the group.
/// Taking a looted items will increase the debt by it's sell value
pub debt: i32,
/// Count of copper pieces
pub cp: i32,
/// Count of silver pieces
pub sp: i32,
/// Count of gold pieces
pub gp: i32,
/// Count of platinum pieces
pub pp: i32,
}
pub struct Players<'q>(pub &'q DbConnection);
impl<'q> Players<'q> {
/// Get all players from database
pub fn all(&self) -> QueryResult<Vec<Player>> {
players::table.load(self.0)
}
/// Find a player by id
pub fn find(&self, id: i32) -> QueryResult<Player> {
players::table.find(id).first(self.0)
}
/// Add a new player with name and starting wealth
pub fn add(&self, name: &str, wealth: f64) -> QueryResult<Player> {
diesel::insert_into(players::table)
.values(&NewPlayer::create(name, wealth))
.execute(self.0)?;
players::table.order(players::dsl::id.desc()).first(self.0)
}
/// Notify all players of an event
pub fn notifiy_all<S: Into<String>>(&self, text: S) -> QueryResult<()> {
Err(diesel::result::Error::NotFound)
}
}
pub struct AsPlayer<'q>(pub &'q DbConnection, pub i32);
impl<'q> AsPlayer<'q> {
/// Updates this player's wealth, returning the difference
pub fn update_wealth(&self, value_in_gp: f64) -> QueryResult<Wealth> {
use crate::schema::players::dsl::*;
let current_wealth = players
.find(self.1)
.select((cp, sp, gp, pp))
.first::<Wealth>(self.0)?;
let updated_wealth = Wealth::from_gp(current_wealth.to_gp() + value_in_gp);
diesel::update(players)
.filter(id.eq(self.1))
.set(&updated_wealth)
.execute(self.0)?;
Ok(updated_wealth - current_wealth)
}
/// Updates this player's debt
pub fn update_debt(&self, value_in_gp: i32) -> QueryResult<()> {
diesel::update(players::table.find(self.1))
.set(players::dsl::debt.eq(players::dsl::debt + value_in_gp))
.execute(self.0)?;
Ok(())
}
}
/// Unpack a floating value of gold pieces to integer /// Unpack a floating value of gold pieces to integer
/// values of copper, silver, gold and platinum pieces /// values of copper, silver, gold and platinum pieces
@@ -167,30 +91,6 @@ impl std::ops::Add for Wealth {
} }
} }
/// Representation of a new player record
#[derive(Insertable)]
#[table_name = "players"]
struct NewPlayer<'a> {
name: &'a str,
cp: i32,
sp: i32,
gp: i32,
pp: i32,
}
impl<'a> NewPlayer<'a> {
fn create(name: &'a str, wealth_in_gp: f64) -> Self {
let (cp, sp, gp, pp) = Wealth::from_gp(wealth_in_gp).as_tuple();
Self {
name,
cp,
sp,
gp,
pp,
}
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {

View File

@@ -24,6 +24,14 @@ table! {
} }
} }
table! {
notifications (id) {
id -> Integer,
player_id -> Integer,
text -> Text,
}
}
table! { table! {
players (id) { players (id) {
id -> Integer, id -> Integer,
@@ -39,5 +47,12 @@ table! {
joinable!(claims -> looted (loot_id)); joinable!(claims -> looted (loot_id));
joinable!(claims -> players (player_id)); joinable!(claims -> players (player_id));
joinable!(looted -> players (owner_id)); joinable!(looted -> players (owner_id));
joinable!(notifications -> players (player_id));
allow_tables_to_appear_in_same_query!(claims, items, looted, players,); allow_tables_to_appear_in_same_query!(
claims,
items,
looted,
notifications,
players,
);