From bab658b43e736c8f4cc63dd88bc4486def3c241c Mon Sep 17 00:00:00 2001 From: Sercan Yesildal <sercan.yesildal@gmail.com> Date: Mon, 10 Jul 2023 11:01:34 +0200 Subject: [PATCH] stuff added --- service/planner/db/client.go | 145 +++++++++++++++++++++++++------ service/planner/db/config.json | 1 - service/planner/db/init.sql | 92 +++++++++++--------- service/planner/go.mod | 1 + service/planner/go.sum | 3 + service/planner/handler/group.go | 26 +++++- service/planner/handler/user.go | 18 +++- service/planner/main.go | 16 +++- service/planner/model/group.go | 1 + service/planner/model/user.go | 7 ++ service/planner/service/group.go | 16 ++-- service/planner/service/user.go | 33 ++++--- 12 files changed, 259 insertions(+), 100 deletions(-) diff --git a/service/planner/db/client.go b/service/planner/db/client.go index 5e9e5c4..613e86e 100644 --- a/service/planner/db/client.go +++ b/service/planner/db/client.go @@ -2,8 +2,12 @@ package db import ( "database/sql" + "errors" + "os" + "time" "github.com/go-sql-driver/mysql" + log "github.com/sirupsen/logrus" "github.com/spf13/viper" "gitlab.reutlingen-university.de/yesildas/mealplanner2go/service/planner/model" ) @@ -26,28 +30,56 @@ func Init() error { cfg = &mysql.Config{ User: vp.GetString("user"), Passwd: vp.GetString("passwd"), - Addr: vp.GetString("addr"), + Net: "tcp", + Addr: os.Getenv("DB_CONNECT"), DBName: vp.GetString("dbName"), + Loc: time.Now().Local().Location(), + MaxAllowedPacket: 64 * 1024 * 1024, AllowNativePasswords: true, + CheckConnLiveness: true, + ParseTime: true, } + log.Info("Using DSN for DB: ", cfg.FormatDSN()) return nil } -func CreateUser(mail string, firstName string, lastName string) error { +func CreateUser(mail string, firstName string, lastName string) (*model.User, error) { udb, err := sql.Open(driverName, cfg.FormatDSN()) if err != nil { - return err + return nil, err } defer udb.Close() + queryCheck, err := udb.Query("SELECT * FROM userAccount WHERE mail = ?;", mail) + if err != nil { + return nil, err + } + defer queryCheck.Close() + if queryCheck.Next() { + return nil, errors.New("account exists") + } + query, err := udb.Query("INSERT INTO userAccount (mail, firstName, lastName) VALUES (?, ?, ?);", mail, firstName, lastName) if err != nil { - return err + return nil, err } query.Close() - return nil + queryGetId, err := udb.Query("SELECT id FROM userAccount WHERE mail = ?;", mail) + if err != nil { + return nil, err + } + defer queryGetId.Close() + var id int + for queryGetId.Next() { + err = queryGetId.Scan(&id) + if err != nil { + return nil, err + } + } + + return GetUser(id) } func GetUser(id int) (*model.User, error) { @@ -101,70 +133,122 @@ func GetUser(id int) (*model.User, error) { return user, nil } -func UpdateUser(id int, mail string, firstName string, lastName string) error { +func GetUsers() ([]*model.UserItem, error) { udb, err := sql.Open(driverName, cfg.FormatDSN()) if err != nil { - return err + return nil, err } defer udb.Close() - query, err := udb.Query("UPDATE userAccount SET mail = ?, firstName = ?, lastName = ? WHERE userId = ?;", mail, firstName, lastName, id) + query, err := udb.Query("SELECT * FROM userAccount;") if err != nil { - return err + return nil, err + } + defer query.Close() + var users []*model.UserItem + for query.Next() { + user := &model.UserItem{} + err = query.Scan(&user.ID, &user.Mail, &user.FirstName, &user.LastName) + if err != nil { + continue + } + users = append(users, user) + } + + return users, nil +} + +func UpdateUser(id int, mail string, firstName string, lastName string) (*model.User, error) { + udb, err := sql.Open(driverName, cfg.FormatDSN()) + if err != nil { + return nil, err + } + defer udb.Close() + + query, err := udb.Query("UPDATE userAccount SET mail = ?, firstName = ?, lastName = ? WHERE id = ?;", mail, firstName, lastName, id) + if err != nil { + return nil, err } query.Close() - return nil + return GetUser(id) } -func DeleteUser(id int) error { +func DeleteUser(id int) (*model.User, error) { udb, err := sql.Open(driverName, cfg.FormatDSN()) if err != nil { - return err + return nil, err } defer udb.Close() + user, err := GetUser(id) + if err != nil { + return nil, err + } + queryMeals, err := udb.Query("DELETE FROM userMeal WHERE userId = ?;", id) if err != nil { - return err + return nil, err } queryMeals.Close() queryShoppingDates, err := udb.Query("DELETE FROM shoppingDate WHERE userId = ?;", id) if err != nil { - return err + return nil, err } queryShoppingDates.Close() queryRelation, err := udb.Query("DELETE FROM userGroupRelation WHERE userId = ?;", id) if err != nil { - return err + return nil, err } queryRelation.Close() query, err := udb.Query("DELETE FROM userAccount WHERE id = ?;", id) if err != nil { - return err + return nil, err } query.Close() - return nil + return user, nil } -func CreateGroup() error { +func CreateGroup(name string) (*model.Group, error) { udb, err := sql.Open(driverName, cfg.FormatDSN()) if err != nil { - return err + return nil, err } defer udb.Close() - query, err := udb.Query("INSERT INTO userGroup;") + queryCheck, err := udb.Query("SELECT * FROM userGroup WHERE name = ?;", name) if err != nil { - return err + return nil, err + } + defer queryCheck.Close() + if queryCheck.Next() { + return nil, errors.New("group name exists") + } + + query, err := udb.Query("INSERT INTO userGroup (name) VALUES (?);", name) + if err != nil { + return nil, err } query.Close() - return nil + queryGetId, err := udb.Query("SELECT id FROM userGroup WHERE name = ?;", name) + if err != nil { + return nil, err + } + defer queryGetId.Close() + var id int + for queryGetId.Next() { + err = queryGetId.Scan(&id) + if err != nil { + return nil, err + } + } + + return GetGroup(id) } func GetGroup(id int) (*model.Group, error) { @@ -218,32 +302,37 @@ func GetGroup(id int) (*model.Group, error) { return group, nil } -func DeleteGroup(id int) error { +func DeleteGroup(id int) (*model.Group, error) { udb, err := sql.Open(driverName, cfg.FormatDSN()) if err != nil { - return err + return nil, err } defer udb.Close() + group, err := GetGroup(id) + if err != nil { + return nil, err + } + queryMeals, err := udb.Query("DELETE FROM groupMeal WHERE groupId = ?;", id) if err != nil { - return err + return nil, err } queryMeals.Close() queryRelation, err := udb.Query("DELETE FROM userGroupRelation WHERE groupId = ?;", id) if err != nil { - return err + return nil, err } queryRelation.Close() query, err := udb.Query("DELETE FROM userGroup WHERE id = ?;", id) if err != nil { - return err + return nil, err } query.Close() - return nil + return group, nil } func CreateUserMeal(userId int, mealId int, date string) error { diff --git a/service/planner/db/config.json b/service/planner/db/config.json index 92e4b80..8cc6ada 100644 --- a/service/planner/db/config.json +++ b/service/planner/db/config.json @@ -1,5 +1,4 @@ { - "addr": "mariadb:3306", "dbName": "planner", "user": "root", "passwd": "secret" diff --git a/service/planner/db/init.sql b/service/planner/db/init.sql index 7259ad3..710a1ce 100644 --- a/service/planner/db/init.sql +++ b/service/planner/db/init.sql @@ -1,50 +1,58 @@ CREATE DATABASE IF NOT EXISTS planner; + USE planner; -CREATE TABLE IF NOT EXISTS `userAccount` ( - `id` int NOT NULL AUTO_INCREMENT, - `mail` varchar(255) NOT NULL, - `firstName` varchar(255) NOT NULL, - `lastName` varchar(255) NOT NULL, - PRIMARY KEY (`id`) -); +CREATE TABLE + IF NOT EXISTS `userAccount` ( + `id` int NOT NULL AUTO_INCREMENT, + `mail` varchar(255) NOT NULL, + `firstName` varchar(255) NOT NULL, + `lastName` varchar(255) NOT NULL, + PRIMARY KEY (`id`) + ); -CREATE TABLE IF NOT EXISTS `userGroup` ( - `id` int NOT NULL AUTO_INCREMENT, - PRIMARY KEY (`id`) -); +CREATE TABLE + IF NOT EXISTS `userGroup` ( + `id` int NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL, + PRIMARY KEY (`id`) + ); -CREATE TABLE IF NOT EXISTS `userMeal` ( - `id` int NOT NULL AUTO_INCREMENT, - `userId` int NOT NULL, - `mealId` int NOT NULL, - `date` DATE NOT NULL, - PRIMARY KEY (`id`), - FOREIGN KEY (`userId`) REFERENCES userAccount(`id`) -); +CREATE TABLE + IF NOT EXISTS `userMeal` ( + `id` int NOT NULL AUTO_INCREMENT, + `userId` int NOT NULL, + `mealId` int NOT NULL, + `date` DATE NOT NULL, + PRIMARY KEY (`id`), + FOREIGN KEY (`userId`) REFERENCES userAccount(`id`) + ); -CREATE TABLE IF NOT EXISTS `groupMeal` ( - `id` int NOT NULL AUTO_INCREMENT, - `groupId` int NOT NULL, - `mealId` int NOT NULL, - `date` DATE NOT NULL, - PRIMARY KEY (`id`), - FOREIGN KEY (`groupId`) REFERENCES userGroup(`id`) -); +CREATE TABLE + IF NOT EXISTS `groupMeal` ( + `id` int NOT NULL AUTO_INCREMENT, + `groupId` int NOT NULL, + `mealId` int NOT NULL, + `date` DATE NOT NULL, + PRIMARY KEY (`id`), + FOREIGN KEY (`groupId`) REFERENCES userGroup(`id`) + ); -CREATE TABLE IF NOT EXISTS `shoppingDate` ( - `id` int NOT NULL AUTO_INCREMENT, - `userId` int NOT NULL, - `date` DATE NOT NULL, - PRIMARY KEY (`id`), - FOREIGN KEY (`userId`) REFERENCES userAccount(`id`) -); +CREATE TABLE + IF NOT EXISTS `shoppingDate` ( + `id` int NOT NULL AUTO_INCREMENT, + `userId` int NOT NULL, + `date` DATE NOT NULL, + PRIMARY KEY (`id`), + FOREIGN KEY (`userId`) REFERENCES userAccount(`id`) + ); -CREATE TABLE IF NOT EXISTS `userGroupRelation` ( - `id` int NOT NULL AUTO_INCREMENT, - `groupId` int NOT NULL, - `userId` int NOT NULL, - PRIMARY KEY (`id`), - FOREIGN KEY (`groupId`) REFERENCES userGroup(`id`), - FOREIGN KEY (`userId`) REFERENCES userAccount(`id`) -); \ No newline at end of file +CREATE TABLE + IF NOT EXISTS `userGroupRelation` ( + `id` int NOT NULL AUTO_INCREMENT, + `groupId` int NOT NULL, + `userId` int NOT NULL, + PRIMARY KEY (`id`), + FOREIGN KEY (`groupId`) REFERENCES userGroup(`id`), + FOREIGN KEY (`userId`) REFERENCES userAccount(`id`) + ); \ No newline at end of file diff --git a/service/planner/go.mod b/service/planner/go.mod index 08066b9..20eaab5 100644 --- a/service/planner/go.mod +++ b/service/planner/go.mod @@ -5,6 +5,7 @@ go 1.20 require ( github.com/go-sql-driver/mysql v1.7.1 github.com/gorilla/mux v1.8.0 + github.com/sirupsen/logrus v1.9.3 github.com/spf13/viper v1.16.0 ) diff --git a/service/planner/go.sum b/service/planner/go.sum index 82a14fb..ce66f6a 100644 --- a/service/planner/go.sum +++ b/service/planner/go.sum @@ -148,6 +148,8 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM= github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA= @@ -307,6 +309,7 @@ golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/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-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/service/planner/handler/group.go b/service/planner/handler/group.go index 4cd476b..2e2119b 100644 --- a/service/planner/handler/group.go +++ b/service/planner/handler/group.go @@ -1,17 +1,35 @@ package handler import ( + "encoding/json" "net/http" + "gitlab.reutlingen-university.de/yesildas/mealplanner2go/service/planner/model" "gitlab.reutlingen-university.de/yesildas/mealplanner2go/service/planner/service" ) +func getGroup(r *http.Request) (*model.Group, error) { + var group model.Group + err := json.NewDecoder(r.Body).Decode(&group) + if err != nil { + return nil, err + } + + return &group, nil +} + func CreateGroup(w http.ResponseWriter, r *http.Request) { - if err := service.CreateGroup(); err != nil { + group, err := getGroup(r) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + group, err = service.CreateGroup(group) + if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } - sendJson(w, nil) + sendJson(w, group) } func GetGroup(w http.ResponseWriter, r *http.Request) { @@ -34,12 +52,12 @@ func DeleteGroup(w http.ResponseWriter, r *http.Request) { http.Error(w, err.Error(), http.StatusBadRequest) return } - err = service.DeleteGroup(id) + group, err := service.DeleteGroup(id) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } - sendJson(w, nil) + sendJson(w, group) } func CreateUserGroupRelation(w http.ResponseWriter, r *http.Request) { diff --git a/service/planner/handler/user.go b/service/planner/handler/user.go index 3517dbb..ba6daee 100644 --- a/service/planner/handler/user.go +++ b/service/planner/handler/user.go @@ -24,7 +24,8 @@ func CreateUser(w http.ResponseWriter, r *http.Request) { http.Error(w, err.Error(), http.StatusBadRequest) return } - if err := service.CreateUser(user); err != nil { + user, err = service.CreateUser(user) + if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } @@ -45,6 +46,15 @@ func GetUser(w http.ResponseWriter, r *http.Request) { sendJson(w, user) } +func GetUsers(w http.ResponseWriter, r *http.Request) { + users, err := service.GetUsers() + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + sendJson(w, users) +} + func UpdateUser(w http.ResponseWriter, r *http.Request) { id, err := getId(r) if err != nil { @@ -56,7 +66,7 @@ func UpdateUser(w http.ResponseWriter, r *http.Request) { http.Error(w, err.Error(), http.StatusBadRequest) return } - err = service.UpdateUser(id, user) + user, err = service.UpdateUser(id, user) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return @@ -70,10 +80,10 @@ func DeleteUser(w http.ResponseWriter, r *http.Request) { http.Error(w, err.Error(), http.StatusBadRequest) return } - err = service.DeleteUser(id) + user, err := service.DeleteUser(id) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } - sendJson(w, nil) + sendJson(w, user) } diff --git a/service/planner/main.go b/service/planner/main.go index 7e3687e..3facd58 100644 --- a/service/planner/main.go +++ b/service/planner/main.go @@ -2,19 +2,32 @@ package main import ( "fmt" - "log" "net/http" + "os" "github.com/gorilla/mux" + log "github.com/sirupsen/logrus" "gitlab.reutlingen-university.de/yesildas/mealplanner2go/service/planner/db" "gitlab.reutlingen-university.de/yesildas/mealplanner2go/service/planner/handler" ) func init() { + // init db err := db.Init() if err != nil { log.Fatal(err) } + + // init logger + log.SetFormatter(&log.TextFormatter{}) + log.SetReportCaller(true) + level, err := log.ParseLevel(os.Getenv("LOG_LEVEL")) + if err != nil { + log.Info("Log level not specified, set default to: INFO") + log.SetLevel(log.InfoLevel) + return + } + log.SetLevel(level) } func main() { @@ -27,6 +40,7 @@ func main() { router.HandleFunc("/user/{id}", handler.GetUser).Methods(http.MethodGet) router.HandleFunc("/user/{id}", handler.UpdateUser).Methods(http.MethodPut) router.HandleFunc("/user/{id}", handler.DeleteUser).Methods(http.MethodDelete) + router.HandleFunc("/user", handler.GetUsers).Methods(http.MethodGet) router.HandleFunc("/user", handler.CreateUser).Methods(http.MethodPost) router.HandleFunc("/group/{groupId}/{userId}", handler.CreateUserGroupRelation).Methods(http.MethodPost) router.HandleFunc("/group/{groupId}/{userId}", handler.DeleteUserGroupRelation).Methods(http.MethodDelete) diff --git a/service/planner/model/group.go b/service/planner/model/group.go index 4a4d419..8069c0d 100644 --- a/service/planner/model/group.go +++ b/service/planner/model/group.go @@ -2,6 +2,7 @@ package model type Group struct { ID int `json:"id"` + Name string `json:"name"` UserIDs []int `json:"userIds"` Meals []GroupMeal `json:"meals"` } diff --git a/service/planner/model/user.go b/service/planner/model/user.go index 134adff..4acc2cb 100644 --- a/service/planner/model/user.go +++ b/service/planner/model/user.go @@ -8,3 +8,10 @@ type User struct { Meals []UserMeal `json:"meals"` ShoppingDates []ShoppingDate `json:"shoppingDates"` } + +type UserItem struct { + ID int `json:"id"` + Mail string `json:"mail"` + FirstName string `json:"firstName"` + LastName string `json:"lastName"` +} diff --git a/service/planner/service/group.go b/service/planner/service/group.go index e844a68..018a819 100644 --- a/service/planner/service/group.go +++ b/service/planner/service/group.go @@ -5,13 +5,13 @@ import ( "gitlab.reutlingen-university.de/yesildas/mealplanner2go/service/planner/model" ) -func CreateGroup() error { - err := db.CreateGroup() +func CreateGroup(group *model.Group) (*model.Group, error) { + group, err := db.CreateGroup(group.Name) if err != nil { - return err + return nil, err } - return nil + return group, nil } func GetGroup(id int) (*model.Group, error) { @@ -23,13 +23,13 @@ func GetGroup(id int) (*model.Group, error) { return group, nil } -func DeleteGroup(id int) error { - err := db.DeleteGroup(id) +func DeleteGroup(id int) (*model.Group, error) { + group, err := db.DeleteGroup(id) if err != nil { - return err + return nil, err } - return nil + return group, nil } func CreateUserGroupRelation(userId int, groupId int) error { diff --git a/service/planner/service/user.go b/service/planner/service/user.go index 1426ca0..53e9d16 100644 --- a/service/planner/service/user.go +++ b/service/planner/service/user.go @@ -5,13 +5,13 @@ import ( "gitlab.reutlingen-university.de/yesildas/mealplanner2go/service/planner/model" ) -func CreateUser(user *model.User) error { - err := db.CreateUser(user.Mail, user.FirstName, user.LastName) +func CreateUser(user *model.User) (*model.User, error) { + user, err := db.CreateUser(user.Mail, user.FirstName, user.LastName) if err != nil { - return err + return nil, err } - return nil + return user, nil } func GetUser(id int) (*model.User, error) { @@ -23,20 +23,29 @@ func GetUser(id int) (*model.User, error) { return user, nil } -func UpdateUser(id int, user *model.User) error { - err := db.UpdateUser(id, user.Mail, user.FirstName, user.LastName) +func GetUsers() ([]*model.UserItem, error) { + users, err := db.GetUsers() + if err != nil { + return nil, err + } + + return users, nil +} + +func UpdateUser(id int, user *model.User) (*model.User, error) { + user, err := db.UpdateUser(id, user.Mail, user.FirstName, user.LastName) if err != nil { - return err + return nil, err } - return nil + return user, nil } -func DeleteUser(id int) error { - err := db.DeleteUser(id) +func DeleteUser(id int) (*model.User, error) { + user, err := db.DeleteUser(id) if err != nil { - return err + return nil, err } - return nil + return user, nil } -- GitLab