From 75d132495282704e3ac7421ebf8e6843f06173c4 Mon Sep 17 00:00:00 2001 From: Dennis Date: Fri, 31 May 2024 21:17:34 +0200 Subject: [PATCH] Implements create feed handler And necessary user helper functions --- internal/api/api.go | 1 + internal/api/feed.go | 58 ++++++++++++++++++++++++++++++++++++++++++++ internal/api/user.go | 31 ++++++++++++++++++++++- 3 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 internal/api/feed.go diff --git a/internal/api/api.go b/internal/api/api.go index bd41177..a4294e7 100644 --- a/internal/api/api.go +++ b/internal/api/api.go @@ -28,6 +28,7 @@ func Setup(app *fiber.App, db *sql.DB) error { v1 := api.Group("/v1") v1.Post("/users", apiHandler.createUser) + v1.Post("/users/:userID/feeds", apiHandler.createFeed) return nil } diff --git a/internal/api/feed.go b/internal/api/feed.go new file mode 100644 index 0000000..4e11628 --- /dev/null +++ b/internal/api/feed.go @@ -0,0 +1,58 @@ +package api + +import ( + "fmt" + "freed/internal/model" + + "github.com/gofiber/fiber/v2" + "github.com/gofiber/fiber/v2/log" + "github.com/mattn/go-sqlite3" +) + +func (h *Handler) createFeed(c *fiber.Ctx) error { + userID := c.Params("userID") + feed := new(model.Feed) + + if parseErr := c.BodyParser(feed); parseErr != nil { + log.Warn(parseErr) + return defaultUserError + } + + validationErr := ValidateModel(feed) + + if validationErr != nil { + return fiber.NewError(fiber.ErrInternalServerError.Code, validationErr.Message) + } + + userExists := h.userExists(userID) + fmt.Printf("exists? %v", userExists) + + if h.userExists(userID) == false { + return fiber.NewError(fiber.ErrInternalServerError.Code, "No existing user found, check user id path param.") + } + + // TODO: Get name from feed + // TODO: Get type from feed + // TODO: Either schedule or request items from feed immediately + + sqlResult, insertErr := h.db.Exec("INSERT INTO feed (userId, name, url) VALUES (?, ?, ?)", userID, feed.Url, feed.Url) + + if sqliteErr, ok := insertErr.(sqlite3.Error); ok { + log.Warn(insertErr) + + if sqliteErr.ExtendedCode == sqlite3.ErrConstraintUnique { + return fiber.NewError(fiber.StatusBadRequest, "Feed with url already exists") + } + + return fiber.NewError(fiber.ErrInternalServerError.Code, "Could not create feed") + } + + feedID, idErr := sqlResult.LastInsertId() + + if idErr != nil { + return fiber.NewError(fiber.ErrInternalServerError.Code, "Created feed, but could not retrieve its ID, check database.") + } + + c.SendStatus(201) + return c.JSON(&fiber.Map{"id": feedID}) +} diff --git a/internal/api/user.go b/internal/api/user.go index f4904fa..d8dfd5d 100644 --- a/internal/api/user.go +++ b/internal/api/user.go @@ -1,6 +1,9 @@ package api import ( + "database/sql" + "errors" + "fmt" "freed/internal/model" "github.com/gofiber/fiber/v2" @@ -31,7 +34,7 @@ func (h *Handler) createUser(c *fiber.Ctx) error { validationErr := ValidateModel(user) if validationErr != nil { - return validationErr + return fiber.NewError(fiber.ErrInternalServerError.Code, validationErr.Message) } _, insertErr := h.db.Exec("INSERT INTO user (id, first_name, email) VALUES (?, ?, ?)", user.ID, user.FirstName, user.Email) @@ -49,3 +52,29 @@ func (h *Handler) createUser(c *fiber.Ctx) error { c.SendStatus(201) return c.JSON(&fiber.Map{"userId": userId}) } + +func (h *Handler) getUserByID(id string) (*model.User, error) { + var user *model.User + + if err := h.db.QueryRow("SELECT * FROM user WHERE id = ?", id).Scan(&user); err != nil { + if err == sql.ErrNoRows { + notFoundErrMessage := fmt.Sprintf("No user found with ID: %s", id) + return nil, errors.New(notFoundErrMessage) + } + + unexpectedErrMessage := fmt.Sprintf("Unexpected error occured, could not get user with ID: %s", id) + return nil, errors.New(unexpectedErrMessage) + } + + return user, nil +} + +func (h *Handler) userExists(id string) bool { + var userID string + + if err := h.db.QueryRow("SELECT id FROM user WHERE id = ?", id).Scan(&userID); err != nil { + return false + } + + return true +}