forked from fajran/go-monetdb
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrows.go
125 lines (101 loc) · 2.02 KB
/
rows.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
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package monetdb
import (
"database/sql/driver"
"fmt"
"io"
)
type Rows struct {
stmt *Stmt
active bool
queryId int
err error
rowNum int
offset int
lastRowId int
rowCount int
rows [][]driver.Value
description []description
columns []string
}
func newRows(s *Stmt) *Rows {
return &Rows{
stmt: s,
active: true,
err: nil,
columns: nil,
rowNum: 0,
}
}
func (r *Rows) Columns() []string {
if r.columns == nil {
r.columns = make([]string, len(r.description))
for i, d := range r.description {
r.columns[i] = d.columnName
}
}
return r.columns
}
func (r *Rows) Close() error {
r.active = false
return nil
}
var cnt = 0
func (r *Rows) Next(dest []driver.Value) error {
if !r.active {
return fmt.Errorf("Rows closed")
}
if r.queryId == -1 {
return fmt.Errorf("Query didn't result in a resultset")
}
if r.rowNum >= r.rowCount || len(r.rows) == 0 {
return io.EOF
}
if r.rowNum >= r.offset+len(r.rows) {
err := r.fetchNext()
if err != nil {
return err
}
}
for i, v := range r.rows[r.rowNum-r.offset] {
if i >= len(dest) {
return fmt.Errorf("received more rows than expected: got %d, expected %d", i, len(dest))
}
if vv, ok := v.(string); ok {
dest[i] = []byte(vv)
} else {
dest[i] = v
}
}
r.rowNum += 1
return nil
}
const (
c_ARRAY_SIZE = 100
)
func min(a, b int) int {
if a < b {
return a
} else {
return b
}
}
func (r *Rows) fetchNext() error {
if r.rowNum >= r.rowCount {
return io.EOF
}
r.offset += len(r.rows)
end := min(r.rowCount, r.rowNum+c_ARRAY_SIZE)
amount := end - r.offset
cmd := fmt.Sprintf("Xexport %d %d %d", r.queryId, r.offset, amount)
res, err := r.stmt.conn.cmd(cmd)
if err != nil {
return err
}
r.stmt.storeResult(res)
r.rows = r.stmt.rows
r.description = r.stmt.description
return nil
}