-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathward_historic_highs_handler.go
118 lines (94 loc) · 3.03 KB
/
ward_historic_highs_handler.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
package main
import (
"github.com/gorilla/mux"
"log"
"net/http"
"net/url"
"strconv"
"time"
)
type HighDay struct {
Date string `json:"date"`
Count int `json:"count"`
}
func WardHistoricHighsHandler(params url.Values, request *http.Request) ([]byte, *ApiError) {
// given a ward and service type, return the set of days with the most SR opened
//
// Parameters:
// count: number of historicl high days to return.
// service_code: (optional) the code used by the City of Chicago to categorize service requests. If omitted, all services codes will be returned
// callback: function to wrap response in (for JSONP functionality)
// include_date: pass a YYYY-MM-DD string and the count for that day will be included
//
vars := mux.Vars(request)
ward_id := vars["id"]
days, err := strconv.Atoi(params.Get("count"))
if err != nil || days < 1 || days > 60 {
return nil, &ApiError{Msg: "invalid count, must be integer, 1..60", Code: 400}
}
service_code := params.Get("service_code")
chi, _ := time.LoadLocation("America/Chicago")
day, err := time.ParseInLocation("2006-01-02", params.Get("include_date"), chi)
if err != nil {
return nil, &ApiError{Msg: "invalid include_date", Code: 400}
}
// if service_code provided, find highs for that code
// otherwise, find highs for each service code
if service_code != "" {
counts := findAllTimeHighs(service_code, ward_id, days)
if !day.IsZero() {
counts = append(counts, HighDay{Date: day.Format("2006-01-02"), Count: findDayTotal(service_code, ward_id, day)})
}
return dumpJson(counts), nil
} else {
type ResponseData struct {
Highs map[string][]HighDay `json:"highs"`
Current map[string]HighDay `json:"current"`
}
var resp ResponseData
resp.Highs = make(map[string][]HighDay)
resp.Current = make(map[string]HighDay)
for _, code := range ServiceCodes {
// find highs
resp.Highs[code] = findAllTimeHighs(code, ward_id, days)
// find date, if spec'd
if !day.IsZero() {
resp.Current[code] = HighDay{Date: day.Format("2006-01-02"), Count: findDayTotal(code, ward_id, day)}
}
}
return dumpJson(resp), nil
}
}
func findAllTimeHighs(service_code string, ward_id string, days int) (counts []HighDay) {
rows, err := api.Db.Query(`SELECT total,requested_date
FROM daily_counts
WHERE service_code = $1
AND ward = $2
ORDER BY total DESC, requested_date DESC
LIMIT $3;`, service_code, ward_id, days)
if err != nil {
log.Print("error fetching historic highs ", err)
}
for rows.Next() {
var d time.Time
var dc HighDay
if err := rows.Scan(&dc.Count, &d); err != nil {
log.Print("error loading high value ", err)
}
counts = append(counts, HighDay{Date: d.Format("2006-01-02"), Count: dc.Count})
}
return
}
func findDayTotal(service_code string, ward_id string, day time.Time) (count int) {
err := api.Db.QueryRow(`SELECT total
FROM daily_counts
WHERE service_code = $1
AND ward = $2
AND requested_date = $3;
`, service_code, ward_id, day).Scan(&count)
if err != nil {
// no rows
count = 0
}
return
}