use chrono::NaiveDateTime; use serde::{Deserialize, Serialize}; use sqlx::{FromRow, SqlitePool}; #[derive(FromRow, Debug, Serialize, Deserialize)] pub struct Logbook { pub id: i64, pub boat_id: i64, pub shipmaster: i64, #[serde(default = "bool::default")] pub shipmaster_only_steering: bool, pub departure: String, //TODO: Switch to chrono::nativedatetime pub arrival: Option, //TODO: Switch to chrono::nativedatetime pub destination: Option, pub distance_in_km: Option, pub comments: Option, pub logtype: Option, } #[derive(Serialize, FromRow)] pub struct LogbookWithBoatAndUsers { pub id: i64, pub boat_id: i64, pub shipmaster: i64, #[serde(default = "bool::default")] pub shipmaster_only_steering: bool, pub departure: String, //TODO: Switch to chrono::nativedatetime pub arrival: Option, //TODO: Switch to chrono::nativedatetime pub destination: Option, pub distance_in_km: Option, pub comments: Option, pub logtype: Option, pub boat: String, pub shipmaster_name: String, } impl Logbook { //pub async fn find_by_id(db: &SqlitePool, id: i32) -> Option { // 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 { // 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() // } // pub async fn on_water(db: &SqlitePool) -> Vec { sqlx::query_as!( LogbookWithBoatAndUsers, " SELECT logbook.id, boat_id, shipmaster, shipmaster_only_steering, departure, arrival, destination, distance_in_km, comments, logtype, boat.name as boat, user.name as shipmaster_name FROM logbook INNER JOIN boat ON logbook.boat_id = boat.id INNER JOIN user ON shipmaster = user.id WHERE arrival is null ORDER BY departure DESC " ) .fetch_all(db) .await .unwrap() //TODO: fixme } pub async fn completed(db: &SqlitePool) -> Vec { sqlx::query_as!( LogbookWithBoatAndUsers, " SELECT logbook.id, boat_id, shipmaster, shipmaster_only_steering, departure, arrival, destination, distance_in_km, comments, logtype, boat.name as boat, user.name as shipmaster_name FROM logbook INNER JOIN boat ON logbook.boat_id = boat.id INNER JOIN user ON shipmaster = user.id WHERE arrival is not null ORDER BY arrival DESC " ) .fetch_all(db) .await .unwrap() //TODO: fixme } pub async fn create( db: &SqlitePool, boat_id: i64, shipmaster: i64, shipmaster_only_steering: bool, departure: NaiveDateTime, arrival: Option, destination: Option, distance_in_km: Option, comments: Option, logtype: Option, ) -> bool { sqlx::query!( "INSERT INTO logbook(boat_id, shipmaster, shipmaster_only_steering, departure, arrival, destination, distance_in_km, comments, logtype) VALUES (?,?,?,?,?,?,?,?,?)", boat_id, shipmaster, shipmaster_only_steering, departure, arrival, destination, distance_in_km, comments, logtype ) .execute(db) .await.is_ok() } // // pub async fn update( // &self, // db: &SqlitePool, // name: &str, // amount_seats: i64, // year_built: Option, // boatbuilder: Option<&str>, // default_shipmaster_only_steering: bool, // skull: bool, // external: bool, // location_id: Option, // owner: Option, // ) -> 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() // } // // 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 // } } // //#[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, // false, // Some(1), // None // ) // .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, // false, // Some(1), // None // ) // .await, // false // ); // } //}