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
|
||||
|
||||
import (
|
||||
// "fmt"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type IngredientID uint64
|
||||
@ -13,7 +13,7 @@ type Ingredient struct {
|
||||
|
||||
QuantityNumerator int64 `db:"quantity_numerator"`
|
||||
QuantityDenominator int64 `db:"quantity_denominator"`
|
||||
Units Units `db:"units"`
|
||||
Units UnitsID `db:"units"`
|
||||
|
||||
InRecipeID RecipeID `db:"in_recipe_id"`
|
||||
ListOrder int64 `db:"list_order"`
|
||||
@ -24,3 +24,64 @@ type Ingredient struct {
|
||||
// func (i Ingredient) String() string {
|
||||
// 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
|
||||
}
|
||||
|
||||
// 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) {
|
||||
err = db.DB.Get(&ret, `
|
||||
select rowid, name, blurb, instructions
|
||||
@ -89,12 +83,13 @@ func (db *DB) GetRecipeByID(id RecipeID) (ret Recipe, err error) {
|
||||
where rowid = ?
|
||||
`, id)
|
||||
if err != nil {
|
||||
return Recipe{}, err
|
||||
return Recipe{}, fmt.Errorf("fetching recipe with ID %d: %w", id, err)
|
||||
}
|
||||
|
||||
// Load the 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
|
||||
where in_recipe_id = ?
|
||||
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)
|
||||
-- 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', 'ct'),
|
||||
(1, 'count', 'ct'),
|
||||
-- Mass
|
||||
('grams', 'g'),
|
||||
('pounds', 'lbs'),
|
||||
('ounces', 'oz'),
|
||||
(2, 'grams', 'g'),
|
||||
(3, 'pounds', 'lbs'),
|
||||
(4, 'ounces', 'oz'),
|
||||
-- Volume
|
||||
('milliliters', 'mL'),
|
||||
('cups', 'cups'),
|
||||
('teaspoons', 'tsp'),
|
||||
('tablespoons', 'tbsp'),
|
||||
('fluid ounces', 'fl-oz');
|
||||
(5, 'milliliters', 'mL'),
|
||||
(6, 'cups', 'cups'),
|
||||
(7, 'teaspoons', 'tsp'),
|
||||
(8, 'tablespoons', 'tbsp'),
|
||||
(9, 'fluid ounces', 'fl-oz');
|
||||
|
||||
|
||||
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,
|
||||
list_order integer not null,
|
||||
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
|
||||
) strict;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user