-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathframer.go
89 lines (85 loc) · 1.94 KB
/
framer.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 csvframer
import (
"encoding/csv"
"errors"
"fmt"
"io"
"strings"
"github.com/grafana/grafana-plugin-sdk-go/data"
"github.com/grafana/infinity-libs/lib/go/gframer"
)
type FramerOptions struct {
FrameName string
Columns []gframer.ColumnSelector
Delimiter string
SkipLinesWithError bool
Comment string
RelaxColumnCount bool
NoHeaders bool
}
func ToFrame(csvString string, options FramerOptions) (frame *data.Frame, err error) {
if strings.TrimSpace(csvString) == "" {
return frame, ErrEmptyCsv
}
r := csv.NewReader(strings.NewReader(csvString))
r.LazyQuotes = true
if options.Comment != "" {
r.Comment = rune(options.Comment[0])
}
if options.Delimiter != "" {
r.Comma = rune(options.Delimiter[0])
}
if options.RelaxColumnCount {
r.FieldsPerRecord = -1
}
parsedCSV := [][]string{}
for {
record, err := r.Read()
if err == io.EOF {
break
}
if err == nil {
parsedCSV = append(parsedCSV, record)
continue
}
if !options.SkipLinesWithError {
return frame, errors.Join(ErrReadingCsvResponse, fmt.Errorf("%w, %v", err, record))
}
}
out := []interface{}{}
header := []string{}
records := [][]string{}
if !options.NoHeaders {
header = parsedCSV[0]
for idx, hItem := range header {
for _, col := range options.Columns {
if col.Selector == hItem && col.Alias != "" {
header[idx] = col.Alias
}
}
}
records = parsedCSV[1:]
}
if options.NoHeaders {
records = parsedCSV
if len(records) > 0 {
for i := 0; i < len(records[0]); i++ {
header = append(header, fmt.Sprintf("%d", i+1))
}
}
}
for _, row := range records {
item := map[string]interface{}{}
for colId, col := range header {
if colId < len(row) {
item[col] = row[colId]
}
}
out = append(out, item)
}
framerOptions := gframer.FramerOptions{
FrameName: options.FrameName,
Columns: options.Columns,
}
return gframer.ToDataFrame(out, framerOptions)
}