-
Notifications
You must be signed in to change notification settings - Fork 0
/
result.go
86 lines (76 loc) · 2.17 KB
/
result.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
package ldb
import (
"database/sql"
"github.com/jmoiron/sqlx"
"github.com/pkg/errors"
"admini.dev/admini/app/lib/schema/field"
"admini.dev/admini/app/lib/schema/model"
"admini.dev/admini/app/loader/lpostgres/postgres"
"admini.dev/admini/app/result"
"admini.dev/admini/app/util"
)
func ParseResult(
title string, count int, q string, timing *result.Timing, rows *sqlx.Rows, enums model.Models, logger util.Logger,
) (*result.Result, error) {
fields, err := parseColumns(rows, enums, logger)
if err != nil {
return nil, errors.Wrap(err, "error processing columns")
}
return ParseResultFields(title, count, q, timing, fields, rows)
}
func ParseResultFields(title string, count int, q string, timing *result.Timing, fields field.Fields, rows *sqlx.Rows) (*result.Result, error) {
data, err := parseRows(rows)
if err != nil {
return nil, errors.Wrap(err, "error processing database rows")
}
if len(data) > 0 {
for _, row := range data {
for colIdx, x := range row {
if _, ok := x.([]uint8); ok {
f := fields[colIdx]
if row[colIdx] != nil {
b, _ := row[colIdx].([]uint8)
row[colIdx] = f.Type.From(string(b))
}
}
}
}
}
if count == 0 {
count = len(data)
}
ret := result.NewResult(title, count, q, fields, data, timing)
return ret, nil
}
func parseColumns(rows *sqlx.Rows, enums model.Models, logger util.Logger) (field.Fields, error) {
cts, err := rows.ColumnTypes()
if err != nil {
return nil, errors.Wrap(err, "unable to determine column types")
}
fs := make(field.Fields, 0, len(cts))
for _, ct := range cts {
f, err := fieldFor(ct, enums, logger)
if err != nil {
return nil, errors.Wrap(err, "unable to parse column type")
}
fs = append(fs, f)
}
return fs, nil
}
func parseRows(rows *sqlx.Rows) ([][]any, error) {
var data [][]any
for rows.Next() {
d, err := rows.SliceScan()
if err != nil {
return nil, errors.Wrap(err, "unable to scan results")
}
data = append(data, d)
}
return data, nil
}
func fieldFor(ct *sql.ColumnType, enums model.Models, logger util.Logger) (*field.Field, error) {
return &field.Field{
Key: ct.Name(),
Type: postgres.TypeForName(ct.DatabaseTypeName(), enums, logger),
}, nil
}