Skip to content

Commit 2d8c873

Browse files
authored
Add support for Valuer Interface parsing
2 parents bc4da84 + 7542d1e commit 2d8c873

File tree

2 files changed

+77
-0
lines changed

2 files changed

+77
-0
lines changed

goqu.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@ type SQLValuer struct {
3737

3838
// Value converts the given value to the correct drive.Value.
3939
func (t SQLValuer) Value() (driver.Value, error) {
40+
if valuer, ok := t.V.(driver.Valuer); ok {
41+
if reflect.TypeOf(t.V).Kind() == reflect.Pointer && reflect.ValueOf(t.V).IsZero() {
42+
return nil, nil
43+
}
44+
return valuer.Value()
45+
}
4046
switch t.V.(type) {
4147
case []string, []bool, []float32, []float64, []int, []int64, []int32:
4248
value, err := pq.Array(t.V).Value()

goqu_test.go

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,27 @@
11
package goqux
22

33
import (
4+
"database/sql/driver"
5+
"encoding/json"
46
"testing"
57

68
"github.com/stretchr/testify/assert"
79
)
810

11+
type structField struct {
12+
V map[string]interface{} `json:"v"`
13+
}
14+
15+
func (s structField) Value() (driver.Value, error) {
16+
return json.Marshal(s)
17+
}
18+
19+
type structValuerArray []structField
20+
21+
func (s structValuerArray) Value() (driver.Value, error) {
22+
return json.Marshal(s)
23+
}
24+
925
func TestSQLValuer_Value(t *testing.T) {
1026
tableTestValues := []struct {
1127
name string
@@ -65,6 +81,61 @@ func TestSQLValuer_Value(t *testing.T) {
6581
},
6682
expected: "{\"test\"}",
6783
},
84+
{
85+
name: "struct_implements_valuer",
86+
value: structField{
87+
V: map[string]interface{}{
88+
"test": "test",
89+
},
90+
},
91+
expected: []byte(`{"v":{"test":"test"}}`),
92+
},
93+
{
94+
name: "valuer_pointer",
95+
value: &structField{
96+
V: map[string]interface{}{
97+
"test": "test",
98+
},
99+
},
100+
expected: []byte(`{"v":{"test":"test"}}`),
101+
},
102+
{
103+
name: "valuer_nil_pointer",
104+
value: (*structField)(nil),
105+
expected: nil,
106+
},
107+
{
108+
name: "empty_struct",
109+
value: structField{},
110+
expected: []byte(`{"v":null}`),
111+
},
112+
{
113+
name: "empty_struct_pointer",
114+
value: &structField{},
115+
expected: []byte(`{"v":null}`),
116+
},
117+
{
118+
name: "valuer_array_struct",
119+
value: structValuerArray{
120+
{
121+
V: map[string]interface{}{
122+
"test": "test",
123+
},
124+
},
125+
},
126+
expected: []byte(`[{"v":{"test":"test"}}]`),
127+
},
128+
{
129+
name: "valuer_array_pointer",
130+
value: &structValuerArray{
131+
{
132+
V: map[string]interface{}{
133+
"test": "test",
134+
},
135+
},
136+
},
137+
expected: []byte(`[{"v":{"test":"test"}}]`),
138+
},
68139
}
69140
for _, tt := range tableTestValues {
70141
t.Run(tt.name, func(t *testing.T) {

0 commit comments

Comments
 (0)