diff --git a/build.gradle b/build.gradle index e282048..c699eb0 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ apply plugin: 'java' apply plugin: 'maven' -group = 'redis.clients' +group = 'com.googlecode.jedis' archiveBaseName = 'jedis' version = '1.2.0' diff --git a/pom.xml b/pom.xml index a6c5c7b..dbb1ed7 100644 --- a/pom.xml +++ b/pom.xml @@ -1,43 +1,77 @@ - - 4.0.0 - redis.clients - jedis - 1.2.0 - - - junit - junit - 4.8.1 - jar - compile - - - - - localhost:6379,localhost:6380 - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 2.0.2 - - 1.6 - 1.6 - - - - org.apache.maven.plugins - maven-surefire-plugin - 2.6 - + + + + org.sonatype.oss + oss-parent + 5 + + + 4.0.0 + jar + + com.googlecode.jedis + jedis + 1.2.0 + + Jedis + Jedis is a blazingly small and sane Redis java client. + http://code.google.com/p/jedis/ + + + + Jedis License + http://github.com/xetorthio/jedis/raw/master/LICENSE.txt + repo + + + + + github + http://github.com/xetorthio/jedis/issues + + + + http://github.com/xetorthio/jedis + scm:git:http://github.com/xetorthio/jedis.git + scm:git:http://github.com/xetorthio/jedis.git + + + + localhost:6379,localhost:6380 + + + + + junit + junit + 4.8.1 + jar + compile + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.0.2 + + 1.6 + 1.6 + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.6 + ${redis-hosts} - - - + + + diff --git a/src/main/java/redis/clients/jedis/Jedis.java b/src/main/java/redis/clients/jedis/Jedis.java index b5a8a39..51f5007 100644 --- a/src/main/java/redis/clients/jedis/Jedis.java +++ b/src/main/java/redis/clients/jedis/Jedis.java @@ -10,837 +10,2840 @@ import java.util.List; import java.util.Map; import java.util.Set; +import redis.clients.jedis.Client; import redis.clients.jedis.Client.LIST_POSITION; +import redis.clients.util.RedisInputStream; import redis.clients.util.ShardInfo; public class Jedis { - private Client client = null; + private Client client = null; - public Jedis(String host) { - client = new Client(host); - } - - public Jedis(String host, int port) { - client = new Client(host, port); - } - - public Jedis(String host, int port, int timeout) { - client = new Client(host, port); - client.setTimeout(timeout); - } - - public Jedis(JedisShardInfo shardInfo) { - client = new Client(shardInfo.getHost(), shardInfo.getPort()); - client.setTimeout(shardInfo.getTimeout()); - if (shardInfo.getPassword() != null) { - this.auth(shardInfo.getPassword()); - } - } - - public String ping() { - checkIsInMulti(); - client.ping(); - return client.getStatusCodeReply(); - } - - public String set(String key, String value) { - checkIsInMulti(); - client.set(key, value); - return client.getStatusCodeReply(); - } - - public String get(String key) { - checkIsInMulti(); - client.sendCommand("GET", key); - return client.getBulkReply(); - } - - public void quit() { - checkIsInMulti(); - client.quit(); - } - - public Integer exists(String key) { - checkIsInMulti(); - client.exists(key); - return client.getIntegerReply(); - } - - public Integer del(String... keys) { - checkIsInMulti(); - client.del(keys); - return client.getIntegerReply(); - } - - public String type(String key) { - checkIsInMulti(); - client.type(key); - return client.getStatusCodeReply(); - } - - public String flushDB() { - checkIsInMulti(); - client.flushDB(); - return client.getStatusCodeReply(); - } - - public List keys(String pattern) { - checkIsInMulti(); - client.keys(pattern); - return client.getMultiBulkReply(); - } - - public String randomKey() { - checkIsInMulti(); - client.randomKey(); - return client.getBulkReply(); - } - - public String rename(String oldkey, String newkey) { - checkIsInMulti(); - client.rename(oldkey, newkey); - return client.getStatusCodeReply(); - } - - public Integer renamenx(String oldkey, String newkey) { - checkIsInMulti(); - client.renamenx(oldkey, newkey); - return client.getIntegerReply(); - } - - public Integer dbSize() { - checkIsInMulti(); - client.dbSize(); - return client.getIntegerReply(); - } - - public Integer expire(String key, int seconds) { - checkIsInMulti(); - client.expire(key, seconds); - return client.getIntegerReply(); - } - - public Integer expireAt(String key, long unixTime) { - checkIsInMulti(); - client.expireAt(key, unixTime); - return client.getIntegerReply(); - } - - public Integer ttl(String key) { - checkIsInMulti(); - client.ttl(key); - return client.getIntegerReply(); - } - - public String select(int index) { - checkIsInMulti(); - client.select(index); - return client.getStatusCodeReply(); - } - - public Integer move(String key, int dbIndex) { - checkIsInMulti(); - client.move(key, dbIndex); - return client.getIntegerReply(); - } - - public String flushAll() { - checkIsInMulti(); - client.flushAll(); - return client.getStatusCodeReply(); - } - - public String getSet(String key, String value) { - checkIsInMulti(); - client.getSet(key, value); - return client.getBulkReply(); - } - - public List mget(String... keys) { - checkIsInMulti(); - client.mget(keys); - return client.getMultiBulkReply(); - } - - public Integer setnx(String key, String value) { - checkIsInMulti(); - client.setnx(key, value); - return client.getIntegerReply(); - } - - public String setex(String key, int seconds, String value) { - checkIsInMulti(); - client.setex(key, seconds, value); - return client.getStatusCodeReply(); - } - - public String mset(String... keysvalues) { - checkIsInMulti(); - client.mset(keysvalues); - return client.getStatusCodeReply(); - } - - public Integer msetnx(String... keysvalues) { - checkIsInMulti(); - client.msetnx(keysvalues); - return client.getIntegerReply(); - } - - public Integer decrBy(String key, int integer) { - checkIsInMulti(); - client.decrBy(key, integer); - return client.getIntegerReply(); - } - - public Integer decr(String key) { - checkIsInMulti(); - client.decr(key); - return client.getIntegerReply(); - } - - public Integer incrBy(String key, int integer) { - checkIsInMulti(); - client.incrBy(key, integer); - return client.getIntegerReply(); - } - - public Integer incr(String key) { - checkIsInMulti(); - client.incr(key); - return client.getIntegerReply(); - } - - public Integer append(String key, String value) { - checkIsInMulti(); - client.append(key, value); - return client.getIntegerReply(); - } - - public String substr(String key, int start, int end) { - checkIsInMulti(); - client.substr(key, start, end); - return client.getBulkReply(); - } - - public Integer hset(String key, String field, String value) { - checkIsInMulti(); - client.hset(key, field, value); - return client.getIntegerReply(); - } - - public String hget(String key, String field) { - checkIsInMulti(); - client.hget(key, field); - return client.getBulkReply(); - } - - public Integer hsetnx(String key, String field, String value) { - checkIsInMulti(); - client.hsetnx(key, field, value); - return client.getIntegerReply(); - } - - public String hmset(String key, Map hash) { - checkIsInMulti(); - client.hmset(key, hash); - return client.getStatusCodeReply(); - } - - public List hmget(String key, String... fields) { - checkIsInMulti(); - client.hmget(key, fields); - return client.getMultiBulkReply(); - } - - public Integer hincrBy(String key, String field, int value) { - checkIsInMulti(); - client.hincrBy(key, field, value); - return client.getIntegerReply(); - } - - public Integer hexists(String key, String field) { - checkIsInMulti(); - client.hexists(key, field); - return client.getIntegerReply(); - } - - public Integer hdel(String key, String field) { - checkIsInMulti(); - client.hdel(key, field); - return client.getIntegerReply(); - } - - public Integer hlen(String key) { - checkIsInMulti(); - client.hlen(key); - return client.getIntegerReply(); - } - - public List hkeys(String key) { - checkIsInMulti(); - client.hkeys(key); - return client.getMultiBulkReply(); - } - - public List hvals(String key) { - checkIsInMulti(); - client.hvals(key); - return client.getMultiBulkReply(); - } - - public Map hgetAll(String key) { - checkIsInMulti(); - client.hgetAll(key); - List flatHash = client.getMultiBulkReply(); - Map hash = new HashMap(); - Iterator iterator = flatHash.iterator(); - while (iterator.hasNext()) { - hash.put(iterator.next(), iterator.next()); + public Jedis(String host) { + client = new Client(host); } - return hash; - } - - public Integer rpush(String key, String string) { - checkIsInMulti(); - client.rpush(key, string); - return client.getIntegerReply(); - } - - public Integer lpush(String key, String string) { - checkIsInMulti(); - client.lpush(key, string); - return client.getIntegerReply(); - } - - public Integer llen(String key) { - checkIsInMulti(); - client.llen(key); - return client.getIntegerReply(); - } - - public List lrange(String key, int start, int end) { - checkIsInMulti(); - client.lrange(key, start, end); - return client.getMultiBulkReply(); - } - - public String ltrim(String key, int start, int end) { - checkIsInMulti(); - client.ltrim(key, start, end); - return client.getStatusCodeReply(); - } - - public String lindex(String key, int index) { - checkIsInMulti(); - client.lindex(key, index); - return client.getBulkReply(); - } - - public String lset(String key, int index, String value) { - checkIsInMulti(); - client.lset(key, index, value); - return client.getStatusCodeReply(); - } - - public Integer lrem(String key, int count, String value) { - checkIsInMulti(); - client.lrem(key, count, value); - return client.getIntegerReply(); - } - - public String lpop(String key) { - checkIsInMulti(); - client.lpop(key); - return client.getBulkReply(); - } - - public String rpop(String key) { - checkIsInMulti(); - client.rpop(key); - return client.getBulkReply(); - } - - public String rpoplpush(String srckey, String dstkey) { - checkIsInMulti(); - client.rpoplpush(srckey, dstkey); - return client.getBulkReply(); - } - - public Integer sadd(String key, String member) { - checkIsInMulti(); - client.sadd(key, member); - return client.getIntegerReply(); - } - - public Set smembers(String key) { - checkIsInMulti(); - client.smembers(key); - List members = client.getMultiBulkReply(); - return new LinkedHashSet(members); - } - - public Integer srem(String key, String member) { - checkIsInMulti(); - client.srem(key, member); - return client.getIntegerReply(); - } - - public String spop(String key) { - checkIsInMulti(); - client.spop(key); - return client.getBulkReply(); - } - - public Integer smove(String srckey, String dstkey, String member) { - checkIsInMulti(); - client.smove(srckey, dstkey, member); - return client.getIntegerReply(); - } - - public Integer scard(String key) { - checkIsInMulti(); - client.scard(key); - return client.getIntegerReply(); - } - - public Integer sismember(String key, String member) { - checkIsInMulti(); - client.sismember(key, member); - return client.getIntegerReply(); - } - - public Set sinter(String... keys) { - checkIsInMulti(); - client.sinter(keys); - List members = client.getMultiBulkReply(); - return new LinkedHashSet(members); - } - - public Integer sinterstore(String dstkey, String... keys) { - checkIsInMulti(); - client.sinterstore(dstkey, keys); - return client.getIntegerReply(); - } - - public Set sunion(String... keys) { - checkIsInMulti(); - client.sunion(keys); - List members = client.getMultiBulkReply(); - return new LinkedHashSet(members); - } - - public Integer sunionstore(String dstkey, String... keys) { - checkIsInMulti(); - client.sunionstore(dstkey, keys); - return client.getIntegerReply(); - } - - public Set sdiff(String... keys) { - checkIsInMulti(); - client.sdiff(keys); - List members = client.getMultiBulkReply(); - return new LinkedHashSet(members); - } - - public Integer sdiffstore(String dstkey, String... keys) { - checkIsInMulti(); - client.sdiffstore(dstkey, keys); - return client.getIntegerReply(); - } - - public String srandmember(String key) { - checkIsInMulti(); - client.srandmember(key); - return client.getBulkReply(); - } - - public Integer zadd(String key, double score, String member) { - checkIsInMulti(); - client.zadd(key, score, member); - return client.getIntegerReply(); - } - - public Set zrange(String key, int start, int end) { - checkIsInMulti(); - client.zrange(key, start, end); - List members = client.getMultiBulkReply(); - return new LinkedHashSet(members); - } - - public Integer zrem(String key, String member) { - checkIsInMulti(); - client.zrem(key, member); - return client.getIntegerReply(); - } - - public Double zincrby(String key, double score, String member) { - checkIsInMulti(); - client.zincrby(key, score, member); - String newscore = client.getBulkReply(); - return Double.valueOf(newscore); - } - - public Integer zrank(String key, String member) { - checkIsInMulti(); - client.zrank(key, member); - return client.getIntegerReply(); - } - - public Integer zrevrank(String key, String member) { - checkIsInMulti(); - client.zrevrank(key, member); - return client.getIntegerReply(); - } - - public Set zrevrange(String key, int start, int end) { - checkIsInMulti(); - client.zrevrange(key, start, end); - List members = client.getMultiBulkReply(); - return new LinkedHashSet(members); - } - - public Set zrangeWithScores(String key, int start, int end) { - checkIsInMulti(); - client.zrangeWithScores(key, start, end); - Set set = getTupledSet(); - return set; - } - - public Set zrevrangeWithScores(String key, int start, int end) { - checkIsInMulti(); - client.zrevrangeWithScores(key, start, end); - Set set = getTupledSet(); - return set; - } - - public Integer zcard(String key) { - checkIsInMulti(); - client.zcard(key); - return client.getIntegerReply(); - } - - public Double zscore(String key, String member) { - checkIsInMulti(); - client.zscore(key, member); - String score = client.getBulkReply(); - return (score != null ? new Double(score) : null); - } - - public Transaction multi() { - client.multi(); - client.getStatusCodeReply(); - return new Transaction(client); - } - - public List multi(TransactionBlock jedisTransaction) { - List results = null; - try { - jedisTransaction.setClient(client); - multi(); - jedisTransaction.execute(); - results = jedisTransaction.exec(); - } catch (Exception ex) { - client.discard(); + public Jedis(String host, int port) { + client = new Client(host, port); } - return results; - } - private void checkIsInMulti() { - if (client.isInMulti()) { - throw new JedisException( - "Cannot use Jedis when in Multi. Please use JedisTransaction instead."); + public Jedis(String host, int port, int timeout) { + client = new Client(host, port); + client.setTimeout(timeout); } - } - public void connect() throws UnknownHostException, IOException { - client.connect(); - } - - public void disconnect() throws IOException { - client.disconnect(); - } - - public String watch(String key) { - client.watch(key); - return client.getStatusCodeReply(); - } - - public String unwatch() { - client.unwatch(); - return client.getStatusCodeReply(); - } - - public List sort(String key) { - checkIsInMulti(); - client.sort(key); - return client.getMultiBulkReply(); - } - - public List sort(String key, SortingParams sortingParameters) { - checkIsInMulti(); - client.sort(key, sortingParameters); - return client.getMultiBulkReply(); - } - - public List blpop(int timeout, String... keys) { - checkIsInMulti(); - List args = new ArrayList(); - for (String arg : keys) { - args.add(arg); + public Jedis(JedisShardInfo shardInfo) { + client = new Client(shardInfo.getHost(), shardInfo.getPort()); + client.setTimeout(shardInfo.getTimeout()); + if (shardInfo.getPassword() != null) { + this.auth(shardInfo.getPassword()); + } } - args.add(String.valueOf(timeout)); - client.blpop(args.toArray(new String[args.size()])); - client.setTimeoutInfinite(); - List multiBulkReply = client.getMultiBulkReply(); - client.rollbackTimeout(); - return multiBulkReply; - } - - public Integer sort(String key, SortingParams sortingParameters, - String dstkey) { - checkIsInMulti(); - client.sort(key, sortingParameters, dstkey); - return client.getIntegerReply(); - } - - public Integer sort(String key, String dstkey) { - checkIsInMulti(); - client.sort(key, dstkey); - return client.getIntegerReply(); - } - - public List brpop(int timeout, String... keys) { - checkIsInMulti(); - List args = new ArrayList(); - for (String arg : keys) { - args.add(arg); + public String ping() { + checkIsInMulti(); + client.ping(); + return client.getStatusCodeReply(); } - args.add(String.valueOf(timeout)); - client.brpop(args.toArray(new String[args.size()])); - client.setTimeoutInfinite(); - List multiBulkReply = client.getMultiBulkReply(); - client.rollbackTimeout(); - - return multiBulkReply; - } - - public String auth(String password) { - checkIsInMulti(); - client.auth(password); - return client.getStatusCodeReply(); - } - - public List pipelined(JedisPipeline jedisPipeline) { - jedisPipeline.setClient(client); - jedisPipeline.execute(); - return client.getAll(); - } - - public void subscribe(JedisPubSub jedisPubSub, String... channels) { - client.setTimeoutInfinite(); - jedisPubSub.proceed(client, channels); - client.rollbackTimeout(); - } - - public Integer publish(String channel, String message) { - client.publish(channel, message); - return client.getIntegerReply(); - } - - public void psubscribe(JedisPubSub jedisPubSub, String... patterns) { - client.setTimeoutInfinite(); - jedisPubSub.proceedWithPatterns(client, patterns); - client.rollbackTimeout(); - } - - public Integer zcount(String key, double min, double max) { - checkIsInMulti(); - client.zcount(key, min, max); - return client.getIntegerReply(); - } - - public Set zrangeByScore(String key, double min, double max) { - checkIsInMulti(); - client.zrangeByScore(key, min, max); - return new LinkedHashSet(client.getMultiBulkReply()); - } - - public Set zrangeByScore(String key, double min, double max, - int offset, int count) { - checkIsInMulti(); - client.zrangeByScore(key, min, max, offset, count); - return new LinkedHashSet(client.getMultiBulkReply()); - } - - public Set zrangeByScoreWithScores(String key, double min, double max) { - checkIsInMulti(); - client.zrangeByScoreWithScores(key, min, max); - Set set = getTupledSet(); - return set; - } - - public Set zrangeByScoreWithScores(String key, double min, - double max, int offset, int count) { - checkIsInMulti(); - client.zrangeByScoreWithScores(key, min, max, offset, count); - Set set = getTupledSet(); - return set; - } - - private Set getTupledSet() { - checkIsInMulti(); - List membersWithScores = client.getMultiBulkReply(); - Set set = new LinkedHashSet(); - Iterator iterator = membersWithScores.iterator(); - while (iterator.hasNext()) { - set - .add(new Tuple(iterator.next(), Double.valueOf(iterator - .next()))); + /** + * Set the string value as value of the key. The string can't be longer than + * 1073741824 bytes (1 GB). + *

