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
|
TODO: figure-out-is-hidden
|
||||||
- what is it? Check in the existing foods database for items that are hidden i guess
|
- 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"`
|
ListOrder int64 `db:"list_order"`
|
||||||
IsHidden bool `db:"is_hidden"`
|
IsHidden bool `db:"is_hidden"`
|
||||||
|
|
||||||
Food *Food
|
Food Food
|
||||||
}
|
}
|
||||||
|
|
||||||
// Format as string
|
// 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))
|
panic(fmt.Errorf("tried to delete ingredient with ID (%d) but it doesn't exist", i.ID))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// func (i Ingredient) AddTo(r *Recipe) {
|
// func (i Ingredient) AddTo(r *Recipe) {
|
||||||
|
|
||||||
// }
|
// }
|
||||||
|
@ -29,7 +29,7 @@ func TestSaveAndLoadIngredient(t *testing.T) {
|
|||||||
// Create an ingredient on the recipe
|
// Create an ingredient on the recipe
|
||||||
ingr := Ingredient{
|
ingr := Ingredient{
|
||||||
FoodID: food.ID,
|
FoodID: food.ID,
|
||||||
Food: &food,
|
Food: food,
|
||||||
Quantity: 1.5,
|
Quantity: 1.5,
|
||||||
Units: 1, // count
|
Units: 1, // count
|
||||||
InRecipeID: recipe.ID,
|
InRecipeID: recipe.ID,
|
||||||
|
@ -36,16 +36,23 @@ type Recipe struct {
|
|||||||
ComputedFoodID FoodID `db:"computed_food_id"`
|
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) {
|
func (db *DB) SaveRecipe(r *Recipe) {
|
||||||
if r.ID == RecipeID(0) {
|
if r.ID == RecipeID(0) {
|
||||||
// Do create
|
// 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(`
|
result, err := db.DB.NamedExec(`
|
||||||
insert into recipes (name, blurb, instructions)
|
insert into recipes (name, blurb, instructions, computed_food_id)
|
||||||
values (:name, :blurb, :instructions)
|
values (:name, :blurb, :instructions, :computed_food_id)
|
||||||
on conflict do update
|
|
||||||
set name=:name,
|
|
||||||
blurb=:blurb,
|
|
||||||
instructions=:instructions
|
|
||||||
`, r)
|
`, r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
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))
|
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) {
|
func (db *DB) GetRecipeByID(id RecipeID) (ret Recipe, err error) {
|
||||||
err = db.DB.Get(&ret, `
|
err = db.DB.Get(&ret, `
|
||||||
select rowid, name, blurb, instructions
|
select rowid, name, blurb, instructions, computed_food_id
|
||||||
from recipes
|
from recipes
|
||||||
where rowid = ?
|
where rowid = ?
|
||||||
`, id)
|
`, id)
|
||||||
@ -98,11 +111,9 @@ func (db *DB) GetRecipeByID(id RecipeID) (ret Recipe, err error) {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
for i := range ret.Ingredients {
|
for i := range ret.Ingredients {
|
||||||
var food Food
|
|
||||||
if ret.Ingredients[i].FoodID != FoodID(0) {
|
if ret.Ingredients[i].FoodID != FoodID(0) {
|
||||||
// ingredient is a food
|
// ingredient is a food
|
||||||
food, err = db.GetFoodByID(ret.Ingredients[i].FoodID)
|
ret.Ingredients[i].Food, err = db.GetFoodByID(ret.Ingredients[i].FoodID)
|
||||||
ret.Ingredients[i].Food = &food
|
|
||||||
} else {
|
} else {
|
||||||
// ingredient is a food; i.Food is the ComputedFood of the Recipe
|
// ingredient is a food; i.Food is the ComputedFood of the Recipe
|
||||||
var computed_food_id FoodID
|
var computed_food_id FoodID
|
||||||
@ -110,8 +121,7 @@ func (db *DB) GetRecipeByID(id RecipeID) (ret Recipe, err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
food, err = db.GetFoodByID(computed_food_id)
|
ret.Ingredients[i].Food, err = db.GetFoodByID(computed_food_id)
|
||||||
ret.Ingredients[i].Food = &food
|
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
@ -121,7 +131,8 @@ func (db *DB) GetRecipeByID(id RecipeID) (ret Recipe, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r Recipe) ComputeFood() Food {
|
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 {
|
for _, ingr := range r.Ingredients {
|
||||||
ret.Cals += ingr.Quantity * ingr.Food.Cals
|
ret.Cals += ingr.Quantity * ingr.Food.Cals
|
||||||
ret.Carbs += ingr.Quantity * ingr.Food.Carbs
|
ret.Carbs += ingr.Quantity * ingr.Food.Carbs
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
|
|
||||||
"github.com/go-test/deep"
|
"github.com/go-test/deep"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
. "recipe_book/pkg/db"
|
. "recipe_book/pkg/db"
|
||||||
)
|
)
|
||||||
@ -21,8 +22,10 @@ func TestRecipeSaveAndLoad(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
assert.Equal(recipe.ID, RecipeID(0))
|
assert.Equal(recipe.ID, RecipeID(0))
|
||||||
|
assert.Equal(recipe.ComputedFoodID, FoodID(0))
|
||||||
db.SaveRecipe(&recipe)
|
db.SaveRecipe(&recipe)
|
||||||
assert.NotEqual(recipe.ID, RecipeID(0))
|
assert.NotEqual(recipe.ID, RecipeID(0))
|
||||||
|
assert.NotEqual(recipe.ComputedFoodID, FoodID(0))
|
||||||
new_recipe, err := db.GetRecipeByID(recipe.ID)
|
new_recipe, err := db.GetRecipeByID(recipe.ID)
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
if diff := deep.Equal(recipe, new_recipe); diff != nil {
|
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}
|
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{
|
recipe := Recipe{Ingredients: []Ingredient{
|
||||||
{Quantity: 1, Food: &f1},
|
{Quantity: 1, Food: f1},
|
||||||
{Quantity: 1, Food: &f2},
|
{Quantity: 1, Food: f2},
|
||||||
}}
|
}}
|
||||||
computed_food := recipe.ComputeFood()
|
computed_food := recipe.ComputeFood()
|
||||||
assert.Equal(computed_food.Cals, float32(17.5))
|
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))
|
assert.Equal(computed_food.Price, float32(17.5))
|
||||||
|
|
||||||
recipe2 := Recipe{Ingredients: []Ingredient{
|
recipe2 := Recipe{Ingredients: []Ingredient{
|
||||||
{Quantity: 1.5, Food: &f1},
|
{Quantity: 1.5, Food: f1},
|
||||||
{Quantity: 0.5, Food: &f2},
|
{Quantity: 0.5, Food: f2},
|
||||||
}}
|
}}
|
||||||
computed_food2 := recipe2.ComputeFood()
|
computed_food2 := recipe2.ComputeFood()
|
||||||
assert.Equal(computed_food2.Cals, float32(9.75))
|
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.Mass, float32(23.75))
|
||||||
assert.Equal(computed_food2.Price, float32(24.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,
|
create table foods (rowid integer primary key,
|
||||||
name text not null check(length(name) != 0),
|
name text not null check(length(name) != 0),
|
||||||
|
|
||||||
-- created_at integer not null,
|
|
||||||
-- updated_at integer,
|
|
||||||
|
|
||||||
cals real not null,
|
cals real not null,
|
||||||
carbs real not null,
|
carbs real not null,
|
||||||
protein 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,
|
create table ingredients (rowid integer primary key,
|
||||||
-- created_at integer not null,
|
|
||||||
-- updated_at integer,
|
|
||||||
|
|
||||||
food_id integer references foods(rowid),
|
food_id integer references foods(rowid),
|
||||||
recipe_id integer references recipes(rowid),
|
recipe_id integer references recipes(rowid),
|
||||||
|
|
||||||
-- Portion size (rational numbers)
|
|
||||||
quantity real not null default 1,
|
quantity real not null default 1,
|
||||||
units integer not null default 0, -- Display purposes only
|
units integer not null default 0, -- Display purposes only
|
||||||
|
|
||||||
@ -86,20 +79,14 @@ create table ingredients (rowid integer primary key,
|
|||||||
) strict;
|
) strict;
|
||||||
|
|
||||||
create table recipes (rowid integer primary key,
|
create table recipes (rowid integer primary key,
|
||||||
-- created_at integer not null,
|
|
||||||
-- updated_at integer,
|
|
||||||
|
|
||||||
name text not null check(length(name) != 0),
|
name text not null check(length(name) != 0),
|
||||||
blurb text not null,
|
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;
|
) strict;
|
||||||
|
|
||||||
create table iterations (rowid integer primary key,
|
create table iterations (rowid integer primary key,
|
||||||
-- created_at integer not null,
|
|
||||||
-- updated_at integer,
|
|
||||||
|
|
||||||
original_recipe_id integer references recipes(rowid),
|
original_recipe_id integer references recipes(rowid),
|
||||||
-- original_author integer not null, -- For azimuth integration
|
-- original_author integer not null, -- For azimuth integration
|
||||||
derived_recipe_id integer references recipes(rowid),
|
derived_recipe_id integer references recipes(rowid),
|
||||||
@ -107,9 +94,6 @@ create table iterations (rowid integer primary key,
|
|||||||
) strict;
|
) strict;
|
||||||
|
|
||||||
create table daily_logs (rowid integer primary key,
|
create table daily_logs (rowid integer primary key,
|
||||||
-- created_at integer not null,
|
|
||||||
-- updated_at integer,
|
|
||||||
|
|
||||||
date integer not null unique,
|
date integer not null unique,
|
||||||
|
|
||||||
computed_food_id integer references foods(rowid) not null
|
computed_food_id integer references foods(rowid) not null
|
||||||
|
Loading…
x
Reference in New Issue
Block a user