Skip to content

Commit b38a83a

Browse files
committed
begin v1 refactoring
1 parent f05b992 commit b38a83a

18 files changed

+571
-441
lines changed

impl/arrays.go

Lines changed: 55 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,31 @@ package impl
22

33
import (
44
"database/sql"
5-
"database/sql/driver"
65
"reflect"
76

87
"github.com/lib/pq"
98
)
109

11-
func WrapForArray(a interface{}) interface {
12-
driver.Valuer
13-
sql.Scanner
14-
} {
10+
// func WrapForArray(a any) interface {
11+
// driver.Valuer
12+
// sql.Scanner
13+
// } {
14+
// return pq.Array(a)
15+
// }
16+
17+
func WrapForArrayScanning(a any) sql.Scanner {
1518
return pq.Array(a)
1619
}
1720

18-
func ShouldWrapForArray(v reflect.Value) bool {
21+
func ShouldWrapForArrayScanning(v reflect.Value) bool {
1922
t := v.Type()
23+
if t.Implements(typeOfSQLScanner) {
24+
return false
25+
}
26+
if t.Kind() == reflect.Ptr && !v.IsNil() {
27+
v = v.Elem()
28+
t = v.Type()
29+
}
2030
switch t.Kind() {
2131
case reflect.Slice:
2232
if t.Elem() == typeOfByte {
@@ -29,6 +39,45 @@ func ShouldWrapForArray(v reflect.Value) bool {
2939
return false
3040
}
3141

42+
// IsNonDriverValuerSliceOrArray returns true if passed type
43+
// does not implement driver.Valuer and is a slice or array,
44+
// or a pointer to a slice or array and in case of a slice
45+
// not of type []byte.
46+
func IsNonDriverValuerSliceOrArray(t reflect.Type) bool {
47+
if t == nil || t.Implements(typeOfDriverValuer) {
48+
return false
49+
}
50+
k := t.Kind()
51+
if k == reflect.Ptr {
52+
t = t.Elem()
53+
k = t.Kind()
54+
}
55+
return k == reflect.Slice && t != typeOfByteSlice || k == reflect.Array
56+
}
57+
58+
// func FormatArrays(args []any) []any {
59+
// var wrappedArgs []any
60+
// for i, arg := range args {
61+
// if ShouldFormatArray(arg) {
62+
// if wrappedArgs == nil {
63+
// // Allocate new slice for wrapped element
64+
// wrappedArgs = make([]any, len(args))
65+
// // Copy previous elements
66+
// for h := 0; h < i; h++ {
67+
// wrappedArgs[h] = args[h]
68+
// }
69+
// }
70+
// wrappedArgs[i], _ = pq.Array(arg).Value()
71+
// } else if wrappedArgs != nil {
72+
// wrappedArgs[i] = arg
73+
// }
74+
// }
75+
// if wrappedArgs != nil {
76+
// return wrappedArgs
77+
// }
78+
// return args
79+
// }
80+
3281
// type ArrayScanner struct {
3382
// Dest reflect.Value
3483
// }

impl/arrays_test.go

Lines changed: 59 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,17 @@ package impl
22

33
import (
44
"database/sql"
5+
"database/sql/driver"
56
"encoding/json"
67
"reflect"
78
"testing"
89

910
"github.com/domonda/go-types/nullable"
11+
"github.com/lib/pq"
12+
"github.com/stretchr/testify/assert"
1013
)
1114

12-
func TestShouldWrapForArray(t *testing.T) {
15+
func TestShouldWrapForArrayScanning(t *testing.T) {
1316
tests := []struct {
1417
v reflect.Value
1518
want bool
@@ -21,14 +24,66 @@ func TestShouldWrapForArray(t *testing.T) {
2124
{v: reflect.ValueOf(json.RawMessage([]byte("null"))), want: false},
2225
{v: reflect.ValueOf(nullable.JSON([]byte("null"))), want: false},
2326
{v: reflect.ValueOf(new(sql.NullInt64)).Elem(), want: false},
27+
{v: reflect.ValueOf(WrapForArrayScanning([]int{0, 1})), want: false},
2428

2529
{v: reflect.ValueOf(new([3]string)).Elem(), want: true},
2630
{v: reflect.ValueOf(new([]string)).Elem(), want: true},
2731
{v: reflect.ValueOf(new([]sql.NullString)).Elem(), want: true},
2832
}
2933
for _, tt := range tests {
30-
if got := ShouldWrapForArray(tt.v); got != tt.want {
31-
t.Errorf("shouldWrapArray() = %v, want %v", got, tt.want)
32-
}
34+
got := ShouldWrapForArrayScanning(tt.v)
35+
assert.Equal(t, tt.want, got)
3336
}
3437
}
38+
39+
func TestIsNonDriverValuerSliceOrArray(t *testing.T) {
40+
tests := []struct {
41+
t reflect.Type
42+
want bool
43+
}{
44+
{t: reflect.TypeOf(nil), want: false},
45+
{t: reflect.TypeOf(0), want: false},
46+
{t: reflect.TypeOf(new(int)), want: false},
47+
{t: reflect.TypeOf("string"), want: false},
48+
{t: reflect.TypeOf([]byte("string")), want: false},
49+
{t: reflect.TypeOf(new([]byte)), want: false},
50+
{t: reflect.TypeOf(pq.BoolArray{true}), want: false},
51+
{t: reflect.TypeOf(new(pq.BoolArray)), want: false},
52+
{t: reflect.TypeOf(new(*[]int)), want: false}, // pointer to a pointer to a slice
53+
{t: reflect.TypeOf((*driver.Valuer)(nil)), want: false},
54+
{t: reflect.TypeOf((*driver.Valuer)(nil)).Elem(), want: false},
55+
56+
{t: reflect.TypeOf([3]int{1, 2, 3}), want: true},
57+
{t: reflect.TypeOf((*[3]int)(nil)), want: true},
58+
{t: reflect.TypeOf([]int{1, 2, 3}), want: true},
59+
{t: reflect.TypeOf((*[]int)(nil)), want: true},
60+
{t: reflect.TypeOf((*[][]byte)(nil)), want: true},
61+
}
62+
for _, tt := range tests {
63+
got := IsNonDriverValuerSliceOrArray(tt.t)
64+
assert.Equalf(t, tt.want, got, "IsNonDriverValuerSliceOrArray(%s)", tt.t)
65+
}
66+
}
67+
68+
// func TestWrapArgsForArrays(t *testing.T) {
69+
// tests := []struct {
70+
// args []any
71+
// want []any
72+
// }{
73+
// {args: nil, want: nil},
74+
// {args: []any{}, want: []any{}},
75+
// {args: []any{0}, want: []any{0}},
76+
// {args: []any{nil}, want: []any{nil}},
77+
// {args: []any{new(int)}, want: []any{new(int)}},
78+
// {args: []any{0, []int{0, 1}, "string"}, want: []any{0, wrapArgForArray([]int{0, 1}), "string"}},
79+
// {args: []any{wrapArgForArray([]int{0, 1})}, want: []any{wrapArgForArray([]int{0, 1})}},
80+
// {args: []any{[]byte("don't wrap []byte")}, want: []any{[]byte("don't wrap []byte")}},
81+
// {args: []any{pq.BoolArray{true}}, want: []any{pq.BoolArray{true}}},
82+
// {args: []any{[3]int{1, 2, 3}}, want: []any{wrapArgForArray([3]int{1, 2, 3})}},
83+
// {args: []any{wrapArgForArray([3]int{1, 2, 3})}, want: []any{wrapArgForArray([3]int{1, 2, 3})}},
84+
// }
85+
// for _, tt := range tests {
86+
// got := WrapArgsForArrays(tt.args)
87+
// assert.Equal(t, tt.want, got)
88+
// }
89+
// }

impl/connection.go

Lines changed: 0 additions & 197 deletions
This file was deleted.

impl/exec.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package impl
2+
3+
import (
4+
"context"
5+
"database/sql"
6+
)
7+
8+
type Execer interface {
9+
ExecContext(ctx context.Context, query string, args ...any) (sql.Result, error)
10+
}
11+
12+
func Exec(ctx context.Context, conn Execer, argFmt, query string, args []any) error {
13+
// args = WrapArgsForArrays(args)
14+
_, err := conn.ExecContext(ctx, query, args...)
15+
return WrapNonNilErrorWithQuery(err, query, argFmt, args)
16+
}

0 commit comments

Comments
 (0)