From 32d688fd965efb2a6c9fbce8a4e36708731e1f80 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Sun, 25 Jun 2017 17:35:04 +0800 Subject: [PATCH] close rows if possible (#629) --- rows.go | 7 ++++++- session.go | 13 ++++++++++--- session_get.go | 50 +++++++++++++++++++++++++++++--------------------- 3 files changed, 45 insertions(+), 25 deletions(-) diff --git a/rows.go b/rows.go index 5aa4ffc3..bb9738cb 100644 --- a/rows.go +++ b/rows.go @@ -122,8 +122,13 @@ func (rows *Rows) Scan(bean interface{}) error { if err := rows.session.Statement.setRefValue(dataStruct); err != nil { 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 } diff --git a/session.go b/session.go index de4a1a04..76d7cb28 100644 --- a/session.go +++ b/session.go @@ -299,7 +299,12 @@ func (session *Session) rows2Beans(rows *core.Rows, fields []string, fieldsCount var newValue = newElemFunc(fields) bean := newValue.Interface() 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 { return err } @@ -312,8 +317,7 @@ func (session *Session) rows2Beans(rows *core.Rows, fields []string, fieldsCount return nil } -func (session *Session) row2Bean(rows *core.Rows, fields []string, fieldsCount int, bean interface{}, dataStruct *reflect.Value, table *core.Table) (core.PK, error) { - // handle beforeClosures +func (session *Session) row2Slice(rows *core.Rows, fields []string, fieldsCount int, bean interface{}) ([]interface{}, error) { for _, closure := range session.beforeClosures { closure(bean) } @@ -332,7 +336,10 @@ func (session *Session) row2Bean(rows *core.Rows, fields []string, fieldsCount i 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() { if b, hasAfterSet := bean.(AfterSetProcessor); hasAfterSet { for ii, key := range fields { diff --git a/session_get.go b/session_get.go index 64203513..70bc9676 100644 --- a/session_get.go +++ b/session_get.go @@ -78,30 +78,38 @@ func (session *Session) nocacheGet(beanKind reflect.Kind, bean interface{}, sqlS defer rawRows.Close() - if rawRows.Next() { - switch beanKind { - case reflect.Struct: - fields, err := rawRows.Columns() - if err != nil { - // WARN: Alougth rawRows return true, but get fields failed - return true, err - } - dataStruct := rValue(bean) - if err := session.Statement.setRefValue(dataStruct); err != nil { - return false, err - } - _, err = session.row2Bean(rawRows, fields, len(fields), bean, &dataStruct, session.Statement.RefTable) - case reflect.Slice: - err = rawRows.ScanSlice(bean) - case reflect.Map: - err = rawRows.ScanMap(bean) - default: - err = rawRows.Scan(bean) + if !rawRows.Next() { + return false, nil + } + + switch beanKind { + case reflect.Struct: + fields, err := rawRows.Columns() + if err != nil { + // WARN: Alougth rawRows return true, but get fields failed + return true, err + } + dataStruct := rValue(bean) + if err := session.Statement.setRefValue(dataStruct); err != nil { + return false, err } - return true, err + 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: + err = rawRows.ScanSlice(bean) + case reflect.Map: + err = rawRows.ScanMap(bean) + default: + err = rawRows.Scan(bean) } - return false, nil + + return true, err } func (session *Session) cacheGet(bean interface{}, sqlStr string, args ...interface{}) (has bool, err error) {