-- | This package is an abstract API for modeling high-level Redis functionality. It makes no opinion on either serialization or key construction, which means there is a fair amount of work to do to make this library usable. If you do not want to do this work and don't mind these decisions being made for you, you may use the HLRDB library, which gives you a ready-to-go API.
-- 
-- This package depends on the Hedis library for low-level Redis bindings, but it is not recommended to import them together in the same module, as there are many name conflicts, since much of what HLRDB does is simply assign types to commands. Despite this, much of the HLRDB API does differ entirely, with many commands added, removed, merged, or simply rethought from a Haskell perspective.
--
-- When using this package, you should always ensure that your Eq instances respect the induced equality via whatever serialization mechanism you've specified, since many commands perform comparisons in Redis directly.

module HLRDB.Core
       ( -- * Basic
         get
       , liftq
       , mget
       , set
       , set'
       , liftqs
       , mset
       , setex
       , incr
       , incrby
       , decr
       , decrby
       , getrange
       , setrange
       , getbit
       , setbit

         -- * List         
       , lrange
       , lprepend
       , lappend
       , lpop
       , lrem
       , llen

         -- * HSet
       , hgetall
       , hget
       , hmget
       , hset
       , hmset
       , hdel
       , hsetnx
       , hscan

         -- * Set
       , smembers
       , sismember
       , sadd
       , srem
       , scard
       , srandmember
       , srandmemberN
       , sscan

         -- * SSet
       , zadd
       , zscore
       , zupdate
       , zbest
       , zworst
       , zmember
       , zrank
       , zrevrank
       , zrem
       , zincrby
       , zcard
       , zscan
       , zrangebyscore

         -- * Universal
       , HLRDB.Core.del
       , HLRDB.Core.persist
       , HLRDB.Core.expire
       , HLRDB.Core.expireat
       
         -- * Re-exports from hedis
       , Redis
       , MonadRedis
       , liftRedis
       , Cursor
       , cursor0

         -- * HLRDB Primitive re-exports
       
       , module HLRDB.Primitives.Aggregate
       , module HLRDB.Primitives.Redis
       
       ) where

import Data.Time
import Data.Time.Clock.POSIX
import Database.Redis (Redis,MonadRedis,liftRedis,Cursor,cursor0,del,persist,expire,expireat)

import HLRDB.Primitives.Aggregate
import HLRDB.Primitives.Redis
import HLRDB.Internal
import HLRDB.Structures.Basic
import HLRDB.Structures.List
import HLRDB.Structures.HSet
import HLRDB.Structures.Set
import HLRDB.Structures.SSet


-- | Delete all data for the given keys in Redis
del :: (Traversable t , MonadRedis m) => RedisStructure v a b -> t a -> m (ActionPerformed Deletion)
del :: RedisStructure v a b -> t a -> m (ActionPerformed Deletion)
del RedisStructure v a b
p =
    (Integer -> ActionPerformed Deletion)
-> m Integer -> m (ActionPerformed Deletion)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Integer -> ActionPerformed Deletion
Deleted
  (m Integer -> m (ActionPerformed Deletion))
-> (t a -> m Integer) -> t a -> m (ActionPerformed Deletion)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([ByteString] -> Redis Integer)
-> (a -> ByteString) -> t a -> m Integer
forall (m :: * -> *) (t :: * -> *) i b a.
(MonadRedis m, Traversable t, Integral i) =>
([b] -> Redis i) -> (a -> b) -> t a -> m i
fixEmpty' (Redis (Either Reply Integer) -> Redis Integer
forall (m :: * -> *) a.
MonadRedis m =>
Redis (Either Reply a) -> m a
unwrap (Redis (Either Reply Integer) -> Redis Integer)
-> ([ByteString] -> Redis (Either Reply Integer))
-> [ByteString]
-> Redis Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ByteString] -> Redis (Either Reply Integer)
forall (m :: * -> *) (f :: * -> *).
RedisCtx m f =>
[ByteString] -> m (f Integer)
Database.Redis.del) (RedisStructure v a b -> a -> ByteString
forall v a b. RedisStructure v a b -> a -> ByteString
primKey RedisStructure v a b
p)

