-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathparse.go
151 lines (126 loc) · 3.73 KB
/
parse.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
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package quirk
import (
"reflect"
"strings"
)
// Credit: The Go Authors @ "encoding/json"
// parseTag splits a struct field's quirk tag into its name and
// comma-separated options.
func parseTag(tag string) (string, tagOptions) {
if idx := strings.Index(tag, ","); idx != -1 {
return tag[:idx], tagOptions(tag[idx+1:])
}
return tag, tagOptions("")
}
// reflectMaps takes an interface which is suspected to be given as a struct.
// Takes the fields and parses through the tags and adds the fieldname, and
// whether it is a unique tag to the returning predicate:value data slice.
func (c *Client) reflectMaps(d interface{}) *DupleNode {
elem := reflect.ValueOf(d).Elem()
numFields := elem.NumField()
duple := &DupleNode{
// Duples: make([]Duple, numFields),
}
var (
tag string // stores the name of the field in Dgraph.
opt tagOptions // stores either "" or "unique" if provided in the tags.
)
// loop through elements of struct.
for i := 0; i < numFields; i++ {
tag, opt = parseTag(reflect.TypeOf(d).Elem().Field(i).Tag.Get(quirkTag))
if tag == "" {
continue
}
// Add the predicate and value to the slice.
// duple.Duples[i] = Duple{
duple.Duples = append(duple.Duples, Duple{
Predicate: tag, // first quirk tag.
Object: elem.Field(i).Interface(),
IsUnique: opt == tagUnique, // if the second option is "unique"
// dataType: checkType(elem.Field(i).Interface()),
})
if tag == c.predicateKey {
duple.Identifier = duple.Duples[i].Object.(string)
}
}
return duple
}
// dynamicMapToPredValPairs may seem like a duplicate of mapToPredValPairs
// but this one uses a map[string]interface{} instead of a map[string]string
// which in Go there is currently no way to have them be interchangeable.
func (c *Client) dynamicMapToPredValPairs(d map[string]interface{}) *DupleNode {
duple := &DupleNode{
Duples: make([]Duple, len(d)),
}
var i int // counter for the predVal slice.
var val interface{}
// loop through elements of map.
for k, v := range d {
dType := checkType(v)
if dType == xsByte {
val = string(v.([]byte))
dType = ""
} else {
val = v
}
duple.Duples[i] = Duple{
Predicate: k,
Object: val,
dataType: dType,
}
if k == c.predicateKey {
duple.Identifier = v.(string)
}
i++
}
return duple
}
// mapToPredValPairs may seem like a duplicate of dynamicMapToPredValPairs
// but this one uses a map[string]string instead of a map[string]interface{}
// which in Go there is currently no way to have them be interchangeable.
func (c *Client) mapToPredValPairs(d map[string]string) *DupleNode {
duple := &DupleNode{
Duples: make([]Duple, len(d)),
}
var i int // counter for the predVal slice.
// loop through elements of map.
for k, v := range d {
duple.Duples[i] = Duple{
Predicate: k,
Object: v,
}
if k == c.predicateKey {
duple.Identifier = v
}
i++
}
return duple
}
// checkType will return an XML datatype tag if
// any valid datatypes have are applicable.
func checkType(val interface{}) string {
switch val.(type) {
case int64: // int64 gets handled as a normal int.
return xsInt
case int32: // int32 gets handled as a normal int.
return xsInt
case int16: // int16 gets handled as normal int.
return xsInt
case int8: // int8 gets handled as normal int.
return xsInt
case int:
return xsInt
case bool:
return xsBool
case float32: // float32 gets handled as a general float.
return xsFloat
case float64: // float64 gets handled as a general float.
return xsFloat
case []byte:
return xsString // Changed from xs:byte to xs:string for Dgraphv.1.1.0
}
return ""
}