Skip to content

Commit

Permalink
Many many changes
Browse files Browse the repository at this point in the history
- Added daily_quotas table
- Implemented all missing endpoints
- Improved custom types
  • Loading branch information
szabolcs-horvath committed Dec 27, 2024
1 parent 7171b88 commit 7e6ed5f
Show file tree
Hide file tree
Showing 27 changed files with 1,181 additions and 123 deletions.
50 changes: 50 additions & 0 deletions custom_types/date.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package custom_types

import (
"database/sql/driver"
"fmt"
"time"
)

type Date struct {
_time time.Time
}

func (d Date) UnderlyingTime() time.Time {
return d._time
}

func ParseDate(str string) (*Date, error) {
t, err := time.Parse(time.DateOnly, str)
if err != nil {
return nil, err
}
return &Date{_time: t}, nil
}

func (d Date) Equal(arg Date) bool {
return d._time.Format(time.DateOnly) == arg._time.Format(time.DateOnly)
}

func (d Date) Scan(src any) error {
if src == nil {
return nil
}

str, ok := src.(string)
if !ok {
return fmt.Errorf("cannot scan type %T into custom_types.Date", src)
}

parsedDate, err := time.Parse(time.DateOnly, str)
if err != nil {
return err
}

d._time = parsedDate
return nil
}

func (d Date) Value() (driver.Value, error) {
return d._time.Format(time.DateOnly), nil
}
50 changes: 50 additions & 0 deletions custom_types/time.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package custom_types

import (
"database/sql/driver"
"fmt"
"time"
)

type Time struct {
_time time.Time
}

func (t Time) UnderlyingTime() time.Time {
return t._time
}

func ParseTime(str string) (*Time, error) {
t, err := time.Parse(time.TimeOnly, str)
if err != nil {
return nil, err
}
return &Time{_time: t}, nil
}

func (t Time) Equal(arg Time) bool {
return t._time.Format(time.TimeOnly) == arg._time.Format(time.TimeOnly)
}

func (t Time) Scan(src any) error {
if src == nil {
return nil
}

str, ok := src.(string)
if !ok {
return fmt.Errorf("cannot scan type %T into custom_types.Time", src)
}

parsedTime, err := time.Parse(time.TimeOnly, str)
if err != nil {
return err
}

t._time = parsedTime
return nil
}

func (t Time) Value() (driver.Value, error) {
return t._time.Format(time.TimeOnly), nil
}
61 changes: 0 additions & 61 deletions custom_types/types.go

This file was deleted.

133 changes: 133 additions & 0 deletions http_server/routes/api/v1/daily_quotas/routes.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
package daily_quotas

import (
"github.com/szabolcs-horvath/nutrition-tracker/custom_types"
"github.com/szabolcs-horvath/nutrition-tracker/repository"
"github.com/szabolcs-horvath/nutrition-tracker/util"
"net/http"
"strconv"
)

const Prefix = "/daily_quotas"

func HandlerFuncs() map[string]http.HandlerFunc {
return map[string]http.HandlerFunc{
"GET /{id}": findByIdHandler,
"GET /owner/{id}": listByOwnerHandler,
"GET /owner/{id}/date/{date}": findByOwnerAndDateHandler,
"GET /owner/{id}/date/{$}": findByOwnerAndDateHandler,
"POST /{$}": createHandler,
"PUT /{$}": updateHandler,
"DELETE /{id}": deleteHandler,
}
}

func findByIdHandler(w http.ResponseWriter, r *http.Request) {
id, err := strconv.ParseInt(r.PathValue("id"), 10, 64)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
dailyQuota, err := repository.FindDailyQuotaById(r.Context(), id)
if err != nil {
http.Error(w, err.Error(), http.StatusNotFound)
return
}
if err = util.WriteJson(w, http.StatusOK, dailyQuota); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
}
}

func listByOwnerHandler(w http.ResponseWriter, r *http.Request) {
id, err := strconv.ParseInt(r.PathValue("id"), 10, 64)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
list, err := repository.ListDailyQuotasForUser(r.Context(), id)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
if err = util.WriteJson(w, http.StatusOK, list); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}

func findByOwnerAndDateHandler(w http.ResponseWriter, r *http.Request) {
ownerId, err := strconv.ParseInt(r.PathValue("id"), 10, 64)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
var result *repository.DailyQuota
dateParam := r.PathValue("date")
if dateParam == "" {
dq, dqErr := repository.FindDailyQuotaByOwnerAndCurrentDay(r.Context(), ownerId)
if dqErr != nil {
http.Error(w, dqErr.Error(), http.StatusInternalServerError)
return
}
result = dq
} else {
date, parseErr := custom_types.ParseDate(r.PathValue("date"))
if parseErr != nil {
http.Error(w, parseErr.Error(), http.StatusBadRequest)
return
}
dq, dqErr := repository.FindDailyQuotaByOwnerAndDate(r.Context(), ownerId, date.UnderlyingTime())
if dqErr != nil {
http.Error(w, dqErr.Error(), http.StatusInternalServerError)
return
}
result = dq
}
if err = util.WriteJson(w, http.StatusOK, result); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}

func createHandler(w http.ResponseWriter, r *http.Request) {
var requestDailyQuota repository.CreateDailyQuotaRequest
if err := util.ReadJson(r, &requestDailyQuota); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
dailyQuota, err := repository.CreateDailyQuota(r.Context(), requestDailyQuota)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
if err = util.WriteJson(w, http.StatusCreated, dailyQuota); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
}
}

func updateHandler(w http.ResponseWriter, r *http.Request) {
var requestDailyQuota repository.UpdateDailyQuotaRequest
if err := util.ReadJson(r, &requestDailyQuota); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
dailyQuota, err := repository.UpdateDailyQuota(r.Context(), requestDailyQuota)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
if err = util.WriteJson(w, http.StatusOK, dailyQuota); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
}
}

func deleteHandler(w http.ResponseWriter, r *http.Request) {
id, err := strconv.ParseInt(r.PathValue("id"), 10, 64)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
if err = repository.ArchiveDailyQuota(r.Context(), id); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.WriteHeader(http.StatusNoContent)
}
6 changes: 3 additions & 3 deletions http_server/routes/api/v1/items/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (

const Prefix = "/items"

func Handlers() map[string]http.HandlerFunc {
func HandlerFuncs() map[string]http.HandlerFunc {
return map[string]http.HandlerFunc{
"GET /{$}": listHandler,
"GET /{id}": findByIdHandler,
Expand Down Expand Up @@ -70,7 +70,7 @@ func createHandler(w http.ResponseWriter, r *http.Request) {

func createMultipleHandler(w http.ResponseWriter, r *http.Request) {
var requestItems []repository.CreateItemRequest
if err := util.ReadJson(r, requestItems); err != nil {
if err := util.ReadJson(r, &requestItems); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
Expand All @@ -86,7 +86,7 @@ func createMultipleHandler(w http.ResponseWriter, r *http.Request) {

func updateHandler(w http.ResponseWriter, r *http.Request) {
var requestItem repository.UpdateItemRequest
if err := util.ReadJson(r, requestItem); err != nil {
if err := util.ReadJson(r, &requestItem); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
Expand Down
Loading

0 comments on commit 7e6ed5f

Please sign in to comment.