2023-07-22 13:57:17 +02:00
use serde ::{ Deserialize , Serialize } ;
use sqlx ::{ FromRow , SqlitePool } ;
#[ derive(FromRow, Debug, Serialize, Deserialize) ]
pub struct Boat {
pub id : i64 ,
pub name : String ,
pub amount_seats : i64 ,
pub location_id : i64 ,
pub owner : Option < i64 > ,
pub year_built : Option < i64 > ,
pub boatbuilder : Option < String > ,
#[ serde(default = " bool::default " ) ]
default_shipmaster_only_steering : bool ,
#[ serde(default = " bool::default " ) ]
skull : bool ,
#[ serde(default = " bool::default " ) ]
external : bool ,
}
impl Boat {
pub async fn find_by_id ( db : & SqlitePool , id : i32 ) -> Option < Self > {
sqlx ::query_as! (
Self ,
"
SELECT id , name , amount_seats , location_id , owner , year_built , boatbuilder , default_shipmaster_only_steering , skull , external
FROM boat
WHERE id like ?
" ,
id
)
. fetch_one ( db )
. await
. ok ( )
}
//
// pub async fn find_by_name(db: &SqlitePool, name: &str) -> Option<Self> {
// sqlx::query_as!(
// User,
// "
//SELECT id, name, pw, is_cox, is_admin, is_guest, deleted, last_access
//FROM user
//WHERE name like ?
// ",
// name
// )
// .fetch_one(db)
// .await
// .ok()
// }
2023-07-24 13:01:39 +02:00
pub async fn is_locked ( & self , db : & SqlitePool ) -> bool {
sqlx ::query! ( " SELECT * FROM boat_damage WHERE boat_id=? AND lock_boat=true AND user_id_verified is null " , self . id ) . fetch_optional ( db ) . await . unwrap ( ) . is_some ( )
}
pub async fn on_water ( & self , db : & SqlitePool ) -> bool {
sqlx ::query! (
" SELECT * FROM logbook WHERE boat_id=? AND arrival is null " ,
self . id
)
. fetch_optional ( db )
. await
. unwrap ( )
. is_some ( )
}
2023-07-22 13:57:17 +02:00
pub async fn all ( db : & SqlitePool ) -> Vec < Self > {
sqlx ::query_as! (
Boat ,
"
SELECT id , name , amount_seats , location_id , owner , year_built , boatbuilder , default_shipmaster_only_steering , skull , external
FROM boat
ORDER BY amount_seats DESC
"
)
. fetch_all ( db )
. await
. unwrap ( ) //TODO: fixme
}
pub async fn create (
db : & SqlitePool ,
name : & str ,
amount_seats : i64 ,
year_built : Option < i64 > ,
boatbuilder : Option < & str > ,
default_shipmaster_only_steering : bool ,
skull : bool ,
external : bool ,
2023-07-22 16:36:02 +02:00
location_id : Option < i64 > ,
owner : Option < i64 > ,
2023-07-22 13:57:17 +02:00
) -> bool {
sqlx ::query! (
2023-07-22 16:36:02 +02:00
" INSERT INTO boat(name, amount_seats, year_built, boatbuilder, default_shipmaster_only_steering, skull, external, location_id, owner) VALUES (?,?,?,?,?,?,?,?,?) " ,
2023-07-22 13:57:17 +02:00
name ,
amount_seats ,
year_built ,
boatbuilder ,
default_shipmaster_only_steering ,
skull ,
2023-07-22 16:36:02 +02:00
external ,
location_id ,
owner
2023-07-22 13:57:17 +02:00
)
. execute ( db )
2023-07-22 16:36:02 +02:00
. await . is_ok ( )
2023-07-22 13:57:17 +02:00
}
2023-07-22 15:34:42 +02:00
pub async fn update (
& self ,
db : & SqlitePool ,
name : & str ,
amount_seats : i64 ,
year_built : Option < i64 > ,
boatbuilder : Option < & str > ,
default_shipmaster_only_steering : bool ,
skull : bool ,
external : bool ,
location_id : Option < i64 > ,
owner : Option < i64 > ,
) -> bool {
sqlx ::query! (
" UPDATE boat SET name=?, amount_seats=?, year_built=?, boatbuilder=?, default_shipmaster_only_steering=?, skull=?, external=?, location_id=?, owner=? WHERE id=? " ,
name ,
amount_seats ,
year_built ,
boatbuilder ,
default_shipmaster_only_steering ,
skull ,
external ,
location_id ,
owner ,
self . id
)
. execute ( db )
. await
. is_ok ( )
}
2023-07-22 13:57:17 +02:00
pub async fn delete ( & self , db : & SqlitePool ) {
sqlx ::query! ( " DELETE FROM boat WHERE id=? " , self . id )
. execute ( db )
. await
. unwrap ( ) ; //Okay, because we can only create a User of a valid id
}
}
2023-07-22 15:34:42 +02:00
#[ cfg(test) ]
mod test {
use crate ::{ model ::boat ::Boat , testdb } ;
use sqlx ::SqlitePool ;
#[ sqlx::test ]
fn test_find_correct_id ( ) {
let pool = testdb! ( ) ;
let boat = Boat ::find_by_id ( & pool , 1 ) . await . unwrap ( ) ;
assert_eq! ( boat . id , 1 ) ;
}
#[ sqlx::test ]
fn test_find_wrong_id ( ) {
let pool = testdb! ( ) ;
let boat = Boat ::find_by_id ( & pool , 1337 ) . await ;
assert! ( boat . is_none ( ) ) ;
}
#[ sqlx::test ]
fn test_all ( ) {
let pool = testdb! ( ) ;
let res = Boat ::all ( & pool ) . await ;
assert! ( res . len ( ) > 3 ) ;
}
#[ sqlx::test ]
fn test_succ_create ( ) {
let pool = testdb! ( ) ;
assert_eq! (
Boat ::create (
& pool ,
" new-boat-name " . into ( ) ,
42 ,
None ,
" Best Boatbuilder " . into ( ) ,
true ,
true ,
2023-07-22 16:36:02 +02:00
false ,
Some ( 1 ) ,
None
2023-07-22 15:34:42 +02:00
)
. await ,
true
) ;
}
#[ sqlx::test ]
fn test_duplicate_name_create ( ) {
let pool = testdb! ( ) ;
assert_eq! (
Boat ::create (
& pool ,
" Haichenbach " . into ( ) ,
42 ,
None ,
" Best Boatbuilder " . into ( ) ,
true ,
true ,
2023-07-22 16:36:02 +02:00
false ,
Some ( 1 ) ,
None
2023-07-22 15:34:42 +02:00
)
. await ,
false
) ;
}
}