As the name indicates this is a Scala client for Terrastore. Terrastore is a modern document store which provides advanced scalability and elasticity features without sacrificing consistency.
TerrsatoreClient is the main class that currently supports all the operations on both buckets and on the objects placed in the buckets.
Dependencies are listed in pom.xml. This project relies on databinder dispatch’s http library (which is backed by Apache’s HttpClient), and on Lift-Json for parsing and extracting JSON. Two extremely well-written libraries!
If you look into TerrastoreClientSpec class, a Scala Specs class the usages are obvious. Here is a brief primer, any way:
Before going into usages let’s define a few sample keys and documents —
val bucketName = “BucketOne”
val key1 = “person1”
val jsonStr1 = """{"name": “Name One”, “address”: {"street": “Street One”,“city”: “City One”}}"""
val key2 = “person2”
val jsonStr2 = """{"name": “Name Two”, “address”: {"street": “Street Two”,“city”: “City Two”}}"""
Also, define corresponding Scala case classes so that we can deserialize or extract the provided JSON into them —
case class Person(name: String, address: Address)
case class Address(street: String, city: String)
Create a new TerrastoreClient instance as …
val tc = TerrastoreClient(“localhost”, 8010)
- To add a new document for the provided bucket and key …
tc.putDocument(bucketName, key1, jsonStr1)
- To get that document …
val person = tc.getDocument[Person](bucketName, key1)
Result> Person(Name One,Address(Street One,City One))
In the above example the client retieves the document in the native format (JSON) and extracts it into Person object.
- To remove that document …
tc.removeDocument(bucketName, key1)
- To get all the documents …
- with no limit …
val personMap = tc.getAllDocuments[Person](bucketName, 0)
Result> Map(person1 → Person(Name One,Address(Street One,City One)), person2 → Person(Name Two,Address(Street Two,City Two)))
- with a limit (of one, in this case) …
val personMap = tc.getAllDocuments[Person](bucketName, 1)
Result> Map(person1 → Person(Name One,Address(Street One,City One)))
- with no limit …
- Update with a server-side function …
val jsonStr3 = """{"name": “Name Three”, “address”: {"street": “Street Three”,“city”: “City Three”}}"""
tc.update(bucketName, key2, “replace”, 2000, jsonStr3)
Result> key2 would now have value {"name": “Name Three”, “address”: {"street": “Street Three”,“city”: “City Three”}}
- Perform a range query …
val personMap = tc.doRangeQuery[Person](bucketName, RangeQueryParam(key2, key3, 0, “lexical-asc”, 0))
Result> Map(person2 → Person(Name Two,Address(Street Two,City Two)), person3 → Person(Name Three,Address(Street Three,City Three)))
- Perform a predicate query …
val personMap = tc.doPredicateQuery[Person](bucketName, “jxpath:/name[.=‘Name Two’]”)
Result> Map(person2 → Person(Name Two,Address(Street Two,City Two)))
- Adding buckets is now handled implicitly by Terrastore when you add a first document into a bucket, and hence there is no client-side operation for that.
- To get a bucket list …
val bucketNames = tc.getBucketNames
Result: List(BucketOne, SPS1, SPS2, XYZ1234, 1274286609248)
- Removing buckets is now handled implicitly by Terrastore when the last document is removed from that bucket, and hence there is no client-side operation for that.
- Export and import a bucket …
val file = bucketName + “.bak”
tc.exportBackup(bucketName, file, “SECRET-KEY”)
tc.importBackup(bucketName, file, “SECRET-KEY”)