-
Notifications
You must be signed in to change notification settings - Fork 4
/
dsimporter.go
108 lines (100 loc) · 2.35 KB
/
dsimporter.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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
package dataset
import (
"encoding/csv"
"fmt"
"io"
"strings"
)
type DSImport struct {
Comma string
Comment string
Overwrite bool
LazyQuotes bool
TrimLeadingSpace bool
}
// normalizeDelimiters handles the messy translation from a format string
// received as an option in the cli to something useful to pass to Join.
func normalizeDelimiter(s string) string {
if strings.Contains(s, `\n`) {
s = strings.Replace(s, `\n`, "\n", -1)
}
if strings.Contains(s, `\t`) {
s = strings.Replace(s, `\t`, "\t", -1)
}
return s
}
// normalizeDelimiterRune take a delimiter string and returns a single Rune
func normalizeDelimiterRune(s string) rune {
runes := []rune(normalizeDelimiter(s))
if len(runes) > 0 {
return runes[0]
}
return ','
}
func (app *DSImport) Run(in io.Reader, out io.Writer, eout io.Writer, cName string, keyColumn string) error {
c, err := Open(cName)
if err != nil {
return err
}
defer c.Close()
r := csv.NewReader(in)
if app.Comma != "" {
r.Comma = normalizeDelimiterRune(app.Comma)
}
if app.Comment != "" {
r.Comment = normalizeDelimiterRune(app.Comment)
}
r.LazyQuotes = app.LazyQuotes
r.TrimLeadingSpace = app.TrimLeadingSpace
i := 0
header := []string{}
keyIndex := 0
for {
row, err := r.Read()
if err == io.EOF {
break
}
if err != nil {
fmt.Fprintf(eout, "row %d: %s\n", i, err)
continue
}
if i == 0 {
header = row
for i, val := range header {
if strings.Compare(keyColumn, val) == 0 {
keyIndex = i
break
}
}
} else {
if keyIndex < len(row) {
key := row[keyIndex]
values := map[string]interface{}{}
for j, attr := range header {
if j < len(row) {
values[attr] = row[j]
} else {
fmt.Fprintf(eout, "row %d: can't find column (%d)\n", i, j)
}
}
if c.HasKey(key) {
if app.Overwrite {
if err := c.Update(key, values); err != nil {
fmt.Fprintf(eout, "row %d: failed to update %q in collection, %s\n", i, key, err)
}
} else {
fmt.Fprintf(eout, "row %d: key already exists in collection %q\n", i, key)
}
} else {
if err := c.Create(key, values); err != nil {
fmt.Fprintf(eout, "row %d: failed to create %q in collection, %s\n", i, key, err)
}
}
} else {
fmt.Fprintf(eout, "row %d: can't find key column\n", i)
}
}
i++
}
return nil
}