forked from scanamo/scanamo
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Philip Wills
committed
Dec 6, 2016
1 parent
a2b419b
commit 8079734
Showing
10 changed files
with
260 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,24 @@ | ||
options: | ||
- title: Put and Get | ||
url: put-get.html | ||
menu_section: operations | ||
|
||
- title: Querying | ||
url: querying.html | ||
menu_section: operations | ||
|
||
- title: Updating | ||
url: updating.html | ||
menu_section: operations | ||
|
||
- title: Using Indexes | ||
url: using-indexes.html | ||
menu_section: home | ||
|
||
- title: Asynchronous Requests | ||
url: asynchronous.html | ||
menu_section: home | ||
|
||
- title: Custom Formats | ||
url: custom-formats.html | ||
menu_section: home |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
--- | ||
layout: docs | ||
title: Asynchronous Requests | ||
position: 7 | ||
--- | ||
|
||
### Non-blocking requests | ||
|
||
Whilst for simplicity most examples in these documents are based on synchronous | ||
requests to DynamoDB, Scanamo supports making the requests asynchronously with | ||
a client that implements the `AmazonDynamoDBAsync` interface: | ||
|
||
```tut:silent | ||
import com.gu.scanamo._ | ||
import com.gu.scanamo.syntax._ | ||
import scala.concurrent.duration._ | ||
import scala.concurrent.ExecutionContext.Implicits.global | ||
val client = LocalDynamoDB.client() | ||
import com.amazonaws.services.dynamodbv2.model.ScalarAttributeType._ | ||
LocalDynamoDB.createTable(client)("farm")('name -> S) | ||
case class Farm(animals: List[String]) | ||
case class Farmer(name: String, age: Long, farm: Farm) | ||
val farmTable = Table[Farmer]("farm") | ||
val ops = for { | ||
_ <- farmTable.putAll(Set( | ||
Farmer("Boggis", 43L, Farm(List("chicken"))), | ||
Farmer("Bunce", 52L, Farm(List("goose"))), | ||
Farmer("Bean", 55L, Farm(List("turkey"))) | ||
)) | ||
bunce <- farmTable.get('name -> "Bunce") | ||
} yield bunce | ||
``` | ||
```tut:book | ||
//concurrent.Await.result(ScanamoAsync.exec(client)(ops), 5.seconds) | ||
``` | ||
|
||
Note that `AmazonDynamoDBAsyncClient` uses a thread pool internally. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
--- | ||
layout: docs | ||
title: Custom Formats | ||
position: 5 | ||
--- | ||
|
||
### Custom Formats | ||
|
||
Scanamo uses the `DynamoFormat` type class to define how to read and write | ||
different types to DynamoDB. Scanamo provides such formats for many common | ||
types, but it's also possible to define a serialisation format for types | ||
which Scanamo doesn't provide. For example to store Joda `DateTime` objects | ||
as ISO `String`s in Dynamo: | ||
|
||
```tut:silent | ||
import org.joda.time._ | ||
import com.gu.scanamo._ | ||
import com.gu.scanamo.syntax._ | ||
case class Foo(dateTime: DateTime) | ||
val client = LocalDynamoDB.client() | ||
import com.amazonaws.services.dynamodbv2.model.ScalarAttributeType._ | ||
LocalDynamoDB.createTable(client)("foo")('dateTime -> S) | ||
``` | ||
```tut:book | ||
implicit val jodaStringFormat = DynamoFormat.coercedXmap[DateTime, String, IllegalArgumentException]( | ||
DateTime.parse(_).withZone(DateTimeZone.UTC) | ||
)( | ||
_.toString | ||
) | ||
val fooTable = Table[Foo]("foo") | ||
val operations = for { | ||
_ <- fooTable.put(Foo(new DateTime(0))) | ||
results <- fooTable.scan() | ||
} yield results | ||
Scanamo.exec(client)(operations).toList | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,48 @@ | ||
--- | ||
layout: home | ||
section: home | ||
position: 1 | ||
--- | ||
|
||
[](https://maven-badges.herokuapp.com/maven-central/com.gu/scanamo_2.12) [](https://travis-ci.org/guardian/scanamo) [](https://coveralls.io/github/guardian/scanamo?branch=master) [](https://gitter.im/guardian/scanamo) | ||
|
||
Scanamo is a library to make using [DynamoDB](https://aws.amazon.com/documentation/dynamodb/) with Scala | ||
simpler and less error-prone. | ||
|
||
The main focus is on making it easier to avoid mistakes and typos by leveraging Scala's type system and some | ||
higher level abstractions. | ||
|
||
Quick start | ||
----------- | ||
|
||
Scanamo is published for Scala 2.11 and 2.12 to Maven Central, so just add the following to your `build.sbt`: | ||
|
||
```scala | ||
libraryDependencies ++= Seq( | ||
"com.gu" %% "scanamo" % "0.8.1" | ||
) | ||
``` | ||
|
||
then, given a table and some case classes | ||
|
||
```tut:silent | ||
import com.gu.scanamo._ | ||
import com.gu.scanamo.syntax._ | ||
val client = LocalDynamoDB.client() | ||
import com.amazonaws.services.dynamodbv2.model.ScalarAttributeType._ | ||
val farmersTableResult = LocalDynamoDB.createTable(client)("farmer")('name -> S) | ||
case class Farm(animals: List[String]) | ||
case class Farmer(name: String, age: Long, farm: Farm) | ||
``` | ||
we can simply `put` and `get` items from Dynamo, without boilerplate or reflection | ||
|
||
```tut:book | ||
val table = Table[Farmer]("farmer") | ||
Scanamo.exec(client)(table.put(Farmer("McDonald", 156L, Farm(List("sheep", "cow"))))) | ||
Scanamo.exec(client)(table.get('name -> "McDonald")) | ||
``` | ||
|
||
Licensed under the [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
--- | ||
layout: docs | ||
title: Putting and Getting | ||
position: 2 | ||
--- | ||
|
||
### Putting and Getting | ||
|
||
Often when using DynamoDB, the primary use case is simply putting objects into | ||
Dynamo and subsequently retrieving them: | ||
|
||
```tut:silent | ||
import com.gu.scanamo._ | ||
import com.gu.scanamo.syntax._ | ||
val client = LocalDynamoDB.client() | ||
import com.amazonaws.services.dynamodbv2.model.ScalarAttributeType._ | ||
LocalDynamoDB.createTable(client)("muppets")('name -> S) | ||
case class Muppet(name: String, species: String) | ||
``` | ||
```tut:book | ||
val muppets = Table[Muppet]("muppets") | ||
val operations = for { | ||
_ <- muppets.put(Muppet("Kermit", "Frog")) | ||
_ <- muppets.put(Muppet("Cookie Monster", "Monster")) | ||
_ <- muppets.put(Muppet("Miss Piggy", "Pig")) | ||
kermit <- muppets.get('name -> "Kermit") | ||
} yield kermit | ||
Scanamo.exec(client)(operations) | ||
``` | ||
|
||
Note that when using `Table` no operations are actually executed against DynamoDB until `exec` is called. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
--- | ||
layout: docs | ||
title: Updating | ||
position: 4 | ||
--- | ||
|
||
### Updating | ||
|
||
If you want to update some of the fields of a row, which don't form part of the key, | ||
without replacing it entirely, you can use the `update` operation: | ||
|
||
```tut:silent | ||
import com.gu.scanamo._ | ||
import com.gu.scanamo.syntax._ | ||
val client = LocalDynamoDB.client() | ||
import com.amazonaws.services.dynamodbv2.model.ScalarAttributeType._ | ||
val teamTableResult = LocalDynamoDB.createTable(client)("teams")('name -> S) | ||
case class Team(name: String, goals: Int, scorers: List[String], mascot: Option[String]) | ||
val teamTable = Table[Team]("teams") | ||
val operations = for { | ||
_ <- teamTable.put(Team("Watford", 1, List("Blissett"), Some("Harry the Hornet"))) | ||
updated <- teamTable.update('name -> "Watford", | ||
set('goals -> 2) and append('scorers -> "Barnes") and remove('mascot)) | ||
} yield updated | ||
``` | ||
```tut:book | ||
Scanamo.exec(client)(operations) | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
--- | ||
layout: docs | ||
title: Using Indexes | ||
position: 6 | ||
--- | ||
|
||
### Using Indexes | ||
|
||
Scanamo supports scanning and querying [global secondary indexes](http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GSI.html). | ||
In the following example, we create and use a table called `transport` with a hash key | ||
of `mode` and range key of `line` and a global secondary called `colour-index` | ||
with only a hash key on the `colour` attribute: | ||
|
||
```tut:silent | ||
import com.gu.scanamo._ | ||
import com.gu.scanamo.syntax._ | ||
case class Transport(mode: String, line: String, colour: String) | ||
val transport = Table[Transport]("transport") | ||
val colourIndex = transport.index("colour-index") | ||
val client = LocalDynamoDB.client() | ||
import com.amazonaws.services.dynamodbv2.model.ScalarAttributeType._ | ||
``` | ||
```tut:book | ||
LocalDynamoDB.withTableWithSecondaryIndex(client)("transport", "colour-index")('mode -> S, 'line -> S)('colour -> S) { | ||
val operations = for { | ||
_ <- transport.putAll(Set( | ||
Transport("Underground", "Circle", "Yellow"), | ||
Transport("Underground", "Metropolitan", "Maroon"), | ||
Transport("Underground", "Central", "Red"))) | ||
maroonLine <- colourIndex.query('colour -> "Maroon") | ||
} yield maroonLine.toList | ||
Scanamo.exec(client)(operations) | ||
} | ||
``` |