mirror of
https://github.com/zaphar/kitchen.git
synced 2025-07-22 19:40:14 -04:00
Fix inventory api serialization issues
This commit is contained in:
parent
2a1180dd94
commit
a1b7f953bb
@ -1,14 +1,14 @@
|
||||
{
|
||||
"db": "SQLite",
|
||||
"0e06f6e072e2c55769feda0d5f998509139097fee640caf8fb38c7087669bee4": {
|
||||
"07f619ff4474e9eb5f4d56497abb724e6952b4e43d681ba5ecd61490cf990ae9": {
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"nullable": [],
|
||||
"parameters": {
|
||||
"Right": 4
|
||||
"Right": 1
|
||||
}
|
||||
},
|
||||
"query": "insert into filtered_ingredients(user_id, name, form, measure_type)\n values (?, ?, ?, ?)"
|
||||
"query": "delete from filtered_ingredients where user_id = ?"
|
||||
},
|
||||
"104f07472670436d3eee1733578bbf0c92dc4f965d3d13f9bf4bfbc92958c5b6": {
|
||||
"describe": {
|
||||
@ -92,16 +92,6 @@
|
||||
},
|
||||
"query": "insert into recipes (user_id, recipe_id, recipe_text) values (?, ?, ?)\n on conflict(user_id, recipe_id) do update set recipe_text=excluded.recipe_text"
|
||||
},
|
||||
"512003bd6ef47567b243bbcaefcbd220acf36efab4cbd43b1a8debe59593577c": {
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"nullable": [],
|
||||
"parameters": {
|
||||
"Right": 5
|
||||
}
|
||||
},
|
||||
"query": "insert into modified_amts(user_id, name, form, measure_type, amt)\n values (?, ?, ?, ?, ?)"
|
||||
},
|
||||
"5d743897fb0d8fd54c3708f1b1c6e416346201faa9e28823c1ba5a421472b1fa": {
|
||||
"describe": {
|
||||
"columns": [],
|
||||
@ -184,6 +174,16 @@
|
||||
},
|
||||
"query": "insert into sessions (id, session_value) values (?, ?)"
|
||||
},
|
||||
"9e24ed2ea4d235e3a036025a0a0b5ea685546a81d7f2469a59a2fc1fc88798dc": {
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"nullable": [],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
}
|
||||
},
|
||||
"query": "delete from modified_amts where user_id = ?"
|
||||
},
|
||||
"ad3408cd773dd8f9308255ec2800171638a1aeda9817c57fb8360f97115f8e97": {
|
||||
"describe": {
|
||||
"columns": [
|
||||
@ -282,6 +282,16 @@
|
||||
},
|
||||
"query": "delete from sessions"
|
||||
},
|
||||
"f510d7f8dcb79907abd8b17bd52127af1699b3b79d2737c7729972d6bd5a0693": {
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"nullable": [],
|
||||
"parameters": {
|
||||
"Right": 4
|
||||
}
|
||||
},
|
||||
"query": "insert into filtered_ingredients(user_id, name, form, measure_type)\n values (?, ?, ?, ?) on conflict(user_id, name, form, measure_type) DO NOTHING"
|
||||
},
|
||||
"fc294739374d2a791214f747095e0bf9378989d1ff07d96a5431dbb208f21951": {
|
||||
"describe": {
|
||||
"columns": [
|
||||
@ -317,5 +327,15 @@
|
||||
}
|
||||
},
|
||||
"query": "select name, form, measure_type, amt from modified_amts where user_id = ?;"
|
||||
},
|
||||
"fc9d3f8ce9d0b42f34307aeb31c128cc3267e77613d6f2e170c95e83d6e361df": {
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"nullable": [],
|
||||
"parameters": {
|
||||
"Right": 5
|
||||
}
|
||||
},
|
||||
"query": "insert into modified_amts(user_id, name, form, measure_type, amt)\n values (?, ?, ?, ?, ?) on conflict (user_id, name, form, measure_type) do update set amt=excluded.amt"
|
||||
}
|
||||
}
|
@ -1,4 +1,3 @@
|
||||
use std::collections::BTreeMap;
|
||||
// Copyright 2022 Jeremy Wall
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -12,9 +11,9 @@ use std::collections::BTreeMap;
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
use std::net::SocketAddr;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
use std::{collections::BTreeSet, net::SocketAddr};
|
||||
|
||||
use axum::{
|
||||
body::{boxed, Full},
|
||||
@ -289,12 +288,14 @@ async fn api_save_inventory(
|
||||
Extension(app_store): Extension<Arc<storage::SqliteStore>>,
|
||||
session: storage::UserIdFromSession,
|
||||
Json((filtered_ingredients, modified_amts)): Json<(
|
||||
BTreeSet<IngredientKey>,
|
||||
BTreeMap<IngredientKey, String>,
|
||||
Vec<IngredientKey>,
|
||||
Vec<(IngredientKey, String)>,
|
||||
)>,
|
||||
) -> impl IntoResponse {
|
||||
use storage::{UserId, UserIdFromSession::FoundUserId};
|
||||
if let FoundUserId(UserId(id)) = session {
|
||||
let filtered_ingredients = filtered_ingredients.into_iter().collect();
|
||||
let modified_amts = modified_amts.into_iter().collect();
|
||||
if let Err(e) = app_store
|
||||
.save_inventory_data(id, filtered_ingredients, modified_amts)
|
||||
.await
|
||||
|
@ -124,7 +124,7 @@ pub trait APIStore {
|
||||
async fn fetch_inventory_data<S: AsRef<str> + Send>(
|
||||
&self,
|
||||
user_id: S,
|
||||
) -> Result<(BTreeSet<IngredientKey>, BTreeMap<IngredientKey, String>)>;
|
||||
) -> Result<(Vec<IngredientKey>, Vec<(IngredientKey, String)>)>;
|
||||
|
||||
async fn save_inventory_data<S: AsRef<str> + Send>(
|
||||
&self,
|
||||
@ -496,7 +496,7 @@ impl APIStore for SqliteStore {
|
||||
async fn fetch_inventory_data<S: AsRef<str> + Send>(
|
||||
&self,
|
||||
user_id: S,
|
||||
) -> Result<(BTreeSet<IngredientKey>, BTreeMap<IngredientKey, String>)> {
|
||||
) -> Result<(Vec<IngredientKey>, Vec<(IngredientKey, String)>)> {
|
||||
let user_id = user_id.as_ref();
|
||||
struct FilteredIngredientRow {
|
||||
name: String,
|
||||
@ -510,9 +510,9 @@ impl APIStore for SqliteStore {
|
||||
)
|
||||
.fetch_all(self.pool.as_ref())
|
||||
.await?;
|
||||
let mut filtered_ingredients = BTreeSet::new();
|
||||
let mut filtered_ingredients = Vec::new();
|
||||
for row in filtered_ingredient_rows {
|
||||
filtered_ingredients.insert(IngredientKey::new(
|
||||
filtered_ingredients.push(IngredientKey::new(
|
||||
row.name,
|
||||
if row.form.is_empty() {
|
||||
None
|
||||
@ -535,9 +535,9 @@ impl APIStore for SqliteStore {
|
||||
)
|
||||
.fetch_all(self.pool.as_ref())
|
||||
.await?;
|
||||
let mut modified_amts = BTreeMap::new();
|
||||
let mut modified_amts = Vec::new();
|
||||
for row in modified_amt_rows {
|
||||
modified_amts.insert(
|
||||
modified_amts.push((
|
||||
IngredientKey::new(
|
||||
row.name,
|
||||
if row.form.is_empty() {
|
||||
@ -548,7 +548,7 @@ impl APIStore for SqliteStore {
|
||||
row.measure_type,
|
||||
),
|
||||
row.amt,
|
||||
);
|
||||
));
|
||||
}
|
||||
Ok((filtered_ingredients, modified_amts))
|
||||
}
|
||||
@ -561,6 +561,15 @@ impl APIStore for SqliteStore {
|
||||
) -> Result<()> {
|
||||
let user_id = user_id.as_ref();
|
||||
let mut transaction = self.pool.as_ref().begin().await?;
|
||||
sqlx::query!(
|
||||
"delete from filtered_ingredients where user_id = ?",
|
||||
user_id
|
||||
)
|
||||
.execute(&mut transaction)
|
||||
.await?;
|
||||
sqlx::query!("delete from modified_amts where user_id = ?", user_id)
|
||||
.execute(&mut transaction)
|
||||
.await?;
|
||||
for key in filtered_ingredients {
|
||||
let name = key.name();
|
||||
let form = key.form();
|
||||
|
@ -1,2 +1,2 @@
|
||||
insert into filtered_ingredients(user_id, name, form, measure_type)
|
||||
values (?, ?, ?, ?)
|
||||
values (?, ?, ?, ?) on conflict(user_id, name, form, measure_type) DO NOTHING
|
@ -1,2 +1,2 @@
|
||||
insert into modified_amts(user_id, name, form, measure_type, amt)
|
||||
values (?, ?, ?, ?, ?)
|
||||
values (?, ?, ?, ?, ?) on conflict (user_id, name, form, measure_type) do update set amt=excluded.amt
|
@ -392,8 +392,14 @@ impl HttpStore {
|
||||
Err(format!("Status: {}", resp.status()).into())
|
||||
} else {
|
||||
debug!("We got a valid response back");
|
||||
let inventory = resp.json().await.map_err(|e| format!("{}", e))?;
|
||||
Ok(inventory)
|
||||
let (filtered_ingredients, modified_amts): (
|
||||
Vec<IngredientKey>,
|
||||
Vec<(IngredientKey, String)>,
|
||||
) = resp.json().await.map_err(|e| format!("{}", e))?;
|
||||
Ok((
|
||||
filtered_ingredients.into_iter().collect(),
|
||||
modified_amts.into_iter().collect(),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
@ -403,6 +409,8 @@ impl HttpStore {
|
||||
modified_amts: BTreeMap<IngredientKey, String>,
|
||||
) -> Result<(), Error> {
|
||||
let mut path = self.root.clone();
|
||||
let filtered_ingredients: Vec<IngredientKey> = filtered_ingredients.into_iter().collect();
|
||||
let modified_amts: Vec<(IngredientKey, String)> = modified_amts.into_iter().collect();
|
||||
let serialized_inventory = to_string(&(filtered_ingredients, modified_amts))
|
||||
.expect("Unable to encode plan as json");
|
||||
path.push_str("/inventory");
|
||||
|
@ -15,7 +15,7 @@ use std::collections::{BTreeMap, BTreeSet};
|
||||
|
||||
use recipes::{Ingredient, IngredientKey};
|
||||
use sycamore::{futures::spawn_local_scoped, prelude::*};
|
||||
use tracing::{debug, instrument};
|
||||
use tracing::{debug, info, instrument};
|
||||
|
||||
fn make_ingredients_rows<'ctx, G: Html>(
|
||||
cx: Scope<'ctx>,
|
||||
@ -187,15 +187,20 @@ pub fn ShoppingList<G: Html>(cx: Scope) -> View<G> {
|
||||
});
|
||||
create_effect(cx, move || {
|
||||
save_click.track();
|
||||
info!("Registering save request for inventory");
|
||||
spawn_local_scoped(cx, {
|
||||
let state = crate::app_state::State::get_from_context(cx);
|
||||
let store = crate::api::HttpStore::get_from_context(cx);
|
||||
let filtered_ingredients = state.filtered_ingredients.get_untracked().as_ref().clone();
|
||||
let modified_amts = state.get_current_modified_amts();
|
||||
async move {
|
||||
debug!(
|
||||
?filtered_ingredients,
|
||||
?modified_amts,
|
||||
"Attempting save for inventory"
|
||||
);
|
||||
store
|
||||
.save_inventory_data(
|
||||
state.filtered_ingredients.get_untracked().as_ref().clone(),
|
||||
state.get_current_modified_amts(),
|
||||
)
|
||||
.save_inventory_data(filtered_ingredients, modified_amts)
|
||||
.await
|
||||
.expect("Unable to save inventory data");
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user