-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathdriver.go
133 lines (106 loc) · 4.06 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
// Copyright 2014 Daniel Theophanes.
// Use of this source code is governed by a zlib-style
// license that can be found in the LICENSE file.
package rdb
import (
"context"
"time"
"github.com/kardianos/rdb/semver"
)
// TODO: Add states for transactions.
type DriverConnStatus byte
const (
StatusDisconnected DriverConnStatus = iota
StatusReady
StatusQuery
StatusResultDone
StatusBulkCopy
)
type DriverOption struct {
Name string
Description string
Parse func(input string) (interface{}, error)
}
type DriverSupport struct {
// PreparePerConn is set to true if prepared statements are local to
// each connection. Set to false if prepared statements are global.
PreparePerConn bool
NamedParameter bool // Supports named parameters.
FluidType bool // Like SQLite.
MultipleResult bool // Supports returning multiple result sets.
SecureConnection bool // Supports a secure connection.
BulkInsert bool // Supports a fast bulk insert method.
Notification bool // Supports driver notifications.
UserDataTypes bool // Handles user supplied data types.
}
type DriverInfo struct {
Options []*DriverOption
DriverSupport
}
type ConnectionInfo struct {
Server, Protocol *semver.Version
}
// Driver is implemented by the database driver.
type Driver interface {
// Open a database. An actual connection does not need to be established
// at this time.
Open(c *Config) (DriverConn, error)
// Return information about the database drivers capabilities.
// Should not reflect any actual server any connections to it.
DriverInfo() *DriverInfo
// Return the command to send a NOOP to the server.
PingCommand() *Command
}
// DriverValue used by the driver to report a field value.
// If a long field, such as a long byte array, it can be chunked
// directly into destination. If the driver is copying from a common
// buffer then the MustCopy field must be true so it is known it must be
// copied out.
type DriverValue struct {
Value interface{}
Null bool
MustCopy bool // If the Value is a common driver buffer, set to true.
More bool // True if more data is expected for the field.
Chunked bool // True if data is sent in chunks.
}
// Conn represents a database driver connection.
type DriverConn interface {
// Close the underlying connection to the database.
Close()
Available() bool // True if not currently in a connection pool.
SetAvailable(available bool) // Set when adding or removing from connection pool.
// Return version information regarding the currently connected server.
ConnectionInfo() *ConnectionInfo
// Time connection was opened.
Opened() time.Time
// Read the next row from the connection. For each field in the row
// call the Valuer.WriteField(...) method. Propagate the reportRow field.
Scan() error
// NextResult advances to the next result if there are multiple results.
NextResult() (more bool, err error)
// NextQuery stops the active query and gets the connection for the next one.
NextQuery() (err error)
// The isolation level is set by the command.
// Should return "PreparedTokenNotValid" if the preparedToken was not recognized.
Query(ctx context.Context, cmd *Command, params []Param, preparedToken interface{}, val DriverValuer) error
Status() DriverConnStatus
// Reset the connection to be ready for next connection.
Reset(config *Config) error
// Happy Path:
// * Interface wants to prepare command, but doesn't have token.
// * Interface sends a conn Prepare requests and gets a token.
// * Interface uses token in query.
// * After some use, Interface unprepares command.
//
// Re-prepare Path:
// * Interface has a token and attempts to use it in query.
// * Query returns "the token is not valid" error (server restart?).
// * Interface attempts to re-prepare query.
// * Interface uses new token in Query. If that fails again, it should fail the query.
Prepare(*Command) (preparedToken interface{}, err error)
Unprepare(preparedToken interface{}) (err error)
Begin(iso IsolationLevel) error
Rollback(savepoint string) error
Commit() error
SavePoint(name string) error
}