Recipes should now compute their equivalent food on save
This commit is contained in:
parent
9023f13b19
commit
7d2f47b1a2
@ -1,2 +1,4 @@
|
||||
TODO: figure-out-is-hidden
|
||||
- what is it? Check in the existing foods database for items that are hidden i guess
|
||||
|
||||
TODO: add-created-at-modified-at-timestamps
|
||||
|
@ -18,7 +18,7 @@ type Ingredient struct {
|
||||
ListOrder int64 `db:"list_order"`
|
||||
IsHidden bool `db:"is_hidden"`
|
||||
|
||||
Food *Food
|
||||
Food Food
|
||||
}
|
||||
|
||||
// Format as string
|
||||
@ -83,6 +83,7 @@ func (db *DB) DeleteIngredient(i Ingredient) {
|
||||
panic(fmt.Errorf("tried to delete ingredient with ID (%d) but it doesn't exist", i.ID))
|
||||
}
|
||||
}
|
||||
|
||||
// func (i Ingredient) AddTo(r *Recipe) {
|
||||
|
||||
// }
|
||||
|
@ -29,7 +29,7 @@ func TestSaveAndLoadIngredient(t *testing.T) {
|
||||
// Create an ingredient on the recipe
|
||||
ingr := Ingredient{
|
||||
FoodID: food.ID,
|
||||
Food: &food,
|
||||
Food: food,
|
||||
Quantity: 1.5,
|
||||
Units: 1, // count
|
||||
InRecipeID: recipe.ID,
|
||||
|
@ -36,16 +36,23 @@ type Recipe struct {
|
||||
ComputedFoodID FoodID `db:"computed_food_id"`
|
||||
}
|
||||
|
||||
// Save the recipe. New recipes will have their ID back-filled from the DB.
|
||||
//
|
||||
// Automatically updates the computed food, creating one if it's a new recipe and back-filling the
|
||||
// `computed_food_id` foreign key to it.
|
||||
func (db *DB) SaveRecipe(r *Recipe) {
|
||||
if r.ID == RecipeID(0) {
|
||||
// Do create
|
||||
|
||||
// Create the computed food
|
||||
computed_food := Food{Name: r.Name}
|
||||
db.SaveFood(&computed_food)
|
||||
r.ComputedFoodID = computed_food.ID
|
||||
|
||||
// Create the recipe
|
||||
result, err := db.DB.NamedExec(`
|
||||
insert into recipes (name, blurb, instructions)
|
||||
values (:name, :blurb, :instructions)
|
||||
on conflict do update
|
||||
set name=:name,
|
||||
blurb=:blurb,
|
||||
instructions=:instructions
|
||||
insert into recipes (name, blurb, instructions, computed_food_id)
|
||||
values (:name, :blurb, :instructions, :computed_food_id)
|
||||
`, r)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
@ -73,12 +80,18 @@ func (db *DB) SaveRecipe(r *Recipe) {
|
||||
panic(fmt.Errorf("Got recipe with ID (%d), so attempted update, but it doesn't exist", r.ID))
|
||||
}
|
||||
}
|
||||
// TODO: recompute the computed_food
|
||||
for i := range r.Ingredients {
|
||||
r.Ingredients[i].InRecipeID = r.ID
|
||||
db.SaveIngredient(&r.Ingredients[i])
|
||||
}
|
||||
// Update the computed food
|
||||
computed_food := r.ComputeFood()
|
||||
db.SaveFood(&computed_food)
|
||||
}
|
||||
|
||||
func (db *DB) GetRecipeByID(id RecipeID) (ret Recipe, err error) {
|
||||
err = db.DB.Get(&ret, `
|
||||
select rowid, name, blurb, instructions
|
||||
select rowid, name, blurb, instructions, computed_food_id
|
||||
from recipes
|
||||
where rowid = ?
|
||||
`, id)
|
||||
@ -98,11 +111,9 @@ func (db *DB) GetRecipeByID(id RecipeID) (ret Recipe, err error) {
|
||||
panic(err)
|
||||
}
|
||||
for i := range ret.Ingredients {
|
||||
var food Food
|
||||
if ret.Ingredients[i].FoodID != FoodID(0) {
|
||||
// ingredient is a food
|
||||
food, err = db.GetFoodByID(ret.Ingredients[i].FoodID)
|
||||
ret.Ingredients[i].Food = &food
|
||||
ret.Ingredients[i].Food, err = db.GetFoodByID(ret.Ingredients[i].FoodID)
|
||||
} else {
|
||||
// ingredient is a food; i.Food is the ComputedFood of the Recipe
|
||||
var computed_food_id FoodID
|
||||
@ -110,8 +121,7 @@ func (db *DB) GetRecipeByID(id RecipeID) (ret Recipe, err error) {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
food, err = db.GetFoodByID(computed_food_id)
|
||||
ret.Ingredients[i].Food = &food
|
||||
ret.Ingredients[i].Food, err = db.GetFoodByID(computed_food_id)
|
||||
}
|
||||
if err != nil {
|
||||
panic(err)
|
||||
@ -121,7 +131,8 @@ func (db *DB) GetRecipeByID(id RecipeID) (ret Recipe, err error) {
|
||||
}
|
||||
|
||||
func (r Recipe) ComputeFood() Food {
|
||||
ret := Food{}
|
||||
// If r.ComputedFoodID is 0, so should be the ID of returned Food
|
||||
ret := Food{ID: r.ComputedFoodID, Name: r.Name}
|
||||
for _, ingr := range r.Ingredients {
|
||||
ret.Cals += ingr.Quantity * ingr.Food.Cals
|
||||
ret.Carbs += ingr.Quantity * ingr.Food.Carbs
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
|
||||
"github.com/go-test/deep"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
. "recipe_book/pkg/db"
|
||||
)
|
||||
@ -21,8 +22,10 @@ func TestRecipeSaveAndLoad(t *testing.T) {
|
||||
},
|
||||
}
|
||||
assert.Equal(recipe.ID, RecipeID(0))
|
||||
assert.Equal(recipe.ComputedFoodID, FoodID(0))
|
||||
db.SaveRecipe(&recipe)
|
||||
assert.NotEqual(recipe.ID, RecipeID(0))
|
||||
assert.NotEqual(recipe.ComputedFoodID, FoodID(0))
|
||||
new_recipe, err := db.GetRecipeByID(recipe.ID)
|
||||
assert.NoError(err)
|
||||
if diff := deep.Equal(recipe, new_recipe); diff != nil {
|
||||
@ -49,8 +52,8 @@ func TestRecipeComputeFood(t *testing.T) {
|
||||
f2 := Food{0, "", 16.5, 15.5, 14.5, 13.5, 12.5, 11.5, 10.5, 9.5, 8.5, 7.5, 6.5, 5.5, 4.5, 3.5, 2.5, 1.5, 0, 0}
|
||||
|
||||
recipe := Recipe{Ingredients: []Ingredient{
|
||||
{Quantity: 1, Food: &f1},
|
||||
{Quantity: 1, Food: &f2},
|
||||
{Quantity: 1, Food: f1},
|
||||
{Quantity: 1, Food: f2},
|
||||
}}
|
||||
computed_food := recipe.ComputeFood()
|
||||
assert.Equal(computed_food.Cals, float32(17.5))
|
||||
@ -71,8 +74,8 @@ func TestRecipeComputeFood(t *testing.T) {
|
||||
assert.Equal(computed_food.Price, float32(17.5))
|
||||
|
||||
recipe2 := Recipe{Ingredients: []Ingredient{
|
||||
{Quantity: 1.5, Food: &f1},
|
||||
{Quantity: 0.5, Food: &f2},
|
||||
{Quantity: 1.5, Food: f1},
|
||||
{Quantity: 0.5, Food: f2},
|
||||
}}
|
||||
computed_food2 := recipe2.ComputeFood()
|
||||
assert.Equal(computed_food2.Cals, float32(9.75))
|
||||
@ -92,3 +95,27 @@ func TestRecipeComputeFood(t *testing.T) {
|
||||
assert.Equal(computed_food2.Mass, float32(23.75))
|
||||
assert.Equal(computed_food2.Price, float32(24.75))
|
||||
}
|
||||
|
||||
func TestRecipeSaveComputedFood(t *testing.T) {
|
||||
// assert := assert.New(t)
|
||||
require := require.New(t)
|
||||
db := get_test_db()
|
||||
|
||||
pasta := get_food(db, 3)
|
||||
require.Equal(pasta.Name, "pasta")
|
||||
tomatoes := get_food(db, 105)
|
||||
require.Equal(tomatoes.Name, "canned tomatoes")
|
||||
parm := get_food(db, 86)
|
||||
require.Equal(parm.Name, "parmigiano")
|
||||
|
||||
recipe := Recipe{Name: "pasta w/ sauce", Ingredients: []Ingredient{
|
||||
{Quantity: 2, FoodID: pasta.ID, Food: pasta, ListOrder: 0},
|
||||
{Quantity: 2.5, FoodID: tomatoes.ID, Food: tomatoes, ListOrder: 1},
|
||||
{Quantity: 0.5, FoodID: parm.ID, Food: parm, ListOrder: 2},
|
||||
}}
|
||||
db.SaveRecipe(&recipe)
|
||||
computed_food := get_food(db, recipe.ComputedFoodID)
|
||||
if diff := deep.Equal(recipe.ComputeFood(), computed_food); diff != nil {
|
||||
t.Error(diff)
|
||||
}
|
||||
}
|
||||
|
@ -20,9 +20,6 @@ insert into food_types (name) values
|
||||
create table foods (rowid integer primary key,
|
||||
name text not null check(length(name) != 0),
|
||||
|
||||
-- created_at integer not null,
|
||||
-- updated_at integer,
|
||||
|
||||
cals real not null,
|
||||
carbs real not null,
|
||||
protein real not null,
|
||||
@ -68,13 +65,9 @@ insert into units(rowid, name, abbreviation) values
|
||||
|
||||
|
||||
create table ingredients (rowid integer primary key,
|
||||
-- created_at integer not null,
|
||||
-- updated_at integer,
|
||||
|
||||
food_id integer references foods(rowid),
|
||||
recipe_id integer references recipes(rowid),
|
||||
|
||||
-- Portion size (rational numbers)
|
||||
quantity real not null default 1,
|
||||
units integer not null default 0, -- Display purposes only
|
||||
|
||||
@ -86,20 +79,14 @@ create table ingredients (rowid integer primary key,
|
||||
) strict;
|
||||
|
||||
create table recipes (rowid integer primary key,
|
||||
-- created_at integer not null,
|
||||
-- updated_at integer,
|
||||
|
||||
name text not null check(length(name) != 0),
|
||||
blurb text not null,
|
||||
instructions text not null
|
||||
instructions text not null,
|
||||
|
||||
-- computed_food_id integer references foods(rowid) not null
|
||||
computed_food_id integer references foods(rowid) not null
|
||||
) strict;
|
||||
|
||||
create table iterations (rowid integer primary key,
|
||||
-- created_at integer not null,
|
||||
-- updated_at integer,
|
||||
|
||||
original_recipe_id integer references recipes(rowid),
|
||||
-- original_author integer not null, -- For azimuth integration
|
||||
derived_recipe_id integer references recipes(rowid),
|
||||
@ -107,9 +94,6 @@ create table iterations (rowid integer primary key,
|
||||
) strict;
|
||||
|
||||
create table daily_logs (rowid integer primary key,
|
||||
-- created_at integer not null,
|
||||
-- updated_at integer,
|
||||
|
||||
date integer not null unique,
|
||||
|
||||
computed_food_id integer references foods(rowid) not null
|
||||
|
Loading…
x
Reference in New Issue
Block a user