Source file src/database/sql/driver/driver.go

     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.
     4  
     5  // Package driver defines interfaces to be implemented by database
     6  // drivers as used by package sql.
     7  //
     8  // Most code should use the [database/sql] package.
     9  //
    10  // The driver interface has evolved over time. Drivers should implement
    11  // [Connector] and [DriverContext] interfaces.
    12  // The Connector.Connect and Driver.Open methods should never return [ErrBadConn].
    13  // [ErrBadConn] should only be returned from [Validator], [SessionResetter], or
    14  // a query method if the connection is already in an invalid (e.g. closed) state.
    15  //
    16  // All [Conn] implementations should implement the following interfaces:
    17  // [Pinger], [SessionResetter], and [Validator].
    18  //
    19  // If named parameters or context are supported, the driver's [Conn] should implement:
    20  // [ExecerContext], [QueryerContext], [ConnPrepareContext], and [ConnBeginTx].
    21  //
    22  // To support custom data types, implement [NamedValueChecker]. [NamedValueChecker]
    23  // also allows queries to accept per-query options as a parameter by returning
    24  // [ErrRemoveArgument] from CheckNamedValue.
    25  //
    26  // If multiple result sets are supported, [Rows] should implement [RowsNextResultSet].
    27  // If the driver knows how to describe the types present in the returned result
    28  // it should implement the following interfaces: [RowsColumnTypeScanType],
    29  // [RowsColumnTypeDatabaseTypeName], [RowsColumnTypeLength], [RowsColumnTypeNullable],
    30  // and [RowsColumnTypePrecisionScale]. A given row value may also return a [Rows]
    31  // type, which may represent a database cursor value.
    32  //
    33  // If a [Conn] implements [Validator], then the IsValid method is called
    34  // before returning the connection to the connection pool. If an entry in the
    35  // connection pool implements [SessionResetter], then ResetSession
    36  // is called before reusing the connection for another query. If a connection is
    37  // never returned to the connection pool but is immediately reused, then
    38  // ResetSession is called prior to reuse but IsValid is not called.
    39  package driver
    40  
    41  import (
    42  	"context"
    43  	"errors"
    44  	"reflect"
    45  )
    46  
    47  // Value is a value that drivers must be able to handle.
    48  // It is either nil, a type handled by a database driver's [NamedValueChecker]
    49  // interface, or an instance of one of these types:
    50  //
    51  //	int64
    52  //	float64
    53  //	bool
    54  //	[]byte
    55  //	string
    56  //	time.Time
    57  //
    58  // If the driver supports cursors, a returned Value may also implement the [Rows] interface
    59  // in this package. This is used, for example, when a user selects a cursor
    60  // such as "select cursor(select * from my_table) from dual". If the [Rows]
    61  // from the select is closed, the cursor [Rows] will also be closed.
    62  type Value any
    63  
    64  // NamedValue holds both the value name and value.
    65  type NamedValue struct {
    66  	// If the Name is not empty it should be used for the parameter identifier and
    67  	// not the ordinal position.
    68  	//
    69  	// Name will not have a symbol prefix.
    70  	Name string
    71  
    72  	// Ordinal position of the parameter starting from one and is always set.
    73  	Ordinal int
    74  
    75  	// Value is the parameter value.
    76  	Value Value
    77  }
    78  
    79  // Driver is the interface that must be implemented by a database
    80  // driver.
    81  //
    82  // Database drivers may implement [DriverContext] for access
    83  // to contexts and to parse the name only once for a pool of connections,
    84  // instead of once per connection.
    85  type Driver interface {
    86  	// Open returns a new connection to the database.
    87  	// The name is a string in a driver-specific format.
    88  	//
    89  	// Open may return a cached connection (one previously
    90  	// closed), but doing so is unnecessary; the sql package
    91  	// maintains a pool of idle connections for efficient re-use.
    92  	//
    93  	// The returned connection is only used by one goroutine at a
    94  	// time.
    95  	Open(name string) (Conn, error)
    96  }
    97  
    98  // If a [Driver] implements DriverContext, then [database/sql.DB] will call
    99  // OpenConnector to obtain a [Connector] and then invoke
   100  // that [Connector]'s Connect method to obtain each needed connection,
   101  // instead of invoking the [Driver]'s Open method for each connection.
   102  // The two-step sequence allows drivers to parse the name just once
   103  // and also provides access to per-[Conn] contexts.
   104  type DriverContext interface {
   105  	// OpenConnector must parse the name in the same format that Driver.Open
   106  	// parses the name parameter.
   107  	OpenConnector(name string) (Connector, error)
   108  }
   109  
   110  // A Connector represents a driver in a fixed configuration
   111  // and can create any number of equivalent Conns for use
   112  // by multiple goroutines.
   113  //
   114  // A Connector can be passed to [database/sql.OpenDB], to allow drivers
   115  // to implement their own [database/sql.DB] constructors, or returned by
   116  // [DriverContext]'s OpenConnector method, to allow drivers
   117  // access to context and to avoid repeated parsing of driver
   118  // configuration.
   119  //
   120  // If a Connector implements [io.Closer], the [database/sql.DB.Close]
   121  // method will call the Close method and return error (if any).
   122  type Connector interface {
   123  	// Connect returns a connection to the database.
   124  	// Connect may return a cached connection (one previously
   125  	// closed), but doing so is unnecessary; the sql package
   126  	// maintains a pool of idle connections for efficient re-use.
   127  	//
   128  	// The provided context.Context is for dialing purposes only
   129  	// (see net.DialContext) and should not be stored or used for
   130  	// other purposes. A default timeout should still be used
   131  	// when dialing as a connection pool may call Connect
   132  	// asynchronously to any query.
   133  	//
   134  	// The returned connection is only used by one goroutine at a
   135  	// time.
   136  	Connect(context.Context) (Conn, error)
   137  
   138  	// Driver returns the underlying Driver of the Connector,
   139  	// mainly to maintain compatibility with the Driver method
   140  	// on sql.DB.
   141  	Driver() Driver
   142  }
   143  
   144  // ErrSkip may be returned by some optional interfaces' methods to
   145  // indicate at runtime that the fast path is unavailable and the sql
   146  // package should continue as if the optional interface was not
   147  // implemented. ErrSkip is only supported where explicitly
   148  // documented.
   149  var ErrSkip = errors.New("driver: skip fast-path; continue as if unimplemented")
   150  
   151  // ErrBadConn should be returned by a driver to signal to the [database/sql]
   152  // package that a driver.[Conn] is in a bad state (such as the server
   153  // having earlier closed the connection) and the [database/sql] package should
   154  // retry on a new connection.
   155  //
   156  // To prevent duplicate operations, ErrBadConn should NOT be returned
   157  // if there's a possibility that the database server might have
   158  // performed the operation. Even if the server sends back an error,
   159  // you shouldn't return ErrBadConn.
   160  //
   161  // Errors will be checked using [errors.Is]. An error may
   162  // wrap ErrBadConn or implement the Is(error) bool method.
   163  var ErrBadConn = errors.New("driver: bad connection")
   164  
   165  // Pinger is an optional interface that may be implemented by a [Conn].
   166  //
   167  // If a [Conn] does not implement Pinger, the [database/sql.DB.Ping] and
   168  // [database/sql.DB.PingContext] will check if there is at least one [Conn] available.
   169  //
   170  // If Conn.Ping returns [ErrBadConn], [database/sql.DB.Ping] and [database/sql.DB.PingContext] will remove
   171  // the [Conn] from pool.
   172  type Pinger interface {
   173  	Ping(ctx context.Context) error
   174  }
   175  
   176  // Execer is an optional interface that may be implemented by a [Conn].
   177  //
   178  // If a [Conn] implements neither [ExecerContext] nor [Execer],
   179  // the [database/sql.DB.Exec] will first prepare a query, execute the statement,
   180  // and then close the statement.
   181  //
   182  // Exec may return [ErrSkip].
   183  //
   184  // Deprecated: Drivers should implement [ExecerContext] instead.
   185  type Execer interface {
   186  	Exec(query string, args []Value) (Result, error)
   187  }
   188  
   189  // ExecerContext is an optional interface that may be implemented by a [Conn].
   190  //
   191  // If a [Conn] does not implement [ExecerContext], the [database/sql.DB.Exec]
   192  // will fall back to [Execer]; if the Conn does not implement Execer either,
   193  // [database/sql.DB.Exec] will first prepare a query, execute the statement, and then
   194  // close the statement.
   195  //
   196  // ExecContext may return [ErrSkip].
   197  //
   198  // ExecContext must honor the context timeout and return when the context is canceled.
   199  type ExecerContext interface {
   200  	ExecContext(ctx context.Context, query string, args []NamedValue) (Result, error)
   201  }
   202  
   203  // Queryer is an optional interface that may be implemented by a [Conn].
   204  //
   205  // If a [Conn] implements neither [QueryerContext] nor [Queryer],
   206  // the [database/sql.DB.Query] will first prepare a query, execute the statement,
   207  // and then close the statement.
   208  //
   209  // Query may return [ErrSkip].
   210  //
   211  // Deprecated: Drivers should implement [QueryerContext] instead.
   212  type Queryer interface {
   213  	Query(query string, args []Value) (Rows, error)
   214  }
   215  
   216  // QueryerContext is an optional interface that may be implemented by a [Conn].
   217  //
   218  // If a [Conn] does not implement QueryerContext, the [database/sql.DB.Query]
   219  // will fall back to [Queryer]; if the [Conn] does not implement [Queryer] either,
   220  // [database/sql.DB.Query] will first prepare a query, execute the statement, and then
   221  // close the statement.
   222  //
   223  // QueryContext may return [ErrSkip].
   224  //
   225  // QueryContext must honor the context timeout and return when the context is canceled.
   226  type QueryerContext interface {
   227  	QueryContext(ctx context.Context, query string, args []NamedValue) (Rows, error)
   228  }
   229  
   230  // Conn is a connection to a database. It is not used concurrently
   231  // by multiple goroutines.
   232  //
   233  // Conn is assumed to be stateful.
   234  type Conn interface {
   235  	// Prepare returns a prepared statement, bound to this connection.
   236  	Prepare(query string) (Stmt, error)
   237  
   238  	// Close invalidates and potentially stops any current
   239  	// prepared statements and transactions, marking this
   240  	// connection as no longer in use.
   241  	//
   242  	// Because the sql package maintains a free pool of
   243  	// connections and only calls Close when there's a surplus of
   244  	// idle connections, it shouldn't be necessary for drivers to
   245  	// do their own connection caching.
   246  	//
   247  	// Drivers must ensure all network calls made by Close
   248  	// do not block indefinitely (e.g. apply a timeout).
   249  	Close() error
   250  
   251  	// Begin starts and returns a new transaction.
   252  	//
   253  	// Deprecated: Drivers should implement ConnBeginTx instead (or additionally).
   254  	Begin() (Tx, error)
   255  }
   256  
   257  // ConnPrepareContext enhances the [Conn] interface with context.
   258  type ConnPrepareContext interface {
   259  	// PrepareContext returns a prepared statement, bound to this connection.
   260  	// context is for the preparation of the statement,
   261  	// it must not store the context within the statement itself.
   262  	PrepareContext(ctx context.Context, query string) (Stmt, error)
   263  }
   264  
   265  // IsolationLevel is the transaction isolation level stored in [TxOptions].
   266  //
   267  // This type should be considered identical to [database/sql.IsolationLevel] along
   268  // with any values defined on it.
   269  type IsolationLevel int
   270  
   271  // TxOptions holds the transaction options.
   272  //
   273  // This type should be considered identical to [database/sql.TxOptions].
   274  type TxOptions struct {
   275  	Isolation IsolationLevel
   276  	ReadOnly  bool
   277  }
   278  
   279  // ConnBeginTx enhances the [Conn] interface with context and [TxOptions].
   280  type ConnBeginTx interface {
   281  	// BeginTx starts and returns a new transaction.
   282  	// If the context is canceled by the user the sql package will
   283  	// call Tx.Rollback before discarding and closing the connection.
   284  	//
   285  	// This must check opts.Isolation to determine if there is a set
   286  	// isolation level. If the driver does not support a non-default
   287  	// level and one is set or if there is a non-default isolation level
   288  	// that is not supported, an error must be returned.
   289  	//
   290  	// This must also check opts.ReadOnly to determine if the read-only
   291  	// value is true to either set the read-only transaction property if supported
   292  	// or return an error if it is not supported.
   293  	BeginTx(ctx context.Context, opts TxOptions) (Tx, error)
   294  }
   295  
   296  // SessionResetter may be implemented by [Conn] to allow drivers to reset the
   297  // session state associated with the connection and to signal a bad connection.
   298  type SessionResetter interface {
   299  	// ResetSession is called prior to executing a query on the connection
   300  	// if the connection has been used before. If the driver returns ErrBadConn
   301  	// the connection is discarded.
   302  	ResetSession(ctx context.Context) error
   303  }
   304  
   305  // Validator may be implemented by [Conn] to allow drivers to
   306  // signal if a connection is valid or if it should be discarded.
   307  //
   308  // If implemented, drivers may return the underlying error from queries,
   309  // even if the connection should be discarded by the connection pool.
   310  type Validator interface {
   311  	// IsValid is called prior to placing the connection into the
   312  	// connection pool. The connection will be discarded if false is returned.
   313  	IsValid() bool
   314  }
   315  
   316  // Result is the result of a query execution.
   317  type Result interface {
   318  	// LastInsertId returns the database's auto-generated ID
   319  	// after, for example, an INSERT into a table with primary
   320  	// key.
   321  	LastInsertId() (int64, error)
   322  
   323  	// RowsAffected returns the number of rows affected by the
   324  	// query.
   325  	RowsAffected() (int64, error)
   326  }
   327  
   328  // Stmt is a prepared statement. It is bound to a [Conn] and not
   329  // used by multiple goroutines concurrently.
   330  type Stmt interface {
   331  	// Close closes the statement.
   332  	//
   333  	// As of Go 1.1, a Stmt will not be closed if it's in use
   334  	// by any queries.
   335  	//
   336  	// Drivers must ensure all network calls made by Close
   337  	// do not block indefinitely (e.g. apply a timeout).
   338  	Close() error
   339  
   340  	// NumInput returns the number of placeholder parameters.
   341  	//
   342  	// If NumInput returns >= 0, the sql package will sanity check
   343  	// argument counts from callers and return errors to the caller
   344  	// before the statement's Exec or Query methods are called.
   345  	//
   346  	// NumInput may also return -1, if the driver doesn't know
   347  	// its number of placeholders. In that case, the sql package
   348  	// will not sanity check Exec or Query argument counts.
   349  	NumInput() int
   350  
   351  	// Exec executes a query that doesn't return rows, such
   352  	// as an INSERT or UPDATE.
   353  	//
   354  	// Deprecated: Drivers should implement StmtExecContext instead (or additionally).
   355  	Exec(args []Value) (Result, error)
   356  
   357  	// Query executes a query that may return rows, such as a
   358  	// SELECT.
   359  	//
   360  	// Deprecated: Drivers should implement StmtQueryContext instead (or additionally).
   361  	Query(args []Value) (Rows, error)
   362  }
   363  
   364  // StmtExecContext enhances the [Stmt] interface by providing Exec with context.
   365  type StmtExecContext interface {
   366  	// ExecContext executes a query that doesn't return rows, such
   367  	// as an INSERT or UPDATE.
   368  	//
   369  	// ExecContext must honor the context timeout and return when it is canceled.
   370  	ExecContext(ctx context.Context, args []NamedValue) (Result, error)
   371  }
   372  
   373  // StmtQueryContext enhances the [Stmt] interface by providing Query with context.
   374  type StmtQueryContext interface {
   375  	// QueryContext executes a query that may return rows, such as a
   376  	// SELECT.
   377  	//
   378  	// QueryContext must honor the context timeout and return when it is canceled.
   379  	QueryContext(ctx context.Context, args []NamedValue) (Rows, error)
   380  }
   381  
   382  // ErrRemoveArgument may be returned from [NamedValueChecker] to instruct the
   383  // [database/sql] package to not pass the argument to the driver query interface.
   384  // Return when accepting query specific options or structures that aren't
   385  // SQL query arguments.
   386  var ErrRemoveArgument = errors.New("driver: remove argument from query")
   387  
   388  // NamedValueChecker may be optionally implemented by [Conn] or [Stmt]. It provides
   389  // the driver more control to handle Go and database types beyond the default
   390  // [Value] types allowed.
   391  //
   392  // The [database/sql] package checks for value checkers in the following order,
   393  // stopping at the first found match: Stmt.NamedValueChecker, Conn.NamedValueChecker,
   394  // Stmt.ColumnConverter, [DefaultParameterConverter].
   395  //
   396  // If CheckNamedValue returns [ErrRemoveArgument], the [NamedValue] will not be included in
   397  // the final query arguments. This may be used to pass special options to
   398  // the query itself.
   399  //
   400  // If [ErrSkip] is returned the column converter error checking
   401  // path is used for the argument. Drivers may wish to return [ErrSkip] after
   402  // they have exhausted their own special cases.
   403  type NamedValueChecker interface {
   404  	// CheckNamedValue is called before passing arguments to the driver
   405  	// and is called in place of any ColumnConverter. CheckNamedValue must do type
   406  	// validation and conversion as appropriate for the driver.
   407  	CheckNamedValue(*NamedValue) error
   408  }
   409  
   410  // ColumnConverter may be optionally implemented by [Stmt] if the
   411  // statement is aware of its own columns' types and can convert from
   412  // any type to a driver [Value].
   413  //
   414  // Deprecated: Drivers should implement [NamedValueChecker].
   415  type ColumnConverter interface {
   416  	// ColumnConverter returns a ValueConverter for the provided
   417  	// column index. If the type of a specific column isn't known
   418  	// or shouldn't be handled specially, [DefaultParameterConverter]
   419  	// can be returned.
   420  	ColumnConverter(idx int) ValueConverter
   421  }
   422  
   423  // Rows is an iterator over an executed query's results.
   424  type Rows interface {
   425  	// Columns returns the names of the columns. The number of
   426  	// columns of the result is inferred from the length of the
   427  	// slice. If a particular column name isn't known, an empty
   428  	// string should be returned for that entry.
   429  	Columns() []string
   430  
   431  	// Close closes the rows iterator.
   432  	Close() error
   433  
   434  	// Next is called to populate the next row of data into
   435  	// the provided slice. The provided slice will be the same
   436  	// size as the Columns() are wide.
   437  	//
   438  	// Next should return io.EOF when there are no more rows.
   439  	//
   440  	// The dest should not be written to outside of Next. Care
   441  	// should be taken when closing Rows not to modify
   442  	// a buffer held in dest.
   443  	Next(dest []Value) error
   444  }
   445  
   446  // RowsNextResultSet extends the [Rows] interface by providing a way to signal
   447  // the driver to advance to the next result set.
   448  type RowsNextResultSet interface {
   449  	Rows
   450  
   451  	// HasNextResultSet is called at the end of the current result set and
   452  	// reports whether there is another result set after the current one.
   453  	HasNextResultSet() bool
   454  
   455  	// NextResultSet advances the driver to the next result set even
   456  	// if there are remaining rows in the current result set.
   457  	//
   458  	// NextResultSet should return io.EOF when there are no more result sets.
   459  	NextResultSet() error
   460  }
   461  
   462  // RowsColumnTypeScanType may be implemented by [Rows]. It should return
   463  // the value type that can be used to scan types into. For example, the database
   464  // column type "bigint" this should return "[reflect.TypeOf](int64(0))".
   465  type RowsColumnTypeScanType interface {
   466  	Rows
   467  	ColumnTypeScanType(index int) reflect.Type
   468  }
   469  
   470  // RowsColumnTypeDatabaseTypeName may be implemented by [Rows]. It should return the
   471  // database system type name without the length. Type names should be uppercase.
   472  // Examples of returned types: "VARCHAR", "NVARCHAR", "VARCHAR2", "CHAR", "TEXT",
   473  // "DECIMAL", "SMALLINT", "INT", "BIGINT", "BOOL", "[]BIGINT", "JSONB", "XML",
   474  // "TIMESTAMP".
   475  type RowsColumnTypeDatabaseTypeName interface {
   476  	Rows
   477  	ColumnTypeDatabaseTypeName(index int) string
   478  }
   479  
   480  // RowsColumnTypeLength may be implemented by [Rows]. It should return the length
   481  // of the column type if the column is a variable length type. If the column is
   482  // not a variable length type ok should return false.
   483  // If length is not limited other than system limits, it should return [math.MaxInt64].
   484  // The following are examples of returned values for various types:
   485  //
   486  //	TEXT          (math.MaxInt64, true)
   487  //	varchar(10)   (10, true)
   488  //	nvarchar(10)  (10, true)
   489  //	decimal       (0, false)
   490  //	int           (0, false)
   491  //	bytea(30)     (30, true)
   492  type RowsColumnTypeLength interface {
   493  	Rows
   494  	ColumnTypeLength(index int) (length int64, ok bool)
   495  }
   496  
   497  // RowsColumnTypeNullable may be implemented by [Rows]. The nullable value should
   498  // be true if it is known the column may be null, or false if the column is known
   499  // to be not nullable.
   500  // If the column nullability is unknown, ok should be false.
   501  type RowsColumnTypeNullable interface {
   502  	Rows
   503  	ColumnTypeNullable(index int) (nullable, ok bool)
   504  }
   505  
   506  // RowsColumnTypePrecisionScale may be implemented by [Rows]. It should return
   507  // the precision and scale for decimal types. If not applicable, ok should be false.
   508  // The following are examples of returned values for various types:
   509  //
   510  //	decimal(38, 4)    (38, 4, true)
   511  //	int               (0, 0, false)
   512  //	decimal           (math.MaxInt64, math.MaxInt64, true)
   513  type RowsColumnTypePrecisionScale interface {
   514  	Rows
   515  	ColumnTypePrecisionScale(index int) (precision, scale int64, ok bool)
   516  }
   517  
   518  // Tx is a transaction.
   519  type Tx interface {
   520  	Commit() error
   521  	Rollback() error
   522  }
   523  
   524  // RowsAffected implements [Result] for an INSERT or UPDATE operation
   525  // which mutates a number of rows.
   526  type RowsAffected int64
   527  
   528  var _ Result = RowsAffected(0)
   529  
   530  func (RowsAffected) LastInsertId() (int64, error) {
   531  	return 0, errors.New("LastInsertId is not supported by this driver")
   532  }
   533  
   534  func (v RowsAffected) RowsAffected() (int64, error) {
   535  	return int64(v), nil
   536  }
   537  
   538  // ResultNoRows is a pre-defined [Result] for drivers to return when a DDL
   539  // command (such as a CREATE TABLE) succeeds. It returns an error for both
   540  // LastInsertId and [RowsAffected].
   541  var ResultNoRows noRows
   542  
   543  type noRows struct{}
   544  
   545  var _ Result = noRows{}
   546  
   547  func (noRows) LastInsertId() (int64, error) {
   548  	return 0, errors.New("no LastInsertId available after DDL statement")
   549  }
   550  
   551  func (noRows) RowsAffected() (int64, error) {
   552  	return 0, errors.New("no RowsAffected available after DDL statement")
   553  }
   554  

View as plain text