diff --git a/benchmark/Benchmark.hs b/benchmark/Benchmark.hs index a41dce7d..74b5eeb4 100644 --- a/benchmark/Benchmark.hs +++ b/benchmark/Benchmark.hs @@ -1,4 +1,4 @@ -{-# LANGUAGE OverloadedStrings, LambdaCase #-} +{-# LANGUAGE OverloadedStrings, LambdaCase, OverloadedLists #-} module Main where diff --git a/src/Database/Redis/Commands.hs b/src/Database/Redis/Commands.hs index a8e29647..90aeb6b2 100644 --- a/src/Database/Redis/Commands.hs +++ b/src/Database/Redis/Commands.hs @@ -1,4 +1,4 @@ -{-# LANGUAGE OverloadedStrings, FlexibleContexts #-} +{-# LANGUAGE OverloadedStrings, FlexibleContexts, OverloadedLists #-} module Database.Redis.Commands ( @@ -6,232 +6,249 @@ module Database.Redis.Commands ( -- *** auth -- $auth -auth, +auth, authOpts, AuthOpts(..), defaultAuthOpts, -- *** Other commands -echo, -- |Echo the given string (). Since Redis 1.0.0 -ping, -- |Ping the server (). Since Redis 1.0.0 -quit, -- |Close the connection (). Since Redis 1.0.0 -select, -- |Change the selected database for the current connection (). Since Redis 1.0.0 +echo, +ping, +quit, +select, -- ** Keys del, -dump, -- |Return a serialized version of the value stored at the specified key (). Since Redis 2.6.0 -exists, -- |Determine if a key exists (). Since Redis 1.0.0 -expire, -- |Set a key's time to live in seconds (). Since Redis 1.0.0 -expireat, -- |Set the expiration for a key as a UNIX timestamp (). Since Redis 1.2.0 -keys, -- |Find all keys matching the given pattern (). Since Redis 1.0.0 +dump, +exists, +expire, +ExpireOpts(..), +expireOpts, +expireat, +expireatOpts, +keys, MigrateOpts(..), defaultMigrateOpts, -migrate, -- |Atomically transfer a key from a Redis instance to another one (). The Redis command @MIGRATE@ is split up into 'migrate', 'migrateMultiple'. Since Redis 2.6.0 -migrateMultiple, -- |Atomically transfer a key from a Redis instance to another one (). The Redis command @MIGRATE@ is split up into 'migrate', 'migrateMultiple'. Since Redis 2.6.0 -move, -- |Move a key to another database (). Since Redis 1.0.0 -objectRefcount, -- |Inspect the internals of Redis objects (). The Redis command @OBJECT@ is split up into 'objectRefcount', 'objectEncoding', 'objectIdletime'. Since Redis 2.2.3 -objectEncoding, -- |Inspect the internals of Redis objects (). The Redis command @OBJECT@ is split up into 'objectRefcount', 'objectEncoding', 'objectIdletime'. Since Redis 2.2.3 -objectIdletime, -- |Inspect the internals of Redis objects (). The Redis command @OBJECT@ is split up into 'objectRefcount', 'objectEncoding', 'objectIdletime'. Since Redis 2.2.3 -persist, -- |Remove the expiration from a key (). Since Redis 2.2.0 -pexpire, -- |Set a key's time to live in milliseconds (). Since Redis 2.6.0 -pexpireat, -- |Set the expiration for a key as a UNIX timestamp specified in milliseconds (). Since Redis 2.6.0 -pttl, -- |Get the time to live for a key in milliseconds (). Since Redis 2.6.0 -randomkey, -- |Return a random key from the keyspace (). Since Redis 1.0.0 -rename, -- |Rename a key (). Since Redis 1.0.0 -renamenx, -- |Rename a key, only if the new key does not exist (). Since Redis 1.0.0 -restore, -- |Create a key using the provided serialized value, previously obtained using DUMP (). The Redis command @RESTORE@ is split up into 'restore', 'restoreReplace'. Since Redis 2.6.0 -restoreReplace, -- |Create a key using the provided serialized value, previously obtained using DUMP (). The Redis command @RESTORE@ is split up into 'restore', 'restoreReplace'. Since Redis 2.6.0 +migrate, +migrateMultiple, +move, +objectRefcount, +objectEncoding, +objectIdletime, +persist, +pexpire, +pexpireat, +pexpireatOpts, +pttl, +randomkey, +rename, +renamenx, +restore, +restoreReplace, Cursor, cursor0, ScanOpts(..), defaultScanOpts, -scan, -- |Incrementally iterate the keys space (). The Redis command @SCAN@ is split up into 'scan', 'scanOpts'. Since Redis 2.8.0 -scanOpts, -- |Incrementally iterate the keys space (). The Redis command @SCAN@ is split up into 'scan', 'scanOpts'. Since Redis 2.8.0 +scan, +scanOpts, SortOpts(..), defaultSortOpts, SortOrder(..), -sort, -- |Sort the elements in a list, set or sorted set (). The Redis command @SORT@ is split up into 'sort', 'sortStore'. Since Redis 1.0.0 -sortStore, -- |Sort the elements in a list, set or sorted set (). The Redis command @SORT@ is split up into 'sort', 'sortStore'. Since Redis 1.0.0 -ttl, -- |Get the time to live for a key (). Since Redis 1.0.0 +sort, +sortStore, +ttl, RedisType(..), -getType, -- |Determine the type stored at key (). Since Redis 1.0.0 -wait, -- |Wait for the synchronous replication of all the write commands sent in the context of the current connection (). Since Redis 3.0.0 +getType, +wait, -- ** Hashes -hdel, -- |Delete one or more hash fields (). Since Redis 2.0.0 -hexists, -- |Determine if a hash field exists (). Since Redis 2.0.0 -hget, -- |Get the value of a hash field (). Since Redis 2.0.0 -hgetall, -- |Get all the fields and values in a hash (). Since Redis 2.0.0 -hincrby, -- |Increment the integer value of a hash field by the given number (). Since Redis 2.0.0 -hincrbyfloat, -- |Increment the float value of a hash field by the given amount (). Since Redis 2.6.0 -hkeys, -- |Get all the fields in a hash (). Since Redis 2.0.0 -hlen, -- |Get the number of fields in a hash (). Since Redis 2.0.0 -hmget, -- |Get the values of all the given hash fields (). Since Redis 2.0.0 -hmset, -- |Set multiple hash fields to multiple values (). Since Redis 2.0.0 -hscan, -- |Incrementally iterate hash fields and associated values (). The Redis command @HSCAN@ is split up into 'hscan', 'hscanOpts'. Since Redis 2.8.0 -hscanOpts, -- |Incrementally iterate hash fields and associated values (). The Redis command @HSCAN@ is split up into 'hscan', 'hscanOpts'. Since Redis 2.8.0 -hset, -- |Set the string value of a hash field (). Since Redis 2.0.0 -hsetnx, -- |Set the value of a hash field, only if the field does not exist (). Since Redis 2.0.0 -hstrlen, -- |Get the length of the value of a hash field (). Since Redis 3.2.0 -hvals, -- |Get all the values in a hash (). Since Redis 2.0.0 +hdel, +hexists, +hget, +hgetall, +hincrby, +hincrbyfloat, +hkeys, +hlen, +hmget, +hmset, +hscan, +hscanOpts, +hset, +hsetnx, +hstrlen, +hvals, -- ** HyperLogLogs -pfadd, -- |Adds all the elements arguments to the HyperLogLog data structure stored at the variable name specified as first argument (). Since Redis 2.8.9 -pfcount, -- |Return the approximated cardinality of the set(s) observed by the HyperLogLog at key(s) (). Since Redis 2.8.9 -pfmerge, -- |Merge N different HyperLogLogs into a single one (). Since Redis 2.8.9 +pfadd, +pfcount, +pfmerge, -- ** Lists -blpop, -- |Remove and get the first element in a list, or block until one is available (). Since Redis 2.0.0 -brpop, -- |Remove and get the last element in a list, or block until one is available (). Since Redis 2.0.0 -brpoplpush, -- |Pop a value from a list, push it to another list and return it; or block until one is available (). Since Redis 2.2.0 -lindex, -- |Get an element from a list by its index (). Since Redis 1.0.0 -linsertBefore, -- |Insert an element before or after another element in a list (). The Redis command @LINSERT@ is split up into 'linsertBefore', 'linsertAfter'. Since Redis 2.2.0 -linsertAfter, -- |Insert an element before or after another element in a list (). The Redis command @LINSERT@ is split up into 'linsertBefore', 'linsertAfter'. Since Redis 2.2.0 -llen, -- |Get the length of a list (). Since Redis 1.0.0 -lpop, -- |Remove and get the first element in a list (). Since Redis 1.0.0 -lpush, -- |Prepend one or multiple values to a list (). Since Redis 1.0.0 -lpushx, -- |Prepend a value to a list, only if the list exists (). Since Redis 2.2.0 -lrange, -- |Get a range of elements from a list (). Since Redis 1.0.0 -lrem, -- |Remove elements from a list (). Since Redis 1.0.0 -lset, -- |Set the value of an element in a list by its index (). Since Redis 1.0.0 -ltrim, -- |Trim a list to the specified range (). Since Redis 1.0.0 -rpop, -- |Remove and get the last element in a list (). Since Redis 1.0.0 -rpoplpush, -- |Remove the last element in a list, prepend it to another list and return it (). Since Redis 1.2.0 -rpush, -- |Append one or multiple values to a list (). Since Redis 1.0.0 -rpushx, -- |Append a value to a list, only if the list exists (). Since Redis 2.2.0 +blpop, +blpopFloat, +brpop, +brpopFloat, +brpoplpush, +lindex, +linsertBefore, +linsertAfter, +llen, +lpop, +lpopCount, +lpush, +lpushx, +lrange, +lrem, +lset, +ltrim, +rpop, +rpopCount, +rpoplpush, +rpush, +rpushx, -- ** Scripting -eval, -- |Execute a Lua script server side (). Since Redis 2.6.0 -evalsha, -- |Execute a Lua script server side (). Since Redis 2.6.0 +eval, +evalsha, DebugMode, -scriptDebug, -- |Set the debug mode for executed scripts (). Since Redis 3.2.0 -scriptExists, -- |Check existence of scripts in the script cache (). Since Redis 2.6.0 -scriptFlush, -- |Remove all the scripts from the script cache (). Since Redis 2.6.0 -scriptKill, -- |Kill the script currently in execution (). Since Redis 2.6.0 -scriptLoad, -- |Load the specified Lua script into the script cache (). Since Redis 2.6.0 +scriptDebug, +scriptExists, +scriptFlush, +scriptKill, +scriptLoad, -- ** Server -bgrewriteaof, -- |Asynchronously rewrite the append-only file (). Since Redis 1.0.0 -bgsave, -- |Asynchronously save the dataset to disk (). Since Redis 1.0.0 -clientGetname, -- |Get the current connection name (). Since Redis 2.6.9 -clientId, -- |Get the current connection ID (). Since Redis 5.0.0 -clientList, -- |Get the list of client connections (). Since Redis 2.4.0 -clientPause, -- |Stop processing commands from clients for some time (). Since Redis 2.9.50 +bgrewriteaof, +bgsave, +bgsaveSchedule, +clientGetname, +clientId, +clientList, +clientPause, ReplyMode, -clientReply, -- |Instruct the server whether to reply to commands (). Since Redis 3.2 -clientSetname, -- |Set the current connection name (). Since Redis 2.6.9 -commandCount, -- |Get total number of Redis commands (). Since Redis 2.8.13 -commandInfo, -- |Get array of specific Redis command details (). Since Redis 2.8.13 -configGet, -- |Get the value of a configuration parameter (). Since Redis 2.0.0 -configResetstat, -- |Reset the stats returned by INFO (). Since Redis 2.0.0 -configRewrite, -- |Rewrite the configuration file with the in memory configuration (). Since Redis 2.8.0 -configSet, -- |Set a configuration parameter to the given value (). Since Redis 2.0.0 -dbsize, -- |Return the number of keys in the selected database (). Since Redis 1.0.0 -debugObject, -- |Get debugging information about a key (). Since Redis 1.0.0 -flushall, -- |Remove all keys from all databases (). Since Redis 1.0.0 -flushdb, -- |Remove all keys from the current database (). Since Redis 1.0.0 +clientReply, +clientSetname, +commandCount, +commandInfo, +configGet, +configResetstat, +configRewrite, +configSet, +dbsize, +debugObject, +flushall, +flushallOpts, +FlushOpts(..), +flushdb, +flushdbOpts, info, -- |Get information and statistics about the server (). The Redis command @INFO@ is split up into 'info', 'infoSection'. Since Redis 1.0.0 infoSection, -- |Get information and statistics about the server (). The Redis command @INFO@ is split up into 'info', 'infoSection'. Since Redis 1.0.0 lastsave, -- |Get the UNIX time stamp of the last successful save to disk (). Since Redis 1.0.0 -save, -- |Synchronously save the dataset to disk (). Since Redis 1.0.0 -slaveof, -- |Make the server a slave of another instance, or promote it as master (). Since Redis 1.0.0 +save, +slaveof, Slowlog(..), slowlogGet, -- |Manages the Redis slow queries log (). The Redis command @SLOWLOG@ is split up into 'slowlogGet', 'slowlogLen', 'slowlogReset'. Since Redis 2.2.12 slowlogLen, -- |Manages the Redis slow queries log (). The Redis command @SLOWLOG@ is split up into 'slowlogGet', 'slowlogLen', 'slowlogReset'. Since Redis 2.2.12 slowlogReset, -- |Manages the Redis slow queries log (). The Redis command @SLOWLOG@ is split up into 'slowlogGet', 'slowlogLen', 'slowlogReset'. Since Redis 2.2.12 -time, -- |Return the current server time (). Since Redis 2.6.0 +time, -- ** Sets sadd, -scard, -- |Get the number of members in a set (). Since Redis 1.0.0 -sdiff, -- |Subtract multiple sets (). Since Redis 1.0.0 -sdiffstore, -- |Subtract multiple sets and store the resulting set in a key (). Since Redis 1.0.0 -sinter, -- |Intersect multiple sets (). Since Redis 1.0.0 -sinterstore, -- |Intersect multiple sets and store the resulting set in a key (). Since Redis 1.0.0 -sismember, -- |Determine if a given value is a member of a set (). Since Redis 1.0.0 -smembers, -- |Get all the members in a set (). Since Redis 1.0.0 -smove, -- |Move a member from one set to another (). Since Redis 1.0.0 -spop, -- |Remove and return one or multiple random members from a set (). The Redis command @SPOP@ is split up into 'spop', 'spopN'. Since Redis 1.0.0 -spopN, -- |Remove and return one or multiple random members from a set (). The Redis command @SPOP@ is split up into 'spop', 'spopN'. Since Redis 1.0.0 -srandmember, -- |Get one or multiple random members from a set (). The Redis command @SRANDMEMBER@ is split up into 'srandmember', 'srandmemberN'. Since Redis 1.0.0 -srandmemberN, -- |Get one or multiple random members from a set (). The Redis command @SRANDMEMBER@ is split up into 'srandmember', 'srandmemberN'. Since Redis 1.0.0 +scard, +sdiff, +sdiffstore, +sinter, +sinterstore, +sismember, +smembers, +smove, +spop, +spopN, +srandmember, +srandmemberN, srem, -sscan, -- |Incrementally iterate Set elements (). The Redis command @SSCAN@ is split up into 'sscan', 'sscanOpts'. Since Redis 2.8.0 -sscanOpts, -- |Incrementally iterate Set elements (). The Redis command @SSCAN@ is split up into 'sscan', 'sscanOpts'. Since Redis 2.8.0 -sunion, -- |Add multiple sets (). Since Redis 1.0.0 -sunionstore, -- |Add multiple sets and store the resulting set in a key (). Since Redis 1.0.0 +sscan, +sscanOpts, +sunion, +sunionstore, -- ** Sorted Sets ZaddOpts(..), defaultZaddOpts, -zadd, -- |Add one or more members to a sorted set, or update its score if it already exists (). The Redis command @ZADD@ is split up into 'zadd', 'zaddOpts'. Since Redis 1.2.0 -zaddOpts, -- |Add one or more members to a sorted set, or update its score if it already exists (). The Redis command @ZADD@ is split up into 'zadd', 'zaddOpts'. Since Redis 1.2.0 +zadd, +zaddOpts, SizeCondition(..), -zcard, -- |Get the number of members in a sorted set (). Since Redis 1.2.0 -zcount, -- |Count the members in a sorted set with scores within the given values (). Since Redis 2.0.0 -zincrby, -- |Increment the score of a member in a sorted set (). Since Redis 1.2.0 +zcard, +zcount, +zincrby, Aggregate(..), -zinterstore, -- |Intersect multiple sorted sets and store the resulting sorted set in a new key (). The Redis command @ZINTERSTORE@ is split up into 'zinterstore', 'zinterstoreWeights'. Since Redis 2.0.0 -zinterstoreWeights, -- |Intersect multiple sorted sets and store the resulting sorted set in a new key (). The Redis command @ZINTERSTORE@ is split up into 'zinterstore', 'zinterstoreWeights'. Since Redis 2.0.0 -zlexcount, -- |Count the number of members in a sorted set between a given lexicographical range (). Since Redis 2.8.9 -zrange, -- |Return a range of members in a sorted set, by index (). The Redis command @ZRANGE@ is split up into 'zrange', 'zrangeWithscores'. Since Redis 1.2.0 -zrangeWithscores, -- |Return a range of members in a sorted set, by index (). The Redis command @ZRANGE@ is split up into 'zrange', 'zrangeWithscores'. Since Redis 1.2.0 +zinterstore, +zinterstoreWeights, +zlexcount, +zrange, +zrangeWithscores, RangeLex(..), -zrangebylex, zrangebylexLimit, -- |Return a range of members in a sorted set, by lexicographical range (). Since Redis 2.8.9 +zrangebylex, zrangebylexLimit, zrangebyscore, -- |Return a range of members in a sorted set, by score (). The Redis command @ZRANGEBYSCORE@ is split up into 'zrangebyscore', 'zrangebyscoreWithscores', 'zrangebyscoreLimit', 'zrangebyscoreWithscoresLimit'. Since Redis 1.0.5 zrangebyscoreWithscores, -- |Return a range of members in a sorted set, by score (). The Redis command @ZRANGEBYSCORE@ is split up into 'zrangebyscore', 'zrangebyscoreWithscores', 'zrangebyscoreLimit', 'zrangebyscoreWithscoresLimit'. Since Redis 1.0.5 zrangebyscoreLimit, -- |Return a range of members in a sorted set, by score (). The Redis command @ZRANGEBYSCORE@ is split up into 'zrangebyscore', 'zrangebyscoreWithscores', 'zrangebyscoreLimit', 'zrangebyscoreWithscoresLimit'. Since Redis 1.0.5 zrangebyscoreWithscoresLimit, -- |Return a range of members in a sorted set, by score (). The Redis command @ZRANGEBYSCORE@ is split up into 'zrangebyscore', 'zrangebyscoreWithscores', 'zrangebyscoreLimit', 'zrangebyscoreWithscoresLimit'. Since Redis 1.0.5 -zrank, -- |Determine the index of a member in a sorted set (). Since Redis 2.0.0 -zrem, -- |Remove one or more members from a sorted set (). Since Redis 1.2.0 -zremrangebylex, -- |Remove all members in a sorted set between the given lexicographical range (). Since Redis 2.8.9 -zremrangebyrank, -- |Remove all members in a sorted set within the given indexes (). Since Redis 2.0.0 -zremrangebyscore, -- |Remove all members in a sorted set within the given scores (). Since Redis 1.2.0 +zrank, +zrankWithScore, +zrem, +zremrangebylex, +zremrangebyrank, +zremrangebyscore, zrevrange, -- |Return a range of members in a sorted set, by index, with scores ordered from high to low (). The Redis command @ZREVRANGE@ is split up into 'zrevrange', 'zrevrangeWithscores'. Since Redis 1.2.0 zrevrangeWithscores, -- |Return a range of members in a sorted set, by index, with scores ordered from high to low (). The Redis command @ZREVRANGE@ is split up into 'zrevrange', 'zrevrangeWithscores'. Since Redis 1.2.0 zrevrangebyscore, -- |Return a range of members in a sorted set, by score, with scores ordered from high to low (). The Redis command @ZREVRANGEBYSCORE@ is split up into 'zrevrangebyscore', 'zrevrangebyscoreWithscores', 'zrevrangebyscoreLimit', 'zrevrangebyscoreWithscoresLimit'. Since Redis 2.2.0 zrevrangebyscoreWithscores, -- |Return a range of members in a sorted set, by score, with scores ordered from high to low (). The Redis command @ZREVRANGEBYSCORE@ is split up into 'zrevrangebyscore', 'zrevrangebyscoreWithscores', 'zrevrangebyscoreLimit', 'zrevrangebyscoreWithscoresLimit'. Since Redis 2.2.0 zrevrangebyscoreLimit, -- |Return a range of members in a sorted set, by score, with scores ordered from high to low (). The Redis command @ZREVRANGEBYSCORE@ is split up into 'zrevrangebyscore', 'zrevrangebyscoreWithscores', 'zrevrangebyscoreLimit', 'zrevrangebyscoreWithscoresLimit'. Since Redis 2.2.0 zrevrangebyscoreWithscoresLimit, -- |Return a range of members in a sorted set, by score, with scores ordered from high to low (). The Redis command @ZREVRANGEBYSCORE@ is split up into 'zrevrangebyscore', 'zrevrangebyscoreWithscores', 'zrevrangebyscoreLimit', 'zrevrangebyscoreWithscoresLimit'. Since Redis 2.2.0 -zrevrank, -- |Determine the index of a member in a sorted set, with scores ordered from high to low (). Since Redis 2.0.0 +zrevrank, +zrevrankWithScore, zscan, -- |Incrementally iterate sorted sets elements and associated scores (). The Redis command @ZSCAN@ is split up into 'zscan', 'zscanOpts'. Since Redis 2.8.0 zscanOpts, -- |Incrementally iterate sorted sets elements and associated scores (). The Redis command @ZSCAN@ is split up into 'zscan', 'zscanOpts'. Since Redis 2.8.0 -zscore, -- |Get the score associated with the given member in a sorted set (). Since Redis 1.2.0 +zscore, zunionstore, -- |Add multiple sorted sets and store the resulting sorted set in a new key (). The Redis command @ZUNIONSTORE@ is split up into 'zunionstore', 'zunionstoreWeights'. Since Redis 2.0.0 zunionstoreWeights, -- |Add multiple sorted sets and store the resulting sorted set in a new key (). The Redis command @ZUNIONSTORE@ is split up into 'zunionstore', 'zunionstoreWeights'. Since Redis 2.0.0 -- ** Strings -append, -- |Append a value to a key (). Since Redis 2.0.0 +append, bitcount, -- |Count set bits in a string (). The Redis command @BITCOUNT@ is split up into 'bitcount', 'bitcountRange'. Since Redis 2.6.0 bitcountRange, -- |Count set bits in a string (). The Redis command @BITCOUNT@ is split up into 'bitcount', 'bitcountRange'. Since Redis 2.6.0 bitopAnd, -- |Perform bitwise operations between strings (). The Redis command @BITOP@ is split up into 'bitopAnd', 'bitopOr', 'bitopXor', 'bitopNot'. Since Redis 2.6.0 bitopOr, -- |Perform bitwise operations between strings (). The Redis command @BITOP@ is split up into 'bitopAnd', 'bitopOr', 'bitopXor', 'bitopNot'. Since Redis 2.6.0 bitopXor, -- |Perform bitwise operations between strings (). The Redis command @BITOP@ is split up into 'bitopAnd', 'bitopOr', 'bitopXor', 'bitopNot'. Since Redis 2.6.0 bitopNot, -- |Perform bitwise operations between strings (). The Redis command @BITOP@ is split up into 'bitopAnd', 'bitopOr', 'bitopXor', 'bitopNot'. Since Redis 2.6.0 -bitpos, -- |Find first bit set or clear in a string (). Since Redis 2.8.7 -decr, -- |Decrement the integer value of a key by one (). Since Redis 1.0.0 -decrby, -- |Decrement the integer value of a key by the given number (). Since Redis 1.0.0 -get, -- |Get the value of a key (). Since Redis 1.0.0 -getbit, -- |Returns the bit value at offset in the string value stored at key (). Since Redis 2.2.0 -getrange, -- |Get a substring of the string stored at a key (). Since Redis 2.4.0 -getset, -- |Set the string value of a key and return its old value (). Since Redis 1.0.0 -incr, -- |Increment the integer value of a key by one (). Since Redis 1.0.0 -incrby, -- |Increment the integer value of a key by the given amount (). Since Redis 1.0.0 -incrbyfloat, -- |Increment the float value of a key by the given amount (). Since Redis 2.6.0 -mget, -- |Get the values of all the given keys (). Since Redis 1.0.0 -mset, -- |Set multiple keys to multiple values (). Since Redis 1.0.1 -msetnx, -- |Set multiple keys to multiple values, only if none of the keys exist (). Since Redis 1.0.1 -psetex, -- |Set the value and expiration in milliseconds of a key (). Since Redis 2.6.0 +bitpos, +bitposOpts, +BitposOpts(..), +BitposType(..), +decr, +decrby, +get, +getbit, +getrange, +getset, +incr, +incrby, +incrbyfloat, +mget, +mset, +msetnx, +psetex, Condition(..), SetOpts(..), set, -- |Set the string value of a key (). The Redis command @SET@ is split up into 'set', 'setOpts', 'setGet', 'setGetOpts'. Since Redis 1.0.0 setOpts, -- |Set the string value of a key (). The Redis command @SET@ is split up into 'set', 'setOpts', 'setGet', 'setGetOpts'. Since Redis 1.0.0 setGet, -- |Set the string value of a key (). The Redis command @SET@ is split up into 'set', 'setOpts', 'setGet', 'setGetOpts'. Since Redis 1.0.0 setGetOpts, -- |Set the string value of a key (). The Redis command @SET@ is split up into 'set', 'setOpts', 'setGet', 'setGetOpts'. Since Redis 1.0.0 -setbit, -- |Sets or clears the bit at offset in the string value stored at key (). Since Redis 2.2.0 -setex, -- |Set the value and expiration of a key (). Since Redis 2.0.0 -setnx, -- |Set the value of a key, only if the key does not exist (). Since Redis 1.0.0 -setrange, -- |Overwrite part of a string at key starting at the specified offset (). Since Redis 2.2.0 -strlen, -- |Get the length of the value stored in a key (). Since Redis 2.2.0 +setbit, +setex, +setnx, +setrange, +strlen, -- ** Streams @@ -241,7 +258,7 @@ XReadResponse(..), StreamsRecord(..), TrimOpts(..), xadd, -xaddOpts, +xaddOpts, XAddOpts(..), defaultXAddOpts, TrimStrategy(..), @@ -305,14 +322,14 @@ xautoclaimJustIds, xautoclaimJustIdsOpts, XAutoclaimJustIdsResult, XInfoConsumersResponse(..), -xinfoConsumers, -- |Get info about consumers in a group. The Redis command @XINFO@ is split into 'xinfoConsumers', 'xinfoGroups', and 'xinfoStream'. Since Redis 5.0.0 +xinfoConsumers, XInfoGroupsResponse(..), -xinfoGroups, -- |Get info about groups consuming from a stream. The Redis command @XINFO@ is split into 'xinfoConsumers', 'xinfoGroups', and 'xinfoStream'. Since Redis 5.0.0 +xinfoGroups, XInfoStreamResponse(..), -xinfoStream, -- |Get info about a stream. The Redis command @XINFO@ is split into 'xinfoConsumers', 'xinfoGroups', and 'xinfoStream'. Since Redis 5.0.0 -xdel, -- |Delete messages from a stream. Since Redis 5.0.0 -xtrim, -- |Set the upper bound for number of messages in a stream. Since Redis 5.0.0 -inf, -- |Constructor for `inf` Redis argument values +xinfoStream, +xdel, +xtrim, +inf, ClusterNodesResponse(..), ClusterNodesResponseEntry(..), ClusterNodesResponseSlotSpec(..), @@ -368,160 +385,287 @@ command ) where import Prelude hiding (min,max) +import Data.Int import Data.ByteString (ByteString) -import Data.List.NonEmpty (NonEmpty) +import Data.List.NonEmpty (NonEmpty(..)) import qualified Data.List.NonEmpty as NE import Database.Redis.ManualCommands import Database.Redis.Types import Database.Redis.Core(sendRequest, RedisCtx) +-- | /O(1)/ +-- Get the time to live for a key (). +-- Since Redis 1.0.0 +-- +-- This command returns: +-- * -2 if the key does not exist +-- * -1 if the key exists but has no associated value +-- ttl :: (RedisCtx m f) - => ByteString -- ^ key + => ByteString -- ^ Key to check. -> m (f Integer) -ttl key = sendRequest (["TTL"] ++ [encode key] ) +ttl key = sendRequest ["TTL", encode key] +-- | /O(1)/ +-- Sets the value of a key, only if the key does not exist (). +-- +-- Returns a result if a value was set. +-- +-- Since Redis 1.0.0 setnx :: (RedisCtx m f) - => ByteString -- ^ key - -> ByteString -- ^ value + => ByteString -- ^ Key to set. + -> ByteString -- ^ Value to set. -> m (f Bool) -setnx key value = sendRequest (["SETNX"] ++ [encode key] ++ [encode value] ) +setnx key value = sendRequest ["SETNX", encode key, encode value] +-- | /O(1)/ +-- Get the time to live for a key in milliseconds (). +-- Since Redis 2.6.0 +-- +-- This command returns @-2@ if the key does not exist. +-- This command returns @-1@ if the key exists but has no associated value pttl :: (RedisCtx m f) - => ByteString -- ^ key + => ByteString -- ^ Key. -> m (f Integer) -pttl key = sendRequest (["PTTL"] ++ [encode key] ) +pttl key = sendRequest ["PTTL", encode key] +-- | /O(1)/ +-- Get total number of Redis commands (). +-- Since Redis 2.8.13 commandCount :: (RedisCtx m f) => m (f Integer) -commandCount = sendRequest (["COMMAND","COUNT"] ) +commandCount = sendRequest ["COMMAND","COUNT"] +-- | Set the current connection name (). +-- Since Redis 2.6.9 clientSetname :: (RedisCtx m f) - => ByteString -- ^ connectionName + => ByteString -- ^ Connection Name. -> m (f Status) -clientSetname connectionName = sendRequest (["CLIENT","SETNAME"] ++ [encode connectionName] ) +clientSetname connectionName = sendRequest ["CLIENT","SETNAME",encode connectionName] +-- | Determine the index of a member in a sorted set (). +-- +-- Since Redis 2.0.0 zrank :: (RedisCtx m f) - => ByteString -- ^ key - -> ByteString -- ^ member + => ByteString -- ^ Key.of the set. + -> ByteString -- ^ Member -> m (f (Maybe Integer)) -zrank key member = sendRequest (["ZRANK"] ++ [encode key] ++ [encode member] ) +zrank key member = sendRequest ["ZRANK", encode key, encode member] +-- | +-- Since Redis 7.2.0: fails on earlier versions +zrankWithScore + :: (RedisCtx m f) + => ByteString -- ^ Key of the set. + -> ByteString -- ^ Member. + -> m (f (Maybe (Integer,Double))) +zrankWithScore key member = sendRequest ["ZRANK", encode key, encode member, "WITHSCORE"] + +-- | /O(log(N)+M)/ with @N@ number of elements in the set, @M@ number of elements to be removed. +-- +-- Remove all members in a sorted set within the given scores (). +-- +-- Returns a number of elements that were removed. +-- +-- Since Redis 1.2.0 zremrangebyscore :: (RedisCtx m f) => ByteString -- ^ key -> Double -- ^ min -> Double -- ^ max -> m (f Integer) -zremrangebyscore key min max = sendRequest (["ZREMRANGEBYSCORE"] ++ [encode key] ++ [encode min] ++ [encode max] ) +zremrangebyscore key min max = + sendRequest ["ZREMRANGEBYSCORE",encode key,encode min,encode max] +-- | /O(N)/ where @N@ is size of the hash. +-- Get all the fields in a hash (). +-- Since Redis 2.0.0 hkeys :: (RedisCtx m f) => ByteString -- ^ key -> m (f [ByteString]) -hkeys key = sendRequest (["HKEYS"] ++ [encode key] ) +hkeys key = sendRequest ["HKEYS",encode key] +-- |Make the server a slave of another instance, or promote it as master (). +-- Deprecated in Redis, can be replaced by replicaif since redis 5.0 +-- Since Redis 1.0.0 slaveof :: (RedisCtx m f) => ByteString -- ^ host -> ByteString -- ^ port -> m (f Status) -slaveof host port = sendRequest (["SLAVEOF"] ++ [encode host] ++ [encode port] ) +slaveof host port = sendRequest ["SLAVEOF",encode host,encode port] +-- | /O(1)/ for each element added. +-- Append a value to a list, only if the list exists (). +-- Since Redis 2.2.0 rpushx :: (RedisCtx m f) => ByteString -- ^ key - -> ByteString -- ^ value + -> NonEmpty ByteString -- ^ value -> m (f Integer) -rpushx key value = sendRequest (["RPUSHX"] ++ [encode key] ++ [encode value] ) +rpushx key (value:|values) = sendRequest ("RPUSHX":encode key:value:values) +-- |Get debugging information about a key (). Since Redis 1.0.0 debugObject :: (RedisCtx m f) => ByteString -- ^ key -> m (f ByteString) -debugObject key = sendRequest (["DEBUG","OBJECT"] ++ [encode key] ) +debugObject key = sendRequest ["DEBUG","OBJECT",encode key] +-- |Asynchronously save the dataset to disk (). +-- +-- Since Redis 1.0.0 bgsave :: (RedisCtx m f) => m (f Status) -bgsave = sendRequest (["BGSAVE"] ) +bgsave = sendRequest ["BGSAVE"] + +-- |Asynchronously save the dataset to disk (). +-- +-- Immediately returns OK when an AOF rewrite is in progress and schedule the background save +-- to run at the next opportunity. +-- +-- A client may bee able to check if the operation succeeded using the 'lastsave' command +-- +-- Since Redis 3.2.2 +bgsaveSchedule + :: (RedisCtx m f) + => m (f Status) +bgsaveSchedule = sendRequest ["BGSAVE", "SCHEDULE"] + +-- | /O(1)/ Get the number of fields in a hash (). +-- +-- Since Redis 2.0.0 hlen :: (RedisCtx m f) => ByteString -- ^ key -> m (f Integer) -hlen key = sendRequest (["HLEN"] ++ [encode key] ) +hlen key = sendRequest ["HLEN", key] +-- |Remove the last element in a list, prepend it to another list and return that +-- element f it existed (). +-- Since Redis 1.2.0 rpoplpush :: (RedisCtx m f) => ByteString -- ^ source -> ByteString -- ^ destination -> m (f (Maybe ByteString)) -rpoplpush source destination = sendRequest (["RPOPLPUSH"] ++ [encode source] ++ [encode destination] ) +rpoplpush source destination = sendRequest ["RPOPLPUSH",encode source,encode destination] +-- | /O(N)/ +-- Remove and get the last element in a list, or block until one is available (). +-- +-- Since Redis 2.0.0 brpop :: (RedisCtx m f) - => [ByteString] -- ^ key + => NonEmpty ByteString -- ^ key -> Integer -- ^ timeout -> m (f (Maybe (ByteString,ByteString))) -brpop key timeout = sendRequest (["BRPOP"] ++ map encode key ++ [encode timeout] ) +brpop (key:|rest) timeout = sendRequest (("BRPOP":key:rest) ++ [encode timeout]) + +-- | /O(N)/ +-- Remove and get the last element in a list, or block until one is available (). +-- +-- Since Redis 2.0.0 +brpopFloat + :: (RedisCtx m f) + => [ByteString] -- ^ key + -> Double -- ^ timeout + -> m (f (Maybe (ByteString,ByteString))) +brpopFloat key timeout = sendRequest (["BRPOP"] ++ map encode key ++ [encode timeout]) +-- |Asynchronously rewrite the append-only file (). Since Redis 1.0.0 bgrewriteaof :: (RedisCtx m f) => m (f Status) -bgrewriteaof = sendRequest (["BGREWRITEAOF"] ) +bgrewriteaof = sendRequest ["BGREWRITEAOF"] +-- | /O(log(N))/ +-- +-- Increment the score of a member in a sorted set (). +-- +-- Returns new score of the element. +-- +-- Since Redis 1.2.0 zincrby :: (RedisCtx m f) => ByteString -- ^ key -> Integer -- ^ increment -> ByteString -- ^ member -> m (f Double) -zincrby key increment member = sendRequest (["ZINCRBY"] ++ [encode key] ++ [encode increment] ++ [encode member] ) +zincrby key increment member = sendRequest ["ZINCRBY",encode key,encode increment,encode member] +-- | Get all the fields and values in a hash (). +-- +-- Since Redis 2.0.0. hgetall :: (RedisCtx m f) => ByteString -- ^ key -> m (f [(ByteString,ByteString)]) -hgetall key = sendRequest (["HGETALL"] ++ [encode key] ) +hgetall key = sendRequest ["HGETALL", encode key] + +-- | Set multiple hash fields to multiple values (). +-- +-- Deprecated by Redis, consider using 'hset' with multiple field-value pairs. +-- +-- Since Redis 2.0.0 hmset :: (RedisCtx m f) => ByteString -- ^ key - -> [(ByteString,ByteString)] -- ^ fieldValue + -> NonEmpty (ByteString,ByteString) -- ^ fieldValue -> m (f Status) -hmset key fieldValue = sendRequest (["HMSET"] ++ [encode key] ++ concatMap (\(x,y) -> [encode x,encode y])fieldValue ) +hmset key ((field,value):|fieldValues) = + sendRequest ("HMSET":key:field:value: concatMap (\(x,y) -> [x,y]) fieldValues) +-- |Intersect multiple sets (). +-- Since Redis 1.0.0 sinter :: (RedisCtx m f) - => [ByteString] -- ^ key + => NonEmpty ByteString -- ^ Keys. -> m (f [ByteString]) -sinter key = sendRequest (["SINTER"] ++ map encode key ) +sinter (key:|keys_) = sendRequest ("SINTER":key:keys_) +-- | /O(1)/ +-- Adds all the elements arguments to the HyperLogLog data structure stored at the variable name specified as first argument (). +-- Since Redis 2.8.9 pfadd :: (RedisCtx m f) - => ByteString -- ^ key - -> [ByteString] -- ^ value + => ByteString -- ^ Key. + -> NonEmpty ByteString -- ^ Value. -> m (f Integer) -pfadd key value = sendRequest (["PFADD"] ++ [encode key] ++ map encode value ) +pfadd key (value:|values) = sendRequest ("PFADD":key:value:values) +-- | /O(log(N)+M/ with @N@ being the number of elements in the sorted set and @M@ the number of elemnts removed by the operation. +-- +-- Remove all members in a sorted set within the given indexes (). +-- +-- Returns a number of elements that were removed. +-- +-- Since Redis 2.0.0 zremrangebyrank :: (RedisCtx m f) => ByteString -- ^ key -> Integer -- ^ start -> Integer -- ^ stop -> m (f Integer) -zremrangebyrank key start stop = sendRequest (["ZREMRANGEBYRANK"] ++ [encode key] ++ [encode start] ++ [encode stop] ) +zremrangebyrank key start stop = + sendRequest ["ZREMRANGEBYRANK",encode key,encode start,encode stop] +-- |Remove all keys from the current database (). +-- Since Redis 1.0.0 flushdb :: (RedisCtx m f) => m (f Status) -flushdb = sendRequest (["FLUSHDB"] ) +flushdb = sendRequest ["FLUSHDB"] -- | /O(1)/ for each element added. -- Add one or more members to a set (). @@ -531,176 +675,242 @@ sadd => ByteString -- ^ Key where set is stored. -> NonEmpty ByteString -- ^ Member to add to the set. -> m (f Integer) -sadd key member = sendRequest (["SADD"] ++ [encode key] ++ NE.toList (fmap encode member)) +sadd key member = sendRequest ("SADD":encode key:NE.toList (fmap encode member)) +-- |Get an element from a list by its index (). +-- Since Redis 1.0.0 lindex :: (RedisCtx m f) - => ByteString -- ^ key - -> Integer -- ^ index + => ByteString -- ^ Key. + -> Integer -- ^ Index -> m (f (Maybe ByteString)) -lindex key index = sendRequest (["LINDEX"] ++ [encode key] ++ [encode index] ) +lindex key index = sendRequest ["LINDEX",encode key,encode index] +-- | Prepend one or multiple values to a list (). +-- Since Redis 1.0.0 lpush :: (RedisCtx m f) - => ByteString -- ^ key - -> [ByteString] -- ^ value + => ByteString -- ^ Key + -> NonEmpty ByteString -- ^ Value -> m (f Integer) -lpush key value = sendRequest (["LPUSH"] ++ [encode key] ++ map encode value ) +lpush key (value:|values) = sendRequest ("LPUSH":key:value:values) +-- |Get the length of the value of a hash field (). +-- Since Redis 3.2.0 hstrlen :: (RedisCtx m f) => ByteString -- ^ key -> ByteString -- ^ field -> m (f Integer) -hstrlen key field = sendRequest (["HSTRLEN"] ++ [encode key] ++ [encode field] ) +hstrlen key field = sendRequest ["HSTRLEN", key, field] +-- | +-- Move a member from one set to another (). +-- Since Redis 1.0.0 smove :: (RedisCtx m f) => ByteString -- ^ source -> ByteString -- ^ destination -> ByteString -- ^ member -> m (f Bool) -smove source destination member = sendRequest (["SMOVE"] ++ [encode source] ++ [encode destination] ++ [encode member] ) +smove source destination member = + sendRequest ["SMOVE", source, destination, member] +-- |Get the score associated with the given member in a sorted set (). +-- Since Redis 1.2.0 zscore :: (RedisCtx m f) - => ByteString -- ^ key - -> ByteString -- ^ member + => ByteString -- ^ Key. + -> ByteString -- ^ Member. -> m (f (Maybe Double)) -zscore key member = sendRequest (["ZSCORE"] ++ [encode key] ++ [encode member] ) +zscore key member = sendRequest ["ZSCORE",encode key,encode member] +-- |Reset the stats returned by INFO (). +-- Since Redis 2.0.0 configResetstat :: (RedisCtx m f) => m (f Status) -configResetstat = sendRequest (["CONFIG","RESETSTAT"] ) +configResetstat = sendRequest ["CONFIG","RESETSTAT"] +-- | +-- Return the approximated cardinality of the set(s) observed by the HyperLogLog at key(s) (). +-- Since Redis 2.8.9 pfcount :: (RedisCtx m f) - => [ByteString] -- ^ key + => NonEmpty ByteString -- ^ key -> m (f Integer) -pfcount key = sendRequest (["PFCOUNT"] ++ map encode key ) +pfcount (key:|keys_) = sendRequest ("PFCOUNT": key: keys_) +-- | Delete one or more hash fields (). +-- Since Redis 2.0.0 hdel :: (RedisCtx m f) => ByteString -- ^ key - -> [ByteString] -- ^ field + -> NonEmpty ByteString -- ^ field -> m (f Integer) -hdel key field = sendRequest (["HDEL"] ++ [encode key] ++ map encode field ) +hdel key (field:|fields) = sendRequest ("HDEL":key:field:fields) +-- |Increment the float value of a key by the given amount (). +-- Since Redis 2.6.0 incrbyfloat :: (RedisCtx m f) - => ByteString -- ^ key - -> Double -- ^ increment + => ByteString -- ^ Key. + -> Double -- ^ Increment. -> m (f Double) -incrbyfloat key increment = sendRequest (["INCRBYFLOAT"] ++ [encode key] ++ [encode increment] ) +incrbyfloat key increment = sendRequest ["INCRBYFLOAT", key, encode increment] +-- |Sets or clears the bit at offset in the string value stored at key (). +-- Since Redis 2.2.0 setbit :: (RedisCtx m f) => ByteString -- ^ key -> Integer -- ^ offset -> ByteString -- ^ value -> m (f Integer) -setbit key offset value = sendRequest (["SETBIT"] ++ [encode key] ++ [encode offset] ++ [encode value] ) +setbit key offset value = sendRequest ["SETBIT", key, encode offset, value] +-- | Remove all keys from all databases (). Since Redis 1.0.0 flushall :: (RedisCtx m f) => m (f Status) -flushall = sendRequest (["FLUSHALL"] ) +flushall = sendRequest ["FLUSHALL"] +-- |Increment the integer value of a key by the given amount (). +-- Since Redis 1.0.0 incrby :: (RedisCtx m f) => ByteString -- ^ key -> Integer -- ^ increment -> m (f Integer) -incrby key increment = sendRequest (["INCRBY"] ++ [encode key] ++ [encode increment] ) +incrby key increment = sendRequest ["INCRBY", key, encode increment] +-- | Return the current server time (). +-- Since Redis 2.6.0 time :: (RedisCtx m f) => m (f (Integer,Integer)) -time = sendRequest (["TIME"] ) +time = sendRequest ["TIME"] +-- |Get all the members in a set (). Since Redis 1.0.0 smembers :: (RedisCtx m f) => ByteString -- ^ key -> m (f [ByteString]) -smembers key = sendRequest (["SMEMBERS"] ++ [encode key] ) +smembers key = sendRequest ["SMEMBERS", key] +-- |Count the number of members in a sorted set between a given lexicographical range (). +-- Since Redis 2.8.9 zlexcount :: (RedisCtx m f) => ByteString -- ^ key -> ByteString -- ^ min -> ByteString -- ^ max -> m (f Integer) -zlexcount key min max = sendRequest (["ZLEXCOUNT"] ++ [encode key] ++ [encode min] ++ [encode max] ) +zlexcount key min max = sendRequest ["ZLEXCOUNT", key, min, max] +-- |Add multiple sets (). +-- Since Redis 1.0.0 sunion :: (RedisCtx m f) - => [ByteString] -- ^ key + => NonEmpty ByteString -- ^ key -> m (f [ByteString]) -sunion key = sendRequest (["SUNION"] ++ map encode key ) +sunion (key:|keys_) = sendRequest ("SUNION":key:keys_) +-- |Intersect multiple sets and store the resulting set in a key (). +-- Since Redis 1.0.0 sinterstore :: (RedisCtx m f) => ByteString -- ^ destination - -> [ByteString] -- ^ key + -> NonEmpty ByteString -- ^ key -> m (f Integer) -sinterstore destination key = sendRequest (["SINTERSTORE"] ++ [encode destination] ++ map encode key ) +sinterstore destination (key:|keys_) = + sendRequest ("SINTERSTORE":destination:key:keys_) +-- | Get all the values in a hash (). +-- Since Redis 2.0.0 hvals :: (RedisCtx m f) => ByteString -- ^ key -> m (f [ByteString]) -hvals key = sendRequest (["HVALS"] ++ [encode key] ) +hvals key = sendRequest ["HVALS", key] +-- |Set a configuration parameter to the given value (). +-- Since Redis 2.0.0 configSet :: (RedisCtx m f) => ByteString -- ^ parameter -> ByteString -- ^ value -> m (f Status) -configSet parameter value = sendRequest (["CONFIG","SET"] ++ [encode parameter] ++ [encode value] ) +configSet parameter value = sendRequest ["CONFIG","SET", parameter, value] +-- |Remove all the scripts from the script cache (). +-- Since Redis 2.6.0 scriptFlush :: (RedisCtx m f) => m (f Status) -scriptFlush = sendRequest (["SCRIPT","FLUSH"] ) +scriptFlush = sendRequest ["SCRIPT","FLUSH"] +-- |Return the number of keys in the selected database (). +-- Since Redis 1.0.0 dbsize :: (RedisCtx m f) => m (f Integer) -dbsize = sendRequest (["DBSIZE"] ) +dbsize = sendRequest ["DBSIZE"] +-- |Wait for the synchronous replication of all the write commands sent in the context of the current connection (). +-- Since Redis 3.0.0 wait :: (RedisCtx m f) => Integer -- ^ numslaves -> Integer -- ^ timeout -> m (f Integer) -wait numslaves timeout = sendRequest (["WAIT"] ++ [encode numslaves] ++ [encode timeout] ) +wait numslaves timeout = sendRequest ["WAIT", encode numslaves, encode timeout] +-- |Remove and get the first element in a list (). Since Redis 1.0.0 lpop :: (RedisCtx m f) => ByteString -- ^ key -> m (f (Maybe ByteString)) -lpop key = sendRequest (["LPOP"] ++ [encode key] ) +lpop key = sendRequest ["LPOP", encode key] +-- | +-- Remove and get the first element in a list (). +-- The reply will consist of up to count elements, depending on the list's length. +-- Since Redis 1.0.0 +lpopCount + :: (RedisCtx m f) + => ByteString -- ^ key + -> Integer + -> m (f [ByteString]) +lpopCount key count = sendRequest ["LPOP", key, encode count] + +-- |Stop processing commands from clients for some time (). +-- Since Redis 2.9.50 clientPause :: (RedisCtx m f) => Integer -- ^ timeout -> m (f Status) -clientPause timeout = sendRequest (["CLIENT","PAUSE"] ++ [encode timeout] ) +clientPause timeout = sendRequest ["CLIENT","PAUSE", encode timeout] +-- |Set a key's time to live in seconds (). Since Redis 1.0.0 expire :: (RedisCtx m f) => ByteString -- ^ key -> Integer -- ^ seconds -> m (f Bool) -expire key seconds = sendRequest (["EXPIRE"] ++ [encode key] ++ [encode seconds] ) +expire key seconds = sendRequest ["EXPIRE", key, encode seconds] +-- |Get the values of all the given keys (). +-- Since Redis 1.0.0 mget :: (RedisCtx m f) - => [ByteString] -- ^ key + => NonEmpty ByteString -- ^ key -> m (f [Maybe ByteString]) -mget key = sendRequest (["MGET"] ++ map encode key ) +mget (key:|keys_) = sendRequest ("MGET":key:keys_) +-- | +-- Find first bit set or clear in a string (). +-- Since Redis 2.8.7 bitpos :: (RedisCtx m f) => ByteString -- ^ key @@ -708,228 +918,290 @@ bitpos -> Integer -- ^ start -> Integer -- ^ end -> m (f Integer) -bitpos key bit start end = sendRequest (["BITPOS"] ++ [encode key] ++ [encode bit] ++ [encode start] ++ [encode end] ) +bitpos key bit start end = sendRequest ["BITPOS", key, encode bit, encode start, encode end] lastsave :: (RedisCtx m f) => m (f Integer) lastsave = sendRequest (["LASTSAVE"] ) +-- | Set a key's time to live in milliseconds (). +-- Since Redis 2.6.0 pexpire :: (RedisCtx m f) => ByteString -- ^ key -> Integer -- ^ milliseconds -> m (f Bool) -pexpire key milliseconds = sendRequest (["PEXPIRE"] ++ [encode key] ++ [encode milliseconds] ) +pexpire key milliseconds = sendRequest ["PEXPIRE", key, encode milliseconds] +-- |Get the list of client connections (). Since Redis 2.4.0 clientList :: (RedisCtx m f) => m (f [ByteString]) clientList = sendRequest (["CLIENT","LIST"] ) +-- |Rename a key, only if the new key does not exist (). Since Redis 1.0.0 renamenx :: (RedisCtx m f) => ByteString -- ^ key -> ByteString -- ^ newkey -> m (f Bool) -renamenx key newkey = sendRequest (["RENAMENX"] ++ [encode key] ++ [encode newkey] ) +renamenx key newkey = sendRequest ["RENAMENX", key, newkey] +-- |Merge N different HyperLogLogs into a single one (). Since Redis 2.8.9 pfmerge :: (RedisCtx m f) => ByteString -- ^ destkey -> [ByteString] -- ^ sourcekey -> m (f ByteString) -pfmerge destkey sourcekey = sendRequest (["PFMERGE"] ++ [encode destkey] ++ map encode sourcekey ) +pfmerge destkey sourcekey = sendRequest ("PFMERGE": destkey: sourcekey) +-- | Remove elements from a list (). Since Redis 1.0.0 lrem :: (RedisCtx m f) => ByteString -- ^ key -> Integer -- ^ count -> ByteString -- ^ value -> m (f Integer) -lrem key count value = sendRequest (["LREM"] ++ [encode key] ++ [encode count] ++ [encode value] ) +lrem key count value = sendRequest ["LREM", key, encode count, value] +-- |Subtract multiple sets (). Since Redis 1.0.0 sdiff :: (RedisCtx m f) - => [ByteString] -- ^ key + => NonEmpty ByteString -- ^ key -> m (f [ByteString]) -sdiff key = sendRequest (["SDIFF"] ++ map encode key ) +sdiff (key_:|keys_) = sendRequest ("SDIFF":key_:keys_) +-- |Get the value of a key (). Since Redis 1.0.0 get :: (RedisCtx m f) => ByteString -- ^ key -> m (f (Maybe ByteString)) get key = sendRequest (["GET"] ++ [encode key] ) +-- |Get a substring of the string stored at a key (). +-- Since Redis 2.4.0 getrange :: (RedisCtx m f) => ByteString -- ^ key -> Integer -- ^ start -> Integer -- ^ end -> m (f ByteString) -getrange key start end = sendRequest (["GETRANGE"] ++ [encode key] ++ [encode start] ++ [encode end] ) +getrange key start end = sendRequest ["GETRANGE", key, encode start, encode end] +-- |Subtract multiple sets and store the resulting set in a key (). Since Redis 1.0.0 sdiffstore :: (RedisCtx m f) => ByteString -- ^ destination - -> [ByteString] -- ^ key + -> NonEmpty ByteString -- ^ key -> m (f Integer) -sdiffstore destination key = sendRequest (["SDIFFSTORE"] ++ [encode destination] ++ map encode key ) +sdiffstore destination (key_:|keys_) = sendRequest ("SDIFFSTORE": destination: key_: keys_) +-- |Count the members in a sorted set with scores within the given values (). Since Redis 2.0.0 zcount :: (RedisCtx m f) => ByteString -- ^ key -> Double -- ^ min -> Double -- ^ max -> m (f Integer) -zcount key min max = sendRequest (["ZCOUNT"] ++ [encode key] ++ [encode min] ++ [encode max] ) +zcount key min max = sendRequest ["ZCOUNT", key, encode min, encode max] +-- |Load the specified Lua script into the script cache (). Since Redis 2.6.0 scriptLoad :: (RedisCtx m f) => ByteString -- ^ script -> m (f ByteString) -scriptLoad script = sendRequest (["SCRIPT","LOAD"] ++ [encode script] ) +scriptLoad script = sendRequest ["SCRIPT","LOAD", encode script] +-- |Set the string value of a key and return its old value (). Since Redis 1.0.0 getset :: (RedisCtx m f) => ByteString -- ^ key -> ByteString -- ^ value -> m (f (Maybe ByteString)) -getset key value = sendRequest (["GETSET"] ++ [encode key] ++ [encode value] ) +getset key value = sendRequest ["GETSET", key, value] +-- |Return a serialized version of the value stored at the specified key (). Since Redis 2.6.0 dump :: (RedisCtx m f) => ByteString -- ^ key -> m (f ByteString) -dump key = sendRequest (["DUMP"] ++ [encode key] ) +dump key = sendRequest ["DUMP", key] +-- |Find all keys matching the given pattern (). Since Redis 1.0.0 keys :: (RedisCtx m f) => ByteString -- ^ pattern -> m (f [ByteString]) -keys pattern = sendRequest (["KEYS"] ++ [encode pattern] ) +keys pattern = sendRequest ["KEYS", pattern] +-- |Get the value of a configuration parameter (). Since Redis 2.0.0 configGet :: (RedisCtx m f) - => ByteString -- ^ parameter + => NonEmpty ByteString -- ^ parameter -> m (f [(ByteString,ByteString)]) -configGet parameter = sendRequest (["CONFIG","GET"] ++ [encode parameter] ) +configGet (parameter:|parameters) = sendRequest ("CONFIG":"GET":parameter:parameters) +-- |Append one or multiple values to a list (). Since Redis 1.0.0 rpush :: (RedisCtx m f) => ByteString -- ^ key - -> [ByteString] -- ^ value + -> NonEmpty ByteString -- ^ value -> m (f Integer) -rpush key value = sendRequest (["RPUSH"] ++ [encode key] ++ map encode value ) +rpush key (value:|values) = sendRequest ("RPUSH": encode key:value:values) +-- |Return a random key from the keyspace (). Since Redis 1.0.0 randomkey :: (RedisCtx m f) => m (f (Maybe ByteString)) -randomkey = sendRequest (["RANDOMKEY"] ) +randomkey = sendRequest ["RANDOMKEY"] +-- |Set the value of a hash field, only if the field does not exist (). Since Redis 2.0.0 hsetnx :: (RedisCtx m f) => ByteString -- ^ key -> ByteString -- ^ field -> ByteString -- ^ value -> m (f Bool) -hsetnx key field value = sendRequest (["HSETNX"] ++ [encode key] ++ [encode field] ++ [encode value] ) +hsetnx key field value = sendRequest ["HSETNX", key, field, value] +-- |Set multiple keys to multiple values (). Since Redis 1.0.1 mset :: (RedisCtx m f) - => [(ByteString,ByteString)] -- ^ keyValue + => NonEmpty (ByteString,ByteString) -- ^ keyValue -> m (f Status) -mset keyValue = sendRequest (["MSET"] ++ concatMap (\(x,y) -> [encode x,encode y])keyValue ) +mset ((key_,value):|keyValue) = + sendRequest ("MSET":key_:value: concatMap (\(x,y) -> [encode x,encode y]) keyValue) +-- |Set the value and expiration of a key (). +-- Regarded as deprected since 2.6 as it can be replaced by SET with the EX argument when +-- migrating or writing new code. +-- Since Redis 2.0.0 setex :: (RedisCtx m f) => ByteString -- ^ key -> Integer -- ^ seconds -> ByteString -- ^ value -> m (f Status) -setex key seconds value = sendRequest (["SETEX"] ++ [encode key] ++ [encode seconds] ++ [encode value] ) +setex key seconds value = sendRequest ["SETEX", key, encode seconds, value] +-- |Set the value and expiration in milliseconds of a key (). +-- Condidered deprecated since it can be replaced by SET with the PX argument when migrating or writing new code +-- Since Redis 2.6.0 psetex :: (RedisCtx m f) => ByteString -- ^ key -> Integer -- ^ milliseconds -> ByteString -- ^ value -> m (f Status) -psetex key milliseconds value = sendRequest (["PSETEX"] ++ [encode key] ++ [encode milliseconds] ++ [encode value] ) +psetex key milliseconds value = sendRequest ["PSETEX", key, encode milliseconds, value] +-- |Get the number of members in a set (). Since Redis 1.0.0 scard :: (RedisCtx m f) => ByteString -- ^ key -> m (f Integer) -scard key = sendRequest (["SCARD"] ++ [encode key] ) +scard key = sendRequest ["SCARD", key] +-- |Check existence of scripts in the script cache (). Since Redis 2.6.0 scriptExists :: (RedisCtx m f) - => [ByteString] -- ^ script + => NonEmpty ByteString -- ^ script -> m (f [Bool]) -scriptExists script = sendRequest (["SCRIPT","EXISTS"] ++ map encode script ) +scriptExists (script:|scripts) = sendRequest ("SCRIPT":"EXISTS":script:scripts) +-- |Add multiple sets and store the resulting set in a key (). Since Redis 1.0.0 sunionstore :: (RedisCtx m f) => ByteString -- ^ destination - -> [ByteString] -- ^ key + -> NonEmpty ByteString -- ^ key -> m (f Integer) -sunionstore destination key = sendRequest (["SUNIONSTORE"] ++ [encode destination] ++ map encode key ) +sunionstore destination (key_:|keys_) = + sendRequest ("SUNIONSTORE":destination:key_:keys_) +-- |Remove the expiration from a key (). Since Redis 2.2.0 persist :: (RedisCtx m f) => ByteString -- ^ key -> m (f Bool) -persist key = sendRequest (["PERSIST"] ++ [encode key] ) +persist key = sendRequest ["PERSIST", key] +-- |Get the length of the value stored in a key (). Since Redis 2.2.0 strlen :: (RedisCtx m f) => ByteString -- ^ key -> m (f Integer) -strlen key = sendRequest (["STRLEN"] ++ [encode key] ) +strlen key = sendRequest ["STRLEN", encode key] +-- |Prepend a value to a list, only if the list exists (). Since Redis 2.2.0 lpushx :: (RedisCtx m f) => ByteString -- ^ key - -> ByteString -- ^ value + -> NonEmpty ByteString -- ^ value -> m (f Integer) -lpushx key value = sendRequest (["LPUSHX"] ++ [encode key] ++ [encode value] ) +lpushx key (value:|values) = sendRequest ("LPUSHX":key:value:values) +-- |Set the string value of a hash field (). +-- +-- This command oveerides keys if they exist in the hash. +-- +-- Since Redis 2.0.0 hset :: (RedisCtx m f) => ByteString -- ^ key - -> ByteString -- ^ field - -> ByteString -- ^ value + -> NonEmpty (ByteString, ByteString) -- ^ Values. -> m (f Integer) -hset key field value = sendRequest (["HSET"] ++ [encode key] ++ [encode field] ++ [encode value] ) +hset key ((field,value):|fieldValues) = + sendRequest ("HSET":encode key:encode field:encode value:concatMap (\(f,v) ->[f,v]) fieldValues) +-- |Pop a value from a list, push it to another list and return it; or block until one is available (). +-- +-- Since Redis 6.0 this command considered deprecated: it can be replaced by BLMOVE with the RIGHT and LEFT arguments when migrating or writing new code. +-- +-- Since Redis 2.2.0 brpoplpush :: (RedisCtx m f) => ByteString -- ^ source -> ByteString -- ^ destination -> Integer -- ^ timeout -> m (f (Maybe ByteString)) -brpoplpush source destination timeout = sendRequest (["BRPOPLPUSH"] ++ [encode source] ++ [encode destination] ++ [encode timeout] ) +brpoplpush source destination timeout = + sendRequest ["BRPOPLPUSH", source, destination, encode timeout] +-- |Determine the index of a member in a sorted set, with scores ordered from high to low (). +-- Since Redis 2.0.0 zrevrank :: (RedisCtx m f) => ByteString -- ^ key -> ByteString -- ^ member -> m (f (Maybe Integer)) -zrevrank key member = sendRequest (["ZREVRANK"] ++ [encode key] ++ [encode member] ) +zrevrank key member = sendRequest ["ZREVRANK", key, member] +zrevrankWithScore + :: (RedisCtx m f) + => ByteString -- ^ key + -> ByteString -- ^ member + -> m (f (Maybe (Integer, Double))) +zrevrankWithScore key member = sendRequest ["ZREVRANK", key, member] + +-- |Kill the script currently in execution (). Since Redis 2.6.0 scriptKill :: (RedisCtx m f) => m (f Status) -scriptKill = sendRequest (["SCRIPT","KILL"] ) +scriptKill = sendRequest ["SCRIPT","KILL"] +-- |Overwrite part of a string at key starting at the specified offset (). +-- +-- Returns the lenght of the string after it was modified. +-- +-- Since Redis 2.2.0 setrange :: (RedisCtx m f) => ByteString -- ^ key -> Integer -- ^ offset -> ByteString -- ^ value -> m (f Integer) -setrange key offset value = sendRequest (["SETRANGE"] ++ [encode key] ++ [encode offset] ++ [encode value] ) +setrange key offset value = sendRequest ["SETRANGE", key, encode offset, value] -- | Delete a key (). -- Returns a number of keys that were removed. @@ -938,24 +1210,35 @@ del :: (RedisCtx m f) => NonEmpty ByteString -- ^ List of keys to delete. -> m (f Integer) -del key = sendRequest (["DEL"] ++ (NE.toList (fmap encode key))) +del (key:|rest) = sendRequest ("DEL":key:rest) +-- |Increment the float value of a hash field by the given amount (). +-- Since Redis 2.6.0 hincrbyfloat :: (RedisCtx m f) => ByteString -- ^ key -> ByteString -- ^ field -> Double -- ^ increment -> m (f Double) -hincrbyfloat key field increment = sendRequest (["HINCRBYFLOAT"] ++ [encode key] ++ [encode field] ++ [encode increment] ) +hincrbyfloat key field increment = sendRequest ["HINCRBYFLOAT", key, field, encode increment] +-- | Increment the integer value of a hash field by the given number (). Since Redis 2.0.0 hincrby :: (RedisCtx m f) => ByteString -- ^ key -> ByteString -- ^ field - -> Integer -- ^ increment - -> m (f Integer) -hincrby key field increment = sendRequest (["HINCRBY"] ++ [encode key] ++ [encode field] ++ [encode increment] ) + -> Int64 -- ^ increment + -> m (f Int64) +hincrby key field increment = sendRequest ["HINCRBY", encode key, encode field, encode increment] +-- | O(log(N)+M) with @N@ being thee number of elements in thee sorted set and @M@ the number +-- of elements removed by the operation. +-- +-- Remove all members in a sorted set between the given lexicographical range (). +-- +-- Returns number of elements that were removed. +-- +-- Since Redis 2.8.9 zremrangebylex :: (RedisCtx m f) => ByteString -- ^ key @@ -964,180 +1247,251 @@ zremrangebylex -> m (f Integer) zremrangebylex key min max = sendRequest (["ZREMRANGEBYLEX"] ++ [encode key] ++ [encode min] ++ [encode max] ) +-- |Remove and get the last element in a list (). +-- Since Redis 1.0.0 rpop :: (RedisCtx m f) => ByteString -- ^ key -> m (f (Maybe ByteString)) -rpop key = sendRequest (["RPOP"] ++ [encode key] ) +rpop key = sendRequest ["RPOP", encode key] +-- |Remove and get the last element in a list (). +-- +-- Result will have no more than @N@ arguments. +-- +-- Since Redis 1.0.0 +rpopCount + :: (RedisCtx m f) + => ByteString -- ^ key + -> Integer + -> m (f (Maybe ByteString)) +rpopCount key count = sendRequest (["RPOP",key, encode count] ) + +-- |Rename a key (). Since Redis 1.0.0 +-- +-- Does not return a error even if newkey existed. rename :: (RedisCtx m f) => ByteString -- ^ key -> ByteString -- ^ newkey -> m (f Status) -rename key newkey = sendRequest (["RENAME"] ++ [encode key] ++ [encode newkey] ) +rename key newkey = sendRequest ["RENAME", encode key, encode newkey] +-- | /O(M*log(N))/ with @N@ number of elements in the sorted set, @M@ number of elements to be +-- removed. +-- +-- Removes one or more members from a sorted set (). +-- +-- Since Redis 1.2.0 zrem :: (RedisCtx m f) => ByteString -- ^ key - -> [ByteString] -- ^ member + -> NonEmpty ByteString -- ^ member -> m (f Integer) -zrem key member = sendRequest (["ZREM"] ++ [encode key] ++ map encode member ) +zrem key (member:|members) = sendRequest ("ZREM":encode key:encode member:members) +-- |Determine if a hash field exists (). +-- Since Redis 2.0.0 hexists :: (RedisCtx m f) => ByteString -- ^ key -> ByteString -- ^ field -> m (f Bool) -hexists key field = sendRequest (["HEXISTS"] ++ [encode key] ++ [encode field] ) +hexists key field = sendRequest ["HEXISTS", key, field] +-- |Get the current connection ID (). Since Redis 5.0.0 clientId :: (RedisCtx m f) => m (f Integer) -clientId = sendRequest (["CLIENT","ID"] ) +clientId = sendRequest ["CLIENT","ID"] +-- |Get the current connection name (). Since Redis 2.6.9 clientGetname :: (RedisCtx m f) => m (f (Maybe ByteString)) -clientGetname = sendRequest (["CLIENT","GETNAME"] ) +clientGetname = sendRequest ["CLIENT","GETNAME"] +-- |Rewrite the configuration file with the in memory configuration (). Since Redis 2.8.0 configRewrite :: (RedisCtx m f) => m (f Status) -configRewrite = sendRequest (["CONFIG","REWRITE"] ) +configRewrite = sendRequest ["CONFIG","REWRITE"] +-- |Decrement the integer value of a key by one (). +-- Since Redis 1.0.0 decr :: (RedisCtx m f) => ByteString -- ^ key -> m (f Integer) -decr key = sendRequest (["DECR"] ++ [encode key] ) +decr key = sendRequest ["DECR", key] +-- |Get the values of all the given hash fields (). +-- Since Redis 2.0.0 hmget :: (RedisCtx m f) => ByteString -- ^ key - -> [ByteString] -- ^ field + -> NonEmpty ByteString -- ^ field -> m (f [Maybe ByteString]) -hmget key field = sendRequest (["HMGET"] ++ [encode key] ++ map encode field ) +hmget key (field:|fields) = sendRequest ("HMGET":key:field:fields) +-- |Get a range of elements from a list (). Since Redis 1.0.0 lrange :: (RedisCtx m f) => ByteString -- ^ key -> Integer -- ^ start -> Integer -- ^ stop -> m (f [ByteString]) -lrange key start stop = sendRequest (["LRANGE"] ++ [encode key] ++ [encode start] ++ [encode stop] ) +lrange key start stop = sendRequest ["LRANGE", key, encode start, encode stop] +-- |Decrement the integer value of a key by the given number (). +-- Since Redis 1.0.0 decrby :: (RedisCtx m f) => ByteString -- ^ key -> Integer -- ^ decrement -> m (f Integer) -decrby key decrement = sendRequest (["DECRBY"] ++ [encode key] ++ [encode decrement] ) +decrby key decrement = sendRequest ["DECRBY",key, encode decrement] +-- |Get the length of a list (). Since Redis 1.0.0 llen :: (RedisCtx m f) => ByteString -- ^ key -> m (f Integer) -llen key = sendRequest (["LLEN"] ++ [encode key] ) +llen key = sendRequest ["LLEN", encode key] +-- | /O(1)/ Append a value to a key (). Since Redis 2.0.0 append :: (RedisCtx m f) => ByteString -- ^ key -> ByteString -- ^ value -> m (f Integer) -append key value = sendRequest (["APPEND"] ++ [encode key] ++ [encode value] ) +append key value = sendRequest ["APPEND", key, value] +-- |Increment the integer value of a key by one (). Since Redis 1.0.0 incr :: (RedisCtx m f) => ByteString -- ^ key -> m (f Integer) -incr key = sendRequest (["INCR"] ++ [encode key] ) +incr key = sendRequest ["INCR", key] +-- |Get the value of a hash field (). Since Redis 2.0.0 hget :: (RedisCtx m f) => ByteString -- ^ key -> ByteString -- ^ field -> m (f (Maybe ByteString)) -hget key field = sendRequest (["HGET"] ++ [encode key] ++ [encode field] ) +hget key field = sendRequest ["HGET",key,field] +-- |Set the expiration for a key as a UNIX timestamp specified in milliseconds (). Since Redis 2.6.0 pexpireat :: (RedisCtx m f) => ByteString -- ^ key -> Integer -- ^ millisecondsTimestamp -> m (f Bool) -pexpireat key millisecondsTimestamp = sendRequest (["PEXPIREAT"] ++ [encode key] ++ [encode millisecondsTimestamp] ) +pexpireat key millisecondsTimestamp = sendRequest ["PEXPIREAT", key, encode millisecondsTimestamp] +-- | Trim a list to the specified range (). +-- Since Redis 1.0.0 ltrim :: (RedisCtx m f) => ByteString -- ^ key -> Integer -- ^ start -> Integer -- ^ stop -> m (f Status) -ltrim key start stop = sendRequest (["LTRIM"] ++ [encode key] ++ [encode start] ++ [encode stop] ) +ltrim key start stop = sendRequest ["LTRIM", key, encode start, encode stop] +-- | /O(1)/ +-- Get the number of members in a sorted set (). +-- Since Redis 1.2.0 zcard :: (RedisCtx m f) => ByteString -- ^ key -> m (f Integer) -zcard key = sendRequest (["ZCARD"] ++ [encode key] ) +zcard key = sendRequest ["ZCARD", key] +-- | Set the value of an element in a list by its index (). +-- Since Redis 1.0.0 lset :: (RedisCtx m f) => ByteString -- ^ key -> Integer -- ^ index -> ByteString -- ^ value -> m (f Status) -lset key index value = sendRequest (["LSET"] ++ [encode key] ++ [encode index] ++ [encode value] ) +lset key index value = sendRequest ["LSET", key, encode index, value] +-- | Set the expiration for a key as a UNIX timestamp (). +-- Since Redis 1.2.0 expireat :: (RedisCtx m f) => ByteString -- ^ key -> Integer -- ^ timestamp -> m (f Bool) -expireat key timestamp = sendRequest (["EXPIREAT"] ++ [encode key] ++ [encode timestamp] ) +expireat key timestamp = sendRequest ["EXPIREAT", key, encode timestamp] +-- | Synchronously save the dataset to disk (). +-- Since Redis 1.0.0 save :: (RedisCtx m f) => m (f Status) -save = sendRequest (["SAVE"] ) +save = sendRequest ["SAVE"] +-- | +-- Move a key to another database (). +-- Since Redis 1.0.0 move :: (RedisCtx m f) => ByteString -- ^ key -> Integer -- ^ db -> m (f Bool) -move key db = sendRequest (["MOVE"] ++ [encode key] ++ [encode db] ) +move key db = sendRequest ["MOVE", key, encode db] +-- | +-- Returns the bit value at offset in the string value stored at key (). Since Redis 2.2.0 getbit :: (RedisCtx m f) - => ByteString -- ^ key - -> Integer -- ^ offset + => ByteString -- ^ Key. + -> Integer -- ^ Offset. -> m (f Integer) -getbit key offset = sendRequest (["GETBIT"] ++ [encode key] ++ [encode offset] ) +getbit key offset = sendRequest ["GETBIT", key, encode offset] +-- |Set multiple keys to multiple values, only if none of the keys exist (). +-- Since Redis 1.0.1 msetnx :: (RedisCtx m f) - => [(ByteString,ByteString)] -- ^ keyValue + => NonEmpty (ByteString,ByteString) -- ^ keyValue -> m (f Bool) -msetnx keyValue = sendRequest (["MSETNX"] ++ concatMap (\(x,y) -> [encode x,encode y])keyValue ) +msetnx ((key,value):|keysValues) = + sendRequest ("MSETNX":key:value:concatMap (\(x,y) -> [encode x,encode y]) keysValues) +-- |Get array of specific Redis command details (). +-- Since Redis 2.8.13 commandInfo :: (RedisCtx m f) => [ByteString] -- ^ commandName -> m (f [ByteString]) -commandInfo commandName = sendRequest (["COMMAND","INFO"] ++ map encode commandName ) +commandInfo commandName = sendRequest ("COMMAND":"INFO":map encode commandName ) +-- | Close the connection (). Since Redis 1.0.0 quit :: (RedisCtx m f) => m (f Status) -quit = sendRequest (["QUIT"] ) +quit = sendRequest ["QUIT"] +-- |Remove and get the first element in a list, or block until one is available (). Since Redis 2.0.0 blpop :: (RedisCtx m f) => [ByteString] -- ^ key -> Integer -- ^ timeout -> m (f (Maybe (ByteString,ByteString))) -blpop key timeout = sendRequest (["BLPOP"] ++ map encode key ++ [encode timeout] ) +blpop keys_ timeout = sendRequest ("BLPOP":keys_ ++ [encode timeout] ) + +-- |Remove and get the first element in a list, or block until one is available (). Since Redis 6.0.0 +blpopFloat + :: (RedisCtx m f) + => [ByteString] -- ^ key + -> Integer -- ^ timeout + -> m (f (Maybe (ByteString,ByteString))) +blpopFloat keys_ timeout = sendRequest ("BLPOP":keys_ ++ [encode timeout] ) -- | /O(N)/ where @N@ is the number of members to be removed. -- Remove one or more members from a set (). @@ -1151,20 +1505,23 @@ srem => ByteString -- ^ Key of the set. -> NonEmpty ByteString -- ^ List of members to be removed. -> m (f Integer) -srem key member = sendRequest (["SREM"] ++ [encode key] ++ NE.toList (fmap encode member)) +srem key (member:|members) = sendRequest ("SREM":key:member:members) +-- |Echo the given string (). Since Redis 1.0.0 echo :: (RedisCtx m f) => ByteString -- ^ message -> m (f ByteString) -echo message = sendRequest (["ECHO"] ++ [encode message] ) +echo message = sendRequest ["ECHO", encode message] +-- |Determine if a given value is a member of a set (). +-- Since Redis 1.0.0 sismember :: (RedisCtx m f) - => ByteString -- ^ key + => ByteString -- ^ Key. -> ByteString -- ^ member -> m (f Bool) -sismember key member = sendRequest (["SISMEMBER"] ++ [encode key] ++ [encode member] ) +sismember key member = sendRequest ["SISMEMBER",key, member] -- $autoclaim -- @@ -1192,3 +1549,4 @@ sismember key member = sendRequest (["SISMEMBER"] ++ [encode key] ++ [encode mem -- $auth -- Authenticate to the server (). Since Redis 1.0.0 + diff --git a/src/Database/Redis/ManualCommands.hs b/src/Database/Redis/ManualCommands.hs index a7ef63e0..37999cef 100644 --- a/src/Database/Redis/ManualCommands.hs +++ b/src/Database/Redis/ManualCommands.hs @@ -6,6 +6,8 @@ import Prelude hiding (min, max) import Data.ByteString (ByteString, empty, append) import qualified Data.ByteString.Char8 as Char8 import qualified Data.ByteString as BS +import Data.List.NonEmpty (NonEmpty(..)) +import qualified Data.List.NonEmpty as NE import Data.Maybe (maybeToList, catMaybes) #if __GLASGOW_HASKELL__ < 808 import Data.Semigroup ((<>)) @@ -18,25 +20,27 @@ import Database.Redis.Protocol import Database.Redis.Types import qualified Database.Redis.Cluster.Command as CMD - +-- |Inspect the internals of Redis objects (). The Redis command @OBJECT@ is split up into 'objectRefcount', 'objectEncoding', 'objectIdletime'. Since Redis 2.2.3 objectRefcount :: (RedisCtx m f) => ByteString -- ^ key -> m (f Integer) -objectRefcount key = sendRequest ["OBJECT", "refcount", encode key] +objectRefcount key = sendRequest ["OBJECT", "refcount", key] objectIdletime :: (RedisCtx m f) => ByteString -- ^ key -> m (f Integer) -objectIdletime key = sendRequest ["OBJECT", "idletime", encode key] +objectIdletime key = sendRequest ["OBJECT", "idletime", key] +-- |Inspect the internals of Redis objects (). The Redis command @OBJECT@ is split up into 'objectRefcount', 'objectEncoding', 'objectIdletime'. Since Redis 2.2.3 objectEncoding :: (RedisCtx m f) => ByteString -- ^ key -> m (f ByteString) -objectEncoding key = sendRequest ["OBJECT", "encoding", encode key] +objectEncoding key = sendRequest ["OBJECT", "encoding", key] +-- |Insert an element before or after another element in a list (). The Redis command @LINSERT@ is split up into 'linsertBefore', 'linsertAfter'. Since Redis 2.2.0 linsertBefore :: (RedisCtx m f) => ByteString -- ^ key @@ -44,8 +48,9 @@ linsertBefore -> ByteString -- ^ value -> m (f Integer) linsertBefore key pivot value = - sendRequest ["LINSERT", encode key, "BEFORE", encode pivot, encode value] + sendRequest ["LINSERT", key, "BEFORE", pivot, value] +-- |Insert an element before or after another element in a list (). The Redis command @LINSERT@ is split up into 'linsertBefore', 'linsertAfter'. Since Redis 2.2.0 linsertAfter :: (RedisCtx m f) => ByteString -- ^ key @@ -55,11 +60,12 @@ linsertAfter linsertAfter key pivot value = sendRequest ["LINSERT", encode key, "AFTER", encode pivot, encode value] +-- |Determine the type stored at key (). Since Redis 1.0.0 getType :: (RedisCtx m f) => ByteString -- ^ key -> m (f RedisType) -getType key = sendRequest ["TYPE", encode key] +getType key = sendRequest ["TYPE", key] -- |A single entry from the slowlog. data Slowlog = Slowlog @@ -106,6 +112,7 @@ slowlogLen = sendRequest ["SLOWLOG", "LEN"] slowlogReset :: (RedisCtx m f) => m (f Status) slowlogReset = sendRequest ["SLOWLOG", "RESET"] +-- |Return a range of members in a sorted set, by index (). The Redis command @ZRANGE@ is split up into 'zrange', 'zrangeWithscores'. Since Redis 1.2.0 zrange :: (RedisCtx m f) => ByteString -- ^ key @@ -115,6 +122,7 @@ zrange zrange key start stop = sendRequest ["ZRANGE", encode key, encode start, encode stop] +-- |Return a range of members in a sorted set, by index (). The Redis command @ZRANGE@ is split up into 'zrange', 'zrangeWithscores'. Since Redis 1.2.0 zrangeWithscores :: (RedisCtx m f) => ByteString -- ^ key @@ -261,6 +269,7 @@ defaultSortOpts = SortOpts data SortOrder = Asc | Desc deriving (Show, Eq) +-- |Sort the elements in a list, set or sorted set (). The Redis command @SORT@ is split up into 'sort', 'sortStore'. Since Redis 1.0.0 sortStore :: (RedisCtx m f) => ByteString -- ^ key @@ -269,6 +278,7 @@ sortStore -> m (f Integer) sortStore key dest = sortInternal key (Just dest) +-- |Sort the elements in a list, set or sorted set (). The Redis command @SORT@ is split up into 'sort', 'sortStore'. Since Redis 1.0.0 sort :: (RedisCtx m f) => ByteString -- ^ key @@ -314,23 +324,25 @@ zunionstoreWeights dest kws = let (keys,weights) = unzip kws in zstoreInternal "ZUNIONSTORE" dest keys weights +-- |Intersect multiple sorted sets and store the resulting sorted set in a new key (). The Redis command @ZINTERSTORE@ is split up into 'zinterstore', 'zinterstoreWeights'. Since Redis 2.0.0 zinterstore :: (RedisCtx m f) => ByteString -- ^ destination - -> [ByteString] -- ^ keys + -> NonEmpty ByteString -- ^ keys -> Aggregate -> m (f Integer) -zinterstore dest keys = - zstoreInternal "ZINTERSTORE" dest keys [] +zinterstore dest (key_:|keys_) = + zstoreInternal "ZINTERSTORE" dest (key_:keys_) [] +-- |Intersect multiple sorted sets and store the resulting sorted set in a new key (). The Redis command @ZINTERSTORE@ is split up into 'zinterstore', 'zinterstoreWeights'. Since Redis 2.0.0 zinterstoreWeights :: (RedisCtx m f) => ByteString -- ^ destination - -> [(ByteString,Double)] -- ^ weighted keys + -> NonEmpty (ByteString,Double) -- ^ weighted keys -> Aggregate -> m (f Integer) zinterstoreWeights dest kws = - let (keys,weights) = unzip kws + let (keys,weights) = unzip (NE.toList kws) in zstoreInternal "ZINTERSTORE" dest keys weights zstoreInternal @@ -342,7 +354,7 @@ zstoreInternal -> Aggregate -> m (f Integer) zstoreInternal cmd dest keys weights aggregate = sendRequest $ - concat [ [cmd, dest, encode . toInteger $ length keys], keys + concat [ [cmd, dest, encode . toInteger $ length keys ], keys , if null weights then [] else "WEIGHTS" : map encode weights , ["AGGREGATE", aggregate'] ] @@ -352,6 +364,7 @@ zstoreInternal cmd dest keys weights aggregate = sendRequest $ Min -> "MIN" Max -> "MAX" +-- |Execute a Lua script server side (). Since Redis 2.6.0 eval :: (RedisCtx m f, RedisResult a) => ByteString -- ^ script @@ -426,10 +439,7 @@ bitop -> m (f Integer) bitop op ks = sendRequest $ "BITOP" : op : ks --- setRange --- :: --- setRange = sendRequest (["SET"] ++ [encode key] ++ [encode value] ++ ) - +-- |Atomically transfer a key from a Redis instance to another one (). The Redis command @MIGRATE@ is split up into 'migrate', 'migrateMultiple'. Since Redis 2.6.0 migrate :: (RedisCtx m f) => ByteString -- ^ host @@ -441,11 +451,16 @@ migrate migrate host port key destinationDb timeout = sendRequest ["MIGRATE", host, port, key, encode destinationDb, encode timeout] +data MigrateAuth + = MigrateAuth ByteString + | MigrateAuth2 ByteString ByteString + deriving (Show, Eq) -- |Options for the 'migrate' command. data MigrateOpts = MigrateOpts { migrateCopy :: Bool , migrateReplace :: Bool + , migrateAuth :: Maybe MigrateAuth } deriving (Show, Eq) -- |Redis default 'MigrateOpts'. Equivalent to omitting all optional parameters. @@ -454,6 +469,7 @@ data MigrateOpts = MigrateOpts -- MigrateOpts -- { migrateCopy = False -- remove the key from the local instance -- , migrateReplace = False -- don't replace existing key on the remote instance +-- , migrateAuth = Nothing -- } -- @ -- @@ -461,8 +477,10 @@ defaultMigrateOpts :: MigrateOpts defaultMigrateOpts = MigrateOpts { migrateCopy = False , migrateReplace = False + , migrateAuth = Nothing } +-- |Atomically transfer a key from a Redis instance to another one (). The Redis command @MIGRATE@ is split up into 'migrate', 'migrateMultiple'. Since Redis 2.6.0 migrateMultiple :: (RedisCtx m f) => ByteString -- ^ host @@ -475,12 +493,17 @@ migrateMultiple migrateMultiple host port destinationDb timeout MigrateOpts{..} keys = sendRequest $ concat [["MIGRATE", host, port, empty, encode destinationDb, encode timeout], - copy, replace, keys] + auth_, copy, replace, keys] where copy = ["COPY" | migrateCopy] replace = ["REPLACE" | migrateReplace] + auth_ = case migrateAuth of + Nothing -> [] + Just (MigrateAuth pass) -> ["AUTH", pass] + Just (MigrateAuth2 user pass) -> ["AUTH2", user, pass] +-- |Create a key using the provided serialized value, previously obtained using DUMP (). The Redis command @RESTORE@ is split up into 'restore', 'restoreReplace'. Since Redis 2.6.0 restore :: (RedisCtx m f) => ByteString -- ^ key @@ -490,6 +513,30 @@ restore restore key timeToLive serializedValue = sendRequest ["RESTORE", key, encode timeToLive, serializedValue] +data RestoreOpts = RestoreOpts + { restoreOptsReplace :: Bool + , restoreOptsAbsTTL :: Bool + , restoreOptsIdle :: Maybe Integer + , restoreOptsFreq :: Maybe Integer + } + +-- |Create a key using the provided serialized value, previously obtained using DUMP (). The Redis command @RESTORE@ is split up into 'restore', 'restoreReplace'. Since Redis 2.6.0 +restoreOpts + :: (RedisCtx m f) + => ByteString -- ^ key + -> Integer -- ^ timeToLive + -> ByteString -- ^ serializedValue + -> RestoreOpts -- ^ restore options + -> m (f Status) +restoreOpts key timeToLive serializedValue RestoreOpts{..} = + sendRequest ("RESTORE": key: encode timeToLive: serializedValue:rest) where + rest = replace <> absttl <> idle <> freq + replace = ["REPLACE" | restoreOptsReplace] + absttl = ["ABSTTL" | restoreOptsAbsTTL] + idle = maybe [] (\i -> ["IDLE", encode i]) restoreOptsIdle + freq = maybe [] (\f -> ["FREQ", encode f]) restoreOptsFreq + +-- |Create a key using the provided serialized value, previously obtained using DUMP (). The Redis command @RESTORE@ is split up into 'restore', 'restoreReplace'. Since Redis 2.6.0 restoreReplace :: (RedisCtx m f) @@ -581,7 +628,7 @@ instance RedisArg DebugMode where encode Sync = "SYNC" encode No = "NO" - +-- |Set the debug mode for executed scripts (). Since Redis 3.2.0 scriptDebug :: (RedisCtx m f) => DebugMode @@ -589,7 +636,7 @@ scriptDebug scriptDebug mode = sendRequest ["SCRIPT DEBUG", encode mode] - +-- |Add one or more members to a sorted set, or update its score if it already exists (). The Redis command @ZADD@ is split up into 'zadd', 'zaddOpts'. Since Redis 1.2.0 zadd :: (RedisCtx m f) => ByteString -- ^ key @@ -608,6 +655,7 @@ instance RedisArg SizeCondition where encode CGT = "GT" encode CLT = "LT" +-- |Add one or more members to a sorted set, or update its score if it already exists (). The Redis command @ZADD@ is split up into 'zadd', 'zaddOpts'. Since Redis 1.2.0 data ZaddOpts = ZaddOpts { zaddCondition :: Maybe Condition -- ^ Add on condition , zaddSizeCondition :: Maybe SizeCondition @@ -663,7 +711,7 @@ instance RedisArg ReplyMode where encode Off = "OFF" encode Skip = "SKIP" - +-- |Instruct the server whether to reply to commands (). Since Redis 3.2 clientReply :: (RedisCtx m f) => ReplyMode @@ -671,7 +719,7 @@ clientReply clientReply mode = sendRequest ["CLIENT REPLY", encode mode] - +-- |Get one or multiple random members from a set (). The Redis command @SRANDMEMBER@ is split up into 'srandmember', 'srandmemberN'. Since Redis 1.0.0 srandmember :: (RedisCtx m f) => ByteString -- ^ key @@ -679,6 +727,7 @@ srandmember srandmember key = sendRequest ["SRANDMEMBER", key] +-- |Get one or multiple random members from a set (). The Redis command @SRANDMEMBER@ is split up into 'srandmember', 'srandmemberN'. Since Redis 1.0.0 srandmemberN :: (RedisCtx m f) => ByteString -- ^ key @@ -686,14 +735,14 @@ srandmemberN -> m (f [ByteString]) srandmemberN key count = sendRequest ["SRANDMEMBER", key, encode count] - +-- |Remove and return one or multiple random members from a set (). The Redis command @SPOP@ is split up into 'spop', 'spopN'. Since Redis 1.0.0 spop :: (RedisCtx m f) => ByteString -- ^ key -> m (f (Maybe ByteString)) spop key = sendRequest ["SPOP", key] - +-- |Remove and return one or multiple random members from a set (). The Redis command @SPOP@ is split up into 'spop', 'spopN'. Since Redis 1.0.0 spopN :: (RedisCtx m f) => ByteString -- ^ key @@ -714,7 +763,7 @@ infoSection -> m (f ByteString) infoSection section = sendRequest ["INFO", section] - +-- |Determine if a key exists (). Since Redis 1.0.0 exists :: (RedisCtx m f) => ByteString -- ^ key @@ -736,12 +785,12 @@ instance RedisResult Cursor where cursor0 :: Cursor cursor0 = Cursor "0" - +-- |Incrementally iterate the keys space (). The Redis command @SCAN@ is split up into 'scan', 'scanOpts'. Since Redis 2.8.0 scan :: (RedisCtx m f) => Cursor -> m (f (Cursor, [ByteString])) -- ^ next cursor and values -scan cursor = scanOpts cursor defaultScanOpts +scan cursor = scanOpts cursor defaultScanOpts Nothing data ScanOpts = ScanOpts @@ -765,13 +814,15 @@ defaultScanOpts = ScanOpts , scanCount = Nothing } - +-- | Incrementally iterate the keys space (). The Redis command @SCAN@ is split up into 'scan', 'scanOpts'. Since Redis 2.8.0 scanOpts :: (RedisCtx m f) => Cursor -> ScanOpts + -> Maybe ByteString -- ^ types of the object to scan -> m (f (Cursor, [ByteString])) -- ^ next cursor and values -scanOpts cursor opts = sendRequest $ addScanOpts ["SCAN", encode cursor] opts +scanOpts cursor opts mtype_ = sendRequest $ addScanOpts ["SCAN", encode cursor] opts + ++ maybe [] (\type_ -> ["TYPE", type_]) mtype_ addScanOpts @@ -785,6 +836,7 @@ addScanOpts cmd ScanOpts{..} = match = maybe [] (prepend "MATCH") scanMatch count = maybe [] ((prepend "COUNT").encode) scanCount +-- |Incrementally iterate Set elements (). The Redis command @SSCAN@ is split up into 'sscan', 'sscanOpts'. Since Redis 2.8.0 sscan :: (RedisCtx m f) => ByteString -- ^ key @@ -792,7 +844,7 @@ sscan -> m (f (Cursor, [ByteString])) -- ^ next cursor and values sscan key cursor = sscanOpts key cursor defaultScanOpts - +-- |Incrementally iterate Set elements (). The Redis command @SSCAN@ is split up into 'sscan', 'sscanOpts'. Since Redis 2.8.0 sscanOpts :: (RedisCtx m f) => ByteString -- ^ key @@ -801,7 +853,7 @@ sscanOpts -> m (f (Cursor, [ByteString])) -- ^ next cursor and values sscanOpts key cursor opts = sendRequest $ addScanOpts ["SSCAN", key, encode cursor] opts - +-- |Incrementally iterate hash fields and associated values (). The Redis command @HSCAN@ is split up into 'hscan', 'hscanOpts'. Since Redis 2.8.0 hscan :: (RedisCtx m f) => ByteString -- ^ key @@ -809,7 +861,7 @@ hscan -> m (f (Cursor, [(ByteString, ByteString)])) -- ^ next cursor and values hscan key cursor = hscanOpts key cursor defaultScanOpts - +-- |Incrementally iterate hash fields and associated values (). The Redis command @HSCAN@ is split up into 'hscan', 'hscanOpts'. Since Redis 2.8.0 hscanOpts :: (RedisCtx m f) => ByteString -- ^ key @@ -843,6 +895,7 @@ instance RedisArg a => RedisArg (RangeLex a) where encode Minr = "-" encode Maxr = "+" +-- |Return a range of members in a sorted set, by lexicographical range (). Since Redis 2.8.9 zrangebylex::(RedisCtx m f) => ByteString -- ^ key -> RangeLex ByteString -- ^ min @@ -1703,26 +1756,32 @@ instance RedisResult XInfoStreamResponse where , ..} decodeRedis7 a = Left a +-- | Get info about a stream. The Redis command @XINFO@ is split into 'xinfoConsumers', 'xinfoGroups', and 'xinfoStream'. +-- Since Redis 5.0.0 xinfoStream :: (RedisCtx m f) => ByteString -- ^ stream -> m (f XInfoStreamResponse) xinfoStream stream = sendRequest ["XINFO", "STREAM", stream] +-- | Delete messages from a stream. +-- Since Redis 5.0.0 xdel :: (RedisCtx m f) => ByteString -- ^ stream - -> [ByteString] -- ^ message IDs + -> NonEmpty ByteString -- ^ message IDs -> m (f Integer) -xdel stream messageIds = sendRequest $ ["XDEL", stream] ++ messageIds +xdel stream (messageId:|messageIds) = sendRequest ("XDEL":stream:messageId: messageIds) +-- |Set the upper bound for number of messages in a stream. Since Redis 5.0.0 xtrim :: (RedisCtx m f) => ByteString -- ^ stream -> TrimOpts -> m (f Integer) -xtrim stream opts = sendRequest $ ["XTRIM", stream] ++ internalTrimArgToList opts +xtrim stream opts = sendRequest ("XTRIM":stream:internalTrimArgToList opts) +-- |Constructor for `inf` Redis argument values inf :: RealFloat a => a inf = 1 / 0 @@ -1768,14 +1827,14 @@ authOpts authOpts password AuthOpts{..} = sendRequest $ ["AUTH"] <> maybe [] (:[]) authOptsUsername <> [password] --- the select command. used in 'connect'. +-- |Change the selected database for the current connection (). Since Redis 1.0.0 select :: RedisCtx m f => Integer -- ^ index -> m (f Status) select ix = sendRequest ["SELECT", encode ix] --- the ping command. used in 'checkedconnect'. +-- |Ping the server (). Since Redis 1.0.0 ping :: (RedisCtx m f) => m (f Status) @@ -1940,3 +1999,86 @@ clusterGetKeysInSlot slot count = sendRequest ["CLUSTER", "GETKEYSINSLOT", (enco command :: (RedisCtx m f) => m (f [CMD.CommandInfo]) command = sendRequest ["COMMAND"] + +data ExpireOpts + = ExpireOptsTime Condition + | ExpireOptsValue SizeCondition + +instance RedisArg ExpireOpts where + encode (ExpireOptsTime c) = encode c + encode (ExpireOptsValue c) = encode c + +-- |Set the expiration for a key as a UNIX timestamp specified in milliseconds (). +-- Since Redis 7.0 +pexpireatOpts + :: (RedisCtx m f) + => ByteString -- ^ key + -> Integer -- ^ millisecondsTimestamp + -> ExpireOpts + -> m (f Bool) +pexpireatOpts key millisecondsTimestamp opts = + sendRequest ["PEXPIREAT", key, encode millisecondsTimestamp, encode opts] + +expireOpts + :: (RedisCtx m f) + => ByteString -- ^ key + -> Integer -- ^ seconds + -> ExpireOpts + -> m (f Bool) +expireOpts key seconds opts = sendRequest ["EXPIRE", key, encode seconds, encode opts] + +-- | Set the expiration for a key as a UNIX timestamp (). +-- Since Redis 1.2.0 +expireatOpts + :: (RedisCtx m f) + => ByteString -- ^ key + -> Integer -- ^ timestamp + -> ExpireOpts + -> m (f Bool) +expireatOpts key timestamp opts = sendRequest ["EXPIREAT", key, encode timestamp, encode opts] + +data FlushOpts + = FlushOptsSync + | FlushOptsAsync + +instance RedisArg FlushOpts where + encode FlushOptsSync = "SYNC" + encode FlushOptsAsync = "ASYNC" + +-- |Remove all keys from the current database (). +-- Since Redis 6.2 +flushdbOpts + :: (RedisCtx m f) + => FlushOpts + -> m (f Status) +flushdbOpts opts = sendRequest ["FLUSHDB", encode opts] + +-- |Remove all keys from the current database (). +-- Since Redis 6.2 +flushallOpts + :: (RedisCtx m f) + => FlushOpts + -> m (f Status) +flushallOpts opts = sendRequest ["FLUSHALL", encode opts] + +data BitposType = Byte | Bit + +instance RedisArg BitposType where + encode Byte = "BYTE" + encode Bit = "BIT" + +data BitposOpts + = BitposOptsStart Integer + | BitposOptsStartEnd Integer Integer (Maybe BitposType) + +bitposOpts + :: (RedisCtx m f) + => ByteString + -> Integer + -> BitposOpts + -> m (f Integer) +bitposOpts key_ bit opts = sendRequest ("BITPOS": key_:encode bit: rest) where + rest = case opts of + BitposOptsStart s -> [encode s] + BitposOptsStartEnd start end bits -> + [encode start, encode end] ++ [ encode bits_ | Just bits_ <- pure bits] diff --git a/src/Database/Redis/Types.hs b/src/Database/Redis/Types.hs index 989e4d68..b33ba067 100644 --- a/src/Database/Redis/Types.hs +++ b/src/Database/Redis/Types.hs @@ -11,6 +11,7 @@ module Database.Redis.Types where #if __GLASGOW_HASKELL__ < 710 import Control.Applicative #endif +import Data.Int import Control.DeepSeq import Data.ByteString.Char8 (ByteString, pack) import qualified Data.ByteString.Lex.Fractional as F (readSigned, readExponential) @@ -38,6 +39,9 @@ instance RedisArg ByteString where instance RedisArg Integer where encode = pack . show +instance RedisArg Int64 where + encode = pack . show + instance RedisArg Double where encode a | isInfinite a && a > 0 = "+inf" @@ -68,6 +72,11 @@ instance RedisResult Integer where decode r = maybe (Left r) (Right . fst) . I.readSigned I.readDecimal =<< decode r +instance RedisResult Int64 where + decode (Integer n) = Right (fromInteger n) + decode r = + maybe (Left r) (Right . fst) . I.readSigned I.readDecimal =<< decode r + instance RedisResult Double where decode r = maybe (Left r) (Right . fst) . F.readSigned F.readExponential =<< decode r diff --git a/test/ClusterMain.hs b/test/ClusterMain.hs index 3854f42c..9770a24c 100644 --- a/test/ClusterMain.hs +++ b/test/ClusterMain.hs @@ -1,9 +1,12 @@ {-# LANGUAGE LambdaCase #-} {-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE OverloadedLists #-} +{-# LANGUAGE TypeApplications #-} module Main (main) where import qualified Test.Framework as Test +import Data.ByteString (ByteString) import Database.Redis import Tests @@ -18,7 +21,7 @@ main = do Test.defaultMain (tests conn) tests :: Connection -> [Test.Test] -tests conn = map ($conn) $ concat +tests conn = map ($conn) $ concat @[] [ testsMisc, testsKeys, testsStrings, [testHashes], testsLists, testsSets, [testHyperLogLog] , testsZSets, [testTransaction], [testScripting] , testsConnection, testsClient, testsServer, [testSScan, testHScan, testZScan], [testZrangelex] @@ -43,7 +46,7 @@ testsKeys = [ testKeys, testExpireAt, testSortCluster, testGetType, testObject ] testSortCluster :: Test testSortCluster = testCase "sort" $ do - lpush "{same}ids" ["1","2","3"] >>=? 3 + lpush "{same}ids" ["1"::ByteString,"2","3"] >>=? 3 sort "{same}ids" defaultSortOpts >>=? ["1","2","3"] sortStore "{same}ids" "{same}anotherKey" defaultSortOpts >>=? 3 let opts = defaultSortOpts { sortOrder = Desc, sortAlpha = True diff --git a/test/Tests.hs b/test/Tests.hs index 914688f7..f1e69e96 100644 --- a/test/Tests.hs +++ b/test/Tests.hs @@ -1,4 +1,4 @@ -{-# LANGUAGE CPP, OverloadedStrings, RecordWildCards, LambdaCase #-} +{-# LANGUAGE CPP, OverloadedStrings, RecordWildCards, LambdaCase, OverloadedLists, TypeApplications #-} module Tests where @@ -11,6 +11,7 @@ import Control.Exception (try) import Control.Concurrent import Control.Monad import Control.Monad.Trans +import Data.ByteString (ByteString) import Data.Either (isRight) import qualified Data.List as L import qualified Data.List.NonEmpty as NE @@ -139,11 +140,11 @@ testKeys = testCase "keys" $ do ttl "{same}key" >>= \case Left _ -> error "error" Right t -> do - assert $ t `elem` [0..1] + assert $ elem @[] t [0..1] pttl "{same}key" >>= \case Left _ -> error "error" Right pt -> do - assert $ pt `elem` [990..1000] + assert $ elem @[] pt [990..1000] persist "{same}key" >>=? True dump "{same}key" >>= \case Left _ -> error "impossible" @@ -196,15 +197,15 @@ testSort = testCase "sort" $ do testGetType :: Test testGetType = testCase "getType" $ do getType "key" >>=? None - forM_ ts $ \(setKey, typ) -> do + forM_ @[] ts $ \(setKey, typ) -> do setKey getType "key" >>=? typ del (NE.fromList ["key"]) >>=? 1 where ts = [ (set "key" "value" >>=? Ok, String) - , (hset "key" "field" "value" >>=? 1, Hash) + , (hset "key" [("field"::ByteString, "value"::ByteString)] >>=? 1, Hash) , (lpush "key" ["value"] >>=? 1, List) - , (sadd "key" (NE.fromList ["member"]) >>=? 1, Set) + , (sadd "key" ["member"] >>=? 1, Set) , (zadd "key" [(42,"member"),(12.3,"value")] >>=? 2, ZSet) ] @@ -261,9 +262,9 @@ testBitops = testCase "bitops" $ do -- testHashes :: Test testHashes = testCase "hashes" $ do - hset "key" "field" "another" >>=? 1 - hset "key" "field" "another" >>=? 0 - hset "key" "field" "value" >>=? 0 + hset "key" [("field"::ByteString, "another"::ByteString)] >>=? 1 + hset "key" [("field"::ByteString, "another"::ByteString)] >>=? 0 + hset "key" [("field"::ByteString, "value"::ByteString)] >>=? 0 hsetnx "key" "field" "value" >>=? False hexists "key" "field" >>=? True hlen "key" >>=? 1 @@ -286,8 +287,8 @@ testsLists = testLists :: Test testLists = testCase "lists" $ do - lpushx "notAKey" "-" >>=? 0 - rpushx "notAKey" "-" >>=? 0 + lpushx "notAKey" ["-" :: ByteString] >>=? 0 + rpushx "notAKey" ["-" :: ByteString] >>=? 0 lpush "key" ["value"] >>=? 1 lpop "key" >>=? Just "value" rpush "key" ["value"] >>=? 1 @@ -373,10 +374,15 @@ testZSets = testCase "sorted sets" $ do zrevrangebyscoreLimit "key" 2.5 0.5 0 1 >>=? ["v2"] zrevrangebyscoreWithscoresLimit "key" 2.5 0.5 0 1 >>=? [("v2",2)] - zrem "key" ["v2"] >>=? 1 + zrem "key" (NE.fromList ["v2"]) >>=? 1 zremrangebyscore "key" 10 100 >>=? 1 zremrangebyrank "key" 0 0 >>=? 1 +-- testZSets7 :: Test +-- testZSets7 = testCase "sorted sets: redis 7" $ do +-- zadd "key" [(2,"v1"),(0,"v2"),(40,"v3")] >>=? 3 +-- zrankWithScore "key" "v1" >>=? Just (1, 2) + testZStore :: Test testZStore = testCase "zunionstore/zinterstore" $ do zadd "{same}k1" [(1, "v1"), (2, "v2")] >>= \case @@ -664,7 +670,7 @@ testBgrewriteaof = testCase "bgrewriteaof/bgsave/save" $ do testConfig :: Test testConfig = testCase "config/auth" $ do - configGet "requirepass" >>=? [("requirepass", "")] + configGet ["requirepass"] >>=? [("requirepass", "")] configSet "requirepass" "pass" >>=? Ok auth "pass" >>=? Ok configSet "requirepass" "" >>=? Ok @@ -705,8 +711,8 @@ testScans :: Test testScans = testCase "scans" $ do set "key" "value" >>=? Ok scan cursor0 >>=? (cursor0, ["key"]) - scanOpts cursor0 sOpts1 >>=? (cursor0, ["key"]) - scanOpts cursor0 sOpts2 >>=? (cursor0, []) + scanOpts cursor0 sOpts1 Nothing >>=? (cursor0, ["key"]) + scanOpts cursor0 sOpts2 Nothing >>=? (cursor0, []) where sOpts1 = defaultScanOpts { scanMatch = Just "k*" } sOpts2 = defaultScanOpts { scanMatch = Just "not*"} @@ -717,8 +723,8 @@ testSScan = testCase "sscan" $ do testHScan :: Test testHScan = testCase "hscan" $ do - hset "hash" "k" "v" >>=? 1 - hscan "hash" cursor0 >>=? (cursor0, [("k", "v")]) + hset "hash" [("k"::ByteString, "v"::ByteString)] >>=? 1 + hscan "hash" cursor0 >>=? (cursor0, [("k", "v")]) testZScan :: Test testZScan = testCase "zscan" $ do