/
handlers.go
122 lines (98 loc) · 3.24 KB
/
handlers.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
package main
import (
"encoding/json"
"fmt"
"github.com/codegangsta/martini"
"net/http"
"reflect"
"strconv"
)
var GetAllUnits func(IUnitRepository) (int, string)
var GetUnit func(martini.Params, IUnitRepository) (int, string)
//var AddUnit func(http.ResponseWriter, Unit, IUnitRepository)
func init() {
makeFunc := func(base func([]reflect.Value) []reflect.Value, fptr interface{}) {
fn := reflect.ValueOf(fptr).Elem()
v := reflect.MakeFunc(fn.Type(), base)
fn.Set(v)
}
// getAll(Repository) (int, string)
getAll := func(in []reflect.Value) []reflect.Value {
values := in[0].MethodByName("GetAll").Call([]reflect.Value{})
// values is []reflect.Value returned by reflect.Call.
// Since GetAll only returns interface{}, we just want the first object in values
jsonResponse := string(jsonEncode(values[0].Interface()))
return genericHandlerReturn(http.StatusFound, jsonResponse)
}
makeFunc(getAll, &GetAllUnits)
/*func AddUnit(rw http.ResponseWriter, u Unit, repo IUnitRepository) (int, string) {
repo.Add(&u)
rw.Header().Set("Location", fmt.Sprintf("/unit/%d", u.Id))
return http.StatusCreated, ""
}
// add(http.ResponseWriter, entity, Repository) (int, string)
add := func(in []reflect.Value) []reflect.Value {
in[2].MethodByName("Add").Call([]reflect.Value{in[1]})
header := in[0].MethodByName("Header").Call(nil)
location := reflect.ValueOf("Location")
locationValue := reflect.ValueOf(fmt.Sprintf("/unit/%d", in[1].FieldByName("Id")))
reflect.ValueOf(header).MethodByName("Set").Call([]reflect.Value{location, locationValue})
return genericHandlerReturn(http.StatusCreated, "")
}
makeFunc(add, &AddUnit)
*/
// get(martini.Params, Repository) (int, string)
get := func(in []reflect.Value) []reflect.Value {
params := in[0].Interface().(martini.Params)
id, err := strconv.Atoi(params["id"])
if err != nil {
return notFoundGeneric()
}
inGet := []reflect.Value{reflect.ValueOf(id)}
values := in[1].MethodByName("Get").Call(inGet)
if values[0].IsNil() {
return notFoundGeneric()
}
jsonResponse := string(jsonEncode(values[0].Interface()))
return []reflect.Value{reflect.ValueOf(http.StatusOK), reflect.ValueOf(jsonResponse)}
}
makeFunc(get, &GetUnit)
}
func AddUnit(rw http.ResponseWriter, u Unit, repo IUnitRepository) (int, string) {
repo.Add(&u)
rw.Header().Set("Location", fmt.Sprintf("/unit/%d", u.Id))
return http.StatusCreated, ""
}
func UpdateUnit(u Unit, repo IUnitRepository) (int, string) {
cnt := repo.Update(&u)
if cnt < 1 {
return notFound()
}
return http.StatusOK, string(cnt)
}
func DeleteUnit(parms martini.Params, repo IUnitRepository) (int, string) {
id, err := strconv.Atoi(parms["id"])
if err != nil {
return notFound()
}
u := repo.Get(id)
if u == nil {
return notFound()
}
cnt := repo.Delete(u)
return http.StatusOK, string(cnt)
}
func jsonEncode(o interface{}) []byte {
jsonResponse, err := json.MarshalIndent(o, "", " ")
PanicIf(err)
return jsonResponse
}
func notFound() (int, string) {
return http.StatusNotFound, "Not found"
}
func genericHandlerReturn(status int, text string) []reflect.Value {
return []reflect.Value{reflect.ValueOf(status), reflect.ValueOf(text)}
}
func notFoundGeneric() []reflect.Value {
return genericHandlerReturn(notFound())
}