OSDN Git Service

4e68c3ee0952b6e778a0facf650862212164cbb9
[pf3gnuchains/gcc-fork.git] / libgo / go / exp / sql / sql.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 sql provides a generic interface around SQL (or SQL-like)
6 // databases.
7 package sql
8
9 import (
10         "errors"
11         "fmt"
12         "io"
13         "sync"
14
15         "exp/sql/driver"
16 )
17
18 var drivers = make(map[string]driver.Driver)
19
20 // Register makes a database driver available by the provided name.
21 // If Register is called twice with the same name or if driver is nil,
22 // it panics.
23 func Register(name string, driver driver.Driver) {
24         if driver == nil {
25                 panic("sql: Register driver is nil")
26         }
27         if _, dup := drivers[name]; dup {
28                 panic("sql: Register called twice for driver " + name)
29         }
30         drivers[name] = driver
31 }
32
33 // NullableString represents a string that may be null.
34 // NullableString implements the ScannerInto interface so
35 // it can be used as a scan destination:
36 //
37 //  var s NullableString
38 //  err := db.QueryRow("SELECT name FROM foo WHERE id=?", id).Scan(&s)
39 //  ...
40 //  if s.Valid {
41 //     // use s.String
42 //  } else {
43 //     // NULL value
44 //  }
45 //
46 // TODO(bradfitz): add other types.
47 type NullableString struct {
48         String string
49         Valid  bool // Valid is true if String is not NULL
50 }
51
52 // ScanInto implements the ScannerInto interface.
53 func (ms *NullableString) ScanInto(value interface{}) error {
54         if value == nil {
55                 ms.String, ms.Valid = "", false
56                 return nil
57         }
58         ms.Valid = true
59         return convertAssign(&ms.String, value)
60 }
61
62 // ScannerInto is an interface used by Scan.
63 type ScannerInto interface {
64         // ScanInto assigns a value from a database driver.
65         //
66         // The value will be of one of the following restricted
67         // set of types:
68         //
69         //    int64
70         //    float64
71         //    bool
72         //    []byte
73         //    nil - for NULL values
74         //
75         // An error should be returned if the value can not be stored
76         // without loss of information.
77         ScanInto(value interface{}) error
78 }
79
80 // ErrNoRows is returned by Scan when QueryRow doesn't return a
81 // row. In such a case, QueryRow returns a placeholder *Row value that
82 // defers this error until a Scan.
83 var ErrNoRows = errors.New("sql: no rows in result set")
84
85 // DB is a database handle. It's safe for concurrent use by multiple
86 // goroutines.
87 type DB struct {
88         driver driver.Driver
89         dsn    string
90
91         mu       sync.Mutex // protects freeConn and closed
92         freeConn []driver.Conn
93         closed   bool
94 }
95
96 // Open opens a database specified by its database driver name and a
97 // driver-specific data source name, usually consisting of at least a
98 // database name and connection information.
99 //
100 // Most users will open a database via a driver-specific connection
101 // helper function that returns a *DB.
102 func Open(driverName, dataSourceName string) (*DB, error) {
103         driver, ok := drivers[driverName]
104         if !ok {
105                 return nil, fmt.Errorf("sql: unknown driver %q (forgotten import?)", driverName)
106         }
107         return &DB{driver: driver, dsn: dataSourceName}, nil
108 }
109
110 // Close closes the database, releasing any open resources.
111 func (db *DB) Close() error {
112         db.mu.Lock()
113         defer db.mu.Unlock()
114         var err error
115         for _, c := range db.freeConn {
116                 err1 := c.Close()
117                 if err1 != nil {
118                         err = err1
119                 }
120         }
121         db.freeConn = nil
122         db.closed = true
123         return err
124 }
125
126 func (db *DB) maxIdleConns() int {
127         const defaultMaxIdleConns = 2
128         // TODO(bradfitz): ask driver, if supported, for its default preference
129         // TODO(bradfitz): let users override?
130         return defaultMaxIdleConns
131 }
132
133 // conn returns a newly-opened or cached driver.Conn
134 func (db *DB) conn() (driver.Conn, error) {
135         db.mu.Lock()
136         if db.closed {
137                 db.mu.Unlock()
138                 return nil, errors.New("sql: database is closed")
139         }
140         if n := len(db.freeConn); n > 0 {
141                 conn := db.freeConn[n-1]
142                 db.freeConn = db.freeConn[:n-1]
143                 db.mu.Unlock()
144                 return conn, nil
145         }
146         db.mu.Unlock()
147         return db.driver.Open(db.dsn)
148 }
149
150 func (db *DB) connIfFree(wanted driver.Conn) (conn driver.Conn, ok bool) {
151         db.mu.Lock()
152         defer db.mu.Unlock()
153         for n, conn := range db.freeConn {
154                 if conn == wanted {
155                         db.freeConn[n] = db.freeConn[len(db.freeConn)-1]
156                         db.freeConn = db.freeConn[:len(db.freeConn)-1]
157                         return wanted, true
158                 }
159         }
160         return nil, false
161 }
162
163 func (db *DB) putConn(c driver.Conn) {
164         db.mu.Lock()
165         defer db.mu.Unlock()
166         if n := len(db.freeConn); !db.closed && n < db.maxIdleConns() {
167                 db.freeConn = append(db.freeConn, c)
168                 return
169         }
170         db.closeConn(c) // TODO(bradfitz): release lock before calling this?
171 }
172
173 func (db *DB) closeConn(c driver.Conn) {
174         // TODO: check to see if we need this Conn for any prepared statements
175         // that are active.
176         c.Close()
177 }
178
179 // Prepare creates a prepared statement for later execution.
180 func (db *DB) Prepare(query string) (*Stmt, error) {
181         // TODO: check if db.driver supports an optional
182         // driver.Preparer interface and call that instead, if so,
183         // otherwise we make a prepared statement that's bound
184         // to a connection, and to execute this prepared statement
185         // we either need to use this connection (if it's free), else
186         // get a new connection + re-prepare + execute on that one.
187         ci, err := db.conn()
188         if err != nil {
189                 return nil, err
190         }
191         defer db.putConn(ci)
192         si, err := ci.Prepare(query)
193         if err != nil {
194                 return nil, err
195         }
196         stmt := &Stmt{
197                 db:    db,
198                 query: query,
199                 css:   []connStmt{{ci, si}},
200         }
201         return stmt, nil
202 }
203
204 // Exec executes a query without returning any rows.
205 func (db *DB) Exec(query string, args ...interface{}) (Result, error) {
206         sargs, err := subsetTypeArgs(args)
207         if err != nil {
208                 return nil, err
209         }
210
211         ci, err := db.conn()
212         if err != nil {
213                 return nil, err
214         }
215         defer db.putConn(ci)
216
217         if execer, ok := ci.(driver.Execer); ok {
218                 resi, err := execer.Exec(query, sargs)
219                 if err != driver.ErrSkip {
220                         if err != nil {
221                                 return nil, err
222                         }
223                         return result{resi}, nil
224                 }
225         }
226
227         sti, err := ci.Prepare(query)
228         if err != nil {
229                 return nil, err
230         }
231         defer sti.Close()
232
233         resi, err := sti.Exec(sargs)
234         if err != nil {
235                 return nil, err
236         }
237         return result{resi}, nil
238 }
239
240 // Query executes a query that returns rows, typically a SELECT.
241 func (db *DB) Query(query string, args ...interface{}) (*Rows, error) {
242         stmt, err := db.Prepare(query)
243         if err != nil {
244                 return nil, err
245         }
246         rows, err := stmt.Query(args...)
247         if err != nil {
248                 stmt.Close()
249                 return nil, err
250         }
251         rows.closeStmt = stmt
252         return rows, nil
253 }
254
255 // QueryRow executes a query that is expected to return at most one row.
256 // QueryRow always return a non-nil value. Errors are deferred until
257 // Row's Scan method is called.
258 func (db *DB) QueryRow(query string, args ...interface{}) *Row {
259         rows, err := db.Query(query, args...)
260         return &Row{rows: rows, err: err}
261 }
262
263 // Begin starts a transaction. The isolation level is dependent on
264 // the driver.
265 func (db *DB) Begin() (*Tx, error) {
266         ci, err := db.conn()
267         if err != nil {
268                 return nil, err
269         }
270         txi, err := ci.Begin()
271         if err != nil {
272                 db.putConn(ci)
273                 return nil, fmt.Errorf("sql: failed to Begin transaction: %v", err)
274         }
275         return &Tx{
276                 db:  db,
277                 ci:  ci,
278                 txi: txi,
279         }, nil
280 }
281
282 // DriverDatabase returns the database's underlying driver.
283 func (db *DB) Driver() driver.Driver {
284         return db.driver
285 }
286
287 // Tx is an in-progress database transaction.
288 //
289 // A transaction must end with a call to Commit or Rollback.
290 //
291 // After a call to Commit or Rollback, all operations on the
292 // transaction fail with ErrTransactionFinished.
293 type Tx struct {
294         db *DB
295
296         // ci is owned exclusively until Commit or Rollback, at which point
297         // it's returned with putConn.
298         ci  driver.Conn
299         txi driver.Tx
300
301         // cimu is held while somebody is using ci (between grabConn
302         // and releaseConn)
303         cimu sync.Mutex
304
305         // done transitions from false to true exactly once, on Commit
306         // or Rollback. once done, all operations fail with
307         // ErrTransactionFinished.
308         done bool
309 }
310
311 var ErrTransactionFinished = errors.New("sql: Transaction has already been committed or rolled back")
312
313 func (tx *Tx) close() {
314         if tx.done {
315                 panic("double close") // internal error
316         }
317         tx.done = true
318         tx.db.putConn(tx.ci)
319         tx.ci = nil
320         tx.txi = nil
321 }
322
323 func (tx *Tx) grabConn() (driver.Conn, error) {
324         if tx.done {
325                 return nil, ErrTransactionFinished
326         }
327         tx.cimu.Lock()
328         return tx.ci, nil
329 }
330
331 func (tx *Tx) releaseConn() {
332         tx.cimu.Unlock()
333 }
334
335 // Commit commits the transaction.
336 func (tx *Tx) Commit() error {
337         if tx.done {
338                 return ErrTransactionFinished
339         }
340         defer tx.close()
341         return tx.txi.Commit()
342 }
343
344 // Rollback aborts the transaction.
345 func (tx *Tx) Rollback() error {
346         if tx.done {
347                 return ErrTransactionFinished
348         }
349         defer tx.close()
350         return tx.txi.Rollback()
351 }
352
353 // Prepare creates a prepared statement for use within a transaction.
354 //
355 // The returned statement operates within the transaction and can no longer
356 // be used once the transaction has been committed or rolled back.
357 //
358 // To use an existing prepared statement on this transaction, see Tx.Stmt.
359 func (tx *Tx) Prepare(query string) (*Stmt, error) {
360         // TODO(bradfitz): We could be more efficient here and either
361         // provide a method to take an existing Stmt (created on
362         // perhaps a different Conn), and re-create it on this Conn if
363         // necessary. Or, better: keep a map in DB of query string to
364         // Stmts, and have Stmt.Execute do the right thing and
365         // re-prepare if the Conn in use doesn't have that prepared
366         // statement.  But we'll want to avoid caching the statement
367         // in the case where we only call conn.Prepare implicitly
368         // (such as in db.Exec or tx.Exec), but the caller package
369         // can't be holding a reference to the returned statement.
370         // Perhaps just looking at the reference count (by noting
371         // Stmt.Close) would be enough. We might also want a finalizer
372         // on Stmt to drop the reference count.
373         ci, err := tx.grabConn()
374         if err != nil {
375                 return nil, err
376         }
377         defer tx.releaseConn()
378
379         si, err := ci.Prepare(query)
380         if err != nil {
381                 return nil, err
382         }
383
384         stmt := &Stmt{
385                 db:    tx.db,
386                 tx:    tx,
387                 txsi:  si,
388                 query: query,
389         }
390         return stmt, nil
391 }
392
393 // Stmt returns a transaction-specific prepared statement from
394 // an existing statement.
395 //
396 // Example:
397 //  updateMoney, err := db.Prepare("UPDATE balance SET money=money+? WHERE id=?")
398 //  ...
399 //  tx, err := db.Begin()
400 //  ...
401 //  res, err := tx.Stmt(updateMoney).Exec(123.45, 98293203)
402 func (tx *Tx) Stmt(stmt *Stmt) *Stmt {
403         // TODO(bradfitz): optimize this. Currently this re-prepares
404         // each time.  This is fine for now to illustrate the API but
405         // we should really cache already-prepared statements
406         // per-Conn. See also the big comment in Tx.Prepare.
407
408         if tx.db != stmt.db {
409                 return &Stmt{stickyErr: errors.New("sql: Tx.Stmt: statement from different database used")}
410         }
411         ci, err := tx.grabConn()
412         if err != nil {
413                 return &Stmt{stickyErr: err}
414         }
415         defer tx.releaseConn()
416         si, err := ci.Prepare(stmt.query)
417         return &Stmt{
418                 db:        tx.db,
419                 tx:        tx,
420                 txsi:      si,
421                 query:     stmt.query,
422                 stickyErr: err,
423         }
424 }
425
426 // Exec executes a query that doesn't return rows.
427 // For example: an INSERT and UPDATE.
428 func (tx *Tx) Exec(query string, args ...interface{}) (Result, error) {
429         ci, err := tx.grabConn()
430         if err != nil {
431                 return nil, err
432         }
433         defer tx.releaseConn()
434
435         if execer, ok := ci.(driver.Execer); ok {
436                 resi, err := execer.Exec(query, args)
437                 if err != nil {
438                         return nil, err
439                 }
440                 return result{resi}, nil
441         }
442
443         sti, err := ci.Prepare(query)
444         if err != nil {
445                 return nil, err
446         }
447         defer sti.Close()
448
449         sargs, err := subsetTypeArgs(args)
450         if err != nil {
451                 return nil, err
452         }
453
454         resi, err := sti.Exec(sargs)
455         if err != nil {
456                 return nil, err
457         }
458         return result{resi}, nil
459 }
460
461 // Query executes a query that returns rows, typically a SELECT.
462 func (tx *Tx) Query(query string, args ...interface{}) (*Rows, error) {
463         if tx.done {
464                 return nil, ErrTransactionFinished
465         }
466         stmt, err := tx.Prepare(query)
467         if err != nil {
468                 return nil, err
469         }
470         defer stmt.Close()
471         return stmt.Query(args...)
472 }
473
474 // QueryRow executes a query that is expected to return at most one row.
475 // QueryRow always return a non-nil value. Errors are deferred until
476 // Row's Scan method is called.
477 func (tx *Tx) QueryRow(query string, args ...interface{}) *Row {
478         rows, err := tx.Query(query, args...)
479         return &Row{rows: rows, err: err}
480 }
481
482 // connStmt is a prepared statement on a particular connection.
483 type connStmt struct {
484         ci driver.Conn
485         si driver.Stmt
486 }
487
488 // Stmt is a prepared statement. Stmt is safe for concurrent use by multiple goroutines.
489 type Stmt struct {
490         // Immutable:
491         db        *DB    // where we came from
492         query     string // that created the Stmt
493         stickyErr error  // if non-nil, this error is returned for all operations
494
495         // If in a transaction, else both nil:
496         tx   *Tx
497         txsi driver.Stmt
498
499         mu     sync.Mutex // protects the rest of the fields
500         closed bool
501
502         // css is a list of underlying driver statement interfaces
503         // that are valid on particular connections.  This is only
504         // used if tx == nil and one is found that has idle
505         // connections.  If tx != nil, txsi is always used.
506         css []connStmt
507 }
508
509 // Exec executes a prepared statement with the given arguments and
510 // returns a Result summarizing the effect of the statement.
511 func (s *Stmt) Exec(args ...interface{}) (Result, error) {
512         _, releaseConn, si, err := s.connStmt()
513         if err != nil {
514                 return nil, err
515         }
516         defer releaseConn()
517
518         // -1 means the driver doesn't know how to count the number of
519         // placeholders, so we won't sanity check input here and instead let the
520         // driver deal with errors.
521         if want := si.NumInput(); want != -1 && len(args) != want {
522                 return nil, fmt.Errorf("sql: expected %d arguments, got %d", want, len(args))
523         }
524
525         // Convert args to subset types.
526         if cc, ok := si.(driver.ColumnConverter); ok {
527                 for n, arg := range args {
528                         args[n], err = cc.ColumnConverter(n).ConvertValue(arg)
529                         if err != nil {
530                                 return nil, fmt.Errorf("sql: converting Exec argument #%d's type: %v", n, err)
531                         }
532                         if !driver.IsParameterSubsetType(args[n]) {
533                                 return nil, fmt.Errorf("sql: driver ColumnConverter error converted %T to unsupported type %T",
534                                         arg, args[n])
535                         }
536                 }
537         } else {
538                 for n, arg := range args {
539                         args[n], err = driver.DefaultParameterConverter.ConvertValue(arg)
540                         if err != nil {
541                                 return nil, fmt.Errorf("sql: converting Exec argument #%d's type: %v", n, err)
542                         }
543                 }
544         }
545
546         resi, err := si.Exec(args)
547         if err != nil {
548                 return nil, err
549         }
550         return result{resi}, nil
551 }
552
553 // connStmt returns a free driver connection on which to execute the
554 // statement, a function to call to release the connection, and a
555 // statement bound to that connection.
556 func (s *Stmt) connStmt() (ci driver.Conn, releaseConn func(), si driver.Stmt, err error) {
557         if err = s.stickyErr; err != nil {
558                 return
559         }
560         s.mu.Lock()
561         if s.closed {
562                 s.mu.Unlock()
563                 err = errors.New("sql: statement is closed")
564                 return
565         }
566
567         // In a transaction, we always use the connection that the
568         // transaction was created on.
569         if s.tx != nil {
570                 s.mu.Unlock()
571                 ci, err = s.tx.grabConn() // blocks, waiting for the connection.
572                 if err != nil {
573                         return
574                 }
575                 releaseConn = func() { s.tx.releaseConn() }
576                 return ci, releaseConn, s.txsi, nil
577         }
578
579         var cs connStmt
580         match := false
581         for _, v := range s.css {
582                 // TODO(bradfitz): lazily clean up entries in this
583                 // list with dead conns while enumerating
584                 if _, match = s.db.connIfFree(cs.ci); match {
585                         cs = v
586                         break
587                 }
588         }
589         s.mu.Unlock()
590
591         // Make a new conn if all are busy.
592         // TODO(bradfitz): or wait for one? make configurable later?
593         if !match {
594                 ci, err := s.db.conn()
595                 if err != nil {
596                         return nil, nil, nil, err
597                 }
598                 si, err := ci.Prepare(s.query)
599                 if err != nil {
600                         return nil, nil, nil, err
601                 }
602                 s.mu.Lock()
603                 cs = connStmt{ci, si}
604                 s.css = append(s.css, cs)
605                 s.mu.Unlock()
606         }
607
608         conn := cs.ci
609         releaseConn = func() { s.db.putConn(conn) }
610         return conn, releaseConn, cs.si, nil
611 }
612
613 // Query executes a prepared query statement with the given arguments
614 // and returns the query results as a *Rows.
615 func (s *Stmt) Query(args ...interface{}) (*Rows, error) {
616         ci, releaseConn, si, err := s.connStmt()
617         if err != nil {
618                 return nil, err
619         }
620
621         // -1 means the driver doesn't know how to count the number of
622         // placeholders, so we won't sanity check input here and instead let the
623         // driver deal with errors.
624         if want := si.NumInput(); want != -1 && len(args) != want {
625                 return nil, fmt.Errorf("sql: statement expects %d inputs; got %d", si.NumInput(), len(args))
626         }
627         sargs, err := subsetTypeArgs(args)
628         if err != nil {
629                 return nil, err
630         }
631         rowsi, err := si.Query(sargs)
632         if err != nil {
633                 s.db.putConn(ci)
634                 return nil, err
635         }
636         // Note: ownership of ci passes to the *Rows, to be freed
637         // with releaseConn.
638         rows := &Rows{
639                 db:          s.db,
640                 ci:          ci,
641                 releaseConn: releaseConn,
642                 rowsi:       rowsi,
643         }
644         return rows, nil
645 }
646
647 // QueryRow executes a prepared query statement with the given arguments.
648 // If an error occurs during the execution of the statement, that error will
649 // be returned by a call to Scan on the returned *Row, which is always non-nil.
650 // If the query selects no rows, the *Row's Scan will return ErrNoRows.
651 // Otherwise, the *Row's Scan scans the first selected row and discards
652 // the rest.
653 //
654 // Example usage:
655 //
656 //  var name string
657 //  err := nameByUseridStmt.QueryRow(id).Scan(&s)
658 func (s *Stmt) QueryRow(args ...interface{}) *Row {
659         rows, err := s.Query(args...)
660         if err != nil {
661                 return &Row{err: err}
662         }
663         return &Row{rows: rows}
664 }
665
666 // Close closes the statement.
667 func (s *Stmt) Close() error {
668         if s.stickyErr != nil {
669                 return s.stickyErr
670         }
671         s.mu.Lock()
672         defer s.mu.Unlock()
673         if s.closed {
674                 return nil
675         }
676         s.closed = true
677
678         if s.tx != nil {
679                 s.txsi.Close()
680         } else {
681                 for _, v := range s.css {
682                         if ci, match := s.db.connIfFree(v.ci); match {
683                                 v.si.Close()
684                                 s.db.putConn(ci)
685                         } else {
686                                 // TODO(bradfitz): care that we can't close
687                                 // this statement because the statement's
688                                 // connection is in use?
689                         }
690                 }
691         }
692         return nil
693 }
694
695 // Rows is the result of a query. Its cursor starts before the first row
696 // of the result set. Use Next to advance through the rows:
697 //
698 //     rows, err := db.Query("SELECT ...")
699 //     ...
700 //     for rows.Next() {
701 //         var id int
702 //         var name string
703 //         err = rows.Scan(&id, &name)
704 //         ...
705 //     }
706 //     err = rows.Err() // get any error encountered during iteration
707 //     ...
708 type Rows struct {
709         db          *DB
710         ci          driver.Conn // owned; must call putconn when closed to release
711         releaseConn func()
712         rowsi       driver.Rows
713
714         closed    bool
715         lastcols  []interface{}
716         lasterr   error
717         closeStmt *Stmt // if non-nil, statement to Close on close
718 }
719
720 // Next prepares the next result row for reading with the Scan method.
721 // It returns true on success, false if there is no next result row.
722 // Every call to Scan, even the first one, must be preceded by a call
723 // to Next.
724 func (rs *Rows) Next() bool {
725         if rs.closed {
726                 return false
727         }
728         if rs.lasterr != nil {
729                 return false
730         }
731         if rs.lastcols == nil {
732                 rs.lastcols = make([]interface{}, len(rs.rowsi.Columns()))
733         }
734         rs.lasterr = rs.rowsi.Next(rs.lastcols)
735         if rs.lasterr == io.EOF {
736                 rs.Close()
737         }
738         return rs.lasterr == nil
739 }
740
741 // Err returns the error, if any, that was encountered during iteration.
742 func (rs *Rows) Err() error {
743         if rs.lasterr == io.EOF {
744                 return nil
745         }
746         return rs.lasterr
747 }
748
749 // Columns returns the column names.
750 // Columns returns an error if the rows are closed, or if the rows
751 // are from QueryRow and there was a deferred error.
752 func (rs *Rows) Columns() ([]string, error) {
753         if rs.closed {
754                 return nil, errors.New("sql: Rows are closed")
755         }
756         if rs.rowsi == nil {
757                 return nil, errors.New("sql: no Rows available")
758         }
759         return rs.rowsi.Columns(), nil
760 }
761
762 // Scan copies the columns in the current row into the values pointed
763 // at by dest. If dest contains pointers to []byte, the slices should
764 // not be modified and should only be considered valid until the next
765 // call to Next or Scan.
766 func (rs *Rows) Scan(dest ...interface{}) error {
767         if rs.closed {
768                 return errors.New("sql: Rows closed")
769         }
770         if rs.lasterr != nil {
771                 return rs.lasterr
772         }
773         if rs.lastcols == nil {
774                 return errors.New("sql: Scan called without calling Next")
775         }
776         if len(dest) != len(rs.lastcols) {
777                 return fmt.Errorf("sql: expected %d destination arguments in Scan, not %d", len(rs.lastcols), len(dest))
778         }
779         for i, sv := range rs.lastcols {
780                 err := convertAssign(dest[i], sv)
781                 if err != nil {
782                         return fmt.Errorf("sql: Scan error on column index %d: %v", i, err)
783                 }
784         }
785         return nil
786 }
787
788 // Close closes the Rows, preventing further enumeration. If the
789 // end is encountered, the Rows are closed automatically. Close
790 // is idempotent.
791 func (rs *Rows) Close() error {
792         if rs.closed {
793                 return nil
794         }
795         rs.closed = true
796         err := rs.rowsi.Close()
797         rs.releaseConn()
798         if rs.closeStmt != nil {
799                 rs.closeStmt.Close()
800         }
801         return err
802 }
803
804 // Row is the result of calling QueryRow to select a single row.
805 type Row struct {
806         // One of these two will be non-nil:
807         err  error // deferred error for easy chaining
808         rows *Rows
809 }
810
811 // Scan copies the columns from the matched row into the values
812 // pointed at by dest.  If more than one row matches the query,
813 // Scan uses the first row and discards the rest.  If no row matches
814 // the query, Scan returns ErrNoRows.
815 func (r *Row) Scan(dest ...interface{}) error {
816         if r.err != nil {
817                 return r.err
818         }
819         defer r.rows.Close()
820         if !r.rows.Next() {
821                 return ErrNoRows
822         }
823         err := r.rows.Scan(dest...)
824         if err != nil {
825                 return err
826         }
827
828         // TODO(bradfitz): for now we need to defensively clone all
829         // []byte that the driver returned, since we're about to close
830         // the Rows in our defer, when we return from this function.
831         // the contract with the driver.Next(...) interface is that it
832         // can return slices into read-only temporary memory that's
833         // only valid until the next Scan/Close.  But the TODO is that
834         // for a lot of drivers, this copy will be unnecessary.  We
835         // should provide an optional interface for drivers to
836         // implement to say, "don't worry, the []bytes that I return
837         // from Next will not be modified again." (for instance, if
838         // they were obtained from the network anyway) But for now we
839         // don't care.
840         for _, dp := range dest {
841                 b, ok := dp.(*[]byte)
842                 if !ok {
843                         continue
844                 }
845                 clone := make([]byte, len(*b))
846                 copy(clone, *b)
847                 *b = clone
848         }
849         return nil
850 }
851
852 // A Result summarizes an executed SQL command.
853 type Result interface {
854         LastInsertId() (int64, error)
855         RowsAffected() (int64, error)
856 }
857
858 type result struct {
859         driver.Result
860 }