summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTucker Evans <tuckerevans24@gmail.com>2019-11-12 10:53:41 -0500
committerTucker Evans <tuckerevans24@gmail.com>2019-11-12 10:56:22 -0500
commita6332c353552bc3ebe378d65322507a5fed3b124 (patch)
tree1b8b236fdadf20463599633b5d1161c4628da021
parentba3a25fe2a98bbf63264c47c8013a6d4d271e1c1 (diff)
Add update functionality to API
-rw-r--r--backend/main.go71
-rw-r--r--backend/recipe.go108
-rw-r--r--backend/todo.txt1
3 files changed, 174 insertions, 6 deletions
diff --git a/backend/main.go b/backend/main.go
index 856cd80..afe1102 100644
--- a/backend/main.go
+++ b/backend/main.go
@@ -40,6 +40,7 @@ func RecipeList(w http.ResponseWriter, r *http.Request) {
rows, err := db.Query("SELECT id FROM recipes")
if err != nil {
+ fmt.Println(err)
} else {
for rows.Next() {
rows.Scan(&id)
@@ -73,6 +74,7 @@ func RecipeList(w http.ResponseWriter, r *http.Request) {
err = json.Unmarshal(body, &recipe)
if err != nil {
+ fmt.Println(err)
w.WriteHeader(http.StatusUnprocessableEntity)
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
resp := APIResponseItem{
@@ -89,6 +91,7 @@ func RecipeList(w http.ResponseWriter, r *http.Request) {
err = AddRecipeDB(recipe, db)
if err != nil {
+ fmt.Println(err)
resp := APIResponseItem{
Status: APIError{Code: http.StatusBadRequest,
Msg: "Recipe could not be added"},
@@ -162,9 +165,73 @@ func SingleRecipe(w http.ResponseWriter, r *http.Request) {
fmt.Printf("Create recipe \"%d\"...\n", recipe_id)
//TODO add error msg response
} else if r.Method == "PUT" {
- //TODO add Update Recipe
- fmt.Printf("Update recipe \"%d\"...\n", recipe_id)
+ var recipe *Recipe
+
+ body, err := ioutil.ReadAll(io.LimitReader(r.Body, 1048576))
+ if err != nil {
+ panic(err)
+ }
+
+ err = r.Body.Close()
+ if err != nil {
+ panic(err)
+ }
+
+ err = json.Unmarshal(body, &recipe)
+ if err != nil {
+ fmt.Println(err)
+ w.WriteHeader(http.StatusUnprocessableEntity)
+ w.Header().Set("Content-Type", "application/json; charset=UTF-8")
+ resp := APIResponseItem{
+ Status: APIError{
+ Code: http.StatusUnprocessableEntity,
+ Msg: "Invalid Recipe"},
+ Data: make([]APIDataRecipe, 0),
+ }
+ if err := json.NewEncoder(w).Encode(resp); err != nil {
+ panic(err)
+ }
+ return
+ }
+
+ recipe.Id = recipe_id
+
+ err = UpdateRecipeDB(recipe, db)
+ if err != nil {
+ fmt.Println(err)
+ resp := APIResponseItem{
+ Status: APIError{Code: http.StatusBadRequest,
+ Msg: "Recipe could not be updated"},
+ Data: make([]APIDataRecipe, 0),
+ }
+
+ resp.Data = append(resp.Data, APIDataRecipe{recipe})
+
+ w.Header().Set("Content-Type",
+ "application/json; charset=UTF-8")
+ w.WriteHeader(http.StatusBadRequest)
+ if err := json.NewEncoder(w).Encode(resp); err != nil {
+ panic(err)
+ }
+ return
+ }
+
+ resp := APIResponseItem{
+ Status: APIError{Code: http.StatusCreated,
+ Msg: "Recipe added successfully"},
+ Data: make([]APIDataRecipe, 0),
+ }
+
+ resp.Data = append(resp.Data, APIDataRecipe{recipe})
+
+ w.Header().Set("Content-Type", "application/json; charset=UTF-8")
+ w.WriteHeader(http.StatusCreated)
+ if err := json.NewEncoder(w).Encode(resp); err != nil {
+ panic(err)
+ }
+
} else if r.Method == "DELETE" {
+
res, err := db.Exec(`DELETE FROM recipes where id = $1`,
recipe_id)
if err != nil {
diff --git a/backend/recipe.go b/backend/recipe.go
index 89a01df..fed83ca 100644
--- a/backend/recipe.go
+++ b/backend/recipe.go
@@ -1,6 +1,7 @@
package main
import "database/sql"
+import "errors"
import "strings"
type Ingredient struct {
@@ -100,7 +101,6 @@ func RecipeFromId(id int, db *sql.DB) *Recipe {
id)
defer rows_ingr.Close()
if err == nil {
- var i int
for rows_ingr.Next() {
rows_ingr.Scan(&name, &amount, &unit)
ingr = Ingredient{
@@ -145,8 +145,11 @@ func AddRecipeDB(r *Recipe, db *sql.DB) error {
keywords.WriteRune('|')
}
- tx := db.Begin()
- err := tx.QueryRow(`INSERT INTO recipes (title, photo_urls,
+ tx, err := db.Begin()
+ if err != nil {
+ return err
+ }
+ err = tx.QueryRow(`INSERT INTO recipes (title, photo_urls,
keywords, description, serving_size, cook_time,
rating, num_cooked)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
@@ -202,3 +205,102 @@ func AddRecipeDB(r *Recipe, db *sql.DB) error {
tx.Commit()
return nil
}
+
+func UpdateRecipeDB(r *Recipe, db *sql.DB) error {
+ var photo_urls, keywords strings.Builder
+
+ for _, u := range r.Photos {
+ photo_urls.WriteString(u)
+ photo_urls.WriteRune('|')
+ }
+
+ for _, k := range r.Keywords {
+ keywords.WriteString(k)
+ keywords.WriteRune('|')
+ }
+
+ tx, err := db.Begin()
+ if err != nil {
+ return err
+ }
+ _, err = tx.Exec(`UPDATE recipes SET (title, photo_urls,
+ keywords, description, serving_size, cook_time,
+ rating, num_cooked)
+ = ($1, $2, $3, $4, $5, $6, $7, $8)
+ WHERE id = $9`,
+ r.Title, //1
+ photo_urls.String(), //2
+ keywords.String(), //3
+ r.Desc, //4
+ r.Serving_size, //5
+ r.Cook_time, //6
+ r.Rating, //7
+ r.Num_cooked, //8
+ r.Id, //9
+ )
+ if err != nil {
+ tx.Rollback()
+ return err
+ }
+
+ _, err = tx.Exec("DELETE FROM ingredients WHERE id > $1",
+ len(r.Ingredients)-1)
+ if err != nil {
+ tx.Rollback()
+ return err
+ }
+
+ for i, ingr := range r.Ingredients {
+ _, err := tx.Exec(`INSERT INTO ingredients
+ (id, name, amount, unit, recipe_id)
+ VALUES ($1, $2, $3, $4, $5)
+ ON CONFLICT (id, recipe_id)
+ DO UPDATE SET
+ (name, amount, unit)
+ = ($2, $3, $4)`,
+
+ i,
+ ingr.Name,
+ ingr.Amount,
+ ingr.Unit,
+ r.Id,
+ )
+ if err != nil {
+ tx.Rollback()
+ return err
+ }
+ }
+
+ _, err = tx.Exec("DELETE FROM steps WHERE step > $1",
+ len(r.Steps)-1)
+ if err != nil {
+ tx.Rollback()
+ return err
+ }
+
+ for i, step := range r.Steps {
+ if step.Num != 0 {
+ tx.Rollback()
+ return errors.New("invalid json Recipe")
+ }
+ _, err := tx.Exec(`INSERT INTO steps
+ (step, description, timer, recipe_id)
+ VALUES ($1, $2, $3, $4)
+ ON CONFLICT (step,recipe_id)
+ DO UPDATE SET
+ (description, timer)
+ = ($2, $3)`,
+ i,
+ step.Desc,
+ step.Time,
+ r.Id,
+ )
+ if err != nil {
+ tx.Rollback()
+ return err
+ }
+ }
+
+ tx.Commit()
+ return nil
+}
diff --git a/backend/todo.txt b/backend/todo.txt
index 3c911c4..cb074a4 100644
--- a/backend/todo.txt
+++ b/backend/todo.txt
@@ -1,2 +1 @@
-Add Update method for recipes
Add Error responses for incorrect methods