use query_as instead of manual mapping

This commit is contained in:
philipp 2023-07-31 16:33:44 +02:00
parent dc4b4b3499
commit 32e6148844
4 changed files with 19 additions and 104 deletions

View File

@ -172,10 +172,7 @@ ORDER BY amount_seats DESC
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use crate::{ use crate::{
model::{ model::boat::{Boat, BoatToAdd},
boat::{Boat, BoatToAdd},
location::Location,
},
testdb, testdb,
}; };
@ -333,7 +330,6 @@ mod test {
fn test_succ_update() { fn test_succ_update() {
let pool = testdb!(); let pool = testdb!();
let boat = Boat::find_by_id(&pool, 1).await.unwrap(); let boat = Boat::find_by_id(&pool, 1).await.unwrap();
let location = Location::find_by_id(&pool, 1).await.unwrap();
let update = BoatToUpdate { let update = BoatToUpdate {
name: "my-new-boat-name", name: "my-new-boat-name",
amount_seats: 3, amount_seats: 3,
@ -356,7 +352,6 @@ mod test {
fn test_failed_update() { fn test_failed_update() {
let pool = testdb!(); let pool = testdb!();
let boat = Boat::find_by_id(&pool, 1).await.unwrap(); let boat = Boat::find_by_id(&pool, 1).await.unwrap();
let location = Location::find_by_id(&pool, 1).await.unwrap();
let update = BoatToUpdate { let update = BoatToUpdate {
name: "my-new-boat-name", name: "my-new-boat-name",
amount_seats: 3, amount_seats: 3,

View File

@ -1,4 +1,3 @@
use rocket::form::FromFormField;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use sqlx::{FromRow, SqlitePool}; use sqlx::{FromRow, SqlitePool};

View File

@ -1,10 +1,7 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use sqlx::{FromRow, Sqlite, SqlitePool, Transaction}; use sqlx::{FromRow, Sqlite, SqlitePool, Transaction};
use super::{ use super::{logbook::Logbook, user::User};
logbook::Logbook,
user::{MyNaiveDateTime, User},
};
#[derive(FromRow, Debug, Serialize, Deserialize)] #[derive(FromRow, Debug, Serialize, Deserialize)]
pub struct Rower { pub struct Rower {
@ -14,7 +11,8 @@ pub struct Rower {
impl Rower { impl Rower {
pub async fn for_log(db: &SqlitePool, log: &Logbook) -> Vec<User> { pub async fn for_log(db: &SqlitePool, log: &Logbook) -> Vec<User> {
sqlx::query!( sqlx::query_as!(
User,
" "
SELECT id, name, pw, is_cox, is_admin, is_guest, deleted, last_access SELECT id, name, pw, is_cox, is_admin, is_guest, deleted, last_access
FROM user FROM user
@ -25,18 +23,6 @@ WHERE id in (SELECT rower_id FROM rower WHERE logbook_id=?)
.fetch_all(db) .fetch_all(db)
.await .await
.unwrap() .unwrap()
.into_iter()
.map(|row| User {
id: row.id,
name: row.name,
pw: row.pw,
is_cox: row.is_cox,
is_admin: row.is_admin,
is_guest: row.is_guest,
deleted: row.deleted,
last_access: row.last_access.map(MyNaiveDateTime),
})
.collect()
} }
pub async fn create(db: &mut Transaction<'_, Sqlite>, logbook_id: i64, rower_id: i64) { pub async fn create(db: &mut Transaction<'_, Sqlite>, logbook_id: i64, rower_id: i64) {

View File

@ -1,44 +1,21 @@
use std::ops::Deref; use std::ops::Deref;
use argon2::{password_hash::SaltString, Argon2, PasswordHasher}; use argon2::{password_hash::SaltString, Argon2, PasswordHasher};
use chrono::{Datelike, Local, NaiveDate, NaiveDateTime}; use chrono::{Datelike, Local, NaiveDate};
use log::info; use log::info;
use rocket::{ use rocket::{
async_trait, async_trait,
form::{self, FromFormField, ValueField},
http::{Cookie, Status}, http::{Cookie, Status},
request::{self, FromRequest, Outcome}, request::{self, FromRequest, Outcome},
time::{Duration, OffsetDateTime}, time::{Duration, OffsetDateTime},
FromForm, Request, Request,
}; };
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use sqlx::{sqlite::SqliteValueRef, Decode, FromRow, SqlitePool}; use sqlx::{FromRow, SqlitePool};
use super::{log::Log, tripdetails::TripDetails, Day}; use super::{log::Log, tripdetails::TripDetails, Day};
#[derive(Debug, Serialize, Deserialize)] #[derive(FromRow, Debug, Serialize, Deserialize)]
pub struct MyNaiveDateTime(pub chrono::NaiveDateTime);
impl<'r> Decode<'r, sqlx::Sqlite> for MyNaiveDateTime {
fn decode(value: SqliteValueRef<'r>) -> Result<Self, Box<dyn std::error::Error + Send + Sync>> {
let dt: NaiveDateTime = Decode::decode(value)?;
Ok(MyNaiveDateTime(dt))
}
}
#[rocket::async_trait]
impl<'r> FromFormField<'r> for MyNaiveDateTime {
fn from_value(field: ValueField<'r>) -> form::Result<'r, Self> {
let dt = NaiveDateTime::parse_from_str(field.value, "%Y-%m-%d %H:%M:%S");
match dt {
Ok(parsed_dt) => Ok(MyNaiveDateTime(parsed_dt)),
Err(_) => Err(rocket::form::Error::validation("Invalid date/time format.").into()),
}
}
}
#[derive(FromRow, Debug, Serialize, Deserialize, FromForm)]
pub struct User { pub struct User {
pub id: i64, pub id: i64,
pub name: String, pub name: String,
@ -47,7 +24,7 @@ pub struct User {
pub is_admin: bool, pub is_admin: bool,
pub is_guest: bool, pub is_guest: bool,
pub deleted: bool, pub deleted: bool,
pub last_access: Option<MyNaiveDateTime>, pub last_access: Option<chrono::NaiveDateTime>,
} }
#[derive(Debug)] #[derive(Debug)]
@ -87,7 +64,8 @@ impl User {
} }
pub async fn find_by_id(db: &SqlitePool, id: i32) -> Option<Self> { pub async fn find_by_id(db: &SqlitePool, id: i32) -> Option<Self> {
let row = sqlx::query!( sqlx::query_as!(
Self,
" "
SELECT id, name, pw, is_cox, is_admin, is_guest, deleted, last_access SELECT id, name, pw, is_cox, is_admin, is_guest, deleted, last_access
FROM user FROM user
@ -97,22 +75,12 @@ WHERE id like ?
) )
.fetch_one(db) .fetch_one(db)
.await .await
.ok()?; .ok()
Some(User {
id: row.id,
name: row.name,
pw: row.pw,
is_cox: row.is_cox,
is_admin: row.is_admin,
is_guest: row.is_guest,
deleted: row.deleted,
last_access: row.last_access.map(MyNaiveDateTime),
})
} }
pub async fn find_by_name(db: &SqlitePool, name: &str) -> Option<Self> { pub async fn find_by_name(db: &SqlitePool, name: &str) -> Option<Self> {
let row = sqlx::query!( sqlx::query_as!(
Self,
" "
SELECT id, name, pw, is_cox, is_admin, is_guest, deleted, last_access SELECT id, name, pw, is_cox, is_admin, is_guest, deleted, last_access
FROM user FROM user
@ -122,18 +90,7 @@ WHERE name like ?
) )
.fetch_one(db) .fetch_one(db)
.await .await
.ok()?; .ok()
Some(User {
id: row.id,
name: row.name,
pw: row.pw,
is_cox: row.is_cox,
is_admin: row.is_admin,
is_guest: row.is_guest,
deleted: row.deleted,
last_access: row.last_access.map(MyNaiveDateTime),
})
} }
pub async fn on_water(&self, db: &SqlitePool) -> bool { pub async fn on_water(&self, db: &SqlitePool) -> bool {
@ -164,7 +121,8 @@ WHERE name like ?
} }
pub async fn all(db: &SqlitePool) -> Vec<Self> { pub async fn all(db: &SqlitePool) -> Vec<Self> {
sqlx::query!( sqlx::query_as!(
Self,
" "
SELECT id, name, pw, is_cox, is_admin, is_guest, deleted, last_access SELECT id, name, pw, is_cox, is_admin, is_guest, deleted, last_access
FROM user FROM user
@ -175,22 +133,11 @@ ORDER BY last_access DESC
.fetch_all(db) .fetch_all(db)
.await .await
.unwrap() .unwrap()
.into_iter()
.map(|row| User {
id: row.id,
name: row.name,
pw: row.pw,
is_cox: row.is_cox,
is_admin: row.is_admin,
is_guest: row.is_guest,
deleted: row.deleted,
last_access: row.last_access.map(MyNaiveDateTime),
})
.collect()
} }
pub async fn cox(db: &SqlitePool) -> Vec<Self> { pub async fn cox(db: &SqlitePool) -> Vec<Self> {
sqlx::query!( sqlx::query_as!(
Self,
" "
SELECT id, name, pw, is_cox, is_admin, is_guest, deleted, last_access SELECT id, name, pw, is_cox, is_admin, is_guest, deleted, last_access
FROM user FROM user
@ -201,18 +148,6 @@ ORDER BY last_access DESC
.fetch_all(db) .fetch_all(db)
.await .await
.unwrap() .unwrap()
.into_iter()
.map(|row| User {
id: row.id,
name: row.name,
pw: row.pw,
is_cox: row.is_cox,
is_admin: row.is_admin,
is_guest: row.is_guest,
deleted: row.deleted,
last_access: row.last_access.map(MyNaiveDateTime),
})
.collect()
} }
pub async fn create(db: &SqlitePool, name: &str, is_guest: bool) -> bool { pub async fn create(db: &SqlitePool, name: &str, is_guest: bool) -> bool {