From 19ccdadd3225f1662c2ba89db915b47402063857 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=20Tr=C3=B6ger?= Date: Thu, 5 Sep 2024 17:05:51 +0200 Subject: [PATCH] CHANGE: go debug working + seperated database and renam,ed module --- .gitignore | 26 ++++++++++++++++ .vscode/launch.json | 5 ++-- Backend/Dockerfile | 12 ++++++++ Backend/database.go | 16 ++++++++++ Backend/go.mod | 30 ++----------------- Backend/go.sum | 58 ----------------------------------- Backend/main.go | 63 ++++++++++++--------------------------- Backend/models/booking.go | 60 ++++++++++++++++++++++++------------- Docker/docker-compose.yml | 4 ++- 9 files changed, 121 insertions(+), 153 deletions(-) create mode 100644 .gitignore create mode 100644 Backend/Dockerfile create mode 100644 Backend/database.go diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1d7394b --- /dev/null +++ b/.gitignore @@ -0,0 +1,26 @@ +# If you prefer the allow list template instead of the deny list, see community template: +# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore +# +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, built with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Dependency directories (remove the comment below to include it) +# vendor/ + +# Go workspace file +go.work +go.work.sum + +#Debug files + +**__debug* diff --git a/.vscode/launch.json b/.vscode/launch.json index 9ae167c..40bd062 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -5,14 +5,13 @@ "version": "0.2.0", "configurations": [ + { "name": "Launch Package", "type": "go", "request": "launch", - "args": ["check-go-version=false"], "mode": "auto", - "cwd": "${cwd}/Backend", - "program": "Backend/main.go", + "program": "${workspaceFolder}/Backend", "dlvFlags": ["--check-go-version=false"] }, ] diff --git a/Backend/Dockerfile b/Backend/Dockerfile new file mode 100644 index 0000000..2ebbeda --- /dev/null +++ b/Backend/Dockerfile @@ -0,0 +1,12 @@ +FROM golang:alpine + +WORKDIR /app + +COPY go.mod go.sum /app/ + +RUN go mod download && go mod verify + +COPY . . +RUN go build -o /usr/local/bin/app + +CMD ["app"] diff --git a/Backend/database.go b/Backend/database.go new file mode 100644 index 0000000..13c1e48 --- /dev/null +++ b/Backend/database.go @@ -0,0 +1,16 @@ +package main + +import ( + "database/sql" + "fmt" +) + +func OpenDatabase() (*sql.DB, error){ + dbHost := getEnv("POSTGRES_HOST", "localhost") + dbName := getEnv("POSTGRES_DB", "arbeitszeitmessung") + dbUser := getEnv("POSTGRES_USER", "arbeit_zeit") + dbPassword := getEnv("POSTGRES_PASS", "password") + + connStr:= fmt.Sprintf("postgres://%s:%s@%s:5432/%s?sslmode=disable", dbUser, dbPassword, dbHost, dbName) + return sql.Open("postgres", connStr) +} diff --git a/Backend/go.mod b/Backend/go.mod index 6abcf25..5308e06 100644 --- a/Backend/go.mod +++ b/Backend/go.mod @@ -1,29 +1,5 @@ -module Backend +module arbeitszeitmessung -go 1.23.0 +go 1.21.7 -require ( - github.com/cilium/ebpf v0.16.0 // indirect - github.com/cosiner/argv v0.1.0 // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect - github.com/derekparker/trie v0.0.0-20230829180723-39f4de51ef7d // indirect - github.com/go-delve/delve v1.23.0 // indirect - github.com/go-delve/liner v1.2.3-0.20231231155935-4726ab1d7f62 // indirect - github.com/google/go-dap v0.12.0 // indirect - github.com/hashicorp/golang-lru v1.0.2 // indirect - github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/lib/pq v1.10.9 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mattn/go-runewidth v0.0.16 // indirect - github.com/rivo/uniseg v0.4.7 // indirect - github.com/russross/blackfriday/v2 v2.1.0 // indirect - github.com/sirupsen/logrus v1.9.3 // indirect - github.com/spf13/cobra v1.8.1 // indirect - github.com/spf13/pflag v1.0.5 // indirect - go.starlark.net v0.0.0-20240725214946-42030a7cedce // indirect - golang.org/x/arch v0.9.0 // indirect - golang.org/x/exp v0.0.0-20240823005443-9b4947da3948 // indirect - golang.org/x/sys v0.24.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect -) +require github.com/lib/pq v1.10.9 diff --git a/Backend/go.sum b/Backend/go.sum index 3df090f..aeddeae 100644 --- a/Backend/go.sum +++ b/Backend/go.sum @@ -1,60 +1,2 @@ -github.com/cilium/ebpf v0.16.0 h1:+BiEnHL6Z7lXnlGUsXQPPAE7+kenAd4ES8MQ5min0Ok= -github.com/cilium/ebpf v0.16.0/go.mod h1:L7u2Blt2jMM/vLAVgjxluxtBKlz3/GWjB0dMOEngfwE= -github.com/cosiner/argv v0.1.0 h1:BVDiEL32lwHukgJKP87btEPenzrrHUjajs/8yzaqcXg= -github.com/cosiner/argv v0.1.0/go.mod h1:EusR6TucWKX+zFgtdUsKT2Cvg45K5rtpCcWz4hK06d8= -github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4= -github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/derekparker/trie v0.0.0-20230829180723-39f4de51ef7d h1:hUWoLdw5kvo2xCsqlsIBMvWUc1QCSsCYD2J2+Fg6YoU= -github.com/derekparker/trie v0.0.0-20230829180723-39f4de51ef7d/go.mod h1:C7Es+DLenIpPc9J6IYw4jrK0h7S9bKj4DNl8+KxGEXU= -github.com/go-delve/delve v1.23.0 h1:jYgZISZ14KAO3ys8kD07kjrowrygE9F9SIwnpz9xXys= -github.com/go-delve/delve v1.23.0/go.mod h1:S3SLuEE2mn7wipKilTvk1p9HdTMnXXElcEpiZ+VcuqU= -github.com/go-delve/liner v1.2.3-0.20231231155935-4726ab1d7f62 h1:IGtvsNyIuRjl04XAOFGACozgUD7A82UffYxZt4DWbvA= -github.com/go-delve/liner v1.2.3-0.20231231155935-4726ab1d7f62/go.mod h1:biJCRbqp51wS+I92HMqn5H8/A0PAhxn2vyOT+JqhiGI= -github.com/google/go-dap v0.12.0 h1:rVcjv3SyMIrpaOoTAdFDyHs99CwVOItIJGKLQFQhNeM= -github.com/google/go-dap v0.12.0/go.mod h1:tNjCASCm5cqePi/RVXXWEVqtnNLV1KTWtYOqu6rZNzc= -github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c= -github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= -github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= -github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= -github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= -github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= -github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= -github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= -github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= -github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= -github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -go.starlark.net v0.0.0-20240725214946-42030a7cedce h1:YyGqCjZtGZJ+mRPaenEiB87afEO2MFRzLiJNZ0Z0bPw= -go.starlark.net v0.0.0-20240725214946-42030a7cedce/go.mod h1:YKMCv9b1WrfWmeqdV5MAuEHWsu5iC+fe6kYl2sQjdI8= -golang.org/x/arch v0.9.0 h1:ub9TgUInamJ8mrZIGlBG6/4TqWeMszd4N8lNorbrr6k= -golang.org/x/arch v0.9.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= -golang.org/x/exp v0.0.0-20240823005443-9b4947da3948 h1:kx6Ds3MlpiUHKj7syVnbp57++8WpuKPcR5yjLBjvLEA= -golang.org/x/exp v0.0.0-20240823005443-9b4947da3948/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= -golang.org/x/sys v0.0.0-20211117180635-dee7805ff2e1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= -golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/Backend/main.go b/Backend/main.go index 25d9d4c..4b24ead 100644 --- a/Backend/main.go +++ b/Backend/main.go @@ -1,15 +1,14 @@ package main import ( - "Backend/models" + "arbeitszeitmessung/models" "database/sql" "encoding/json" + "errors" "fmt" "log" "net/http" - "net/url" "os" - "strconv" _ "github.com/lib/pq" ) @@ -18,11 +17,10 @@ var DB *sql.DB func main() { var err error - dbConnStr := getDBConn() - DB, err = sql.Open("postgres", dbConnStr) - if err!= nil { - log.Fatal(err) - } + DB, err = OpenDatabase() + if err != nil { + log.Fatal(err) + } defer DB.Close() http.HandleFunc("/time", timeHandler) @@ -41,50 +39,27 @@ func timeHandler(w http.ResponseWriter, r *http.Request) { } func createBooking(w http.ResponseWriter, r *http.Request) { - - booking := getBooking(r.URL.Query()) - if models.VerifyBooking(booking) { - err := models.InsertBooking(booking, DB) - if err == fmt.Errorf("the same booking already exists") { + booking := (*models.Booking).FromUrlParams(nil, r.URL.Query()) + if booking.Verify() { + err := booking.Insert(DB) + if errors.Is(models.SameBookingError{}, err) { http.Error(w, "Booking already exists", http.StatusConflict) - return + return } if err != nil { - log.Println("Error inserting booking: ", err) - http.Error(w, "Internal Server Error", http.StatusInternalServerError) - return - } + log.Println("Error inserting booking: ", err) + http.Error(w, "Internal Server Error", http.StatusInternalServerError) + return + } w.WriteHeader(http.StatusAccepted) json.NewEncoder(w).Encode(booking) } w.WriteHeader(http.StatusBadRequest) } -func getBooking(query_params url.Values) models.Booking { - bookingType, err := strconv.Atoi(query_params.Get("bookingType")) - if err!= nil { - log.Println("Error parsing bookingType: ", err) - return models.Booking{} - } - return models.Booking{ - CradID: query_params.Get("cardID"), - ReaderID: query_params.Get("readerID"), - BookingType: bookingType, - } -} - -func getDBConn() string { - dbHost := getEnv("POSTGRES_HOST", "localhost") - dbName := getEnv("POSTGRES_DB", "arbeitszeitmessung") - dbUser := getEnv("POSTGRES_USER", "arbeit_zeit") - dbPassword := getEnv("POSTGRES_PASS", "password") - - return fmt.Sprintf("postgres://%s:%s@%s:5432/%s?sslmode=disable", dbUser, dbPassword, dbHost, dbName) -} - func getEnv(key, fallback string) string { - if value, ok := os.LookupEnv(key); ok { - return value - } - return fallback + if value, ok := os.LookupEnv(key); ok { + return value + } + return fallback } diff --git a/Backend/models/booking.go b/Backend/models/booking.go index 3d52f34..1c0ed5e 100644 --- a/Backend/models/booking.go +++ b/Backend/models/booking.go @@ -2,38 +2,58 @@ package models import ( "database/sql" - "fmt" "log" + "net/url" + "strconv" ) -type Booking struct { - CradID string `json:"cradID"` - ReaderID string `json:"readerID"` - BookingType int `json:"bookingTyp"` -} - type SameBookingError struct{} func (e SameBookingError) Error() string { return "the same booking already exists!" } -func VerifyBooking(b Booking) bool { - if b.CradID == "" || b.ReaderID == "" || b.BookingType == 0 { +type Booking struct { + CardID string `json:"cradID"` + ReaderID string `json:"readerID"` + BookingType int `json:"bookingTyp"` +} + +func (b Booking) New(card_id string, reader_id string, booking_type int) Booking { + return Booking{ + CardID: card_id, + ReaderID: reader_id, + BookingType: booking_type, + } +} + +func (b *Booking) FromUrlParams(params url.Values) Booking { + bookingType, err := strconv.Atoi(params.Get("bookingType")) + if err != nil { + log.Println("Error parsing bookingType: ", err) + return b.New("", "", 0) + } + cardID := params.Get("cardID") + readerID := params.Get("readerID") + return Booking{BookingType: bookingType, CardID: cardID, ReaderID: readerID} +} + +func (b Booking) Verify() bool { + if b.CardID == "" || b.ReaderID == "" || b.BookingType == 0 { return false } return true } -func InsertBooking(b Booking, db *sql.DB) error { +func (b Booking) Insert(db *sql.DB) error { if !checkLastBooking(b, db) { - return fmt.Errorf("the same booking already exists") - } + return SameBookingError{} + } stmt, err := db.Prepare((`INSERT INTO zeiten (card_id, reader_id, booking_type) VALUES ($1, $2, $3)`)) if err != nil { return err } - _, err = stmt.Query(b.CradID, b.ReaderID, b.BookingType) + _, err = stmt.Query(b.CardID, b.ReaderID, b.BookingType) if err != nil { return err } @@ -45,16 +65,16 @@ func checkLastBooking(b Booking, db *sql.DB) bool { stmt, err := db.Prepare((`SELECT booking_type FROM "zeiten" WHERE "card_id" = $1 ORDER BY "logged_time" DESC LIMIT 1;`)) if err != nil { log.Fatalf("Error preparing query: %v", err) - return false - } - err = stmt.QueryRow(b.CradID).Scan(&booking_type) + return false + } + err = stmt.QueryRow(b.CardID).Scan(&booking_type) if err == sql.ErrNoRows { return true } - if err!= nil { - log.Println("Error checking last booking: ", err) - return false - } + if err != nil { + log.Println("Error checking last booking: ", err) + return false + } if booking_type == b.BookingType { return false } diff --git a/Docker/docker-compose.yml b/Docker/docker-compose.yml index 0308f19..e1322a4 100644 --- a/Docker/docker-compose.yml +++ b/Docker/docker-compose.yml @@ -1,4 +1,4 @@ -name: Arbeitszeitmessung-Main +name: arbeitszeitmessung-main services: db: image: postgres:16 @@ -30,3 +30,5 @@ services: POSTGRES_DB: ${POSTGRES_DB} POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASS: ${POSTGRES_PASSWORD} + ports: + - 8001:8080