gdritter repos tansu / master Database / Tansu.hs
master

Tree @master (Download .tar.gz)

Tansu.hs @master

66c9cf9
 
134f153
 
06b8518
6a5b3c3
134f153
6a5b3c3
 
 
 
7874530
 
6a5b3c3
 
 
 
 
8c3cab2
 
6a5b3c3
 
8c3cab2
6a5b3c3
8c3cab2
6a5b3c3
 
8c3cab2
6a5b3c3
 
 
8c3cab2
6a5b3c3
 
134f153
8c3cab2
 
6a5b3c3
134f153
 
8c3cab2
6a5b3c3
 
134f153
 
8c3cab2
 
6a5b3c3
134f153
 
 
 
 
8c3cab2
6a5b3c3
8c3cab2
 
6f70696
 
8c3cab2
6a5b3c3
8c3cab2
 
 
7874530
134f153
 
 
8c3cab2
 
{-# LANGUAGE RankNTypes #-}

module Database.Tansu ( -- * The 'Tansu' monad
                        Tansu
                      , TansuDb
                      , TansuError(..)
                        -- * 'Tansu' Operations
                      , get
                      , getMb
                      , set
                      , (=:)
                      , del
                        -- * Running a 'Tansu' operation
                      , run
                      ) where

import Data.ByteString (ByteString)
import Data.Serialize (Serialize, encode, decode)
import MonadLib (raise, try)
import Database.Tansu.Monad
import Database.Tansu.Internal

newtype Tansu a = Tansu { runTansu :: TansuM a }

instance Functor Tansu where
  fmap f (Tansu t) = Tansu (fmap f t)

instance Applicative Tansu where
  pure = Tansu . pure
  Tansu f <*> Tansu x = Tansu (f <*> x)

instance Monad Tansu where
  Tansu x >>= f = Tansu (x >>= runTansu . f)

-- | Sets the value for a key to a value.
set :: ByteString -> ByteString -> Tansu ()
set key val = Tansu $ setInternal key val

-- | Sets the value for a key to a value. A convenience operator
--   that is identical to 'set'.
(=:) :: ByteString -> ByteString -> Tansu ()
(=:) = set

-- | Gets a value for a given key. The resulting 'Tansu' computation
--   will fail if the key is not present in the storage backend.
get :: ByteString -> Tansu ByteString
get key = Tansu $ getInternal key

-- | Gets a value for a given key. If the key is not present, this
--   computation will return 'Nothing' instead. Other errors, such
--   as problems decoding the serialized value or difficulties
--   communicating with the storage backend, will still cause the
--   'Tansu' computation to fail.
getMb :: ByteString -> Tansu (Maybe ByteString)
getMb key = do
  rs <- Tansu $ try $ runTansu $ get key
  case rs of
    Left (KeyNotFound _) -> return Nothing
    Left err             -> Tansu (raise err)
    Right val            -> return (Just val)

-- | Delete a key.
del :: ByteString -> Tansu ()
del key = Tansu $ delInternal key

-- | Given a storage backend and a 'Tansu' computation, execute the
--   sequence of 'get' and 'set' commands and produce either the value
--   or the error encountered while running the computation.
run :: TansuDb -> Tansu a -> IO (Either TansuError a)
run db (Tansu mote) = runInternal db mote