Skip to content

Commit

Permalink
JsonType introduced to help typization
Browse files Browse the repository at this point in the history
  • Loading branch information
tishun committed Sep 2, 2024
1 parent fb8a5c2 commit 71ff72a
Show file tree
Hide file tree
Showing 15 changed files with 158 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import io.lettuce.core.codec.Base16;
import io.lettuce.core.codec.RedisCodec;
import io.lettuce.core.internal.LettuceAssert;
import io.lettuce.core.json.JsonType;
import io.lettuce.core.json.JsonValue;
import io.lettuce.core.json.arguments.JsonGetArgs;
import io.lettuce.core.json.arguments.JsonMsetArgs;
Expand Down Expand Up @@ -1558,7 +1559,7 @@ public RedisFuture<List<Long>> jsonToggle(K key, JsonPath jsonPath) {
}

@Override
public RedisFuture<List<V>> jsonType(K key, JsonPath jsonPath) {
public RedisFuture<List<JsonType>> jsonType(K key, JsonPath jsonPath) {
return dispatch(jsonCommandBuilder.jsonType(key, jsonPath));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import io.lettuce.core.codec.RedisCodec;
import io.lettuce.core.internal.LettuceAssert;
import io.lettuce.core.json.JsonPath;
import io.lettuce.core.json.JsonType;
import io.lettuce.core.json.JsonValue;
import io.lettuce.core.json.arguments.JsonGetArgs;
import io.lettuce.core.json.arguments.JsonMsetArgs;
Expand Down Expand Up @@ -1621,7 +1622,7 @@ public Flux<Long> jsonToggle(K key, JsonPath jsonPath) {
}

@Override
public Flux<V> jsonType(K key, JsonPath jsonPath) {
public Flux<JsonType> jsonType(K key, JsonPath jsonPath) {
return createDissolvingFlux(() -> jsonCommandBuilder.jsonType(key, jsonPath));
}

Expand Down
5 changes: 3 additions & 2 deletions src/main/java/io/lettuce/core/RedisJsonCommandBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
package io.lettuce.core;

import io.lettuce.core.codec.RedisCodec;
import io.lettuce.core.json.JsonType;
import io.lettuce.core.json.JsonValue;
import io.lettuce.core.json.arguments.JsonGetArgs;
import io.lettuce.core.json.arguments.JsonMsetArgs;
Expand Down Expand Up @@ -309,7 +310,7 @@ Command<K, V, Long> jsonDel(K key, JsonPath jsonPath) {
return createCommand(JSON_DEL, new IntegerOutput<>(codec), args);
}

Command<K, V, List<V>> jsonType(K key, JsonPath jsonPath) {
Command<K, V, List<JsonType>> jsonType(K key, JsonPath jsonPath) {
notNullKey(key);

CommandArgs<K, V> args = new CommandArgs<>(codec).addKey(key);
Expand All @@ -318,7 +319,7 @@ Command<K, V, List<V>> jsonType(K key, JsonPath jsonPath) {
args.add(jsonPath.toString());
}

return createCommand(JSON_TYPE, new ValueListOutput<>(codec), args);
return createCommand(JSON_TYPE, new JsonTypeListOutput<>(codec), args);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import java.util.List;
import io.lettuce.core.RedisFuture;
import io.lettuce.core.json.JsonPath;
import io.lettuce.core.json.JsonType;
import io.lettuce.core.json.JsonValue;
import io.lettuce.core.json.arguments.JsonGetArgs;
import io.lettuce.core.json.arguments.JsonMsetArgs;
Expand Down Expand Up @@ -207,7 +208,7 @@ public interface RedisJsonAsyncCommands<K, V> {
*
* @param key the key holding the JSON document.
* @param jsonPath the {@link JsonPath} pointing to the value(s) whose key(s) we want.
* @return List<K> the keys in the JSON document that are referenced by the given {@link JsonPath}.
* @return List<V> the keys in the JSON document that are referenced by the given {@link JsonPath}.
* @since 6.5
*/
RedisFuture<List<V>> jsonObjkeys(K key, JsonPath jsonPath);
Expand Down Expand Up @@ -282,6 +283,6 @@ public interface RedisJsonAsyncCommands<K, V> {
* @return List<JsonType> the type of JSON value at the provided {@link JsonPath}
* @since 6.5
*/
RedisFuture<List<V>> jsonType(K key, JsonPath jsonPath);
RedisFuture<List<JsonType>> jsonType(K key, JsonPath jsonPath);

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import java.util.List;
import io.lettuce.core.json.JsonPath;
import io.lettuce.core.json.JsonType;
import io.lettuce.core.json.JsonValue;
import io.lettuce.core.json.arguments.JsonGetArgs;
import io.lettuce.core.json.arguments.JsonMsetArgs;
Expand Down Expand Up @@ -208,7 +209,7 @@ public interface RedisJsonReactiveCommands<K, V> {
*
* @param key the key holding the JSON document.
* @param jsonPath the {@link JsonPath} pointing to the value(s) whose key(s) we want.
* @return List<K> the keys in the JSON document that are referenced by the given {@link JsonPath}.
* @return List<V> the keys in the JSON document that are referenced by the given {@link JsonPath}.
* @since 6.5
*/
Flux<V> jsonObjkeys(K key, JsonPath jsonPath);
Expand Down Expand Up @@ -283,6 +284,6 @@ public interface RedisJsonReactiveCommands<K, V> {
* @return List<JsonType> the type of JSON value at the provided {@link JsonPath}
* @since 6.5
*/
Flux<V> jsonType(K key, JsonPath jsonPath);
Flux<JsonType> jsonType(K key, JsonPath jsonPath);

}
5 changes: 3 additions & 2 deletions src/main/java/io/lettuce/core/api/sync/RedisJsonCommands.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import java.util.List;
import io.lettuce.core.json.JsonPath;
import io.lettuce.core.json.JsonType;
import io.lettuce.core.json.JsonValue;
import io.lettuce.core.json.arguments.JsonGetArgs;
import io.lettuce.core.json.arguments.JsonMsetArgs;
Expand Down Expand Up @@ -206,7 +207,7 @@ public interface RedisJsonCommands<K, V> {
*
* @param key the key holding the JSON document.
* @param jsonPath the {@link JsonPath} pointing to the value(s) whose key(s) we want.
* @return List<K> the keys in the JSON document that are referenced by the given {@link JsonPath}.
* @return List<V> the keys in the JSON document that are referenced by the given {@link JsonPath}.
* @since 6.5
*/
List<V> jsonObjkeys(K key, JsonPath jsonPath);
Expand Down Expand Up @@ -281,6 +282,6 @@ public interface RedisJsonCommands<K, V> {
* @return List<JsonType> the type of JSON value at the provided {@link JsonPath}
* @since 6.5
*/
List<V> jsonType(K key, JsonPath jsonPath);
List<JsonType> jsonType(K key, JsonPath jsonPath);

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import java.util.List;
import io.lettuce.core.json.JsonPath;
import io.lettuce.core.json.JsonType;
import io.lettuce.core.json.JsonValue;
import io.lettuce.core.json.arguments.JsonGetArgs;
import io.lettuce.core.json.arguments.JsonMsetArgs;
Expand Down Expand Up @@ -206,7 +207,7 @@ public interface NodeSelectionJsonAsyncCommands<K, V> {
*
* @param key the key holding the JSON document.
* @param jsonPath the {@link JsonPath} pointing to the value(s) whose key(s) we want.
* @return List<K> the keys in the JSON document that are referenced by the given {@link JsonPath}.
* @return List<V> the keys in the JSON document that are referenced by the given {@link JsonPath}.
* @since 6.5
*/
AsyncExecutions<List<V>> jsonObjkeys(K key, JsonPath jsonPath);
Expand Down Expand Up @@ -281,6 +282,6 @@ public interface NodeSelectionJsonAsyncCommands<K, V> {
* @return List<JsonType> the type of JSON value at the provided {@link JsonPath}
* @since 6.5
*/
AsyncExecutions<List<V>> jsonType(K key, JsonPath jsonPath);
AsyncExecutions<List<JsonType>> jsonType(K key, JsonPath jsonPath);

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import java.util.List;
import io.lettuce.core.json.JsonPath;
import io.lettuce.core.json.JsonType;
import io.lettuce.core.json.JsonValue;
import io.lettuce.core.json.arguments.JsonGetArgs;
import io.lettuce.core.json.arguments.JsonMsetArgs;
Expand Down Expand Up @@ -206,7 +207,7 @@ public interface NodeSelectionJsonCommands<K, V> {
*
* @param key the key holding the JSON document.
* @param jsonPath the {@link JsonPath} pointing to the value(s) whose key(s) we want.
* @return List<K> the keys in the JSON document that are referenced by the given {@link JsonPath}.
* @return List<V> the keys in the JSON document that are referenced by the given {@link JsonPath}.
* @since 6.5
*/
Executions<List<V>> jsonObjkeys(K key, JsonPath jsonPath);
Expand Down Expand Up @@ -281,6 +282,6 @@ public interface NodeSelectionJsonCommands<K, V> {
* @return List<JsonType> the type of JSON value at the provided {@link JsonPath}
* @since 6.5
*/
Executions<List<V>> jsonType(K key, JsonPath jsonPath);
Executions<List<JsonType>> jsonType(K key, JsonPath jsonPath);

}
53 changes: 53 additions & 0 deletions src/main/java/io/lettuce/core/json/JsonType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* Copyright 2024, Redis Ltd. and Contributors
* All rights reserved.
*
* Licensed under the MIT License.
*
* This file contains contributions from third-party contributors
* licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.lettuce.core.json;

/**
* JSON types as returned by the JSON.TYPE command
*
* @see io.lettuce.core.api.sync.RedisCommands#jsonType
* @since 6.5
* @author Tihomir Mateev
*/
public enum JsonType {

OBJECT, ARRAY, STRING, INTEGER, NUMBER, BOOLEAN, UNKNOWN;

public static JsonType fromString(String s) {
switch (s) {
case "object":
return OBJECT;
case "array":
return ARRAY;
case "string":
return STRING;
case "integer":
return INTEGER;
case "number":
return NUMBER;
case "boolean":
return BOOLEAN;
default:
return UNKNOWN;
}
}

}
49 changes: 49 additions & 0 deletions src/main/java/io/lettuce/core/output/JsonTypeListOutput.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright 2011-Present, Redis Ltd. and Contributors
* All rights reserved.
*
* Licensed under the MIT License.
*/
package io.lettuce.core.output;

import io.lettuce.core.codec.RedisCodec;
import io.lettuce.core.json.JsonType;

import java.nio.ByteBuffer;
import java.util.Collections;
import java.util.List;

/**
* {@link List} of {@link JsonType} output.
*
* @param <K> Key type.
* @param <V> Value type.
* @author Tihomir Mateev
*/
public class JsonTypeListOutput<K, V> extends CommandOutput<K, V, List<JsonType>> {

private boolean initialized;

public JsonTypeListOutput(RedisCodec<K, V> codec) {
super(codec, Collections.emptyList());
}

@Override
public void set(ByteBuffer bytes) {
if (!initialized) {
multi(1);
}

output.add(JsonType.fromString(decodeAscii(bytes)));
}

@Override
public void multi(int count) {

if (!initialized) {
output = OutputFactory.newList(count);
initialized = true;
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ package io.lettuce.core.api.coroutines

import io.lettuce.core.ExperimentalLettuceCoroutinesApi
import kotlinx.coroutines.flow.Flow
import io.lettuce.core.json.JsonType
import io.lettuce.core.json.JsonValue
import io.lettuce.core.json.arguments.JsonGetArgs
import io.lettuce.core.json.arguments.JsonMsetArgs
Expand Down Expand Up @@ -209,7 +210,7 @@ interface RedisJsonCoroutinesCommands<K : Any, V : Any> {
*
* @param key the key holding the JSON document.
* @param jsonPath the [JsonPath] pointing to the value(s) whose key(s) we want.
* @return List<K> the keys in the JSON document that are referenced by the given [JsonPath].
* @return List<V> the keys in the JSON document that are referenced by the given [JsonPath].
* @since 6.5
*/
suspend fun jsonObjkeys(key: K, jsonPath: JsonPath): List<V>
Expand Down Expand Up @@ -284,7 +285,7 @@ interface RedisJsonCoroutinesCommands<K : Any, V : Any> {
* @return List<JsonType> the type of JSON value at the provided [JsonPath]
* @since 6.5
*/
suspend fun jsonType(key: K, jsonPath: JsonPath): List<V>
suspend fun jsonType(key: K, jsonPath: JsonPath): List<JsonType>

}

Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ package io.lettuce.core.api.coroutines
import io.lettuce.core.*
import io.lettuce.core.api.reactive.RedisJsonReactiveCommands
import io.lettuce.core.json.JsonPath
import io.lettuce.core.json.JsonType
import io.lettuce.core.json.JsonValue
import io.lettuce.core.json.arguments.JsonGetArgs
import io.lettuce.core.json.arguments.JsonMsetArgs
Expand Down Expand Up @@ -74,7 +75,7 @@ internal class RedisJsonCoroutinesCommandsImpl<K : Any, V : Any>(internal val op
override suspend fun jsonMSet(arguments: List<JsonMsetArgs<K, V>>): String? =
ops.jsonMSet(arguments).awaitFirstOrNull()

override suspend fun jsonType(key: K, jsonPath: JsonPath): List<V> =
override suspend fun jsonType(key: K, jsonPath: JsonPath): List<JsonType> =
ops.jsonType(key, jsonPath).asFlow().toList()

override suspend fun jsonToggle(key: K, jsonPath: JsonPath): List<Long> =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/
package io.lettuce.core.api;

import io.lettuce.core.json.JsonType;
import io.lettuce.core.json.JsonValue;
import io.lettuce.core.json.arguments.JsonGetArgs;
import io.lettuce.core.json.arguments.JsonMsetArgs;
Expand Down Expand Up @@ -281,6 +282,6 @@ public interface RedisJsonCommands<K, V> {
* @return List<JsonType> the type of JSON value at the provided {@link JsonPath}
* @since 6.5
*/
List<V> jsonType(K key, JsonPath jsonPath);
List<JsonType> jsonType(K key, JsonPath jsonPath);

}
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,7 @@ void jsonDel(String path) {
void jsonType(String path) {
JsonPath myPath = JsonPath.of(path);

String jsonType = redis.jsonType(BIKES_INVENTORY, myPath).get(0);
JsonType jsonType = redis.jsonType(BIKES_INVENTORY, myPath).get(0);
assertThat(jsonType).isEqualTo("array");
}

Expand Down
28 changes: 26 additions & 2 deletions src/test/java/io/lettuce/core/json/RedisJsonIntegrationTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -447,8 +447,32 @@ void jsonDel(String path) {
void jsonType(String path) {
JsonPath myPath = JsonPath.of(path);

String jsonType = redis.jsonType(BIKES_INVENTORY, myPath).get(0);
assertThat(jsonType).isEqualTo("array");
JsonType jsonType = redis.jsonType(BIKES_INVENTORY, myPath).get(0);
assertThat(jsonType).isEqualTo(JsonType.ARRAY);
}

@Test
void jsonAllTypes() {
JsonPath myPath = JsonPath.of("$..mountain_bikes[1]");

JsonType jsonType = redis.jsonType(BIKES_INVENTORY, myPath).get(0);
assertThat(jsonType).isEqualTo(JsonType.OBJECT);

myPath = JsonPath.of("$..mountain_bikes[0:1].price");
jsonType = redis.jsonType(BIKES_INVENTORY, myPath).get(0);
assertThat(jsonType).isEqualTo(JsonType.INTEGER);

myPath = JsonPath.of("$..weight");
jsonType = redis.jsonType(BIKES_INVENTORY, myPath).get(0);
assertThat(jsonType).isEqualTo(JsonType.NUMBER);

myPath = JsonPath.of("$..complete");
jsonType = redis.jsonType(BIKES_INVENTORY, myPath).get(0);
assertThat(jsonType).isEqualTo(JsonType.BOOLEAN);

myPath = JsonPath.of("$..inventory.owner");
jsonType = redis.jsonType(BIKES_INVENTORY, myPath).get(0);
assertThat(jsonType).isEqualTo(JsonType.UNKNOWN);
}

}

0 comments on commit 71ff72a

Please sign in to comment.