/
crud.go
155 lines (129 loc) · 3.61 KB
/
crud.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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
package fuel
import (
"encoding/json"
"fmt"
"github.com/rightjoin/dorm"
"github.com/jinzhu/gorm"
"github.com/rightjoin/rutl/conv"
"github.com/rightjoin/rutl/refl"
)
// Note: Even if there is a table column named PageSize, its
// SQL reference would be page_size (snake case). It would not
// conflict with default query values
var QPageSize = "page-size"
var QPageNum = "page-num"
var QOrderBy = "order-by"
var QOrderDir = "order-dir"
var QAltDb = "alt-db"
// FindHelper runs when model.Find GET service is invoked
func FindHelper(modl interface{}, ptrArrModel interface{}, ad Aide, dbo *gorm.DB) error {
// If dbo is null, obtain
// a DBO object
if dbo == nil {
dbo = QueryDB(ad)
}
flds := refl.NestedFields(modl)
query := map[string]interface{}{}
params := ad.Query()
// If param matches one of model fields,
// then only we use it in exact query
for _, f := range flds {
fldName := conv.CaseSnake(f.Name) // field's sql or db name
if val, ok := params[fldName]; ok {
query[fldName] = val
}
}
// Total Record Count
var count int
err := dbo.Model(modl).Where(query).Count(&count).Error
if err != nil {
return err
}
ad.Response.Header().Set(HeaderTotalRecords, fmt.Sprintf("%d", count))
// Pagination Size
sizeVal, ok := params[QPageSize]
size := conv.IntOr(sizeVal, 100)
if size == -1 { // if pagination size is -1, then retreive all records
size = count
}
ad.Response.Header().Set(HeaderPageSize, fmt.Sprintf("%d", size))
// Page Number (to retreive)
pageVal, ok := params[QPageNum]
if !ok {
pageVal = "1"
}
page := conv.IntOr(pageVal, 1)
ad.Response.Header().Set(HeaderPageNum, fmt.Sprintf("%d", page))
// Calculate Offset
offset := (page - 1) * size
// Order-By and Order Direction
idDefault := false
order, ok := params[QOrderBy]
if !ok {
// default order is "id"
idDefault = true
order = "id"
}
dirn, ok := params[QOrderDir]
if !ok {
if idDefault {
dirn = "desc"
} else {
dirn = "asc"
}
}
orderDir := fmt.Sprintf("%s %s", order, dirn)
return dbo.Where(query).Order(orderDir).Offset(offset).Limit(size).Find(ptrArrModel).Error
}
// QueryHelper runs when model.Query POST service is invoked
func QueryHelper(modl interface{}, ptrArrModel interface{}, ad Aide, dbo *gorm.DB) error {
// If dbo is null, obtain
// a DBO object
if dbo == nil {
dbo = QueryDB(ad)
}
body := ad.Post()
where := body["where"]
params := []interface{}{}
if paramsStr, ok := body["params"]; ok {
err := json.Unmarshal([]byte(paramsStr), ¶ms)
if err != nil {
return err
}
}
// Record Count
var count int
err := dbo.Model(modl).Where(where, params).Count(&count).Error
if err != nil {
return err
}
ad.Response.Header().Set(HeaderTotalRecords, fmt.Sprintf("%d", count))
// Pagination Size
sizeVal, pageSizeOK := body[QPageSize]
if !pageSizeOK {
return dbo.Where(where, params).Find(ptrArrModel).Error
}
size := conv.IntOr(sizeVal, 100)
if size == -1 { // if pagination size is -1, then retreive all records
size = count
}
ad.Response.Header().Set(HeaderPageSize, fmt.Sprintf("%d", size))
// Page Number (to retreive)
pageVal, ok := body[QPageNum]
if !ok {
pageVal = "1"
}
page := conv.IntOr(pageVal, 1)
ad.Response.Header().Set(HeaderPageNum, fmt.Sprintf("%d", page))
// Calculate Offset
offset := (page - 1) * size
return dbo.Where(where, params).Offset(offset).Limit(size).Find(ptrArrModel).Error
}
// QueryDB sets up how fule gets the underlying ORM
// for the call. Default is to use master. However,
// if "alt-db" is present in Query String, then use
// a slave
func QueryDB(ad Aide) *gorm.DB {
_, slave := ad.Query()[QAltDb]
return dorm.GetORM(!slave)
}