+ * Time complexity: O(1) + * + * @param key + * @param value + * @return Status code reply + */ + public String set(String key, String value) { + checkIsInMulti(); + client.set(key, value); + return client.getStatusCodeReply(); } - return set; - } - public Integer zremrangeByRank(String key, int start, int end) { - checkIsInMulti(); - client.zremrangeByRank(key, start, end); - return client.getIntegerReply(); - } - - public Integer zremrangeByScore(String key, double start, double end) { - checkIsInMulti(); - client.zremrangeByScore(key, start, end); - return client.getIntegerReply(); - } - - public Integer zunionstore(String dstkey, String... sets) { - checkIsInMulti(); - client.zunionstore(dstkey, sets); - return client.getIntegerReply(); - } - - public Integer zunionstore(String dstkey, ZParams params, String... sets) { - checkIsInMulti(); - client.zunionstore(dstkey, params, sets); - return client.getIntegerReply(); - } - - public Integer zinterstore(String dstkey, String... sets) { - checkIsInMulti(); - client.zinterstore(dstkey, sets); - return client.getIntegerReply(); - } - - public Integer zinterstore(String dstkey, ZParams params, String... sets) { - checkIsInMulti(); - client.zinterstore(dstkey, params, sets); - return client.getIntegerReply(); - } - - public String save() { - client.save(); - return client.getStatusCodeReply(); - } - - public String bgsave() { - client.bgsave(); - return client.getStatusCodeReply(); - } - - public String bgrewriteaof() { - client.bgrewriteaof(); - return client.getStatusCodeReply(); - } - - public Integer lastsave() { - client.lastsave(); - return client.getIntegerReply(); - } - - public String shutdown() { - client.shutdown(); - String status = null; - try { - status = client.getStatusCodeReply(); - } catch (JedisException ex) { - status = null; + /** + * Get the value of the specified key. If the key does not exist the special + * value 'nil' is returned. If the value stored at key is not a string an + * error is returned because GET can only handle string values. + *

+ * Time complexity: O(1) + * + * @param key + * @return Bulk reply + */ + public String get(String key) { + checkIsInMulti(); + client.sendCommand("GET", key); + return client.getBulkReply(); } - return status; - } - public String info() { - client.info(); - return client.getBulkReply(); - } + /** + * Ask the server to silently close the connection. + */ + public void quit() { + checkIsInMulti(); + client.quit(); + } - public void monitor(JedisMonitor jedisMonitor) { - client.monitor(); - jedisMonitor.proceed(client); - } + /** + * Test if the specified key exists. The command returns "0" if the key + * exists, otherwise "1" is returned. Note that even keys set with an empty + * string as value will return "1". + * + * Time complexity: O(1) + * + * @param key + * @return Integer reply, "0" if the key exists, otherwise "1" + */ + public Integer exists(String key) { + checkIsInMulti(); + client.exists(key); + return client.getIntegerReply(); + } - public String slaveof(String host, int port) { - client.slaveof(host, port); - return client.getStatusCodeReply(); - } + /** + * Remove the specified keys. If a given key does not exist no operation is + * performed for this key. The command returns the number of keys removed. + * + * Time complexity: O(1) + * + * @param keys + * @return Integer reply, specifically: an integer greater than 0 if one or + * more keys were removed 0 if none of the specified key existed + */ + public Integer del(String... keys) { + checkIsInMulti(); + client.del(keys); + return client.getIntegerReply(); + } - public String slaveofNoOne() { - client.slaveofNoOne(); - return client.getStatusCodeReply(); - } + /** + * Return the type of the value stored at key in form of a string. The type + * can be one of "none", "string", "list", "set". "none" is returned if the + * key does not exist. + * + * Time complexity: O(1) + * + * @param key + * @return Status code reply, specifically: "none" if the key does not exist + * "string" if the key contains a String value "list" if the key + * contains a List value "set" if the key contains a Set value + * "zset" if the key contains a Sorted Set value "hash" if the key + * contains a Hash value + */ + public String type(String key) { + checkIsInMulti(); + client.type(key); + return client.getStatusCodeReply(); + } - public List configGet(String pattern) { - client.configGet(pattern); - return client.getMultiBulkReply(); - } + /** + * Delete all the keys of the currently selected DB. This command never + * fails. + * + * @return Status code reply + */ + public String flushDB() { + checkIsInMulti(); + client.flushDB(); + return client.getStatusCodeReply(); + } - public String configSet(String parameter, String value) { - client.configSet(parameter, value); - return client.getStatusCodeReply(); - } + /** + * Returns all the keys matching the glob-style pattern as space separated + * strings. For example if you have in the database the keys "foo" and + * "foobar" the command "KEYS foo*" will return "foo foobar". + *

+ * Note that while the time complexity for this operation is O(n) the + * constant times are pretty low. For example Redis running on an entry + * level laptop can scan a 1 million keys database in 40 milliseconds. + * Still it's better to consider this one of the slow commands that may + * ruin the DB performance if not used with care. + *

+ * In other words this command is intended only for debugging and special + * operations like creating a script to change the DB schema. Don't use it + * in your normal code. Use Redis Sets in order to group together a subset + * of objects. + *

+ * Glob style patterns examples: + *

    + *
  • h?llo will match hello hallo hhllo + *
  • h*llo will match hllo heeeello + *
  • h[ae]llo will match hello and hallo, but not hillo + *
+ *

+ * Use \ to escape special chars if you want to match them verbatim. + *

+ * Time complexity: O(n) (with n being the number of keys in the DB, and + * assuming keys and pattern of limited length) + * + * @param pattern + * @return Multi bulk reply + */ + public List keys(String pattern) { + checkIsInMulti(); + client.keys(pattern); + return client.getMultiBulkReply(); + } - public boolean isConnected() { - return client.isConnected(); - } + /** + * Return a randomly selected key from the currently selected DB. + *

+ * Time complexity: O(1) + * + * @return Singe line reply, specifically the randomly selected key or an + * empty string is the database is empty + */ + public String randomKey() { + checkIsInMulti(); + client.randomKey(); + return client.getBulkReply(); + } - public Integer strlen(String key) { - client.strlen(key); - return client.getIntegerReply(); - } + /** + * Atomically renames the key oldkey to newkey. If the source and + * destination name are the same an error is returned. If newkey already + * exists it is overwritten. + *

+ * Time complexity: O(1) + * + * @param oldkey + * @param newkey + * @return Status code repy + */ + public String rename(String oldkey, String newkey) { + checkIsInMulti(); + client.rename(oldkey, newkey); + return client.getStatusCodeReply(); + } - public void sync() { - client.sync(); - } + /** + * Rename oldkey into newkey but fails if the destination key newkey already + * exists. + *

+ * Time complexity: O(1) + * + * @param oldkey + * @param newkey + * @return Integer reply, specifically: 1 if the key was renamed 0 if the + * target key already exist + */ + public Integer renamenx(String oldkey, String newkey) { + checkIsInMulti(); + client.renamenx(oldkey, newkey); + return client.getIntegerReply(); + } - public Integer lpushx(String key, String string) { - client.lpushx(key, string); - return client.getIntegerReply(); - } + /** + * Return the number of keys in the currently selected database. + * + * @return Integer reply + */ + public Integer dbSize() { + checkIsInMulti(); + client.dbSize(); + return client.getIntegerReply(); + } - public Integer persist(String key) { - client.persist(key); - return client.getIntegerReply(); - } + /** + * Set a timeout on the specified key. After the timeout the key will be + * automatically deleted by the server. A key with an associated timeout is + * said to be volatile in Redis terminology. + *

+ * Voltile keys are stored on disk like the other keys, the timeout is + * persistent too like all the other aspects of the dataset. Saving a + * dataset containing expires and stopping the server does not stop the flow + * of time as Redis stores on disk the time when the key will no longer be + * available as Unix time, and not the remaining seconds. + *

+ * Since Redis 2.1.3 you can update the value of the timeout of a key + * already having an expire set. It is also possible to undo the expire at + * all turning the key into a normal key using the {@link #persist(String) + * PERSIST} command. + *

+ * Time complexity: O(1) + * + * @see ExpireCommand + * + * @param key + * @param seconds + * @return Integer reply, specifically: 1: the timeout was set. 0: the + * timeout was not set since the key already has an associated + * timeout (this may happen only in Redis versions < 2.1.3, Redis >= + * 2.1.3 will happily update the timeout), or the key does not + * exist. + */ + public Integer expire(String key, int seconds) { + checkIsInMulti(); + client.expire(key, seconds); + return client.getIntegerReply(); + } - public Integer rpushx(String key, String string) { - client.rpushx(key, string); - return client.getIntegerReply(); - } + /** + * EXPIREAT works exctly like {@link #expire(String, int) EXPIRE} but + * instead to get the number of seconds representing the Time To Live of the + * key as a second argument (that is a relative way of specifing the TTL), + * it takes an absolute one in the form of a UNIX timestamp (Number of + * seconds elapsed since 1 Gen 1970). + *

+ * EXPIREAT was introduced in order to implement the Append Only File + * persistence mode so that EXPIRE commands are automatically translated + * into EXPIREAT commands for the append only file. Of course EXPIREAT can + * also used by programmers that need a way to simply specify that a given + * key should expire at a given time in the future. + *

+ * Since Redis 2.1.3 you can update the value of the timeout of a key + * already having an expire set. It is also possible to undo the expire at + * all turning the key into a normal key using the {@link #persist(String) + * PERSIST} command. + *

+ * Time complexity: O(1) + * + * @see ExpireCommand + * + * @param key + * @param unixTime + * @return Integer reply, specifically: 1: the timeout was set. 0: the + * timeout was not set since the key already has an associated + * timeout (this may happen only in Redis versions < 2.1.3, Redis >= + * 2.1.3 will happily update the timeout), or the key does not + * exist. + */ + public Integer expireAt(String key, long unixTime) { + checkIsInMulti(); + client.expireAt(key, unixTime); + return client.getIntegerReply(); + } - public String echo(String string) { - client.echo(string); - return client.getBulkReply(); - } + /** + * The TTL command returns the remaining time to live in seconds of a key + * that has an {@link #expire(String, int) EXPIRE} set. This introspection + * capability allows a Redis client to check how many seconds a given key + * will continue to be part of the dataset. + * + * @param key + * @return Integer reply, returns the remaining time to live in seconds of a + * key that has an EXPIRE. If the Key does not exists or does not + * have an associated expire, -1 is returned. + */ + public Integer ttl(String key) { + checkIsInMulti(); + client.ttl(key); + return client.getIntegerReply(); + } - public Integer linsert(String key, LIST_POSITION where, String pivot, - String value) { - client.linsert(key, where, pivot, value); - return client.getIntegerReply(); - } + /** + * Select the DB with having the specified zero-based numeric index. For + * default every new client connection is automatically selected to DB 0. + * + * @param index + * @return Status code reply + */ + public String select(int index) { + checkIsInMulti(); + client.select(index); + return client.getStatusCodeReply(); + } - public String debug(DebugParams params) { - client.debug(params); - return client.getStatusCodeReply(); - } + /** + * Move the specified key from the currently selected DB to the specified + * destination DB. Note that this command returns 1 only if the key was + * successfully moved, and 0 if the target key was already there or if the + * source key was not found at all, so it is possible to use MOVE as a + * locking primitive. + * + * @param key + * @param dbIndex + * @return Integer reply, specifically: 1 if the key was moved 0 if the key + * was not moved because already present on the target DB or was not + * found in the current DB. + */ + public Integer move(String key, int dbIndex) { + checkIsInMulti(); + client.move(key, dbIndex); + return client.getIntegerReply(); + } + + /** + * Delete all the keys of all the existing databases, not just the currently + * selected one. This command never fails. + * + * @return Status code reply + */ + public String flushAll() { + checkIsInMulti(); + client.flushAll(); + return client.getStatusCodeReply(); + } + + /** + * GETSET is an atomic set this value and return the old value command. Set + * key to the string value and return the old value stored at key. The + * string can't be longer than 1073741824 bytes (1 GB). + *

+ * Time complexity: O(1) + * + * @param key + * @param value + * @return Bulk reply + */ + public String getSet(String key, String value) { + checkIsInMulti(); + client.getSet(key, value); + return client.getBulkReply(); + } + + /** + * Get the values of all the specified keys. If one or more keys dont exist + * or is not of type String, a 'nil' value is returned instead of the value + * of the specified key, but the operation never fails. + *

+ * Time complexity: O(1) for every key + * + * @param keys + * @return Multi bulk reply + */ + public List mget(String... keys) { + checkIsInMulti(); + client.mget(keys); + return client.getMultiBulkReply(); + } + + /** + * SETNX works exactly like {@link #set(String, String) SET} with the only + * difference that if the key already exists no operation is performed. + * SETNX actually means "SET if Not eXists". + *

+ * Time complexity: O(1) + * + * @param key + * @param value + * @return Integer reply, specifically: 1 if the key was set 0 if the key + * was not set + */ + public Integer setnx(String key, String value) { + checkIsInMulti(); + client.setnx(key, value); + return client.getIntegerReply(); + } + + /** + * The command is exactly equivalent to the following group of commands: + * {@link #set(String, String) SET} + {@link #expire(String, int) EXPIRE}. + * The operation is atomic. + *

+ * Time complexity: O(1) + * + * @param key + * @param seconds + * @param value + * @return Status code reply + */ + public String setex(String key, int seconds, String value) { + checkIsInMulti(); + client.setex(key, seconds, value); + return client.getStatusCodeReply(); + } + + /** + * Set the the respective keys to the respective values. MSET will replace + * old values with new values, while {@link #msetnx(String...) MSETNX} will + * not perform any operation at all even if just a single key already + * exists. + *

+ * Because of this semantic MSETNX can be used in order to set different + * keys representing different fields of an unique logic object in a way + * that ensures that either all the fields or none at all are set. + *

+ * Both MSET and MSETNX are atomic operations. This means that for instance + * if the keys A and B are modified, another client talking to Redis can + * either see the changes to both A and B at once, or no modification at + * all. + * + * @see #msetnx(String...) + * + * @param keysvalues + * @return Status code reply Basically +OK as MSET can't fail + */ + public String mset(String... keysvalues) { + checkIsInMulti(); + client.mset(keysvalues); + return client.getStatusCodeReply(); + } + + /** + * Set the the respective keys to the respective values. + * {@link #mset(String...) MSET} will replace old values with new values, + * while MSETNX will not perform any operation at all even if just a single + * key already exists. + *

+ * Because of this semantic MSETNX can be used in order to set different + * keys representing different fields of an unique logic object in a way + * that ensures that either all the fields or none at all are set. + *

+ * Both MSET and MSETNX are atomic operations. This means that for instance + * if the keys A and B are modified, another client talking to Redis can + * either see the changes to both A and B at once, or no modification at + * all. + * + * @see #mset(String...) + * + * @param keysvalues + * @return Integer reply, specifically: 1 if the all the keys were set 0 if + * no key was set (at least one key already existed) + */ + public Integer msetnx(String... keysvalues) { + checkIsInMulti(); + client.msetnx(keysvalues); + return client.getIntegerReply(); + } + + /** + * IDECRBY work just like {@link #decr(String) INCR} but instead to + * decrement by 1 the decrement is integer. + *

+ * INCR commands are limited to 64 bit signed integers. + *

+ * Note: this is actually a string operation, that is, in Redis there are + * not "integer" types. Simply the string stored at the key is parsed as a + * base 10 64 bit signed integer, incremented, and then converted back as a + * string. + *

+ * Time complexity: O(1) + * + * @see #incr(String) + * @see #decr(String) + * @see #incrBy(String, int) + * + * @param key + * @param integer + * @return Integer reply, this commands will reply with the new value of key + * after the increment. + */ + public Integer decrBy(String key, int integer) { + checkIsInMulti(); + client.decrBy(key, integer); + return client.getIntegerReply(); + } + + /** + * Decrement the number stored at key by one. If the key does not exist or + * contains a value of a wrong type, set the key to the value of "0" before + * to perform the decrement operation. + *

+ * INCR commands are limited to 64 bit signed integers. + *

+ * Note: this is actually a string operation, that is, in Redis there are + * not "integer" types. Simply the string stored at the key is parsed as a + * base 10 64 bit signed integer, incremented, and then converted back as a + * string. + *

+ * Time complexity: O(1) + * + * @see #incr(String) + * @see #incrBy(String, int) + * @see #decrBy(String, int) + * + * @param key + * @return Integer reply, this commands will reply with the new value of key + * after the increment. + */ + public Integer decr(String key) { + checkIsInMulti(); + client.decr(key); + return client.getIntegerReply(); + } + + /** + * INCRBY work just like {@link #incr(String) INCR} but instead to increment + * by 1 the increment is integer. + *

+ * INCR commands are limited to 64 bit signed integers. + *

+ * Note: this is actually a string operation, that is, in Redis there are + * not "integer" types. Simply the string stored at the key is parsed as a + * base 10 64 bit signed integer, incremented, and then converted back as a + * string. + *

+ * Time complexity: O(1) + * + * @see #incr(String) + * @see #decr(String) + * @see #decrBy(String, int) + * + * @param key + * @param integer + * @return Integer reply, this commands will reply with the new value of key + * after the increment. + */ + public Integer incrBy(String key, int integer) { + checkIsInMulti(); + client.incrBy(key, integer); + return client.getIntegerReply(); + } + + /** + * Increment the number stored at key by one. If the key does not exist or + * contains a value of a wrong type, set the key to the value of "0" before + * to perform the increment operation. + *

+ * INCR commands are limited to 64 bit signed integers. + *

+ * Note: this is actually a string operation, that is, in Redis there are + * not "integer" types. Simply the string stored at the key is parsed as a + * base 10 64 bit signed integer, incremented, and then converted back as a + * string. + *

+ * Time complexity: O(1) + * + * @see #incrBy(String, int) + * @see #decr(String) + * @see #decrBy(String, int) + * + * @param key + * @return Integer reply, this commands will reply with the new value of key + * after the increment. + */ + public Integer incr(String key) { + checkIsInMulti(); + client.incr(key); + return client.getIntegerReply(); + } + + /** + * If the key already exists and is a string, this command appends the + * provided value at the end of the string. If the key does not exist it is + * created and set as an empty string, so APPEND will be very similar to SET + * in this special case. + *

+ * Time complexity: O(1). The amortized time complexity is O(1) assuming the + * appended value is small and the already present value is of any size, + * since the dynamic string library used by Redis will double the free space + * available on every reallocation. + * + * @param key + * @param value + * @return Integer reply, specifically the total length of the string after + * the append operation. + */ + public Integer append(String key, String value) { + checkIsInMulti(); + client.append(key, value); + return client.getIntegerReply(); + } + + /** + * Return a subset of the string from offset start to offset end (both + * offsets are inclusive). Negative offsets can be used in order to provide + * an offset starting from the end of the string. So -1 means the last char, + * -2 the penultimate and so forth. + *

+ * The function handles out of range requests without raising an error, but + * just limiting the resulting range to the actual length of the string. + *

+ * Time complexity: O(start+n) (with start being the start index and n the + * total length of the requested range). Note that the lookup part of this + * command is O(1) so for small strings this is actually an O(1) command. + * + * @param key + * @param start + * @param end + * @return Bulk reply + */ + public String substr(String key, int start, int end) { + checkIsInMulti(); + client.substr(key, start, end); + return client.getBulkReply(); + } + + /** + * + * Set the specified hash field to the specified value. + *

+ * If key does not exist, a new key holding a hash is created. + *

+ * Time complexity: O(1) + * + * @param key + * @param field + * @param value + * @return If the field already exists, and the HSET just produced an update + * of the value, 0 is returned, otherwise if a new field is created + * 1 is returned. + */ + public Integer hset(String key, String field, String value) { + checkIsInMulti(); + client.hset(key, field, value); + return client.getIntegerReply(); + } + + /** + * If key holds a hash, retrieve the value associated to the specified + * field. + *

+ * If the field is not found or the key does not exist, a special 'nil' + * value is returned. + *

+ * Time complexity: O(1) + * + * @param key + * @param field + * @return Bulk reply + */ + public String hget(String key, String field) { + checkIsInMulti(); + client.hget(key, field); + return client.getBulkReply(); + } + + /** + * + * Set the specified hash field to the specified value if the field not + * exists. Time complexity: O(1) + * + * @param key + * @param field + * @param value + * @return If the field already exists, 0 is returned, otherwise if a new + * field is created 1 is returned. + */ + public Integer hsetnx(String key, String field, String value) { + checkIsInMulti(); + client.hsetnx(key, field, value); + return client.getIntegerReply(); + } + + /** + * Set the respective fields to the respective values. HMSET replaces old + * values with new values. + *

+ * If key does not exist, a new key holding a hash is created. + *

+ * Time complexity: O(N) (with N being the number of fields) + * + * @param key + * @param hash + * @return Always OK because HMSET can't fail + */ + public String hmset(String key, Map hash) { + checkIsInMulti(); + client.hmset(key, hash); + return client.getStatusCodeReply(); + } + + /** + * Retrieve the values associated to the specified fields. + *

+ * If some of the specified fields do not exist, nil values are returned. + * Non existing keys are considered like empty hashes. + *

+ * Time complexity: O(N) (with N being the number of fields) + * + * @param key + * @param fields + * @return Multi Bulk Reply specifically a list of all the values associated + * with the specified fields, in the same order of the request. + */ + public List hmget(String key, String... fields) { + checkIsInMulti(); + client.hmget(key, fields); + return client.getMultiBulkReply(); + } + + /** + * Increment the number stored at field in the hash at key by value. If key + * does not exist, a new key holding a hash is created. If field does not + * exist or holds a string, the value is set to 0 before applying the + * operation. Since the value argument is signed you can use this command to + * perform both increments and decrements. + *

+ * The range of values supported by HINCRBY is limited to 64 bit signed + * integers. + *

+ * Time complexity: O(1) + * + * @param key + * @param field + * @param value + * @return Integer reply The new value at field after the increment + * operation. + */ + public Integer hincrBy(String key, String field, int value) { + checkIsInMulti(); + client.hincrBy(key, field, value); + return client.getIntegerReply(); + } + + /** + * Test for existence of a specified field in a hash. + * + * Time complexity: O(1) + * + * @param key + * @param field + * @return Return 1 if the hash stored at key contains the specified field. + * Return 0 if the key is not found or the field is not present. + */ + public Integer hexists(String key, String field) { + checkIsInMulti(); + client.hexists(key, field); + return client.getIntegerReply(); + } + + /** + * Remove the specified field from an hash stored at key. + *

+ * Time complexity: O(1) + * + * @param key + * @param field + * @return If the field was present in the hash it is deleted and 1 is + * returned, otherwise 0 is returned and no operation is performed. + */ + public Integer hdel(String key, String field) { + checkIsInMulti(); + client.hdel(key, field); + return client.getIntegerReply(); + } + + /** + * Return the number of items in a hash. + *

+ * Time complexity: O(1) + * + * @param key + * @return The number of entries (fields) contained in the hash stored at + * key. If the specified key does not exist, 0 is returned assuming + * an empty hash. + */ + public Integer hlen(String key) { + checkIsInMulti(); + client.hlen(key); + return client.getIntegerReply(); + } + + /** + * Return all the fields in a hash. + *

+ * Time complexity: O(N), where N is the total number of entries + * + * @param key + * @return All the fields names contained into a hash. + */ + public List hkeys(String key) { + checkIsInMulti(); + client.hkeys(key); + return client.getMultiBulkReply(); + } + + /** + * Return all the values in a hash. + *

+ * Time complexity: O(N), where N is the total number of entries + * + * @param key + * @return All the fields values contained into a hash. + */ + public List hvals(String key) { + checkIsInMulti(); + client.hvals(key); + return client.getMultiBulkReply(); + } + + /** + * Return all the fields and associated values in a hash. + *

+ * Time complexity: O(N), where N is the total number of entries + * + * @param key + * @return All the fields and values contained into a hash. + */ + public Map hgetAll(String key) { + checkIsInMulti(); + client.hgetAll(key); + List flatHash = client.getMultiBulkReply(); + Map hash = new HashMap(); + Iterator iterator = flatHash.iterator(); + while (iterator.hasNext()) { + hash.put(iterator.next(), iterator.next()); + } + + return hash; + } + + /** + * Add the string value to the head (LPUSH) or tail (RPUSH) of the list + * stored at key. If the key does not exist an empty list is created just + * before the append operation. If the key exists but is not a List an error + * is returned. + *

+ * Time complexity: O(1) + * + * @see Jedis#lpush(String, String) + * + * @param key + * @param string + * @return Integer reply, specifically, the number of elements inside the + * list after the push operation. + */ + public Integer rpush(String key, String string) { + checkIsInMulti(); + client.rpush(key, string); + return client.getIntegerReply(); + } + + /** + * Add the string value to the head (LPUSH) or tail (RPUSH) of the list + * stored at key. If the key does not exist an empty list is created just + * before the append operation. If the key exists but is not a List an error + * is returned. + *

+ * Time complexity: O(1) + * + * @see Jedis#rpush(String, String) + * + * @param key + * @param string + * @return Integer reply, specifically, the number of elements inside the + * list after the push operation. + */ + public Integer lpush(String key, String string) { + checkIsInMulti(); + client.lpush(key, string); + return client.getIntegerReply(); + } + + /** + * Return the length of the list stored at the specified key. If the key + * does not exist zero is returned (the same behaviour as for empty lists). + * If the value stored at key is not a list an error is returned. + *

+ * Time complexity: O(1) + * + * @param key + * @return The length of the list. + */ + public Integer llen(String key) { + checkIsInMulti(); + client.llen(key); + return client.getIntegerReply(); + } + + /** + * Return the specified elements of the list stored at the specified key. + * Start and end are zero-based indexes. 0 is the first element of the list + * (the list head), 1 the next element and so on. + *

+ * For example LRANGE foobar 0 2 will return the first three elements of the + * list. + *

+ * start and end can also be negative numbers indicating offsets from the + * end of the list. For example -1 is the last element of the list, -2 the + * penultimate element and so on. + *

+ * Consistency with range functions in various programming languages + *

+ * Note that if you have a list of numbers from 0 to 100, LRANGE 0 10 will + * return 11 elements, that is, rightmost item is included. This may or may + * not be consistent with behavior of range-related functions in your + * programming language of choice (think Ruby's Range.new, Array#slice or + * Python's range() function). + *

+ * LRANGE behavior is consistent with one of Tcl. + *

+ * Out-of-range indexes + *

+ * Indexes out of range will not produce an error: if start is over the end + * of the list, or start > end, an empty list is returned. If end is over + * the end of the list Redis will threat it just like the last element of + * the list. + *

+ * Time complexity: O(start+n) (with n being the length of the range and + * start being the start offset) + * + * @param key + * @param start + * @param end + * @return Multi bulk reply, specifically a list of elements in the + * specified range. + */ + public List lrange(String key, int start, int end) { + checkIsInMulti(); + client.lrange(key, start, end); + return client.getMultiBulkReply(); + } + + /** + * Trim an existing list so that it will contain only the specified range of + * elements specified. Start and end are zero-based indexes. 0 is the first + * element of the list (the list head), 1 the next element and so on. + *

+ * For example LTRIM foobar 0 2 will modify the list stored at foobar key so + * that only the first three elements of the list will remain. + *

+ * start and end can also be negative numbers indicating offsets from the + * end of the list. For example -1 is the last element of the list, -2 the + * penultimate element and so on. + *

+ * Indexes out of range will not produce an error: if start is over the end + * of the list, or start > end, an empty list is left as value. If end over + * the end of the list Redis will threat it just like the last element of + * the list. + *

+ * Hint: the obvious use of LTRIM is together with LPUSH/RPUSH. For example: + *

+ * {@code + * lpush("mylist", "someelement"); + * ltrim("mylist", 0, 99); + * } + *

+ * The above two commands will push elements in the list taking care that + * the list will not grow without limits. This is very useful when using + * Redis to store logs for example. It is important to note that when used + * in this way LTRIM is an O(1) operation because in the average case just + * one element is removed from the tail of the list. + *

+ * Time complexity: O(n) (with n being len of list - len of range) + * + * @param key + * @param start + * @param end + * @return Status code reply + */ + public String ltrim(String key, int start, int end) { + checkIsInMulti(); + client.ltrim(key, start, end); + return client.getStatusCodeReply(); + } + + /** + * Return the specified element of the list stored at the specified key. 0 + * is the first element, 1 the second and so on. Negative indexes are + * supported, for example -1 is the last element, -2 the penultimate and so + * on. + *

+ * If the value stored at key is not of list type an error is returned. If + * the index is out of range a 'nil' reply is returned. + *

+ * Note that even if the average time complexity is O(n) asking for the + * first or the last element of the list is O(1). + *

+ * Time complexity: O(n) (with n being the length of the list) + * + * @param key + * @param index + * @return Bulk reply, specifically the requested element + */ + public String lindex(String key, int index) { + checkIsInMulti(); + client.lindex(key, index); + return client.getBulkReply(); + } + + /** + * Set a new value as the element at index position of the List at key. + *

+ * Out of range indexes will generate an error. + *

+ * Similarly to other list commands accepting indexes, the index can be + * negative to access elements starting from the end of the list. So -1 is + * the last element, -2 is the penultimate, and so forth. + *

+ * Time complexity: + *

+ * O(N) (with N being the length of the list), setting the first or last + * elements of the list is O(1). + * + * @see #lindex(String, int) + * + * @param key + * @param index + * @param value + * @return Status code reply + */ + public String lset(String key, int index, String value) { + checkIsInMulti(); + client.lset(key, index, value); + return client.getStatusCodeReply(); + } + + /** + * Remove the first count occurrences of the value element from the list. If + * count is zero all the elements are removed. If count is negative elements + * are removed from tail to head, instead to go from head to tail that is + * the normal behaviour. So for example LREM with count -2 and hello as + * value to remove against the list (a,b,c,hello,x,hello,hello) will lave + * the list (a,b,c,hello,x). The number of removed elements is returned as + * an integer, see below for more information about the returned value. Note + * that non existing keys are considered like empty lists by LREM, so LREM + * against non existing keys will always return 0. + *

+ * Time complexity: O(N) (with N being the length of the list) + * + * @param key + * @param count + * @param value + * @return Integer Reply, specifically: The number of removed elements if + * the operation succeeded + */ + public Integer lrem(String key, int count, String value) { + checkIsInMulti(); + client.lrem(key, count, value); + return client.getIntegerReply(); + } + + /** + * Atomically return and remove the first (LPOP) or last (RPOP) element of + * the list. For example if the list contains the elements "a","b","c" LPOP + * will return "a" and the list will become "b","c". + *

+ * If the key does not exist or the list is already empty the special value + * 'nil' is returned. + * + * @see #rpop(String) + * + * @param key + * @return Bulk reply + */ + public String lpop(String key) { + checkIsInMulti(); + client.lpop(key); + return client.getBulkReply(); + } + + /** + * Atomically return and remove the first (LPOP) or last (RPOP) element of + * the list. For example if the list contains the elements "a","b","c" LPOP + * will return "a" and the list will become "b","c". + *

+ * If the key does not exist or the list is already empty the special value + * 'nil' is returned. + * + * @see #lpop(String) + * + * @param key + * @return Bulk reply + */ + public String rpop(String key) { + checkIsInMulti(); + client.rpop(key); + return client.getBulkReply(); + } + + /** + * Atomically return and remove the last (tail) element of the srckey list, + * and push the element as the first (head) element of the dstkey list. For + * example if the source list contains the elements "a","b","c" and the + * destination list contains the elements "foo","bar" after an RPOPLPUSH + * command the content of the two lists will be "a","b" and "c","foo","bar". + *

+ * If the key does not exist or the list is already empty the special value + * 'nil' is returned. If the srckey and dstkey are the same the operation is + * equivalent to removing the last element from the list and pusing it as + * first element of the list, so it's a "list rotation" command. + *

+ * Time complexity: O(1) + * + * @param srckey + * @param dstkey + * @return Bulk reply + */ + public String rpoplpush(String srckey, String dstkey) { + checkIsInMulti(); + client.rpoplpush(srckey, dstkey); + return client.getBulkReply(); + } + + /** + * Add the specified member to the set value stored at key. If member is + * already a member of the set no operation is performed. If key does not + * exist a new set with the specified member as sole member is created. If + * the key exists but does not hold a set value an error is returned. + *

+ * Time complexity O(1) + * + * @param key + * @param member + * @return Integer reply, specifically: 1 if the new element was added 0 if + * the element was already a member of the set + */ + public Integer sadd(String key, String member) { + checkIsInMulti(); + client.sadd(key, member); + return client.getIntegerReply(); + } + + /** + * Return all the members (elements) of the set value stored at key. This is + * just syntax glue for {@link #sinter(String...) SINTER}. + *

+ * Time complexity O(N) + * + * @param key + * @return Multi bulk reply + */ + public Set smembers(String key) { + checkIsInMulti(); + client.smembers(key); + List members = client.getMultiBulkReply(); + return new LinkedHashSet(members); + } + + /** + * Remove the specified member from the set value stored at key. If member + * was not a member of the set no operation is performed. If key does not + * hold a set value an error is returned. + *

+ * Time complexity O(1) + * + * @param key + * @param member + * @return Integer reply, specifically: 1 if the new element was removed 0 + * if the new element was not a member of the set + */ + public Integer srem(String key, String member) { + checkIsInMulti(); + client.srem(key, member); + return client.getIntegerReply(); + } + + /** + * Remove a random element from a Set returning it as return value. If the + * Set is empty or the key does not exist, a nil object is returned. + *

+ * The {@link #srandmember(String)} command does a similar work but the + * returned element is not removed from the Set. + *

+ * Time complexity O(1) + * + * @param key + * @return Bulk reply + */ + public String spop(String key) { + checkIsInMulti(); + client.spop(key); + return client.getBulkReply(); + } + + /** + * Move the specifided member from the set at srckey to the set at dstkey. + * This operation is atomic, in every given moment the element will appear + * to be in the source or destination set for accessing clients. + *

+ * If the source set does not exist or does not contain the specified + * element no operation is performed and zero is returned, otherwise the + * element is removed from the source set and added to the destination set. + * On success one is returned, even if the element was already present in + * the destination set. + *

+ * An error is raised if the source or destination keys contain a non Set + * value. + *

+ * Time complexity O(1) + * + * @param srckey + * @param dstkey + * @param member + * @return Integer reply, specifically: 1 if the element was moved 0 if the + * element was not found on the first set and no operation was + * performed + */ + public Integer smove(String srckey, String dstkey, String member) { + checkIsInMulti(); + client.smove(srckey, dstkey, member); + return client.getIntegerReply(); + } + + /** + * Return the set cardinality (number of elements). If the key does not + * exist 0 is returned, like for empty sets. + * + * @param key + * @return Integer reply, specifically: the cardinality (number of elements) + * of the set as an integer. + */ + public Integer scard(String key) { + checkIsInMulti(); + client.scard(key); + return client.getIntegerReply(); + } + + /** + * Return 1 if member is a member of the set stored at key, otherwise 0 is + * returned. + *

+ * Time complexity O(1) + * + * @param key + * @param member + * @return Integer reply, specifically: 1 if the element is a member of the + * set 0 if the element is not a member of the set OR if the key + * does not exist + */ + public Integer sismember(String key, String member) { + checkIsInMulti(); + client.sismember(key, member); + return client.getIntegerReply(); + } + + /** + * Return the members of a set resulting from the intersection of all the + * sets hold at the specified keys. Like in + * {@link #lrange(String, int, int) LRANGE} the result is sent to the client + * as a multi-bulk reply (see the protocol specification for more + * information). If just a single key is specified, then this command + * produces the same result as {@link #smembers(String) SMEMBERS}. Actually + * SMEMBERS is just syntax sugar for SINTER. + *

+ * Non existing keys are considered like empty sets, so if one of the keys + * is missing an empty set is returned (since the intersection with an empty + * set always is an empty set). + *

+ * Time complexity O(N*M) worst case where N is the cardinality of the + * smallest set and M the number of sets + * + * @param keys + * @return Multi bulk reply, specifically the list of common elements. + */ + public Set sinter(String... keys) { + checkIsInMulti(); + client.sinter(keys); + List members = client.getMultiBulkReply(); + return new LinkedHashSet(members); + } + + /** + * This commnad works exactly like {@link #sinter(String...) SINTER} but + * instead of being returned the resulting set is sotred as dstkey. + *

+ * Time complexity O(N*M) worst case where N is the cardinality of the + * smallest set and M the number of sets + * + * @param dstkey + * @param keys + * @return Status code reply + */ + public Integer sinterstore(String dstkey, String... keys) { + checkIsInMulti(); + client.sinterstore(dstkey, keys); + return client.getIntegerReply(); + } + + /** + * Return the members of a set resulting from the union of all the sets hold + * at the specified keys. Like in {@link #lrange(String, int, int) LRANGE} + * the result is sent to the client as a multi-bulk reply (see the protocol + * specification for more information). If just a single key is specified, + * then this command produces the same result as {@link #smembers(String) + * SMEMBERS}. + *

+ * Non existing keys are considered like empty sets. + *

+ * Time complexity O(N) where N is the total number of elements in all the + * provided sets + * + * @param keys + * @return Multi bulk reply, specifically the list of common elements. + */ + public Set sunion(String... keys) { + checkIsInMulti(); + client.sunion(keys); + List members = client.getMultiBulkReply(); + return new LinkedHashSet(members); + } + + /** + * This command works exactly like {@link #sunion(String...) SUNION} but + * instead of being returned the resulting set is stored as dstkey. Any + * existing value in dstkey will be over-written. + *

+ * Time complexity O(N) where N is the total number of elements in all the + * provided sets + * + * @param dstkey + * @param keys + * @return Status code reply + */ + public Integer sunionstore(String dstkey, String... keys) { + checkIsInMulti(); + client.sunionstore(dstkey, keys); + return client.getIntegerReply(); + } + + /** + * Return the difference between the Set stored at key1 and all the Sets + * key2, ..., keyN + *

+ * Example: + * + *

+	 * key1 = [x, a, b, c]
+	 * key2 = [c]
+	 * key3 = [a, d]
+	 * SDIFF key1,key2,key3 => [x, b]
+	 * 
+ * + * Non existing keys are considered like empty sets. + *

+ * Time complexity: + *

+ * O(N) with N being the total number of elements of all the sets + * + * @param keys + * @return Return the members of a set resulting from the difference between + * the first set provided and all the successive sets. + */ + public Set sdiff(String... keys) { + checkIsInMulti(); + client.sdiff(keys); + List members = client.getMultiBulkReply(); + return new LinkedHashSet(members); + } + + /** + * This command works exactly like {@link #sdiff(String...) SDIFF} but + * instead of being returned the resulting set is stored in dstkey. + * + * @param dstkey + * @param keys + * @return Status code reply + */ + public Integer sdiffstore(String dstkey, String... keys) { + checkIsInMulti(); + client.sdiffstore(dstkey, keys); + return client.getIntegerReply(); + } + + /** + * Return a random element from a Set, without removing the element. If the + * Set is empty or the key does not exist, a nil object is returned. + *

+ * The SPOP command does a similar work but the returned element is popped + * (removed) from the Set. + *

+ * Time complexity O(1) + * + * @param key + * @return Bulk reply + */ + public String srandmember(String key) { + checkIsInMulti(); + client.srandmember(key); + return client.getBulkReply(); + } + + /** + * Add the specified member having the specifeid score to the sorted set + * stored at key. If member is already a member of the sorted set the score + * is updated, and the element reinserted in the right position to ensure + * sorting. If key does not exist a new sorted set with the specified member + * as sole member is crated. If the key exists but does not hold a sorted + * set value an error is returned. + *

+ * The score value can be the string representation of a double precision + * floating point number. + *

+ * Time complexity O(log(N)) with N being the number of elements in the + * sorted set + * + * @param key + * @param score + * @param member + * @return Integer reply, specifically: 1 if the new element was added 0 if + * the element was already a member of the sorted set and the score + * was updated + */ + public Integer zadd(String key, double score, String member) { + checkIsInMulti(); + client.zadd(key, score, member); + return client.getIntegerReply(); + } + + public Set zrange(String key, int start, int end) { + checkIsInMulti(); + client.zrange(key, start, end); + List members = client.getMultiBulkReply(); + return new LinkedHashSet(members); + } + + /** + * Remove the specified member from the sorted set value stored at key. If + * member was not a member of the set no operation is performed. If key does + * not not hold a set value an error is returned. + *

+ * Time complexity O(log(N)) with N being the number of elements in the + * sorted set + * + * + * + * @param key + * @param member + * @return Integer reply, specifically: 1 if the new element was removed 0 + * if the new element was not a member of the set + */ + public Integer zrem(String key, String member) { + checkIsInMulti(); + client.zrem(key, member); + return client.getIntegerReply(); + } + + /** + * If member already exists in the sorted set adds the increment to its + * score and updates the position of the element in the sorted set + * accordingly. If member does not already exist in the sorted set it is + * added with increment as score (that is, like if the previous score was + * virtually zero). If key does not exist a new sorted set with the + * specified member as sole member is crated. If the key exists but does not + * hold a sorted set value an error is returned. + *

+ * The score value can be the string representation of a double precision + * floating point number. It's possible to provide a negative value to + * perform a decrement. + *

+ * For an introduction to sorted sets check the Introduction to Redis data + * types page. + *

+ * Time complexity O(log(N)) with N being the number of elements in the + * sorted set + * + * @param key + * @param score + * @param member + * @return The new score + */ + public Double zincrby(String key, double score, String member) { + checkIsInMulti(); + client.zincrby(key, score, member); + String newscore = client.getBulkReply(); + return Double.valueOf(newscore); + } + + /** + * Return the rank (or index) or member in the sorted set at key, with + * scores being ordered from low to high. + *

+ * When the given member does not exist in the sorted set, the special value + * 'nil' is returned. The returned rank (or index) of the member is 0-based + * for both commands. + *

+ * Time complexity: + *

+ * O(log(N)) + * + * @see #zrevrank(String, String) + * + * @param key + * @param member + * @return Integer reply or a nil bulk reply, specifically: the rank of the + * element as an integer reply if the element exists. A nil bulk + * reply if there is no such element. + */ + public Integer zrank(String key, String member) { + checkIsInMulti(); + client.zrank(key, member); + return client.getIntegerReply(); + } + + /** + * Return the rank (or index) or member in the sorted set at key, with + * scores being ordered from high to low. + *

+ * When the given member does not exist in the sorted set, the special value + * 'nil' is returned. The returned rank (or index) of the member is 0-based + * for both commands. + *

+ * Time complexity: + *

+ * O(log(N)) + * + * @see #zrank(String, String) + * + * @param key + * @param member + * @return Integer reply or a nil bulk reply, specifically: the rank of the + * element as an integer reply if the element exists. A nil bulk + * reply if there is no such element. + */ + public Integer zrevrank(String key, String member) { + checkIsInMulti(); + client.zrevrank(key, member); + return client.getIntegerReply(); + } + + public Set zrevrange(String key, int start, int end) { + checkIsInMulti(); + client.zrevrange(key, start, end); + List members = client.getMultiBulkReply(); + return new LinkedHashSet(members); + } + + public Set zrangeWithScores(String key, int start, int end) { + checkIsInMulti(); + client.zrangeWithScores(key, start, end); + Set set = getTupledSet(); + return set; + } + + public Set zrevrangeWithScores(String key, int start, int end) { + checkIsInMulti(); + client.zrevrangeWithScores(key, start, end); + Set set = getTupledSet(); + return set; + } + + /** + * Return the sorted set cardinality (number of elements). If the key does + * not exist 0 is returned, like for empty sorted sets. + *

+ * Time complexity O(1) + * + * @param key + * @return the cardinality (number of elements) of the set as an integer. + */ + public Integer zcard(String key) { + checkIsInMulti(); + client.zcard(key); + return client.getIntegerReply(); + } + + /** + * Return the score of the specified element of the sorted set at key. If + * the specified element does not exist in the sorted set, or the key does + * not exist at all, a special 'nil' value is returned. + *

+ * Time complexity: O(1) + * + * @param key + * @param member + * @return the score + */ + public Double zscore(String key, String member) { + checkIsInMulti(); + client.zscore(key, member); + String score = client.getBulkReply(); + return (score != null ? new Double(score) : null); + } + + public Transaction multi() { + client.multi(); + client.getStatusCodeReply(); + return new Transaction(client); + } + + public List multi(TransactionBlock jedisTransaction) { + List results = null; + try { + jedisTransaction.setClient(client); + multi(); + jedisTransaction.execute(); + results = jedisTransaction.exec(); + } catch (Exception ex) { + client.discard(); + } + return results; + } + + private void checkIsInMulti() { + if (client.isInMulti()) { + throw new JedisException( + "Cannot use Jedis when in Multi. Please use JedisTransaction instead."); + } + } + + public void connect() throws UnknownHostException, IOException { + client.connect(); + } + + public void disconnect() throws IOException { + client.disconnect(); + } + + public String watch(String key) { + client.watch(key); + return client.getStatusCodeReply(); + } + + public String unwatch() { + client.unwatch(); + return client.getStatusCodeReply(); + } + + /** + * Sort a Set or a List. + *

+ * Sort the elements contained in the List, Set, or Sorted Set value at key. + * By default sorting is numeric with elements being compared as double + * precision floating point numbers. This is the simplest form of SORT. + * + * @see #sort(String, String) + * @see #sort(String, SortingParams) + * @see #sort(String, SortingParams, String) + * + * + * @param key + * @return Assuming the Set/List at key contains a list of numbers, the + * return value will be the list of numbers ordered from the + * smallest to the biggest number. + */ + public List sort(String key) { + checkIsInMulti(); + client.sort(key); + return client.getMultiBulkReply(); + } + + /** + * Sort a Set or a List accordingly to the specified parameters. + *

+ * examples: + *

+ * Given are the following sets and key/values: + * + *

+	 * x = [1, 2, 3]
+	 * y = [a, b, c]
+	 * 
+	 * k1 = z
+	 * k2 = y
+	 * k3 = x
+	 * 
+	 * w1 = 9
+	 * w2 = 8
+	 * w3 = 7
+	 * 
+ * + * Sort Order: + * + *
+	 * sort(x) or sort(x, sp.asc())
+	 * -> [1, 2, 3]
+	 * 
+	 * sort(x, sp.desc())
+	 * -> [3, 2, 1]
+	 * 
+	 * sort(y)
+	 * -> [c, a, b]
+	 * 
+	 * sort(y, sp.alpha())
+	 * -> [a, b, c]
+	 * 
+	 * sort(y, sp.alpha().desc())
+	 * -> [c, a, b]
+	 * 
+ * + * Limit (e.g. for Pagination): + * + *
+	 * sort(x, sp.limit(0, 2))
+	 * -> [1, 2]
+	 * 
+	 * sort(y, sp.alpha().desc().limit(1, 2))
+	 * -> [b, a]
+	 * 
+ * + * Sorting by external keys: + * + *
+	 * sort(x, sb.by(w*))
+	 * -> [3, 2, 1]
+	 * 
+	 * sort(x, sb.by(w*).desc())
+	 * -> [1, 2, 3]
+	 * 
+ * + * Getting external keys: + * + *
+	 * sort(x, sp.by(w*).get(k*))
+	 * -> [x, y, z]
+	 * 
+	 * sort(x, sp.by(w*).get(#).get(k*))
+	 * -> [3, x, 2, y, 1, z]
+	 * 
+ * + * @see #sort(String) + * @see #sort(String, SortingParams, String) + * + * @param key + * @param sortingParameters + * @return a list of sorted elements. + */ + public List sort(String key, SortingParams sortingParameters) { + checkIsInMulti(); + client.sort(key, sortingParameters); + return client.getMultiBulkReply(); + } + + /** + * BLPOP (and BRPOP) is a blocking list pop primitive. You can see this + * commands as blocking versions of LPOP and RPOP able to block if the + * specified keys don't exist or contain empty lists. + *

+ * The following is a description of the exact semantic. We describe BLPOP + * but the two commands are identical, the only difference is that BLPOP + * pops the element from the left (head) of the list, and BRPOP pops from + * the right (tail). + *

+ * Non blocking behavior + *

+ * When BLPOP is called, if at least one of the specified keys contain a non + * empty list, an element is popped from the head of the list and returned + * to the caller together with the name of the key (BLPOP returns a two + * elements array, the first element is the key, the second the popped + * value). + *

+ * Keys are scanned from left to right, so for instance if you issue BLPOP + * list1 list2 list3 0 against a dataset where list1 does not exist but + * list2 and list3 contain non empty lists, BLPOP guarantees to return an + * element from the list stored at list2 (since it is the first non empty + * list starting from the left). + *

+ * Blocking behavior + *

+ * If none of the specified keys exist or contain non empty lists, BLPOP + * blocks until some other client performs a LPUSH or an RPUSH operation + * against one of the lists. + *

+ * Once new data is present on one of the lists, the client finally returns + * with the name of the key unblocking it and the popped value. + *

+ * When blocking, if a non-zero timeout is specified, the client will + * unblock returning a nil special value if the specified amount of seconds + * passed without a push operation against at least one of the specified + * keys. + *

+ * The timeout argument is interpreted as an integer value. A timeout of + * zero means instead to block forever. + *

+ * Multiple clients blocking for the same keys + *

+ * Multiple clients can block for the same key. They are put into a queue, + * so the first to be served will be the one that started to wait earlier, + * in a first-blpopping first-served fashion. + *

+ * blocking POP inside a MULTI/EXEC transaction + *

+ * BLPOP and BRPOP can be used with pipelining (sending multiple commands + * and reading the replies in batch), but it does not make sense to use + * BLPOP or BRPOP inside a MULTI/EXEC block (a Redis transaction). + *

+ * The behavior of BLPOP inside MULTI/EXEC when the list is empty is to + * return a multi-bulk nil reply, exactly what happens when the timeout is + * reached. If you like science fiction, think at it like if inside + * MULTI/EXEC the time will flow at infinite speed :) + *

+ * Time complexity: O(1) + * + * @see #brpop(int, String...) + * + * @param timeout + * @param keys + * @return BLPOP returns a two-elements array via a multi bulk reply in + * order to return both the unblocking key and the popped value. + *

+ * When a non-zero timeout is specified, and the BLPOP operation + * timed out, the return value is a nil multi bulk reply. Most + * client values will return false or nil accordingly to the + * programming language used. + */ + public List blpop(int timeout, String... keys) { + checkIsInMulti(); + List args = new ArrayList(); + for (String arg : keys) { + args.add(arg); + } + args.add(String.valueOf(timeout)); + + client.blpop(args.toArray(new String[args.size()])); + client.setTimeoutInfinite(); + List multiBulkReply = client.getMultiBulkReply(); + client.rollbackTimeout(); + return multiBulkReply; + } + + /** + * Sort a Set or a List accordingly to the specified parameters and store + * the result at dstkey. + * + * @see #sort(String, SortingParams) + * @see #sort(String) + * @see #sort(String, String) + * + * @param key + * @param sortingParameters + * @param dstkey + * @return The number of elements of the list at dstkey. + */ + public Integer sort(String key, SortingParams sortingParameters, + String dstkey) { + checkIsInMulti(); + client.sort(key, sortingParameters, dstkey); + return client.getIntegerReply(); + } + + /** + * Sort a Set or a List and Store the Result at dstkey. + *

+ * Sort the elements contained in the List, Set, or Sorted Set value at key + * and store the result at dstkey. By default sorting is numeric with + * elements being compared as double precision floating point numbers. This + * is the simplest form of SORT. + * + * @see #sort(String) + * @see #sort(String, SortingParams) + * @see #sort(String, SortingParams, String) + * + * @param key + * @param dstkey + * @return The number of elements of the list at dstkey. + */ + public Integer sort(String key, String dstkey) { + checkIsInMulti(); + client.sort(key, dstkey); + return client.getIntegerReply(); + } + + /** + * BLPOP (and BRPOP) is a blocking list pop primitive. You can see this + * commands as blocking versions of LPOP and RPOP able to block if the + * specified keys don't exist or contain empty lists. + *

+ * The following is a description of the exact semantic. We describe BLPOP + * but the two commands are identical, the only difference is that BLPOP + * pops the element from the left (head) of the list, and BRPOP pops from + * the right (tail). + *

+ * Non blocking behavior + *

+ * When BLPOP is called, if at least one of the specified keys contain a non + * empty list, an element is popped from the head of the list and returned + * to the caller together with the name of the key (BLPOP returns a two + * elements array, the first element is the key, the second the popped + * value). + *

+ * Keys are scanned from left to right, so for instance if you issue BLPOP + * list1 list2 list3 0 against a dataset where list1 does not exist but + * list2 and list3 contain non empty lists, BLPOP guarantees to return an + * element from the list stored at list2 (since it is the first non empty + * list starting from the left). + *

+ * Blocking behavior + *

+ * If none of the specified keys exist or contain non empty lists, BLPOP + * blocks until some other client performs a LPUSH or an RPUSH operation + * against one of the lists. + *

+ * Once new data is present on one of the lists, the client finally returns + * with the name of the key unblocking it and the popped value. + *

+ * When blocking, if a non-zero timeout is specified, the client will + * unblock returning a nil special value if the specified amount of seconds + * passed without a push operation against at least one of the specified + * keys. + *

+ * The timeout argument is interpreted as an integer value. A timeout of + * zero means instead to block forever. + *

+ * Multiple clients blocking for the same keys + *

+ * Multiple clients can block for the same key. They are put into a queue, + * so the first to be served will be the one that started to wait earlier, + * in a first-blpopping first-served fashion. + *

+ * blocking POP inside a MULTI/EXEC transaction + *

+ * BLPOP and BRPOP can be used with pipelining (sending multiple commands + * and reading the replies in batch), but it does not make sense to use + * BLPOP or BRPOP inside a MULTI/EXEC block (a Redis transaction). + *

+ * The behavior of BLPOP inside MULTI/EXEC when the list is empty is to + * return a multi-bulk nil reply, exactly what happens when the timeout is + * reached. If you like science fiction, think at it like if inside + * MULTI/EXEC the time will flow at infinite speed :) + *

+ * Time complexity: O(1) + * + * @see #blpop(int, String...) + * + * @param timeout + * @param keys + * @return BLPOP returns a two-elements array via a multi bulk reply in + * order to return both the unblocking key and the popped value. + *

+ * When a non-zero timeout is specified, and the BLPOP operation + * timed out, the return value is a nil multi bulk reply. Most + * client values will return false or nil accordingly to the + * programming language used. + */ + public List brpop(int timeout, String... keys) { + checkIsInMulti(); + List args = new ArrayList(); + for (String arg : keys) { + args.add(arg); + } + args.add(String.valueOf(timeout)); + + client.brpop(args.toArray(new String[args.size()])); + client.setTimeoutInfinite(); + List multiBulkReply = client.getMultiBulkReply(); + client.rollbackTimeout(); + + return multiBulkReply; + } + + /** + * Request for authentication in a password protected Redis server. A Redis + * server can be instructed to require a password before to allow clients to + * issue commands. This is done using the requirepass directive in the Redis + * configuration file. If the password given by the client is correct the + * server replies with an OK status code reply and starts accepting commands + * from the client. Otherwise an error is returned and the clients needs to + * try a new password. Note that for the high performance nature of Redis it + * is possible to try a lot of passwords in parallel in very short time, so + * make sure to generate a strong and very long password so that this attack + * is infeasible. + * + * @param password + * @return Status code reply + */ + public String auth(String password) { + checkIsInMulti(); + client.auth(password); + return client.getStatusCodeReply(); + } + + public List pipelined(JedisPipeline jedisPipeline) { + jedisPipeline.setClient(client); + jedisPipeline.execute(); + return client.getAll(); + } + + public void subscribe(JedisPubSub jedisPubSub, String... channels) { + client.setTimeoutInfinite(); + jedisPubSub.proceed(client, channels); + client.rollbackTimeout(); + } + + public Integer publish(String channel, String message) { + client.publish(channel, message); + return client.getIntegerReply(); + } + + public void psubscribe(JedisPubSub jedisPubSub, String... patterns) { + client.setTimeoutInfinite(); + jedisPubSub.proceedWithPatterns(client, patterns); + client.rollbackTimeout(); + } + + public Integer zcount(String key, double min, double max) { + checkIsInMulti(); + client.zcount(key, min, max); + return client.getIntegerReply(); + } + + /** + * Return the all the elements in the sorted set at key with a score between + * min and max (including elements with score equal to min or max). + *

+ * The elements having the same score are returned sorted lexicographically + * as ASCII strings (this follows from a property of Redis sorted sets and + * does not involve further computation). + *

+ * Using the optional + * {@link #zrangeByScore(String, double, double, int, int) LIMIT} it's + * possible to get only a range of the matching elements in an SQL-alike + * way. Note that if offset is large the commands needs to traverse the list + * for offset elements and this adds up to the O(M) figure. + *

+ * The {@link #zcount(String, double, double) ZCOUNT} command is similar to + * {@link #zrangeByScore(String, double, double) ZRANGEBYSCORE} but instead + * of returning the actual elements in the specified interval, it just + * returns the number of matching elements. + *

+ * Exclusive intervals and infinity + *

+ * min and max can be -inf and +inf, so that you are not required to know + * what's the greatest or smallest element in order to take, for instance, + * elements "up to a given value". + *

+ * Also while the interval is for default closed (inclusive) it's possible + * to specify open intervals prefixing the score with a "(" character, so + * for instance: + *

+ * {@code ZRANGEBYSCORE zset (1.3 5} + *

+ * Will return all the values with score > 1.3 and <= 5, while for instance: + *

+ * {@code ZRANGEBYSCORE zset (5 (10} + *

+ * Will return all the values with score > 5 and < 10 (5 and 10 excluded). + *

+ * Time complexity: + *

+ * O(log(N))+O(M) with N being the number of elements in the sorted set and + * M the number of elements returned by the command, so if M is constant + * (for instance you always ask for the first ten elements with LIMIT) you + * can consider it O(log(N)) + * + * @see #zrangeByScore(String, double, double) + * @see #zrangeByScore(String, double, double, int, int) + * @see #zrangeByScoreWithScores(String, double, double) + * @see #zrangeByScoreWithScores(String, double, double, int, int) + * @see #zcount(String, double, double) + * + * @param key + * @param min + * @param max + * @return Multi bulk reply specifically a list of elements in the specified + * score range. + */ + public Set zrangeByScore(String key, double min, double max) { + checkIsInMulti(); + client.zrangeByScore(key, min, max); + return new LinkedHashSet(client.getMultiBulkReply()); + } + + /** + * Return the all the elements in the sorted set at key with a score between + * min and max (including elements with score equal to min or max). + *

+ * The elements having the same score are returned sorted lexicographically + * as ASCII strings (this follows from a property of Redis sorted sets and + * does not involve further computation). + *

+ * Using the optional + * {@link #zrangeByScore(String, double, double, int, int) LIMIT} it's + * possible to get only a range of the matching elements in an SQL-alike + * way. Note that if offset is large the commands needs to traverse the list + * for offset elements and this adds up to the O(M) figure. + *

+ * The {@link #zcount(String, double, double) ZCOUNT} command is similar to + * {@link #zrangeByScore(String, double, double) ZRANGEBYSCORE} but instead + * of returning the actual elements in the specified interval, it just + * returns the number of matching elements. + *

+ * Exclusive intervals and infinity + *

+ * min and max can be -inf and +inf, so that you are not required to know + * what's the greatest or smallest element in order to take, for instance, + * elements "up to a given value". + *

+ * Also while the interval is for default closed (inclusive) it's possible + * to specify open intervals prefixing the score with a "(" character, so + * for instance: + *

+ * {@code ZRANGEBYSCORE zset (1.3 5} + *

+ * Will return all the values with score > 1.3 and <= 5, while for instance: + *

+ * {@code ZRANGEBYSCORE zset (5 (10} + *

+ * Will return all the values with score > 5 and < 10 (5 and 10 excluded). + *

+ * Time complexity: + *

+ * O(log(N))+O(M) with N being the number of elements in the sorted set and + * M the number of elements returned by the command, so if M is constant + * (for instance you always ask for the first ten elements with LIMIT) you + * can consider it O(log(N)) + * + * @see #zrangeByScore(String, double, double) + * @see #zrangeByScore(String, double, double, int, int) + * @see #zrangeByScoreWithScores(String, double, double) + * @see #zrangeByScoreWithScores(String, double, double, int, int) + * @see #zcount(String, double, double) + * + * @param key + * @param min + * @param max + * @return Multi bulk reply specifically a list of elements in the specified + * score range. + */ + public Set zrangeByScore(String key, double min, double max, + int offset, int count) { + checkIsInMulti(); + client.zrangeByScore(key, min, max, offset, count); + return new LinkedHashSet(client.getMultiBulkReply()); + } + + /** + * Return the all the elements in the sorted set at key with a score between + * min and max (including elements with score equal to min or max). + *

+ * The elements having the same score are returned sorted lexicographically + * as ASCII strings (this follows from a property of Redis sorted sets and + * does not involve further computation). + *

+ * Using the optional + * {@link #zrangeByScore(String, double, double, int, int) LIMIT} it's + * possible to get only a range of the matching elements in an SQL-alike + * way. Note that if offset is large the commands needs to traverse the list + * for offset elements and this adds up to the O(M) figure. + *

+ * The {@link #zcount(String, double, double) ZCOUNT} command is similar to + * {@link #zrangeByScore(String, double, double) ZRANGEBYSCORE} but instead + * of returning the actual elements in the specified interval, it just + * returns the number of matching elements. + *

+ * Exclusive intervals and infinity + *

+ * min and max can be -inf and +inf, so that you are not required to know + * what's the greatest or smallest element in order to take, for instance, + * elements "up to a given value". + *

+ * Also while the interval is for default closed (inclusive) it's possible + * to specify open intervals prefixing the score with a "(" character, so + * for instance: + *

+ * {@code ZRANGEBYSCORE zset (1.3 5} + *

+ * Will return all the values with score > 1.3 and <= 5, while for instance: + *

+ * {@code ZRANGEBYSCORE zset (5 (10} + *

+ * Will return all the values with score > 5 and < 10 (5 and 10 excluded). + *

+ * Time complexity: + *

+ * O(log(N))+O(M) with N being the number of elements in the sorted set and + * M the number of elements returned by the command, so if M is constant + * (for instance you always ask for the first ten elements with LIMIT) you + * can consider it O(log(N)) + * + * @see #zrangeByScore(String, double, double) + * @see #zrangeByScore(String, double, double, int, int) + * @see #zrangeByScoreWithScores(String, double, double) + * @see #zrangeByScoreWithScores(String, double, double, int, int) + * @see #zcount(String, double, double) + * + * @param key + * @param min + * @param max + * @return Multi bulk reply specifically a list of elements in the specified + * score range. + */ + public Set zrangeByScoreWithScores(String key, double min, double max) { + checkIsInMulti(); + client.zrangeByScoreWithScores(key, min, max); + Set set = getTupledSet(); + return set; + } + + /** + * Return the all the elements in the sorted set at key with a score between + * min and max (including elements with score equal to min or max). + *

+ * The elements having the same score are returned sorted lexicographically + * as ASCII strings (this follows from a property of Redis sorted sets and + * does not involve further computation). + *

+ * Using the optional + * {@link #zrangeByScore(String, double, double, int, int) LIMIT} it's + * possible to get only a range of the matching elements in an SQL-alike + * way. Note that if offset is large the commands needs to traverse the list + * for offset elements and this adds up to the O(M) figure. + *

+ * The {@link #zcount(String, double, double) ZCOUNT} command is similar to + * {@link #zrangeByScore(String, double, double) ZRANGEBYSCORE} but instead + * of returning the actual elements in the specified interval, it just + * returns the number of matching elements. + *

+ * Exclusive intervals and infinity + *

+ * min and max can be -inf and +inf, so that you are not required to know + * what's the greatest or smallest element in order to take, for instance, + * elements "up to a given value". + *

+ * Also while the interval is for default closed (inclusive) it's possible + * to specify open intervals prefixing the score with a "(" character, so + * for instance: + *

+ * {@code ZRANGEBYSCORE zset (1.3 5} + *

+ * Will return all the values with score > 1.3 and <= 5, while for instance: + *

+ * {@code ZRANGEBYSCORE zset (5 (10} + *

+ * Will return all the values with score > 5 and < 10 (5 and 10 excluded). + *

+ * Time complexity: + *

+ * O(log(N))+O(M) with N being the number of elements in the sorted set and + * M the number of elements returned by the command, so if M is constant + * (for instance you always ask for the first ten elements with LIMIT) you + * can consider it O(log(N)) + * + * @see #zrangeByScore(String, double, double) + * @see #zrangeByScore(String, double, double, int, int) + * @see #zrangeByScoreWithScores(String, double, double) + * @see #zrangeByScoreWithScores(String, double, double, int, int) + * @see #zcount(String, double, double) + * + * @param key + * @param min + * @param max + * @return Multi bulk reply specifically a list of elements in the specified + * score range. + */ + public Set zrangeByScoreWithScores(String key, double min, + double max, int offset, int count) { + checkIsInMulti(); + client.zrangeByScoreWithScores(key, min, max, offset, count); + Set set = getTupledSet(); + return set; + } + + private Set getTupledSet() { + checkIsInMulti(); + List membersWithScores = client.getMultiBulkReply(); + Set set = new LinkedHashSet(); + Iterator iterator = membersWithScores.iterator(); + while (iterator.hasNext()) { + set.add(new Tuple(iterator.next(), Double.valueOf(iterator.next()))); + } + return set; + } + + /** + * Remove all elements in the sorted set at key with rank between start and + * end. Start and end are 0-based with rank 0 being the element with the + * lowest score. Both start and end can be negative numbers, where they + * indicate offsets starting at the element with the highest rank. For + * example: -1 is the element with the highest score, -2 the element with + * the second highest score and so forth. + *

+ * Time complexity: O(log(N))+O(M) with N being the number of + * elements in the sorted set and M the number of elements removed by the + * operation + * + */ + public Integer zremrangeByRank(String key, int start, int end) { + checkIsInMulti(); + client.zremrangeByRank(key, start, end); + return client.getIntegerReply(); + } + + /** + * Remove all the elements in the sorted set at key with a score between min + * and max (including elements with score equal to min or max). + *

+ * Time complexity: + *

+ * O(log(N))+O(M) with N being the number of elements in the sorted set and + * M the number of elements removed by the operation + * + * @param key + * @param start + * @param end + * @return Integer reply, specifically the number of elements removed. + */ + public Integer zremrangeByScore(String key, double start, double end) { + checkIsInMulti(); + client.zremrangeByScore(key, start, end); + return client.getIntegerReply(); + } + + /** + * Creates a union or intersection of N sorted sets given by keys k1 through + * kN, and stores it at dstkey. It is mandatory to provide the number of + * input keys N, before passing the input keys and the other (optional) + * arguments. + *

+ * As the terms imply, the {@link #zinterstore(String, String...) + * ZINTERSTORE} command requires an element to be present in each of the + * given inputs to be inserted in the result. The + * {@link #zunionstore(String, String...) ZUNIONSTORE} command inserts all + * elements across all inputs. + *

+ * Using the WEIGHTS option, it is possible to add weight to each input + * sorted set. This means that the score of each element in the sorted set + * is first multiplied by this weight before being passed to the + * aggregation. When this option is not given, all weights default to 1. + *

+ * With the AGGREGATE option, it's possible to specify how the results of + * the union or intersection are aggregated. This option defaults to SUM, + * where the score of an element is summed across the inputs where it + * exists. When this option is set to be either MIN or MAX, the resulting + * set will contain the minimum or maximum score of an element across the + * inputs where it exists. + *

+ * Time complexity: O(N) + O(M log(M)) with N being the sum of the + * sizes of the input sorted sets, and M being the number of elements in the + * resulting sorted set + * + * @see #zunionstore(String, String...) + * @see #zunionstore(String, ZParams, String...) + * @see #zinterstore(String, String...) + * @see #zinterstore(String, ZParams, String...) + * + * @param dstkey + * @param sets + * @return Integer reply, specifically the number of elements in the sorted + * set at dstkey + */ + public Integer zunionstore(String dstkey, String... sets) { + checkIsInMulti(); + client.zunionstore(dstkey, sets); + return client.getIntegerReply(); + } + + /** + * Creates a union or intersection of N sorted sets given by keys k1 through + * kN, and stores it at dstkey. It is mandatory to provide the number of + * input keys N, before passing the input keys and the other (optional) + * arguments. + *

+ * As the terms imply, the {@link #zinterstore(String, String...) + * ZINTERSTORE} command requires an element to be present in each of the + * given inputs to be inserted in the result. The + * {@link #zunionstore(String, String...) ZUNIONSTORE} command inserts all + * elements across all inputs. + *

+ * Using the WEIGHTS option, it is possible to add weight to each input + * sorted set. This means that the score of each element in the sorted set + * is first multiplied by this weight before being passed to the + * aggregation. When this option is not given, all weights default to 1. + *

+ * With the AGGREGATE option, it's possible to specify how the results of + * the union or intersection are aggregated. This option defaults to SUM, + * where the score of an element is summed across the inputs where it + * exists. When this option is set to be either MIN or MAX, the resulting + * set will contain the minimum or maximum score of an element across the + * inputs where it exists. + *

+ * Time complexity: O(N) + O(M log(M)) with N being the sum of the + * sizes of the input sorted sets, and M being the number of elements in the + * resulting sorted set + * + * @see #zunionstore(String, String...) + * @see #zunionstore(String, ZParams, String...) + * @see #zinterstore(String, String...) + * @see #zinterstore(String, ZParams, String...) + * + * @param dstkey + * @param sets + * @param params + * @return Integer reply, specifically the number of elements in the sorted + * set at dstkey + */ + public Integer zunionstore(String dstkey, ZParams params, String... sets) { + checkIsInMulti(); + client.zunionstore(dstkey, params, sets); + return client.getIntegerReply(); + } + + /** + * Creates a union or intersection of N sorted sets given by keys k1 through + * kN, and stores it at dstkey. It is mandatory to provide the number of + * input keys N, before passing the input keys and the other (optional) + * arguments. + *

+ * As the terms imply, the {@link #zinterstore(String, String...) + * ZINTERSTORE} command requires an element to be present in each of the + * given inputs to be inserted in the result. The + * {@link #zunionstore(String, String...) ZUNIONSTORE} command inserts all + * elements across all inputs. + *

+ * Using the WEIGHTS option, it is possible to add weight to each input + * sorted set. This means that the score of each element in the sorted set + * is first multiplied by this weight before being passed to the + * aggregation. When this option is not given, all weights default to 1. + *

+ * With the AGGREGATE option, it's possible to specify how the results of + * the union or intersection are aggregated. This option defaults to SUM, + * where the score of an element is summed across the inputs where it + * exists. When this option is set to be either MIN or MAX, the resulting + * set will contain the minimum or maximum score of an element across the + * inputs where it exists. + *

+ * Time complexity: O(N) + O(M log(M)) with N being the sum of the + * sizes of the input sorted sets, and M being the number of elements in the + * resulting sorted set + * + * @see #zunionstore(String, String...) + * @see #zunionstore(String, ZParams, String...) + * @see #zinterstore(String, String...) + * @see #zinterstore(String, ZParams, String...) + * + * @param dstkey + * @param sets + * @return Integer reply, specifically the number of elements in the sorted + * set at dstkey + */ + public Integer zinterstore(String dstkey, String... sets) { + checkIsInMulti(); + client.zinterstore(dstkey, sets); + return client.getIntegerReply(); + } + + /** + * Creates a union or intersection of N sorted sets given by keys k1 through + * kN, and stores it at dstkey. It is mandatory to provide the number of + * input keys N, before passing the input keys and the other (optional) + * arguments. + *

+ * As the terms imply, the {@link #zinterstore(String, String...) + * ZINTERSTORE} command requires an element to be present in each of the + * given inputs to be inserted in the result. The + * {@link #zunionstore(String, String...) ZUNIONSTORE} command inserts all + * elements across all inputs. + *

+ * Using the WEIGHTS option, it is possible to add weight to each input + * sorted set. This means that the score of each element in the sorted set + * is first multiplied by this weight before being passed to the + * aggregation. When this option is not given, all weights default to 1. + *

+ * With the AGGREGATE option, it's possible to specify how the results of + * the union or intersection are aggregated. This option defaults to SUM, + * where the score of an element is summed across the inputs where it + * exists. When this option is set to be either MIN or MAX, the resulting + * set will contain the minimum or maximum score of an element across the + * inputs where it exists. + *

+ * Time complexity: O(N) + O(M log(M)) with N being the sum of the + * sizes of the input sorted sets, and M being the number of elements in the + * resulting sorted set + * + * @see #zunionstore(String, String...) + * @see #zunionstore(String, ZParams, String...) + * @see #zinterstore(String, String...) + * @see #zinterstore(String, ZParams, String...) + * + * @param dstkey + * @param sets + * @param params + * @return Integer reply, specifically the number of elements in the sorted + * set at dstkey + */ + public Integer zinterstore(String dstkey, ZParams params, String... sets) { + checkIsInMulti(); + client.zinterstore(dstkey, params, sets); + return client.getIntegerReply(); + } + + /** + * Synchronously save the DB on disk. + *

+ * Save the whole dataset on disk (this means that all the databases are + * saved, as well as keys with an EXPIRE set (the expire is preserved). The + * server hangs while the saving is not completed, no connection is served + * in the meanwhile. An OK code is returned when the DB was fully stored in + * disk. + *

+ * The background variant of this command is {@link #bgsave() BGSAVE} that + * is able to perform the saving in the background while the server + * continues serving other clients. + *

+ * + * @return Status code reply + */ + public String save() { + client.save(); + return client.getStatusCodeReply(); + } + + /** + * Asynchronously save the DB on disk. + *

+ * Save the DB in background. The OK code is immediately returned. Redis + * forks, the parent continues to server the clients, the child saves the DB + * on disk then exit. A client my be able to check if the operation + * succeeded using the LASTSAVE command. + * + * @return Status code reply + */ + public String bgsave() { + client.bgsave(); + return client.getStatusCodeReply(); + } + + /** + * Rewrite the append only file in background when it gets too big. Please + * for detailed information about the Redis Append Only File check the Append + * Only File Howto. + *

+ * BGREWRITEAOF rewrites the Append Only File in background when it gets too + * big. The Redis Append Only File is a Journal, so every operation + * modifying the dataset is logged in the Append Only File (and replayed at + * startup). This means that the Append Only File always grows. In order to + * rebuild its content the BGREWRITEAOF creates a new version of the append + * only file starting directly form the dataset in memory in order to + * guarantee the generation of the minimal number of commands needed to + * rebuild the database. + *

+ * + * @return Status code reply + */ + public String bgrewriteaof() { + client.bgrewriteaof(); + return client.getStatusCodeReply(); + } + + /** + * Return the UNIX time stamp of the last successfully saving of the dataset + * on disk. + *

+ * Return the UNIX TIME of the last DB save executed with success. A client + * may check if a {@link #bgsave() BGSAVE} command succeeded reading the + * LASTSAVE value, then issuing a BGSAVE command and checking at regular + * intervals every N seconds if LASTSAVE changed. + * + * @return Integer reply, specifically an UNIX time stamp. + */ + public Integer lastsave() { + client.lastsave(); + return client.getIntegerReply(); + } + + /** + * Synchronously save the DB on disk, then shutdown the server. + *

+ * Stop all the clients, save the DB, then quit the server. This commands + * makes sure that the DB is switched off without the lost of any data. This + * is not guaranteed if the client uses simply {@link #save() SAVE} and then + * {@link #quit() QUIT} because other clients may alter the DB data between + * the two commands. + * + * @return Status code reply on error. On success nothing is returned since + * the server quits and the connection is closed. + */ + public String shutdown() { + client.shutdown(); + String status = null; + try { + status = client.getStatusCodeReply(); + } catch (JedisException ex) { + status = null; + } + return status; + } + + /** + * Provide information and statistics about the server. + *

+ * The info command returns different information and statistics about the + * server in an format that's simple to parse by computers and easy to read + * by humans. + *

+ * Format of the returned String: + *

+ * All the fields are in the form field:value + * + *

+	 * edis_version:0.07
+	 * connected_clients:1
+	 * connected_slaves:0
+	 * used_memory:3187
+	 * changes_since_last_save:0
+	 * last_save_time:1237655729
+	 * total_connections_received:1
+	 * total_commands_processed:1
+	 * uptime_in_seconds:25
+	 * uptime_in_days:0
+	 * 
+ * + * Notes + *

+ * used_memory is returned in bytes, and is the total number of bytes + * allocated by the program using malloc. + *

+ * uptime_in_days is redundant since the uptime in seconds contains already + * the full uptime information, this field is only mainly present for + * humans. + *

+ * changes_since_last_save does not refer to the number of key changes, but + * to the number of operations that produced some kind of change in the + * dataset. + *

+ * + * @return Bulk reply + */ + public String info() { + client.info(); + return client.getBulkReply(); + } + + /** + * Dump all the received requests in real time. + *

+ * MONITOR is a debugging command that outputs the whole sequence of + * commands received by the Redis server. is very handy in order to + * understand what is happening into the database. This command is used + * directly via telnet. + * + * @param jedisMonitor + */ + public void monitor(JedisMonitor jedisMonitor) { + client.monitor(); + jedisMonitor.proceed(client); + } + + /** + * Change the replication settings. + *

+ * The SLAVEOF command can change the replication settings of a slave on the + * fly. If a Redis server is arleady acting as slave, the command SLAVEOF NO + * ONE will turn off the replicaiton turning the Redis server into a MASTER. + * In the proper form SLAVEOF hostname port will make the server a slave of + * the specific server listening at the specified hostname and port. + *

+ * If a server is already a slave of some master, SLAVEOF hostname port will + * stop the replication against the old server and start the + * synchrnonization against the new one discarding the old dataset. + *

+ * The form SLAVEOF no one will stop replication turning the server into a + * MASTER but will not discard the replication. So if the old master stop + * working it is possible to turn the slave into a master and set the + * application to use the new master in read/write. Later when the other + * Redis server will be fixed it can be configured in order to work as + * slave. + *

+ * + * @param host + * @param port + * @return Status code reply + */ + public String slaveof(String host, int port) { + client.slaveof(host, port); + return client.getStatusCodeReply(); + } + + public String slaveofNoOne() { + client.slaveofNoOne(); + return client.getStatusCodeReply(); + } + + /** + * Retrieve the configuration of a running Redis server. Not all the + * configuration parameters are supported. + *

+ * CONFIG GET returns the current configuration parameters. This sub command + * only accepts a single argument, that is glob style pattern. All the + * configuration parameters matching this parameter are reported as a list + * of key-value pairs. + *

+ * Example: + * + *

+	 * $ redis-cli config get '*'
+	 * 1. "dbfilename"
+	 * 2. "dump.rdb"
+	 * 3. "requirepass"
+	 * 4. (nil)
+	 * 5. "masterauth"
+	 * 6. (nil)
+	 * 7. "maxmemory"
+	 * 8. "0\n"
+	 * 9. "appendfsync"
+	 * 10. "everysec"
+	 * 11. "save"
+	 * 12. "3600 1 300 100 60 10000"
+	 * 
+	 * $ redis-cli config get 'm*'
+	 * 1. "masterauth"
+	 * 2. (nil)
+	 * 3. "maxmemory"
+	 * 4. "0\n"
+	 * 
+ * + * @param pattern + * @return Bulk reply. + */ + public List configGet(String pattern) { + client.configGet(pattern); + return client.getMultiBulkReply(); + } + + /** + * Alter the configuration of a running Redis server. Not all the + * configuration parameters are supported. + *

+ * The list of configuration parameters supported by CONFIG SET can be + * obtained issuing a {@link #configGet(String) CONFIG GET *} command. + *

+ * The configuration set using CONFIG SET is immediately loaded by the Redis + * server that will start acting as specified starting from the next + * command. + *

+ * + * Parameters value format + *

+ * The value of the configuration parameter is the same as the one of the + * same parameter in the Redis configuration file, with the following + * exceptions: + *

+ *

    + *
  • The save paramter is a list of space-separated integers. Every pair + * of integers specify the time and number of changes limit to trigger a + * save. For instance the command CONFIG SET save "3600 10 60 10000" will + * configure the server to issue a background saving of the RDB file every + * 3600 seconds if there are at least 10 changes in the dataset, and every + * 60 seconds if there are at least 10000 changes. To completely disable + * automatic snapshots just set the parameter as an empty string. + *
  • All the integer parameters representing memory are returned and + * accepted only using bytes as unit. + *
+ * + * @param parameter + * @param value + * @return Status code reply + */ + public String configSet(String parameter, String value) { + client.configSet(parameter, value); + return client.getStatusCodeReply(); + } + + public boolean isConnected() { + return client.isConnected(); + } + + public Integer strlen(String key) { + client.strlen(key); + return client.getIntegerReply(); + } + + public void sync() { + client.sync(); + } + + public Integer lpushx(String key, String string) { + client.lpushx(key, string); + return client.getIntegerReply(); + } + + /** + * Undo a {@link #expire(String, int) expire} at turning the expire key into + * a normal key. + *

+ * Time complexity: O(1) + * + * @param key + * @return Integer reply, specifically: 1: the key is now persist. 0: the + * key is not persist (only happens when key not set). + */ + public Integer persist(String key) { + client.persist(key); + return client.getIntegerReply(); + } + + public Integer rpushx(String key, String string) { + client.rpushx(key, string); + return client.getIntegerReply(); + } + + public String echo(String string) { + client.echo(string); + return client.getBulkReply(); + } + + public Integer linsert(String key, LIST_POSITION where, String pivot, + String value) { + client.linsert(key, where, pivot, value); + return client.getIntegerReply(); + } + + public String debug(DebugParams params) { + client.debug(params); + return client.getStatusCodeReply(); + } } \ No newline at end of file diff --git a/src/main/java/redis/clients/jedis/SortingParams.java b/src/main/java/redis/clients/jedis/SortingParams.java index 35f3712..fef950d 100644 --- a/src/main/java/redis/clients/jedis/SortingParams.java +++ b/src/main/java/redis/clients/jedis/SortingParams.java @@ -5,46 +5,115 @@ import java.util.Collection; import java.util.Collections; import java.util.List; +/** + * Builder Class for {@link Jedis#sort(String, SortingParams) SORT} Parameters. + * + */ public class SortingParams { - private List params = new ArrayList(); + private List params = new ArrayList(); - public SortingParams by(String pattern) { - params.add("BY"); - params.add(pattern); - return this; - } - - public Collection getParams() { - return Collections.unmodifiableCollection(params); - } - - public SortingParams desc() { - params.add("DESC"); - return this; - } - - public SortingParams asc() { - params.add("ASC"); - return this; - } - - public SortingParams limit(int start, int count) { - params.add("LIMIT"); - params.add(String.valueOf(start)); - params.add(String.valueOf(count)); - return this; - } - - public SortingParams alpha() { - params.add("ALPHA"); - return this; - } - - public SortingParams get(String... patterns) { - for (String pattern : patterns) { - params.add("GET"); - params.add(pattern); + /** + * Sort by weight in keys. + *

+ * Takes a pattern that is used in order to generate the key names of the + * weights used for sorting. Weight key names are obtained substituting the + * first occurrence of * with the actual value of the elements on the list. + *

+ * The pattern for a normal key/value pair is "keyname*" and for a value in + * a hash "keyname*->fieldname". + * + * @param pattern + * @return the SortingParams Object + */ + public SortingParams by(String pattern) { + params.add("BY"); + params.add(pattern); + return this; + } + + /** + * No sorting. + *

+ * This is useful if you want to retrieve a external key (using + * {@link #get(String...) GET}) but you don't want the sorting overhead. + * + * @return the SortingParams Object + */ + public SortingParams nosort() { + params.add("BY nosort"); + return this; + } + + public Collection getParams() { + return Collections.unmodifiableCollection(params); + } + + /** + * Get the Sorting in Descending Order. + * + * @return the sortingParams Object + */ + public SortingParams desc() { + params.add("DESC"); + return this; + } + + /** + * Get the Sorting in Ascending Order. This is the default order. + * + * @return the SortingParams Object + */ + public SortingParams asc() { + params.add("ASC"); + return this; + } + + /** + * Limit the Numbers of returned Elements. + * + * @param start + * is zero based + * @param count + * @return the SortingParams Object + */ + public SortingParams limit(int start, int count) { + params.add("LIMIT"); + params.add(String.valueOf(start)); + params.add(String.valueOf(count)); + return this; + } + + /** + * Sort lexicographicaly. Note that Redis is utf-8 aware assuming you set + * the right value for the LC_COLLATE environment variable. + * + * @return the SortingParams Object + */ + public SortingParams alpha() { + params.add("ALPHA"); + return this; + } + + /** + * Retrieving external keys from the result of the search. + *

+ * Takes a pattern that is used in order to generate the key names of the + * result of sorting. The key names are obtained substituting the + * first occurrence of * with the actual value of the elements on the list. + *

+ * The pattern for a normal key/value pair is "keyname*" and for a value in + * a hash "keyname*->fieldname". + *

+ * To get the list itself use the char # as pattern. + * + * @param patterns + * @return the SortingParams Object + */ + public SortingParams get(String... patterns) { + for (String pattern : patterns) { + params.add("GET"); + params.add(pattern); + } + return this; } - return this; - } } \ No newline at end of file