1 // Copyright 2011 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 // Package driver defines interfaces to be implemented by database
6 // drivers as used by package sql.
8 // Most code should use package sql.
13 // A driver Value is a value that drivers must be able to handle.
14 // A Value is either nil or an instance of one of these types:
20 // string [*] everywhere except from Rows.Next.
22 type Value interface{}
24 // Driver is the interface that must be implemented by a database
26 type Driver interface {
27 // Open returns a new connection to the database.
28 // The name is a string in a driver-specific format.
30 // Open may return a cached connection (one previously
31 // closed), but doing so is unnecessary; the sql package
32 // maintains a pool of idle connections for efficient re-use.
34 // The returned connection is only used by one goroutine at a
36 Open(name string) (Conn, error)
39 // ErrSkip may be returned by some optional interfaces' methods to
40 // indicate at runtime that the fast path is unavailable and the sql
41 // package should continue as if the optional interface was not
42 // implemented. ErrSkip is only supported where explicitly
44 var ErrSkip = errors.New("driver: skip fast-path; continue as if unimplemented")
46 // Execer is an optional interface that may be implemented by a Conn.
48 // If a Conn does not implement Execer, the db package's DB.Exec will
49 // first prepare a query, execute the statement, and then close the
52 // Exec may return ErrSkip.
53 type Execer interface {
54 Exec(query string, args []Value) (Result, error)
57 // Conn is a connection to a database. It is not used concurrently
58 // by multiple goroutines.
60 // Conn is assumed to be stateful.
62 // Prepare returns a prepared statement, bound to this connection.
63 Prepare(query string) (Stmt, error)
65 // Close invalidates and potentially stops any current
66 // prepared statements and transactions, marking this
67 // connection as no longer in use.
69 // Because the sql package maintains a free pool of
70 // connections and only calls Close when there's a surplus of
71 // idle connections, it shouldn't be necessary for drivers to
72 // do their own connection caching.
75 // Begin starts and returns a new transaction.
79 // Result is the result of a query execution.
80 type Result interface {
81 // LastInsertId returns the database's auto-generated ID
82 // after, for example, an INSERT into a table with primary
84 LastInsertId() (int64, error)
86 // RowsAffected returns the number of rows affected by the
88 RowsAffected() (int64, error)
91 // Stmt is a prepared statement. It is bound to a Conn and not
92 // used by multiple goroutines concurrently.
94 // Close closes the statement.
96 // Closing a statement should not interrupt any outstanding
97 // query created from that statement. That is, the following
98 // order of operations is valid:
100 // * create a driver statement
101 // * call Query on statement, returning Rows
102 // * close the statement
105 // If closing a statement invalidates currently-running
106 // queries, the final step above will incorrectly fail.
108 // TODO(bradfitz): possibly remove the restriction above, if
109 // enough driver authors object and find it complicates their
110 // code too much. The sql package could be smarter about
111 // refcounting the statement and closing it at the appropriate
115 // NumInput returns the number of placeholder parameters.
117 // If NumInput returns >= 0, the sql package will sanity check
118 // argument counts from callers and return errors to the caller
119 // before the statement's Exec or Query methods are called.
121 // NumInput may also return -1, if the driver doesn't know
122 // its number of placeholders. In that case, the sql package
123 // will not sanity check Exec or Query argument counts.
126 // Exec executes a query that doesn't return rows, such
127 // as an INSERT or UPDATE.
128 Exec(args []Value) (Result, error)
130 // Exec executes a query that may return rows, such as a
132 Query(args []Value) (Rows, error)
135 // ColumnConverter may be optionally implemented by Stmt if the
136 // the statement is aware of its own columns' types and can
137 // convert from any type to a driver Value.
138 type ColumnConverter interface {
139 // ColumnConverter returns a ValueConverter for the provided
140 // column index. If the type of a specific column isn't known
141 // or shouldn't be handled specially, DefaultValueConverter
143 ColumnConverter(idx int) ValueConverter
146 // Rows is an iterator over an executed query's results.
147 type Rows interface {
148 // Columns returns the names of the columns. The number of
149 // columns of the result is inferred from the length of the
150 // slice. If a particular column name isn't known, an empty
151 // string should be returned for that entry.
154 // Close closes the rows iterator.
157 // Next is called to populate the next row of data into
158 // the provided slice. The provided slice will be the same
159 // size as the Columns() are wide.
161 // The dest slice may be populated only with
162 // a driver Value type, but excluding string.
163 // All string values must be converted to []byte.
165 // Next should return io.EOF when there are no more rows.
166 Next(dest []Value) error
169 // Tx is a transaction.
175 // RowsAffected implements Result for an INSERT or UPDATE operation
176 // which mutates a number of rows.
177 type RowsAffected int64
179 var _ Result = RowsAffected(0)
181 func (RowsAffected) LastInsertId() (int64, error) {
182 return 0, errors.New("no LastInsertId available")
185 func (v RowsAffected) RowsAffected() (int64, error) {
189 // ResultNoRows is a pre-defined Result for drivers to return when a DDL
190 // command (such as a CREATE TABLE) succeeds. It returns an error for both
191 // LastInsertId and RowsAffected.
192 var ResultNoRows noRows
196 var _ Result = noRows{}
198 func (noRows) LastInsertId() (int64, error) {
199 return 0, errors.New("no LastInsertId available after DDL statement")
202 func (noRows) RowsAffected() (int64, error) {
203 return 0, errors.New("no RowsAffected available after DDL statement")