diff options
Diffstat (limited to 'src/user/repo.rs')
| -rw-r--r-- | src/user/repo.rs | 108 |
1 files changed, 60 insertions, 48 deletions
diff --git a/src/user/repo.rs b/src/user/repo.rs index 0f67e9a..aaf3b73 100644 --- a/src/user/repo.rs +++ b/src/user/repo.rs @@ -3,9 +3,10 @@ use sqlx::{SqliteConnection, Transaction, sqlite::Sqlite}; use crate::{ clock::DateTime, + db::NotFound, event::{Instant, Sequence}, + login::Login, name::{self, Name}, - password::StoredHash, user::{History, Id, User}, }; @@ -24,62 +25,58 @@ pub struct Users<'t>(&'t mut SqliteConnection); impl Users<'_> { pub async fn create( &mut self, - name: &Name, - password_hash: &StoredHash, + login: &Login, created: &Instant, ) -> Result<History, sqlx::Error> { - let id = Id::generate(); - let display_name = name.display(); - let canonical_name = name.canonical(); - sqlx::query!( r#" - insert - into user (id, display_name, canonical_name, password_hash, created_sequence, created_at) - values ($1, $2, $3, $4, $5, $6) + insert into user (id, created_sequence, created_at) + values ($1, $2, $3) "#, - id, - display_name, - canonical_name, - password_hash, + login.id, created.sequence, created.at, ) .execute(&mut *self.0) .await?; - let user = History { - created: *created, + Ok(History { user: User { - id, - name: name.clone(), + id: login.id.clone().into(), + name: login.name.clone(), }, - }; - - Ok(user) + created: *created, + }) } - pub async fn set_password( - &mut self, - login: &History, - to: &StoredHash, - ) -> Result<(), sqlx::Error> { - let login = login.id(); - - sqlx::query_scalar!( + pub async fn by_login(&mut self, login: &Login) -> Result<History, LoadError> { + let user = sqlx::query!( r#" - update user - set password_hash = $1 - where id = $2 - returning id as "id: Id" + select + id as "id: Id", + login.display_name as "display_name: String", + login.canonical_name as "canonical_name: String", + user.created_at as "created_at: DateTime", + user.created_sequence as "created_sequence: Sequence" + from user + join login using (id) + where id = $1 "#, - to, - login, + login.id, ) + .map(|row| { + Ok::<_, LoadError>(History { + user: User { + id: row.id, + name: Name::new(row.display_name, row.canonical_name)?, + }, + created: Instant::new(row.created_at, row.created_sequence), + }) + }) .fetch_one(&mut *self.0) - .await?; + .await??; - Ok(()) + Ok(user) } pub async fn all(&mut self, resume_at: Sequence) -> Result<Vec<History>, LoadError> { @@ -87,13 +84,14 @@ impl Users<'_> { r#" select id as "id: Id", - display_name as "display_name: String", - canonical_name as "canonical_name: String", - created_sequence as "created_sequence: Sequence", - created_at as "created_at: DateTime" + login.display_name as "display_name: String", + login.canonical_name as "canonical_name: String", + user.created_sequence as "created_sequence: Sequence", + user.created_at as "created_at: DateTime" from user - where created_sequence <= $1 - order by canonical_name + join login using (id) + where user.created_sequence <= $1 + order by canonical_name "#, resume_at, ) @@ -119,12 +117,13 @@ impl Users<'_> { r#" select id as "id: Id", - display_name as "display_name: String", - canonical_name as "canonical_name: String", - created_sequence as "created_sequence: Sequence", - created_at as "created_at: DateTime" + login.display_name as "display_name: String", + login.canonical_name as "canonical_name: String", + user.created_sequence as "created_sequence: Sequence", + user.created_at as "created_at: DateTime" from user - where created_sequence > $1 + join login using (id) + where user.created_sequence > $1 "#, resume_at, ) @@ -152,3 +151,16 @@ pub enum LoadError { Database(#[from] sqlx::Error), Name(#[from] name::Error), } + +impl<T> NotFound for Result<T, LoadError> { + type Ok = T; + type Error = LoadError; + + fn optional(self) -> Result<Option<T>, LoadError> { + match self { + Ok(value) => Ok(Some(value)), + Err(LoadError::Database(sqlx::Error::RowNotFound)) => Ok(None), + Err(other) => Err(other), + } + } +} |
