CouchDB

From HaskellWiki
Revision as of 10:12, 31 July 2010 by Andrewufrank (talk | contribs) (--)
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

CouchDB

CouchDB Haskell package is the Haskell interface to the couchDB database software. CouchDB is a document oriented datastorage system (with versions) which is geared towards replication. For more information read Anderson, Lehnardt and Slater's book "CouchDB - The definite guide" ([1]).

Examples how to use the Haskell CouchDB interface are not easy to find on the web. I found only one [2].

I created this wiki page to make available the simple examples I coded to learn to use CouchDB and to report of some of the not-so-obvious traps beginners could fall into.

Example: Store and retrieve notes

The simple example I selected is the database backend of a "note" application (e.g. Tomboy or any other of the yellow paste-it notes look-alike). The first function is to store a note, as an example on how to store data in couch:

Store note

Here the code for storing a note and retrieving it with the doc id:

 
{-# LANGUAGE DeriveDataTypeable
        , ScopedTypeVariables
        #-}

module Notes1  where

import Database.CouchDB (getDoc, newDoc, runCouchDB', db, Rev(..), Doc)
import Data.Data (Data, Typeable)

import Text.JSON
import Text.JSON.Pretty (pp_value)
import Text.JSON.Pretty (render)
import Text.JSON.Generic (toJSON, fromJSON)

type Strings = [String]  -- basic

data Note = Note {title, text :: String, tags :: Strings}
    deriving (Eq, Ord, Show, Read , Typeable, Data)  -- not yet necessary

------ copied from henry laxon

ppJSON = putStrLn . render . pp_value

justDoc :: (Data a) => Maybe (Doc, Rev, JSValue) -> a
justDoc (Just (d,r,x)) = stripResult (fromJSON x)
  where stripResult (Ok z) = z
        stripResult (Error s) = error $ "JSON error " ++ s
justDoc Nothing = error "No such Document"

 --------------------------------
mynotes = db "firstnotes1"

n0 = Note "a59" "a1 text vv 45" ["tag1"]

n1 = Note "a56" "a1 text vv 45" ["tag1"]
n2 = Note "a56" "updated a1 text vv 45" ["tag1"]

n1j = toJSON n1  -- convNote2js n1

runNotes1 = do
            (doc1, rev1) <- runCouchDB' $ newDoc mynotes n1j
            putStrLn $ "stored note" ++ show doc1 ++ "  revision " ++ show rev1
            Just (_,_,jvalue) <- runCouchDB' $ getDoc mynotes doc1
            ppJSON jvalue

            jstuff <- runCouchDB' $ getDoc mynotes doc1
            let d = justDoc jstuff :: Note
            putStrLn $ "found " ++ show d
            return ()
            
-- the output is:
--stored noteaa45700981408039346f9c8c73f8701f  
--               revision 1-7fa1d1116e6ae0c1ee8d4ce89a701fdf
--{"_id": "aa45700981408039346f9c8c73f8701f",
-- "_rev": "1-7fa1d1116e6ae0c1ee8d4ce89a701fdf", "title": "a56",
-- "text": "a1 text vv 45", "tags": ["tag1"]}
--found Note {title = "a56", text = "a1 text vv 45", tags = ["tag1"]}

Retrieve note

Notice that the syntax for retrieval has changed since the example code for "converting from MySQL to CouchDB" was written: no preceeding "/_design/" in the name of the view.


Coda

I do not guarantee for the correctness of the code (of course). I hope it is useful. I invite others to contribute their examples or more complex codes so we can learn from each other.

I am currently working and interested to hear comments at frank at geoinfo dot tuwien dot ac dot at.