Skip to content

Commit 929601d

Browse files
authored
Add RequestLimit (#234)
* support for RequestLimit in Count * more docs
1 parent 8e12eac commit 929601d

File tree

4 files changed

+41
-26
lines changed

4 files changed

+41
-26
lines changed

encoding.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,13 @@ var typeCache sync.Map // unmarshalKey → *typedef
1616
type typedef struct {
1717
decoders map[unmarshalKey]decodeFunc
1818
fields []structField
19-
root reflect.Type
2019
info *structInfo
2120
}
2221

2322
func newTypedef(rt reflect.Type) (*typedef, error) {
2423
def := &typedef{
2524
decoders: make(map[unmarshalKey]decodeFunc),
2625
// encoders: make(map[encodeKey]encodeFunc),
27-
root: rt,
2826
}
2927
err := def.init(rt)
3028
return def, err

query.go

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -185,10 +185,11 @@ func (q *Query) SearchLimit(limit int64) *Query {
185185
}
186186

187187
// RequestLimit specifies the maximum amount of requests to make against DynamoDB's API.
188-
// func (q *Query) RequestLimit(limit int) *Query {
189-
// q.reqLimit = limit
190-
// return q
191-
// }
188+
// A limit of zero or less means unlimited requests.
189+
func (q *Query) RequestLimit(limit int) *Query {
190+
q.reqLimit = limit
191+
return q
192+
}
192193

193194
// Order specifies the desired result order.
194195
// Requires a range key (a.k.a. partition key) to be specified.
@@ -286,22 +287,29 @@ func (q *Query) CountWithContext(ctx context.Context) (int64, error) {
286287
return 0, q.err
287288
}
288289

289-
var count int64
290+
var count, scanned int64
291+
var reqs int
290292
var res *dynamodb.QueryOutput
291293
for {
292-
req := q.queryInput()
293-
req.Select = selectCount
294+
input := q.queryInput()
295+
input.Select = selectCount
294296

295297
err := q.table.db.retry(ctx, func() error {
296298
var err error
297-
res, err = q.table.db.client.QueryWithContext(ctx, req)
299+
res, err = q.table.db.client.QueryWithContext(ctx, input)
298300
if err != nil {
299301
return err
300302
}
303+
reqs++
304+
301305
if res.Count == nil {
302-
return errors.New("nil count")
306+
return errors.New("malformed DynamoDB response: count is nil")
303307
}
304308
count += *res.Count
309+
if res.ScannedCount != nil {
310+
scanned += *res.ScannedCount
311+
}
312+
305313
return nil
306314
})
307315
if err != nil {
@@ -312,7 +320,10 @@ func (q *Query) CountWithContext(ctx context.Context) (int64, error) {
312320
}
313321

314322
q.startKey = res.LastEvaluatedKey
315-
if res.LastEvaluatedKey == nil || q.searchLimit > 0 {
323+
if res.LastEvaluatedKey == nil ||
324+
(q.limit > 0 && count >= q.limit) ||
325+
(q.searchLimit > 0 && scanned >= q.searchLimit) ||
326+
(q.reqLimit > 0 && reqs >= q.reqLimit) {
316327
break
317328
}
318329
}

reflect.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,11 +193,11 @@ type encodeKey struct {
193193

194194
type structInfo struct {
195195
root reflect.Type
196+
parent *structInfo
196197
fields map[string]*structField // by name
197198
refs map[encodeKey][]*structField
198199
types map[encodeKey]encodeFunc
199200
zeros map[reflect.Type]func(reflect.Value) bool
200-
parent *structInfo
201201

202202
seen map[encodeKey]struct{}
203203
queue []encodeKey

scan.go

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package dynamo
22

33
import (
44
"context"
5+
"errors"
56
"strings"
67
"sync"
78

@@ -131,10 +132,11 @@ func (s *Scan) SearchLimit(limit int64) *Scan {
131132
}
132133

133134
// RequestLimit specifies the maximum amount of requests to make against DynamoDB's API.
134-
// func (s *Scan) RequestLimit(limit int) *Scan {
135-
// s.reqLimit = limit
136-
// return s
137-
// }
135+
// A limit of zero or less means unlimited requests.
136+
func (s *Scan) RequestLimit(limit int) *Scan {
137+
s.reqLimit = limit
138+
return s
139+
}
138140

139141
// ConsumedCapacity will measure the throughput capacity consumed by this operation and add it to cc.
140142
func (s *Scan) ConsumedCapacity(cc *ConsumedCapacity) *Scan {
@@ -260,6 +262,7 @@ func (s *Scan) CountWithContext(ctx context.Context) (int64, error) {
260262
var count, scanned int64
261263
input := s.scanInput()
262264
input.Select = aws.String(dynamodb.SelectCount)
265+
var reqs int
263266
for {
264267
var out *dynamodb.ScanOutput
265268
err := s.table.db.retry(ctx, func() error {
@@ -268,23 +271,26 @@ func (s *Scan) CountWithContext(ctx context.Context) (int64, error) {
268271
return err
269272
})
270273
if err != nil {
271-
return count, err
274+
return 0, err
272275
}
276+
reqs++
273277

278+
if out.Count == nil {
279+
return count, errors.New("malformed DynamoDB outponse: count is nil")
280+
}
274281
count += *out.Count
275-
scanned += *out.ScannedCount
282+
if out.ScannedCount != nil {
283+
scanned += *out.ScannedCount
284+
}
276285

277286
if s.cc != nil {
278287
addConsumedCapacity(s.cc, out.ConsumedCapacity)
279288
}
280289

281-
if s.limit > 0 && count >= s.limit {
282-
break
283-
}
284-
if s.searchLimit > 0 && scanned >= s.searchLimit {
285-
break
286-
}
287-
if out.LastEvaluatedKey == nil {
290+
if out.LastEvaluatedKey == nil ||
291+
(s.limit > 0 && count >= s.limit) ||
292+
(s.searchLimit > 0 && scanned >= s.searchLimit) ||
293+
(s.reqLimit > 0 && reqs >= s.reqLimit) {
288294
break
289295
}
290296

0 commit comments

Comments
 (0)