-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcsv.go
More file actions
74 lines (59 loc) · 1.42 KB
/
Copy pathcsv.go
File metadata and controls
74 lines (59 loc) · 1.42 KB
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
package csv2opensearch
import (
"context"
"encoding/csv"
"errors"
"fmt"
"strings"
)
// Reader reads the CSV and returns JSON stringified versions for each record.
type Reader struct {
reader *csv.Reader
headers []string
}
// NewReader returns a new Reader that maps CSV records to JSONs.
func NewReader(reader *csv.Reader) *Reader {
return &Reader{reader: reader}
}
// Read returns a JSON serialized record from the CSV file and then advances the offset.
func (r *Reader) Read(_ context.Context) (string, error) {
if len(r.headers) == 0 { // lazy load headers
h, err := r.reader.Read()
if err != nil {
return "", fmt.Errorf("failed to read CSV headers: %v", err)
}
if len(h) == 0 {
return "", errors.New("missing headers")
}
r.headers = h
}
row, err := r.reader.Read()
if err != nil {
return "", fmt.Errorf("failed to read row: %w", err)
}
if len(row) == 0 {
return "", nil
}
rs := r.jsonify(row)
return rs, nil
}
func (r *Reader) jsonify(row []string) string {
b := strings.Builder{}
b.WriteString("{")
for i := range r.headers {
// Set the key
fmt.Fprintf(&b, "\"%s\":", r.headers[i])
// Sanitize the value
v := row[i]
v = strings.ReplaceAll(v, "\n", "")
v = strings.ReplaceAll(v, "\"", "")
v = strings.ReplaceAll(v, "\\", "")
// Set the value
fmt.Fprintf(&b, "\"%s\"", v)
if i < len(r.headers)-1 {
b.WriteString(",")
}
}
b.WriteString("}")
return b.String()
}