-
-
Notifications
You must be signed in to change notification settings - Fork 7
Getting Started Legacy
To use sohva in your project, if you are using maven, just add the following dependency to your pom.xml file:
<dependency>
<groupId>org.gnieh</groupId>
<artifactId>sohva-client_${scala.version}</artifactId>
<version>0.5</version>
</dependency>
If you are using sbt, simply add the following line to your project descriptor:
libraryDependencies += "org.gnieh" %% "sohva-client" % "0.5"
Sohva is compiled against scala 2.9.3
and 2.10
First of all you should import all the stuffs to work with couchdb:
import gnieh.sohva.sync._
In Sohva, all starts with an instance of CouchClient
which gives all the indication on the server location and port.
val couch = new CouchClient
By default this gives a connection to a couchdb instance at localhost on port 5984.
Of course, one can override these settings by passing parameters to the constructor. See the documentation of the CouchClient
class.
Once you have a CouchClient
instance, you can access a database by using the database
method:
val database = couch.database("test")
database.create
Pretty easy, huh?
Working with documents is a piece of cake as well. Before continuing, one has to know a bit about couchdb and documents, but I am pretty sure you do, otherwise you wouldn't be here... However if anybody has no idea about couchdb, you should probably have a look at the couchdb documentation first and then come back here!
So a couchdb document is a json object that must have at least one field named _id
and containing the document id. In addition the class representing the object must have an optional field named _rev
that will hold the document revision.
Let's say one wants to save a test document into the above created database, the class representing this document may look like this:
case class Test(_id: String, value: String, _rev: Option[String] = None)
So we defined a class that has three attributes _id
, value
and _rev
.
Then instantiate a test object and save it to the database:
val test = Test("test1", "this is a test")
database.saveDoc(test)
One can then retrieve the saved document by using the getDocById
method:
val fromDb = database.getDocById[Test]("test1")
That's it!
Oh, wait! What if one wants to use designs and views? Well, the Database
class gives access to designs and design gives access to view. In Sohva, views are typed so the user has to specify the different types used in the view to work with. Be careful though, because no check is performed to ensure that the types are correct with respect to what is saved in the database, so you must ensure that your types are right to avoid weird exceptions! Three types have to be specified for a view:
-
Key
: which is the key type used to query this view. It may be any type that will be serialized to a JSON object, -
Value
: which is the type of the value returned by this view, -
Doc
: which is the type of the associated document that is returned in the case where the view is queried with theinclude_docs
option.
So you played with your couchdb client, stored and retrieved a lot of documents into and from your couchdb instance. That's good! But don't forget to shut down every couchdb client instance you created once you do not need it anymore. Each instance starts background threads that must be stopped once they become useless. To do this, it is, once more, pretty easy, you just have to run:
couch.shutdown
And voilà!
Did you noticed so far we imported stuffs from gnieh.sohva.sync
package? Thus, so far every call to a method that queries the database is synchronous.
Actually, by default, all the methods that send requests to the database server do this in an asynchronous way and return immediately. So what if this method returns a document fetched from the server? you'll ask. Well, these methods return a Future
object that encapsulates the value that will be eventually returned in response to the query. Sohva is based on the http library Dispatch, so to understand what the Promise
object does, take a look at the documentation of this project.
In the sync
package, all calls are made synchronous by waiting for the server response before unpacking the returned value and return it (or turn it into an exception if needed). Using blocking calls may look easier when starting to work with Sohva, but actually, once you understood the power of Future
s, you will probably continue using Sohva by importing gnieh.sohva.async._
. It exposes the same classes and methods but returning Future
s holding the result
The package gnieh.sohva.control
contains the interface that allows to explicitly manage failures, having results of type Try. The calls are synchronous as with interfaces in gnieh.sohva.sync
.
One other nice feature of couchdb, is that it provides user management, authentication and authorization out of the box. So why would you rebuild an entirely new user management system for your application if your database already provides all you need? That is why Sohva provides a simple way to manage users and sessions so you can benefit from it directly.
The CouchClient
provides user management methods in an object called users
val created = couch.users.add("username", "password")
This call will create a new user with the given username
and password
.
Until now, all the queries we sent to the couchdb instance were anonymous. If you want to start sending authenticated requests you will need to start a session. Two kinds of sessions are available to the user:
- Cookie based authentication session,
- OAuth session
To start a cookie based session just call
val session = couch.startCookieSession
The CookieSession
object returned exposes merely the same interface as CouchClient
plus some methods to login, logout, test login status, current user, current roles, ... All the queries sent from a CouchSession
belong to the same session, and are authenticated (if you logged in of course). To login, simply run
session.login("username", "password")
From now on (and as long as you do not logout or the session does not expire), all database accesses using the session
object are authenticated as originating from user username
.
val authTest = session.database("test")
authTest.saveDoc(Test("test2", "this is another test document"))
To start an OAuth session just call
val session = couch.startOAuthSession("consumerKey", "consumerSecret", "token", "secret")
The OAuthSession
interface is merely the same as for cookie based session, but has no login
nor logout
methods which do not make any sense in the case of OAuth.
To see how OAuth can be configured in couchdb, pleader refer to the documentation.
The ScalaDoc can be found there: http://sohva.gnieh.org/v0.5/