embulk-input-dynamodb 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/master.yml +34 -0
  3. data/.github/workflows/test.yml +30 -0
  4. data/.scalafmt.conf +5 -0
  5. data/CHANGELOG.md +49 -0
  6. data/README.md +204 -54
  7. data/build.gradle +53 -44
  8. data/example/config-deprecated.yml +20 -0
  9. data/example/config-query-as-json.yml +18 -0
  10. data/example/config-query.yml +22 -0
  11. data/example/config-scan.yml +18 -0
  12. data/example/prepare_dynamodb_table.sh +67 -0
  13. data/gradle/wrapper/gradle-wrapper.jar +0 -0
  14. data/gradle/wrapper/gradle-wrapper.properties +1 -2
  15. data/gradlew +67 -48
  16. data/gradlew.bat +20 -10
  17. data/{test/run_dynamodb_local.sh → run_dynamodb_local.sh} +2 -1
  18. data/settings.gradle +1 -0
  19. data/src/main/scala/org/embulk/input/dynamodb/DeprecatedDynamodbInputPlugin.scala +73 -0
  20. data/src/main/scala/org/embulk/input/dynamodb/DynamodbInputPlugin.scala +76 -25
  21. data/src/main/scala/org/embulk/input/dynamodb/PluginTask.scala +132 -32
  22. data/src/main/scala/org/embulk/input/dynamodb/aws/Aws.scala +44 -0
  23. data/src/main/scala/org/embulk/input/dynamodb/aws/AwsClientConfiguration.scala +37 -0
  24. data/src/main/scala/org/embulk/input/dynamodb/aws/AwsCredentials.scala +240 -0
  25. data/src/main/scala/org/embulk/input/dynamodb/aws/AwsDynamodbConfiguration.scala +35 -0
  26. data/src/main/scala/org/embulk/input/dynamodb/aws/AwsEndpointConfiguration.scala +79 -0
  27. data/src/main/scala/org/embulk/input/dynamodb/aws/HttpProxy.scala +61 -0
  28. data/src/main/scala/org/embulk/input/dynamodb/deprecated/AttributeValueHelper.scala +72 -0
  29. data/src/main/scala/org/embulk/input/dynamodb/{Filter.scala → deprecated/Filter.scala} +3 -3
  30. data/src/main/scala/org/embulk/input/dynamodb/{FilterConfig.scala → deprecated/FilterConfig.scala} +13 -13
  31. data/src/main/scala/org/embulk/input/dynamodb/{ope → deprecated/ope}/AbstractOperation.scala +36 -18
  32. data/src/main/scala/org/embulk/input/dynamodb/{ope → deprecated/ope}/QueryOperation.scala +21 -13
  33. data/src/main/scala/org/embulk/input/dynamodb/{ope → deprecated/ope}/ScanOperation.scala +20 -13
  34. data/src/main/scala/org/embulk/input/dynamodb/item/DynamodbAttributeValue.scala +154 -0
  35. data/src/main/scala/org/embulk/input/dynamodb/item/DynamodbAttributeValueEmbulkTypeTransformable.scala +245 -0
  36. data/src/main/scala/org/embulk/input/dynamodb/item/DynamodbAttributeValueType.scala +33 -0
  37. data/src/main/scala/org/embulk/input/dynamodb/item/DynamodbItemColumnVisitor.scala +50 -0
  38. data/src/main/scala/org/embulk/input/dynamodb/item/DynamodbItemConsumer.scala +40 -0
  39. data/src/main/scala/org/embulk/input/dynamodb/item/DynamodbItemIterator.scala +19 -0
  40. data/src/main/scala/org/embulk/input/dynamodb/item/DynamodbItemReader.scala +64 -0
  41. data/src/main/scala/org/embulk/input/dynamodb/item/DynamodbItemSchema.scala +135 -0
  42. data/src/main/scala/org/embulk/input/dynamodb/operation/AbstractDynamodbOperation.scala +169 -0
  43. data/src/main/scala/org/embulk/input/dynamodb/operation/DynamodbOperationProxy.scala +59 -0
  44. data/src/main/scala/org/embulk/input/dynamodb/operation/DynamodbQueryOperation.scala +72 -0
  45. data/src/main/scala/org/embulk/input/dynamodb/operation/DynamodbScanOperation.scala +93 -0
  46. data/src/main/scala/org/embulk/input/dynamodb/operation/EmbulkDynamodbOperation.scala +15 -0
  47. data/src/main/scala/org/embulk/input/dynamodb/package.scala +4 -9
  48. data/src/test/scala/org/embulk/input/dynamodb/AttributeValueHelperTest.scala +245 -101
  49. data/src/test/scala/org/embulk/input/dynamodb/AwsCredentialsTest.scala +150 -97
  50. data/src/test/scala/org/embulk/input/dynamodb/DynamodbQueryOperationTest.scala +188 -0
  51. data/src/test/scala/org/embulk/input/dynamodb/DynamodbScanOperationTest.scala +181 -0
  52. data/src/test/scala/org/embulk/input/dynamodb/testutil/EmbulkTestBase.scala +85 -0
  53. metadata +73 -49
  54. data/circle.yml +0 -16
  55. data/config/checkstyle/checkstyle.xml +0 -128
  56. data/config/checkstyle/default.xml +0 -108
  57. data/src/main/scala/org/embulk/input/dynamodb/AttributeValueHelper.scala +0 -41
  58. data/src/main/scala/org/embulk/input/dynamodb/AwsCredentials.scala +0 -63
  59. data/src/main/scala/org/embulk/input/dynamodb/DynamoDBClient.scala +0 -23
  60. data/src/test/resources/yaml/authMethodBasic.yml +0 -21
  61. data/src/test/resources/yaml/authMethodBasic_Error.yml +0 -19
  62. data/src/test/resources/yaml/authMethodEnv.yml +0 -19
  63. data/src/test/resources/yaml/authMethodProfile.yml +0 -20
  64. data/src/test/resources/yaml/dynamodb-local-query.yml +0 -25
  65. data/src/test/resources/yaml/dynamodb-local-scan.yml +0 -23
  66. data/src/test/resources/yaml/notSetAuthMethod.yml +0 -20
  67. data/src/test/scala/org/embulk/input/dynamodb/ope/QueryOperationTest.scala +0 -83
  68. data/src/test/scala/org/embulk/input/dynamodb/ope/ScanOperationTest.scala +0 -83
  69. data/test/create_table.sh +0 -16
  70. data/test/put_items.sh +0 -25
