Add AfterClose and Conn to Rows

pull/120/head
Jack Christensen 2016-02-13 13:03:06 -06:00
parent 74b33db979
commit a93025479d
2 changed files with 31 additions and 8 deletions

View File

@ -243,7 +243,8 @@ func (p *ConnPool) Query(sql string, args ...interface{}) (*Rows, error) {
return rows, err
}
rows.pool = p
rows.AfterClose(p.rowsAfterClose)
return rows, nil
}
@ -295,3 +296,7 @@ func (p *ConnPool) BeginIso(iso string) (*Tx, error) {
func (p *ConnPool) txAfterClose(tx *Tx) {
p.Release(tx.Conn())
}
func (p *ConnPool) rowsAfterClose(rows *Rows) {
p.Release(rows.Conn())
}

View File

@ -39,7 +39,6 @@ func (r *Row) Scan(dest ...interface{}) (err error) {
// the *Conn can be used again. Rows are closed by explicitly calling Close(),
// calling Next() until it returns false, or when a fatal error occurs.
type Rows struct {
pool *ConnPool
conn *Conn
mr *msgReader
fields []FieldDescription
@ -47,13 +46,14 @@ type Rows struct {
rowCount int
columnIdx int
err error
closed bool
startTime time.Time
sql string
args []interface{}
log func(lvl int, msg string, ctx ...interface{})
shouldLog func(lvl int) bool
afterClose func(*Rows)
unlockConn bool
closed bool
}
func (rows *Rows) FieldDescriptions() []FieldDescription {
@ -70,11 +70,6 @@ func (rows *Rows) close() {
rows.unlockConn = false
}
if rows.pool != nil {
rows.pool.Release(rows.conn)
rows.pool = nil
}
rows.closed = true
if rows.err == nil {
@ -85,6 +80,10 @@ func (rows *Rows) close() {
} else if rows.shouldLog(LogLevelError) {
rows.log(LogLevelError, "Query", "sql", rows.sql, "args", logQueryArgs(rows.args))
}
if rows.afterClose != nil {
rows.afterClose(rows)
}
}
func (rows *Rows) readUntilReadyForQuery() {
@ -195,6 +194,11 @@ func (rows *Rows) Next() bool {
}
}
// Conn returns the *Conn this *Rows is using.
func (rows *Rows) Conn() *Conn {
return rows.conn
}
func (rows *Rows) nextColumn() (*ValueReader, bool) {
if rows.closed {
return nil, false
@ -469,6 +473,20 @@ func (rows *Rows) Values() ([]interface{}, error) {
return values, rows.Err()
}
// AfterClose adds f to a LILO queue of functions that will be called when
// rows is closed.
func (rows *Rows) AfterClose(f func(*Rows)) {
if rows.afterClose == nil {
rows.afterClose = f
} else {
prevFn := rows.afterClose
rows.afterClose = func(rows *Rows) {
f(rows)
prevFn(rows)
}
}
}
// Query executes sql with args. If there is an error the returned *Rows will
// be returned in an error state. So it is allowed to ignore the error returned
// from Query and handle it in *Rows.