Skip to content

Commit 10b9f1a

Browse files
committed
Scan: support Count
1 parent 43369c8 commit 10b9f1a

File tree

2 files changed

+65
-0
lines changed

2 files changed

+65
-0
lines changed

scan.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,58 @@ func (s *Scan) AllWithLastEvaluatedKeyContext(ctx aws.Context, out interface{})
139139
return itr.LastEvaluatedKey(), itr.Err()
140140
}
141141

142+
// Count executes this request and returns the number of items matching the scan.
143+
// It takes into account the filter, limit, search limit, and all other parameters given.
144+
// It may return a higher count than the limits.
145+
func (s *Scan) Count() (int64, error) {
146+
ctx, cancel := defaultContext()
147+
defer cancel()
148+
return s.CountWithContext(ctx)
149+
}
150+
151+
// CountWithContext executes this request and returns the number of items matching the scan.
152+
// It takes into account the filter, limit, search limit, and all other parameters given.
153+
// It may return a higher count than the limits.
154+
func (s *Scan) CountWithContext(ctx aws.Context) (int64, error) {
155+
if s.err != nil {
156+
return 0, s.err
157+
}
158+
var count, scanned int64
159+
input := s.scanInput()
160+
input.Select = aws.String(dynamodb.SelectCount)
161+
for {
162+
var out *dynamodb.ScanOutput
163+
err := retry(ctx, func() error {
164+
var err error
165+
out, err = s.table.db.client.ScanWithContext(ctx, input)
166+
return err
167+
})
168+
if err != nil {
169+
return count, err
170+
}
171+
172+
count += *out.Count
173+
scanned += *out.ScannedCount
174+
175+
if s.cc != nil {
176+
addConsumedCapacity(s.cc, out.ConsumedCapacity)
177+
}
178+
179+
if s.limit > 0 && count >= s.limit {
180+
break
181+
}
182+
if s.searchLimit > 0 && scanned >= s.searchLimit {
183+
break
184+
}
185+
if out.LastEvaluatedKey == nil {
186+
break
187+
}
188+
189+
input.ExclusiveStartKey = out.LastEvaluatedKey
190+
}
191+
return count, nil
192+
}
193+
142194
func (s *Scan) scanInput() *dynamodb.ScanInput {
143195
input := &dynamodb.ScanInput{
144196
ExclusiveStartKey: s.startKey,

scan_test.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,19 @@ func TestScan(t *testing.T) {
4242
t.Error("bad consumed capacity", cc)
4343
}
4444

45+
// check this against Scan's count, too
46+
var cc2 ConsumedCapacity
47+
scanCt, err := table.Scan().Filter("UserID = ?", 42).Consistent(true).ConsumedCapacity(&cc2).Count()
48+
if err != nil {
49+
t.Error("unexpected error:", err)
50+
}
51+
if scanCt != ct {
52+
t.Errorf("scan count and get count don't match. scan count: %d, get count: %d", scanCt, ct)
53+
}
54+
if cc2.Total == 0 {
55+
t.Error("bad consumed capacity", cc2)
56+
}
57+
4558
// search for our inserted item
4659
found := false
4760
for _, w := range result {

0 commit comments

Comments
 (0)