-
Notifications
You must be signed in to change notification settings - Fork 28
/
Copy pathjsonb.go
68 lines (57 loc) · 1.82 KB
/
jsonb.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
package sqlz
import (
"strings"
)
// JSONBObject represents a PostgreSQL JSONB object.
type JSONBObject struct {
// Bindings is the list of bindings for the object.
Bindings []interface{}
}
// JSONBBuilder represents usage of PostgreSQL's jsonb_build_array or
// jsonb_build_object functions.
type JSONBBuilder struct {
// Array indicates whether an array is being built, or an object
Array bool
// Bindings is the list of bindings for the function call
Bindings []interface{}
}
// BuildJSONBObject creates a call to jsonb_build_object.
func BuildJSONBObject(in map[string]interface{}) (out JSONBBuilder) {
for _, key := range sortKeys(in) {
val := in[key]
out.Bindings = append(out.Bindings, key, val)
}
return out
}
// BuildJSONBArray creates a call to jsonb_build_array.
func BuildJSONBArray(in ...interface{}) (out JSONBBuilder) {
out.Array = true
out.Bindings = append(out.Bindings, in...)
return out
}
// Parse processes the JSONB object creator, returning SQL code that calls
// the appropriate function.
func (b JSONBBuilder) Parse() (asSQL string, bindings []interface{}) {
asSQL = "jsonb_build_"
if b.Array {
asSQL += "array("
} else {
asSQL += "object("
}
var placeholders []string
for _, val := range b.Bindings {
if object, isObject := val.(map[string]interface{}); isObject {
subSQL, subBindings := BuildJSONBObject(object).Parse()
placeholders = append(placeholders, subSQL)
bindings = append(bindings, subBindings...)
} else if array, isArray := val.([]interface{}); isArray {
subSQL, subBindings := BuildJSONBArray(array...).Parse()
placeholders = append(placeholders, subSQL)
bindings = append(bindings, subBindings...)
} else {
placeholders = append(placeholders, "?")
bindings = append(bindings, val)
}
}
return asSQL + strings.Join(placeholders, ", ") + ")", bindings
}