module Database.LevelDB.MonadResource
    ( 
      DB
    , BatchOp(..)
    , Comparator(..)
    , Compression(..)
    , Options(..)
    , ReadOptions(..)
    , Snapshot
    , WriteBatch
    , WriteOptions(..)
    , Range
    
    , defaultOptions
    , defaultWriteOptions
    , defaultReadOptions
    
    , withSnapshot
    , open
    , put
    , delete
    , write
    , get
    , createSnapshot
    , createSnapshot'
    
    , FilterPolicy(..)
    , bloomFilter
    
    , Property(..), getProperty
    , destroy
    , repair
    , approximateSize
    , compactRange
    , version
    
    , Iterator
    , withIterator
    , iterOpen
    , iterOpen'
    , iterValid
    , iterSeek
    , iterFirst
    , iterLast
    , iterNext
    , iterPrev
    , iterKey
    , iterValue
    , iterGetError
    
    , MonadResource (..)
    , runResourceT
    , resourceForkIO
    )
where
import           Control.Applicative          ((<$>))
import           Control.Monad.Trans.Resource
import           Database.LevelDB.Base        (BatchOp, BloomFilter, Comparator,
                                               Compression, DB, FilterPolicy,
                                               Iterator, Options, Property,
                                               Range, ReadOptions, Snapshot,
                                               WriteBatch, WriteOptions,
                                               approximateSize, compactRange,
                                               defaultOptions,
                                               defaultReadOptions,
                                               defaultWriteOptions, delete,
                                               destroy, get, getProperty,
                                               iterFirst, iterGetError, iterKey,
                                               iterLast, iterNext, iterPrev,
                                               iterSeek, iterValid, iterValue,
                                               put, repair, version, write)
import qualified Database.LevelDB.Base        as Base
import qualified Database.LevelDB.Internal    as Internal
bloomFilter :: MonadResource m => Int -> m BloomFilter
bloomFilter i =
    snd <$> allocate (Base.createBloomFilter i)
                      Base.releaseBloomFilter
open :: MonadResource m => FilePath -> Options -> m DB
open path opts = snd <$> open' path opts
open' :: MonadResource m => FilePath -> Options -> m (ReleaseKey, DB)
open' path opts = allocate (Base.open path opts) Internal.unsafeClose
withSnapshot :: MonadResource m => DB -> (Snapshot -> m a) -> m a
withSnapshot db f = do
    (rk, snap) <- createSnapshot' db
    res <- f snap
    release rk
    return res
createSnapshot :: MonadResource m => DB -> m Snapshot
createSnapshot db = snd <$> createSnapshot' db
createSnapshot' :: MonadResource m => DB -> m (ReleaseKey, Snapshot)
createSnapshot' db = allocate (Base.createSnapshot db) (Base.releaseSnapshot db)
withIterator :: MonadResource m => DB -> ReadOptions -> (Iterator -> m a) -> m a
withIterator db opts f = do
    (rk, iter) <- iterOpen' db opts
    res <- f iter
    release rk
    return res
iterOpen :: MonadResource m => DB -> ReadOptions -> m Iterator
iterOpen db opts = snd <$> iterOpen' db opts
iterOpen' :: MonadResource m => DB -> ReadOptions -> m (ReleaseKey, Iterator)
iterOpen' db opts = allocate (Base.createIter db opts) Base.releaseIter