summaryrefslogtreecommitdiff
path: root/model/recipe.go
diff options
context:
space:
mode:
authorxengineering <me@xengineering.eu>2024-04-06 18:45:49 +0200
committerxengineering <me@xengineering.eu>2024-04-06 20:22:04 +0200
commit4aee2c3b45caa890537a0fc0c850c4523a4eb56c (patch)
tree4818466a50c57360c24abbbde559edafc9125e29 /model/recipe.go
parentf65b11a5b3011f370df5b4d32239225f3708ecd5 (diff)
downloadceres-4aee2c3b45caa890537a0fc0c850c4523a4eb56c.tar
ceres-4aee2c3b45caa890537a0fc0c850c4523a4eb56c.tar.zst
ceres-4aee2c3b45caa890537a0fc0c850c4523a4eb56c.zip
model: CRUD methods only for targeted objects
A create, read, update or delete (CRUD) method should only care about the object which provides the receiver and the relations to its child objects. For example the method func (r *Recipe) Create(tx *sql.Tx) error {} should only create the relational data inside the database for the recipe, not for the steps nested into this Recipe struct. This should be covered by the func (s *Step) Create(tx *sql.Tx) error {} method which is then called by `func (r *Recipe) Create()`. This has the advantage that every CRUD method has a constraint scope and is more unified since the Step CRUD methods now have a Step struct as receiver instead of a Recipe receiver.
Diffstat (limited to 'model/recipe.go')
-rw-r--r--model/recipe.go106
1 files changed, 90 insertions, 16 deletions
diff --git a/model/recipe.go b/model/recipe.go
index b1ad781..c4f0d47 100644
--- a/model/recipe.go
+++ b/model/recipe.go
@@ -24,6 +24,10 @@ func (r Recipe) String() string {
}
func (r *Recipe) Create(tx *sql.Tx) error {
+ if r.Id != "" {
+ return fmt.Errorf("Cannot create recipe if ID is given")
+ }
+
cmd := `
INSERT INTO recipes
(title, portions, url, notes, created, last_changed)
@@ -44,19 +48,60 @@ VALUES
r.Id = fmt.Sprint(id)
- err = r.CreateSteps(tx)
- if err != nil {
- return err
+ for i := range r.Steps {
+ r.Steps[i].Recipe = r.Id
+ r.Steps[i].Index = fmt.Sprint(i)
+ err = r.Steps[i].Create(tx)
+ if err != nil {
+ return err
+ }
}
return nil
}
+func (r *Recipe) getStepIds(tx *sql.Tx) ([]Step, error) {
+ retval := make([]Step, 0)
+
+ cmd := `
+SELECT
+ id
+FROM
+ steps
+WHERE
+ recipe = ?
+ORDER BY
+ 'index' ASC
+`
+
+ rows, err := tx.Query(cmd, r.Id)
+ if err != nil {
+ return retval, err
+ }
+ defer rows.Close()
+
+ for rows.Next() {
+ s := Step{}
+
+ err = rows.Scan(&s.Id)
+ if err != nil {
+ return retval, err
+ }
+
+ retval = append(retval, s)
+ }
+
+ return retval, nil
+}
+
func (r *Recipe) Read(tx *sql.Tx) error {
cmd := `
-SELECT id, title, portions, url, notes, created, last_changed
-FROM recipes
-WHERE id = ?
+SELECT
+ title, portions, url, notes, created, last_changed
+FROM
+ recipes
+WHERE
+ id = ?
`
rows, err := tx.Query(cmd, r.Id)
@@ -70,7 +115,6 @@ WHERE id = ?
}
err = rows.Scan(
- &r.Id,
&r.Title,
&r.Portions,
&r.Url,
@@ -82,32 +126,57 @@ WHERE id = ?
return err
}
- err = r.ReadSteps(tx)
+ r.Steps, err = r.getStepIds(tx)
if err != nil {
return err
}
+ for i := range r.Steps {
+ err = r.Steps[i].Read(tx)
+ if err != nil {
+ return err
+ }
+ }
+
return nil
}
func (r *Recipe) Update(tx *sql.Tx) error {
- err := r.UpdateSteps(tx)
+ oldSteps, err := r.getStepIds(tx)
if err != nil {
return err
}
- query := `UPDATE
+ for i := range oldSteps {
+ err = oldSteps[i].Delete(tx)
+ if err != nil {
+ return err
+ }
+ }
+
+ for i := range r.Steps {
+ r.Steps[i].Index = fmt.Sprint(i)
+ r.Steps[i].Recipe = r.Id
+ r.Steps[i].Create(tx)
+ if err != nil {
+ return err
+ }
+ }
+
+ cmd := `
+UPDATE
recipes
SET
title = ?,
portions = ?,
url = ?,
notes = ?,
+ created = ?,
last_changed = ?
WHERE
id = ?`
- res, err := tx.Exec(query, r.Title, r.Portions, r.Url, r.Notes,
+ res, err := tx.Exec(cmd, r.Title, r.Portions, r.Url, r.Notes, r.Created,
r.LastChanged, r.Id)
if err != nil {
return err
@@ -125,19 +194,26 @@ WHERE
}
func (r *Recipe) Delete(tx *sql.Tx) error {
- err := r.DeleteSteps(tx)
+ oldSteps, err := r.getStepIds(tx)
if err != nil {
return err
}
- query := `
+ for i := range oldSteps {
+ err = oldSteps[i].Delete(tx)
+ if err != nil {
+ return err
+ }
+ }
+
+ cmd := `
DELETE FROM
recipes
WHERE
id = ?
`
- result, err := tx.Exec(query, r.Id)
+ result, err := tx.Exec(cmd, r.Id)
if err != nil {
return err
}
@@ -153,7 +229,6 @@ WHERE
func RecipeTestData() []Recipe {
return []Recipe{
{
- Id: "1",
Title: "Pancakes",
Portions: "4",
Url: "https://example.org",
@@ -167,7 +242,6 @@ func RecipeTestData() []Recipe {
},
},
{
- Id: "2",
Title: "Burger",
Portions: "2",
Url: "https://xengineering.eu/git/ceres",