From d973ae965eefec12708503daa424c052a545b504 Mon Sep 17 00:00:00 2001 From: Vic Date: Fri, 21 Oct 2022 20:21:28 +0200 Subject: [PATCH] added user controller + product controller fixes --- controllers/product.go | 33 ++++-- controllers/user.go | 149 +++++++++++++++++++++++++ main.go | 11 +- migrations/000001_init_schema.down.sql | 3 +- migrations/000001_init_schema.up.sql | 10 +- 5 files changed, 194 insertions(+), 12 deletions(-) diff --git a/controllers/product.go b/controllers/product.go index fb9ae9f..a527a23 100644 --- a/controllers/product.go +++ b/controllers/product.go @@ -59,7 +59,7 @@ func CreateProduct(c *gin.Context) { if err := c.ShouldBindJSON(&reqBody); err != nil { c.JSON(http.StatusUnprocessableEntity, gin.H{ "error": true, - "message": "Invalid request body", + "message": "Invalid JSON binding", }) return } @@ -74,7 +74,7 @@ func CreateProduct(c *gin.Context) { if err != nil { c.JSON(http.StatusInternalServerError, gin.H{ "error": true, - "message": "Could not create product", + "message": err.Error(), }) return } @@ -84,7 +84,7 @@ func CreateProduct(c *gin.Context) { c.JSON(http.StatusCreated, gin.H{ "error": false, "id": id, - "message": "New product created", + "message": "New product created successfully", }) } @@ -101,7 +101,10 @@ func UpdateProduct(c *gin.Context) { return } - res, err := db_client.ConnectDB.Exec("UPDATE products SET name=$1, price=$2 WHERE id=$3 RETURNING *", reqBody.Name, reqBody.Price, id) + res, err := db_client.ConnectDB.Exec("UPDATE products SET name=$1, price=$2 WHERE id=$3 RETURNING *", + reqBody.Name, + reqBody.Price, id) + if err == sql.ErrNoRows { c.JSON(http.StatusNotFound, gin.H{ "error": true, @@ -110,11 +113,18 @@ func UpdateProduct(c *gin.Context) { return } - AffectedId, _ := res.RowsAffected() + if err != nil { + c.JSON(http.StatusUnprocessableEntity, gin.H{ + "error": true, + "message": err.Error(), + }) + } + + affectedId, _ := res.RowsAffected() c.JSON(http.StatusCreated, gin.H{ "error": false, - "id": AffectedId, + "id": affectedId, "message": "Product have been updated successfully", }) @@ -134,11 +144,18 @@ func DeleteProduct(c *gin.Context) { return } - AffectedId, _ := res.RowsAffected() + if err != nil { + c.JSON(http.StatusUnprocessableEntity, gin.H{ + "error": true, + "message": err.Error(), + }) + } + + affectedId, _ := res.RowsAffected() c.JSON(http.StatusCreated, gin.H{ "error": false, - "id": AffectedId, + "id": affectedId, "message": "Product have been deleted successfully", }) diff --git a/controllers/user.go b/controllers/user.go index 6d0531b..f69e893 100644 --- a/controllers/user.go +++ b/controllers/user.go @@ -1 +1,150 @@ package controllers + +import ( + "database/sql" + "net/http" + "strconv" + + "git.sp4ke.xyz/AnisB/shelf_api_go/db_client" + "github.com/gin-gonic/gin" +) + +type User struct { + Id int64 `db:"id"` + FirstName string `db:"first_name"` + LastName string `db:"last_name"` + UserName string `db:"user_name"` + Password string `db:"password"` +} + +func GetUsers(c *gin.Context) { + var users []User + + err := db_client.ConnectDB.Select(&users, "SELECT * FROM users") + if err != nil { + c.JSON(http.StatusUnprocessableEntity, gin.H{ + "error": true, + "message": err.Error(), + }) + return + } + + c.JSON(http.StatusOK, users) + +} + +func GetUser(c *gin.Context) { + idStr := c.Param("id") + id, _ := strconv.Atoi(idStr) + var user User + + err := db_client.ConnectDB.Get(&user, "SELECT * FROM users WHERE id=($1)", id) + if err == sql.ErrNoRows { + c.JSON(http.StatusNotFound, gin.H{ + "error": true, + "message": "User not found", + }) + return + } + + c.JSON(http.StatusOK, user) +} + +func CreateUser(c *gin.Context) { + var reqBody User + if err := c.ShouldBindJSON(&reqBody); err != nil { + c.JSON(http.StatusUnprocessableEntity, gin.H{ + "error": true, + "message": "Invalid JSON binding", + }) + return + } + res, err := db_client.ConnectDB.Exec("INSERT INTO users (first_name, last_name, user_name, password) VALUES ($1, $2, $3, $4)", + reqBody.FirstName, + reqBody.LastName, + reqBody.UserName, + reqBody.Password) + + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{ + "error": true, + "message": err.Error(), + }) + return + } + + id, _ := res.LastInsertId() + c.JSON(http.StatusCreated, gin.H{ + "error": false, + "id": id, + "message": "New user created successfully", + }) +} + +func UpdateUser(c *gin.Context) { + idStr := c.Param("id") + id, _ := strconv.Atoi(idStr) + var reqBody User + + if err := c.ShouldBindJSON(&reqBody); err != nil { + c.JSON(http.StatusUnprocessableEntity, gin.H{ + "error": true, + "message": "Invalid request body", + }) + return + } + + res, err := db_client.ConnectDB.Exec("UPDATE users SET first_name=$1, last_name=$2, user_name=$3, password=$4 WHERE id=$5 RETURNING *", + reqBody.FirstName, + reqBody.LastName, + reqBody.UserName, + reqBody.Password, + id) + + if err == sql.ErrNoRows { + c.JSON(http.StatusNotFound, gin.H{ + "error": true, + "message": "User not found", + }) + return + } + + if err != nil { + c.JSON(http.StatusUnprocessableEntity, gin.H{ + "error": true, + "message": err.Error(), + }) + } + + affectedId, _ := res.RowsAffected() + + c.JSON(http.StatusCreated, gin.H{ + "error": false, + "id": affectedId, + "message": "User have been updated successfully", + }) +} + +func DeleteUser(c *gin.Context) { + idStr := c.Param("id") + id, _ := strconv.Atoi(idStr) + + res, err := db_client.ConnectDB.Exec("DELETE FROM users WHERE id=($1)", id) + + if err == sql.ErrNoRows { + c.JSON(http.StatusNotFound, gin.H{ + "error": true, + "message": "User not found", + }) + return + } + + affectedId, _ := res.RowsAffected() + + c.JSON(http.StatusCreated, gin.H{ + "error": false, + "id": affectedId, + "message": "User have been deleted successfully", + }) + +} diff --git a/main.go b/main.go index 6fe5b3c..6eafd57 100644 --- a/main.go +++ b/main.go @@ -22,8 +22,15 @@ func main() { r.GET("/products", controllers.GetProducts) r.GET("/products/:id", controllers.GetProduct) r.POST("/products", controllers.CreateProduct) - r.PUT("products/:id", controllers.UpdateProduct) - r.DELETE("products/:id", controllers.DeleteProduct) + r.PUT("/products/:id", controllers.UpdateProduct) + r.DELETE("/products/:id", controllers.DeleteProduct) + + // Users + r.GET("/users", controllers.GetUsers) + r.GET("/users/:id", controllers.GetUser) + r.POST("/users", controllers.CreateUser) + r.PUT("/users/:id", controllers.UpdateUser) + r.DELETE("/users/:id", controllers.DeleteUser) if err := r.Run(":5000"); err != nil { panic(err.Error()) diff --git a/migrations/000001_init_schema.down.sql b/migrations/000001_init_schema.down.sql index 4ecd689..455f71f 100644 --- a/migrations/000001_init_schema.down.sql +++ b/migrations/000001_init_schema.down.sql @@ -1 +1,2 @@ -DROP TABLE IF EXISTS products; \ No newline at end of file +DROP TABLE IF EXISTS products; +DROP TABLE IF EXISTS users; \ No newline at end of file diff --git a/migrations/000001_init_schema.up.sql b/migrations/000001_init_schema.up.sql index 1e0b546..27ddd1e 100644 --- a/migrations/000001_init_schema.up.sql +++ b/migrations/000001_init_schema.up.sql @@ -2,4 +2,12 @@ CREATE TABLE IF NOT EXISTS products ( id SERIAL PRIMARY KEY, name VARCHAR(250) NOT NULL, price INTEGER NOT NULL -); \ No newline at end of file +); + +CREATE TABLE users ( + id SERIAL PRIMARY KEY, + first_name VARCHAR(250) NOT NULL, + last_name VARCHAR(250) NOT NULL, + user_name VARCHAR(250) NOT NULL, + password VARCHAR(250) NOT NULL +) \ No newline at end of file