-
Notifications
You must be signed in to change notification settings - Fork 14
Home
scouchdb offers a Scala interface to using CouchDB. Scala offers objects and classes as the natural way to abstract entities, while CouchDB stores artifacts as JSON documents. scouchdb makes it easy to use the object interface of Scala for persistence and management of Scala objects as JSON documents.
The primary motivation for making scouchdb is to offer a form of CouchDB driver to manipulate objects in a completely non-intrusive manner. The Scala objects are not CouchDB aware and remain completely transparent of any CouchDB dependency. Incorporating CouchDB specific attributes like id and rev take away a lot of reusability goodness from domain objects and make them constrained only for the specific platform.
One of the biggest hits of CouchDB is the view engine that uses the power of MapReduce to fetch data to the users. The current version of the framework does not offer much in terms of view creation apart from basic abstractions that allow plugging in “map” and “reduce” functions in Javascript to the design document. There are some plans to make this more Scala ish with little languages that will enable map and reduce function generation from Scala objects.
But what it offers today is a small DSL that enables building up view queries along with the sea of options that CouchDB server offers ..
// fetches records from the view named least_cost_lunch http(test view(Views.builder("lunch/least_cost_lunch").build)) // fetches records from the view named least_cost_lunch // using key and limit options couch(test view( Views.builder("lunch/least_cost_lunch") .options(optionBuilder key(List("apple", 0.79)) limit(10) build) .build)) // fetches records from the view named least_cost_lunch // using specific keys and other options for deciding output filters http(test view( Views.builder("lunch/least_cost_lunch") .options(optionBuilder descending(true) limit(10) build) .keys(List(List("apple", 0.79), List("banana", 0.79))) .build)) // temporary views val mf = """function(doc) { var store, price; if (doc.item && doc.prices) { for (store in doc.prices) { price = doc.prices[store]; emit(doc.item, price); } } }""" val rf = """function(key, values, rereduce) { return(sum(values)) }""" // with grouping val aq = Views.adhocBuilder(View(mf, rf)) .options(optionBuilder group(true) build) .build val s = http(test adhocView(aq)) s.size should equal(3) // without grouping val aq_1 = Views.adhocBuilder(View(mf, rf)) .build val s_1 = http(test adhocView(aq_1)) s_1.size should equal(1)
val att = "The quick brown fox jumps over the lazy dog." val s = Shop("Sears", "refrigerator", 12500) val d = Doc(test, "sears") var ir:(String, String) = null var ii:(String, String) = null // create a document from an object couch(d add s) ir = http(d ># %(Id._id, Id._rev)) ir._1 should equal("sears") // query by id should fetch a row ii = http(test by_id ir._1) ii._1 should equal("sears") // sticking an attachment should be successful http(d attach("foo", "text/plain", att.getBytes, Some(ii._2))) // retrieving the attachment should equal to att val air = http(d ># %(Id._id, Id._rev)) air._1 should equal("sears") http(d.getAttachment("foo") as_str) should equal(att)
Attachments can also be created for non-existing documents. In that case, the document also gets created along with the attachment. Have a look at the test suite for the spec.
Documents can be manipulated in bulks. Through one single POST, new documents can be simultaneously added, existing ones updated and deleted. Here is a sample session ..
// should insert 2 new documents, update 1 existing document and delete 1 // a scala object val s = Shop("Shoppers Stop", "refrigerator", 12500) val d = Doc(test, "ss") // another scala object val t = Address("Monroe Street", "Denver, CO", "987651") val ad = Doc(test, "add1") var ir:(String, String) = null var ir1:(String, String) = null // create a new document http(d add s) ir = http(d ># %(Id._id, Id._rev)) ir._1 should equal("ss") // create another new document http(ad add t) ir1 = http(ad ># %(Id._id, Id._rev)) ir1._1 should equal("add1") // new scala objects val s1 = Shop("cc", "refrigerator", 12500) val s2 = Shop("best buy", "macpro", 1500) val a1 = Address("Survey Park", "Kolkata", "700075") // a dsl that adds s1 and s2, updates s and deletes t val d1 = bulkBuilder(Some(s1)).id("a").build val d2 = bulkBuilder(Some(s2)).id("b").build val d3 = bulkBuilder(Some(s)).id("ss").rev(ir._2).build val d4 = bulkBuilder(None).id("add1").rev(ir1._2).deleted(true).build http(test bulkDocs(List(d1, d2, d3, d4), false)).size should equal(4)