-
Notifications
You must be signed in to change notification settings - Fork 16
/
row.go
76 lines (68 loc) · 1.81 KB
/
row.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
package pgxpoolmock
import (
"fmt"
"reflect"
"github.com/jackc/pgproto3/v2"
)
func scanRow(row []interface{}, defs []pgproto3.FieldDescription, dest ...interface{}) error {
for i, col := range row {
if dest[i] == nil {
//behave compatible with pgx
continue
}
destVal := reflect.ValueOf(dest[i])
if destVal.Kind() != reflect.Ptr {
return fmt.Errorf("destination argument must be a pointer for column %s", defs[i].Name)
}
if col == nil {
dest[i] = nil
continue
}
val := reflect.ValueOf(col)
destKind := destVal.Elem().Kind()
if destKind == val.Kind() || destKind == reflect.Interface {
if destElem := destVal.Elem(); destElem.CanSet() {
destElem.Set(val)
} else {
return fmt.Errorf("cannot set destination value for column %s", string(defs[i].Name))
}
} else {
return fmt.Errorf("destination kind '%v' not supported for value kind '%v' of column '%s'",
destKind, val.Kind(), string(defs[i].Name))
}
}
return nil
}
// Row is a mocked row that can be returned from QueryRow
type Row struct {
defs []pgproto3.FieldDescription
row []interface{}
nextErr error
closeErr error
}
func (r *Row) Scan(dest ...interface{}) error {
if len(dest) != len(r.defs) {
return fmt.Errorf("incorrect argument number %d for columns %d", len(dest), len(r.defs))
}
err := scanRow(r.row, r.defs, dest...)
if err != nil {
return err
}
return r.nextErr
}
func NewRow(columns []string, values ...interface{}) *Row {
var coldefs []pgproto3.FieldDescription
for _, column := range columns {
coldefs = append(coldefs, pgproto3.FieldDescription{Name: []byte(column)})
}
return &Row{
defs: coldefs,
row: values,
}
}
// RowError allows to set an error
// which will be returned when the row is read
func (r *Row) RowError(row int, err error) *Row {
r.nextErr = err
return r
}