use rocket::fairing::{self, AdHoc}; use rocket::response::status::Created; use rocket::serde::json::Json; use rocket::{Build, Rocket}; use rocket_db_pools::{Connection, Database}; use rocket::futures::stream::TryStreamExt; use crate::place::{Place, UpdatePlace}; type Result> = std::result::Result; #[derive(Database)] #[database("db")] struct Db(rocket_db_pools::sqlx::SqlitePool); #[get("/places")] async fn get_places(mut db: Connection) -> Result>> { let places = rocket_db_pools::sqlx::query!( "SELECT id, name, address, open_hours, icon, description, longitude, latitude FROM places WHERE active = TRUE") .fetch(&mut *db) .map_ok(|p| Place { id: Some(p.id), name: p.name, address: p.address, open_hours: p.open_hours, icon: p.icon, description: p.description, latitude: p.latitude, longitude: p.longitude }) .try_collect::>() .await?; Ok(Json(places)) } #[post("/places", format = "json", data = "")] async fn create_place(mut db: Connection, place: Json) -> Result>> { ::sqlx::query!( "INSERT INTO places (name, address, open_hours, icon, description, longitude, latitude) VALUES (?, ?, ?, ?, ?, ?, ?)", place.name, place.address, place.open_hours, place.icon, place.description, place.longitude, place.latitude ) .execute(&mut *db) .await?; Ok(Created::new("/places").body(place)) } #[patch("/places/", format = "json", data = "")] fn update_place(id: i64, update_place: Json) -> &'static str { "Hello, world!" } #[delete("/places/")] async fn delete_place(mut db: Connection, id: i64) -> Result> { let result = ::sqlx::query!("UPDATE places SET active = FALSE WHERE id = ?", id) .execute(&mut *db) .await?; Ok((result.rows_affected() == 1).then(|| ())) } async fn run_migrations(rocket: Rocket) -> fairing::Result { match Db::fetch(&rocket) { Some(db) => match ::sqlx::migrate!("./migrations").run(&**db).await { Ok(_) => Ok(rocket), Err(e) => { error!("Failed to initialize SQLx database: {}", e); Err(rocket) } }, None => Err(rocket), } } pub fn stage() -> AdHoc { AdHoc::on_ignite("SQLx Stage", |rocket| async { rocket .attach(Db::init()) .attach(AdHoc::try_on_ignite("SQLx Migrations", run_migrations)) .mount( "/", routes![create_place, get_places, update_place, delete_place], ) }) }