-
Notifications
You must be signed in to change notification settings - Fork 72
/
driver.go
145 lines (124 loc) · 2.6 KB
/
driver.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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
package gosql
import (
"database/sql"
"database/sql/driver"
"fmt"
"io"
)
type Rows struct {
columns []ResultColumn
index uint64
rows [][]Cell
}
func (r *Rows) Columns() []string {
columns := []string{}
for _, c := range r.columns {
columns = append(columns, c.Name)
}
return columns
}
func (r *Rows) Close() error {
r.index = uint64(len(r.rows))
return nil
}
func (r *Rows) Next(dest []driver.Value) error {
if r.index >= uint64(len(r.rows)) {
return io.EOF
}
row := r.rows[r.index]
for idx, cell := range row {
typ := r.columns[idx].Type
switch typ {
case IntType:
i := cell.AsInt()
if i == nil {
dest[idx] = i
} else {
dest[idx] = *i
}
case TextType:
s := cell.AsText()
if s == nil {
dest[idx] = s
} else {
dest[idx] = *s
}
case BoolType:
b := cell.AsBool()
if b == nil {
dest[idx] = b
} else {
dest[idx] = b
}
}
}
r.index++
return nil
}
type Conn struct {
bkd Backend
}
func (dc *Conn) Query(query string, args []driver.Value) (driver.Rows, error) {
if len(args) > 0 {
// TODO: support parameterization
panic("Parameterization not supported")
}
parser := Parser{}
ast, err := parser.Parse(query)
if err != nil {
return nil, fmt.Errorf("Error while parsing: %s", err)
}
// NOTE: ignorning all but the first statement
stmt := ast.Statements[0]
switch stmt.Kind {
case CreateIndexKind:
err = dc.bkd.CreateIndex(stmt.CreateIndexStatement)
if err != nil {
return nil, fmt.Errorf("Error adding index on table: %s", err)
}
case CreateTableKind:
err = dc.bkd.CreateTable(stmt.CreateTableStatement)
if err != nil {
return nil, fmt.Errorf("Error creating table: %s", err)
}
case DropTableKind:
err = dc.bkd.DropTable(stmt.DropTableStatement)
if err != nil {
return nil, fmt.Errorf("Error dropping table: %s", err)
}
case InsertKind:
err = dc.bkd.Insert(stmt.InsertStatement)
if err != nil {
return nil, fmt.Errorf("Error inserting values: %s", err)
}
case SelectKind:
results, err := dc.bkd.Select(stmt.SelectStatement)
if err != nil {
return nil, err
}
return &Rows{
rows: results.Rows,
columns: results.Columns,
index: 0,
}, nil
}
return nil, nil
}
func (dc *Conn) Prepare(query string) (driver.Stmt, error) {
panic("Prepare not implemented")
}
func (dc *Conn) Begin() (driver.Tx, error) {
panic("Begin not implemented")
}
func (dc *Conn) Close() error {
return nil
}
type Driver struct {
bkd Backend
}
func (d *Driver) Open(name string) (driver.Conn, error) {
return &Conn{d.bkd}, nil
}
func init() {
sql.Register("postgres", &Driver{NewMemoryBackend()})
}