@@ -0,0 +1,35 @@
1
+ package org.embulk.input.dynamodb.aws
2
+
3
+ import java.util.Optional
4
+
5
+ import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder
6
+ import org.embulk.config.{Config, ConfigDefault}
7
+ import org.embulk.input.dynamodb.aws.AwsDynamodbConfiguration.Task
8
+
9
+ object AwsDynamodbConfiguration {
10
+
11
+ trait Task {
12
+
13
+ @Config("enable_endpoint_discovery")
14
+ @ConfigDefault("null")
15
+ def getEnableEndpointDiscovery: Optional[Boolean]
16
+
17
+ }
18
+
19
+ def apply(task: Task): AwsDynamodbConfiguration = {
20
+ new AwsDynamodbConfiguration(task)
21
+ }
22
+ }
23
+
24
+ class AwsDynamodbConfiguration(task: Task) {
25
+
26
+ def configureAmazonDynamoDBClientBuilder(
27
+ builder: AmazonDynamoDBClientBuilder
28
+ ): Unit = {
29
+ task.getEnableEndpointDiscovery.ifPresent { v =>
30
+ if (v) builder.enableEndpointDiscovery()
31
+ else builder.disableEndpointDiscovery()
32
+ }
33
+ }
34
+
35
+ }
@@ -0,0 +1,79 @@
1
+ package org.embulk.input.dynamodb.aws
2
+
3
+ import java.util.Optional
4
+
5
+ import com.amazonaws.client.builder.AwsClientBuilder
6
+ import com.amazonaws.client.builder.AwsClientBuilder.EndpointConfiguration
7
+ import com.amazonaws.regions.{DefaultAwsRegionProviderChain, Regions}
8
+ import org.embulk.config.{Config, ConfigDefault, ConfigException}
9
+ import org.embulk.input.dynamodb.aws.AwsEndpointConfiguration.Task
10
+ import org.embulk.input.dynamodb.logger
11
+ import zio.macros.annotation.delegate
12
+
13
+ import scala.util.Try
14
+
15
+ object AwsEndpointConfiguration {
16
+
17
+ trait Task {
18
+
19
+ @deprecated(message = "Use #getEndpoint() instead.", since = "0.3.0")
20
+ @Config("end_point")
21
+ @ConfigDefault("null")
22
+ def getEndPoint: Optional[String]
23
+
24
+ @Config("endpoint")
25
+ @ConfigDefault("null")
26
+ def getEndpoint: Optional[String]
27
+
28
+ @Config("region")
29
+ @ConfigDefault("null")
30
+ def getRegion: Optional[String]
31
+ }
32
+
33
+ def apply(task: Task): AwsEndpointConfiguration = {
34
+ new AwsEndpointConfiguration(AwsEndpointConfigurationTaskCompat(task))
35
+ }
36
+ }
37
+
38
+ case class AwsEndpointConfigurationTaskCompat(@delegate task: Task)
39
+ extends Task {
40
+ override def getEndPoint: Optional[String] = throw new NotImplementedError()
41
+
42
+ override def getEndpoint: Optional[String] = {
43
+ if (task.getEndpoint.isPresent && task.getEndPoint.isPresent)
44
+ throw new ConfigException(
45
+ "You cannot use both \"endpoint\" option and \"end_point\" option. Use \"endpoint\" option."
46
+ )
47
+ if (task.getEndPoint.isPresent) {
48
+ logger.warn(
49
+ "[Deprecated] \"end_point\" option is deprecated. Use \"endpoint\" option instead."
50
+ )
51
+ return task.getEndPoint
52
+ }
53
+ task.getEndpoint
54
+ }
55
+ }
56
+
57
+ class AwsEndpointConfiguration(task: Task) {
58
+
59
+ def configureAwsClientBuilder[S <: AwsClientBuilder[S, T], T](
60
+ builder: AwsClientBuilder[S, T]
61
+ ): Unit = {
62
+ if (task.getRegion.isPresent && task.getEndpoint.isPresent) {
63
+ val ec =
64
+ new EndpointConfiguration(task.getEndpoint.get, task.getRegion.get)
65
+ builder.setEndpointConfiguration(ec)
66
+ }
67
+ else if (task.getRegion.isPresent && !task.getEndpoint.isPresent) {
68
+ builder.setRegion(task.getRegion.get)
69
+ }
70
+ else if (!task.getRegion.isPresent && task.getEndpoint.isPresent) {
71
+ val r: String = Try(new DefaultAwsRegionProviderChain().getRegion)
72
+ .getOrElse(Regions.DEFAULT_REGION.getName)
73
+ val e: String = task.getEndpoint.get
74
+ val ec = new EndpointConfiguration(e, r)
75
+ builder.setEndpointConfiguration(ec)
76
+ }
77
+ }
78
+
79
+ }
@@ -0,0 +1,61 @@
1
+ package org.embulk.input.dynamodb.aws
2
+
3
+ import java.util.Optional
4
+
5
+ import com.amazonaws.{ClientConfiguration, Protocol}
6
+ import org.embulk.config.{Config, ConfigDefault, ConfigException}
7
+ import org.embulk.input.dynamodb.aws.HttpProxy.Task
8
+
9
+ object HttpProxy {
10
+
11
+ trait Task {
12
+
13
+ @Config("host")
14
+ @ConfigDefault("null")
15
+ def getHost: Optional[String]
16
+
17
+ @Config("port")
18
+ @ConfigDefault("null")
19
+ def getPort: Optional[Int]
20
+
21
+ @Config("protocol")
22
+ @ConfigDefault("\"https\"")
23
+ def getProtocol: String
24
+
25
+ @Config("user")
26
+ @ConfigDefault("null")
27
+ def getUser: Optional[String]
28
+
29
+ @Config("password")
30
+ @ConfigDefault("null")
31
+ def getPassword: Optional[String]
32
+
33
+ }
34
+
35
+ def apply(task: Task): HttpProxy = {
36
+ new HttpProxy(task)
37
+ }
38
+
39
+ }
40
+
41
+ class HttpProxy(task: Task) {
42
+
43
+ def configureClientConfiguration(cc: ClientConfiguration): Unit = {
44
+ task.getHost.ifPresent(v => cc.setProxyHost(v))
45
+ task.getPort.ifPresent(v => cc.setProxyPort(v))
46
+
47
+ Protocol.values.find(p => p.name().equals(task.getProtocol)) match {
48
+ case Some(v) =>
49
+ cc.setProtocol(v)
50
+ case None =>
51
+ throw new ConfigException(
52
+ s"'${task.getProtocol}' is unsupported: `protocol` must be one of [${Protocol.values
53
+ .map(v => s"'$v'")
54
+ .mkString(", ")}]."
55
+ )
56
+ }
57
+
58
+ task.getUser.ifPresent(v => cc.setProxyUsername(v))
59
+ task.getPassword.ifPresent(v => cc.setProxyPassword(v))
60
+ }
61
+ }
@@ -0,0 +1,72 @@
1
+ package org.embulk.input.dynamodb.deprecated
2
+
3
+ import com.amazonaws.services.dynamodbv2.model.AttributeValue
4
+ import org.msgpack.value.{Value, ValueFactory}
5
+
6
+ import scala.util.Try
7
+
8
+ object AttributeValueHelper {
9
+
10
+ // referring aws-scala
11
+ def decodeToValue(value: AttributeValue): Value = {
12
+ import scala.jdk.CollectionConverters._
13
+
14
+ // FIXME: Need Encode?
15
+ lazy val _bin = Option(value.getB).map(v => ValueFactory.newBinary(v.array))
16
+ lazy val _bool = Option(value.getBOOL).map(v => ValueFactory.newBoolean(v))
17
+ lazy val _num = Option(value.getN).map(v =>
18
+ Try(v.toLong)
19
+ .map(ValueFactory.newInteger)
20
+ .getOrElse(ValueFactory.newFloat(v.toDouble))
21
+ )
22
+ lazy val _str = Option(value.getS).map(v => ValueFactory.newString(v))
23
+ lazy val _nil = Option(value.getNULL).map(v => ValueFactory.newNil)
24
+
25
+ lazy val _list = Option(value.getL).map(l =>
26
+ ValueFactory.newArray(l.asScala.map(v => decodeToValue(v)).asJava)
27
+ )
28
+ lazy val _ss = Option(value.getSS).map(l =>
29
+ ValueFactory.newArray(
30
+ l.asScala.map(v => ValueFactory.newString(v)).asJava
31
+ )
32
+ )
33
+ lazy val _ns = Option(value.getNS).map(l =>
34
+ ValueFactory.newArray(
35
+ l.asScala
36
+ .map(v =>
37
+ Try(v.toLong)
38
+ .map(ValueFactory.newInteger)
39
+ .getOrElse(ValueFactory.newFloat(v.toDouble))
40
+ )
41
+ .asJava
42
+ )
43
+ )
44
+ // FIXME: Need Encode?
45
+ lazy val _bs = Option(value.getBS).map(l =>
46
+ ValueFactory.newArray(
47
+ l.asScala.map(v => ValueFactory.newBinary(v.array)).asJava
48
+ )
49
+ )
50
+ lazy val _map = Option(value.getM).map(m =>
51
+ ValueFactory.newMap(
52
+ m.asScala
53
+ .map(v => ValueFactory.newString(v._1) -> decodeToValue(v._2))
54
+ .asJava
55
+ )
56
+ )
57
+
58
+ _bin
59
+ .orElse(_bool)
60
+ .orElse(_num)
61
+ .orElse(_str)
62
+ .orElse(_nil)
63
+ .orElse(_list)
64
+ .orElse(_ss)
65
+ .orElse(_ns)
66
+ .orElse(_bs)
67
+ .orElse(_map) match {
68
+ case None => ValueFactory.newNil
69
+ case Some(j) => j
70
+ }
71
+ }
72
+ }
@@ -1,4 +1,4 @@
1
- package org.embulk.input.dynamodb
1
+ package org.embulk.input.dynamodb.deprecated
2
2
 
