Sabari Krishnan M
Sabari Krishnan M

Reputation: 151

Is there a way to pass redis commands in jedis, without using the functions?

We are trying to build a console to process redis queries. But, in the back end we need to use Jedis. So, the commands, given as the inputs needs to be processed using Jedis. For example, in redis-cli, we use " keys * ". For the same we use jedis.keys(" * ") in Jedis. I have no idea, how to convert " keys * " into jedis.keys(" * "). Kindly tell me some suggestions....

Upvotes: 2

Views: 3425

Answers (3)

Antony Nguyen
Antony Nguyen

Reputation: 179

I know this is an old question, but hopefully the following will be useful for others.

Here's something I came up with as the most recent version of Jedis (3.2.0 as of this time) did not support the "memory usage " command which is available on Redis >= 4. This code assumes a Jedis object has been created, probably from a Jedis resource pool:

import redis.clients.jedis.util.SafeEncoder;
// ... Jedis setup code ...
byteSize = (Long) jedis.sendCommand(new ProtocolCommand() {
                                        @Override
                                        public byte[] getRaw() {
                                          return SafeEncoder.encode("memory");
                                        }}, 
                                    SafeEncoder.encode("usage"), 
                                    SafeEncoder.encode(key));

This is a special case command as it has a primary keyword memory with a secondary action usage (other ones are doctor, stats, purge, etc). When sending multi-keyword commands to Redis, the keywords must be treated as a list. My first attempt at specifying memory usage as a single argument failed with a Redis server error.

Subsequently, it seems the current Jedis implementation is geared toward single keyword commands, as underneath the hood there's a bunch of special code to deal with multi-keyword commands such as debug object that doesn't quite fit the original command keyword framework.

Anyway, once my current project that required the ability to call memory usage is complete, I'll try my hand at providing a patch to the Jedis maintainer to implement the above command in a more official/conventional way, which would look something like:

Long byteSize = jedis.memoryUsage(key);

Finally, to address your specific need, you're best bet is to use the scan() method of the Jedis class. There are articles here on SO that explain how to use the scan() method.

Upvotes: 3

Sabari Krishnan M
Sabari Krishnan M

Reputation: 151

I have found a way for this. There is a function named eval(). We can use that for this as shown below.

`Scanner s=new Scanner(System.in);String query=s.nextLine();
 String[] q=query.split(" ");
 String cmd='\''+q[0]+'\'';
 for(int i=1;i<q.length;i++)
 cmd+=",\'"+q[i]+'\'';
 System.out.println(j.eval("return redis.call("+cmd+")"));`

Upvotes: 1

yeahseol
yeahseol

Reputation: 385

Hmm...You can make the same thing by referring to the following.
redis.clients.jedis.Connection.sendCommand(Command, String...)
Create a class extend Connection.
Create a class extend Connection instance and call the connect() method.
Call super.sendCommand(Protocol.Command.valueOf(args[0].toUpperCase()), args[1~end]).
example for you:

public class JedisConn extends Connection {

    public JedisConn(String host, int port) {

        super(host, port);
    }

    @Override
    protected Connection sendCommand(final Protocol.Command cmd, final String... args) {
        return super.sendCommand(cmd, args);
    }


    public static void main(String[] args) {

        JedisConn jedisConn = new JedisConn("host", 6379);
        jedisConn.connect();

        Connection connection = jedisConn.sendCommand(Protocol.Command.valueOf(args[0].toUpperCase()),  Arrays.copyOfRange(args, 1, args.length));
        System.out.println(connection.getAll());
        jedisConn.close();
    }
}

Haha~~

Upvotes: 1

Related Questions