Add update by shop id handlers
This commit is contained in:
parent
df48b64ffd
commit
58583a553a
@ -123,11 +123,11 @@ where
|
||||
Ok(cached_response)
|
||||
}
|
||||
|
||||
pub async fn delete_response(&self, key: K) -> Result<Option<CachedResponse>> {
|
||||
pub async fn delete_response(&self, key: K) -> Option<CachedResponse> {
|
||||
let mut guard = self.lru_mutex.lock().await;
|
||||
let cached_response = guard.pop(&key);
|
||||
self.log_with_key(&key, "delete_response");
|
||||
|
||||
Ok(cached_response)
|
||||
cached_response
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ pub struct Caches {
|
||||
pub list_interior_ref_lists: Cache<ListParams, CachedResponse>,
|
||||
pub list_merchandise_lists: Cache<ListParams, CachedResponse>,
|
||||
pub interior_ref_list_by_shop_id: Cache<i32, CachedResponse>,
|
||||
pub merchandise_list_by_shop_id: Cache<i32, CachedResponse>,
|
||||
}
|
||||
|
||||
impl Caches {
|
||||
@ -36,6 +37,7 @@ impl Caches {
|
||||
list_interior_ref_lists: Cache::new("list_interior_ref_lists", 100),
|
||||
list_merchandise_lists: Cache::new("list_merchandise_lists", 100),
|
||||
interior_ref_list_by_shop_id: Cache::new("interior_ref_list_by_shop_id", 100),
|
||||
merchandise_list_by_shop_id: Cache::new("merchandise_list_by_shop_id", 100),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -145,11 +145,7 @@ pub async fn update_shop(
|
||||
let reply = json(&updated_shop);
|
||||
let reply = with_header(reply, "Location", url.as_str());
|
||||
let reply = with_status(reply, StatusCode::CREATED);
|
||||
env.caches
|
||||
.shop
|
||||
.delete_response(id)
|
||||
.await
|
||||
.map_err(reject_anyhow)?;
|
||||
env.caches.shop.delete_response(id).await;
|
||||
env.caches.list_shops.clear().await;
|
||||
Ok(reply)
|
||||
}
|
||||
@ -163,13 +159,16 @@ pub async fn delete_shop(
|
||||
Shop::delete(&env.db, owner_id, id)
|
||||
.await
|
||||
.map_err(reject_anyhow)?;
|
||||
env.caches
|
||||
.shop
|
||||
.delete_response(id)
|
||||
.await
|
||||
.map_err(reject_anyhow)?;
|
||||
env.caches.shop.delete_response(id).await;
|
||||
env.caches.list_shops.clear().await;
|
||||
env.caches.interior_ref_list_by_shop_id.delete(id).await;
|
||||
env.caches
|
||||
.interior_ref_list_by_shop_id
|
||||
.delete_response(id)
|
||||
.await;
|
||||
env.caches
|
||||
.merchandise_list_by_shop_id
|
||||
.delete_response(id)
|
||||
.await;
|
||||
Ok(StatusCode::NO_CONTENT)
|
||||
}
|
||||
|
||||
@ -254,11 +253,7 @@ pub async fn update_owner(
|
||||
let reply = json(&updated_owner);
|
||||
let reply = with_header(reply, "Location", url.as_str());
|
||||
let reply = with_status(reply, StatusCode::CREATED);
|
||||
env.caches
|
||||
.owner
|
||||
.delete_response(id)
|
||||
.await
|
||||
.map_err(reject_anyhow)?;
|
||||
env.caches.owner.delete_response(id).await;
|
||||
env.caches.list_owners.clear().await;
|
||||
Ok(reply)
|
||||
}
|
||||
@ -272,11 +267,7 @@ pub async fn delete_owner(
|
||||
Owner::delete(&env.db, owner_id, id)
|
||||
.await
|
||||
.map_err(reject_anyhow)?;
|
||||
env.caches
|
||||
.owner
|
||||
.delete_response(id)
|
||||
.await
|
||||
.map_err(reject_anyhow)?;
|
||||
env.caches.owner.delete_response(id).await;
|
||||
env.caches
|
||||
.owner_ids_by_api_key
|
||||
.delete(api_key.expect("api-key has been validated during authenticate"))
|
||||
@ -335,7 +326,7 @@ pub async fn create_interior_ref_list(
|
||||
env.caches.list_interior_ref_lists.clear().await;
|
||||
env.caches
|
||||
.interior_ref_list_by_shop_id
|
||||
.delete(saved_interior_ref_list.shop_id)
|
||||
.delete_response(saved_interior_ref_list.shop_id)
|
||||
.await;
|
||||
Ok(reply)
|
||||
}
|
||||
@ -369,16 +360,48 @@ pub async fn update_interior_ref_list(
|
||||
let reply = json(&updated_interior_ref_list);
|
||||
let reply = with_header(reply, "Location", url.as_str());
|
||||
let reply = with_status(reply, StatusCode::CREATED);
|
||||
env.caches
|
||||
.interior_ref_list
|
||||
.delete_response(id)
|
||||
.await
|
||||
.map_err(reject_anyhow)?;
|
||||
env.caches.interior_ref_list.delete_response(id).await;
|
||||
env.caches
|
||||
.interior_ref_list_by_shop_id
|
||||
.delete_response(updated_interior_ref_list.shop_id)
|
||||
.await;
|
||||
env.caches.list_interior_ref_lists.clear().await;
|
||||
Ok(reply)
|
||||
}
|
||||
|
||||
pub async fn update_interior_ref_list_by_shop_id(
|
||||
shop_id: i32,
|
||||
interior_ref_list: InteriorRefList,
|
||||
api_key: Option<Uuid>,
|
||||
env: Environment,
|
||||
) -> Result<impl Reply, Rejection> {
|
||||
let owner_id = authenticate(&env, api_key).await.map_err(reject_anyhow)?;
|
||||
let interior_ref_list_with_owner_id = InteriorRefList {
|
||||
owner_id: Some(owner_id),
|
||||
..interior_ref_list
|
||||
};
|
||||
let updated_interior_ref_list = interior_ref_list_with_owner_id
|
||||
.update_by_shop_id(&env.db, owner_id, shop_id)
|
||||
.await
|
||||
.map_err(reject_anyhow)?;
|
||||
let url = updated_interior_ref_list
|
||||
.url(&env.api_url)
|
||||
.map_err(reject_anyhow)?;
|
||||
let reply = json(&updated_interior_ref_list);
|
||||
let reply = with_header(reply, "Location", url.as_str());
|
||||
let reply = with_status(reply, StatusCode::CREATED);
|
||||
env.caches
|
||||
.interior_ref_list
|
||||
.delete_response(
|
||||
updated_interior_ref_list
|
||||
.id
|
||||
.expect("saved interior_ref_list has no id"),
|
||||
)
|
||||
.await;
|
||||
env.caches
|
||||
.interior_ref_list_by_shop_id
|
||||
.delete_response(updated_interior_ref_list.shop_id)
|
||||
.await;
|
||||
env.caches.list_interior_ref_lists.clear().await;
|
||||
Ok(reply)
|
||||
}
|
||||
@ -395,15 +418,11 @@ pub async fn delete_interior_ref_list(
|
||||
InteriorRefList::delete(&env.db, owner_id, id)
|
||||
.await
|
||||
.map_err(reject_anyhow)?;
|
||||
env.caches
|
||||
.interior_ref_list
|
||||
.delete_response(id)
|
||||
.await
|
||||
.map_err(reject_anyhow)?;
|
||||
env.caches.interior_ref_list.delete_response(id).await;
|
||||
env.caches.list_interior_ref_lists.clear().await;
|
||||
env.caches
|
||||
.interior_ref_list_by_shop_id
|
||||
.delete(interior_ref_list.shop_id)
|
||||
.delete_response(interior_ref_list.shop_id)
|
||||
.await;
|
||||
Ok(StatusCode::NO_CONTENT)
|
||||
}
|
||||
@ -472,6 +491,10 @@ pub async fn create_merchandise_list(
|
||||
let reply = with_header(reply, "Location", url.as_str());
|
||||
let reply = with_status(reply, StatusCode::CREATED);
|
||||
env.caches.list_merchandise_lists.clear().await;
|
||||
env.caches
|
||||
.merchandise_list_by_shop_id
|
||||
.delete_response(saved_merchandise_list.shop_id)
|
||||
.await;
|
||||
Ok(reply)
|
||||
}
|
||||
|
||||
@ -504,11 +527,48 @@ pub async fn update_merchandise_list(
|
||||
let reply = json(&updated_merchandise_list);
|
||||
let reply = with_header(reply, "Location", url.as_str());
|
||||
let reply = with_status(reply, StatusCode::CREATED);
|
||||
env.caches.merchandise_list.delete_response(id).await;
|
||||
env.caches
|
||||
.merchandise_list
|
||||
.delete_response(id)
|
||||
.merchandise_list_by_shop_id
|
||||
.delete_response(updated_merchandise_list.shop_id)
|
||||
.await;
|
||||
env.caches.list_merchandise_lists.clear().await;
|
||||
Ok(reply)
|
||||
}
|
||||
|
||||
pub async fn update_merchandise_list_by_shop_id(
|
||||
shop_id: i32,
|
||||
merchandise_list: MerchandiseList,
|
||||
api_key: Option<Uuid>,
|
||||
env: Environment,
|
||||
) -> Result<impl Reply, Rejection> {
|
||||
let owner_id = authenticate(&env, api_key).await.map_err(reject_anyhow)?;
|
||||
let merchandise_list_with_owner_id = MerchandiseList {
|
||||
owner_id: Some(owner_id),
|
||||
..merchandise_list
|
||||
};
|
||||
let updated_merchandise_list = merchandise_list_with_owner_id
|
||||
.update_by_shop_id(&env.db, owner_id, shop_id)
|
||||
.await
|
||||
.map_err(reject_anyhow)?;
|
||||
let url = updated_merchandise_list
|
||||
.url(&env.api_url)
|
||||
.map_err(reject_anyhow)?;
|
||||
let reply = json(&updated_merchandise_list);
|
||||
let reply = with_header(reply, "Location", url.as_str());
|
||||
let reply = with_status(reply, StatusCode::CREATED);
|
||||
env.caches
|
||||
.merchandise_list
|
||||
.delete_response(
|
||||
updated_merchandise_list
|
||||
.id
|
||||
.expect("saved merchandise_list has no id"),
|
||||
)
|
||||
.await;
|
||||
env.caches
|
||||
.merchandise_list_by_shop_id
|
||||
.delete_response(updated_merchandise_list.shop_id)
|
||||
.await;
|
||||
env.caches.list_merchandise_lists.clear().await;
|
||||
Ok(reply)
|
||||
}
|
||||
@ -519,14 +579,32 @@ pub async fn delete_merchandise_list(
|
||||
env: Environment,
|
||||
) -> Result<impl Reply, Rejection> {
|
||||
let owner_id = authenticate(&env, api_key).await.map_err(reject_anyhow)?;
|
||||
let merchandise_list = MerchandiseList::get(&env.db, id)
|
||||
.await
|
||||
.map_err(reject_anyhow)?;
|
||||
MerchandiseList::delete(&env.db, owner_id, id)
|
||||
.await
|
||||
.map_err(reject_anyhow)?;
|
||||
env.caches.merchandise_list.delete_response(id).await;
|
||||
env.caches
|
||||
.merchandise_list
|
||||
.delete_response(id)
|
||||
.await
|
||||
.map_err(reject_anyhow)?;
|
||||
.merchandise_list_by_shop_id
|
||||
.delete_response(merchandise_list.shop_id)
|
||||
.await;
|
||||
env.caches.list_merchandise_lists.clear().await;
|
||||
Ok(StatusCode::NO_CONTENT)
|
||||
}
|
||||
|
||||
pub async fn get_merchandise_list_by_shop_id(
|
||||
shop_id: i32,
|
||||
env: Environment,
|
||||
) -> Result<impl Reply, Rejection> {
|
||||
env.caches
|
||||
.merchandise_list_by_shop_id
|
||||
.get_response(shop_id, || async {
|
||||
let merchandise_list = MerchandiseList::get_by_shop_id(&env.db, shop_id).await?;
|
||||
let reply = json(&merchandise_list);
|
||||
let reply = with_status(reply, StatusCode::OK);
|
||||
Ok(reply)
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
32
src/main.rs
32
src/main.rs
@ -164,6 +164,7 @@ async fn main() -> Result<()> {
|
||||
);
|
||||
let update_shop_handler = warp::path("shops").and(
|
||||
warp::path::param()
|
||||
.and(warp::path::end())
|
||||
.and(warp::patch())
|
||||
.and(json_body::<Shop>())
|
||||
.and(warp::header::optional("api-key"))
|
||||
@ -209,6 +210,16 @@ async fn main() -> Result<()> {
|
||||
.and(with_env(env.clone()))
|
||||
.and_then(handlers::update_interior_ref_list),
|
||||
);
|
||||
let update_interior_ref_list_by_shop_id_handler = warp::path("shops").and(
|
||||
warp::path::param()
|
||||
.and(warp::path("interior_ref_list"))
|
||||
.and(warp::path::end())
|
||||
.and(warp::patch())
|
||||
.and(json_body::<InteriorRefList>())
|
||||
.and(warp::header::optional("api-key"))
|
||||
.and(with_env(env.clone()))
|
||||
.and_then(handlers::update_interior_ref_list_by_shop_id),
|
||||
);
|
||||
let list_interior_ref_lists_handler = warp::path("interior_ref_lists").and(
|
||||
warp::path::end()
|
||||
.and(warp::get())
|
||||
@ -256,6 +267,16 @@ async fn main() -> Result<()> {
|
||||
.and(with_env(env.clone()))
|
||||
.and_then(handlers::update_merchandise_list),
|
||||
);
|
||||
let update_merchandise_list_by_shop_id_handler = warp::path("shops").and(
|
||||
warp::path::param()
|
||||
.and(warp::path("merchandise_list"))
|
||||
.and(warp::path::end())
|
||||
.and(warp::patch())
|
||||
.and(json_body::<MerchandiseList>())
|
||||
.and(warp::header::optional("api-key"))
|
||||
.and(with_env(env.clone()))
|
||||
.and_then(handlers::update_merchandise_list_by_shop_id),
|
||||
);
|
||||
let list_merchandise_lists_handler = warp::path("merchandise_lists").and(
|
||||
warp::path::end()
|
||||
.and(warp::get())
|
||||
@ -263,6 +284,14 @@ async fn main() -> Result<()> {
|
||||
.and(with_env(env.clone()))
|
||||
.and_then(handlers::list_merchandise_lists),
|
||||
);
|
||||
let get_merchandise_list_by_shop_id_handler = warp::path("shops").and(
|
||||
warp::path::param()
|
||||
.and(warp::path("merchandise_list"))
|
||||
.and(warp::path::end())
|
||||
.and(warp::get())
|
||||
.and(with_env(env.clone()))
|
||||
.and_then(handlers::get_merchandise_list_by_shop_id),
|
||||
);
|
||||
|
||||
let routes = warp::path("v1")
|
||||
.and(balanced_or_tree!(
|
||||
@ -278,6 +307,9 @@ async fn main() -> Result<()> {
|
||||
create_shop_handler,
|
||||
list_shops_handler,
|
||||
get_interior_ref_list_by_shop_id_handler,
|
||||
get_merchandise_list_by_shop_id_handler,
|
||||
update_interior_ref_list_by_shop_id_handler,
|
||||
update_merchandise_list_by_shop_id_handler,
|
||||
get_interior_ref_list_handler,
|
||||
delete_interior_ref_list_handler,
|
||||
update_interior_ref_list_handler,
|
||||
|
@ -50,6 +50,7 @@ impl Model for InteriorRefList {
|
||||
self.id
|
||||
}
|
||||
|
||||
// TODO: this model will probably never need to be accessed through it's ID, should these methods be removed/unimplemented?
|
||||
#[instrument(level = "debug", skip(db))]
|
||||
async fn get(db: &PgPool, id: i32) -> Result<Self> {
|
||||
sqlx::query_as_unchecked!(Self, "SELECT * FROM interior_ref_lists WHERE id = $1", id)
|
||||
@ -158,14 +159,38 @@ impl InteriorRefList {
|
||||
pub async fn get_by_shop_id(db: &PgPool, shop_id: i32) -> Result<Self> {
|
||||
sqlx::query_as_unchecked!(
|
||||
Self,
|
||||
"SELECT interior_ref_lists.* FROM interior_ref_lists
|
||||
INNER JOIN shops ON (interior_ref_lists.shop_id = shops.id)
|
||||
WHERE shops.id = $1
|
||||
LIMIT 1",
|
||||
"SELECT * FROM interior_ref_lists
|
||||
WHERE shop_id = $1",
|
||||
shop_id,
|
||||
)
|
||||
.fetch_one(db)
|
||||
.await
|
||||
.map_err(Error::new)
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self, db))]
|
||||
pub async fn update_by_shop_id(self, db: &PgPool, owner_id: i32, shop_id: i32) -> Result<Self> {
|
||||
let interior_ref_list = sqlx::query!(
|
||||
"SELECT owner_id FROM interior_ref_lists WHERE shop_id = $1",
|
||||
shop_id
|
||||
)
|
||||
.fetch_one(db)
|
||||
.await?;
|
||||
if interior_ref_list.owner_id == owner_id {
|
||||
Ok(sqlx::query_as_unchecked!(
|
||||
Self,
|
||||
"UPDATE interior_ref_lists SET
|
||||
ref_list = $2,
|
||||
updated_at = now()
|
||||
WHERE shop_id = $1
|
||||
RETURNING *",
|
||||
shop_id,
|
||||
self.ref_list,
|
||||
)
|
||||
.fetch_one(db)
|
||||
.await?)
|
||||
} else {
|
||||
return Err(forbidden_permission());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -46,6 +46,7 @@ impl Model for MerchandiseList {
|
||||
self.id
|
||||
}
|
||||
|
||||
// TODO: this model will probably never need to be accessed through it's ID, should these methods be removed/unimplemented?
|
||||
#[instrument(level = "debug", skip(db))]
|
||||
async fn get(db: &PgPool, id: i32) -> Result<Self> {
|
||||
sqlx::query_as_unchecked!(Self, "SELECT * FROM merchandise_lists WHERE id = $1", id)
|
||||
@ -144,3 +145,44 @@ impl UpdateableModel for MerchandiseList {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl MerchandiseList {
|
||||
#[instrument(level = "debug", skip(db))]
|
||||
pub async fn get_by_shop_id(db: &PgPool, shop_id: i32) -> Result<Self> {
|
||||
sqlx::query_as_unchecked!(
|
||||
Self,
|
||||
"SELECT * FROM merchandise_lists
|
||||
WHERE shop_id = $1",
|
||||
shop_id,
|
||||
)
|
||||
.fetch_one(db)
|
||||
.await
|
||||
.map_err(Error::new)
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(db))]
|
||||
pub async fn update_by_shop_id(self, db: &PgPool, owner_id: i32, shop_id: i32) -> Result<Self> {
|
||||
let merchandise_list = sqlx::query!(
|
||||
"SELECT owner_id FROM merchandise_lists WHERE shop_id = $1",
|
||||
shop_id
|
||||
)
|
||||
.fetch_one(db)
|
||||
.await?;
|
||||
if merchandise_list.owner_id == owner_id {
|
||||
Ok(sqlx::query_as_unchecked!(
|
||||
Self,
|
||||
"UPDATE merchandise_lists SET
|
||||
form_list = $2,
|
||||
updated_at = now()
|
||||
WHERE shop_id = $1
|
||||
RETURNING *",
|
||||
shop_id,
|
||||
self.form_list,
|
||||
)
|
||||
.fetch_one(db)
|
||||
.await?)
|
||||
} else {
|
||||
return Err(forbidden_permission());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user