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