Skip to content

Commit

Permalink
add maybeFound convenience extension method (#376)
Browse files Browse the repository at this point in the history
  • Loading branch information
googley42 authored Jan 30, 2024
1 parent 75507bc commit 6e19c9b
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 4 deletions.
24 changes: 23 additions & 1 deletion dynamodb/src/it/scala/zio/dynamodb/TypeSafeApiCrudSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import zio.test._
import zio.test.assertTrue
import zio.test.Assertion._
import zio.dynamodb.DynamoDBError.ItemError
import zio.dynamodb.DynamoDBQuery.{ deleteFrom, forEach, get, put, scanAll, update }
import zio.dynamodb.DynamoDBQuery.{ deleteFrom, forEach, get, put, putItem, scanAll, update }
import zio.dynamodb.syntax._
import zio.Chunk
import software.amazon.awssdk.services.dynamodb.model.ConditionalCheckFailedException
import zio.stream.ZStream
Expand Down Expand Up @@ -51,6 +52,27 @@ object TypeSafeApiCrudSpec extends DynamoDBLocalSpec {
} yield assertTrue(p == person)
}
},
test("and get using maybeFound extension method") {
withSingleIdKeyTable { tableName =>
val person = Person("1", "Smith", Some("John"), 21)
for {
_ <- put(tableName, person).execute
personFound <- get(tableName)(Person.id.partitionKey === "1").execute.maybeFound
personNotFound <- get(tableName)(Person.id.partitionKey === "DOES_NOT_EXIST").execute.maybeFound
_ <- putItem(tableName, Item("id" -> "WILL_GIVE_DECODE_ERROR")).execute
decodeErrorExit <-
get(tableName)(Person.id.partitionKey === "WILL_GIVE_DECODE_ERROR").execute.maybeFound.exit
} yield assertTrue(personFound == Some(person) && personNotFound == None) && assert(decodeErrorExit)(
fails(
equalTo(
DynamoDBError.ItemError.DecodingError(
"field 'surname' not found in Map(Map(String(id) -> String(WILL_GIVE_DECODE_ERROR)))"
)
)
)
)
}
},
test("with condition expression that id not exists fails when item exists") {
withSingleIdKeyTable { tableName =>
val person = Person("1", "Smith", Some("John"), 21)
Expand Down
20 changes: 20 additions & 0 deletions dynamodb/src/main/scala/zio/dynamodb/syntax.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package zio.dynamodb

import zio.ZIO

object syntax {
implicit class MaybeFound[R, A](zio: ZIO[R, DynamoDBError, Either[DynamoDBError.ItemError, A]]) {

/**
* Moves Left[ItemError.DecodingError] to the error channel and returns Some(a) if the item is found else None
* eg {{{ DynamoDBQuery.get("table")(Person.id.partitionKey === 1).execute.maybeFound }}}
*/
def maybeFound: ZIO[R, DynamoDBError, Option[A]] =
zio.flatMap {
case Left(e @ DynamoDBError.ItemError.DecodingError(_)) => ZIO.fail(e)
case Left(DynamoDBError.ItemError.ValueNotFound(_)) => ZIO.succeed(None)
case Right(a) => ZIO.succeed(Some(a))
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import zio.dynamodb.DynamoDBExecutor
import zio.dynamodb.DynamoDBQuery.get
import zio.dynamodb.DynamoDBQuery.put
import zio.dynamodb.ProjectionExpression
import zio.dynamodb.syntax._
import zio.schema.DeriveSchema
import zio.schema.Schema

Expand Down Expand Up @@ -66,9 +67,9 @@ object DynamoDBLocalMain extends ZIOAppDefault {
val examplePerson = Person(1, "avi")

private val program = for {
_ <- put("person", examplePerson).execute
person <- get("person")(Person.id.partitionKey === 1).execute
_ <- zio.Console.printLine(s"hello $person")
_ <- put("person", examplePerson).execute
maybePerson <- get("person")(Person.id.partitionKey === 1).execute.maybeFound
_ <- zio.Console.printLine(s"hello $maybePerson")
} yield ()

override def run =
Expand Down

0 comments on commit 6e19c9b

Please sign in to comment.