package model import ( "database/sql" "errors" "fmt" "time" ) type Recipe struct { Id string `json:"id"` Title string `json:"title"` Portions string `json:"portions"` Url string `json:"url"` Notes string `json:"notes"` Created string `json:"created"` LastChanged string `json:"last_changed"` } func (r *Recipe) Touch() { now := time.Now().Unix() r.LastChanged = fmt.Sprint(now) } func (r *Recipe) Create() error { r.Touch() r.Created = r.LastChanged query := `INSERT INTO recipes (title, portions, url, notes, created, last_changed) VALUES (?, ?, ?, ?, ?, ?)` result, err := db.Exec(query, r.Title, r.Portions, r.Url, r.Notes, r.Created, r.LastChanged) if err != nil { return err } id, err := result.LastInsertId() if err != nil { return err } r.Id = fmt.Sprint(id) return nil } func (r *Recipe) Read() error { query := `SELECT id, title, portions, url, notes, created, last_changed FROM recipes WHERE id = ?` rows, err := db.Query(query, r.Id) if err != nil { return err } defer rows.Close() if !rows.Next() { return sql.ErrNoRows } err = rows.Scan( &r.Id, &r.Title, &r.Portions, &r.Url, &r.Notes, &r.Created, &r.LastChanged, ) if err != nil { return err } if rows.Next() { return errors.New("model: More than one object found on read") } return nil } func (r *Recipe) Update() error { r.Touch() query := `UPDATE recipes SET title = ?, portions = ?, url = ?, notes = ?, last_changed = ? WHERE id = ?` res, err := db.Exec(query, r.Title, r.Portions, r.Url, r.Notes, r.LastChanged, r.Id) if err != nil { return err } affected, err := res.RowsAffected() if err != nil { return err } if affected != 1 { return fmt.Errorf("Recipe update affected %d rows instead of 1", affected) } return nil } func (r *Recipe) Delete() error { query := `DELETE FROM recipes WHERE id = ?` result, err := db.Exec(query, r.Id) if err != nil { return err } rows, err := result.RowsAffected() if rows != 1 { return errors.New("Recipe deletion did not affect exactly one row") } return nil } func RecipeTestData() []Recipe { return []Recipe{ { Id: "1", Title: "Pancakes", Portions: "4", Url: "https://example.org", Notes: "Very fluffy", Created: "", LastChanged: "", }, { Id: "2", Title: "Burger", Portions: "2", Url: "https://xengineering.eu/git/ceres", Notes: "Delicious!", Created: "", LastChanged: "", }, } }