From 3c98c82f8a8441a5e8f27fb621e50de13c4fdbc8 Mon Sep 17 00:00:00 2001 From: servostar Date: Tue, 15 Oct 2024 12:22:05 +0200 Subject: [PATCH] feat: added database integration for /api/recipes --- server/.env | 4 +- server/docker-compose.yml | 16 +++++++ server/go.mod | 5 ++- server/go.sum | 2 + server/main.go | 91 ++++++++++++++++++++++++++++++++++++++- 5 files changed, 114 insertions(+), 4 deletions(-) create mode 100644 server/docker-compose.yml diff --git a/server/.env b/server/.env index bedd69f..090904b 100644 --- a/server/.env +++ b/server/.env @@ -1,2 +1,2 @@ -GREPFOOD_SYNCSERVER_PORT=8080 -GREPFOOD_JWT_SECRET=9v8bnz7560983n765098z7nb30945 +GREPFOOD_SYNCSERVER_PORT=:8080 +GREPFOOD_DATABASE_CONNECTION=postgresql://user:password@localhost:5432/grepfood?sslmode=disable diff --git a/server/docker-compose.yml b/server/docker-compose.yml new file mode 100644 index 0000000..052c65f --- /dev/null +++ b/server/docker-compose.yml @@ -0,0 +1,16 @@ +version: '3.3' +services: + database: + image: postgres:14-alpine + container_name: postgres + environment: + POSTGRES_USER: "user" + POSTGRES_PASSWORD: "password" + POSTGRES_DB: "grepfood" + ports: + - "5432:5432" + volumes: + - db:/var/lib/postgresql/data + +volumes: + db: diff --git a/server/go.mod b/server/go.mod index a057f25..57eb284 100644 --- a/server/go.mod +++ b/server/go.mod @@ -2,4 +2,7 @@ module git.montehaselino.de/grepfood-server-demo go 1.23.2 -require github.com/golang-jwt/jwt v3.2.2+incompatible // indirect +require ( + github.com/golang-jwt/jwt v3.2.2+incompatible // indirect + github.com/lib/pq v1.10.9 // indirect +) diff --git a/server/go.sum b/server/go.sum index efdb2a9..f568cf3 100644 --- a/server/go.sum +++ b/server/go.sum @@ -1,2 +1,4 @@ github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= +github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= +github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= diff --git a/server/main.go b/server/main.go index 4bbaf98..ed8ac37 100644 --- a/server/main.go +++ b/server/main.go @@ -7,6 +7,8 @@ import ( "os" "github.com/golang-jwt/jwt" "time" + "database/sql" + _ "github.com/lib/pq" ) func GenerateJwt(username string) (string, error) { @@ -45,10 +47,97 @@ func handleVersion(w http.ResponseWriter, r *http.Request) { WriteJson(w, version) } +func InitDatabase(db *sql.DB) { + _, err := db.Exec( +`CREATE TABLE IF NOT EXISTS ingredient ( + id SERIAL, + name VARCHAR(64) UNIQUE NOT NULL, + icon VARCHAR(64), + price INT, + PRIMARY KEY(id) +)`) + + if err != nil { + log.Fatal(err) + } + log.Print("created table for ingredients") + + _, err = db.Exec( +`CREATE TABLE IF NOT EXISTS recipe ( + id SERIAL, + name VARCHAR(64) UNIQUE NOT NULL, + icon VARCHAR(64), + PRIMARY KEY(id) +)`) + + if err != nil { + log.Fatal(err) + } + log.Print("created table for receipts") + + _, err = db.Exec( +`CREATE TABLE IF NOT EXISTS recipe_ingredient ( + recipe_id INT NOT NULL, + ingredient_d INT NOT NULL, + amount INT, + FOREIGN KEY (recipe_id) REFERENCES recipe(id), + FOREIGN KEY (ingredient_d) REFERENCES ingredient(id) +)`) + + if err != nil { + log.Fatal(err) + } + log.Print("created table for recipe ingredients") +} + +type Ingredient struct { + Name string `json:name` + Icon string `json:icon` + Price int `json:price` +} + +type Recipe struct { + Name string `json:name` + Icon string `json:icon` +} + +type RecipeIngredient struct { + Recipe int `json:recipe` + Ingredient int `json:ingredient` + Amount int `json:amount` +} + func main() { + dbconn := os.Getenv("GREPFOOD_DATABASE_CONNECTION") + + db, err := sql.Open("postgres", dbconn) + if err != nil { + log.Fatal(err) + } + log.Print("connected to database: ", dbconn) + + InitDatabase(db) http.HandleFunc("/version", handleVersion) - http.Handle("/", http.FileServer(http.Dir("./static"))) + http.HandleFunc("/api/recipes", func(w http.ResponseWriter, r *http.Request) { + rows, err := db.Query("SELECT name, icon FROM recipe") + if err != nil { + http.Error(w, "Internal server error", http.StatusInternalServerError) + return + } + + recipes := struct { Recipes []Recipe `json:recipes`} { + Recipes: []Recipe{}, + } + + for rows.Next() { + recipe := Recipe{} + rows.Scan(&recipe.Name, &recipe.Icon) + recipes.Recipes = append(recipes.Recipes, recipe) + } + + WriteJson(w, recipes) + }) log.Fatal(http.ListenAndServe(os.Getenv("GREPFOOD_SYNCSERVER_PORT"), nil)) }