@@ -588,33 +588,19 @@ trait AmazonDynamoDBScalaMapper {
588
588
def scan [T ](
589
589
scanFilter : Map [String , Condition ] = Map .empty
590
590
)(implicit serializer : DynamoDBSerializer [T ]): Future [Seq [T ]] = {
591
- val scanRequest =
592
- new ScanRequest ()
593
- .withTableName(tableName)
594
- .withScanFilter(scanFilter.asJava)
595
- if (logger.isDebugEnabled)
596
- scanRequest.setReturnConsumedCapacity(ReturnConsumedCapacity .TOTAL )
597
-
598
591
val builder = Seq .newBuilder[T ]
599
592
600
- def local (lastKey : Option [DynamoDBKey ] = None ): Future [Unit ] =
601
- client.scan(
602
- scanRequest.withExclusiveStartKey(lastKey.orNull)
603
- ) flatMap { result =>
604
- if (logger.isDebugEnabled)
605
- logger.debug(s " scan() ConsumedCapacity = ${result.getConsumedCapacity()}" )
606
-
607
- builder ++= result.getItems.asScala.view map { item =>
608
- serializer.fromAttributeMap(item.asScala)
609
- }
610
-
611
- Option { result.getLastEvaluatedKey } match {
612
- case None => Future .successful(())
613
- case optKey => local(optKey)
614
- }
593
+ def local (lastKey : Option [DynamoDBKey ] = None ): Future [Seq [T ]] =
594
+ scanProgressively(scanFilter, lastEvaluatedKey = lastKey).flatMap {
595
+ case (key, result) =>
596
+ builder ++= result
597
+ key match {
598
+ case None => Future .successful(builder.result())
599
+ case optKey => local(optKey)
600
+ }
615
601
}
616
602
617
- local() map { _ => builder.result }
603
+ local()
618
604
}
619
605
620
606
/**
@@ -634,27 +620,59 @@ trait AmazonDynamoDBScalaMapper {
634
620
scanFilter : Map [String , Condition ] = Map .empty,
635
621
limit : Int = 0
636
622
)(implicit serializer : DynamoDBSerializer [T ]): Future [Seq [T ]] = {
623
+ scanProgressively(scanFilter, limit).map(_._2)
624
+ }
625
+
626
+ /**
627
+ * Scan a table.
628
+ *
629
+ * This method will issue one scan request, stopping either
630
+ * at the supplied limit or at the response size limit.
631
+ *
632
+ * @param scanFilter
633
+ * the optional filter conditions for the scan.
634
+ * @param lastEvaluatedKey
635
+ * the optional starting key.
636
+ * @param limit
637
+ * the optional limit for the number of items to return.
638
+ * @return Tuple of
639
+ * some last dynamoDB key or none if the "end" of the scan is reached
640
+ * and sequence of scanned objects in a future.
641
+ * @see [[countScan ]]
642
+ */
643
+ def scanProgressively [T ](
644
+ scanFilter : Map [String , Condition ] = Map .empty,
645
+ limit : Int = 0 ,
646
+ lastEvaluatedKey : Option [DynamoDBKey ] = None
647
+ )(implicit serializer : DynamoDBSerializer [T ]): Future [(Option [DynamoDBKey ], Seq [T ])] = {
637
648
val scanRequest =
638
649
new ScanRequest ()
639
- .withTableName(tableName)
640
- .withScanFilter(scanFilter.asJava)
650
+ .withTableName(tableName)
651
+ .withScanFilter(scanFilter.asJava)
652
+
641
653
if (limit > 0 )
642
654
scanRequest.setLimit(limit)
655
+
643
656
if (logger.isDebugEnabled)
644
657
scanRequest.setReturnConsumedCapacity(ReturnConsumedCapacity .TOTAL )
645
658
646
- client.scan(scanRequest) map { result =>
659
+ client.scan(
660
+ scanRequest.withExclusiveStartKey(lastEvaluatedKey.orNull)
661
+ ) map { result =>
647
662
if (logger.isDebugEnabled)
648
663
logger.debug(s " scanOnce() ConsumedCapacity = ${result.getConsumedCapacity()}" )
649
664
650
- result.getItems.asScala.view map { item =>
665
+ val r = result.getItems.asScala map { item =>
651
666
serializer.fromAttributeMap(item.asScala)
652
667
}
668
+
669
+ val lastEvaluatedKey = Option {
670
+ result.getLastEvaluatedKey
671
+ }
672
+ (lastEvaluatedKey, r)
653
673
}
654
674
}
655
675
656
-
657
-
658
676
/**
659
677
* Scan a table and return a count.
660
678
*
0 commit comments