From d40b5f63203e0edab24f54ff299d091e8e7cd631 Mon Sep 17 00:00:00 2001 From: Avinder Bahra Date: Sat, 27 Jul 2024 08:53:59 +0100 Subject: [PATCH 1/5] do not auto-batch a single query --- .../zio/dynamodb/DynamoDBExecutorImpl.scala | 11 ++-- .../scala/zio/dynamodb/DynamoDBQuery.scala | 58 ++++++++++++------- .../scala/zio/dynamodb/BatchingDSLSpec.scala | 2 +- 3 files changed, 45 insertions(+), 26 deletions(-) diff --git a/dynamodb/src/main/scala/zio/dynamodb/DynamoDBExecutorImpl.scala b/dynamodb/src/main/scala/zio/dynamodb/DynamoDBExecutorImpl.scala index b60fe77e..47ea589b 100644 --- a/dynamodb/src/main/scala/zio/dynamodb/DynamoDBExecutorImpl.scala +++ b/dynamodb/src/main/scala/zio/dynamodb/DynamoDBExecutorImpl.scala @@ -218,8 +218,10 @@ private[dynamodb] final case class DynamoDBExecutorImpl private[dynamodb] (dynam ) private def executeBatchWriteItem(batchWriteItem: BatchWriteItem): ZIO[Any, Throwable, BatchWriteItem.Response] = - if (batchWriteItem.requestItems.isEmpty) ZIO.succeed(BatchWriteItem.Response(None)) - else { + if (batchWriteItem.requestItems.isEmpty) { + println(s"XXXXXXXX batchWriteItem.requestItems.isEmpty") + ZIO.succeed(BatchWriteItem.Response(None)) + } else { // need to explicitly type this for Scala 3 compiler val t: zio.Schedule[Any, Throwable, Any] = batchWriteItem.retryPolicy.getOrElse(defaultRetryPolicy).whileInput { case BatchRetryError() => true @@ -328,9 +330,10 @@ private[dynamodb] final case class DynamoDBExecutorImpl private[dynamodb] (dynam ) private def executeBatchGetItem(batchGetItem: BatchGetItem): ZIO[Any, Throwable, BatchGetItem.Response] = - if (batchGetItem.requestItems.isEmpty) + if (batchGetItem.requestItems.isEmpty) { + println(s"XXXXXXXX batchGetItem.requestItems.isEmpty") ZIO.succeed(BatchGetItem.Response()) - else { + } else { val t: zio.Schedule[Any, Throwable, Any] = batchGetItem.retryPolicy.getOrElse(defaultRetryPolicy).whileInput { case BatchRetryError() => true case _ => false diff --git a/dynamodb/src/main/scala/zio/dynamodb/DynamoDBQuery.scala b/dynamodb/src/main/scala/zio/dynamodb/DynamoDBQuery.scala index c365d30d..19056caf 100644 --- a/dynamodb/src/main/scala/zio/dynamodb/DynamoDBQuery.scala +++ b/dynamodb/src/main/scala/zio/dynamodb/DynamoDBQuery.scala @@ -45,6 +45,10 @@ sealed trait DynamoDBQuery[-In, +Out] { self => val (indexedConstructors, (batchGetItem, batchGetIndexes), (batchWriteItem, batchWriteIndexes)) = batched(constructors) + println(s"XXXXXXX indexedConstructors: $indexedConstructors") + println(s"XXXXXXX batchGetItem: $batchGetItem") + println(s"XXXXXXX batchWriteItem: $batchWriteItem") + val indexedNonBatchedResults = ZIO.foreachPar(indexedConstructors) { case (constructor, index) => @@ -995,6 +999,8 @@ object DynamoDBQuery { type IndexedGetItem = (GetItem, Int) type IndexedWriteItem = (Write[Any, Option[Any]], Int) + println(s"XXXXXXXXXX constructors.size: ${constructors.size}") + def projectionsContainPrimaryKey(pes: List[ProjectionExpression[_, _]], pk: PrimaryKey): Boolean = { val matchedPrimaryKeys: List[Boolean] = pes.collect { case ProjectionExpression.MapElement(ProjectionExpression.Root, key) if pk.map.keySet.contains(key) => true @@ -1003,40 +1009,50 @@ object DynamoDBQuery { hasNoProjections || matchedPrimaryKeys.filter(_ == true).size == pk.map.size } + val isSingleQuery = constructors.size == 1 // single queries are not batched + val (indexedNonBatched, indexedGets, indexedWrites) = constructors.zipWithIndex.foldLeft[(Chunk[IndexedConstructor], Chunk[IndexedGetItem], Chunk[IndexedWriteItem])]( (Chunk.empty, Chunk.empty, Chunk.empty) ) { case ((nonBatched, gets, writes), (get @ GetItem(_, pk, pes, _, _, _), index)) => - if (projectionsContainPrimaryKey(pes, pk)) + if (isSingleQuery) + (nonBatched :+ (get -> index), gets, writes) + else if (projectionsContainPrimaryKey(pes, pk)) (nonBatched, gets :+ (get -> index), writes) else (nonBatched :+ (get -> index), gets, writes) case ((nonBatched, gets, writes), (put @ PutItem(_, _, conditionExpression, _, _, returnValues, _), index)) => - conditionExpression match { - case Some(_) => - (nonBatched :+ (put -> index), gets, writes) - case None => - if (returnValues != ReturnValues.None) - (nonBatched :+ (put -> index), gets, writes) - else - (nonBatched, gets, writes :+ (put -> index)) - } + if (isSingleQuery) + (nonBatched :+ (put -> index), gets, writes) + else + conditionExpression match { + case Some(_) => + (nonBatched :+ (put -> index), gets, writes) + case None => + if (returnValues != ReturnValues.None) + (nonBatched :+ (put -> index), gets, writes) + else + (nonBatched, gets, writes :+ (put -> index)) + } case ( (nonBatched, gets, writes), (delete @ DeleteItem(_, _, conditionExpression, _, _, returnValues, _), index) ) => - conditionExpression match { - case Some(_) => - (nonBatched :+ (delete -> index), gets, writes) - case None => - if (returnValues != ReturnValues.None) - (nonBatched :+ (delete -> index), gets, writes) - else - (nonBatched, gets, writes :+ (delete -> index)) - } - case ((nonBatched, gets, writes), (nonGetItem, index)) => - (nonBatched :+ (nonGetItem -> index), gets, writes) + if (isSingleQuery) + (nonBatched :+ (delete -> index), gets, writes) + else + conditionExpression match { + case Some(_) => + (nonBatched :+ (delete -> index), gets, writes) + case None => + if (returnValues != ReturnValues.None) + (nonBatched :+ (delete -> index), gets, writes) + else + (nonBatched, gets, writes :+ (delete -> index)) + } + case ((nonBatched, gets, writes), (nonBatchable, index)) => + (nonBatched :+ (nonBatchable -> index), gets, writes) } val indexedBatchGetItem: (BatchGetItem, Chunk[Int]) = indexedGets diff --git a/dynamodb/src/test/scala/zio/dynamodb/BatchingDSLSpec.scala b/dynamodb/src/test/scala/zio/dynamodb/BatchingDSLSpec.scala index 317e14c1..8bccd9dd 100644 --- a/dynamodb/src/test/scala/zio/dynamodb/BatchingDSLSpec.scala +++ b/dynamodb/src/test/scala/zio/dynamodb/BatchingDSLSpec.scala @@ -22,7 +22,7 @@ object BatchingDSLSpec extends ZIOSpecDefault with DynamoDBFixtures { suite("Batching")(crudSuite, scanAndQuerySuite, batchingSuite).provideLayer(DynamoDBExecutor.test) private val crudSuite = suite("single Item CRUD suite")( - test("getItem") { + test("getItemX") { for { _ <- TestDynamoDBExecutor.addTable(tableName1.value, "k1", primaryKeyT1 -> itemT1, primaryKeyT1_2 -> itemT1_2) result <- getItemT1.execute From 46c49b26bfd7507cd16051793185580076f7a349 Mon Sep 17 00:00:00 2001 From: Avinder Bahra Date: Sun, 28 Jul 2024 09:49:07 +0100 Subject: [PATCH 2/5] clean up, tests --- .../scala/zio/dynamodb/DynamoDBExecutor.scala | 8 ++-- .../zio/dynamodb/DynamoDBExecutorImpl.scala | 18 ++++---- .../scala/zio/dynamodb/DynamoDBQuery.scala | 6 --- .../zio/dynamodb/TestDynamoDBExecutor.scala | 17 ++++++++ .../dynamodb/TestDynamoDBExecutorImpl.scala | 7 +++- .../scala/zio/dynamodb/BatchingDSLSpec.scala | 42 +++++++++++++++---- 6 files changed, 70 insertions(+), 28 deletions(-) diff --git a/dynamodb/src/main/scala/zio/dynamodb/DynamoDBExecutor.scala b/dynamodb/src/main/scala/zio/dynamodb/DynamoDBExecutor.scala index a280f599..0bc48693 100644 --- a/dynamodb/src/main/scala/zio/dynamodb/DynamoDBExecutor.scala +++ b/dynamodb/src/main/scala/zio/dynamodb/DynamoDBExecutor.scala @@ -2,7 +2,7 @@ package zio.dynamodb import zio.aws.dynamodb.DynamoDb import zio.stm.{ STM, TMap } -import zio.{ ULayer, URLayer, ZIO, ZLayer } +import zio.{ Ref, ULayer, URLayer, ZIO, ZLayer } trait DynamoDBExecutor { def execute[A](atomicQuery: DynamoDBQuery[_, A]): ZIO[Any, DynamoDBError, A] @@ -16,16 +16,18 @@ object DynamoDBExecutor { lazy val test: ULayer[DynamoDBExecutor with TestDynamoDBExecutor] = { val effect = for { + ref <- Ref.make(List.empty[DynamoDBQuery[_, _]]) test <- (for { tableMap <- TMap.empty[String, TMap[PrimaryKey, Item]] tablePkNameMap <- TMap.empty[String, String] - } yield TestDynamoDBExecutorImpl(tableMap, tablePkNameMap)).commit + } yield TestDynamoDBExecutorImpl(ref, tableMap, tablePkNameMap)).commit } yield test ZLayer.fromZIO(effect) } def test(tableDefs: TableNameAndPK*): ULayer[DynamoDBExecutor with TestDynamoDBExecutor] = { val effect = for { + ref <- Ref.make(List.empty[DynamoDBQuery[_, _]]) test <- (for { tableMap <- TMap.empty[String, TMap[PrimaryKey, Item]] tablePkNameMap <- TMap.empty[String, String] @@ -37,7 +39,7 @@ object DynamoDBExecutor { _ <- tableMap.put(tableName, pkToItemMap) } yield () } - } yield TestDynamoDBExecutorImpl(tableMap, tablePkNameMap)).commit + } yield TestDynamoDBExecutorImpl(ref, tableMap, tablePkNameMap)).commit } yield test ZLayer.fromZIO(effect) } diff --git a/dynamodb/src/main/scala/zio/dynamodb/DynamoDBExecutorImpl.scala b/dynamodb/src/main/scala/zio/dynamodb/DynamoDBExecutorImpl.scala index 47ea589b..efc4aa8d 100644 --- a/dynamodb/src/main/scala/zio/dynamodb/DynamoDBExecutorImpl.scala +++ b/dynamodb/src/main/scala/zio/dynamodb/DynamoDBExecutorImpl.scala @@ -124,6 +124,7 @@ private[dynamodb] final case class DynamoDBExecutorImpl private[dynamodb] (dynam } override def execute[A](atomicQuery: DynamoDBQuery[_, A]): ZIO[Any, DynamoDBError, A] = { + val result = atomicQuery match { case constructor: Constructor[_, A] => executeConstructor(constructor) case zip @ Zip(_, _, _) => executeZip(zip) @@ -153,7 +154,7 @@ private[dynamodb] final case class DynamoDBExecutorImpl private[dynamodb] (dynam private def executeDeleteItem(deleteItem: DeleteItem): ZIO[Any, Throwable, Option[Item]] = dynamoDb .deleteItem(awsDeleteItemRequest(deleteItem)) - .mapBoth(_.toThrowable, _.attributes.toOption.map(dynamoDBItem(_))) + .mapBoth(_.toThrowable, _.attributes.toOption.map(dynamoDBItem)) private def executeDeleteTable(deleteTable: DeleteTable): ZIO[Any, Throwable, Unit] = dynamoDb @@ -162,13 +163,13 @@ private[dynamodb] final case class DynamoDBExecutorImpl private[dynamodb] (dynam .unit private def executePutItem(putItem: PutItem): ZIO[Any, Throwable, Option[Item]] = - dynamoDb.putItem(awsPutItemRequest(putItem)).mapBoth(_.toThrowable, _.attributes.toOption.map(dynamoDBItem(_))) + dynamoDb.putItem(awsPutItemRequest(putItem)).mapBoth(_.toThrowable, _.attributes.toOption.map(dynamoDBItem)) private def executeGetItem(getItem: GetItem): ZIO[Any, Throwable, Option[Item]] = dynamoDb .getItem(awsGetItemRequest(getItem)) .mapBoth(_.toThrowable, _.item.map(dynamoDBItem)) - .map(_.toOption) + .map(_.toOption.flatMap(item => if (item.map.isEmpty) None else Some(item))) private def executeUpdateItem(updateItem: UpdateItem): ZIO[Any, Throwable, Option[Item]] = dynamoDb.updateItem(awsUpdateItemRequest(updateItem)).mapBoth(_.toThrowable, optionalItem) @@ -218,10 +219,8 @@ private[dynamodb] final case class DynamoDBExecutorImpl private[dynamodb] (dynam ) private def executeBatchWriteItem(batchWriteItem: BatchWriteItem): ZIO[Any, Throwable, BatchWriteItem.Response] = - if (batchWriteItem.requestItems.isEmpty) { - println(s"XXXXXXXX batchWriteItem.requestItems.isEmpty") - ZIO.succeed(BatchWriteItem.Response(None)) - } else { + if (batchWriteItem.requestItems.isEmpty) ZIO.succeed(BatchWriteItem.Response(None)) + else { // need to explicitly type this for Scala 3 compiler val t: zio.Schedule[Any, Throwable, Any] = batchWriteItem.retryPolicy.getOrElse(defaultRetryPolicy).whileInput { case BatchRetryError() => true @@ -330,10 +329,9 @@ private[dynamodb] final case class DynamoDBExecutorImpl private[dynamodb] (dynam ) private def executeBatchGetItem(batchGetItem: BatchGetItem): ZIO[Any, Throwable, BatchGetItem.Response] = - if (batchGetItem.requestItems.isEmpty) { - println(s"XXXXXXXX batchGetItem.requestItems.isEmpty") + if (batchGetItem.requestItems.isEmpty) ZIO.succeed(BatchGetItem.Response()) - } else { + else { val t: zio.Schedule[Any, Throwable, Any] = batchGetItem.retryPolicy.getOrElse(defaultRetryPolicy).whileInput { case BatchRetryError() => true case _ => false diff --git a/dynamodb/src/main/scala/zio/dynamodb/DynamoDBQuery.scala b/dynamodb/src/main/scala/zio/dynamodb/DynamoDBQuery.scala index 19056caf..34402d4b 100644 --- a/dynamodb/src/main/scala/zio/dynamodb/DynamoDBQuery.scala +++ b/dynamodb/src/main/scala/zio/dynamodb/DynamoDBQuery.scala @@ -45,10 +45,6 @@ sealed trait DynamoDBQuery[-In, +Out] { self => val (indexedConstructors, (batchGetItem, batchGetIndexes), (batchWriteItem, batchWriteIndexes)) = batched(constructors) - println(s"XXXXXXX indexedConstructors: $indexedConstructors") - println(s"XXXXXXX batchGetItem: $batchGetItem") - println(s"XXXXXXX batchWriteItem: $batchWriteItem") - val indexedNonBatchedResults = ZIO.foreachPar(indexedConstructors) { case (constructor, index) => @@ -999,8 +995,6 @@ object DynamoDBQuery { type IndexedGetItem = (GetItem, Int) type IndexedWriteItem = (Write[Any, Option[Any]], Int) - println(s"XXXXXXXXXX constructors.size: ${constructors.size}") - def projectionsContainPrimaryKey(pes: List[ProjectionExpression[_, _]], pk: PrimaryKey): Boolean = { val matchedPrimaryKeys: List[Boolean] = pes.collect { case ProjectionExpression.MapElement(ProjectionExpression.Root, key) if pk.map.keySet.contains(key) => true diff --git a/dynamodb/src/main/scala/zio/dynamodb/TestDynamoDBExecutor.scala b/dynamodb/src/main/scala/zio/dynamodb/TestDynamoDBExecutor.scala index 9c5f9579..913b31b7 100644 --- a/dynamodb/src/main/scala/zio/dynamodb/TestDynamoDBExecutor.scala +++ b/dynamodb/src/main/scala/zio/dynamodb/TestDynamoDBExecutor.scala @@ -1,6 +1,7 @@ package zio.dynamodb import zio.{ UIO, ZIO } +import zio.dynamodb.DynamoDBQuery.{BatchGetItem, BatchWriteItem} /** * A Fake implementation of `DynamoDBExecutor.Service` that currently has the very modest aspiration of providing bare minimum @@ -33,6 +34,7 @@ import zio.{ UIO, ZIO } trait TestDynamoDBExecutor { def addTable(tableName: String, pkFieldName: String, pkAndItems: PkAndItem*): UIO[Unit] def addItems(tableName: String, pkAndItems: PkAndItem*): ZIO[Any, DynamoDBError, Unit] + def queries: UIO[List[DynamoDBQuery[_, _]]] } object TestDynamoDBExecutor { @@ -47,4 +49,19 @@ object TestDynamoDBExecutor { def addItems(tableName: String, pkAndItems: PkAndItem*): ZIO[TestDynamoDBExecutor, DynamoDBError, Unit] = ZIO.serviceWithZIO[TestDynamoDBExecutor](_.addItems(tableName, pkAndItems: _*)) + def queries: ZIO[TestDynamoDBExecutor, Nothing, List[DynamoDBQuery[_, _]]] = + ZIO.serviceWithZIO[TestDynamoDBExecutor](_.queries) + + def isEmptyBatchWrite(q: DynamoDBQuery[_, _]) = + q match { + case BatchWriteItem(items, _, _, _, _) => items.isEmpty + case _ => false + } + + def isEmptyBatchGet(q: DynamoDBQuery[_, _]) = + q match { + case BatchGetItem(items, _, _, _) => items.isEmpty + case _ => false + } + } diff --git a/dynamodb/src/main/scala/zio/dynamodb/TestDynamoDBExecutorImpl.scala b/dynamodb/src/main/scala/zio/dynamodb/TestDynamoDBExecutorImpl.scala index ea35b911..13cf7d21 100644 --- a/dynamodb/src/main/scala/zio/dynamodb/TestDynamoDBExecutorImpl.scala +++ b/dynamodb/src/main/scala/zio/dynamodb/TestDynamoDBExecutorImpl.scala @@ -4,11 +4,12 @@ import zio.dynamodb.DynamoDBQuery.BatchGetItem.TableGet import zio.dynamodb.DynamoDBQuery._ import zio.stm.{ STM, TMap, ZSTM } import zio.stream.{ Stream, ZStream } -import zio.{ Chunk, IO, UIO, ZIO } +import zio.{ Chunk, IO, Ref, UIO, ZIO } import scala.annotation.nowarn @nowarn private[dynamodb] final case class TestDynamoDBExecutorImpl private[dynamodb] ( + recordedQueries: Ref[List[DynamoDBQuery[_, _]]], tableMap: TMap[String, TMap[PrimaryKey, Item]], tablePkNameMap: TMap[String, String] ) extends DynamoDBExecutor @@ -84,7 +85,7 @@ private[dynamodb] final case class TestDynamoDBExecutorImpl private[dynamodb] ( ZIO.die(new Exception(s"Constructor $unknown not implemented yet")) } - result + recordedQueries.update(_ :+ atomicQuery) *> result } private def tableError(tableName: String): DynamoDBError = @@ -231,4 +232,6 @@ private[dynamodb] final case class TestDynamoDBExecutorImpl private[dynamodb] ( case (pk, item) => tableMap.put(pk, item) } } yield ()).commit + + override def queries: UIO[List[DynamoDBQuery[_, _]]] = self.recordedQueries.get } diff --git a/dynamodb/src/test/scala/zio/dynamodb/BatchingDSLSpec.scala b/dynamodb/src/test/scala/zio/dynamodb/BatchingDSLSpec.scala index 8bccd9dd..1b4d2136 100644 --- a/dynamodb/src/test/scala/zio/dynamodb/BatchingDSLSpec.scala +++ b/dynamodb/src/test/scala/zio/dynamodb/BatchingDSLSpec.scala @@ -3,7 +3,7 @@ package zio.dynamodb import zio.Chunk import zio.dynamodb.DynamoDBQuery._ import zio.test.Assertion._ -import zio.test.{ assert, TestAspect, ZIOSpecDefault } +import zio.test.{ assert, assertTrue, TestAspect, ZIOSpecDefault } import zio.test.Spec object BatchingDSLSpec extends ZIOSpecDefault with DynamoDBFixtures { @@ -19,15 +19,35 @@ object BatchingDSLSpec extends ZIOSpecDefault with DynamoDBFixtures { ) override def spec: Spec[Environment, Any] = - suite("Batching")(crudSuite, scanAndQuerySuite, batchingSuite).provideLayer(DynamoDBExecutor.test) + suite("Batching")(crudSuite, scanAndQuerySuite, batchingSuite, singleQueryDoesNotBatchSuite).provideLayer( + DynamoDBExecutor.test + ) - private val crudSuite = suite("single Item CRUD suite")( - test("getItemX") { + private val singleQueryDoesNotBatchSuite = suite("single query does not batch CRUD suite")( + test("a single getItem does not batch") { for { - _ <- TestDynamoDBExecutor.addTable(tableName1.value, "k1", primaryKeyT1 -> itemT1, primaryKeyT1_2 -> itemT1_2) - result <- getItemT1.execute - } yield assert(result)(equalTo(Some(itemT1))) + _ <- TestDynamoDBExecutor.addTable(tableName1.value, "k1", primaryKeyT1 -> itemT1, primaryKeyT1_2 -> itemT1_2) + result <- getItemT1.execute + queries <- TestDynamoDBExecutor.queries + } yield assert(result)(equalTo(Some(itemT1))) && assertQueryNotBatched(queries) }, + test("a single putItem does not batch") { + for { + _ <- TestDynamoDBExecutor.addTable(tableName1.value, "k1", primaryKeyT1 -> itemT1, primaryKeyT1_2 -> itemT1_2) + result <- putItemT1.execute + queries <- TestDynamoDBExecutor.queries + } yield assert(result)(equalTo(None)) && assertQueryNotBatched(queries) + }, + test("a single deleteItem does not batch") { + for { + _ <- TestDynamoDBExecutor.addTable(tableName1.value, "k1", primaryKeyT1 -> itemT1, primaryKeyT1_2 -> itemT1_2) + result <- deleteItemT1.execute + queries <- TestDynamoDBExecutor.queries + } yield assert(result)(equalTo(None)) && assertQueryNotBatched(queries) + } + ) + + private val crudSuite = suite("single Item CRUD suite")( test("getItem returns an error when table does not exist") { for { result <- getItem("TABLE_DOES_NOT_EXISTS", primaryKeyT1).execute.either @@ -175,4 +195,12 @@ object BatchingDSLSpec extends ZIOSpecDefault with DynamoDBFixtures { } yield assert(result)(equalTo(List(Some(itemT1), Some(itemT1_2)))) } @@ beforeAddTable1AndTable2 ) + + private def assertQueryNotBatched(queries: List[DynamoDBQuery[_, _]]) = + assertTrue(queries.size == 3) && assertTrue( + queries.find(TestDynamoDBExecutor.isEmptyBatchWrite).isDefined + ) && assertTrue( + queries.find(TestDynamoDBExecutor.isEmptyBatchGet).isDefined + ) + } From 5c1d47e25f22cfb7a3aec224c65cdae01738967f Mon Sep 17 00:00:00 2001 From: Avinder Bahra Date: Sun, 28 Jul 2024 09:53:43 +0100 Subject: [PATCH 3/5] scalafmt --- dynamodb/src/main/scala/zio/dynamodb/TestDynamoDBExecutor.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dynamodb/src/main/scala/zio/dynamodb/TestDynamoDBExecutor.scala b/dynamodb/src/main/scala/zio/dynamodb/TestDynamoDBExecutor.scala index 913b31b7..129c777a 100644 --- a/dynamodb/src/main/scala/zio/dynamodb/TestDynamoDBExecutor.scala +++ b/dynamodb/src/main/scala/zio/dynamodb/TestDynamoDBExecutor.scala @@ -1,7 +1,7 @@ package zio.dynamodb import zio.{ UIO, ZIO } -import zio.dynamodb.DynamoDBQuery.{BatchGetItem, BatchWriteItem} +import zio.dynamodb.DynamoDBQuery.{ BatchGetItem, BatchWriteItem } /** * A Fake implementation of `DynamoDBExecutor.Service` that currently has the very modest aspiration of providing bare minimum From 6f448d2be247d62d44b14b10e44f2b50e14abeb7 Mon Sep 17 00:00:00 2001 From: Avinder Bahra Date: Sun, 28 Jul 2024 10:02:37 +0100 Subject: [PATCH 4/5] rename atomicQuery --- dynamodb/src/main/scala/zio/dynamodb/DynamoDBExecutor.scala | 2 +- .../src/main/scala/zio/dynamodb/DynamoDBExecutorImpl.scala | 4 ++-- .../main/scala/zio/dynamodb/TestDynamoDBExecutorImpl.scala | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/dynamodb/src/main/scala/zio/dynamodb/DynamoDBExecutor.scala b/dynamodb/src/main/scala/zio/dynamodb/DynamoDBExecutor.scala index 0bc48693..97448c13 100644 --- a/dynamodb/src/main/scala/zio/dynamodb/DynamoDBExecutor.scala +++ b/dynamodb/src/main/scala/zio/dynamodb/DynamoDBExecutor.scala @@ -5,7 +5,7 @@ import zio.stm.{ STM, TMap } import zio.{ Ref, ULayer, URLayer, ZIO, ZLayer } trait DynamoDBExecutor { - def execute[A](atomicQuery: DynamoDBQuery[_, A]): ZIO[Any, DynamoDBError, A] + def execute[A](query: DynamoDBQuery[_, A]): ZIO[Any, DynamoDBError, A] } object DynamoDBExecutor { diff --git a/dynamodb/src/main/scala/zio/dynamodb/DynamoDBExecutorImpl.scala b/dynamodb/src/main/scala/zio/dynamodb/DynamoDBExecutorImpl.scala index efc4aa8d..7eab34b4 100644 --- a/dynamodb/src/main/scala/zio/dynamodb/DynamoDBExecutorImpl.scala +++ b/dynamodb/src/main/scala/zio/dynamodb/DynamoDBExecutorImpl.scala @@ -123,9 +123,9 @@ private[dynamodb] final case class DynamoDBExecutorImpl private[dynamodb] (dynam case Fail(dynamoDBError) => ZIO.fail(dynamoDBError()) } - override def execute[A](atomicQuery: DynamoDBQuery[_, A]): ZIO[Any, DynamoDBError, A] = { + override def execute[A](query: DynamoDBQuery[_, A]): ZIO[Any, DynamoDBError, A] = { - val result = atomicQuery match { + val result = query match { case constructor: Constructor[_, A] => executeConstructor(constructor) case zip @ Zip(_, _, _) => executeZip(zip) case map @ Map(_, _) => executeMap(map) diff --git a/dynamodb/src/main/scala/zio/dynamodb/TestDynamoDBExecutorImpl.scala b/dynamodb/src/main/scala/zio/dynamodb/TestDynamoDBExecutorImpl.scala index 13cf7d21..00193f09 100644 --- a/dynamodb/src/main/scala/zio/dynamodb/TestDynamoDBExecutorImpl.scala +++ b/dynamodb/src/main/scala/zio/dynamodb/TestDynamoDBExecutorImpl.scala @@ -16,8 +16,8 @@ private[dynamodb] final case class TestDynamoDBExecutorImpl private[dynamodb] ( with TestDynamoDBExecutor { self => - override def execute[A](atomicQuery: DynamoDBQuery[_, A]): ZIO[Any, DynamoDBError, A] = { - val result: ZIO[Any, DynamoDBError, A] = atomicQuery match { + override def execute[A](query: DynamoDBQuery[_, A]): ZIO[Any, DynamoDBError, A] = { + val result: ZIO[Any, DynamoDBError, A] = query match { case BatchGetItem(requestItemsMap, _, _, _) => val requestItems: Seq[(TableName, TableGet)] = requestItemsMap.toList @@ -85,7 +85,7 @@ private[dynamodb] final case class TestDynamoDBExecutorImpl private[dynamodb] ( ZIO.die(new Exception(s"Constructor $unknown not implemented yet")) } - recordedQueries.update(_ :+ atomicQuery) *> result + recordedQueries.update(_ :+ query) *> result } private def tableError(tableName: String): DynamoDBError = From 0168f02fc2013a9c5c3806922d307ae69401e883 Mon Sep 17 00:00:00 2001 From: Avinder Bahra Date: Sun, 28 Jul 2024 10:13:08 +0100 Subject: [PATCH 5/5] improve test labels --- dynamodb/src/test/scala/zio/dynamodb/BatchingDSLSpec.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dynamodb/src/test/scala/zio/dynamodb/BatchingDSLSpec.scala b/dynamodb/src/test/scala/zio/dynamodb/BatchingDSLSpec.scala index 1b4d2136..ce0217bc 100644 --- a/dynamodb/src/test/scala/zio/dynamodb/BatchingDSLSpec.scala +++ b/dynamodb/src/test/scala/zio/dynamodb/BatchingDSLSpec.scala @@ -24,21 +24,21 @@ object BatchingDSLSpec extends ZIOSpecDefault with DynamoDBFixtures { ) private val singleQueryDoesNotBatchSuite = suite("single query does not batch CRUD suite")( - test("a single getItem does not batch") { + test("a single getItem does not get auto-batch") { for { _ <- TestDynamoDBExecutor.addTable(tableName1.value, "k1", primaryKeyT1 -> itemT1, primaryKeyT1_2 -> itemT1_2) result <- getItemT1.execute queries <- TestDynamoDBExecutor.queries } yield assert(result)(equalTo(Some(itemT1))) && assertQueryNotBatched(queries) }, - test("a single putItem does not batch") { + test("a single putItem does not get auto-batch") { for { _ <- TestDynamoDBExecutor.addTable(tableName1.value, "k1", primaryKeyT1 -> itemT1, primaryKeyT1_2 -> itemT1_2) result <- putItemT1.execute queries <- TestDynamoDBExecutor.queries } yield assert(result)(equalTo(None)) && assertQueryNotBatched(queries) }, - test("a single deleteItem does not batch") { + test("a single deleteItem does not get auto-batch") { for { _ <- TestDynamoDBExecutor.addTable(tableName1.value, "k1", primaryKeyT1 -> itemT1, primaryKeyT1_2 -> itemT1_2) result <- deleteItemT1.execute