embulk-input-dynamodb 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
  }