hlrdb-core 0.1.5.0 → 0.1.6.0
raw patch · 6 files changed
+62/−9 lines, 6 filesdep ~bytestringdep ~hashabledep ~hedisPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: bytestring, hashable, hedis, lens, profunctors, random, time, unordered-containers
API changes (from Hackage documentation)
+ HLRDB.Core: getbit :: MonadRedis m => RedisByteString a ByteString -> a -> Integer -> m Bool
+ HLRDB.Core: getrange :: MonadRedis m => RedisByteString a ByteString -> a -> Integer -> Integer -> m ByteString
+ HLRDB.Core: setbit :: MonadRedis m => RedisByteString a ByteString -> a -> Integer -> Bool -> m Bool
+ HLRDB.Core: setrange :: MonadRedis m => RedisByteString a ByteString -> a -> Integer -> ByteString -> m Integer
+ HLRDB.Primitives.Redis: [RKeyValueByteString] :: (a -> ByteString) -> RedisStructure (BASIC ByteString) a ByteString
+ HLRDB.Primitives.Redis: type RedisByteString k v = RedisStructure (BASIC ByteString) k ByteString
+ HLRDB.Structures.Basic: getbit :: MonadRedis m => RedisByteString a ByteString -> a -> Integer -> m Bool
+ HLRDB.Structures.Basic: getrange :: MonadRedis m => RedisByteString a ByteString -> a -> Integer -> Integer -> m ByteString
+ HLRDB.Structures.Basic: setbit :: MonadRedis m => RedisByteString a ByteString -> a -> Integer -> Bool -> m Bool
+ HLRDB.Structures.Basic: setrange :: MonadRedis m => RedisByteString a ByteString -> a -> Integer -> ByteString -> m Integer
Files
- CHANGELOG.md +4/−0
- hlrdb-core.cabal +9/−9
- src/HLRDB/Core.hs +4/−0
- src/HLRDB/Internal.hs +1/−0
- src/HLRDB/Primitives/Redis.hs +3/−0
- src/HLRDB/Structures/Basic.hs +41/−0
CHANGELOG.md view
@@ -1,3 +1,7 @@+# New in 0.1.6.0++- `getrange`, `setrange`, `getbit`, `setbit` added for new ByteString-based primitive+ # New in 0.1.4.0 - `srandmembersN` command added
hlrdb-core.cabal view
@@ -1,5 +1,5 @@ name: hlrdb-core-version: 0.1.5.0+version: 0.1.6.0 synopsis: High-level Redis Database Core API description: A library for type-driven interaction with Redis license: MIT@@ -29,15 +29,15 @@ , HLRDB.Structures.SSet , HLRDB.Internal build-depends: base >= 4.9 && < 5.0- , bytestring (>= 0.10.8.2 && < 0.10.10.0) || ^>= 0.10.10.0- , hashable (>= 1.2.6.1 && < 1.3) || ^>= 1.3- , hedis (>= 0.10.1 && <= 0.12.10) || ^>= 0.12.10- , lens (>= 4.16 && <= 4.18.1) || ^>= 4.18.1+ , bytestring >= 0.10.8.2 && < 0.10.11+ , hashable >= 1.2.6.1 && < 1.4+ , hedis >= 0.10.1 && < 0.13+ , lens >= 4.16 && < 4.20 , mtl ^>= 2.2.2- , profunctors (>= 5.2.2 && <= 5.5.1) || ^>= 5.5.1- , random ^>= 1.1- , time (>=1.6 && <1.9.3) || ^>= 1.9.3- , unordered-containers (>= 0.2.8.0 && < 0.2.10.0) || ^>= 0.2.10.0+ , profunctors >= 5.2.2 && < 5.6+ , random >= 1.1 && < 1.2+ , time >=1.6 && <1.10+ , unordered-containers >= 0.2.8.0 && < 0.2.11 hs-source-dirs: src default-language: Haskell2010 default-extensions:
src/HLRDB/Core.hs view
@@ -18,6 +18,10 @@ , incrby , decr , decrby+ , getrange+ , setrange+ , getbit+ , setbit -- * List , lrange
src/HLRDB/Internal.hs view
@@ -44,6 +44,7 @@ primKey :: RedisStructure v a b -> a -> ByteString primKey (RKeyValue (E e _ _)) k = e k primKey (RKeyValueInteger e _ _) k = e k+primKey (RKeyValueByteString e) k = e k primKey (RList (E e _ _) _) k = e k primKey (RHSet (E e _ _) _) k = e k primKey (RSet (E e _ _)) k = e k
src/HLRDB/Primitives/Redis.hs view
@@ -20,6 +20,7 @@ -- Do not allow specifying an encoding for Integer, since Redis commands like incr -- demand that *only* the standard encoding is used, e.g., 123 -> "123" RKeyValueInteger :: (a -> ByteString) -> (b -> Integer) -> (Integer -> b) -> RedisStructure (BASIC Integer) a b+ RKeyValueByteString :: (a -> ByteString) -> RedisStructure (BASIC ByteString) a ByteString RList :: RE a b -> Maybe TrimScheme -> RedisStructure LIST a b RHSet :: RE a b -> HSET v -> RedisStructure (HSET v) a b RSet :: RE a b -> RedisStructure SET a b@@ -29,6 +30,8 @@ type RedisBasic k v = RedisStructure (BASIC ()) k v -- | Alias for simple Integer storage type RedisIntegral k v = RedisStructure (BASIC Integer) k v+-- | Alias for indexable ByteString storage, allowing getting and setting ranges within the value. To enforce consistency across the low-level getrange/setrange commands, non-existent values are transparently rendered as empty ByteStrings. Note that the maximum size permitted in a single value by Redis is 512 MB.+type RedisByteString k v = RedisStructure (BASIC ByteString) k ByteString -- | Alias for a Redis List type RedisList k v = RedisStructure LIST k v -- | Alias for a Redis HSet
src/HLRDB/Structures/Basic.hs view
@@ -6,6 +6,7 @@ import HLRDB.Primitives.Aggregate import HLRDB.Primitives.Redis import HLRDB.Internal+import Data.ByteString (ByteString) import Data.ByteString.Char8 (pack) import qualified Data.HashMap.Strict as HM @@ -18,11 +19,15 @@ get (RKeyValueInteger k _ d) a = liftRedis $ Redis.get (k a) >>= \case Left e -> fail (show e) Right r -> pure $ d . fromIntegral $ decodeMInteger r+get (RKeyValueByteString k) a = liftRedis $ Redis.get (k a) >>= \case+ Left e -> fail (show e)+ Right r -> pure (maybe mempty id r) -- | Construct a query to be used with @mget@. You may combine many of these together to create complex queries. Use @mget@ to execute the query back in the Redis monad. Works on @RedisBasic a b@ and @RedisIntegral a b@. liftq :: RedisStructure (BASIC w) a b -> a ⟿ b liftq (RKeyValue (E k _ d)) = T $ \f -> fmap d . f . k liftq (RKeyValueInteger k _ d) = T $ \f -> fmap (d . fromIntegral . decodeMInteger) . f . k+liftq (RKeyValueByteString k) = T $ \f -> fmap (maybe mempty id) . f . k -- | Reify a (⟿) query into the Redis monad via a single mget command. mget :: MonadRedis m => a ⟿ b -> a -> m b@@ -39,6 +44,9 @@ Just bs -> ignore $ Redis.set (k a) bs Nothing -> ignore $ del [ k a ] set (RKeyValueInteger k e _) a i = liftRedis $ ignore $ Redis.set (k a) (pack $ show (e i))+set (RKeyValueByteString k) a b = liftRedis $ if b == mempty+ then ignore $ Redis.del [ k a ]+ else ignore $ Redis.set (k a) b -- | Convenient alias for setting a value for an optional path set' :: MonadRedis m => RedisBasic a (Maybe b) -> a -> b -> m ()@@ -50,6 +58,7 @@ liftqs :: RedisStructure (BASIC w) a b -> (a , b) -> MSET liftqs (RKeyValue (E k e _)) (a , b) = MSET $ (<>) [ (k a , e b) ] liftqs (RKeyValueInteger k e _) (a , b) = MSET $ (<>) [ (k a , Just $ pack (show (e b))) ]+liftqs (RKeyValueByteString k) (a , b) = MSET $ (<>) [ (k a , Just b) ] -- | Execute a @MSET@ query. mset :: MonadRedis m => MSET -> m ()@@ -75,6 +84,9 @@ Just bs -> ignore $ Redis.setex (k a) t bs Nothing -> ignore $ del [ k a ] setex (RKeyValueInteger k e _) a t i = liftRedis $ ignore $ Redis.setex (k a) t (pack $ show (e i))+setex (RKeyValueByteString k) a t b = liftRedis $ if b == mempty+ then ignore $ Redis.del [ k a ]+ else ignore $ Redis.setex (k a) t b -- | Increment an Integer in Redis. Empty values are treated as 0. incr :: MonadRedis m => RedisIntegral a b -> a -> m b@@ -107,4 +119,33 @@ . unwrap . Redis.decrby (p k) . e++-- | Start and end indices are inclusive. Unlike @get@, the empty bytestring is returned if the key does not exist in Redis or if the specified range is out of range.+getrange :: MonadRedis m => RedisByteString a ByteString -> a -> Integer -> Integer -> m ByteString+getrange (RKeyValueByteString p) k start =+ unwrap+ . Redis.getrange (p k) start++-- | The @Integer@ paramter is the offset. Returns the length of the string after the command has been executed.+setrange :: MonadRedis m => RedisByteString a ByteString -> a -> Integer -> ByteString -> m Integer+setrange (RKeyValueByteString p) k start =+ unwrap+ . Redis.setrange (p k) start++-- | Get the bit stored at the specified offset. Note that if no value exists in Redis or if the specified range is outside the defined range, @False@ will be returned by default.+getbit :: MonadRedis m => RedisByteString a ByteString -> a -> Integer -> m Bool+getbit (RKeyValueByteString p) k =+ fmap (1==)+ . unwrap+ . Redis.getbit (p k)++-- | Set the bit at the specified offset. If the offset is outside the existing defined range of the value, 0s are implicitly inserted to fill the intermediate space. Returns the existing value of this bit, as defined by the @getbit@ semantics above.+setbit :: MonadRedis m => RedisByteString a ByteString -> a -> Integer -> Bool -> m Bool+setbit (RKeyValueByteString p) k i =+ fmap (1==)+ . unwrap+ . Redis.setbit (p k) i+ . \case+ True -> "1"+ False -> "0"