-
Notifications
You must be signed in to change notification settings - Fork 2
/
table.go
96 lines (77 loc) · 2.11 KB
/
table.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
package csvquery
import (
"encoding/csv"
"fmt"
"os"
"gopkg.in/src-d/go-mysql-server.v0/sql"
)
// Table is a SQL table that will read CSV rows as SQL rows.
type Table struct {
name string
file string
schema sql.Schema
}
// NewTable creates a new table given a name and filename.
func NewTable(name, file string) (*Table, error) {
f, err := os.Open(file)
if err != nil {
return nil, err
}
defer f.Close()
csvr := csv.NewReader(f)
header, err := csvr.Read()
if err != nil {
return nil, fmt.Errorf("csvquery: unable to read header of table %s: %s", name, err)
}
t := &Table{name: name, file: file}
t.schema = make(sql.Schema, len(header))
for i, col := range header {
t.schema[i] = &sql.Column{
Type: sql.Text,
Nullable: false,
Source: name,
Name: col,
Default: "",
}
}
return t, nil
}
// Children implements the sql.Table interface.
func (Table) Children() []sql.Node { return nil }
// Name returns the table name.
func (t Table) Name() string { return t.name }
// Resolved implements the sql.Table interface.
func (t Table) Resolved() bool { return true }
// RowIter returns an iterator over all table rows.
func (t Table) RowIter(ctx *sql.Context) (sql.RowIter, error) {
f, err := os.Open(t.file)
if err != nil {
return nil, err
}
r := csv.NewReader(f)
_, err = r.Read()
if err != nil {
return nil, fmt.Errorf("csvquery: error reading header of table %q: %s", t.name, err)
}
return &csvRowIter{closer: f, r: r}, nil
}
// Schema returns the table schema.
func (t Table) Schema() sql.Schema { return t.schema }
func (t Table) String() string {
var columns = make([]string, len(t.schema))
for i, col := range t.schema {
columns[i] = col.Name
}
tp := sql.NewTreePrinter()
_ = tp.WriteNode("CSVTable(%s)", t.name)
_ = tp.WriteChildren(columns...)
return tp.String()
}
// TransformExpressionsUp implements the sql.Table interface.
func (t Table) TransformExpressionsUp(sql.TransformExprFunc) (sql.Node, error) {
return t, nil
}
// TransformUp implements the sql.Table interface.
func (t Table) TransformUp(fn sql.TransformNodeFunc) (sql.Node, error) {
return fn(t)
}