close rows if possible (#629)

This commit is contained in:
Lunny Xiao 2017-06-25 17:35:04 +08:00 committed by GitHub
parent d9e6f21d60
commit 32d688fd96
3 changed files with 45 additions and 25 deletions

View File

@ -122,8 +122,13 @@ func (rows *Rows) Scan(bean interface{}) error {
if err := rows.session.Statement.setRefValue(dataStruct); err != nil { if err := rows.session.Statement.setRefValue(dataStruct); err != nil {
return err return err
} }
_, err := rows.session.row2Bean(rows.rows, rows.fields, len(rows.fields), bean, &dataStruct, rows.session.Statement.RefTable)
scanResults, err := rows.session.row2Slice(rows.rows, rows.fields, len(rows.fields), bean)
if err != nil {
return err
}
_, err = rows.session.slice2Bean(scanResults, rows.fields, len(rows.fields), bean, &dataStruct, rows.session.Statement.RefTable)
return err return err
} }

View File

@ -299,7 +299,12 @@ func (session *Session) rows2Beans(rows *core.Rows, fields []string, fieldsCount
var newValue = newElemFunc(fields) var newValue = newElemFunc(fields)
bean := newValue.Interface() bean := newValue.Interface()
dataStruct := rValue(bean) dataStruct := rValue(bean)
pk, err := session.row2Bean(rows, fields, fieldsCount, bean, &dataStruct, table) // handle beforeClosures
scanResults, err := session.row2Slice(rows, fields, fieldsCount, bean)
if err != nil {
return err
}
pk, err := session.slice2Bean(scanResults, fields, fieldsCount, bean, &dataStruct, table)
if err != nil { if err != nil {
return err return err
} }
@ -312,8 +317,7 @@ func (session *Session) rows2Beans(rows *core.Rows, fields []string, fieldsCount
return nil return nil
} }
func (session *Session) row2Bean(rows *core.Rows, fields []string, fieldsCount int, bean interface{}, dataStruct *reflect.Value, table *core.Table) (core.PK, error) { func (session *Session) row2Slice(rows *core.Rows, fields []string, fieldsCount int, bean interface{}) ([]interface{}, error) {
// handle beforeClosures
for _, closure := range session.beforeClosures { for _, closure := range session.beforeClosures {
closure(bean) closure(bean)
} }
@ -332,7 +336,10 @@ func (session *Session) row2Bean(rows *core.Rows, fields []string, fieldsCount i
b.BeforeSet(key, Cell(scanResults[ii].(*interface{}))) b.BeforeSet(key, Cell(scanResults[ii].(*interface{})))
} }
} }
return scanResults, nil
}
func (session *Session) slice2Bean(scanResults []interface{}, fields []string, fieldsCount int, bean interface{}, dataStruct *reflect.Value, table *core.Table) (core.PK, error) {
defer func() { defer func() {
if b, hasAfterSet := bean.(AfterSetProcessor); hasAfterSet { if b, hasAfterSet := bean.(AfterSetProcessor); hasAfterSet {
for ii, key := range fields { for ii, key := range fields {

View File

@ -78,7 +78,10 @@ func (session *Session) nocacheGet(beanKind reflect.Kind, bean interface{}, sqlS
defer rawRows.Close() defer rawRows.Close()
if rawRows.Next() { if !rawRows.Next() {
return false, nil
}
switch beanKind { switch beanKind {
case reflect.Struct: case reflect.Struct:
fields, err := rawRows.Columns() fields, err := rawRows.Columns()
@ -90,7 +93,14 @@ func (session *Session) nocacheGet(beanKind reflect.Kind, bean interface{}, sqlS
if err := session.Statement.setRefValue(dataStruct); err != nil { if err := session.Statement.setRefValue(dataStruct); err != nil {
return false, err return false, err
} }
_, err = session.row2Bean(rawRows, fields, len(fields), bean, &dataStruct, session.Statement.RefTable)
scanResults, err := session.row2Slice(rawRows, fields, len(fields), bean)
if err != nil {
return false, err
}
rawRows.Close()
_, err = session.slice2Bean(scanResults, fields, len(fields), bean, &dataStruct, session.Statement.RefTable)
case reflect.Slice: case reflect.Slice:
err = rawRows.ScanSlice(bean) err = rawRows.ScanSlice(bean)
case reflect.Map: case reflect.Map:
@ -101,8 +111,6 @@ func (session *Session) nocacheGet(beanKind reflect.Kind, bean interface{}, sqlS
return true, err return true, err
} }
return false, nil
}
func (session *Session) cacheGet(bean interface{}, sqlStr string, args ...interface{}) (has bool, err error) { func (session *Session) cacheGet(bean interface{}, sqlStr string, args ...interface{}) (has bool, err error) {
// if has no reftable, then don't use cache currently // if has no reftable, then don't use cache currently