diff options
author | xengineering <me@xengineering.eu> | 2024-04-06 13:12:17 +0200 |
---|---|---|
committer | xengineering <me@xengineering.eu> | 2024-04-06 13:12:17 +0200 |
commit | f65b11a5b3011f370df5b4d32239225f3708ecd5 (patch) | |
tree | 360261244c95e80cf2a56160527f5be7c6f5e2d7 /model/recipe.go | |
parent | 9985d6f86fcee9d3c1d1148a5977190b673a8e8e (diff) | |
download | ceres-f65b11a5b3011f370df5b4d32239225f3708ecd5.tar ceres-f65b11a5b3011f370df5b4d32239225f3708ecd5.tar.zst ceres-f65b11a5b3011f370df5b4d32239225f3708ecd5.zip |
model: Always pass *sql.Tx to CRUD methods
When nesting objects like steps into other objects like recipes it is
required to pass a *sql.Tx value to the CRUD methods of the inner
object to be able to roll back the whole transaction.
The top level object used to be responsible for the creation of this
*sql.Tx inside its CRUD methods.
This is now moved to the caller of the CRUD methods (here the HTTP
handler function). The advantage is that all CRUD methods now accept a
*sql.Tx as only argument which makes those methods more consistent.
Diffstat (limited to 'model/recipe.go')
-rw-r--r-- | model/recipe.go | 54 |
1 files changed, 10 insertions, 44 deletions
diff --git a/model/recipe.go b/model/recipe.go index 6750426..b1ad781 100644 --- a/model/recipe.go +++ b/model/recipe.go @@ -23,12 +23,7 @@ func (r Recipe) String() string { return string(b) } -func (r *Recipe) Create() error { - tx, err := db.Begin() - if err != nil { - return err - } - +func (r *Recipe) Create(tx *sql.Tx) error { cmd := ` INSERT INTO recipes (title, portions, url, notes, created, last_changed) @@ -39,13 +34,11 @@ VALUES result, err := tx.Exec(cmd, r.Title, r.Portions, r.Url, r.Notes, r.Created, r.LastChanged) if err != nil { - rollback(tx) return err } id, err := result.LastInsertId() if err != nil { - rollback(tx) return err } @@ -53,19 +46,13 @@ VALUES err = r.CreateSteps(tx) if err != nil { - rollback(tx) return err } - return tx.Commit() + return nil } -func (r *Recipe) Read() error { - tx, err := db.Begin() - if err != nil { - return err - } - +func (r *Recipe) Read(tx *sql.Tx) error { cmd := ` SELECT id, title, portions, url, notes, created, last_changed FROM recipes @@ -74,13 +61,11 @@ WHERE id = ? rows, err := tx.Query(cmd, r.Id) if err != nil { - rollback(tx) return err } defer rows.Close() if !rows.Next() { - rollback(tx) return sql.ErrNoRows } @@ -94,31 +79,23 @@ WHERE id = ? &r.LastChanged, ) if err != nil { - rollback(tx) return err } err = r.ReadSteps(tx) if err != nil { - rollback(tx) return err } - return tx.Commit() + return nil } -func (r *Recipe) Update() error { - tx, err := db.Begin() +func (r *Recipe) Update(tx *sql.Tx) error { + err := r.UpdateSteps(tx) if err != nil { return err } - err = r.UpdateSteps(tx) - if err != nil { - rollback(tx) - return err - } - query := `UPDATE recipes SET @@ -133,32 +110,23 @@ WHERE res, err := tx.Exec(query, r.Title, r.Portions, r.Url, r.Notes, r.LastChanged, r.Id) if err != nil { - rollback(tx) return err } affected, err := res.RowsAffected() if err != nil { - rollback(tx) return err } if affected != 1 { - rollback(tx) return fmt.Errorf("Recipe update affected %d rows instead of 1", affected) } - return tx.Commit() + return nil } -func (r *Recipe) Delete() error { - tx, err := db.Begin() - if err != nil { - return err - } - - err = r.DeleteSteps(tx) +func (r *Recipe) Delete(tx *sql.Tx) error { + err := r.DeleteSteps(tx) if err != nil { - rollback(tx) return err } @@ -171,17 +139,15 @@ WHERE result, err := tx.Exec(query, r.Id) if err != nil { - rollback(tx) return err } rows, err := result.RowsAffected() if rows != 1 { - rollback(tx) return errors.New("Recipe deletion did not affect exactly one row") } - return tx.Commit() + return nil } func RecipeTestData() []Recipe { |