-- | Discard any pending expirations of this key. Returns True if the key both exists and had a timeout which was removed by the command.
persist :: MonadRedis m => RedisStructure v a b -> a -> m Bool
persist :: RedisStructure v a b -> a -> m Bool
persist RedisStructure v a b
p =
  Redis Bool -> m Bool
forall (m :: * -> *) a. MonadRedis m => Redis a -> m a
liftRedis (Redis Bool -> m Bool) -> (a -> Redis Bool) -> a -> m Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Redis (Either Reply Bool) -> Redis Bool
forall (m :: * -> *) a.
MonadRedis m =>
Redis (Either Reply a) -> m a
unwrap (Redis (Either Reply Bool) -> Redis Bool)
-> (a -> Redis (Either Reply Bool)) -> a -> Redis Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Redis (Either Reply Bool)
forall (m :: * -> *) (f :: * -> *).
RedisCtx m f =>
ByteString -> m (f Bool)
Database.Redis.persist (ByteString -> Redis (Either Reply Bool))
-> (a -> ByteString) -> a -> Redis (Either Reply Bool)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RedisStructure v a b -> a -> ByteString
forall v a b. RedisStructure v a b -> a -> ByteString
primKey RedisStructure v a b
p

-- | Expire after a given amount of time (in seconds). Returns True if the key existed and a timeout was set.
expire :: MonadRedis m => RedisStructure v a b -> a -> Integer -> m Bool
expire :: RedisStructure v a b -> a -> Integer -> m Bool
expire RedisStructure v a b
p a
k =
  Redis Bool -> m Bool
forall (m :: * -> *) a. MonadRedis m => Redis a -> m a
liftRedis (Redis Bool -> m Bool)
-> (Integer -> Redis Bool) -> Integer -> m Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Redis (Either Reply Bool) -> Redis Bool
forall (m :: * -> *) a.
MonadRedis m =>
Redis (Either Reply a) -> m a
unwrap (Redis (Either Reply Bool) -> Redis Bool)
-> (Integer -> Redis (Either Reply Bool)) -> Integer -> Redis Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Integer -> Redis (Either Reply Bool)
forall (m :: * -> *) (f :: * -> *).
RedisCtx m f =>
ByteString -> Integer -> m (f Bool)
Database.Redis.expire (RedisStructure v a b -> a -> ByteString
forall v a b. RedisStructure v a b -> a -> ByteString
primKey RedisStructure v a b
p a
k)

-- | Expire at a given timestamp. Returns True if the key existed and a timeout was set.
expireat :: MonadRedis m => RedisStructure v a b -> a -> UTCTime -> m Bool
expireat :: RedisStructure v a b -> a -> UTCTime -> m Bool
expireat RedisStructure v a b
p a
k =
    Redis Bool -> m Bool
forall (m :: * -> *) a. MonadRedis m => Redis a -> m a
liftRedis
  (Redis Bool -> m Bool)
-> (UTCTime -> Redis Bool) -> UTCTime -> m Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Redis (Either Reply Bool) -> Redis Bool
forall (m :: * -> *) a.
MonadRedis m =>
Redis (Either Reply a) -> m a
unwrap
  (Redis (Either Reply Bool) -> Redis Bool)
-> (UTCTime -> Redis (Either Reply Bool)) -> UTCTime -> Redis Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Integer -> Redis (Either Reply Bool)
forall (m :: * -> *) (f :: * -> *).
RedisCtx m f =>
ByteString -> Integer -> m (f Bool)
Database.Redis.expireat (RedisStructure v a b -> a -> ByteString
forall v a b. RedisStructure v a b -> a -> ByteString
primKey RedisStructure v a b
p a
k)
  (Integer -> Redis (Either Reply Bool))
-> (UTCTime -> Integer) -> UTCTime -> Redis (Either Reply Bool)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. POSIXTime -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
round
  (POSIXTime -> Integer)
-> (UTCTime -> POSIXTime) -> UTCTime -> Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UTCTime -> POSIXTime
utcTimeToPOSIXSeconds