Compare commits

..

1 Commits

Author SHA1 Message Date
projectmoon 5d002e5063 Add ability to store user active room, with skeleton accounts.
continuous-integration/drone/pr Build is passing Details
continuous-integration/drone/push Build is passing Details
- Adds a user_state table, currently only with active_room.
 - A user must have an account to take advantage of state.
 - Now, all users will get an 'account' even if they don't explicitly register.
 - Bonus: converts user queries to compile-time checked macros.

To support these automatically created "accounts," the accounts table
now also has an account_status column, indicating if the user is
registered or not (or pending activation--future use).

The User model has been updated with extra properties from the state,
and the user is now carrried in the Context during command execution.
A user is ensured to be created before executing the command.
2021-05-25 22:29:01 +00:00
2 changed files with 54 additions and 16 deletions

View File

@ -18,6 +18,26 @@
]
}
},
"26903a92a7de34df3e227fe599e41ae1bb61612eb80befad398383af36df0ce4": {
"query": "DELETE FROM accounts WHERE user_id = ?",
"describe": {
"columns": [],
"parameters": {
"Right": 1
},
"nullable": []
}
},
"2d4a32735da04509c2e3c4f99bef79ef699964f58ae332b0611f3de088596e1e": {
"query": "INSERT INTO accounts (user_id, password, account_status)\n VALUES (?, ?, ?)\n ON CONFLICT(user_id) DO\n UPDATE SET password = ?, account_status = ?",
"describe": {
"columns": [],
"parameters": {
"Right": 5
},
"nullable": []
}
},
"59313c67900a1a9399389720b522e572f181ae503559cd2b49d6305acb9e2207": {
"query": "SELECT key, value as \"value: i32\" FROM user_variables\n WHERE room_id = ? AND user_id = ?",
"describe": {
@ -60,6 +80,16 @@
]
}
},
"667b26343ce44e1c48ac689ce887ef6a0558a2ce199f7372a5dce58672499c5a": {
"query": "INSERT INTO user_state (user_id, active_room)\n VALUES (?, ?)\n ON CONFLICT(user_id) DO\n UPDATE SET active_room = ?",
"describe": {
"columns": [],
"parameters": {
"Right": 3
},
"nullable": []
}
},
"711d222911c1258365a6a0de1fe00eeec4686fd3589e976e225ad599e7cfc75d": {
"query": "SELECT count(*) as \"count: i32\" FROM user_variables\n WHERE room_id = ? and user_id = ?",
"describe": {
@ -95,5 +125,15 @@
false
]
}
},
"dce9bb45cf954054a920ee8b53852c6d562e3588d76bbfaa1433d8309d4e4921": {
"query": "DELETE FROM user_state WHERE user_id = ?",
"describe": {
"columns": [],
"parameters": {
"Right": 1
},
"nullable": []
}
}
}

View File

@ -10,29 +10,29 @@ impl Users for Database {
async fn upsert_user(&self, user: &User) -> Result<(), DataError> {
let mut tx = self.conn.begin().await?;
sqlx::query(
sqlx::query!(
r#"INSERT INTO accounts (user_id, password, account_status)
VALUES (?, ?, ?)
ON CONFLICT(user_id) DO
UPDATE SET password = ?, account_status = ?"#,
user.username,
user.password,
user.account_status,
user.password,
user.account_status
)
.bind(&user.username)
.bind(&user.password)
.bind(&user.account_status)
.bind(&user.password)
.bind(&user.account_status)
.execute(&mut tx)
.await?;
sqlx::query(
sqlx::query!(
r#"INSERT INTO user_state (user_id, active_room)
VALUES (?, ?)
ON CONFLICT(user_id) DO
UPDATE SET active_room = ?"#,
user.username,
user.active_room,
user.active_room
)
.bind(&user.username)
.bind(&user.active_room)
.bind(&user.active_room)
.execute(&mut tx)
.await?;
@ -43,13 +43,11 @@ impl Users for Database {
async fn delete_user(&self, username: &str) -> Result<(), DataError> {
let mut tx = self.conn.begin().await?;
sqlx::query(r#"DELETE FROM accounts WHERE user_id = ?"#)
.bind(&username)
sqlx::query!(r#"DELETE FROM accounts WHERE user_id = ?"#, username)
.execute(&mut tx)
.await?;
sqlx::query(r#"DELETE FROM user_state WHERE user_id = ?"#)
.bind(&username)
sqlx::query!(r#"DELETE FROM user_state WHERE user_id = ?"#, username)
.execute(&mut tx)
.await?;
@ -199,7 +197,7 @@ mod tests {
.upsert_user(&User {
username: "myuser".to_string(),
password: Some("abc".to_string()),
account_status: AccountStatus::Registered,
account_status: AccountStatus::AwaitingActivation,
active_room: Some("myroom".to_string()),
})
.await;
@ -220,9 +218,9 @@ mod tests {
let user = user.unwrap();
assert_eq!(user.username, "myuser");
assert_eq!(user.password, Some("abc".to_string()));
assert_eq!(user.account_status, AccountStatus::AwaitingActivation);
//These should be default values because the state record is missing.
assert_eq!(user.account_status, AccountStatus::NotRegistered);
assert_eq!(user.active_room, None);
}