Update moved into upsert endpoint. Insert now returns the id.
This commit is contained in:
parent
643c42d970
commit
deabc5649f
2 changed files with 51 additions and 27 deletions
12
src/place.rs
12
src/place.rs
|
|
@ -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>,
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -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],
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue