-
Notifications
You must be signed in to change notification settings - Fork 1
/
classic.go
111 lines (98 loc) · 2.5 KB
/
classic.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
// Copyright 2009 Peter H. Froehlich. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package db
import "os"
import "container/vector"
// ClassicConnections avoid the use of channels for results.
// They perform slightly better (at least while we wait for
// the Go runtime to get tuned more) but are less convenient
// to use because the for/range construct doesn't apply.
//
// ExecuteClassic() is similar to Execute() except that it
// returns a ClassicResultSet (see below).
type ClassicConnection interface {
Connection;
ExecuteClassic(stat Statement, parameters ...) (ClassicResultSet, os.Error);
}
// ClassicResultSets offer the same functionality as regular
// ResultSets but without the use of channels.
//
// More() returns true if there are more results to fetch.
//
// Fetch() produces the next result.
//
// Close() frees all resources associated with the result
// set. After a call to close, no operations can be applied
// anymore.
type ClassicResultSet interface {
More() bool;
Fetch() Result;
Close() os.Error;
}
// Fetch all remaining results. If we get no results at
// all, an error will be returned; otherwise it probably
// still occurred but will be hidden.
func ClassicFetchAll(rs ClassicResultSet) (data [][]interface{}, error os.Error) {
var v vector.Vector;
var d interface{}
var e os.Error;
for rs.More() {
r := rs.Fetch();
d = r.Data();
if d != nil {
v.Push(d)
}
e = r.Error();
if e != nil {
break
}
}
l := v.Len();
if l > 0 {
// TODO: how can this be done better?
data = make([][]interface{}, l);
for i := 0; i < l; i++ {
data[i] = v.At(i).([]interface{})
}
} else {
// no results at all, return the error
error = e
}
return;
}
// Fetch at most count results. If we get no results at
// all, an error will be returned; otherwise it probably
// still occurred but will be hidden.
func ClassicFetchMany(rs ClassicResultSet, count int) (data [][]interface{}, error os.Error) {
d := make([][]interface{}, count);
l := 0;
var e os.Error;
// grab at most count results
for l < count {
r := rs.Fetch();
d[l] = r.Data();
e = r.Error();
if e == nil {
l += 1
} else {
break
}
}
if l > 0 {
// there were results
if l < count {
// but fewer than expected, need fresh copy
data = make([][]interface{}, l);
for i := 0; i < l; i++ {
data[i] = d[i]
}
} else {
data = d
}
} else {
// no results at all, return the error
error = e
}
return;
}