3
3
  import java.util.{List => JList}
4
4
 
@@ -18,9 +18,9 @@ class Filter {
18
18
  def getFilters: JList[FilterConfig] = filters
19
19
 
20
20
  override def equals(obj: Any): Boolean = {
21
- if(this == obj) return true
21
+ if (this == obj) return true
22
22
 
23
- if(!obj.isInstanceOf[Filter]) return false
23
+ if (!obj.isInstanceOf[Filter]) return false
24
24
 
25
25
  val other: Filter = obj.asInstanceOf[Filter]
26
26
  Objects.equal(filters, other.filters)
@@ -1,4 +1,4 @@
1
- package org.embulk.input.dynamodb
1
+ package org.embulk.input.dynamodb.deprecated
2
2
 
3
3
  import com.fasterxml.jackson.annotation.JsonProperty
4
4
  import com.google.common.base.Objects
@@ -11,12 +11,12 @@ class FilterConfig {
11
11
  private var _value2: String = _
12
12
 
13
13
  def this(
14
- @JsonProperty("name") _name: String,
15
- @JsonProperty("type") _type: String,
16
- @JsonProperty("condition") _condition: String,
17
- @JsonProperty("value") _value: String,
18
- @JsonProperty("value2") _value2: String)
19
- {
14
+ @JsonProperty("name") _name: String,
15
+ @JsonProperty("type") _type: String,
16
+ @JsonProperty("condition") _condition: String,
17
+ @JsonProperty("value") _value: String,
18
+ @JsonProperty("value2") _value2: String
19
+ ) {
20
20
  this()
21
21
  this._name = _name
22
22
  this._type = _type
@@ -41,15 +41,15 @@ class FilterConfig {
41
41
  def getValue2 = _value2
42
42
 
43
43
  override def equals(obj: Any): Boolean = {
44
- if(this == obj) return true
44
+ if (this == obj) return true
45
45
 
46
- if(!obj.isInstanceOf[FilterConfig]) return false
46
+ if (!obj.isInstanceOf[FilterConfig]) return false
47
47
 
48
48
  val other: FilterConfig = obj.asInstanceOf[FilterConfig]
49
49
  Objects.equal(this._name, other._name) &&
50
- Objects.equal(this._type, other._type) &&
51
- Objects.equal(this._condition, other._condition) &&
52
- Objects.equal(this._value, other._value) &&
53
- Objects.equal(this._value2, other._value2)
50
+ Objects.equal(this._type, other._type) &&
51
+ Objects.equal(this._condition, other._condition) &&
52
+ Objects.equal(this._value, other._value) &&
53
+ Objects.equal(this._value2, other._value2)
54
54
  }
55
55
  }
@@ -1,12 +1,13 @@
1
- package org.embulk.input.dynamodb.ope
1
+ package org.embulk.input.dynamodb.deprecated.ope
2
2
 
3
3
  import com.amazonaws.services.dynamodbv2.model.{AttributeValue, Condition}
4
- import org.embulk.input.dynamodb.{AttributeValueHelper, PluginTask}
4
+ import org.embulk.input.dynamodb.PluginTask
5
+ import org.embulk.input.dynamodb.deprecated.AttributeValueHelper
5
6
  import org.embulk.spi._
6
7
  import org.embulk.spi.`type`.Types
7
8
  import org.msgpack.value.{Value, ValueFactory}
8
9
 
9
- import scala.collection.JavaConverters._
10
+ import scala.jdk.CollectionConverters._
10
11
 
11
12
  abstract class AbstractOperation {
12
13
  def execute(task: PluginTask, schema: Schema, output: PageOutput): Unit
@@ -14,20 +15,29 @@ abstract class AbstractOperation {
14
15
  def getLimit(limit: Long, recordLimit: Long, recordCount: Long): Int = {
15
16
  if (limit > 0 && recordLimit > 0) {
16
17
  math.min(limit, recordLimit - recordCount).toInt
17
- } else if (limit > 0 || recordLimit > 0) {
18
+ }
19
+ else if (limit > 0 || recordLimit > 0) {
18
20
  math.max(limit, recordLimit).toInt
19
- } else { 0 }
21
+ }
22
+ else {
23
+ 0
24
+ }
20
25
  }
21
26
 
22
27
  def createFilters(task: PluginTask): Map[String, Condition] = {
23
28
  val filterMap = collection.mutable.HashMap[String, Condition]()
24
29
 
25
- Option(task.getFilters.orNull).map { filters =>
30
+ Option(task.getFilters.orElse(null)).map { filters =>
26
31
  filters.getFilters.asScala.map { filter =>
27
- val attributeValueList = collection.mutable.ArrayBuffer[AttributeValue]()
28
- attributeValueList += createAttributeValue(filter.getType, filter.getValue)
32
+ val attributeValueList =
33
+ collection.mutable.ArrayBuffer[AttributeValue]()
34
+ attributeValueList += createAttributeValue(
35
+ filter.getType,
36
+ filter.getValue
37
+ )
29
38
  Option(filter.getValue2).map { value2 =>
30
- attributeValueList+= createAttributeValue(filter.getType, value2) }
39
+ attributeValueList += createAttributeValue(filter.getType, value2)
40
+ }
31
41
 
32
42
  filterMap += filter.getName -> new Condition()
33
43
  .withComparisonOperator(filter.getCondition)
@@ -49,7 +59,11 @@ abstract class AbstractOperation {
49
59
  }
50
60
  }
51
61
 
52
- def write(pageBuilder: PageBuilder, schema: Schema, items: Seq[Map[String, AttributeValue]]): Long = {
62
+ def write(
63
+ pageBuilder: PageBuilder,
64
+ schema: Schema,
65
+ items: Seq[Map[String, AttributeValue]]
66
+ ): Long = {
53
67
  var count = 0
54
68
 
55
69
  items.foreach { item =>
@@ -76,26 +90,30 @@ abstract class AbstractOperation {
76
90
  count
77
91
  }
78
92
 
79
- def convert[A](column: Column,
80
- value: Option[AttributeValue],
81
- f: (Column, A) => Unit)(implicit f1: Option[AttributeValue] => A): Unit =
93
+ def convert[A](
94
+ column: Column,
95
+ value: Option[AttributeValue],
96
+ f: (Column, A) => Unit
97
+ )(implicit f1: Option[AttributeValue] => A): Unit =
82
98
  f(column, f1(value))
83
99
 
84
100
  implicit def StringConvert(value: Option[AttributeValue]): String =
85
101
  value.map(_.getS).getOrElse("")
86
102
 
87
103
  implicit def LongConvert(value: Option[AttributeValue]): Long =
88
- value.map(_.getN.toLong).getOrElse(0L)
104
+ value.map(_.getN).flatMap(Option(_)).map(_.toLong).getOrElse(0L)
89
105
 
90
106
  implicit def DoubleConvert(value: Option[AttributeValue]): Double =
91
- value.map(_.getN.toDouble).getOrElse(0D)
107
+ value.map(_.getN).flatMap(Option(_)).map(_.toDouble).getOrElse(0d)
92
108
 
93
109
  implicit def BooleanConvert(value: Option[AttributeValue]): Boolean =
94
110
  value.exists(_.getBOOL)
95
111
 
96
112
  implicit def JsonConvert(value: Option[AttributeValue]): Value = {
97
- value.map { attr =>
98
- AttributeValueHelper.decodeToValue(attr)
99
- }.getOrElse(ValueFactory.newNil())
113
+ value
114
+ .map { attr =>
115
+ AttributeValueHelper.decodeToValue(attr)
116
+ }
117
+ .getOrElse(ValueFactory.newNil())
100
118
  }
101
119
  }
@@ -1,27 +1,35 @@
1
- package org.embulk.input.dynamodb.ope
1
+ package org.embulk.input.dynamodb.deprecated.ope
2
2
 
3
3
  import java.util.{List => JList, Map => JMap}
4
4
 
5
- import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient
6
- import com.amazonaws.services.dynamodbv2.model.{AttributeValue, Condition, QueryRequest, QueryResult}
5
+ import com.amazonaws.services.dynamodbv2.{AmazonDynamoDB, AmazonDynamoDBClient}
6
+ import com.amazonaws.services.dynamodbv2.model.{
7
+ AttributeValue,
8
+ Condition,
9
+ QueryRequest,
10
+ QueryResult
11
+ }
7
12
  import org.embulk.input.dynamodb.PluginTask
8
13
  import org.embulk.spi.{BufferAllocator, PageBuilder, PageOutput, Schema}
9
14
 
10
- import scala.collection.JavaConverters._
15
+ import scala.jdk.CollectionConverters._
16
+
17
+ class QueryOperation(client: AmazonDynamoDB) extends AbstractOperation {
11
18
 
12
- class QueryOperation(client: AmazonDynamoDBClient) extends AbstractOperation {
13
- override def execute(task: PluginTask,
14
- schema: Schema,
15
- output: PageOutput): Unit =
16
- {
19
+ override def execute(
20
+ task: PluginTask,
21
+ schema: Schema,
22
+ output: PageOutput
23
+ ): Unit = {
17
24
  val allocator: BufferAllocator = task.getBufferAllocator
18
25
  val pageBuilder: PageBuilder = new PageBuilder(allocator, schema, output)
19
26
 
20
- val attributes: JList[String] = schema.getColumns.asScala.map(_.getName).asJava
27
+ val attributes: JList[String] =
28
+ schema.getColumns.asScala.map(_.getName).asJava
21
29
  val conditions: JMap[String, Condition] = createFilters(task).asJava
22
30
  var evaluateKey: JMap[String, AttributeValue] = null
23
31
 
24
- val limit: Long = math.max(task.getScanLimit, task.getLimit)
32
+ val limit: Long = math.max(task.getScanLimit, task.getLimit)
25
33
  val recordLimit: Long = task.getRecordLimit
26
34
  var recordCount: Long = 0
27
35
 
@@ -41,9 +49,9 @@ class QueryOperation(client: AmazonDynamoDBClient) extends AbstractOperation {
41
49
  val result: QueryResult = client.query(request)
42
50
  evaluateKey = result.getLastEvaluatedKey
43
51
 
44
- val items = result.getItems.asScala.map(_.asScala.toMap)
52
+ val items = result.getItems.asScala.map(_.asScala.toMap).toSeq
45
53
  recordCount += write(pageBuilder, schema, items)
46
- } while(evaluateKey != null && (recordLimit == 0 || recordLimit > recordCount))
54
+ } while (evaluateKey != null && (recordLimit == 0 || recordLimit > recordCount))
47
55
 
48
56
  pageBuilder.finish()
49
57
  }