From 14a0c19a0c92de6c3c65d6ba9f7251b3aaf77ae7 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Mon, 20 Jan 2020 05:28:07 +0000 Subject: [PATCH] fix bug when buffersize with iterate (#941) Merge branch 'master' into lunny/fix_buffer_iterate Exclude schema from index name (#1505) Merge branch 'master' into fix-schema-idx SetExpr support more go types (#1499) Improve tests SetExpr support more go types fix vet fix drone lint remove go1.10 test on drone Reviewed-on: https://gitea.com/xorm/xorm/pulls/1499 fix vet fix drone lint remove go1.10 test on drone Exclude schema from the index name Co-authored-by: Guillermo Prandi Co-authored-by: Lunny Xiao Reviewed-on: https://gitea.com/xorm/xorm/pulls/1505 fix test fix bug fix bug when buffersize with iterate SetExpr support more go types (#1499) Improve tests SetExpr support more go types fix vet fix drone lint remove go1.10 test on drone Reviewed-on: https://gitea.com/xorm/xorm/pulls/1499 fix vet fix drone lint remove go1.10 test on drone Fix update with Alias (#1455) Co-authored-by: Guillermo Prandi Reviewed-on: https://gitea.com/xorm/xorm/pulls/941 --- session_iterate.go | 27 +++++++++++++++------------ session_iterate_test.go | 11 +++++++++++ 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/session_iterate.go b/session_iterate.go index ca996c28..a1642bb3 100644 --- a/session_iterate.go +++ b/session_iterate.go @@ -4,7 +4,9 @@ package xorm -import "reflect" +import ( + "reflect" +) // IterFunc only use by Iterate type IterFunc func(idx int, bean interface{}) error @@ -60,10 +62,6 @@ func (session *Session) BufferSize(size int) *Session { } func (session *Session) bufferIterate(bean interface{}, fun IterFunc) error { - if session.isAutoClose { - defer session.Close() - } - var bufferSize = session.statement.bufferSize var limit = session.statement.LimitN if limit > 0 && bufferSize > limit { @@ -73,9 +71,14 @@ func (session *Session) bufferIterate(bean interface{}, fun IterFunc) error { v := rValue(bean) sliceType := reflect.SliceOf(v.Type()) var idx = 0 - for { + session.autoResetStatement = false + defer func() { + session.autoResetStatement = true + }() + + for bufferSize > 0 { slice := reflect.New(sliceType) - if err := session.Limit(bufferSize, start).find(slice.Interface(), bean); err != nil { + if err := session.NoCache().Limit(bufferSize, start).find(slice.Interface(), bean); err != nil { return err } @@ -86,13 +89,13 @@ func (session *Session) bufferIterate(bean interface{}, fun IterFunc) error { idx++ } - start = start + slice.Elem().Len() - if limit > 0 && idx+bufferSize > limit { - bufferSize = limit - idx + if bufferSize > slice.Elem().Len() { + break } - if bufferSize <= 0 || slice.Elem().Len() < bufferSize || idx == limit { - break + start = start + slice.Elem().Len() + if limit > 0 && start+bufferSize > limit { + bufferSize = limit - start } } diff --git a/session_iterate_test.go b/session_iterate_test.go index 9a7ec25f..bb0c59c4 100644 --- a/session_iterate_test.go +++ b/session_iterate_test.go @@ -89,4 +89,15 @@ func TestBufferIterate(t *testing.T) { }) assert.NoError(t, err) assert.EqualValues(t, 7, cnt) + + cnt = 0 + err = testEngine.Where("id <= 10").BufferSize(2).Iterate(new(UserBufferIterate), func(i int, bean interface{}) error { + user := bean.(*UserBufferIterate) + assert.EqualValues(t, cnt+1, user.Id) + assert.EqualValues(t, true, user.IsMan) + cnt++ + return nil + }) + assert.NoError(t, err) + assert.EqualValues(t, 10, cnt) }