-
Notifications
You must be signed in to change notification settings - Fork 1
/
catholic-dioceses.go
128 lines (111 loc) · 3.4 KB
/
catholic-dioceses.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
119
120
121
122
123
124
125
126
127
128
package apiary
import (
"context"
"encoding/json"
"fmt"
"log"
"net/http"
)
// CatholicDiocese describes a diocese of the Roman Catholic Church.
type CatholicDiocese struct {
City string `json:"city"`
State string `json:"state"`
Country string `json:"country"`
Rite string `json:"rite"`
YearErected int64 `json:"year_erected"`
YearMetropolitan NullInt64 `json:"year_metropolitan"`
YearDestroyed NullInt64 `json:"year_destroyed"`
Lon float32 `json:"lon"`
Lat float32 `json:"lat"`
}
// CatholicDiocesesPerDecade shows how many dioceses were established in North
// America per year.
type CatholicDiocesesPerDecade struct {
Decade int64 `json:"decade"`
Count int64 `json:"n"`
}
// CatholicDiocesesHandler returns a JSON array of Catholic dioceses. Though
// the spatial data is stored in the database as a geometry, it is returned as
// simple lon/lat coordinates because that is easiest to process in the
// visualizations.
func (s *Server) CatholicDiocesesHandler() http.HandlerFunc {
query := `
SELECT city, state, country, rite,
date_part( 'year', date_erected) as year_erected,
date_part('year', date_metropolitan) as year_metropolitan,
date_part('year', date_destroyed) as year_destroyed,
ST_X(geometry) as lon, ST_Y(geometry) as lat
FROM catholic_dioceses
ORDER BY date_erected;
`
return func(w http.ResponseWriter, r *http.Request) {
results := make([]CatholicDiocese, 0)
var row CatholicDiocese
rows, err := s.DB.Query(context.TODO(), query)
if err != nil {
log.Println(err)
}
defer rows.Close()
for rows.Next() {
err := rows.Scan(&row.City, &row.State, &row.Country, &row.Rite,
&row.YearErected, &row.YearMetropolitan, &row.YearDestroyed,
&row.Lon, &row.Lat)
if err != nil {
log.Println(err)
}
results = append(results, row)
}
err = rows.Err()
if err != nil {
log.Println(err)
}
response, _ := json.Marshal(results)
w.Header().Set("Content-Type", "application/json")
fmt.Fprint(w, string(response))
}
}
// CatholicDiocesesPerDecadeHandler returns a JSON array of the number of dioceses
// established in North America per year.
func (s *Server) CatholicDiocesesPerDecadeHandler() http.HandlerFunc {
// This query counts the number of dioceses established per decade. But it
// also generates a series of decades from 1500 to 2020 so that there are
// no gaps between decades in the result.
query := `
SELECT
series.decade,
coalesce(n, 0) AS n
FROM
(SELECT generate_series(1500, 2020, 10) AS decade) AS series
LEFT JOIN
(SELECT
floor(date_part( 'year', date_erected)/10)*10 AS decade,
count(*) AS n
FROM catholic_dioceses
GROUP BY decade) counts
ON series.decade = counts.decade
ORDER BY series.decade;
`
return func(w http.ResponseWriter, r *http.Request) {
results := make([]CatholicDiocesesPerDecade, 0, 52) // Preallocate slice capacity
var row CatholicDiocesesPerDecade
rows, err := s.DB.Query(context.TODO(), query)
if err != nil {
log.Println(err)
}
defer rows.Close()
for rows.Next() {
err := rows.Scan(&row.Decade, &row.Count)
if err != nil {
log.Println(err)
}
results = append(results, row)
}
err = rows.Err()
if err != nil {
log.Println(err)
}
response, _ := json.Marshal(results)
w.Header().Set("Content-Type", "application/json")
fmt.Fprint(w, string(response))
}
}