Skip to content

Commit 7aa3e3e

Browse files
committed
push handler util model files
1 parent 02acaa1 commit 7aa3e3e

File tree

3 files changed

+174
-11
lines changed

3 files changed

+174
-11
lines changed

handler/handler.go

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
package handler
2+
3+
import (
4+
"context"
5+
"database/sql"
6+
"encoding/json"
7+
c "github.com/core-go/cassandra"
8+
"github.com/gocql/gocql"
9+
"net/http"
10+
)
11+
12+
type Handler struct {
13+
DB *sql.DB
14+
Session *gocql.Session
15+
Error func(context.Context, string)
16+
}
17+
18+
func NewHandler(db *sql.DB, options ...func(context.Context, string)) *Handler {
19+
var logError func(context.Context, string)
20+
if len(options) >= 1 {
21+
logError = options[0]
22+
}
23+
return &Handler{DB: db, Error: logError}
24+
}
25+
26+
func (h *Handler) Exec(w http.ResponseWriter, r *http.Request) {
27+
s := c.JStatement{}
28+
er0 := json.NewDecoder(r.Body).Decode(&s)
29+
if er0 != nil {
30+
http.Error(w, er0.Error(), http.StatusBadRequest)
31+
return
32+
}
33+
s.Params = c.ParseDates(s.Params, s.Dates)
34+
res, er1 := c.Exec(h.Session, s.Query, s.Params...)
35+
if er1 != nil {
36+
handleError(w, r, 500, er1.Error(), h.Error, er1)
37+
return
38+
}
39+
succeed(w, r, http.StatusOK, res)
40+
}
41+
42+
func (h *Handler) Query(w http.ResponseWriter, r *http.Request) {
43+
s := c.JStatement{}
44+
er0 := json.NewDecoder(r.Body).Decode(&s)
45+
if er0 != nil {
46+
http.Error(w, er0.Error(), http.StatusBadRequest)
47+
return
48+
}
49+
s.Params = c.ParseDates(s.Params, s.Dates)
50+
res, err := c.QueryMap(h.Session, s.Query, s.Params...)
51+
if err != nil {
52+
handleError(w, r, 500, err.Error(), h.Error, err)
53+
return
54+
}
55+
succeed(w, r, http.StatusOK, res)
56+
}
57+
58+
func (h *Handler) ExecBatch(w http.ResponseWriter, r *http.Request) {
59+
var s []c.JStatement
60+
b := make([]c.Statement, 0)
61+
er0 := json.NewDecoder(r.Body).Decode(&s)
62+
if er0 != nil {
63+
http.Error(w, er0.Error(), http.StatusBadRequest)
64+
return
65+
}
66+
l := len(s)
67+
for i := 0; i < l; i++ {
68+
st := c.Statement{}
69+
st.Query = s[i].Query
70+
st.Params = c.ParseDates(s[i].Params, s[i].Dates)
71+
b = append(b, st)
72+
}
73+
res, err := c.ExecuteAll(r.Context(), h.Session, b...)
74+
if err != nil {
75+
handleError(w, r, 500, err.Error(), h.Error, err)
76+
return
77+
}
78+
succeed(w, r, http.StatusOK, res)
79+
}
80+
81+
func handleError(w http.ResponseWriter, r *http.Request, code int, result interface{}, logError func(context.Context, string), err error) {
82+
if logError != nil {
83+
logError(r.Context(), err.Error())
84+
}
85+
returnJSON(w, code, result)
86+
}
87+
func succeed(w http.ResponseWriter, r *http.Request, code int, result interface{}) {
88+
response, _ := json.Marshal(result)
89+
w.Header().Set("Content-Type", "application/json")
90+
w.WriteHeader(code)
91+
w.Write(response)
92+
}
93+
func returnJSON(w http.ResponseWriter, code int, result interface{}) error {
94+
w.Header().Set("Content-Type", "application/json")
95+
w.WriteHeader(code)
96+
if result == nil {
97+
w.Write([]byte("null"))
98+
return nil
99+
}
100+
response, err := marshal(result)
101+
if err != nil {
102+
// log.Println("cannot marshal of result: " + err.Error())
103+
http.Error(w, err.Error(), http.StatusInternalServerError)
104+
return err
105+
}
106+
w.Write(response)
107+
return nil
108+
}
109+
func marshal(v interface{}) ([]byte, error) {
110+
b, ok1 := v.([]byte)
111+
if ok1 {
112+
return b, nil
113+
}
114+
s, ok2 := v.(string)
115+
if ok2 {
116+
return []byte(s), nil
117+
}
118+
return json.Marshal(v)
119+
}

