161 lines
4.1 KiB
Rust
161 lines
4.1 KiB
Rust
use sqlx::{PgPool, Postgres};
|
|
|
|
use crate::model::member::Roles;
|
|
|
|
use super::Member as DbMember;
|
|
|
|
#[derive(validator::Validate)]
|
|
pub struct User {
|
|
pub user_id: uuid::Uuid,
|
|
#[validate(email)]
|
|
pub email: String,
|
|
pub password: Option<String>,
|
|
pub admin: bool,
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct UpdateUser {
|
|
pub email: Option<String>,
|
|
pub password: Option<String>,
|
|
pub admin: Option<bool>,
|
|
}
|
|
|
|
impl User {
|
|
pub async fn insert(
|
|
transaction: &mut sqlx::Transaction<'_, Postgres>,
|
|
email: &str,
|
|
password: &str,
|
|
) -> Result<uuid::Uuid, sqlx::Error> {
|
|
let user_id = uuid::Uuid::new_v4();
|
|
|
|
sqlx::query!(
|
|
"
|
|
INSERT INTO users (
|
|
user_id, email, password, admin
|
|
)
|
|
VALUES (
|
|
$1, $2, $3, $4
|
|
);
|
|
",
|
|
&user_id,
|
|
email,
|
|
password,
|
|
false
|
|
)
|
|
.execute(&mut **transaction)
|
|
.await?;
|
|
|
|
Ok(user_id)
|
|
}
|
|
|
|
pub async fn get_from_email(transaction: &PgPool, email: String) -> Result<Self, sqlx::Error> {
|
|
let user = sqlx::query_as!(Self, "SELECT * FROM users WHERE email = $1", email)
|
|
.fetch_one(transaction)
|
|
.await?;
|
|
|
|
Ok(user)
|
|
}
|
|
|
|
pub async fn get(transaction: &PgPool, user_id: uuid::Uuid) -> Result<Self, sqlx::Error> {
|
|
let user = sqlx::query_as!(Self, "SELECT * FROM users WHERE user_id = $1", user_id)
|
|
.fetch_one(transaction)
|
|
.await?;
|
|
|
|
Ok(user)
|
|
}
|
|
|
|
pub async fn get_password(&self, pool: &PgPool) -> Result<String, sqlx::Error> {
|
|
let password = sqlx::query_scalar!(
|
|
"
|
|
SELECT password FROM users WHERE user_id = $1
|
|
",
|
|
self.user_id,
|
|
)
|
|
.fetch_one(pool)
|
|
.await?;
|
|
|
|
Ok(password)
|
|
}
|
|
|
|
pub async fn update(
|
|
&self,
|
|
transaction: &mut sqlx::Transaction<'_, Postgres>,
|
|
update_user: UpdateUser,
|
|
) -> Result<(), sqlx::Error> {
|
|
sqlx::query!(
|
|
"
|
|
UPDATE users
|
|
SET email = coalesce($1, email),
|
|
password = coalesce($2, password)
|
|
WHERE user_id = $3;
|
|
",
|
|
update_user.email,
|
|
update_user.password,
|
|
self.user_id
|
|
)
|
|
.execute(&mut **transaction)
|
|
.await?;
|
|
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct UserMember {
|
|
user_id: uuid::Uuid,
|
|
member_id: String,
|
|
}
|
|
|
|
impl UserMember {
|
|
pub async fn insert_many(
|
|
transaction: &mut sqlx::Transaction<'_, Postgres>,
|
|
user_ids: &[uuid::Uuid],
|
|
member_ids: &[String],
|
|
) -> Result<(), sqlx::Error> {
|
|
sqlx::query!(
|
|
"
|
|
INSERT INTO users_members (
|
|
user_id, member_id
|
|
)
|
|
SELECT * FROM UNNEST($1::uuid[], $2::varchar[])
|
|
",
|
|
&user_ids[..],
|
|
&member_ids[..]
|
|
)
|
|
.execute(&mut **transaction)
|
|
.await?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
pub async fn get_roles(pool: &PgPool, user_id: &uuid::Uuid) -> Result<Roles, sqlx::Error> {
|
|
let roles = sqlx::query_scalar!(
|
|
"
|
|
SELECT roles FROM users_members INNER JOIN members ON users_members.member_id = members.member_id AND users_members.user_id = $1;
|
|
",
|
|
user_id
|
|
).fetch_all(pool).await?;
|
|
|
|
let roles: Vec<Roles> = roles.into_iter().map(|r| r.into()).collect();
|
|
let roles = roles
|
|
.into_iter()
|
|
.fold(Roles::empty(), |acc, flag| acc | flag);
|
|
|
|
Ok(roles)
|
|
}
|
|
|
|
pub async fn get_members_from_user(
|
|
pool: &PgPool,
|
|
user_id: &uuid::Uuid,
|
|
) -> Result<Vec<DbMember>, sqlx::Error> {
|
|
let members = sqlx::query_as!(DbMember,
|
|
"
|
|
SELECT members.* FROM users_members INNER JOIN members ON users_members.member_id = members.member_id AND users_members.user_id = $1;
|
|
",
|
|
user_id
|
|
).fetch_all(pool).await?;
|
|
|
|
Ok(members)
|
|
}
|
|
}
|