Skip to content
This repository has been archived by the owner on Oct 14, 2020. It is now read-only.

Getting Started Legacy

Lucas Satabin edited this page Apr 7, 2014 · 1 revision

Download

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

Basic Usage

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 the include_docs option.

Shutting Down

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à!

Getting Asynchronous

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 Futures, you will probably continue using Sohva by importing gnieh.sohva.async._. It exposes the same classes and methods but returning Futures holding the result

Explicit Failure Management

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.

Working With Sessions, Authentication and Friends

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

Cookie Based Authentication 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"))

OAuth Session

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.

API Documentation

The ScalaDoc can be found there: http://sohva.gnieh.org/v0.5/