{-# LANGUAGE LambdaCase            #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-|
Module      : Database.RocksDB.Query
Copyright   : No rights reserved
License     : UNLICENSE
Maintainer  : xenog@protonmail.com
Stability   : experimental
Portability : POSIX

Query functions to make interaction with RocksDB stores easier and safer.
-}
module Database.RocksDB.Query where

import           Conduit
import           Control.Monad
import qualified Data.ByteString  as B
import           Data.Serialize   as S
import           Database.RocksDB as R
import           UnliftIO

-- | Class for types that are database keys.
class Key key

-- | Class for types that are corresponding database key and value.
class KeyValue key value

-- | Read a value from the database, or 'Nothing' if not found.
retrieve ::
       (MonadIO m, KeyValue key value, Serialize key, Serialize value)
    => DB
    -> key
    -> m (Maybe value)
retrieve :: DB -> key -> m (Maybe value)
retrieve DB
db = DB -> Maybe ColumnFamily -> key -> m (Maybe value)
forall (m :: * -> *) key value.
(MonadIO m, KeyValue key value, Serialize key, Serialize value) =>
DB -> Maybe ColumnFamily -> key -> m (Maybe value)
retrieveCommon DB
db Maybe ColumnFamily
forall a. Maybe a
Nothing

retrieveCF ::
       (MonadIO m, KeyValue key value, Serialize key, Serialize value)
    => DB
    -> ColumnFamily
    -> key
    -> m (Maybe value)
retrieveCF :: DB -> ColumnFamily -> key -> m (Maybe value)
retrieveCF DB
db ColumnFamily
cf = DB -> Maybe ColumnFamily -> key -> m (Maybe value)
forall (m :: * -> *) key value.
(MonadIO m, KeyValue key value, Serialize key, Serialize value) =>
DB -> Maybe ColumnFamily -> key -> m (Maybe value)
retrieveCommon DB
db (ColumnFamily -> Maybe ColumnFamily
forall a. a -> Maybe a
Just ColumnFamily
cf)

-- | Read a value from the database, or 'Nothing' if not found.
retrieveCommon ::
       (MonadIO m, KeyValue key value, Serialize key, Serialize value)
    => DB
    -> Maybe ColumnFamily
    -> key
    -> m (Maybe value)
retrieveCommon :: DB -> Maybe ColumnFamily -> key -> m (Maybe value)
retrieveCommon DB
db Maybe ColumnFamily
mcf key
key =
    m (Maybe ByteString)
f m (Maybe ByteString)
-> (Maybe ByteString -> m (Maybe value)) -> m (Maybe value)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
        Maybe ByteString
Nothing -> Maybe value -> m (Maybe value)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe value
forall a. Maybe a
Nothing
        Just ByteString
bytes ->
            case ByteString -> Either String value
forall a. Serialize a => ByteString -> Either String a
decode ByteString
bytes of
                Left String
e  -> String -> m (Maybe value)
forall (m :: * -> *) a. (MonadIO m, HasCallStack) => String -> m a
throwString String
e
                Right value
x -> Maybe value -> m (Maybe value)
forall (m :: * -> *) a. Monad m => a -> m a
return (value -> Maybe value
forall a. a -> Maybe a
Just value
x)
  where
    f :: m (Maybe ByteString)
f = case Maybe ColumnFamily
mcf of
        Just ColumnFamily
cf -> DB -> ColumnFamily -> ByteString -> m (Maybe ByteString)
forall (m :: * -> *).
MonadIO m =>
DB -> ColumnFamily -> ByteString -> m (Maybe ByteString)
R.getCF DB
db ColumnFamily
cf (key -> ByteString
forall a. Serialize a => a -> ByteString
encode key
key)
        Maybe ColumnFamily
Nothing -> DB -> ByteString -> m (Maybe ByteString)
forall (m :: * -> *).
MonadIO m =>
DB -> ByteString -> m (Maybe ByteString)
R.get DB
db (key -> ByteString
forall a. Serialize a => a -> ByteString
encode key
key)

