Skip to content

Commit

Permalink
Add support for Valuer Interface parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
OrCh3n authored Feb 12, 2024
2 parents bc4da84 + 7542d1e commit 2d8c873
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 0 deletions.
6 changes: 6 additions & 0 deletions goqu.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ type SQLValuer struct {

// Value converts the given value to the correct drive.Value.
func (t SQLValuer) Value() (driver.Value, error) {
if valuer, ok := t.V.(driver.Valuer); ok {
if reflect.TypeOf(t.V).Kind() == reflect.Pointer && reflect.ValueOf(t.V).IsZero() {
return nil, nil
}
return valuer.Value()
}
switch t.V.(type) {
case []string, []bool, []float32, []float64, []int, []int64, []int32:
value, err := pq.Array(t.V).Value()
Expand Down
71 changes: 71 additions & 0 deletions goqu_test.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,27 @@
package goqux

import (
"database/sql/driver"
"encoding/json"
"testing"

"github.com/stretchr/testify/assert"
)

type structField struct {
V map[string]interface{} `json:"v"`
}

func (s structField) Value() (driver.Value, error) {
return json.Marshal(s)
}

type structValuerArray []structField

func (s structValuerArray) Value() (driver.Value, error) {
return json.Marshal(s)
}

func TestSQLValuer_Value(t *testing.T) {
tableTestValues := []struct {
name string
Expand Down Expand Up @@ -65,6 +81,61 @@ func TestSQLValuer_Value(t *testing.T) {
},
expected: "{\"test\"}",
},
{
name: "struct_implements_valuer",
value: structField{
V: map[string]interface{}{
"test": "test",
},
},
expected: []byte(`{"v":{"test":"test"}}`),
},
{
name: "valuer_pointer",
value: &structField{
V: map[string]interface{}{
"test": "test",
},
},
expected: []byte(`{"v":{"test":"test"}}`),
},
{
name: "valuer_nil_pointer",
value: (*structField)(nil),
expected: nil,
},
{
name: "empty_struct",
value: structField{},
expected: []byte(`{"v":null}`),
},
{
name: "empty_struct_pointer",
value: &structField{},
expected: []byte(`{"v":null}`),
},
{
name: "valuer_array_struct",
value: structValuerArray{
{
V: map[string]interface{}{
"test": "test",
},
},
},
expected: []byte(`[{"v":{"test":"test"}}]`),
},
{
name: "valuer_array_pointer",
value: &structValuerArray{
{
V: map[string]interface{}{
"test": "test",
},
},
},
expected: []byte(`[{"v":{"test":"test"}}]`),
},
}
for _, tt := range tableTestValues {
t.Run(tt.name, func(t *testing.T) {
Expand Down

0 comments on commit 2d8c873

Please sign in to comment.