-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
🎨fix #8 : modularly organize the location handler and add comments fo…
…r each of the separate functions
- Loading branch information
Showing
1 changed file
with
46 additions
and
47 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,76 +1,75 @@ | ||
package server | ||
|
||
import ( | ||
"time" | ||
|
||
"github.com/gin-gonic/gin" | ||
. "github.com/yedhink/covid19-kerala-api/internal/date" | ||
. "github.com/yedhink/covid19-kerala-api/internal/storage" | ||
) | ||
|
||
type Locations struct { | ||
type Query struct { | ||
Loc []string `form:"loc"` | ||
Date string `form:"date"` | ||
} | ||
|
||
func filterByLoc(value map[string]interface{}, key string, d map[string]interface{}, userLoc []string) { | ||
// goes through all the input loc and append matches from value obj to the obj d | ||
// value is server.JsonData.All.Data[timestamp], d is the result and userLoc contains all loc params | ||
func filterByLoc(value map[string]interface{}, d map[string]interface{}, userLoc []string) { | ||
for _, loc := range userLoc { | ||
d[key].(map[string]interface{})[loc] = value[loc] | ||
d[loc] = value[loc] | ||
} | ||
} | ||
|
||
func parseDate(k string, s string) (time.Time, time.Time) { | ||
userDate, err := time.Parse("02-01-2006", s) | ||
if err != nil { | ||
userDate, _ = time.Parse("02/01/2006", s) | ||
} | ||
userDate.Format(time.RFC3339) | ||
keyDate, _ := time.Parse(time.RFC3339, k) | ||
return keyDate, userDate | ||
} | ||
// q is the Query struct, d is our final result, st is Storage referenc and apiData is server.JsonData.All.Data | ||
// the function validates the date and filters using loc and date parameters of user | ||
func LocDateFilter(q *Query, d map[string]interface{}, st *Storage, apiData map[string]interface{}, locExist bool) { | ||
// start by checking if the date param value is valid formatted Date | ||
switch IsDate(q.Date) { | ||
case true: | ||
for key, value := range apiData { | ||
if ValidDate(key, q.Date, st) { | ||
// if loc length > 0 then only filterByLoc | ||
if locExist == true { | ||
d[key] = make(map[string]interface{}, len(q.Loc)) | ||
filterByLoc(value.(map[string]interface{}), d[key].(map[string]interface{}), q.Loc) | ||
} else { | ||
// if no loc, then just assign to valid date | ||
d[key] = value | ||
} | ||
} | ||
} | ||
// if the date is not correctly formatted | ||
case false: | ||
d["success"] = false | ||
d["message"] = "Invalid Date Format as Parameter" | ||
} | ||
} | ||
|
||
// handles the /location related parameter and non-parametric queries | ||
func (server *Server) Location(st *Storage) gin.HandlerFunc { | ||
return func(c *gin.Context) { | ||
var l Locations | ||
c.Bind(&l) | ||
if len(l.Loc) > 0 { | ||
d := make(map[string]interface{}) | ||
d["success"] = true | ||
var q Query | ||
c.Bind(&q) | ||
// initialize the final result 'd' with success=true | ||
d := make(map[string]interface{}) | ||
d["success"] = true | ||
// check if loc param is nil or not | ||
switch length := len(q.Loc); { | ||
//serve the array of locations | ||
case length == 0 && q.Date == "": | ||
d = server.JsonData.Districts.Loc | ||
// validate just the date and append matching obj entries | ||
case length == 0 && q.Date != "": | ||
LocDateFilter(&q, d, st, server.JsonData.All.Data, false) | ||
// just filter by loc parameter | ||
case length > 0 && q.Date == "": | ||
for key, value := range server.JsonData.All.Data { | ||
// since we cant assert a value interface of type bool as map[string]interface{} | ||
if key == "success" { | ||
continue | ||
} | ||
if l.Date != "" { | ||
if validateDate(key, l.Date, st) { | ||
d[key] = make(map[string]interface{}, len(l.Loc)) | ||
filterByLoc(value.(map[string]interface{}), key, d, l.Loc) | ||
} | ||
} else { | ||
d[key] = make(map[string]interface{}, len(l.Loc)) | ||
filterByLoc(value.(map[string]interface{}), key, d, l.Loc) | ||
} | ||
} | ||
c.IndentedJSON(200, d) | ||
} else { | ||
if l.Date != "" { | ||
d := make(map[string]interface{}) | ||
d["success"] = true | ||
for key, value := range server.JsonData.All.Data { | ||
if key != "success" && validateDate(key, l.Date, st) { | ||
d[key] = value | ||
} | ||
} | ||
c.IndentedJSON(200, d) | ||
} else { | ||
server.JsonData.Districts.Loc["success"] = true | ||
c.IndentedJSON(200, server.JsonData.Districts.Loc) | ||
d[key] = make(map[string]interface{}, len(q.Loc)) | ||
filterByLoc(value.(map[string]interface{}), d[key].(map[string]interface{}), q.Loc) | ||
} | ||
// filter by both loc and date params | ||
case length > 0 && q.Date != "": | ||
LocDateFilter(&q, d, st, server.JsonData.All.Data, true) | ||
} | ||
c.IndentedJSON(200, d) | ||
} | ||
} |