-
Notifications
You must be signed in to change notification settings - Fork 0
/
rowset.go
89 lines (78 loc) · 2.01 KB
/
rowset.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
77
78
79
80
81
82
83
84
85
86
87
88
89
package sqlt
import "database/sql"
// Rowset is plain two-dimensional data table
// containing data, obtained from SQL database
// in non-structured way (via interface{})
type Rowset struct {
ColumnNames []string
ColumnTypes []*sql.ColumnType
Rows [][]any
}
// Clear cleans up rowset contents.
func (r *Rowset) Clear() {
r.ColumnNames = nil
r.ColumnTypes = nil
r.Rows = nil
}
// Scan method fills rowset contents using data
// from given sql.Rows.
func (r *Rowset) Scan(rows *sql.Rows) error {
// Clearing current state
r.Clear()
return IterateScan(rows, func(names []string, types []*sql.ColumnType, row []any) {
if r.ColumnNames == nil {
// First row
r.ColumnNames = names
r.ColumnTypes = types
}
r.Rows = append(r.Rows, row)
})
}
// Size returns amount of rows.
func (r Rowset) Size() int {
return len(r.Rows)
}
// Each iterated over each row, passing it with
// corresponding metadata to callback function.
func (r Rowset) Each(f func([]string, []*sql.ColumnType, []any)) {
if f != nil {
for _, row := range r.Rows {
f(r.ColumnNames, r.ColumnTypes, row)
}
}
}
// SliceMap returns content of rowset as slice of maps.
func (r Rowset) SliceMap() (out []map[string]any) {
cnt := len(r.ColumnNames)
r.Each(func(names []string, _ []*sql.ColumnType, data []any) {
m := make(map[string]any, cnt)
for i := 0; i < cnt; i++ {
m[names[i]] = data[i]
}
out = append(out, m)
})
return
}
// MapValuesStd maps all values in rowset using standard conversion function.
func (r Rowset) MapValuesStd() Rowset {
return r.MapValues(StdConvert)
}
// MapValues maps all values in rowset using given conversion function.
func (r Rowset) MapValues(f func(src any, def *sql.ColumnType) any) Rowset {
if f == nil {
return r
}
out := Rowset{
ColumnNames: r.ColumnNames,
ColumnTypes: r.ColumnTypes,
}
cnt := len(r.ColumnNames)
for _, src := range r.Rows {
row := make([]any, cnt)
for i := 0; i < cnt; i++ {
row[i] = f(src[i], r.ColumnTypes[i])
}
out.Rows = append(out.Rows, row)
}
return out
}