Set up the user interface state model and set up the admin user onboarding #283
|
@ -0,0 +1,16 @@
|
|||
CREATE TABLE users(
|
||||
uuid TEXT PRIMARY KEY,
|
||||
name TEXT,
|
||||
password TEXT,
|
||||
admin BOOLEAN,
|
||||
enabled BOOLEAN
|
||||
);
|
||||
|
||||
CREATE TABLE roles(
|
||||
user_id TEXT,
|
||||
game_id TEXT,
|
||||
role TEXT,
|
||||
|
||||
FOREIGN KEY(user_id) REFERENCES users(uuid),
|
||||
FOREIGN KEY(game_id) REFERENCES games(uuid)
|
||||
);
|
|
@ -48,12 +48,62 @@ enum DatabaseResponse {
|
|||
Charsheet(Option<CharsheetRow>),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
|
||||
pub struct UserId(String);
|
||||
|
||||
impl UserId {
|
||||
pub fn new() -> Self {
|
||||
Self(format!("{}", Uuid::new_v4().hyphenated()))
|
||||
}
|
||||
|
||||
pub fn as_str<'a>(&'a self) -> &'a str {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&str> for UserId {
|
||||
fn from(s: &str) -> Self {
|
||||
Self(s.to_owned())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for UserId {
|
||||
fn from(s: String) -> Self {
|
||||
Self(s)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
|
||||
pub struct GameId(String);
|
||||
|
||||
impl GameId {
|
||||
pub fn new() -> Self {
|
||||
Self(format!("{}", Uuid::new_v4().hyphenated()))
|
||||
}
|
||||
|
||||
pub fn as_str<'a>(&'a self) -> &'a str {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&str> for GameId {
|
||||
fn from(s: &str) -> Self {
|
||||
Self(s.to_owned())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for GameId {
|
||||
fn from(s: String) -> Self {
|
||||
Self(s)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
|
||||
pub struct CharacterId(String);
|
||||
|
||||
impl CharacterId {
|
||||
pub fn new() -> Self {
|
||||
CharacterId(format!("{}", Uuid::new_v4().hyphenated()))
|
||||
Self(format!("{}", Uuid::new_v4().hyphenated()))
|
||||
}
|
||||
|
||||
pub fn as_str<'a>(&'a self) -> &'a str {
|
||||
|
@ -63,20 +113,36 @@ impl CharacterId {
|
|||
|
||||
impl From<&str> for CharacterId {
|
||||
fn from(s: &str) -> Self {
|
||||
CharacterId(s.to_owned())
|
||||
Self(s.to_owned())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for CharacterId {
|
||||
fn from(s: String) -> Self {
|
||||
CharacterId(s)
|
||||
Self(s)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct UserRow {
|
||||
id: String,
|
||||
name: String,
|
||||
password: String,
|
||||
admin: bool,
|
||||
enabled: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Role {
|
||||
userid: String,
|
||||
gameid: String,
|
||||
role: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct CharsheetRow {
|
||||
id: String,
|
||||
gametype: String,
|
||||
game: String,
|
||||
pub data: serde_json::Value,
|
||||
}
|
||||
|
||||
|
@ -93,11 +159,20 @@ fn setup_test_database(conn: &Connection) {
|
|||
let mut gamecount_stmt = conn.prepare("SELECT count(*) FROM games").unwrap();
|
||||
let mut count = gamecount_stmt.query([]).unwrap();
|
||||
if count.next().unwrap().unwrap().get::<usize, usize>(0) == Ok(0) {
|
||||
let admin_id = format!("{}", Uuid::new_v4());
|
||||
let user_id = format!("{}", Uuid::new_v4());
|
||||
let game_id = format!("{}", Uuid::new_v4());
|
||||
let char_id = CharacterId::new();
|
||||
|
||||
let mut user_stmt = conn.prepare("INSERT INTO users VALUES (?, ?, ?, ?, ?)").unwrap();
|
||||
user_stmt.execute((admin_id.clone(), "admin", "abcdefg", true, true)).unwrap();
|
||||
user_stmt.execute((user_id.clone(), "savanni", "abcdefg", false, true)).unwrap();
|
||||
|
||||
let mut game_stmt = conn.prepare("INSERT INTO games VALUES (?, ?)").unwrap();
|
||||
game_stmt.execute((game_id.clone(), "Circle of Bluest Sky"));
|
||||
game_stmt.execute((game_id.clone(), "Circle of Bluest Sky")).unwrap();
|
||||
|
||||
let mut role_stmt = conn.prepare("INSERT INTO roles VALUES (?, ?, ?)").unwrap();
|
||||
role_stmt.execute((user_id.clone(), game_id.clone(), "gm")).unwrap();
|
||||
|
||||
let mut sheet_stmt = conn
|
||||
.prepare("INSERT INTO characters VALUES (?, ?, ?)")
|
||||
|
@ -124,17 +199,37 @@ impl DiskDb {
|
|||
Ok(DiskDb { conn })
|
||||
}
|
||||
|
||||
fn user(&self, id: UserId) -> Result<Option<UserRow>, Error> {
|
||||
let mut stmt = self
|
||||
.conn
|
||||
.prepare("SELECT uuid, name, password, admin, enabled WHERE uuid=?")
|
||||
.unwrap();
|
||||
let items: Vec<UserRow> = stmt
|
||||
.query_map([id.as_str()], |row| Ok(UserRow {
|
||||
id: row.get(0).unwrap(),
|
||||
name: row.get(1).unwrap(),
|
||||
password: row.get(2).unwrap(),
|
||||
admin: row.get(3).unwrap(),
|
||||
enabled: row.get(4).unwrap(),
|
||||
})).unwrap().collect::<Result<Vec<UserRow>, rusqlite::Error>>().unwrap();
|
||||
match &items[..] {
|
||||
[] => Ok(None),
|
||||
[item] => Ok(Some(item.clone())),
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn charsheet(&self, id: CharacterId) -> Result<Option<CharsheetRow>, Error> {
|
||||
let mut stmt = self
|
||||
.conn
|
||||
.prepare("SELECT uuid, gametype, data FROM charsheet WHERE uuid=?")
|
||||
.prepare("SELECT uuid, game, data FROM charsheet WHERE uuid=?")
|
||||
.unwrap();
|
||||
let items: Vec<CharsheetRow> = stmt
|
||||
.query_map([id.as_str()], |row| {
|
||||
let data: String = row.get(2).unwrap();
|
||||
Ok(CharsheetRow {
|
||||
id: row.get(0).unwrap(),
|
||||
gametype: row.get(1).unwrap(),
|
||||
game: row.get(1).unwrap(),
|
||||
data: serde_json::from_str(&data).unwrap(),
|
||||
})
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue