-
-
Notifications
You must be signed in to change notification settings - Fork 6
/
json.go
143 lines (113 loc) · 3.04 KB
/
json.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
package goriak
import (
"encoding/json"
"errors"
"reflect"
"strconv"
riak "github.com/basho/riak-go-client"
)
// SetJSON saves value as key in the bucket bucket/bucketType
// Values can automatically be added to indexes with the struct tag goriakindex
func (c *Command) SetJSON(value interface{}) *SetRawCommand {
by, err := json.Marshal(value)
cmdSet := &SetRawCommand{c: c}
if err != nil {
cmdSet.err = err
return cmdSet
}
object := riak.Object{
Value: by,
}
refValue := reflect.ValueOf(value)
// Handling case with the pointer as an argument
if refValue.Kind() == reflect.Ptr {
refValue = refValue.Elem()
}
refType := reflect.TypeOf(value)
// Avoiding panic when zero value passed
if refValue.IsValid() {
refType = refValue.Type()
}
// Indexes from struct value
if refType.Kind() == reflect.Struct {
// Set indexes
for i := 0; i < refType.NumField(); i++ {
indexName := refType.Field(i).Tag.Get("goriakindex")
if len(indexName) == 0 {
continue
}
switch refValue.Field(i).Type().Kind() {
// String
case reflect.String:
object.AddToIndex(indexName, refValue.Field(i).String())
// Slice
case reflect.Slice:
sliceType := refValue.Field(i).Type().Elem()
sliceValue := refValue.Field(i)
switch sliceType.Kind() {
// []string
case reflect.String:
for sli := 0; sli < sliceValue.Len(); sli++ {
object.AddToIndex(indexName, sliceValue.Index(sli).String())
}
// []int
case reflect.Int:
fallthrough
case reflect.Int8:
fallthrough
case reflect.Int16:
fallthrough
case reflect.Int32:
fallthrough
case reflect.Int64:
for sli := 0; sli < sliceValue.Len(); sli++ {
object.AddToIndex(indexName, strconv.FormatInt(sliceValue.Index(sli).Int(), 10))
}
default:
cmdSet.err = errors.New("Did not know how to set index: " + refType.Field(i).Name)
return cmdSet
}
// Int
case reflect.Int:
fallthrough
case reflect.Int8:
fallthrough
case reflect.Int16:
fallthrough
case reflect.Int32:
fallthrough
case reflect.Int64:
// Bashos AddToIntIndex() only accepts int as a type. Using AddToIndex() has
// the same effect but allows for different sizes of ints
object.AddToIndex(
indexName,
strconv.FormatInt(refValue.Field(i).Int(), 10),
)
default:
cmdSet.err = errors.New("Did not know how to set index: " + refType.Field(i).Name)
return cmdSet
}
}
}
builder := riak.NewStoreValueCommandBuilder().
WithBucket(c.bucket).
WithBucketType(c.bucketType)
cmdSet.storeValueObject = &object
cmdSet.storeValueCommandBuilder = builder
return cmdSet
}
// GetJSON is the same as GetRaw, but with automatic JSON unmarshalling
func (c *Command) GetJSON(key string, output interface{}) *GetRawCommand {
builder := riak.NewFetchValueCommandBuilder().
WithBucket(c.bucket).
WithBucketType(c.bucketType).
WithKey(key)
return &GetRawCommand{
c: c,
key: key,
bucket: c.bucket,
bucketType: c.bucketType,
builder: builder,
output: output,
}
}