hzk 0.0.2 → 0.1.0
raw patch · 4 files changed
+60/−56 lines, 4 files
Files
- hzk.cabal +3/−3
- src/Database/Zookeeper.hs +41/−53
- src/Database/Zookeeper/CApi.hsc +4/−0
- src/test-zookeeper.hs +12/−0
hzk.cabal view
@@ -1,12 +1,12 @@ name: hzk-author: DiegoSouza+author: DiegoSouza <dsouza@c0d3.xxx> license: BSD3-version: 0.0.2+version: 0.1.0 category: Database homepage: http://github.com/dgvncsz0f/hzk synopsis: Haskell client library for Apache Zookeeper build-type: Simple-maintainer: DiegoSouza+maintainer: DiegoSouza <dsouza@c0d3.xxx> description: A haskell binding to Apache Zookeeper C library license-file: LICENSE cabal-version: >= 1.16
src/Database/Zookeeper.hs view
@@ -27,7 +27,17 @@ -- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --- | Zookeeper client library+--------------------------------------------------------------------------------+-- |+-- Module : Database.Zookeeper+-- Copyright : (C) 2013 Diego Souza+-- License : BSD-style (see the file LICENSE)+--+-- Maintainer : Diego Souza <dsouza@c0d3.xxx>+-- Stability : experimental+--+-- Zookeeper client library+-------------------------------------------------------------------------------- module Database.Zookeeper ( -- * Description -- $description@@ -54,6 +64,7 @@ , exists , getAcl , getChildren+ , ownsEphemeral -- * Writing , set@@ -65,7 +76,7 @@ , Scheme , Timeout , Watcher- , ClientID (..)+ , ClientID () , Zookeeper () , Acl (..)@@ -124,6 +135,14 @@ Nothing -> nullPtr Just (ClientID ptr) -> ptr +-- | Test if the ephemeral node has been created by this+-- clientid. This function shall return False if the node is not+-- ephemeral or is not owned by this clientid.+ownsEphemeral :: ClientID -> Stat -> IO Bool+ownsEphemeral (ClientID clientPtr) stat = do+ uid <- toClientId clientPtr+ return (statEphemeralOwner stat == Just uid)+ -- | Sets [or redefines] the watcher function setWatcher :: Zookeeper -- ^ Zookeeper handle@@ -166,20 +185,7 @@ -> [CreateFlag] -- ^ Optional, may be empty -> (Either ZKError String -> IO ())- -- ^ The callback function. On error the user may observe the- -- following values:- --- -- * Left NoNodeError -> the parent znode does not exit- --- -- * Left NodeExistsError -> the node already exists- --- -- * Left NoAuthError -> client does not have permission- --- -- * Left NoChildrenForEphemeralsError -> cannot create children of ephemeral nodes- --- -- * Left BadArgumentsError -> invalid input params- --- -- * Left InvalidStateError -> Zookeeper state is either `ExpiredSessionState' or `AuthFailedState'+ -- ^ The callback function -> IO () create (Zookeeper zh) path mvalue acls flags callback = withCString path $ \pathPtr ->@@ -187,12 +193,12 @@ withAclList acls $ \aclPtr -> do cStrFn <- wrapStringCompletion callback rc <- c_zooACreate zh pathPtr valuePtr (fromIntegral valueLen) aclPtr (fromCreateFlags flags) cStrFn nullPtr- when (not $ isZOK rc) (callback $ Left (toZKError rc))+ unless (isZOK rc) (callback $ Left (toZKError rc)) where maybeUseAsCStringLen Nothing f = f (nullPtr, -1) maybeUseAsCStringLen (Just s) f = B.useAsCStringLen s f --- | Delete a znode in zookeeper+-- | Delete a znode in zookeeper (synchronous) delete :: Zookeeper -- ^ Zookeeper handle -> String@@ -204,21 +210,11 @@ -- expected version. If `Nothing' is given the version check -- will not take place -> IO (Either ZKError ())- -- ^ If an error occurs, you may observe the following values:- -- * Left NoNodeError -> znode does not exist- --- -- * Left NoAuthError -> client does not have permission- --- -- * Left BadVersionError -> expected version does not match actual version- --- -- * Left BadArgumentsError -> invalid input parameters- --- -- * Left InvalidStateError -> Zookeeper state is either `ExpiredSessionState' or `AuthFailedState' delete (Zookeeper zh) path mversion = withCString path $ \pathPtr -> tryZ (c_zooDelete zh pathPtr (maybe (-1) fromIntegral mversion)) (return ()) --- ^ Checks the existence of a znode+-- ^ | Checks the existence of a znode (synchronous) exists :: Zookeeper -- ^ Zookeeper handle -> String@@ -228,14 +224,6 @@ -- ^ This is set even if the znode does not exist. This allows -- users to watch znodes to appear -> IO (Either ZKError Stat)- -- ^ If an error occurs, you may observe the following values:- -- * Left NoNodeError -> znode does not exist- --- -- * Left NoAuthError -> client does not have permission- --- -- * Left BadArgumentsError -> invalid input parameters- --- -- * Left InvalidStateError -> Zookeeper state is either `ExpiredSessionState' or `AuthFailedState' exists (Zookeeper zh) path mwatcher = withCString path $ \pathPtr -> allocaStat $ \statPtr -> do@@ -254,14 +242,14 @@ -> (Either ZKError [String] -> IO ()) -- ^ The callback function -> IO ()-getChildren (Zookeeper zh) path mwatcher callback = do+getChildren (Zookeeper zh) path mwatcher callback = withCString path (\pathPtr -> do cWatcher <- wrapWatcher mwatcher cStrFn <- wrapStringsCompletion callback rc <- c_zooAWGetChildren zh pathPtr cWatcher nullPtr cStrFn nullPtr- when (not $ isZOK rc) (callback $ Left (toZKError rc)))+ unless (isZOK rc) (callback $ Left (toZKError rc))) --- | Gets the data associated with a znode+-- | Gets the data associated with a znode (asynchronous) get :: Zookeeper -- ^ The Zookeeper handle -> String@@ -278,9 +266,9 @@ cWatcher <- wrapWatcher mwatcher cDataFn <- wrapDataCompletion callback rc <- c_zooAWGet zh pathPtr cWatcher nullPtr cDataFn nullPtr- when (not $ isZOK rc) (callback $ Left (toZKError rc))+ unless (isZOK rc) (callback $ Left (toZKError rc)) --- | Sets the data associated with a znode+-- | Sets the data associated with a znode (synchronous) set :: Zookeeper -- ^ Zookeeper handle -> String@@ -296,7 +284,7 @@ -> IO (Either ZKError Stat) set (Zookeeper zh) path mdata version = withCString path $ \pathPtr ->- allocaStat $ \statPtr -> do+ allocaStat $ \statPtr -> maybeUseAsCStringLen mdata $ \(dataPtr, dataLen) -> do rc <- c_zooSet2 zh pathPtr dataPtr (fromIntegral dataLen) (maybe (-1) fromIntegral version) statPtr onZOK rc (toStat statPtr)@@ -305,7 +293,7 @@ maybeUseAsCStringLen (Just s) f = B.useAsCStringLen s f -- | Sets the acl associated with a node. This operation is not--- recursive on the children. See 'getAcl' for more information.+-- recursive on the children. See 'getAcl' for more information (synchronous) setAcl :: Zookeeper -- ^ Zookeeper handle -> String@@ -325,7 +313,7 @@ rc <- c_zooSetAcl zh pathPtr (maybe (-1) fromIntegral version) aclPtr onZOK rc $ return () --- | Gets the acl associated with a node. Unexpectedly, 'setAcl' and+-- | Gets the acl associated with a node (asynchronous). Unexpectedly, 'setAcl' and -- 'getAcl' are not symmetric: -- -- > setAcl zh path Nothing OpenAclUnsafe@@ -342,9 +330,9 @@ withCString path $ \pathPtr -> do cAclFn <- wrapAclCompletion callback rc <- c_zooAGetAcl zh pathPtr cAclFn nullPtr- when (not $ isZOK rc) (callback $ Left (toZKError rc))+ unless (isZOK rc) (callback $ Left (toZKError rc)) --- | Specify application credentials+-- | Specify application credentials (asynchronous) -- -- The application calls this function to specify its credentials for -- purposes of authentication. The server will use the security@@ -360,11 +348,11 @@ -> Scheme -- ^ Scheme id of the authentication scheme. Natively supported: --- -- * "digest" -> password authentication;+ -- * ''digest'' -> password authentication; --- -- * "ip" -> client's IP address;+ -- * ''ip'' -> client's IP address; --- -- * "host" -> client's hostname;+ -- * ''host'' -> client's hostname; -> B.ByteString -- ^ Applicaton credentials. The actual value depends on the scheme -> (Either ZKError () -> IO ())@@ -375,7 +363,7 @@ B.useAsCStringLen cert $ \(certPtr, certLen) -> do cVoidFn <- wrapVoidCompletion callback rc <- c_zooAddAuth zh schemePtr certPtr (fromIntegral certLen) cVoidFn nullPtr- when (not $ isZOK rc) (callback $ Left (toZKError rc))+ unless (isZOK rc) (callback $ Left (toZKError rc)) -- $description --@@ -392,8 +380,8 @@ -- $example ----- The following snippet creates a `/foobar' znode, then it lists and--- prints all children of the `/' znode:+-- The following snippet creates a ''/foobar'' znode, then it lists and+-- prints all children of the root znode: -- -- > module Main where -- >
src/Database/Zookeeper/CApi.hsc view
@@ -35,6 +35,7 @@ , toState , toZKError , allocaStat+ , toClientId -- * Haskell to C , withAclList , wrapWatcher@@ -160,6 +161,9 @@ buildList acc n ptr = do item <- peek ptr >>= peekCString buildList (item : acc) (n-1) (ptr `plusPtr` (sizeOf ptr))++toClientId :: Ptr CClientID -> IO Int64+toClientId clientPtr = (#peek clientid_t, client_id) clientPtr allocaStat :: (Ptr CStat -> IO a) -> IO a allocaStat fun = allocaBytes (#size struct Stat) fun
src/test-zookeeper.hs view
@@ -130,6 +130,17 @@ where watcher mvar _ event _ mpath = putMVar mvar (event, mpath) +testOwnsEphemeral zh = testGroup "ownsEphemeral"+ [ testCase "get ephemeral" $ do+ let path = chroot "/testGet#6"+ mvar <- newEmptyMVar+ create zh path Nothing OpenAclUnsafe [Ephemeral] (\_ ->+ get zh path Nothing (\(Right (_, stat)) -> do+ myId <- getClientId zh+ putMVar mvar =<< ownsEphemeral myId stat))+ takeMVar mvar @? "owns ephemeral"+ ]+ testGetChildren zh = testGroup "getChildren" [ testCase "getChildren without znode" $ do let path = chroot "/testGetChildren#1"@@ -226,6 +237,7 @@ , testExists zh , testGetAcl zh , testGetChildren zh+ , testOwnsEphemeral zh ] _ -> exitFailure where