Add ingredient methods
This commit is contained in:
parent
981e1a663c
commit
7e03e15b3b
2
doc/TODO.txt
Normal file
2
doc/TODO.txt
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
TODO: figure-out-is-hidden
|
||||||
|
- what is it? Check in the existing foods database for items that are hidden i guess
|
@ -1,7 +1,7 @@
|
|||||||
package db
|
package db
|
||||||
|
|
||||||
import (
|
import (
|
||||||
// "fmt"
|
"fmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
type IngredientID uint64
|
type IngredientID uint64
|
||||||
@ -13,7 +13,7 @@ type Ingredient struct {
|
|||||||
|
|
||||||
QuantityNumerator int64 `db:"quantity_numerator"`
|
QuantityNumerator int64 `db:"quantity_numerator"`
|
||||||
QuantityDenominator int64 `db:"quantity_denominator"`
|
QuantityDenominator int64 `db:"quantity_denominator"`
|
||||||
Units Units `db:"units"`
|
Units UnitsID `db:"units"`
|
||||||
|
|
||||||
InRecipeID RecipeID `db:"in_recipe_id"`
|
InRecipeID RecipeID `db:"in_recipe_id"`
|
||||||
ListOrder int64 `db:"list_order"`
|
ListOrder int64 `db:"list_order"`
|
||||||
@ -24,3 +24,64 @@ type Ingredient struct {
|
|||||||
// func (i Ingredient) String() string {
|
// func (i Ingredient) String() string {
|
||||||
// return fmt.Sprintf("%s(%d)", f.Name, f.ID)
|
// return fmt.Sprintf("%s(%d)", f.Name, f.ID)
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
func (db *DB) SaveIngredient(i *Ingredient) {
|
||||||
|
if i.ID == IngredientID(0) {
|
||||||
|
println("creating---------")
|
||||||
|
// Do create
|
||||||
|
result, err := db.DB.NamedExec(`
|
||||||
|
insert into ingredients
|
||||||
|
(food_id, recipe_id, quantity_numerator, quantity_denominator, units, in_recipe_id, list_order, is_hidden)
|
||||||
|
values (nullif(:food_id, 0), nullif(:recipe_id, 0), :quantity_numerator, :quantity_denominator, :units, :in_recipe_id,
|
||||||
|
:list_order, :is_hidden)
|
||||||
|
`, i)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the ID
|
||||||
|
id, err := result.LastInsertId()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
i.ID = IngredientID(id)
|
||||||
|
} else {
|
||||||
|
println("updating---------")
|
||||||
|
// Do update
|
||||||
|
result, err := db.DB.NamedExec(`
|
||||||
|
update ingredients
|
||||||
|
set food_id=nullif(:food_id, 0),
|
||||||
|
recipe_id=nullif(:recipe_id, 0),
|
||||||
|
quantity_numerator=:quantity_numerator,
|
||||||
|
quantity_denominator=:quantity_denominator,
|
||||||
|
units=:units,
|
||||||
|
list_order=:list_order,
|
||||||
|
is_hidden=:is_hidden
|
||||||
|
where rowid = :rowid
|
||||||
|
`, i)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
count, err := result.RowsAffected()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if count != 1 {
|
||||||
|
panic(fmt.Errorf("Got ingredient with ID (%d), so attempted update, but it doesn't exist", i.ID))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *DB) DeleteIngredient(i Ingredient) {
|
||||||
|
result, err := db.DB.Exec(`delete from ingredients where rowid = ?`, i.ID)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
count, err := result.RowsAffected()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if count != 1 {
|
||||||
|
panic(fmt.Errorf("tried to delete ingredient with ID (%d) but it doesn't exist", i.ID))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
77
pkg/db/ingredient_test.go
Normal file
77
pkg/db/ingredient_test.go
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
package db_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/go-test/deep"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
. "recipe_book/pkg/db"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSaveAndLoadIngredient(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
require := require.New(t)
|
||||||
|
db := get_test_db()
|
||||||
|
|
||||||
|
// Setup
|
||||||
|
recipe := Recipe{
|
||||||
|
Name: "some Recipe",
|
||||||
|
Blurb: "Lorem Ispum dolor sit amet consquiter id blah blabh albha blahbla blahblahblh",
|
||||||
|
Instructions: RecipeInstructions{
|
||||||
|
"instr 1", "isntr 2", "instr3", "ins32gjkifw",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
db.SaveRecipe(&recipe)
|
||||||
|
food := Food{
|
||||||
|
Name: "a food",
|
||||||
|
Cals: 10,
|
||||||
|
Carbs: 1,
|
||||||
|
Protein: 2,
|
||||||
|
}
|
||||||
|
db.SaveFood(&food)
|
||||||
|
|
||||||
|
// Create an ingredient on the recipe
|
||||||
|
ingr := Ingredient{
|
||||||
|
FoodID: food.ID,
|
||||||
|
QuantityNumerator: 3,
|
||||||
|
QuantityDenominator: 2,
|
||||||
|
Units: 1, // count
|
||||||
|
InRecipeID: recipe.ID,
|
||||||
|
ListOrder: 0,
|
||||||
|
}
|
||||||
|
assert.Equal(ingr.ID, IngredientID(0))
|
||||||
|
db.SaveIngredient(&ingr)
|
||||||
|
assert.NotEqual(ingr.ID, IngredientID(0))
|
||||||
|
|
||||||
|
// It should be added to the recipe at position 0
|
||||||
|
new_recipe, err := db.GetRecipeByID(recipe.ID)
|
||||||
|
assert.NoError(err)
|
||||||
|
require.Len(new_recipe.Ingredients, 1)
|
||||||
|
new_ingr := new_recipe.Ingredients[0]
|
||||||
|
if diff := deep.Equal(ingr, new_ingr); diff != nil {
|
||||||
|
t.Error(diff)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Modify the ingredient
|
||||||
|
ingr.QuantityNumerator = 5
|
||||||
|
ingr.QuantityDenominator = 4
|
||||||
|
ingr.Units = 2
|
||||||
|
|
||||||
|
// Save it and reload the recipe
|
||||||
|
db.SaveIngredient(&ingr)
|
||||||
|
new_recipe, err = db.GetRecipeByID(recipe.ID)
|
||||||
|
assert.NoError(err)
|
||||||
|
require.Len(new_recipe.Ingredients, 1)
|
||||||
|
new_ingr = new_recipe.Ingredients[0]
|
||||||
|
if diff := deep.Equal(ingr, new_ingr); diff != nil {
|
||||||
|
t.Error(diff)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete and reload-- should be gone
|
||||||
|
db.DeleteIngredient(ingr)
|
||||||
|
new_recipe, err = db.GetRecipeByID(recipe.ID)
|
||||||
|
assert.NoError(err)
|
||||||
|
require.Len(new_recipe.Ingredients, 0)
|
||||||
|
}
|
@ -76,12 +76,6 @@ func (db *DB) SaveRecipe(r *Recipe) {
|
|||||||
// TODO: recompute the computed_food
|
// TODO: recompute the computed_food
|
||||||
}
|
}
|
||||||
|
|
||||||
// func (db *DB) AddIngredientToRecipe(r Recipe, i *Ingredient) {
|
|
||||||
// result, err := db.DB.NamedExec(`
|
|
||||||
// insert into ingredients
|
|
||||||
// `, ingr)
|
|
||||||
// }
|
|
||||||
|
|
||||||
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
|
||||||
@ -89,12 +83,13 @@ func (db *DB) GetRecipeByID(id RecipeID) (ret Recipe, err error) {
|
|||||||
where rowid = ?
|
where rowid = ?
|
||||||
`, id)
|
`, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Recipe{}, err
|
return Recipe{}, fmt.Errorf("fetching recipe with ID %d: %w", id, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load the ingredients
|
// Load the ingredients
|
||||||
err = db.DB.Select(&ret.Ingredients, `
|
err = db.DB.Select(&ret.Ingredients, `
|
||||||
select food_id, recipe_id, quantity_numerator, quantity_denominator, units, list_order, is_hidden
|
select rowid, ifnull(food_id, 0) food_id, ifnull(recipe_id, 0) recipe_id, quantity_numerator, quantity_denominator, units,
|
||||||
|
in_recipe_id, list_order, is_hidden
|
||||||
from ingredients
|
from ingredients
|
||||||
where in_recipe_id = ?
|
where in_recipe_id = ?
|
||||||
order by list_order asc
|
order by list_order asc
|
||||||
|
@ -52,19 +52,19 @@ create table units (rowid integer primary key,
|
|||||||
abbreviation text not null unique check(length(abbreviation) != 0)
|
abbreviation text not null unique check(length(abbreviation) != 0)
|
||||||
-- is_metric integer not null check(is_metric in (0, 1))
|
-- is_metric integer not null check(is_metric in (0, 1))
|
||||||
);
|
);
|
||||||
insert into units(name, abbreviation) values
|
insert into units(rowid, name, abbreviation) values
|
||||||
-- Count
|
-- Count
|
||||||
('count', 'ct'),
|
(1, 'count', 'ct'),
|
||||||
-- Mass
|
-- Mass
|
||||||
('grams', 'g'),
|
(2, 'grams', 'g'),
|
||||||
('pounds', 'lbs'),
|
(3, 'pounds', 'lbs'),
|
||||||
('ounces', 'oz'),
|
(4, 'ounces', 'oz'),
|
||||||
-- Volume
|
-- Volume
|
||||||
('milliliters', 'mL'),
|
(5, 'milliliters', 'mL'),
|
||||||
('cups', 'cups'),
|
(6, 'cups', 'cups'),
|
||||||
('teaspoons', 'tsp'),
|
(7, 'teaspoons', 'tsp'),
|
||||||
('tablespoons', 'tbsp'),
|
(8, 'tablespoons', 'tbsp'),
|
||||||
('fluid ounces', 'fl-oz');
|
(9, 'fluid ounces', 'fl-oz');
|
||||||
|
|
||||||
|
|
||||||
create table ingredients (rowid integer primary key,
|
create table ingredients (rowid integer primary key,
|
||||||
@ -82,7 +82,7 @@ create table ingredients (rowid integer primary key,
|
|||||||
in_recipe_id integer references recipes(rowid) on delete cascade not null,
|
in_recipe_id integer references recipes(rowid) on delete cascade not null,
|
||||||
list_order integer not null,
|
list_order integer not null,
|
||||||
is_hidden integer not null default false,
|
is_hidden integer not null default false,
|
||||||
unique (recipe_id, list_order)
|
unique (in_recipe_id, list_order)
|
||||||
check((food_id is null) + (recipe_id is null) = 1) -- Exactly one should be active
|
check((food_id is null) + (recipe_id is null) = 1) -- Exactly one should be active
|
||||||
) strict;
|
) strict;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user