Skip to content

Commit

Permalink
Add test for calling scanMulti multiple times with the same cols (go-…
Browse files Browse the repository at this point in the history
  • Loading branch information
aligator committed May 27, 2022
1 parent 6ddb27e commit 489ed4c
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 0 deletions.
86 changes: 86 additions & 0 deletions cursor_test.go
Expand Up @@ -304,3 +304,89 @@ func TestScanMulti_fieldsError(t *testing.T) {
assert.Equal(t, err, scanMulti(cur, keyField, keyType, cols))
cur.AssertExpectations(t)
}

func TestScanMulti_multipleTimes(t *testing.T) {
var (
users = make([][]User, 6)
cur = &testCursor{}
keyField = "id"
keyType = reflect.TypeOf(0)
cols = map[interface{}][]slice{
10: {NewCollection(&users[0]), NewCollection(&users[1])},
11: {NewCollection(&users[2])},
12: {NewCollection(&users[3]), NewCollection(&users[4])},
13: {NewCollection(&users[5])},
}
now = Now()
)

cur.On("Close").Return(nil).Once()
cur.On("Fields").Return([]string{"id", "name", "age", "created_at", "updated_at"}, nil).Once()

cur.On("Next").Return(true).Twice()
cur.MockScan(10, "Del Piero", nil, now, nil).Times(3)
cur.MockScan(11, "Nedved", 46, now, now).Twice()
cur.On("Next").Return(false).Once()

assert.Nil(t, scanMulti(cur, keyField, keyType, cols))
assert.Len(t, users[0], 1)
assert.Equal(t, User{
ID: 10,
Name: "Del Piero",
CreatedAt: now,
}, users[0][0])
assert.Len(t, users[1], 1)
assert.Equal(t, User{
ID: 10,
Name: "Del Piero",
CreatedAt: now,
}, users[1][0])
assert.Len(t, users[2], 1)
assert.Equal(t, User{
ID: 11,
Name: "Nedved",
Age: 46,
CreatedAt: now,
UpdatedAt: now,
}, users[2][0])

cur.AssertExpectations(t)

// Continue with a new cursor but the same cols -> works only if the ids in
// the subsequent calls did not occur yet.
cur = &testCursor{}

cur.On("Close").Return(nil).Once()
cur.On("Fields").Return([]string{"id", "name", "age", "created_at", "updated_at"}, nil).Once()

cur.On("Next").Return(true).Twice()
cur.MockScan(12, "Linus Torvalds", 52, now, nil).Times(3)
cur.MockScan(13, "Tim Cook", 61, now, now).Twice()
cur.On("Next").Return(false).Once()

assert.Nil(t, scanMulti(cur, keyField, keyType, cols))
assert.Len(t, users[3], 1)
assert.Equal(t, User{
ID: 12,
Name: "Linus Torvalds",
Age: 52,
CreatedAt: now,
}, users[3][0])
assert.Len(t, users[4], 1)
assert.Equal(t, User{
ID: 12,
Age: 52,
Name: "Linus Torvalds",
CreatedAt: now,
}, users[4][0])
assert.Len(t, users[5], 1)
assert.Equal(t, User{
ID: 13,
Name: "Tim Cook",
Age: 61,
CreatedAt: now,
UpdatedAt: now,
}, users[5][0])

cur.AssertExpectations(t)
}
3 changes: 3 additions & 0 deletions repository.go
Expand Up @@ -1062,6 +1062,9 @@ func (r repository) preload(cw contextWrapper, records slice, field string, quer
}

scanFinish := r.instrumenter.Observe(cw.ctx, "rel-scan-multi", "scanning all records to multiple targets")
// Note: Calling scanMulti multiple times with the same targets works
// only if the cursor of each execution only contains a new set of keys.
// That is here the case as each select is with a unique set of ids.
err = scanMulti(cur, keyField, keyType, targets)
scanFinish(err)
if err != nil {
Expand Down

0 comments on commit 489ed4c

Please sign in to comment.