Update moved into upsert endpoint. Insert now returns the id.

This commit is contained in:
Felipe Contreras 2022-07-18 01:14:35 -04:00
parent 643c42d970
commit deabc5649f
2 changed files with 51 additions and 27 deletions

View file

@ -12,15 +12,3 @@ pub struct Place {
pub longitude: f32, pub longitude: f32,
pub latitude: f32, pub latitude: f32,
} }
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(crate = "rocket::serde")]
pub struct UpdatePlace {
pub name: Option<String>,
pub address: Option<String>,
pub open_hours: Option<String>,
pub icon: Option<String>,
pub description: Option<String>,
pub longitude: Option<f32>,
pub latitude: Option<f32>,
}

View file

@ -1,12 +1,12 @@
use rocket::fairing::{self, AdHoc}; use rocket::fairing::{self, AdHoc};
use rocket::response::status::Created; use rocket::response::status::{Accepted, Created, NotFound};
use rocket::serde::json::Json; use rocket::serde::json::Json;
use rocket::{Build, Rocket}; use rocket::{Build, Rocket};
use rocket_db_pools::{Connection, Database}; use rocket_db_pools::{Connection, Database};
use rocket::futures::stream::TryStreamExt; use rocket::futures::stream::TryStreamExt;
use crate::place::{Place, UpdatePlace}; use crate::place::Place;
type Result<T, E = rocket::response::Debug<sqlx::Error>> = std::result::Result<T, E>; type Result<T, E = rocket::response::Debug<sqlx::Error>> = std::result::Result<T, E>;
#[derive(Database)] #[derive(Database)]
@ -34,10 +34,50 @@ async fn get_places(mut db: Connection<Db>) -> Result<Json<Vec<Place>>> {
Ok(Json(places)) Ok(Json(places))
} }
#[derive(Debug, Responder)]
enum UpsertResponse {
Created(Created<Json<Place>>),
Accepted(Accepted<Json<Place>>),
NotFound(NotFound<Json<Place>>),
}
#[post("/places", format = "json", data = "<place>")] #[post("/places", format = "json", data = "<place>")]
async fn create_place(mut db: Connection<Db>, place: Json<Place>) -> Result<Created<Json<Place>>> { async fn upsert_place(db: Connection<Db>, place: Json<Place>) -> Result<UpsertResponse> {
::sqlx::query!( if place.id.is_some() {
"INSERT INTO places (name, address, open_hours, icon, description, longitude, latitude) VALUES (?, ?, ?, ?, ?, ?, ?)", update_place(db, place).await
} else {
insert_place(db, place).await
}
}
struct Id {
id: i64,
}
async fn insert_place(mut db: Connection<Db>, mut place: Json<Place>) -> Result<UpsertResponse> {
let i = ::sqlx::query_as!(
Id,
"INSERT INTO places (name, address, open_hours, icon, description, longitude, latitude)\
VALUES (?, ?, ?, ?, ?, ?, ?)\
RETURNING id",
place.name,
place.address,
place.open_hours,
place.icon,
place.description,
place.longitude,
place.latitude
)
.fetch_one(&mut *db)
.await?;
place.id = Some(i.id);
Ok(UpsertResponse::Created(Created::new("/places").body(place)))
}
async fn update_place(mut db: Connection<Db>, place: Json<Place>) -> Result<UpsertResponse> {
let result = ::sqlx::query!(
"UPDATE places SET (name, address, open_hours, icon, description, longitude, latitude) = (?, ?, ?, ?, ?, ?, ?)",
place.name, place.name,
place.address, place.address,
place.open_hours, place.open_hours,
@ -49,12 +89,11 @@ async fn create_place(mut db: Connection<Db>, place: Json<Place>) -> Result<Crea
.execute(&mut *db) .execute(&mut *db)
.await?; .await?;
Ok(Created::new("/places").body(place)) if result.rows_affected() == 1 {
} Ok(UpsertResponse::Accepted(Accepted(Some(place))))
} else {
#[patch("/places/<id>", format = "json", data = "<update_place>")] Ok(UpsertResponse::NotFound(NotFound(place)))
fn update_place(id: i64, update_place: Json<UpdatePlace>) -> &'static str { }
"Hello, world!"
} }
#[delete("/places/<id>")] #[delete("/places/<id>")]
@ -84,9 +123,6 @@ pub fn stage() -> AdHoc {
rocket rocket
.attach(Db::init()) .attach(Db::init())
.attach(AdHoc::try_on_ignite("SQLx Migrations", run_migrations)) .attach(AdHoc::try_on_ignite("SQLx Migrations", run_migrations))
.mount( .mount("/", routes![upsert_place, get_places, delete_place])
"/",
routes![create_place, get_places, update_place, delete_place],
)
}) })
} }