dev: Handle serving counts in the api

This commit is contained in:
Jeremy Wall 2024-07-10 11:49:39 -04:00
parent 9833e22e42
commit 113b03016f
8 changed files with 38 additions and 31 deletions

View File

@ -1,12 +0,0 @@
{
"db_name": "SQLite",
"query": "insert into recipes (user_id, recipe_id, recipe_text, category) values (?, ?, ?, ?)\n on conflict(user_id, recipe_id) do update set recipe_text=excluded.recipe_text, category=excluded.category",
"describe": {
"columns": [],
"parameters": {
"Right": 4
},
"nullable": []
},
"hash": "05a9f963e3f18b8ceb787c33b6dbdac993f999ff32bb5155f2dff8dc18d840bf"
}

View File

@ -0,0 +1,12 @@
{
"db_name": "SQLite",
"query": "insert into recipes (user_id, recipe_id, recipe_text, category, serving_count) values (?, ?, ?, ?, ?)\n on conflict(user_id, recipe_id) do update set recipe_text=excluded.recipe_text, category=excluded.category",
"describe": {
"columns": [],
"parameters": {
"Right": 5
},
"nullable": []
},
"hash": "eb99a37e18009e0dd46caccacea57ba0b25510d80a4e4a282a5ac2be50bba81c"
}

View File

@ -1,6 +1,6 @@
{
"db_name": "SQLite",
"query": "select recipe_id, recipe_text, category from recipes where user_id = ? and recipe_id = ?",
"query": "select recipe_id, recipe_text, category, serving_count from recipes where user_id = ? and recipe_id = ?",
"describe": {
"columns": [
{
@ -17,6 +17,11 @@
"name": "category",
"ordinal": 2,
"type_info": "Text"
},
{
"name": "serving_count",
"ordinal": 3,
"type_info": "Int64"
}
],
"parameters": {
@ -25,8 +30,9 @@
"nullable": [
false,
true,
true,
true
]
},
"hash": "1cc4412dfc3d4acdf257e839b50d6c9abbb6e74e7af606fd12da20f0aedde3de"
"hash": "ee0491c7d1a31ef80d7abe6ea4c9a8b0618dba58a0a8bceef7bdafec98ccd543"
}

View File

@ -98,7 +98,7 @@ impl AsyncFileStore {
let file_name = entry.file_name().to_string_lossy().to_string();
debug!("adding recipe file {}", file_name);
let recipe_contents = read_to_string(entry.path()).await?;
entry_vec.push(RecipeEntry(file_name, recipe_contents, None));
entry_vec.push(RecipeEntry(file_name, recipe_contents, None, None));
} else {
warn!(
file = %entry.path().to_string_lossy(),
@ -122,6 +122,7 @@ impl AsyncFileStore {
id.as_ref().to_owned(),
recipe_contents,
None,
None,
)));
} else {
return Ok(None);

View File

@ -429,20 +429,10 @@ impl APIStore for SqliteStore {
user_id: S,
id: S,
) -> Result<Option<RecipeEntry>> {
// NOTE(jwall): We allow dead code becaue Rust can't figure out that
// this code is actually constructed but it's done via the query_as
// macro.
#[allow(dead_code)]
struct RecipeRow {
pub recipe_id: String,
pub recipe_text: Option<String>,
pub category: Option<String>,
}
let id = id.as_ref();
let user_id = user_id.as_ref();
let entry = sqlx::query_as!(
RecipeRow,
"select recipe_id, recipe_text, category from recipes where user_id = ? and recipe_id = ?",
let entry = sqlx::query!(
"select recipe_id, recipe_text, category, serving_count from recipes where user_id = ? and recipe_id = ?",
user_id,
id,
)
@ -453,7 +443,8 @@ impl APIStore for SqliteStore {
RecipeEntry(
row.recipe_id.clone(),
row.recipe_text.clone().unwrap_or_else(|| String::new()),
row.category.clone()
row.category.clone(),
row.serving_count.clone(),
)
})
.nth(0);
@ -473,6 +464,7 @@ impl APIStore for SqliteStore {
row.recipe_id.clone(),
row.recipe_text.clone().unwrap_or_else(|| String::new()),
row.category.clone(),
row.serving_count.clone(),
)
})
.collect();
@ -488,13 +480,15 @@ impl APIStore for SqliteStore {
let recipe_id = entry.recipe_id().to_owned();
let recipe_text = entry.recipe_text().to_owned();
let category = entry.category();
let serving_count = entry.serving_count();
sqlx::query!(
"insert into recipes (user_id, recipe_id, recipe_text, category) values (?, ?, ?, ?)
"insert into recipes (user_id, recipe_id, recipe_text, category, serving_count) values (?, ?, ?, ?, ?)
on conflict(user_id, recipe_id) do update set recipe_text=excluded.recipe_text, category=excluded.category",
user_id,
recipe_id,
recipe_text,
category,
serving_count,
)
.execute(self.pool.as_ref())
.await?;

View File

@ -50,11 +50,11 @@ impl Mealplan {
}
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct RecipeEntry(pub String, pub String, pub Option<String>);
pub struct RecipeEntry(pub String, pub String, pub Option<String>, pub Option<i64>);
impl RecipeEntry {
pub fn new<IS: Into<String>, TS: Into<String>>(recipe_id: IS, text: TS) -> Self {
Self(recipe_id.into(), text.into(), None)
Self(recipe_id.into(), text.into(), None, None)
}
pub fn set_recipe_id<S: Into<String>>(&mut self, id: S) {
@ -80,6 +80,10 @@ impl RecipeEntry {
pub fn category(&self) -> Option<&String> {
self.2.as_ref()
}
pub fn serving_count(&self) -> Option<i64> {
self.3.clone()
}
}
/// A Recipe with a title, description, and a series of steps.

View File

@ -53,6 +53,7 @@ pub fn AddRecipe<'ctx, G: Html>(cx: Scope<'ctx>, sh: StateHandler<'ctx>) -> View
.replace("TITLE_PLACEHOLDER", recipe_title.get().as_str())
.replace("\r", ""),
category,
None,
)
});

View File

@ -119,6 +119,7 @@ pub fn Editor<'ctx, G: Html>(cx: Scope<'ctx>, props: RecipeComponentProps<'ctx>)
id.get_untracked().as_ref().clone(),
text.get_untracked().as_ref().clone(),
category,
None,
);
sh.dispatch(cx, Message::SaveRecipe(recipe_entry, None));
dirty.set(false);