Newer
Older
// err := nameByUseridStmt.QueryRow(id).Scan(&name)
func (s *Stmt) QueryRow(args ...interface{}) *Row {
rows, err := s.Query(args...)
if err != nil {
return &Row{err: err}
}
return &Row{rows: rows}
}
// Close closes the statement.
s.closemu.Lock()
defer s.closemu.Unlock()
if s.stickyErr != nil {
return s.stickyErr
}
defer s.mu.Unlock()
if s.closed {
return nil
}
s.closed = true
if s.tx != nil {
s.txsi.Close()
return nil
}
return s.db.removeDep(s, s)
}
func (s *Stmt) finalClose() error {
for _, v := range s.css {
s.db.noteUnusedDriverStatement(v.ci, v.si)
return nil
}
// Rows is the result of a query. Its cursor starts before the first row
// of the result set. Use Next to advance through the rows:
//
// rows, err := db.Query("SELECT ...")
// ...
// for rows.Next() {
// var id int
// var name string
// err = rows.Scan(&id, &name)
// ...
// }
// err = rows.Err() // get any error encountered during iteration
// ...
type Rows struct {
ci driver.Conn // owned; must call releaseConn when closed to release
releaseConn func(error)
rowsi driver.Rows
closeStmt driver.Stmt // if non-nil, statement to Close on close
}
// Next prepares the next result row for reading with the Scan method.
// It returns true on success, false if there is no next result row.
// Every call to Scan, even the first one, must be preceded by a call
// to Next.
func (rs *Rows) Next() bool {
if rs.closed {
return false
}
if rs.lasterr != nil {
return false
}
if rs.lastcols == nil {
rs.lastcols = make([]driver.Value, len(rs.rowsi.Columns()))
}
rs.lasterr = rs.rowsi.Next(rs.lastcols)
if rs.lasterr == io.EOF {
rs.Close()
}
return rs.lasterr == nil
}
// Err returns the error, if any, that was encountered during iteration.
func (rs *Rows) Err() error {
return nil
}
return rs.lasterr
}
// Columns returns the column names.
// Columns returns an error if the rows are closed, or if the rows
// are from QueryRow and there was a deferred error.
func (rs *Rows) Columns() ([]string, error) {
if rs.closed {
return nil, errors.New("sql: Rows are closed")
}
if rs.rowsi == nil {
return nil, errors.New("sql: no Rows available")
}
return rs.rowsi.Columns(), nil
}
// Scan copies the columns in the current row into the values pointed
// at by dest.
//
// If an argument has type *[]byte, Scan saves in that argument a copy
// of the corresponding data. The copy is owned by the caller and can
// be modified and held indefinitely. The copy can be avoided by using
// an argument of type *RawBytes instead; see the documentation for
// RawBytes for restrictions on its use.
//
// If an argument has type *interface{}, Scan copies the value
// provided by the underlying driver without conversion. If the value
// is of type []byte, a copy is made and the caller owns the result.
func (rs *Rows) Scan(dest ...interface{}) error {
}
if rs.lasterr != nil {
return rs.lasterr
}
if rs.lastcols == nil {
return errors.New("sql: Scan called without calling Next")
}
if len(dest) != len(rs.lastcols) {
return fmt.Errorf("sql: expected %d destination arguments in Scan, not %d", len(rs.lastcols), len(dest))
}
for i, sv := range rs.lastcols {
err := convertAssign(dest[i], sv)
if err != nil {
return fmt.Errorf("sql: Scan error on column index %d: %v", i, err)
for _, dp := range dest {
b, ok := dp.(*[]byte)
if !ok {
continue
}
if *b == nil {
// If the []byte is now nil (for a NULL value),
// don't fall through to below which would
// turn it into a non-nil 0-length byte slice
continue
}
if _, ok = dp.(*RawBytes); ok {
continue
}
clone := make([]byte, len(*b))
copy(clone, *b)
*b = clone
}
return nil
}
// Close closes the Rows, preventing further enumeration. If the
// end is encountered, the Rows are closed automatically. Close
// is idempotent.
if rs.closed {
return nil
}
rs.closed = true
err := rs.rowsi.Close()
rs.releaseConn(err)
if rs.closeStmt != nil {
rs.closeStmt.Close()
}
return err
}
// Row is the result of calling QueryRow to select a single row.
type Row struct {
// One of these two will be non-nil:
err error // deferred error for easy chaining
rows *Rows
}
// Scan copies the columns from the matched row into the values
// pointed at by dest. If more than one row matches the query,
// Scan uses the first row and discards the rest. If no row matches
// the query, Scan returns ErrNoRows.
func (r *Row) Scan(dest ...interface{}) error {
if r.err != nil {
return r.err
}
// TODO(bradfitz): for now we need to defensively clone all
// []byte that the driver returned (not permitting
// *RawBytes in Rows.Scan), since we're about to close
// the Rows in our defer, when we return from this function.
// the contract with the driver.Next(...) interface is that it
// can return slices into read-only temporary memory that's
// only valid until the next Scan/Close. But the TODO is that
// for a lot of drivers, this copy will be unnecessary. We
// should provide an optional interface for drivers to
// implement to say, "don't worry, the []bytes that I return
// from Next will not be modified again." (for instance, if
// they were obtained from the network anyway) But for now we
// don't care.
for _, dp := range dest {
if _, ok := dp.(*RawBytes); ok {
return errors.New("sql: RawBytes isn't allowed on Row.Scan")
}
defer r.rows.Close()
if !r.rows.Next() {
return ErrNoRows
}
err := r.rows.Scan(dest...)
if err != nil {
return err
}
return nil
}
// A Result summarizes an executed SQL command.
type Result interface {
LastInsertId() (int64, error)
RowsAffected() (int64, error)
}
type result struct {
driver.Result
}
func stack() string {
var buf [1024]byte
return string(buf[:runtime.Stack(buf[:], false)])
}