Skip to content

Commit b0eb6d9

Browse files
authored
Implement JSON raw return types (#3478)
1 parent f188b20 commit b0eb6d9

14 files changed

+808
-2
lines changed

src/main/java/io/lettuce/core/AbstractRedisAsyncCommands.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1807,6 +1807,21 @@ public RedisFuture<List<JsonValue>> jsonArrpop(K key) {
18071807
return dispatch(jsonCommandBuilder.jsonArrpop(key, JsonPath.ROOT_PATH, -1));
18081808
}
18091809

1810+
@Override
1811+
public RedisFuture<List<String>> jsonArrpopRaw(K key, JsonPath jsonPath, int index) {
1812+
return dispatch(jsonCommandBuilder.jsonArrpopRaw(key, jsonPath, index));
1813+
}
1814+
1815+
@Override
1816+
public RedisFuture<List<String>> jsonArrpopRaw(K key, JsonPath jsonPath) {
1817+
return dispatch(jsonCommandBuilder.jsonArrpopRaw(key, jsonPath, -1));
1818+
}
1819+
1820+
@Override
1821+
public RedisFuture<List<String>> jsonArrpopRaw(K key) {
1822+
return dispatch(jsonCommandBuilder.jsonArrpopRaw(key, JsonPath.ROOT_PATH, -1));
1823+
}
1824+
18101825
@Override
18111826
public RedisFuture<List<Long>> jsonArrtrim(K key, JsonPath jsonPath, JsonRangeArgs range) {
18121827
return dispatch(jsonCommandBuilder.jsonArrtrim(key, jsonPath, range));
@@ -1827,11 +1842,26 @@ public RedisFuture<Long> jsonDel(K key, JsonPath jsonPath) {
18271842
return dispatch(jsonCommandBuilder.jsonDel(key, jsonPath));
18281843
}
18291844

1845+
@Override
1846+
public RedisFuture<List<String>> jsonGetRaw(K key, JsonGetArgs options, JsonPath... jsonPaths) {
1847+
return dispatch(jsonCommandBuilder.jsonGetRaw(key, options, jsonPaths));
1848+
}
1849+
1850+
@Override
1851+
public RedisFuture<List<String>> jsonGetRaw(K key, JsonPath... jsonPaths) {
1852+
return dispatch(jsonCommandBuilder.jsonGetRaw(key, JsonGetArgs.Builder.defaults(), jsonPaths));
1853+
}
1854+
18301855
@Override
18311856
public RedisFuture<Long> jsonDel(K key) {
18321857
return dispatch(jsonCommandBuilder.jsonDel(key, JsonPath.ROOT_PATH));
18331858
}
18341859

1860+
@Override
1861+
public RedisFuture<List<String>> jsonMGetRaw(JsonPath jsonPath, K... keys) {
1862+
return dispatch(jsonCommandBuilder.jsonMGetRaw(jsonPath, keys));
1863+
}
1864+
18351865
@Override
18361866
public RedisFuture<List<JsonValue>> jsonGet(K key, JsonGetArgs options, JsonPath... jsonPaths) {
18371867
return dispatch(jsonCommandBuilder.jsonGet(key, options, jsonPaths));

src/main/java/io/lettuce/core/AbstractRedisReactiveCommands.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1871,6 +1871,21 @@ public Flux<JsonValue> jsonArrpop(K key) {
18711871
return createDissolvingFlux(() -> jsonCommandBuilder.jsonArrpop(key, JsonPath.ROOT_PATH, -1));
18721872
}
18731873

1874+
@Override
1875+
public Flux<String> jsonArrpopRaw(K key, JsonPath jsonPath, int index) {
1876+
return createDissolvingFlux(() -> jsonCommandBuilder.jsonArrpopRaw(key, jsonPath, index));
1877+
}
1878+
1879+
@Override
1880+
public Flux<String> jsonArrpopRaw(K key, JsonPath jsonPath) {
1881+
return createDissolvingFlux(() -> jsonCommandBuilder.jsonArrpopRaw(key, jsonPath, -1));
1882+
}
1883+
1884+
@Override
1885+
public Flux<String> jsonArrpopRaw(K key) {
1886+
return createDissolvingFlux(() -> jsonCommandBuilder.jsonArrpopRaw(key, JsonPath.ROOT_PATH, -1));
1887+
}
1888+
18741889
@Override
18751890
public Flux<Long> jsonArrtrim(K key, JsonPath jsonPath, JsonRangeArgs range) {
18761891
return createDissolvingFlux(() -> jsonCommandBuilder.jsonArrtrim(key, jsonPath, range));
@@ -1891,6 +1906,17 @@ public Mono<Long> jsonDel(K key, JsonPath jsonPath) {
18911906
return createMono(() -> jsonCommandBuilder.jsonDel(key, jsonPath));
18921907
}
18931908

1909+
@Override
1910+
public Flux<String> jsonGetRaw(K key, JsonGetArgs options, JsonPath... jsonPaths) {
1911+
return createDissolvingFlux(() -> jsonCommandBuilder.jsonGetRaw(key, options, jsonPaths));
1912+
}
1913+
1914+
@Override
1915+
public Flux<String> jsonGetRaw(K key, JsonPath... jsonPaths) {
1916+
final JsonGetArgs args = JsonGetArgs.Builder.defaults();
1917+
return createDissolvingFlux(() -> jsonCommandBuilder.jsonGetRaw(key, args, jsonPaths));
1918+
}
1919+
18941920
@Override
18951921
public Mono<Long> jsonDel(K key) {
18961922
return createMono(() -> jsonCommandBuilder.jsonDel(key, JsonPath.ROOT_PATH));
@@ -1927,6 +1953,11 @@ public Mono<String> jsonMSet(List<JsonMsetArgs<K, V>> arguments) {
19271953
return createMono(() -> jsonCommandBuilder.jsonMSet(arguments));
19281954
}
19291955

1956+
@Override
1957+
public Flux<String> jsonMGetRaw(JsonPath jsonPath, K... keys) {
1958+
return createDissolvingFlux(() -> jsonCommandBuilder.jsonMGetRaw(jsonPath, keys));
1959+
}
1960+
19301961
@Override
19311962
public Flux<Number> jsonNumincrby(K key, JsonPath jsonPath, Number number) {
19321963
return createDissolvingFlux(() -> jsonCommandBuilder.jsonNumincrby(key, jsonPath, number));

src/main/java/io/lettuce/core/RedisJsonCommandBuilder.java

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,25 @@ Command<K, V, List<JsonValue>> jsonArrpop(K key, JsonPath jsonPath, int index) {
169169
return createCommand(JSON_ARRPOP, new JsonValueListOutput<>(codec, parser.get()), args);
170170
}
171171

172+
Command<K, V, List<String>> jsonArrpopRaw(K key, JsonPath jsonPath, int index) {
173+
notNullKey(key);
174+
175+
CommandArgs<K, V> args = new CommandArgs<>(codec).addKey(key);
176+
177+
if (jsonPath != null) {
178+
if (index != -1) {
179+
// OPTIONAL as per API
180+
args.add(jsonPath.toString());
181+
args.add(index);
182+
} else if (!jsonPath.isRootPath()) {
183+
// OPTIONAL as per API
184+
args.add(jsonPath.toString());
185+
}
186+
}
187+
188+
return createCommand(JSON_ARRPOP, new StringListOutput<>(codec), args);
189+
}
190+
172191
Command<K, V, List<Long>> jsonArrtrim(K key, JsonPath jsonPath, JsonRangeArgs range) {
173192

174193
notNullKey(key);
@@ -218,6 +237,28 @@ Command<K, V, List<JsonValue>> jsonGet(K key, JsonGetArgs options, JsonPath... j
218237
return createCommand(JSON_GET, new JsonValueListOutput<>(codec, parser.get()), args);
219238
}
220239

240+
Command<K, V, List<String>> jsonGetRaw(K key, JsonGetArgs options, JsonPath... jsonPaths) {
241+
notNullKey(key);
242+
243+
CommandArgs<K, V> args = new CommandArgs<>(codec).addKey(key);
244+
245+
if (options != null) {
246+
// OPTIONAL as per API
247+
options.build(args);
248+
}
249+
250+
if (jsonPaths != null) {
251+
// OPTIONAL as per API
252+
for (JsonPath jsonPath : jsonPaths) {
253+
if (jsonPath != null) {
254+
args.add(jsonPath.toString());
255+
}
256+
}
257+
}
258+
259+
return createCommand(JSON_GET, new StringListOutput<>(codec), args);
260+
}
261+
221262
Command<K, V, String> jsonMerge(K key, JsonPath jsonPath, JsonValue value) {
222263

223264
notNullKey(key);
@@ -248,6 +289,15 @@ Command<K, V, List<JsonValue>> jsonMGet(JsonPath jsonPath, K... keys) {
248289
return createCommand(JSON_MGET, new JsonValueListOutput<>(codec, parser.get()), args);
249290
}
250291

292+
Command<K, V, List<String>> jsonMGetRaw(JsonPath jsonPath, K... keys) {
293+
notEmpty(keys);
294+
295+
CommandArgs<K, V> args = new CommandArgs<>(codec).addKeys(keys);
296+
args.add(jsonPath.toString());
297+
298+
return createCommand(JSON_MGET, new StringListOutput<>(codec), args);
299+
}
300+
251301
Command<K, V, String> jsonMSet(List<JsonMsetArgs<K, V>> arguments) {
252302

253303
notEmpty(arguments.toArray());

src/main/java/io/lettuce/core/api/async/RedisJsonAsyncCommands.java

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,21 @@ public interface RedisJsonAsyncCommands<K, V> {
177177
*/
178178
RedisFuture<List<JsonValue>> jsonArrpop(K key, JsonPath jsonPath, int index);
179179

180+
/**
181+
* Remove and return the JSON value at a given index in the array at a given {@link JsonPath} as raw JSON strings.
182+
* <p>
183+
* Behaves like {@link #jsonArrpop(Object, JsonPath, int)} but returns {@code List<String>} with raw JSON instead of
184+
* {@link JsonValue} wrappers.
185+
*
186+
* @param key the key holding the JSON document.
187+
* @param jsonPath the {@link JsonPath} pointing to the array inside the document.
188+
* @param index the index of the element to be removed. Default is -1, meaning the last element. Out-of-range indexes round
189+
* to their respective array ends. Popping an empty array returns null.
190+
* @return List<String> the removed element, or null if the specified path is not an array.
191+
* @since 7.0
192+
*/
193+
RedisFuture<List<String>> jsonArrpopRaw(K key, JsonPath jsonPath, int index);
194+
180195
/**
181196
* Remove and return {@link JsonValue} at index -1 (last element) in the array at a given {@link JsonPath}
182197
*
@@ -187,6 +202,19 @@ public interface RedisJsonAsyncCommands<K, V> {
187202
*/
188203
RedisFuture<List<JsonValue>> jsonArrpop(K key, JsonPath jsonPath);
189204

205+
/**
206+
* Remove and return the JSON value at index -1 (last element) in the array at a given {@link JsonPath} as raw JSON strings.
207+
* <p>
208+
* Behaves like {@link #jsonArrpop(Object, JsonPath)} but returns {@code List<String>} with raw JSON instead of
209+
* {@link JsonValue} wrappers.
210+
*
211+
* @param key the key holding the JSON document.
212+
* @param jsonPath the {@link JsonPath} pointing to the array inside the document.
213+
* @return List<String> the removed element, or null if the specified path is not an array.
214+
* @since 7.0
215+
*/
216+
RedisFuture<List<String>> jsonArrpopRaw(K key, JsonPath jsonPath);
217+
190218
/**
191219
* Remove and return {@link JsonValue} at index -1 (last element) in the array at the {@link JsonPath#ROOT_PATH}
192220
*
@@ -196,6 +224,19 @@ public interface RedisJsonAsyncCommands<K, V> {
196224
*/
197225
RedisFuture<List<JsonValue>> jsonArrpop(K key);
198226

227+
/**
228+
* Remove and return the JSON value at index -1 (last element) in the array at the {@link JsonPath#ROOT_PATH} as raw JSON
229+
* strings.
230+
* <p>
231+
* Behaves like {@link #jsonArrpop(Object)} but returns {@code List<String>} with raw JSON instead of {@link JsonValue}
232+
* wrappers.
233+
*
234+
* @param key the key holding the JSON document.
235+
* @return List<String> the removed element, or null if the specified path is not an array.
236+
* @since 7.0
237+
*/
238+
RedisFuture<List<String>> jsonArrpopRaw(K key);
239+
199240
/**
200241
* Trim an array at a given {@link JsonPath} so that it contains only the specified inclusive range of elements. All
201242
* elements with indexes smaller than the start range and all elements with indexes bigger than the end range are trimmed.
@@ -272,6 +313,20 @@ public interface RedisJsonAsyncCommands<K, V> {
272313
*/
273314
RedisFuture<List<JsonValue>> jsonGet(K key, JsonGetArgs options, JsonPath... jsonPaths);
274315

316+
/**
317+
* Return the value at the specified path in JSON serialized form as raw strings.
318+
* <p>
319+
* Behaves like {@link #jsonGet(Object, JsonGetArgs, JsonPath...)} but returns {@code List<String>} with raw JSON instead of
320+
* {@link JsonValue} wrappers.
321+
*
322+
* @param key the key holding the JSON document.
323+
* @param options the {@link JsonGetArgs} to use.
324+
* @param jsonPaths the {@link JsonPath}s to use to identify the values to get.
325+
* @return List<String> the value at path in JSON serialized form, or null if the path does not exist.
326+
* @since 7.0
327+
*/
328+
RedisFuture<List<String>> jsonGetRaw(K key, JsonGetArgs options, JsonPath... jsonPaths);
329+
275330
/**
276331
* Return the value at the specified path in JSON serialized form. Uses defaults for the {@link JsonGetArgs}.
277332
* <p>
@@ -290,6 +345,19 @@ public interface RedisJsonAsyncCommands<K, V> {
290345
*/
291346
RedisFuture<List<JsonValue>> jsonGet(K key, JsonPath... jsonPaths);
292347

348+
/**
349+
* Return the value at the specified path in JSON serialized form as raw strings. Uses defaults for the {@link JsonGetArgs}.
350+
* <p>
351+
* Behaves like {@link #jsonGet(Object, JsonPath...)} but returns {@code List<String>} with raw JSON instead of
352+
* {@link JsonValue} wrappers.
353+
*
354+
* @param key the key holding the JSON document.
355+
* @param jsonPaths the {@link JsonPath}s to use to identify the values to get.
356+
* @return List<String> the value at path in JSON serialized form, or null if the path does not exist.
357+
* @since 7.0
358+
*/
359+
RedisFuture<List<String>> jsonGetRaw(K key, JsonPath... jsonPaths);
360+
293361
/**
294362
* Merge a given {@link JsonValue} with the value matching {@link JsonPath}. Consequently, JSON values at matching paths are
295363
* updated, deleted, or expanded with new children.
@@ -335,6 +403,19 @@ public interface RedisJsonAsyncCommands<K, V> {
335403
*/
336404
RedisFuture<List<JsonValue>> jsonMGet(JsonPath jsonPath, K... keys);
337405

406+
/**
407+
* Return the values at the specified path from multiple key arguments as raw JSON strings.
408+
* <p>
409+
* Behaves like {@link #jsonMGet(JsonPath, Object[])} but returns {@code List<String>} with raw JSON instead of
410+
* {@link JsonValue} wrappers.
411+
*
412+
* @param jsonPath the {@link JsonPath} pointing to the value to fetch.
413+
* @param keys the keys holding the values to fetch.
414+
* @return List<String> the values at path, or null if the path does not exist.
415+
* @since 7.0
416+
*/
417+
RedisFuture<List<String>> jsonMGetRaw(JsonPath jsonPath, K... keys);
418+
338419
/**
339420
* Set or update one or more JSON values according to the specified {@link JsonMsetArgs}
340421
* <p>

0 commit comments

Comments
 (0)