From 776cbe6d526f65c0be27b1fbb6dc068b9cd495b4 Mon Sep 17 00:00:00 2001 From: fef Date: Mon, 19 Dec 2022 15:45:03 +0100 Subject: [PATCH] add even more fields to user schema --- migrations/20221206184956_create_users.sql | 4 +- src/data/user/pg.rs | 47 +++++++++++----------- src/model/user.rs | 14 +++++++ src/repo/user.rs | 20 ++++++--- 4 files changed, 56 insertions(+), 29 deletions(-) diff --git a/migrations/20221206184956_create_users.sql b/migrations/20221206184956_create_users.sql index 94872f6..0a28a92 100644 --- a/migrations/20221206184956_create_users.sql +++ b/migrations/20221206184956_create_users.sql @@ -3,7 +3,9 @@ CREATE TABLE users ( account_id BIGINT REFERENCES accounts (id), email VARCHAR NOT NULL, password VARCHAR NOT NULL, - activated BOOLEAN NOT NULL DEFAULT FALSE + reason VARCHAR DEFAULT NULL, + activated BOOLEAN NOT NULL DEFAULT FALSE, + locale VARCHAR NOT NULL ); CREATE UNIQUE INDEX index_users_on_email ON users (email); diff --git a/src/data/user/pg.rs b/src/data/user/pg.rs index 4586da9..4e792bc 100644 --- a/src/data/user/pg.rs +++ b/src/data/user/pg.rs @@ -13,11 +13,7 @@ impl PgUserDataSource { PgUserDataSource { pool } } - pub async fn by_id(&self, id: I) -> Result - where - I: Into + Send, - { - let id: Id = id.into(); + pub async fn by_id(&self, id: Id) -> Result { let user: User = sqlx::query_as("SELECT * FROM users WHERE id = $1") .bind(id) .fetch_one(&self.pool) @@ -25,30 +21,35 @@ impl PgUserDataSource { Ok(user) } - pub async fn by_account(&self, account_id: I) -> Result - where - I: Into + Send, - { - let id: Id = account_id.into(); + pub async fn by_account(&self, account_id: Id) -> Result { let user: User = sqlx::query_as("SELECT * FROM users WHERE account_id = $1") - .bind(id) + .bind(account_id) .fetch_one(&self.pool) .await?; Ok(user) } - pub async fn create(&self, new: T) -> Result - where - T: Into + Send, - { - let new = new.into(); - let user: User = - sqlx::query_as("INSERT INTO users (account_id, email, password) VALUES ($1, $2, $3)") - .bind(new.account_id) - .bind(new.email) - .bind(new.password) - .fetch_one(&self.pool) - .await?; + pub async fn by_email(&self, email: &str) -> Result { + let user: User = sqlx::query_as("SELECT * FROM users WHERE email = $1") + .bind(email) + .fetch_one(&self.pool) + .await?; + Ok(user) + } + + pub async fn create(&self, new: NewUser) -> Result { + let user: User = sqlx::query_as( + "INSERT INTO users (account_id, email, password, reason, locale) \ + VALUES ($1, $2, $3, $4, $5) \ + RETURNING *", + ) + .bind(new.account_id) + .bind(new.email) + .bind(new.password) + .bind(new.reason) + .bind(new.locale) + .fetch_one(&self.pool) + .await?; Ok(user) } } diff --git a/src/model/user.rs b/src/model/user.rs index 9fe4eba..b88a8ad 100644 --- a/src/model/user.rs +++ b/src/model/user.rs @@ -2,6 +2,7 @@ use serde::{Deserialize, Serialize}; use sqlx::FromRow; use crate::core::*; +use crate::util::validate::{ResultBuilder, Validate}; #[derive(Deserialize, Serialize, FromRow)] pub struct User { @@ -9,12 +10,17 @@ pub struct User { pub account_id: Id, pub email: String, pub password: String, + pub reason: Option, + pub locale: String, + pub activated: bool, } pub struct NewUser { pub account_id: Id, pub email: String, pub password: String, + pub reason: Option, + pub locale: String, } impl From for Id { @@ -22,3 +28,11 @@ impl From for Id { user.id } } + +impl Validate for NewUser { + fn validate(&self, builder: ResultBuilder) -> ResultBuilder { + builder.field(&self.email, "email", |f| { + f.check("Email must not be empty", |v| v.len() > 0) + }) + } +} diff --git a/src/repo/user.rs b/src/repo/user.rs index df839f8..fd1820f 100644 --- a/src/repo/user.rs +++ b/src/repo/user.rs @@ -19,20 +19,30 @@ impl UserRepo { where I: Into + Send, { - self.db.by_id(id).await + self.db.by_id(id.into()).await } pub async fn by_account(&self, account_id: I) -> Result where I: Into + Send, { - self.db.by_account(account_id).await + self.db.by_account(account_id.into()).await } - pub async fn create(&self, new: T) -> Result + pub async fn by_email(&self, email: T) -> Result where - T: Into + Send, + T: AsRef, { - self.db.create(new).await + self.db.by_email(email.as_ref()).await + } + + pub async fn create(&self, new: T) -> Result + where + T: TryInto, Error = E> + Send, + E: Into, + { + self.db + .create(new.try_into().map_err(|e| e.into())?.inner()) + .await } }