matchRecursiveList ::
     (MonadIO m, KeyValue key value, Serialize key, Serialize value)
  => key
  -> Iterator
  -> m [(key, value)]
matchRecursiveList :: key -> Iterator -> m [(key, value)]
matchRecursiveList key
base Iterator
it = m [(key, value)]
go
  where
    go :: m [(key, value)]
go = Iterator -> m (Maybe (ByteString, ByteString))
forall (m :: * -> *).
MonadIO m =>
Iterator -> m (Maybe (ByteString, ByteString))
iterEntry Iterator
it m (Maybe (ByteString, ByteString))
-> (Maybe (ByteString, ByteString) -> m [(key, value)])
-> m [(key, value)]
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
        Maybe (ByteString, ByteString)
Nothing -> [(key, value)] -> m [(key, value)]
forall (m :: * -> *) a. Monad m => a -> m a
return []
        Just (ByteString
key_bytes, ByteString
value_bytes) ->
          if ByteString
base_bytes ByteString -> ByteString -> Bool
`B.isPrefixOf` ByteString
key_bytes
              then do
                  key
key <- (String -> m key) -> (key -> m key) -> Either String key -> m key
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either String -> m key
forall (m :: * -> *) a. (MonadIO m, HasCallStack) => String -> m a
throwString key -> m key
forall (m :: * -> *) a. Monad m => a -> m a
return (ByteString -> Either String key
forall a. Serialize a => ByteString -> Either String a
decode ByteString
key_bytes)
                  value
value <- (String -> m value)
-> (value -> m value) -> Either String value -> m value
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either String -> m value
forall (m :: * -> *) a. (MonadIO m, HasCallStack) => String -> m a
throwString value -> m value
forall (m :: * -> *) a. Monad m => a -> m a
return (ByteString -> Either String value
forall a. Serialize a => ByteString -> Either String a
decode ByteString
value_bytes)
                  Iterator -> m ()
