From 4636511bf32383cb7fc2b7d62ae3139cf97b28e4 Mon Sep 17 00:00:00 2001 From: Clement Escoffier Date: Thu, 15 Dec 2022 11:39:57 +0100 Subject: [PATCH] With the latest Redis release, the geo commands may return doubles containing un-parseable characters. This is due to an optimization (https://github.com/redis/redis/pull/11552/files) added in the Redis:7 stream. (cherry picked from commit df5d507c940963fa10445f115f25179fcfc7d305) --- .../datasource/AbstractGeoCommands.java | 42 ++++++++++++------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/AbstractGeoCommands.java b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/AbstractGeoCommands.java index 9550a98db6542..04367f7dfb73a 100644 --- a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/AbstractGeoCommands.java +++ b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/AbstractGeoCommands.java @@ -12,6 +12,7 @@ import java.util.OptionalDouble; import java.util.OptionalLong; import java.util.Set; +import java.util.regex.Pattern; import io.quarkus.redis.datasource.codecs.Codec; import io.quarkus.redis.datasource.codecs.Codecs; @@ -34,6 +35,8 @@ class AbstractGeoCommands extends AbstractRedisCommands { protected final Codec keyCodec; protected final Codec valueCodec; + private static final Pattern NOISE_REMOVER_PATTERN = Pattern.compile("[^a-zA-Z0-9\\.]"); + AbstractGeoCommands(RedisCommandExecutor redis, Class k, Class v) { super(redis, new Marshaller(k, v)); this.typeOfValue = v; @@ -233,7 +236,7 @@ Double decodeDistance(Response r) { if (r == null) { return null; } - return r.toDouble(); + return parseDouble(r); } List decodeGeoPositions(Response response) { @@ -241,7 +244,7 @@ List decodeGeoPositions(Response response) { if (nested == null) { return null; } else { - return GeoPosition.of(nested.get(0).toDouble(), nested.get(1).toDouble()); + return GeoPosition.of(parseDouble(nested.get(0)), parseDouble(nested.get(1))); } }); } @@ -261,33 +264,33 @@ List> decodeAsListOfGeoValues(Response r, boolean withDistance, bool V member = marshaller.decode(typeOfValue, response.get(0)); if (withCoordinates && withDistance && withHash) { - double dist = response.get(1).toDouble(); + double dist = parseDouble(response.get(1)); long hash = response.get(2).toLong(); - double longitude = response.get(3).get(0).toDouble(); - double latitude = response.get(3).get(1).toDouble(); + double longitude = parseDouble(response.get(3).get(0)); + double latitude = parseDouble(response.get(3).get(1)); list.add(new GeoValue<>(member, OptionalDouble.of(dist), OptionalLong.of(hash), OptionalDouble.of(longitude), OptionalDouble.of(latitude))); } else if (withCoordinates && withDistance) { - double dist = response.get(1).toDouble(); - double longitude = response.get(2).get(0).toDouble(); - double latitude = response.get(2).get(1).toDouble(); + double dist = parseDouble(response.get(1)); + double longitude = parseDouble(response.get(2).get(0)); + double latitude = parseDouble(response.get(2).get(1)); list.add(new GeoValue<>(member, OptionalDouble.of(dist), OptionalLong.empty(), OptionalDouble.of(longitude), OptionalDouble.of(latitude))); } else if (withCoordinates && withHash) { long hash = response.get(1).toLong(); - double longitude = response.get(2).get(0).toDouble(); - double latitude = response.get(2).get(1).toDouble(); + double longitude = parseDouble(response.get(2).get(0)); + double latitude = parseDouble(response.get(2).get(1)); list.add(new GeoValue<>(member, OptionalDouble.empty(), OptionalLong.of(hash), OptionalDouble.of(longitude), OptionalDouble.of(latitude))); } else if (withCoordinates) { // Only coordinates - double longitude = response.get(1).get(0).toDouble(); - double latitude = response.get(1).get(1).toDouble(); + double longitude = parseDouble(response.get(1).get(0)); + double latitude = parseDouble(response.get(1).get(1)); list.add(new GeoValue<>(member, OptionalDouble.empty(), OptionalLong.empty(), OptionalDouble.of(longitude), OptionalDouble.of(latitude))); } else if (withDistance && !withHash) { // Only distance - double dist = response.get(1).toDouble(); + double dist = parseDouble(response.get(1)); list.add(new GeoValue<>(member, OptionalDouble.of(dist), OptionalLong.empty(), OptionalDouble.empty(), OptionalDouble.empty())); } else if (!withDistance) { @@ -297,7 +300,7 @@ List> decodeAsListOfGeoValues(Response r, boolean withDistance, bool OptionalDouble.empty())); } else { // Distance and Hash - double dist = response.get(1).toDouble(); + double dist = parseDouble(response.get(1)); long hash = response.get(2).toLong(); list.add(new GeoValue<>(member, OptionalDouble.of(dist), OptionalLong.of(hash), OptionalDouble.empty(), OptionalDouble.empty())); @@ -305,4 +308,15 @@ List> decodeAsListOfGeoValues(Response r, boolean withDistance, bool } return list; } + + private static double parseDouble(Response response) { + double dist; + try { + dist = response.toDouble(); + } catch (NumberFormatException e) { + String s = NOISE_REMOVER_PATTERN.matcher(response.toString()).replaceAll(""); + dist = Double.parseDouble(s); + } + return dist; + } }