108 lines
2.7 KiB
Rust
108 lines
2.7 KiB
Rust
use crate::prelude::*;
|
|
|
|
/// Creates user and returns its id
|
|
pub async fn create_user(
|
|
user_name: &str,
|
|
user_email: &str,
|
|
hashed_password: &[u8],
|
|
pool: &Pool,
|
|
) -> sqlx::Result<Option<i32>> {
|
|
let Some(record) = sqlx::query!(
|
|
"INSERT INTO users(username, email, hashed_password) VALUES ($1, $2, $3) ON CONFLICT DO NOTHING RETURNING user_id",
|
|
user_name,
|
|
user_email,
|
|
hashed_password
|
|
)
|
|
.fetch_optional(pool)
|
|
.await?
|
|
else {
|
|
return Ok(None);
|
|
};
|
|
let id = record.user_id;
|
|
sqlx::query!(
|
|
"INSERT INTO folders(owner_id, folder_name) VALUES ($1, $2)",
|
|
id,
|
|
"ROOT"
|
|
)
|
|
.execute(pool)
|
|
.await?;
|
|
Ok(Some(id))
|
|
}
|
|
|
|
/// Deletes the user and returns the files that must be deleted
|
|
pub fn delete_user(user_id: i32, pool: &Pool) -> impl Stream<Item = sqlx::Result<Uuid>> + '_ {
|
|
sqlx::query_file!("sql/delete_user.sql", user_id)
|
|
.fetch(pool)
|
|
.map_ok(|record| record.file_id)
|
|
}
|
|
|
|
#[derive(Serialize, Debug)]
|
|
pub struct UserInfo {
|
|
user_id: i32,
|
|
username: String,
|
|
email: String,
|
|
}
|
|
|
|
pub async fn update(
|
|
user_id: i32,
|
|
username: &str,
|
|
email: &str,
|
|
pool: &Pool,
|
|
) -> sqlx::Result<UserInfo> {
|
|
sqlx::query_as!(
|
|
UserInfo,
|
|
"UPDATE users SET username = $2, email = $3 WHERE user_id = $1 RETURNING user_id, username, email",
|
|
user_id,
|
|
username,
|
|
email
|
|
)
|
|
.fetch_one(pool)
|
|
.await
|
|
}
|
|
|
|
pub async fn exists(user_id: i32, pool: &Pool) -> sqlx::Result<bool> {
|
|
sqlx::query!(
|
|
"SELECT EXISTS(SELECT user_id FROM users WHERE user_id = $1)",
|
|
user_id
|
|
)
|
|
.fetch_one(pool)
|
|
.await
|
|
.map(|record| record.exists.unwrap_or(false))
|
|
}
|
|
|
|
pub async fn get(user_id: i32, pool: &Pool) -> sqlx::Result<Option<UserInfo>> {
|
|
sqlx::query_as!(
|
|
UserInfo,
|
|
"SELECT user_id, username, email FROM users WHERE user_id = $1",
|
|
user_id
|
|
)
|
|
.fetch_optional(pool)
|
|
.await
|
|
}
|
|
|
|
/// Gets the hashed password field by either the email or the username
|
|
pub async fn get_hash(search_string: &str, pool: &Pool) -> sqlx::Result<Option<(i32, Vec<u8>)>> {
|
|
let record = sqlx::query!(
|
|
"SELECT user_id, hashed_password FROM users WHERE username = $1 OR email = $1",
|
|
search_string
|
|
)
|
|
.fetch_optional(pool)
|
|
.await?;
|
|
Ok(record.map(|record| (record.user_id, record.hashed_password)))
|
|
}
|
|
|
|
#[derive(Serialize, Debug)]
|
|
pub struct UserSearch {
|
|
pub user_id: i32,
|
|
pub username: String,
|
|
pub email: String,
|
|
pub similarity: f32,
|
|
}
|
|
|
|
pub fn search_for_user<'a>(
|
|
search_string: &str,
|
|
pool: &'a Pool,
|
|
) -> BoxStream<'a, sqlx::Result<UserSearch>> {
|
|
sqlx::query_file_as!(UserSearch, "sql/search_for_user.sql", search_string).fetch(pool)
|
|
}
|