forall (m :: * -> *). MonadIO m => Iterator -> m ()
iterNext Iterator
it
                  ((key
key, value
value) (key, value) -> [(key, value)] -> [(key, value)]
forall a. a -> [a] -> [a]
:) ([(key, value)] -> [(key, value)])
-> m [(key, value)] -> m [(key, value)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m [(key, value)]
go
              else [(key, value)] -> m [(key, value)]
forall (m :: * -> *) a. Monad m => a -> m a
return []
    base_bytes :: ByteString
base_bytes = key -> ByteString
forall a. Serialize a => a -> ByteString
encode key
base

-- | Internal function for recursively matching a key.
matchRecursive ::
       ( MonadIO m
       , KeyValue key value
       , Serialize key
       , Serialize value
       )
    => key
    -> Iterator
    -> ConduitT i (key, value) m ()
matchRecursive :: key -> Iterator -> ConduitT i (key, value) m ()
matchRecursive key
base Iterator
it = ConduitT i (key, value) m ()
forall i. ConduitT i (key, value) m ()
go
  where
    go :: ConduitT i (key, value) m ()
go =
      Iterator
-> ConduitT i (key, value) m (Maybe (ByteString, ByteString))
forall (m :: * -> *).
MonadIO m =>
Iterator -> m (Maybe (ByteString, ByteString))
iterEntry Iterator
it ConduitT i (key, value) m (Maybe (ByteString, ByteString))
-> (Maybe (ByteString, ByteString) -> ConduitT i (key, value) m ())
-> ConduitT i (key, value) m ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
        Maybe (ByteString, ByteString)
Nothing -> () -> ConduitT i (key, value) m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
        Just (ByteString
key_bytes, ByteString
value_bytes) ->
            Bool
-> ConduitT i (key, value) m () -> ConduitT i (key, value) m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (ByteString
base_bytes ByteString -> ByteString -> Bool
`B.isPrefixOf` ByteString
key_bytes) (ConduitT i (key, value) m () -> ConduitT i (key, value) m ())
-> ConduitT i (key, value) m () -> ConduitT i (key, value) m ()
forall a b. (a -> b) -> a -> b
$ do
                key
key <- (String -> ConduitT i (key, value) m key)
-> (key -> ConduitT i (key, value) m key)
-> Either String key
-> ConduitT i (key, value) m key
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either String -> ConduitT i (key, value) m key
forall (m :: * -> *) a. (MonadIO m, HasCallStack) => String -> m a
throwString key -> ConduitT i (key, value) m key
forall (m :: * -> *) a. Monad m => a -> m a
return (ByteString -> Either String key
forall a. Serialize a => ByteString -> Either String a
decode ByteString
key_bytes)
                value
value <- (String -> ConduitT i (key, value) m value)
-> (value -> ConduitT i (key, value) m value)
-> Either String value
-> ConduitT i (key, value) m value
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either String -> ConduitT i (key, value) m value
forall (m :: * -> *) a. (MonadIO m, HasCallStack) => String -> m a
throwString value -> ConduitT i (key, value) m value
forall (m :: * -> *) a. Monad m => a -> m a
return (ByteString -> Either String value
forall a. Serialize a => ByteString -> Either String a
decode ByteString
value_bytes)
                (key, value) -> ConduitT i (key, value) m ()
forall (m :: * -> *) o i. Monad m => o -> ConduitT i o m ()
yield (key
key, value
value)
                Iterator -> ConduitT i (key, value) m ()
forall (m :: * -> *). MonadIO m => Iterator -> m ()
iterNext Iterator
it
                ConduitT i (key, value) m ()
go
    base_bytes :: ByteString
base_bytes = key -> ByteString
forall a. Serialize a => a -> ByteString
encode key
base

-- | Pass a short key to filter all the elements whose key prefix match it. Use
-- a sum type for keys that allows to create a version of the key that
-- serializes to a prefix of a full key.
--
-- > data MyKey = ShortKey String | FullKey String String deriving Show
-- > instance Serialize MyKey where
-- >   put (ShortKey a)  = put a
-- >   put (FullKey a b) = put a >> put b
-- >   get = FullKey <$> get <*> get
-- > instance KeyValue MyKey String
-- > main = do
-- >   db <- open "test-db" defaultOptions {createIfMissing = True}
-- >   insert db (FullKey "hello" "world") "despite all my rage"
-- >   Just record <- runResourceT . runConduit $
-- >     matching db def (ShortKey "hello") .| headC
-- >   print (record :: (MyKey, String))
-- >   -- (Fullkey "hello" "world","despite all my rage")
--
-- In this example the @ShortKey@ is serialized to the prefix of the only
-- element in the database, which is then returned. Since the 'get' function of
-- the 'Serialize' instance for @MyKey@ only understands how to deserialize a
-- @FullKey@, then that is what is returned.
matching ::
       ( MonadIO m
       , KeyValue key value
       , Serialize key
       , Serialize value
       )
    => Iterator
    -> key
    -> ConduitT i (key, value) m ()
matching :: Iterator -> key -> ConduitT i (key, value) m ()
matching Iterator
it key
base = do
    Iterator -> ByteString -> ConduitT i (key, value) m ()
forall (m :: * -> *). MonadIO m => Iterator -> ByteString -> m ()
iterSeek Iterator
it (key -> ByteString
forall a. Serialize a => a -> ByteString
encode key
base)
    key -> Iterator -> ConduitT i (key, value) m ()
forall (m :: * -> *) key value i.
(MonadIO m, KeyValue key value, Serialize key, Serialize value) =>
key -> Iterator -> ConduitT i (key, value) m ()
matchRecursive key
base Iterator
it

-- | Like 'matching', but skip to the second key passed as argument, or after if
-- there is no entry for the second key.
matchingSkip ::
       ( MonadIO m
       , KeyValue key value
       , Serialize key
       , Serialize value
       )
    => Iterator
    -> key
    -> key
    -> ConduitT i (key, value) m ()
matchingSkip :: Iterator -> key -> key -> ConduitT i (key, value) m ()
matchingSkip Iterator
it key
base key
start = do
    Iterator -> ByteString -> ConduitT i (key, value) m ()
forall (m :: * -> *). MonadIO m => Iterator -> ByteString -> m ()
iterSeek Iterator
it (key -> ByteString
forall a. Serialize a => a -> ByteString
encode key
start)
    key -> Iterator -> ConduitT i (key, value) m ()
forall (m :: * -> *) key value i.
(MonadIO m, KeyValue key value, Serialize key, Serialize value) =>
key -> Iterator -> ConduitT i (key, value) m ()
matchRecursive key
base Iterator
it

-- | Insert a record into the database.
insert ::
       (MonadIO m, KeyValue key value, Serialize key, Serialize value)
    => DB
    -> key
    -> value
    -> m ()
insert :: DB -> key -> value -> m ()
insert DB
db key
key value
value = DB -> ByteString -> ByteString -> m ()
forall (m :: * -> *).
MonadIO m =>
DB -> ByteString -> ByteString -> m ()
R.put DB
db (key -> ByteString
forall a. Serialize a => a -> ByteString
encode key
key) (value -> ByteString
forall a. Serialize a => a -> ByteString
encode value
value)

-- | Insert a record into the database.
insertCF ::
       (MonadIO m, KeyValue key value, Serialize key, Serialize value)
    => DB
    -> ColumnFamily
    -> key
    -> value
    -> m ()
insertCF :: DB -> ColumnFamily -> key -> value -> m ()
insertCF DB
db ColumnFamily
cf key
key value
value = DB -> ColumnFamily -> ByteString -> ByteString -> m ()
forall (m :: * -> *).
MonadIO m =>
DB -> ColumnFamily -> ByteString -> ByteString -> m ()
R.putCF DB
db ColumnFamily
cf (key -> ByteString
forall a. Serialize a => a -> ByteString
encode key
key) (value -> ByteString
forall a. Serialize a => a -> ByteString
encode value
value)

-- | Delete a record from the database.
remove :: (MonadIO m, Key key, Serialize key) => DB -> key -> m ()
remove :: DB -> key -> m ()
remove DB
db key
key = DB -> ByteString -> m ()
forall (m :: * -> *). MonadIO m => DB -> ByteString -> m ()
delete DB
db (key -> ByteString
forall a. Serialize a => a -> ByteString
encode key
key)

-- | Delete a record from the database.
removeCF :: (MonadIO m, Key key, Serialize key)
         => DB -> ColumnFamily -> key -> m ()
removeCF :: DB -> ColumnFamily -> key -> m ()
removeCF DB
db ColumnFamily
cf key
key = DB -> ColumnFamily -> ByteString -> m ()
forall (m :: * -> *).
MonadIO m =>
DB -> ColumnFamily -> ByteString -> m ()
deleteCF DB
db ColumnFamily
cf (key -> ByteString
forall a. Serialize a => a -> ByteString
encode key
key)

-- | Get the 'BatchOp' to insert a record in the database.
insertOp ::
       (KeyValue key value, Serialize key, Serialize value)
    => key
    -> value
    -> BatchOp
insertOp :: key -> value -> BatchOp
insertOp key
key value
value = ByteString -> ByteString -> BatchOp
R.Put (key -> ByteString
forall a. Serialize a => a -> ByteString
encode key
key) (value -> ByteString
forall a. Serialize a => a -> ByteString
encode value
value)

-- | Get the 'BatchOp' to insert a record in the database.
insertOpCF ::
       (KeyValue key value, Serialize key, Serialize value)
    => ColumnFamily
    -> key
    -> value
    -> BatchOp
insertOpCF :: ColumnFamily -> key -> value -> BatchOp
insertOpCF ColumnFamily
cf key
key value
value = ColumnFamily -> ByteString -> ByteString -> BatchOp
R.PutCF ColumnFamily
cf (key -> ByteString
forall a. Serialize a => a -> ByteString
encode key
key) (value -> ByteString
forall a. Serialize a => a -> ByteString
encode value
value)

-- | Get the 'BatchOp' to delete a record from the database.
deleteOp :: (Key key, Serialize key) => key -> BatchOp
deleteOp :: key -> BatchOp
deleteOp key
key = ByteString -> BatchOp
Del (key -> ByteString
forall a. Serialize a => a -> ByteString
encode key
key)

-- | Get the 'BatchOp' to delete a record from the database.
deleteOpCF :: (Key key, Serialize key) => ColumnFamily -> key -> BatchOp
deleteOpCF :: ColumnFamily -> key -> BatchOp
deleteOpCF ColumnFamily
cf key
key = ColumnFamily -> ByteString -> BatchOp
DelCF ColumnFamily
cf (key -> ByteString
forall a. Serialize a => a -> ByteString
encode key
key)

-- | Write a batch to the database.
writeBatch :: MonadIO m => DB -> [BatchOp] -> m ()
writeBatch :: DB -> [BatchOp] -> m ()
writeBatch = DB -> [BatchOp] -> m ()
forall (m :: * -> *). MonadIO m => DB -> [BatchOp] -> m ()
write

-- | Like 'matching' but return the first element only.
firstMatching ::
       ( MonadUnliftIO m
       , KeyValue key value
       , Serialize key
       , Serialize value
       )
    => DB
    -> key
    -> m (Maybe (key, value))
firstMatching :: DB -> key -> m (Maybe (key, value))
firstMatching DB
db key
base =
    DB
-> (Iterator -> m (Maybe (key, value))) -> m (Maybe (key, value))
forall (m :: * -> *) a.
MonadUnliftIO m =>
DB -> (Iterator -> m a) -> m a
withIter DB
db ((Iterator -> m (Maybe (key, value))) -> m (Maybe (key, value)))
-> (Iterator -> m (Maybe (key, value))) -> m (Maybe (key, value))
forall a b. (a -> b) -> a -> b
$ \Iterator
it -> ConduitT () Void m (Maybe (key, value)) -> m (Maybe (key, value))
forall (m :: * -> *) r. Monad m => ConduitT () Void m r -> m r
runConduit (ConduitT () Void m (Maybe (key, value)) -> m (Maybe (key, value)))
-> ConduitT () Void m (Maybe (key, value))
-> m (Maybe (key, value))
forall a b. (a -> b) -> a -> b
$ Iterator -> key -> ConduitT () (key, value) m ()
forall (m :: * -> *) key value i.
(MonadIO m, KeyValue key value, Serialize key, Serialize value) =>
Iterator -> key -> ConduitT i (key, value) m ()
matching Iterator
it key
base ConduitT () (key, value) m ()
-> ConduitM (key, value) Void m (Maybe (key, value))
-> ConduitT () Void m (Maybe (key, value))
forall (m :: * -> *) a b c r.
Monad m =>
ConduitM a b m () -> ConduitM b c m r -> ConduitM a c m r
.| ConduitM (key, value) Void m (Maybe (key, value))
forall (m :: * -> *) a o. Monad m => ConduitT a o m (Maybe a)
headC

-- | Like 'matching' but return the first element only.
firstMatchingCF ::
       ( MonadUnliftIO m
       , KeyValue key value
       , Serialize key
       , Serialize value
       )
    => DB
    -> ColumnFamily
    -> key
    -> m (Maybe (key, value))
firstMatchingCF :: DB -> ColumnFamily -> key -> m (Maybe (key, value))
firstMatchingCF DB
db ColumnFamily
cf key
base =
    DB
-> ColumnFamily
-> (Iterator -> m (Maybe (key, value)))
-> m (Maybe (key, value))
forall (m :: * -> *) a.
MonadUnliftIO m =>
DB -> ColumnFamily -> (Iterator -> m a) -> m a
withIterCF DB
db ColumnFamily
cf ((Iterator -> m (Maybe (key, value))) -> m (Maybe (key, value)))
-> (Iterator -> m (Maybe (key, value))) -> m (Maybe (key, value))
forall a b. (a -> b) -> a -> b
$ \Iterator
it -> ConduitT () Void m (Maybe (key, value)) -> m (Maybe (key, value))
forall (m :: * -> *) r. Monad m => ConduitT () Void m r -> m r
runConduit (ConduitT () Void m (Maybe (key, value)) -> m (Maybe (key, value)))
-> ConduitT () Void m (Maybe (key, value))
-> m (Maybe (key, value))
forall a b. (a -> b) -> a -> b
$ Iterator -> key -> ConduitT () (key, value) m ()
forall (m :: * -> *) key value i.
(MonadIO m, KeyValue key value, Serialize key, Serialize value) =>
Iterator -> key -> ConduitT i (key, value) m ()
matching Iterator
it key
base ConduitT () (key, value) m ()
-> ConduitM (key, value) Void m (Maybe (key, value))
-> ConduitT () Void m (Maybe (key, value))
forall (m :: * -> *) a b c r.
Monad m =>
ConduitM a b m () -> ConduitM b c m r -> ConduitM a c m r
.| ConduitM (key, value) Void m (Maybe (key, value))
forall (m :: * -> *) a o. Monad m => ConduitT a o m (Maybe a)
headC

-- | Like 'matchingSkip', but return the first element only.
firstMatchingSkip ::
       ( MonadUnliftIO m
       , KeyValue key value
       , Serialize key
       , Serialize value
       )
    => DB
    -> key
    -> key
    -> m (Maybe (key, value))
firstMatchingSkip :: DB -> key -> key -> m (Maybe (key, value))
firstMatchingSkip DB
db key
base key
start =
    DB
-> (Iterator -> m (Maybe (key, value))) -> m (Maybe (key, value))
forall (m :: * -> *) a.
MonadUnliftIO m =>
DB -> (Iterator -> m a) -> m a
withIter DB
db ((Iterator -> m (Maybe (key, value))) -> m (Maybe (key, value)))
-> (Iterator -> m (Maybe (key, value))) -> m (Maybe (key, value))
forall a b. (a -> b) -> a -> b
$ \Iterator
it -> ConduitT () Void m (Maybe (key, value)) -> m (Maybe (key, value))
forall (m :: * -> *) r. Monad m => ConduitT () Void m r -> m r
runConduit (ConduitT () Void m (Maybe (key, value)) -> m (Maybe (key, value)))
-> ConduitT () Void m (Maybe (key, value))
-> m (Maybe (key, value))
forall a b. (a -> b) -> a -> b
$
    Iterator -> key -> key -> ConduitT () (key, value) m ()
forall (m :: * -> *) key value i.
(MonadIO m, KeyValue key value, Serialize key, Serialize value) =>
Iterator -> key -> key -> ConduitT i (key, value) m ()
matchingSkip Iterator
it key
base key
start ConduitT () (key, value) m ()
-> ConduitM (key, value) Void m (Maybe (key, value))
-> ConduitT () Void m (Maybe (key, value))
forall (m :: * -> *) a b c r.
Monad m =>
ConduitM a b m () -> ConduitM b c m r -> ConduitM a c m r
.| ConduitM (key, value) Void m (Maybe (key, value))
forall (m :: * -> *) a o. Monad m => ConduitT a o m (Maybe a)
headC

-- | Like 'matchingSkip', but return the first element only.
firstMatchingSkipCF ::
       ( MonadUnliftIO m
       , KeyValue key value
       , Serialize key
       , Serialize value
       )
    => DB
    -> ColumnFamily
    -> key
    -> key
    -> m (Maybe (key, value))
firstMatchingSkipCF :: DB -> ColumnFamily -> key -> key -> m (Maybe (key, value))
firstMatchingSkipCF DB
db ColumnFamily
cf key
base key
start =
    DB
-> ColumnFamily
-> (Iterator -> m (Maybe (key, value)))
-> m (Maybe (key, value))
forall (m :: * -> *) a.
MonadUnliftIO m =>
DB -> ColumnFamily -> (Iterator -> m a) -> m a
withIterCF DB
db ColumnFamily
cf ((Iterator -> m (Maybe (key, value))) -> m (Maybe (key, value)))
-> (Iterator -> m (Maybe (key, value))) -> m (Maybe (key, value))
forall a b. (a -> b) -> a -> b
$ \Iterator
it -> ConduitT () Void m (Maybe (key, value)) -> m (Maybe (key, value))
forall (m :: * -> *) r. Monad m => ConduitT () Void m r -> m r
runConduit (ConduitT () Void m (Maybe (key, value)) -> m (Maybe (key, value)))
-> ConduitT () Void m (Maybe (key, value))
-> m (Maybe (key, value))
forall a b. (a -> b) -> a -> b
$
    Iterator -> key -> key -> ConduitT () (key, value) m ()
forall (m :: * -> *) key value i.
(MonadIO m, KeyValue key value, Serialize key, Serialize value) =>
Iterator -> key -> key -> ConduitT i (key, value) m ()
matchingSkip Iterator
it key
base key
start ConduitT () (key, value) m ()
-> ConduitM (key, value) Void m (Maybe (key, value))
-> ConduitT () Void m (Maybe (key, value))
forall (m :: * -> *) a b c r.
Monad m =>
ConduitM a b m () -> ConduitM b c m r -> ConduitM a c m r
.| ConduitM (key, value) Void m (Maybe (key, value))
forall (m :: * -> *) a o. Monad m => ConduitT a o m (Maybe a)
headC

-- | Like 'matching' but return a list.
matchingAsList ::
       ( MonadUnliftIO m
       , KeyValue key value
       , Serialize key
       , Serialize value
       )
    => DB
    -> key
    -> m [(key, value)]
matchingAsList :: DB -> key -> m [(key, value)]
matchingAsList DB
db key
base =
    DB -> (Iterator -> m [(key, value)]) -> m [(key, value)]
forall (m :: * -> *) a.
MonadUnliftIO m =>
DB -> (Iterator -> m a) -> m a
withIter DB
db ((Iterator -> m [(key, value)]) -> m [(key, value)])
-> (Iterator -> m [(key, value)]) -> m [(key, value)]
forall a b. (a -> b) -> a -> b
$ \Iterator
it -> do
    Iterator -> ByteString -> m ()
forall (m :: * -> *). MonadIO m => Iterator -> ByteString -> m ()
iterSeek Iterator
it (key -> ByteString
forall a. Serialize a => a -> ByteString
encode key
base)
    key -> Iterator -> m [(key, value)]
forall (m :: * -> *) key value.
(MonadIO m, KeyValue key value, Serialize key, Serialize value) =>
key -> Iterator -> m [(key, value)]
matchRecursiveList key
base Iterator
it

-- | Like 'matching' but return a list.
matchingAsListCF ::
       ( MonadUnliftIO m
       , KeyValue key value
       , Serialize key
       , Serialize value
       )
    => DB
    -> ColumnFamily
    -> key
    -> m [(key, value)]
matchingAsListCF :: DB -> ColumnFamily -> key -> m [(key, value)]
matchingAsListCF DB
db ColumnFamily
cf key
base =
    DB
-> ColumnFamily
-> (Iterator -> m [(key, value)])
-> m [(key, value)]
forall (m :: * -> *) a.
MonadUnliftIO m =>
DB -> ColumnFamily -> (Iterator -> m a) -> m a
withIterCF DB
db ColumnFamily
cf ((Iterator -> m [(key, value)]) -> m [(key, value)])
-> (Iterator -> m [(key, value)]) -> m [(key, value)]
forall a b. (a -> b) -> a -> b
$ \Iterator
it -> do
    Iterator -> ByteString -> m ()
forall (m :: * -> *). MonadIO m => Iterator -> ByteString -> m ()
iterSeek Iterator
it (key -> ByteString
forall a. Serialize a => a -> ByteString
encode key
base)
    key -> Iterator -> m [(key, value)]
forall (m :: * -> *) key value.
(MonadIO m, KeyValue key value, Serialize key, Serialize value) =>
key -> Iterator -> m [(key, value)]
matchRecursiveList key
base Iterator
it

-- | Like 'matchingSkip', but return a list.
matchingSkipAsList ::
       ( MonadUnliftIO m
       , KeyValue key value
       , Serialize key
       , Serialize value
       )
    => DB
    -> key
    -> key
    -> m [(key, value)]
matchingSkipAsList :: DB -> key -> key -> m [(key, value)]
matchingSkipAsList DB
db key
base key
start =
    DB -> (Iterator -> m [(key, value)]) -> m [(key, value)]
forall (m :: * -> *) a.
MonadUnliftIO m =>
DB -> (Iterator -> m a) -> m a
withIter DB
db ((Iterator -> m [(key, value)]) -> m [(key, value)])
-> (Iterator -> m [(key, value)]) -> m [(key, value)]
forall a b. (a -> b) -> a -> b
$ \Iterator
it -> do
    Iterator -> ByteString -> m ()
forall (m :: * -> *). MonadIO m => Iterator -> ByteString -> m ()
iterSeek Iterator
it (key -> ByteString
forall a. Serialize a => a -> ByteString
encode key
start)
    key -> Iterator -> m [(key, value)]
forall (m :: * -> *) key value.
(MonadIO m, KeyValue key value, Serialize key, Serialize value) =>
key -> Iterator -> m [(key, value)]
matchRecursiveList key
base Iterator
it

-- | Like 'matchingSkip', but return a list.
matchingSkipAsListCF ::
       ( MonadUnliftIO m
       , KeyValue key value
       , Serialize key
       , Serialize value
       )
    => DB
    -> ColumnFamily
    -> key
    -> key
    -> m [(key, value)]
matchingSkipAsListCF :: DB -> ColumnFamily -> key -> key -> m [(key, value)]
matchingSkipAsListCF DB
db ColumnFamily
cf key
base key
start =
    DB
-> ColumnFamily
-> (Iterator -> m [(key, value)])
-> m [(key, value)]
forall (m :: * -> *) a.
MonadUnliftIO m =>
DB -> ColumnFamily -> (Iterator -> m a) -> m a
withIterCF DB
db ColumnFamily
cf ((Iterator -> m [(key, value)]) -> m [(key, value)])
-> (Iterator -> m [(key, value)]) -> m [(key, value)]
forall a b. (a -> b) -> a -> b
$ \Iterator
it -> do
    Iterator -> ByteString -> m ()
forall (m :: * -> *). MonadIO m => Iterator -> ByteString -> m ()
iterSeek Iterator
it (key -> ByteString
forall a. Serialize a => a -> ByteString
encode key
start)
    key -> Iterator -> m [(key, value)]
forall (m :: * -> *) key value.
(MonadIO m, KeyValue key value, Serialize key, Serialize value) =>
key -> Iterator -> m [(key, value)]
matchRecursiveList key
base Iterator
it