Difference between revisions of "CouchDB"

From HaskellWiki
Jump to navigation Jump to search
Line 15: Line 15:
 
==== Store note ====
 
==== Store note ====
   
  +
Here the code for storing a note and retrieving it with the doc id:
more text
 
  +
<code> (
  +
{-# 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"]}
  +
  +
)</code>
   
 
==== Retrieve note ====
 
==== Retrieve note ====

Revision as of 10:05, 31 July 2010

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.