Skip to content

Commit

Permalink
Add REMOVE support to the update API
Browse files Browse the repository at this point in the history
  • Loading branch information
Chris Birchall committed Sep 19, 2016
1 parent 8b3ca75 commit 557e2d8
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 7 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,16 +129,16 @@ scala> import com.gu.scanamo.syntax._
scala> val client = LocalDynamoDB.client()
scala> import com.amazonaws.services.dynamodbv2.model.ScalarAttributeType._
scala> val teamTableResult = LocalDynamoDB.createTable(client)("teams")('name -> S)
scala> case class Team(name: String, goals: Int, scorers: List[String])
scala> case class Team(name: String, goals: Int, scorers: List[String], mascot: Option[String])
scala> val teamTable = Table[Team]("teams")
scala> val operations = for {
| _ <- teamTable.put(Team("Watford", 1, List("Blissett")))
| _ <- teamTable.update('name -> "Watford", set('goals -> 2) and append('scorers -> "Barnes"))
| _ <- teamTable.put(Team("Watford", 1, List("Blissett"), Some("Harry the Hornet")))
| _ <- teamTable.update('name -> "Watford", set('goals -> 2) and append('scorers -> "Barnes") and remove('mascot))
| watford <- teamTable.get('name -> "Watford")
| } yield watford

scala> Scanamo.exec(client)(operations)
res1: Option[cats.data.Xor[error.DynamoReadError, Team]] = Some(Right(Team(Watford,2,List(Blissett, Barnes))))
res1: Option[cats.data.Xor[error.DynamoReadError, Team]] = Some(Right(Team(Watford,2,List(Blissett, Barnes),None)))
```

### Using Indexes
Expand Down
2 changes: 2 additions & 0 deletions src/main/scala/com/gu/scanamo/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ package object scanamo {
AddExpression(fieldValue._1, fieldValue._2)
def delete[V: DynamoFormat](fieldValue: (Symbol, V)) =
DeleteExpression(fieldValue._1, fieldValue._2)
def remove(field: Symbol) =
RemoveExpression(field)

implicit class AndUpdateExpression[X: UpdateExpression](x: X) {
def and[Y: UpdateExpression](y: Y) = AndUpdate(x, y)
Expand Down
27 changes: 24 additions & 3 deletions src/main/scala/com/gu/scanamo/update/UpdateExpression.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ import simulacrum.typeclass
}

sealed trait UpdateType { val op: String }
final object SET extends UpdateType { override val op = "SET" }
final object ADD extends UpdateType { override val op = "ADD" }
final object DELETE extends UpdateType { override val op = "DELETE" }
case object SET extends UpdateType { override val op = "SET" }
case object ADD extends UpdateType { override val op = "ADD" }
case object DELETE extends UpdateType { override val op = "DELETE" }
case object REMOVE extends UpdateType { override val op = "REMOVE" }

case class SetExpression[V: DynamoFormat](field: Symbol, value: V)

Expand Down Expand Up @@ -74,6 +75,12 @@ object AddExpression {
}
}

/*
Note the difference between DELETE and REMOVE:
- DELETE is used to delete an element from a set
- REMOVE is used to remove an attribute from an item
*/

case class DeleteExpression[V: DynamoFormat](field: Symbol, value: V)

object DeleteExpression {
Expand All @@ -88,6 +95,20 @@ object DeleteExpression {
}
}

case class RemoveExpression(field: Symbol)

object RemoveExpression {
implicit val removeUpdateExpression =
new UpdateExpression[RemoveExpression] {
override def typeExpressions(t: RemoveExpression): Map[UpdateType, String] =
Map(REMOVE -> "#update")
override def attributeNames(t: RemoveExpression): Map[String, String] =
Map("#update" -> t.field.name)
override def attributeValues(t: RemoveExpression): Map[String, AttributeValue] =
Map()
}
}

case class AndUpdate[L: UpdateExpression, R: UpdateExpression](l: L, r: R)

object AndUpdate {
Expand Down

0 comments on commit 557e2d8

Please sign in to comment.