/** * Read a simple or bulk string response from the server, throwing an exception if the result is * not one of those two types. * * <p>This is a blocking operation. * * @return The response as a string * @throws BajaTypeMismatchException If the response was not a simple or bulk string * @throws BajaResourceException If there was an error reading from the stream * @throws BajaProtocolErrorException If the server responded with an error result */ public String readSimpleOrBulkString() { final Set<RespType> expected = new HashSet<>(); expected.add(RespType.BULK_STRING); expected.add(RespType.SIMPLE_STRING); final RespType type = verifyResponseType(expected); if (type == RespType.BULK_STRING) { return IOFunction.runCommand(() -> parser.readBulkString(inputStream)); } return IOFunction.runCommand(() -> parser.readSimpleString(inputStream)); }
// VisibleForTesting RespType verifyResponseType(Set<RespType> expected) { final RespType type = IOFunction.runCommand(() -> parser.findType(inputStream)); if (type == RespType.ERROR) { final RespErrResponse err = IOFunction.runCommand(() -> parser.readError(inputStream)); throw new BajaProtocolErrorException(err.getMessage()); } if (!expected.contains(type)) { throw new BajaTypeMismatchException( "Unexpected type. Expected one of " + expected + ", got " + type); } return type; }
static <R> R runCommand(IOFunction<R> func) { try { return func.call(); } catch (IOException e) { throw new BajaResourceException(e); } }
/** * Read an "array" response from the server and convert each entry to a string using the default * string representation ({@link String#valueOf}), throwing an exception if the result is not an * array type. * * <p>Null values in the array will be preserved as {@code null}s. * * <p>This is a blocking operation. * * @return The response as a {@code List} of strings * @throws BajaTypeMismatchException If the response was not an array * @throws BajaResourceException If there was an error reading from the stream * @throws BajaProtocolErrorException If the server responded with an error result */ public List<String> readStringArray() { verifyResponseType(Collections.singleton(RespType.ARRAY)); return IOFunction.runCommand(() -> parser.readArray(inputStream)) .stream() .map(i -> i == null ? null : String.valueOf(i)) .collect(Collectors.toList()); }
/** * Encode and send multiple commands and arguments to the Redis Server * * <p>This is a blocking operation. * * @param commands Multiple commands and associated arguments to send as strings * @return fluent interface * @throws BajaResourceException If there was an error writing to the output stream */ public RedisConnection writeMultiCommand(List<List<String>> commands) { IOFunction.runCommand( () -> { outputStream.write(encoder.encodeMulti(Objects.requireNonNull(commands))); return null; }); return this; }
/** * Read any type of response from the server, throwing an exception if the result is an Redis * error. * * <p>This might be useful for Redis commands that return different types based on the arguments * supplied to them. In this case, the caller will have to inspect the type of the result * afterwards to determine the appropriate course of action. * * <p>This is a blocking operation. * * @return The response as an Object * @throws BajaResourceException If there was an error reading from the stream * @throws BajaProtocolErrorException If the server responded with an error result */ public Object readAnyType() { final Set<RespType> expected = new HashSet<>(); expected.add(RespType.BULK_STRING); expected.add(RespType.SIMPLE_STRING); expected.add(RespType.INTEGER); expected.add(RespType.ARRAY); final RespType type = verifyResponseType(expected); switch (type) { case BULK_STRING: return IOFunction.runCommand(() -> parser.readBulkString(inputStream)); case SIMPLE_STRING: return IOFunction.runCommand(() -> parser.readSimpleString(inputStream)); case INTEGER: return IOFunction.runCommand(() -> parser.readLong(inputStream)); case ARRAY: return IOFunction.runCommand(() -> parser.readArray(inputStream)); } throw new IllegalStateException("Got unexpected result type " + type); }
/** * Read an "array" response from the server, throwing an exception if the result is not an array * type. * * <p>It is the responsibility of the caller to know the expected types of each entry in the list. * * <p>This is a blocking operation. * * @return The response as a {@code List} of objects * @throws BajaTypeMismatchException If the response was not an array * @throws BajaResourceException If there was an error reading from the stream * @throws BajaProtocolErrorException If the server responded with an error result */ public List<Object> readArray() { verifyResponseType(Collections.singleton(RespType.ARRAY)); return IOFunction.runCommand(() -> parser.readArray(inputStream)); }
/** * Read a 64 bit integer response from the server, throwing an exception if the result is not a 64 * bit integer type. * * <p>This is a blocking operation. * * @return The response as a {@code long} * @throws BajaTypeMismatchException If the response was not a 64 bit integer * @throws BajaResourceException If there was an error reading from the stream * @throws BajaProtocolErrorException If the server responded with an error result */ public long readLong() { verifyResponseType(Collections.singleton(RespType.INTEGER)); return IOFunction.runCommand(() -> parser.readLong(inputStream)); }
/** * Read a bulk string response from the server, throwing an exception if the response is not a * bulk string type. * * <p>This is a blocking operation. * * @return The response as a string * @throws BajaTypeMismatchException If the response was not a bulk string * @throws BajaResourceException If there was an error reading from the stream * @throws BajaProtocolErrorException If the server responded with an error result */ public String readBulkString() { verifyResponseType(Collections.singleton(RespType.BULK_STRING)); return IOFunction.runCommand(() -> parser.readBulkString(inputStream)); }