model.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,8 @@ type Statement struct {
44
Query string `mapstructure:"query" json:"query,omitempty" gorm:"column:query" bson:"query,omitempty" dynamodbav:"query,omitempty" firestore:"query,omitempty"`
55
Params []interface{} `mapstructure:"params" json:"params,omitempty" gorm:"column:params" bson:"params,omitempty" dynamodbav:"params,omitempty" firestore:"params,omitempty"`
66
}
7+
type JStatement struct {
8+
Query string `mapstructure:"query" json:"query,omitempty" gorm:"column:query" bson:"query,omitempty" dynamodbav:"query,omitempty" firestore:"query,omitempty"`
9+
Params []interface{} `mapstructure:"params" json:"params,omitempty" gorm:"column:params" bson:"params,omitempty" dynamodbav:"params,omitempty" firestore:"params,omitempty"`
10+
Dates []int `mapstructure:"dates" json:"dates,omitempty" gorm:"column:dates" bson:"dates,omitempty" dynamodbav:"dates,omitempty" firestore:"dates,omitempty"`
11+
}

util.go

Lines changed: 50 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,16 @@ import (
44
"reflect"
55
"strconv"
66
"strings"
7+
"time"
8+
)
9+
const (
10+
t1 = "2006-01-02T15:04:05Z"
11+
t2 = "2006-01-02T15:04:05-0700"
12+
t3 = "2006-01-02T15:04:05.0000000-0700"
13+
14+
l1 = len(t1)
15+
l2 = len(t2)
16+
l3 = len(t3)
717
)
818

919
type FieldDB struct {
@@ -26,22 +36,16 @@ func CreateSchema(modelType reflect.Type) *Schema {
2636
return s
2737
}
2838
func MakeSchema(modelType reflect.Type) ([]string, []string, map[string]FieldDB) {
29-
numField := 0
30-
if modelType.Kind() == reflect.Ptr {
31-
numField = modelType.Elem().NumField()
32-
} else {
33-
numField = modelType.NumField()
39+
m := modelType
40+
if m.Kind() == reflect.Ptr {
41+
m = m.Elem()
3442
}
43+
numField := m.NumField()
3544
columns := make([]string, 0)
3645
keys := make([]string, 0)
3746
schema := make(map[string]FieldDB, 0)
3847
for idx := 0; idx < numField; idx++ {
39-
var field reflect.StructField
40-
if modelType.Kind() == reflect.Ptr {
41-
field = modelType.Elem().Field(idx)
42-
} else {
43-
field = modelType.Field(idx)
44-
}
48+
field := m.Field(idx)
4549
tag, _ := field.Tag.Lookup("gorm")
4650
if !strings.Contains(tag, IgnoreReadWrite) {
4751
update := !strings.Contains(tag, "update:false")
@@ -109,3 +113,38 @@ func GetDBValue(v interface{}) (string, bool) {
109113
return "", false
110114
}
111115
}
116+
func ParseDates(args []interface{}, dates []int) []interface{} {
117+
if args == nil || len(args) == 0 {
118+
return nil
119+
}
120+
if dates == nil || len(dates) == 0 {
121+
return args
122+
}
123+
res := append([]interface{}{}, args...)
124+
for _, d := range dates {
125+
if d >= len(args) {
126+
break
127+
}
128+
a := args[d]
129+
if s, ok := a.(string); ok {
130+
switch len(s) {
131+
case l1:
132+
t, err := time.Parse(t1, s)
133+
if err == nil {
134+
res[d] = t
135+
}
136+
case l2:
137+
t, err := time.Parse(t2, s)
138+
if err == nil {
139+
res[d] = t
140+
}
141+
case l3:
142+
t, err := time.Parse(t3, s)
143+
if err == nil {
144+
res[d] = t
145+
}
146+
}
147+
}
148+
}
149+
return res
150+
}

0 commit comments

Comments
 (0)