From 898a9ed40e4422d9062b58efaf070cf31a7ef168 Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Sun, 10 Nov 2019 14:32:40 -0500 Subject: Add create recipe functionality --- backend/main.go | 67 +++++++++++++++++++++++++++++++++++++++++++++++-- backend/recipe.go | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 139 insertions(+), 2 deletions(-) diff --git a/backend/main.go b/backend/main.go index 7376bd0..c39f123 100644 --- a/backend/main.go +++ b/backend/main.go @@ -1,6 +1,8 @@ package main import "fmt" +import "io" +import "io/ioutil" import "net/http" import "os" import "strconv" @@ -56,7 +58,70 @@ func RecipeList(w http.ResponseWriter, r *http.Request) { if err := json.NewEncoder(w).Encode(resp); err != nil { panic(err) } + } else if r.Method == "POST" { + 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 { + 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 + } + + err = AddRecipeDB(recipe, db) + if err != nil { + resp := APIResponseItem{ + Status: APIError{Code: http.StatusBadRequest, + Msg: "Recipe could not be added"}, + 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) + } + } + } func SingleRecipe(w http.ResponseWriter, r *http.Request) { @@ -77,7 +142,6 @@ func SingleRecipe(w http.ResponseWriter, r *http.Request) { status = http.StatusOK msg = "Successful" } - fmt.Println(status, msg, recipe) resp := APIResponseItem{ Status: APIError{Code: status, Msg: msg}, @@ -119,7 +183,6 @@ func main() { dbinfo := fmt.Sprintf("user=%s password=%s dbname=%s sslmode=disable", DB_USER, DB_PASSWORD, DB_NAME) - fmt.Println(dbinfo) db, err = sql.Open("postgres", dbinfo) if err != nil || db.Ping() != nil { fmt.Println("Error connecting to database") diff --git a/backend/recipe.go b/backend/recipe.go index ceae402..e14c79b 100644 --- a/backend/recipe.go +++ b/backend/recipe.go @@ -23,6 +23,7 @@ type Recipe struct { Serving_size int Cook_time int Rating int + Num_cooked int Keywords []string Ingredients []Ingredient Steps []Step @@ -38,6 +39,7 @@ func MakeRecipe() *Recipe { Serving_size: 0, Cook_time: 0, Rating: 5, + Num_cooked: 0, Keywords: make([]string, 0), Ingredients: make([]Ingredient, 0), Steps: make([]Step, 0)} @@ -73,6 +75,7 @@ func RecipeFromId(id int, db *sql.DB) *Recipe { Serving_size: servings, Cook_time: cook_time, Rating: rating, + Num_cooked: num_cooked, Keywords: make([]string, 0), Ingredients: make([]Ingredient, 0), Steps: make([]Step, 0)} @@ -126,3 +129,74 @@ func RecipeFromId(id int, db *sql.DB) *Recipe { return &rec } + +func AddRecipeDB(r *Recipe, db *sql.DB) error { + var photo_urls, keywords strings.Builder + var id int + + for _, u := range r.Photos { + photo_urls.WriteString(u) + photo_urls.WriteRune('|') + } + + for _, k := range r.Keywords { + keywords.WriteString(k) + keywords.WriteRune('|') + } + + err := db.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) + RETURNING id`, + 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 + ).Scan(&id) + + if err != nil { + return err + } + + var ingr_id int + for i, ingr := range r.Ingredients { + err := db.QueryRow(`INSERT INTO ingredients + (name, amount, unit, recipe_id) + VALUES ($1, $2, $3, $4) + RETURNING id`, + ingr.Name, + ingr.Amount, + ingr.Unit, + id, + ).Scan(&ingr_id) + if err != nil { + r.Ingredients = append(r.Ingredients[:i], + r.Ingredients[i+1:]...) + } + } + + var step_id int + for i, step := range r.Steps { + err := db.QueryRow(`INSERT INTO steps + (step, description, timer, recipe_id) + VALUES ($1, $2, $3, $4) + RETURNING id`, + step.Num, + step.Desc, + step.Time, + id, + ).Scan(&step_id) + if err != nil { + r.Steps = append(r.Steps[:i], + r.Steps[i+1:]...) + } + } + + r.Id = id + return nil +} -- cgit v1.1