Skip to content

Commit 635dff9

Browse files
authored
Support DynamoDB's UpdateItemRequest (#288)
* Add decodeItemResponse() * Use Long.MaxValue instead of magic number
1 parent 475953a commit 635dff9

File tree

3 files changed

+35
-9
lines changed

3 files changed

+35
-9
lines changed

src/main/scala/scynamo/Scynamo.scala

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package scynamo
22

33
import cats.data.EitherNec
4-
import software.amazon.awssdk.services.dynamodb.model.{GetItemResponse, QueryResponse, ScanResponse}
4+
import software.amazon.awssdk.services.dynamodb.model.{GetItemResponse, QueryResponse, ScanResponse, UpdateItemResponse}
55
import cats.syntax.all._
66

77
import scala.jdk.CollectionConverters._
@@ -14,10 +14,15 @@ trait ScynamoFunctions {
1414
else
1515
Right(None)
1616

17+
def decodeUpdateItemResponse[A: ObjectScynamoDecoder](response: UpdateItemResponse): EitherNec[ScynamoDecodeError, Option[A]] =
18+
if (response.hasAttributes)
19+
ObjectScynamoDecoder[A].decodeMap(response.attributes()).map(Some(_))
20+
else
21+
Right(None)
22+
1723
def decodeQueryResponse[A: ObjectScynamoDecoder](response: QueryResponse): EitherNec[ScynamoDecodeError, List[A]] =
1824
response.items().asScala.toList.traverse(ObjectScynamoDecoder[A].decodeMap(_))
1925

2026
def decodeScanResponse[A: ObjectScynamoDecoder](response: ScanResponse): EitherNec[ScynamoDecodeError, List[A]] =
2127
response.items().asScala.toList.traverse(ObjectScynamoDecoder[A].decodeMap(_))
22-
2328
}

src/test/scala/scynamo/ScynamoCodecProps.scala

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -82,15 +82,15 @@ class ScynamoCodecProps extends Properties("ScynamoCodec") {
8282

8383
propertyWithSeed("decode.encode === id (option)", propertySeed) = Prop.forAll { value: Option[Int] => decodeAfterEncodeIsIdentity(value) }
8484

85-
propertyWithSeed("decode.encode === id (finite duration)", propertySeed) =
86-
Prop.forAll(Gen.chooseNum(-9223372036854775807L, 9223372036854775807L)) { value =>
85+
propertyWithSeed("decode.encode === id (finite duration)", propertySeed) = Prop.forAll(Gen.chooseNum(Long.MinValue + 1, Long.MaxValue)) {
86+
value: Long =>
8787
decodeAfterEncodeIsIdentity(Duration.fromNanos(value))
88-
}
88+
}
8989

90-
propertyWithSeed("decode.encode === id (duration)", propertySeed) =
91-
Prop.forAll(Gen.chooseNum(-9223372036854775807L, 9223372036854775807L)) { value =>
90+
propertyWithSeed("decode.encode === id (duration)", propertySeed) = Prop.forAll(Gen.chooseNum(Long.MinValue + 1, Long.MaxValue)) {
91+
value: Long =>
9292
decodeAfterEncodeIsIdentity(Duration.fromNanos(value): Duration)
93-
}
93+
}
9494

9595
propertyWithSeed("decode.encode === id (java duration)", propertySeed) = Prop.forAll { value: Long =>
9696
decodeAfterEncodeIsIdentity(java.time.Duration.ofNanos(value))

src/test/scala/scynamo/ScynamoTest.scala

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,15 @@ class ScynamoTest extends UnitTest {
1717
result should ===(Right(None))
1818
}
1919

20+
"return None if the update item response has no item" in {
21+
val response = UpdateItemResponse.builder().build()
22+
val result = for {
23+
result <- Scynamo.decodeUpdateItemResponse[Map[String, AttributeValue]](response)
24+
} yield result
25+
26+
result should ===(Right(None))
27+
}
28+
2029
"return an empty List if the query response has no items" in {
2130
val response = QueryResponse.builder().build()
2231

@@ -37,7 +46,7 @@ class ScynamoTest extends UnitTest {
3746
result should ===(Right(List.empty))
3847
}
3948

40-
"return the decoded result if it has an item that is well formed" in {
49+
"return the decoded get item result if it has an item that is well formed" in {
4150
val input = Map("foo" -> "bar")
4251

4352
val result = for {
@@ -49,6 +58,18 @@ class ScynamoTest extends UnitTest {
4958
result should ===(Right(Some(input)))
5059
}
5160

61+
"return the decoded update item result if it has an item that is well formed" in {
62+
val input = Map("foo" -> "bar")
63+
64+
val result = for {
65+
encodedInput <- input.encodedMap
66+
response = UpdateItemResponse.builder().attributes(encodedInput).build()
67+
result <- Scynamo.decodeUpdateItemResponse[Map[String, String]](response)
68+
} yield result
69+
70+
result should ===(Right(Some(input)))
71+
}
72+
5273
"return the decoded query result if it has multiple items that are well formed" in {
5374
val input1 = Map("foo" -> "bar")
5475
val input2 = Map("Miami" -> "Ibiza")

0 commit comments

Comments
 (0)