git » nmdb » master » tree

[master] / bindings / haskell / Nmdb.hs

-- Haskell bindings for the nmdb C library
-- Alberto Bertogli (albertito@blitiri.com.ar)

module Nmdb (
	NmdbStruct,
	nmdbInit, nmdbFree,
	nmdbAddTIPCServer, nmdbAddTCPServer, nmdbAddUDPServer,
		nmdbAddSCTPServer,
	nmdbSet, nmdbSetSync, nmdbCacheSet,
	nmdbGet, nmdbCacheGet,
	nmdbDel, nmdbDelSync, nmdbCacheDel,
	nmdbCAS, nmdbCacheCAS,
	nmdbIncr, nmdbCacheIncr,
) where

import Foreign
import Foreign.Ptr
import Foreign.Storable
import Foreign.C.Types
import Foreign.C.String
import Foreign.Marshal.Alloc


-- Opaque pointer to nmdb_t
data NmdbStruct = NmdbStruct
type NmdbPtr = Ptr NmdbStruct


-- DB creation and destroy
foreign import ccall "nmdb.h nmdb_init" llNmdbInit :: IO NmdbPtr
foreign import ccall "nmdb.h nmdb_free" llNmdbFree :: NmdbPtr -> IO ()

nmdbInit :: IO NmdbPtr
nmdbInit = llNmdbInit

nmdbFree :: NmdbPtr -> IO ()
nmdbFree = llNmdbFree


-- Adding servers
foreign import ccall "nmdb.h nmdb_add_tipc_server" llNmdbAddTIPCServer ::
	NmdbPtr -> Int -> IO Int
foreign import ccall "nmdb.h nmdb_add_tcp_server" llNmdbAddTCPServer ::
	NmdbPtr -> CString -> Int -> IO Int
foreign import ccall "nmdb.h nmdb_add_udp_server" llNmdbAddUDPServer ::
	NmdbPtr -> CString -> Int -> IO Int
foreign import ccall "nmdb.h nmdb_add_sctp_server" llNmdbAddSCTPServer ::
	NmdbPtr -> CString -> Int -> IO Int

nmdbAddTIPCServer db port = do
	r <- llNmdbAddTIPCServer db port
	return r

nmdbAddTCPServer db host port = do
	hstr <- newCString host
	r <- llNmdbAddTCPServer db hstr port
	free hstr
	return r

nmdbAddUDPServer db host port = do
	hstr <- newCString host
	r <- llNmdbAddUDPServer db hstr port
	free hstr
	return r

nmdbAddSCTPServer db host port = do
	hstr <- newCString host
	r <- llNmdbAddSCTPServer db hstr port
	free hstr
	return r

-- Set functions
foreign import ccall "nmdb.h nmdb_set" llNmdbSet ::
	NmdbPtr -> CString -> Int -> CString -> Int -> IO Int
foreign import ccall "nmdb.h nmdb_set_sync" llNmdbSetSync ::
	NmdbPtr -> CString -> Int -> CString -> Int -> IO Int
foreign import ccall "nmdb.h nmdb_cache_set" llNmdbCacheSet ::
	NmdbPtr -> CString -> Int -> CString -> Int -> IO Int

nmdbGenericSet llfunc db key val = do
	kl <- newCStringLen key
	vl <- newCStringLen val
	r <- llfunc db (fst kl) (snd kl) (fst vl) (snd vl)
	free (fst kl)
	free (fst vl)
	return r

nmdbSet = nmdbGenericSet llNmdbSet
nmdbSetSync = nmdbGenericSet llNmdbSetSync
nmdbCacheSet = nmdbGenericSet llNmdbCacheSet


-- Get functions
foreign import ccall "nmdb.h nmdb_get" llNmdbGet ::
	NmdbPtr -> CString -> Int -> CString -> Int -> IO Int
foreign import ccall "nmdb.h nmdb_cache_get" llNmdbCacheGet ::
	NmdbPtr -> CString -> Int -> CString -> Int -> IO Int

nmdbGenericGet llfunc db key = do
	let buflen = 64 * 1024
	buf <- mallocBytes buflen
	kl <- newCStringLen key
	r <- llfunc db (fst kl) (snd kl) buf buflen
	free (fst kl)
	if r < 0
	  then do
		free buf
		return Nothing
	  else do
		val <- peekCStringLen (buf, r)
		free buf
		return $ Just val

nmdbGet = nmdbGenericGet llNmdbGet
nmdbCacheGet = nmdbGenericGet llNmdbCacheGet


-- Del functions
foreign import ccall "nmdb.h nmdb_del" llNmdbDel ::
	NmdbPtr -> CString -> Int -> IO Int
foreign import ccall "nmdb.h nmdb_del_sync" llNmdbDelSync ::
	NmdbPtr -> CString -> Int -> IO Int
foreign import ccall "nmdb.h nmdb_cache_del" llNmdbCacheDel ::
	NmdbPtr -> CString -> Int -> IO Int

nmdbGenericDel llfunc db key = do
	kl <- newCStringLen key
	r <- llfunc db (fst kl) (snd kl)
	free (fst kl)
	return r

nmdbDel = nmdbGenericDel llNmdbDel
nmdbDelSync = nmdbGenericDel llNmdbDelSync
nmdbCacheDel = nmdbGenericDel llNmdbCacheDel


-- CAS functions
foreign import ccall "nmdb.h nmdb_cas" llNmdbCAS ::
	NmdbPtr -> CString -> Int -> CString -> Int -> CString -> Int -> IO Int
foreign import ccall "nmdb.h nmdb_cache_cas" llNmdbCacheCAS ::
	NmdbPtr -> CString -> Int -> CString -> Int -> CString -> Int -> IO Int

nmdbGenericCAS llfunc db key oldval newval = do
	kl <- newCStringLen key
	ovl <- newCStringLen oldval
	nvl <- newCStringLen newval
	r <- llfunc db
		(fst kl) (snd kl)
		(fst ovl) (snd ovl)
		(fst nvl) (snd nvl)
	free (fst kl)
	free (fst ovl)
	free (fst nvl)
	return r

nmdbCAS = nmdbGenericCAS llNmdbCAS
nmdbCacheCAS = nmdbGenericCAS llNmdbCacheCAS


-- Incr functions
foreign import ccall "nmdb.h nmdb_incr" llNmdbIncr ::
	NmdbPtr -> CString -> Int -> Int64 -> Ptr Int64 -> IO Int
foreign import ccall "nmdb.h nmdb_cache_incr" llNmdbCacheIncr ::
	NmdbPtr -> CString -> Int -> Int64 -> Ptr Int64 -> IO Int

nmdbGenericIncr llfunc db key increment = do
	kl <- newCStringLen key
	newval <- malloc
	r <- llfunc db (fst kl) (snd kl) increment newval
	v <- (peek newval)
	free (fst kl)
	free newval
	if r == 2
	  then do
		return $ Just v
	  else
		return Nothing

nmdbIncr = nmdbGenericIncr llNmdbIncr
nmdbCacheIncr = nmdbGenericIncr llNmdbCacheIncr