Haskell Riak driver: creating a simple put operation

I am trying to introduce myself to Riak with a Haskell driver, and I am stuck in a simple put operation. I am confused with the signature of the put function. and nowhere is there a single example.

So, with this signature:

 put :: (FromJSON c, ToJSON c, Resolvable c) => Connection -> Bucket -> Key -> Maybe VClock -> c -> W -> DW -> IO (c, VClock) 

I have a few questions.

What is possibly VClock? Do I have to generate it in some way or enough to just indicate β€œNo”? And why did I return this VClock to the returned tuple?

Do I have to write FromJSON and ToJSON instances for every simple value I set, even if it is a simple string value? For example, if I want to put the value "Stitch" with the key "Name", how can I do this?

What is a Resolvable Instance? How to make the value of Text or String resolvable? I understand that I need to define a resolve function, but I don’t quite understand what this means and how to do it.

+6
source share
2 answers

Hopefully the following code of a simple put and get operation can help you:

 {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE UndecidableInstances #-} module Main where import Data.Aeson import qualified Network.Riak as Riak import Network.Riak.Types import Data.ByteString.Char8 hiding (putStrLn) import Data.ByteString.Lazy as L hiding (pack,putStrLn) import GHC.Generics hiding (R) -- convert String to lazy ByteString toBS :: String -> L.ByteString toBS str = L.fromChunks (pack (str):[]) putBucket :: Bucket putBucket = toBS "Bucket" putKey :: Key putKey = toBS "key" r :: R r = Default w :: W w = Default dw :: DW dw = Default rw :: RW rw = Default -- declare a data and create its instances data Coord = Coord { x :: Double, y :: Double } deriving (Generic, Show) instance FromJSON Coord instance ToJSON Coord instance (Show Coord) => Riak.Resolvable Coord where resolve ab = a value :: Coord value = Coord { x = 2.2, y = 3.3 } main :: IO () main = do -- establish a connection let client = Riak.defaultClient con <- Riak.connect client -- simple put operation put_ret <- (Riak.put con putBucket putKey Nothing value w dw) putStrLn (show put_ret) buckets <- Riak.listBuckets con print buckets -- simple get operation get_ret <- (Riak.get con putBucket putKey r) :: IO ( Maybe (Coord, VClock)) putStrLn (show get_ret) -- delete a value Riak.delete con putBucket putKey rw -- if try to get that value we will find "Nothing" get_ret <- (Riak.get con putBucket putKey r) :: IO ( Maybe (Coord, VClock)) putStrLn (show get_ret) -- print the final bucket list buckets <- Riak.listBuckets con print buckets 
+3
source

Maybe VClock is either the VClock of the object you are updating ( Just vclock ) or Nothing . You can specify Nothing here if there is no object in the database for this key.

VClock wrapped in IO ( IO (c, VClock) ) is the VClock of an inserted object returned from the database.

To use this put function, your ToJSON and FromJSON instance will be required for your data type. Aeson contains instructions for recording this automatically. You can store data other than JSON with Network.Riak.Value modules, but it's more complicated.

Resolvable is used to resolve two siblings and looks like this: a and b are MyDataType s:

instance Resolvable MyDataType where resolve ab = a

Ideally, your resolution function does something more intelligent than just choosing a or b , since ordering is not guaranteed and can be called several times if there are several siblings.

here is some code to create a Riak connection pool that you might find useful.

You end up with something similar to this:

put conn bucket key Nothing value Quorum Quorum

where value is your data. Read more about Quorum here .

+4
source

All Articles