diff --git a/data/command-api-mapping.json b/data/command-api-mapping.json index 0fa1dd6c0c..cac7011f8a 100644 --- a/data/command-api-mapping.json +++ b/data/command-api-mapping.json @@ -67090,6 +67090,37 @@ "description": "The array length after the append operation." } } + ], + "redis_rb": [ + { + "signature": "json_arrappend(key, path, *values, raw: false)", + "params": [ + { + "name": "key", + "type": "String", + "description": "" + }, + { + "name": "path", + "type": "String", + "description": "a JSONPath to the target array" + }, + { + "name": "*values", + "type": "Array", + "description": "one or more JSON values to append" + }, + { + "name": "raw", + "type": "Boolean", + "description": "treat each value as an already-encoded JSON string" + } + ], + "returns": { + "type": "Array, Integer", + "description": "the new array length(s); an Array for a JSONPath, a single Integer for a legacy path (nil for a match that is not an array)" + } + } ] } }, @@ -67758,6 +67789,47 @@ "description": "The index of the first matching element in the requested range." } } + ], + "redis_rb": [ + { + "signature": "json_arrindex(key, path, value, start: nil, stop: nil, raw: false)", + "params": [ + { + "name": "key", + "type": "String", + "description": "" + }, + { + "name": "path", + "type": "String", + "description": "a JSONPath to the target array" + }, + { + "name": "value", + "type": "Object", + "description": "the scalar JSON value to search for" + }, + { + "name": "start", + "type": "Integer", + "description": "optional inclusive start index" + }, + { + "name": "stop", + "type": "Integer", + "description": "optional exclusive stop index" + }, + { + "name": "raw", + "type": "Boolean", + "description": "treat value as an already-encoded JSON string" + } + ], + "returns": { + "type": "Array, Integer", + "description": "the index/indices of the first match (-1 if not found)" + } + } ] } }, @@ -68229,6 +68301,42 @@ "description": "The array length after the insert operation." } } + ], + "redis_rb": [ + { + "signature": "json_arrinsert(key, path, index, *values, raw: false)", + "params": [ + { + "name": "key", + "type": "String", + "description": "" + }, + { + "name": "path", + "type": "String", + "description": "a JSONPath to the target array" + }, + { + "name": "index", + "type": "Integer", + "description": "the position to insert before" + }, + { + "name": "*values", + "type": "Array", + "description": "one or more JSON values to insert" + }, + { + "name": "raw", + "type": "Boolean", + "description": "treat each value as an already-encoded JSON string" + } + ], + "returns": { + "type": "Array, Integer", + "description": "the new array length(s)" + } + } ] } }, @@ -68544,6 +68652,27 @@ "description": "The length of the JSON array at the requested path." } } + ], + "redis_rb": [ + { + "signature": "json_arrlen(key, path = nil)", + "params": [ + { + "name": "key", + "type": "String", + "description": "" + }, + { + "name": "path", + "type": "String", + "description": "an optional JSONPath (defaults to the root \"$\")" + } + ], + "returns": { + "type": "Array, Integer, nil", + "description": "the array length(s); nil for a match that is not an array, or when the key/path does not exist" + } + } ] } }, @@ -69009,6 +69138,37 @@ "description": "The removed JSON element." } } + ], + "redis_rb": [ + { + "signature": "json_arrpop(key, path = nil, index = nil, raw: false)", + "params": [ + { + "name": "key", + "type": "String", + "description": "" + }, + { + "name": "path", + "type": "String", + "description": "an optional JSONPath to the target array (defaults to the root \"$\")" + }, + { + "name": "index", + "type": "Integer", + "description": "an optional position to pop from (defaults to -1, the last element)" + }, + { + "name": "raw", + "type": "Boolean", + "description": "return the unparsed JSON string(s) instead of parsed Ruby objects" + } + ], + "returns": { + "type": "Array, Object, nil", + "description": "the popped value(s); an Array for a JSONPath, a single value for a legacy path, nil for an empty array or a non-array match" + } + } ] } }, @@ -69363,6 +69523,37 @@ "description": "The length of the array after trimming." } } + ], + "redis_rb": [ + { + "signature": "json_arrtrim(key, path, start, stop)", + "params": [ + { + "name": "key", + "type": "String", + "description": "" + }, + { + "name": "path", + "type": "String", + "description": "a JSONPath to the target array" + }, + { + "name": "start", + "type": "Integer", + "description": "inclusive index of the first element to keep" + }, + { + "name": "stop", + "type": "Integer", + "description": "inclusive index of the last element to keep" + } + ], + "returns": { + "type": "Array, Integer", + "description": "the new array length(s)" + } + } ] } }, @@ -69692,6 +69883,27 @@ "description": "The number of values cleared." } } + ], + "redis_rb": [ + { + "signature": "json_clear(key, path = nil)", + "params": [ + { + "name": "key", + "type": "String", + "description": "" + }, + { + "name": "path", + "type": "String", + "description": "an optional JSONPath (defaults to the root \"$\")" + } + ], + "returns": { + "type": "Integer", + "description": "the number of values cleared" + } + } ] } }, @@ -69797,6 +70009,27 @@ "description": "" } } + ], + "redis_rb": [ + { + "signature": "json_debug_memory(key, path = nil)", + "params": [ + { + "name": "key", + "type": "String", + "description": "" + }, + { + "name": "path", + "type": "String", + "description": "an optional JSONPath (defaults to the root)" + } + ], + "returns": { + "type": "Array, Integer", + "description": "the size(s) in bytes: an Array for a JSONPath, a single integer for a legacy path or when no path is given (0 for a missing key)" + } + } ] } }, @@ -70126,6 +70359,27 @@ "description": "The number of paths deleted." } } + ], + "redis_rb": [ + { + "signature": "json_del(key, path = nil)", + "params": [ + { + "name": "key", + "type": "String", + "description": "" + }, + { + "name": "path", + "type": "String", + "description": "an optional JSONPath (defaults to the root \"$\")" + } + ], + "returns": { + "type": "Integer", + "description": "the number of values deleted" + } + } ] } }, @@ -70198,6 +70452,27 @@ "description": "" } } + ], + "redis_rb": [ + { + "signature": "json_forget(key, path = nil)", + "params": [ + { + "name": "key", + "type": "String", + "description": "" + }, + { + "name": "path", + "type": "String", + "description": "an optional JSONPath (defaults to the root \"$\")" + } + ], + "returns": { + "type": "Integer", + "description": "the number of values deleted (alias of json_del)" + } + } ] } }, @@ -70625,6 +70900,32 @@ "description": "The JSON value at the requested path." } } + ], + "redis_rb": [ + { + "signature": "json_get(key, *paths, raw: false)", + "params": [ + { + "name": "key", + "type": "String", + "description": "" + }, + { + "name": "*paths", + "type": "Array", + "description": "zero or more JSONPath expressions; with none the whole document is returned" + }, + { + "name": "raw", + "type": "Boolean", + "description": "return the unparsed JSON string instead of a parsed Ruby object" + } + ], + "returns": { + "type": "Object, String, nil", + "description": "the parsed JSON value (or the raw JSON string when raw is true), or nil if the key does not exist" + } + } ] } }, @@ -70998,6 +71299,37 @@ "description": "" } } + ], + "redis_rb": [ + { + "signature": "json_merge(key, path, value, raw: false)", + "params": [ + { + "name": "key", + "type": "String", + "description": "" + }, + { + "name": "path", + "type": "String", + "description": "a JSONPath (must be \"$\" when creating a new key)" + }, + { + "name": "value", + "type": "Object", + "description": "a JSON-serializable Ruby object, or a pre-encoded JSON string when raw is true" + }, + { + "name": "raw", + "type": "Boolean", + "description": "treat value as an already-encoded JSON string and send it as-is" + } + ], + "returns": { + "type": "String", + "description": "the raw \"OK\" reply" + } + } ] } }, @@ -71338,6 +71670,32 @@ "description": "The JSON values found at the requested path across the requested keys." } } + ], + "redis_rb": [ + { + "signature": "json_mget(*keys, path, raw: false)", + "params": [ + { + "name": "*keys", + "type": "Array", + "description": "one or more keys to read" + }, + { + "name": "path", + "type": "String", + "description": "a single JSONPath applied to every key" + }, + { + "name": "raw", + "type": "Boolean", + "description": "return the unparsed JSON strings instead of parsed Ruby objects" + } + ], + "returns": { + "type": "Array", + "description": "one value per key (nil for a missing key/path)" + } + } ] } }, @@ -71507,6 +71865,27 @@ "description": "The status reply for the multi-set operation." } } + ], + "redis_rb": [ + { + "signature": "json_mset(*args, raw: false)", + "params": [ + { + "name": "*args", + "type": "Array", + "description": "a flat list of key, path, value triplets" + }, + { + "name": "raw", + "type": "Boolean", + "description": "treat each value as an already-encoded JSON string" + } + ], + "returns": { + "type": "String", + "description": "the raw \"OK\" reply" + } + } ] } }, @@ -71826,6 +72205,32 @@ "description": "The updated numeric value." } } + ], + "redis_rb": [ + { + "signature": "json_numincrby(key, path, number)", + "params": [ + { + "name": "key", + "type": "String", + "description": "" + }, + { + "name": "path", + "type": "String", + "description": "a JSONPath to the numeric value(s)" + }, + { + "name": "number", + "type": "Numeric", + "description": "the amount to add" + } + ], + "returns": { + "type": "Array, Numeric, nil", + "description": "the new value(s): an Array for a JSONPath, a single number for a legacy path; nil (or nil element) for a non-numeric match" + } + } ] } }, @@ -72141,6 +72546,27 @@ "description": "The keys contained in the JSON object at the requested path." } } + ], + "redis_rb": [ + { + "signature": "json_objkeys(key, path = nil)", + "params": [ + { + "name": "key", + "type": "String", + "description": "" + }, + { + "name": "path", + "type": "String", + "description": "an optional JSONPath (defaults to the root)" + } + ], + "returns": { + "type": "Array", + "description": "an array of key-name arrays (JSONPath) or a single array of key names (legacy path); nil for a non-object match" + } + } ] } }, @@ -72456,6 +72882,27 @@ "description": "The number of keys in the JSON object at the requested path." } } + ], + "redis_rb": [ + { + "signature": "json_objlen(key, path = nil)", + "params": [ + { + "name": "key", + "type": "String", + "description": "" + }, + { + "name": "path", + "type": "String", + "description": "an optional JSONPath (defaults to the root)" + } + ], + "returns": { + "type": "Array, Integer, nil", + "description": "the key count(s): an Array for a JSONPath, a single integer for a legacy path; nil for a non-object match" + } + } ] } }, @@ -73272,6 +73719,47 @@ "description": "The status reply for the set operation." } } + ], + "redis_rb": [ + { + "signature": "json_set(key, path, value, nx: false, xx: false, raw: false)", + "params": [ + { + "name": "key", + "type": "String", + "description": "" + }, + { + "name": "path", + "type": "String", + "description": "a JSONPath, e.g. \"$\" for the document root" + }, + { + "name": "value", + "type": "Object", + "description": "a JSON-serializable Ruby object, or a pre-encoded JSON string when raw is true" + }, + { + "name": "nx", + "type": "Boolean", + "description": "only set when the path does not already exist" + }, + { + "name": "xx", + "type": "Boolean", + "description": "only set when the path already exists" + }, + { + "name": "raw", + "type": "Boolean", + "description": "treat value as an already-encoded JSON string and send it as-is" + } + ], + "returns": { + "type": "Boolean, String", + "description": "when nx or xx is given, true on success and false when the condition was not met; otherwise the raw \"OK\" reply" + } + } ] } }, @@ -73796,6 +74284,37 @@ "description": "The string length after the append operation." } } + ], + "redis_rb": [ + { + "signature": "json_strappend(key, path, value, raw: false)", + "params": [ + { + "name": "key", + "type": "String", + "description": "" + }, + { + "name": "path", + "type": "String", + "description": "a JSONPath to the target string(s)" + }, + { + "name": "value", + "type": "String", + "description": "the string to append" + }, + { + "name": "raw", + "type": "Boolean", + "description": "treat value as an already-encoded JSON string and send it as-is" + } + ], + "returns": { + "type": "Array, Integer, nil", + "description": "the new string length(s): an Array for a JSONPath, a single integer for a legacy path; nil for a non-string match" + } + } ] } }, @@ -74111,6 +74630,27 @@ "description": "The length of the JSON string at the requested path." } } + ], + "redis_rb": [ + { + "signature": "json_strlen(key, path = nil)", + "params": [ + { + "name": "key", + "type": "String", + "description": "" + }, + { + "name": "path", + "type": "String", + "description": "an optional JSONPath (defaults to the root)" + } + ], + "returns": { + "type": "Array, Integer, nil", + "description": "the string length(s): an Array for a JSONPath, a single integer for a legacy path; nil for a non-string match" + } + } ] } }, @@ -74370,6 +74910,27 @@ "description": "The toggled boolean value." } } + ], + "redis_rb": [ + { + "signature": "json_toggle(key, path)", + "params": [ + { + "name": "key", + "type": "String", + "description": "" + }, + { + "name": "path", + "type": "String", + "description": "a JSONPath to the target boolean(s)" + } + ], + "returns": { + "type": "Array, Object, nil", + "description": "1/0 for the new true/false value(s): an Array for a JSONPath, a single value for a legacy path; nil for a non-boolean match" + } + } ] } }, @@ -74685,6 +75246,27 @@ "description": "The JSON type at the requested path." } } + ], + "redis_rb": [ + { + "signature": "json_type(key, path = nil)", + "params": [ + { + "name": "key", + "type": "String", + "description": "" + }, + { + "name": "path", + "type": "String", + "description": "an optional JSONPath (defaults to the root)" + } + ], + "returns": { + "type": "Array, String, nil", + "description": "the type name(s): an Array for a JSONPath, a single string for a legacy path" + } + } ] } }, diff --git a/data/command-api-mapping/JSON.ARRAPPEND.json b/data/command-api-mapping/JSON.ARRAPPEND.json index 4ca06e9a0d..664f8df97e 100644 --- a/data/command-api-mapping/JSON.ARRAPPEND.json +++ b/data/command-api-mapping/JSON.ARRAPPEND.json @@ -505,6 +505,37 @@ "description": "The array length after the append operation." } } + ], + "redis_rb": [ + { + "signature": "json_arrappend(key, path, *values, raw: false)", + "params": [ + { + "name": "key", + "type": "String", + "description": "" + }, + { + "name": "path", + "type": "String", + "description": "a JSONPath to the target array" + }, + { + "name": "*values", + "type": "Array", + "description": "one or more JSON values to append" + }, + { + "name": "raw", + "type": "Boolean", + "description": "treat each value as an already-encoded JSON string" + } + ], + "returns": { + "type": "Array, Integer", + "description": "the new array length(s); an Array for a JSONPath, a single Integer for a legacy path (nil for a match that is not an array)" + } + } ] } } diff --git a/data/command-api-mapping/JSON.ARRINDEX.json b/data/command-api-mapping/JSON.ARRINDEX.json index fcd603b3d8..913eb7c330 100644 --- a/data/command-api-mapping/JSON.ARRINDEX.json +++ b/data/command-api-mapping/JSON.ARRINDEX.json @@ -663,6 +663,47 @@ "description": "The index of the first matching element in the requested range." } } + ], + "redis_rb": [ + { + "signature": "json_arrindex(key, path, value, start: nil, stop: nil, raw: false)", + "params": [ + { + "name": "key", + "type": "String", + "description": "" + }, + { + "name": "path", + "type": "String", + "description": "a JSONPath to the target array" + }, + { + "name": "value", + "type": "Object", + "description": "the scalar JSON value to search for" + }, + { + "name": "start", + "type": "Integer", + "description": "optional inclusive start index" + }, + { + "name": "stop", + "type": "Integer", + "description": "optional exclusive stop index" + }, + { + "name": "raw", + "type": "Boolean", + "description": "treat value as an already-encoded JSON string" + } + ], + "returns": { + "type": "Array, Integer", + "description": "the index/indices of the first match (-1 if not found)" + } + } ] } } diff --git a/data/command-api-mapping/JSON.ARRINSERT.json b/data/command-api-mapping/JSON.ARRINSERT.json index bdbf7b80bf..36a9b98483 100644 --- a/data/command-api-mapping/JSON.ARRINSERT.json +++ b/data/command-api-mapping/JSON.ARRINSERT.json @@ -466,6 +466,42 @@ "description": "The array length after the insert operation." } } + ], + "redis_rb": [ + { + "signature": "json_arrinsert(key, path, index, *values, raw: false)", + "params": [ + { + "name": "key", + "type": "String", + "description": "" + }, + { + "name": "path", + "type": "String", + "description": "a JSONPath to the target array" + }, + { + "name": "index", + "type": "Integer", + "description": "the position to insert before" + }, + { + "name": "*values", + "type": "Array", + "description": "one or more JSON values to insert" + }, + { + "name": "raw", + "type": "Boolean", + "description": "treat each value as an already-encoded JSON string" + } + ], + "returns": { + "type": "Array, Integer", + "description": "the new array length(s)" + } + } ] } } diff --git a/data/command-api-mapping/JSON.ARRLEN.json b/data/command-api-mapping/JSON.ARRLEN.json index d98f1c099e..93187fa63d 100644 --- a/data/command-api-mapping/JSON.ARRLEN.json +++ b/data/command-api-mapping/JSON.ARRLEN.json @@ -310,6 +310,27 @@ "description": "The length of the JSON array at the requested path." } } + ], + "redis_rb": [ + { + "signature": "json_arrlen(key, path = nil)", + "params": [ + { + "name": "key", + "type": "String", + "description": "" + }, + { + "name": "path", + "type": "String", + "description": "an optional JSONPath (defaults to the root \"$\")" + } + ], + "returns": { + "type": "Array, Integer, nil", + "description": "the array length(s); nil for a match that is not an array, or when the key/path does not exist" + } + } ] } } diff --git a/data/command-api-mapping/JSON.ARRPOP.json b/data/command-api-mapping/JSON.ARRPOP.json index 7fc9764159..b6677f4287 100644 --- a/data/command-api-mapping/JSON.ARRPOP.json +++ b/data/command-api-mapping/JSON.ARRPOP.json @@ -460,6 +460,37 @@ "description": "The removed JSON element." } } + ], + "redis_rb": [ + { + "signature": "json_arrpop(key, path = nil, index = nil, raw: false)", + "params": [ + { + "name": "key", + "type": "String", + "description": "" + }, + { + "name": "path", + "type": "String", + "description": "an optional JSONPath to the target array (defaults to the root \"$\")" + }, + { + "name": "index", + "type": "Integer", + "description": "an optional position to pop from (defaults to -1, the last element)" + }, + { + "name": "raw", + "type": "Boolean", + "description": "return the unparsed JSON string(s) instead of parsed Ruby objects" + } + ], + "returns": { + "type": "Array, Object, nil", + "description": "the popped value(s); an Array for a JSONPath, a single value for a legacy path, nil for an empty array or a non-array match" + } + } ] } } diff --git a/data/command-api-mapping/JSON.ARRTRIM.json b/data/command-api-mapping/JSON.ARRTRIM.json index b975fa2b1e..11dabb8c6f 100644 --- a/data/command-api-mapping/JSON.ARRTRIM.json +++ b/data/command-api-mapping/JSON.ARRTRIM.json @@ -349,6 +349,37 @@ "description": "The length of the array after trimming." } } + ], + "redis_rb": [ + { + "signature": "json_arrtrim(key, path, start, stop)", + "params": [ + { + "name": "key", + "type": "String", + "description": "" + }, + { + "name": "path", + "type": "String", + "description": "a JSONPath to the target array" + }, + { + "name": "start", + "type": "Integer", + "description": "inclusive index of the first element to keep" + }, + { + "name": "stop", + "type": "Integer", + "description": "inclusive index of the last element to keep" + } + ], + "returns": { + "type": "Array, Integer", + "description": "the new array length(s)" + } + } ] } } diff --git a/data/command-api-mapping/JSON.CLEAR.json b/data/command-api-mapping/JSON.CLEAR.json index 557336d3e2..629fc1097b 100644 --- a/data/command-api-mapping/JSON.CLEAR.json +++ b/data/command-api-mapping/JSON.CLEAR.json @@ -324,6 +324,27 @@ "description": "The number of values cleared." } } + ], + "redis_rb": [ + { + "signature": "json_clear(key, path = nil)", + "params": [ + { + "name": "key", + "type": "String", + "description": "" + }, + { + "name": "path", + "type": "String", + "description": "an optional JSONPath (defaults to the root \"$\")" + } + ], + "returns": { + "type": "Integer", + "description": "the number of values cleared" + } + } ] } } diff --git a/data/command-api-mapping/JSON.DEBUG MEMORY.json b/data/command-api-mapping/JSON.DEBUG MEMORY.json index 9a9f5fb9a4..6585b6095d 100644 --- a/data/command-api-mapping/JSON.DEBUG MEMORY.json +++ b/data/command-api-mapping/JSON.DEBUG MEMORY.json @@ -100,6 +100,27 @@ "description": "" } } + ], + "redis_rb": [ + { + "signature": "json_debug_memory(key, path = nil)", + "params": [ + { + "name": "key", + "type": "String", + "description": "" + }, + { + "name": "path", + "type": "String", + "description": "an optional JSONPath (defaults to the root)" + } + ], + "returns": { + "type": "Array, Integer", + "description": "the size(s) in bytes: an Array for a JSONPath, a single integer for a legacy path or when no path is given (0 for a missing key)" + } + } ] } } diff --git a/data/command-api-mapping/JSON.DEL.json b/data/command-api-mapping/JSON.DEL.json index 178d01591d..adf1a67702 100644 --- a/data/command-api-mapping/JSON.DEL.json +++ b/data/command-api-mapping/JSON.DEL.json @@ -324,6 +324,27 @@ "description": "The number of paths deleted." } } + ], + "redis_rb": [ + { + "signature": "json_del(key, path = nil)", + "params": [ + { + "name": "key", + "type": "String", + "description": "" + }, + { + "name": "path", + "type": "String", + "description": "an optional JSONPath (defaults to the root \"$\")" + } + ], + "returns": { + "type": "Integer", + "description": "the number of values deleted" + } + } ] } } diff --git a/data/command-api-mapping/JSON.FORGET.json b/data/command-api-mapping/JSON.FORGET.json index cd9128da54..2db712d116 100644 --- a/data/command-api-mapping/JSON.FORGET.json +++ b/data/command-api-mapping/JSON.FORGET.json @@ -67,6 +67,27 @@ "description": "" } } + ], + "redis_rb": [ + { + "signature": "json_forget(key, path = nil)", + "params": [ + { + "name": "key", + "type": "String", + "description": "" + }, + { + "name": "path", + "type": "String", + "description": "an optional JSONPath (defaults to the root \"$\")" + } + ], + "returns": { + "type": "Integer", + "description": "the number of values deleted (alias of json_del)" + } + } ] } } diff --git a/data/command-api-mapping/JSON.GET.json b/data/command-api-mapping/JSON.GET.json index 7ca201022d..1fbe258d7b 100644 --- a/data/command-api-mapping/JSON.GET.json +++ b/data/command-api-mapping/JSON.GET.json @@ -422,6 +422,32 @@ "description": "The JSON value at the requested path." } } + ], + "redis_rb": [ + { + "signature": "json_get(key, *paths, raw: false)", + "params": [ + { + "name": "key", + "type": "String", + "description": "" + }, + { + "name": "*paths", + "type": "Array", + "description": "zero or more JSONPath expressions; with none the whole document is returned" + }, + { + "name": "raw", + "type": "Boolean", + "description": "return the unparsed JSON string instead of a parsed Ruby object" + } + ], + "returns": { + "type": "Object, String, nil", + "description": "the parsed JSON value (or the raw JSON string when raw is true), or nil if the key does not exist" + } + } ] } } diff --git a/data/command-api-mapping/JSON.MERGE.json b/data/command-api-mapping/JSON.MERGE.json index 23d47efd58..cc163cee8c 100644 --- a/data/command-api-mapping/JSON.MERGE.json +++ b/data/command-api-mapping/JSON.MERGE.json @@ -368,6 +368,37 @@ "description": "" } } + ], + "redis_rb": [ + { + "signature": "json_merge(key, path, value, raw: false)", + "params": [ + { + "name": "key", + "type": "String", + "description": "" + }, + { + "name": "path", + "type": "String", + "description": "a JSONPath (must be \"$\" when creating a new key)" + }, + { + "name": "value", + "type": "Object", + "description": "a JSON-serializable Ruby object, or a pre-encoded JSON string when raw is true" + }, + { + "name": "raw", + "type": "Boolean", + "description": "treat value as an already-encoded JSON string and send it as-is" + } + ], + "returns": { + "type": "String", + "description": "the raw \"OK\" reply" + } + } ] } } diff --git a/data/command-api-mapping/JSON.MGET.json b/data/command-api-mapping/JSON.MGET.json index 0cf064a30e..8145190e79 100644 --- a/data/command-api-mapping/JSON.MGET.json +++ b/data/command-api-mapping/JSON.MGET.json @@ -335,6 +335,32 @@ "description": "The JSON values found at the requested path across the requested keys." } } + ], + "redis_rb": [ + { + "signature": "json_mget(*keys, path, raw: false)", + "params": [ + { + "name": "*keys", + "type": "Array", + "description": "one or more keys to read" + }, + { + "name": "path", + "type": "String", + "description": "a single JSONPath applied to every key" + }, + { + "name": "raw", + "type": "Boolean", + "description": "return the unparsed JSON strings instead of parsed Ruby objects" + } + ], + "returns": { + "type": "Array", + "description": "one value per key (nil for a missing key/path)" + } + } ] } } diff --git a/data/command-api-mapping/JSON.MSET.json b/data/command-api-mapping/JSON.MSET.json index cc87c13c60..c7309486c8 100644 --- a/data/command-api-mapping/JSON.MSET.json +++ b/data/command-api-mapping/JSON.MSET.json @@ -164,6 +164,27 @@ "description": "The status reply for the multi-set operation." } } + ], + "redis_rb": [ + { + "signature": "json_mset(*args, raw: false)", + "params": [ + { + "name": "*args", + "type": "Array", + "description": "a flat list of key, path, value triplets" + }, + { + "name": "raw", + "type": "Boolean", + "description": "treat each value as an already-encoded JSON string" + } + ], + "returns": { + "type": "String", + "description": "the raw \"OK\" reply" + } + } ] } } diff --git a/data/command-api-mapping/JSON.NUMINCRBY.json b/data/command-api-mapping/JSON.NUMINCRBY.json index fc01c50ba6..0146c493e9 100644 --- a/data/command-api-mapping/JSON.NUMINCRBY.json +++ b/data/command-api-mapping/JSON.NUMINCRBY.json @@ -314,6 +314,32 @@ "description": "The updated numeric value." } } + ], + "redis_rb": [ + { + "signature": "json_numincrby(key, path, number)", + "params": [ + { + "name": "key", + "type": "String", + "description": "" + }, + { + "name": "path", + "type": "String", + "description": "a JSONPath to the numeric value(s)" + }, + { + "name": "number", + "type": "Numeric", + "description": "the amount to add" + } + ], + "returns": { + "type": "Array, Numeric, nil", + "description": "the new value(s): an Array for a JSONPath, a single number for a legacy path; nil (or nil element) for a non-numeric match" + } + } ] } } diff --git a/data/command-api-mapping/JSON.OBJKEYS.json b/data/command-api-mapping/JSON.OBJKEYS.json index 6a284bc591..8d73aaecc8 100644 --- a/data/command-api-mapping/JSON.OBJKEYS.json +++ b/data/command-api-mapping/JSON.OBJKEYS.json @@ -310,6 +310,27 @@ "description": "The keys contained in the JSON object at the requested path." } } + ], + "redis_rb": [ + { + "signature": "json_objkeys(key, path = nil)", + "params": [ + { + "name": "key", + "type": "String", + "description": "" + }, + { + "name": "path", + "type": "String", + "description": "an optional JSONPath (defaults to the root)" + } + ], + "returns": { + "type": "Array", + "description": "an array of key-name arrays (JSONPath) or a single array of key names (legacy path); nil for a non-object match" + } + } ] } } diff --git a/data/command-api-mapping/JSON.OBJLEN.json b/data/command-api-mapping/JSON.OBJLEN.json index de7dc66308..4105dc8c78 100644 --- a/data/command-api-mapping/JSON.OBJLEN.json +++ b/data/command-api-mapping/JSON.OBJLEN.json @@ -310,6 +310,27 @@ "description": "The number of keys in the JSON object at the requested path." } } + ], + "redis_rb": [ + { + "signature": "json_objlen(key, path = nil)", + "params": [ + { + "name": "key", + "type": "String", + "description": "" + }, + { + "name": "path", + "type": "String", + "description": "an optional JSONPath (defaults to the root)" + } + ], + "returns": { + "type": "Array, Integer, nil", + "description": "the key count(s): an Array for a JSONPath, a single integer for a legacy path; nil for a non-object match" + } + } ] } } diff --git a/data/command-api-mapping/JSON.SET.json b/data/command-api-mapping/JSON.SET.json index 9f3708ce50..a22ae454cb 100644 --- a/data/command-api-mapping/JSON.SET.json +++ b/data/command-api-mapping/JSON.SET.json @@ -744,6 +744,47 @@ "description": "The status reply for the set operation." } } + ], + "redis_rb": [ + { + "signature": "json_set(key, path, value, nx: false, xx: false, raw: false)", + "params": [ + { + "name": "key", + "type": "String", + "description": "" + }, + { + "name": "path", + "type": "String", + "description": "a JSONPath, e.g. \"$\" for the document root" + }, + { + "name": "value", + "type": "Object", + "description": "a JSON-serializable Ruby object, or a pre-encoded JSON string when raw is true" + }, + { + "name": "nx", + "type": "Boolean", + "description": "only set when the path does not already exist" + }, + { + "name": "xx", + "type": "Boolean", + "description": "only set when the path already exists" + }, + { + "name": "raw", + "type": "Boolean", + "description": "treat value as an already-encoded JSON string and send it as-is" + } + ], + "returns": { + "type": "Boolean, String", + "description": "when nx or xx is given, true on success and false when the condition was not met; otherwise the raw \"OK\" reply" + } + } ] } } diff --git a/data/command-api-mapping/JSON.STRAPPEND.json b/data/command-api-mapping/JSON.STRAPPEND.json index 28d5272733..abc6876394 100644 --- a/data/command-api-mapping/JSON.STRAPPEND.json +++ b/data/command-api-mapping/JSON.STRAPPEND.json @@ -519,6 +519,37 @@ "description": "The string length after the append operation." } } + ], + "redis_rb": [ + { + "signature": "json_strappend(key, path, value, raw: false)", + "params": [ + { + "name": "key", + "type": "String", + "description": "" + }, + { + "name": "path", + "type": "String", + "description": "a JSONPath to the target string(s)" + }, + { + "name": "value", + "type": "String", + "description": "the string to append" + }, + { + "name": "raw", + "type": "Boolean", + "description": "treat value as an already-encoded JSON string and send it as-is" + } + ], + "returns": { + "type": "Array, Integer, nil", + "description": "the new string length(s): an Array for a JSONPath, a single integer for a legacy path; nil for a non-string match" + } + } ] } } diff --git a/data/command-api-mapping/JSON.STRLEN.json b/data/command-api-mapping/JSON.STRLEN.json index bb3682336b..13c8acaa8d 100644 --- a/data/command-api-mapping/JSON.STRLEN.json +++ b/data/command-api-mapping/JSON.STRLEN.json @@ -310,6 +310,27 @@ "description": "The length of the JSON string at the requested path." } } + ], + "redis_rb": [ + { + "signature": "json_strlen(key, path = nil)", + "params": [ + { + "name": "key", + "type": "String", + "description": "" + }, + { + "name": "path", + "type": "String", + "description": "an optional JSONPath (defaults to the root)" + } + ], + "returns": { + "type": "Array, Integer, nil", + "description": "the string length(s): an Array for a JSONPath, a single integer for a legacy path; nil for a non-string match" + } + } ] } } diff --git a/data/command-api-mapping/JSON.TOGGLE.json b/data/command-api-mapping/JSON.TOGGLE.json index bc0c30cdee..2dd8ca413f 100644 --- a/data/command-api-mapping/JSON.TOGGLE.json +++ b/data/command-api-mapping/JSON.TOGGLE.json @@ -254,6 +254,27 @@ "description": "The toggled boolean value." } } + ], + "redis_rb": [ + { + "signature": "json_toggle(key, path)", + "params": [ + { + "name": "key", + "type": "String", + "description": "" + }, + { + "name": "path", + "type": "String", + "description": "a JSONPath to the target boolean(s)" + } + ], + "returns": { + "type": "Array, Object, nil", + "description": "1/0 for the new true/false value(s): an Array for a JSONPath, a single value for a legacy path; nil for a non-boolean match" + } + } ] } } diff --git a/data/command-api-mapping/JSON.TYPE.json b/data/command-api-mapping/JSON.TYPE.json index bffe86d968..7bc33fcb0a 100644 --- a/data/command-api-mapping/JSON.TYPE.json +++ b/data/command-api-mapping/JSON.TYPE.json @@ -310,6 +310,27 @@ "description": "The JSON type at the requested path." } } + ], + "redis_rb": [ + { + "signature": "json_type(key, path = nil)", + "params": [ + { + "name": "key", + "type": "String", + "description": "" + }, + { + "name": "path", + "type": "String", + "description": "an optional JSONPath (defaults to the root)" + } + ], + "returns": { + "type": "Array, String, nil", + "description": "the type name(s): an Array for a JSONPath, a single string for a legacy path" + } + } ] } } diff --git a/local_examples/tmp/datatypes/json/dt_json.rb b/local_examples/tmp/datatypes/json/dt_json.rb new file mode 100644 index 0000000000..a4598f2f1c --- /dev/null +++ b/local_examples/tmp/datatypes/json/dt_json.rb @@ -0,0 +1,392 @@ +# EXAMPLE: json_tutorial +# HIDE_START +require 'redis' + +r = Redis.new +# HIDE_END + +# REMOVE_START +def assert_equal(expected, actual) + raise "Expected #{expected.inspect}, got #{actual.inspect}" unless actual == expected +end + +r.del('bike', 'crashes', 'newbike', 'riders', 'bike:1', 'bikes:inventory') +# REMOVE_END + +# STEP_START set_get +res1 = r.json_set('bike', '$', 'Hyperion') +puts res1 # >>> OK + +res2 = r.json_get('bike', '$') +p res2 # >>> ["Hyperion"] + +res3 = r.json_type('bike', '$') +p res3 # >>> ["string"] + +# With raw: true, json_set accepts an already-encoded JSON string (skipping +# serialization) and json_get returns the unparsed JSON string rather than a +# Ruby object — useful when you store or forward plain JSON. +res_raw1 = r.json_set('bike', '$', '"Hyperion"', raw: true) +puts res_raw1 # >>> OK + +res_raw2 = r.json_get('bike', '$', raw: true) +puts res_raw2 # >>> ["Hyperion"] (a JSON string, not a Ruby array) +# STEP_END + +# REMOVE_START +assert_equal(['Hyperion'], res2) +assert_equal('["Hyperion"]', res_raw2) +# REMOVE_END + +# STEP_START str +res4 = r.json_strlen('bike', '$') +p res4 # >>> [8] + +res5 = r.json_strappend('bike', '$', ' (Enduro bikes)') +p res5 # >>> [23] + +res6 = r.json_get('bike', '$') +p res6 # >>> ["Hyperion (Enduro bikes)"] +# STEP_END + +# REMOVE_START +assert_equal(['Hyperion (Enduro bikes)'], res6) +# REMOVE_END + +# STEP_START num +res7 = r.json_set('crashes', '$', 0) +puts res7 # >>> OK + +res8 = r.json_numincrby('crashes', '$', 1) +p res8 # >>> [1] + +res9 = r.json_numincrby('crashes', '$', 1.5) +p res9 # >>> [2.5] + +res10 = r.json_numincrby('crashes', '$', -0.75) +p res10 # >>> [1.75] +# STEP_END + +# REMOVE_START +assert_equal([1.75], res10) +# REMOVE_END + +# STEP_START arr +res11 = r.json_set('newbike', '$', ['Deimos', { 'crashes' => 0 }, nil]) +puts res11 # >>> OK + +res12 = r.json_get('newbike', '$') +p res12 # >>> [["Deimos", {"crashes"=>0}, nil]] + +res13 = r.json_get('newbike', '$[1].crashes') +p res13 # >>> [0] + +res14 = r.json_del('newbike', '$.[-1]') +p res14 # >>> 1 + +res15 = r.json_get('newbike', '$') +p res15 # >>> [["Deimos", {"crashes"=>0}]] + +# The same raw: true option returns the array as unparsed JSON text. +res_raw3 = r.json_get('newbike', '$', raw: true) +puts res_raw3 # >>> [["Deimos",{"crashes":0}]] (a JSON string) +# STEP_END + +# REMOVE_START +assert_equal([['Deimos', { 'crashes' => 0 }]], res15) +assert_equal('[["Deimos",{"crashes":0}]]', res_raw3) +# REMOVE_END + +# STEP_START arr2 +res16 = r.json_set('riders', '$', []) +puts res16 # >>> OK + +res17 = r.json_arrappend('riders', '$', 'Norem') +p res17 # >>> [1] + +res18 = r.json_get('riders', '$') +p res18 # >>> [["Norem"]] + +res19 = r.json_arrinsert('riders', '$', 1, 'Prickett', 'Royce', 'Castilla') +p res19 # >>> [4] + +res20 = r.json_get('riders', '$') +p res20 # >>> [["Norem", "Prickett", "Royce", "Castilla"]] + +res21 = r.json_arrtrim('riders', '$', 1, 1) +p res21 # >>> [1] + +res22 = r.json_get('riders', '$') +p res22 # >>> [["Prickett"]] + +res23 = r.json_arrpop('riders', '$') +p res23 # >>> ["Prickett"] + +res24 = r.json_arrpop('riders', '$') +p res24 # >>> [nil] + +# json_arrappend also takes a pre-encoded JSON value with raw: true. +res_raw4 = r.json_arrappend('riders', '$', '"Castilla"', raw: true) +p res_raw4 # >>> [1] +# STEP_END + +# REMOVE_START +assert_equal([nil], res24) +assert_equal([1], res_raw4) +# REMOVE_END + +# STEP_START obj +res25 = r.json_set('bike:1', '$', { 'model' => 'Deimos', 'brand' => 'Ergonom', 'price' => 4972 }) +puts res25 # >>> OK + +res26 = r.json_objlen('bike:1', '$') +p res26 # >>> [3] + +res27 = r.json_objkeys('bike:1', '$') +p res27 # >>> [["model", "brand", "price"]] + +# raw: true returns the object as unparsed JSON text. +res_raw5 = r.json_get('bike:1', '$', raw: true) +puts res_raw5 # >>> [{"model":"Deimos","brand":"Ergonom","price":4972}] (a JSON string) +# STEP_END + +# REMOVE_START +assert_equal([%w[model brand price]], res27) +assert_equal('[{"model":"Deimos","brand":"Ergonom","price":4972}]', res_raw5) +# REMOVE_END + +# STEP_START set_bikes +# HIDE_START +inventory_json = { + 'inventory' => { + 'mountain_bikes' => [ + { + 'id' => 'bike:1', + 'model' => 'Phoebe', + 'description' => 'This is a mid-travel trail slayer that is a fantastic ' \ + 'daily driver or one bike quiver. The Shimano Claris 8-speed groupset ' \ + 'gives plenty of gear range to tackle hills and there’s room for ' \ + 'mudguards and a rack too. This is the bike for the rider who wants ' \ + 'trail manners with low fuss ownership.', + 'price' => 1920, + 'specs' => { 'material' => 'carbon', 'weight' => 13.1 }, + 'colors' => %w[black silver] + }, + { + 'id' => 'bike:2', + 'model' => 'Quaoar', + 'description' => 'Redesigned for the 2020 model year, this bike ' \ + "impressed our testers and is the best all-around trail bike we've " \ + 'ever tested. The Shimano gear system effectively does away with an ' \ + 'external cassette, so is super low maintenance in terms of wear ' \ + "and tear. All in all it's an impressive package for the price, " \ + 'making it very competitive.', + 'price' => 2072, + 'specs' => { 'material' => 'aluminium', 'weight' => 7.9 }, + 'colors' => %w[black white] + }, + { + 'id' => 'bike:3', + 'model' => 'Weywot', + 'description' => 'This bike gives kids aged six years and older ' \ + 'a durable and uberlight mountain bike for their first experience ' \ + 'on tracks and easy cruising through forests and fields. A set of ' \ + 'powerful Shimano hydraulic disc brakes provide ample stopping ' \ + "ability. If you're after a budget option, this is one of the best " \ + 'bikes you could get.', + 'price' => 3264, + 'specs' => { 'material' => 'alloy', 'weight' => 13.8 } + } + ], + 'commuter_bikes' => [ + { + 'id' => 'bike:4', + 'model' => 'Salacia', + 'description' => 'This bike is a great option for anyone who just ' \ + 'wants a bike to get about on With a slick-shifting Claris gears ' \ + 'from Shimano’s, this is a bike which doesn’t break the ' \ + "bank and delivers craved performance. It's for the rider " \ + 'who wants both efficiency and capability.', + 'price' => 1475, + 'specs' => { 'material' => 'aluminium', 'weight' => 16.6 }, + 'colors' => %w[black silver] + }, + { + 'id' => 'bike:5', + 'model' => 'Mimas', + 'description' => 'A real joy to ride, this bike got very high ' \ + 'scores in last years Bike of the year report. The carefully ' \ + 'crafted 50-34 tooth chainset and 11-32 tooth cassette give an ' \ + 'easy-on-the-legs bottom gear for climbing, and the high-quality ' \ + 'Vittoria Zaffiro tires give balance and grip.It includes ' \ + 'a low-step frame , our memory foam seat, bump-resistant shocks and ' \ + 'conveniently placed thumb throttle. Put it all together and you ' \ + 'get a bike that helps redefine what can be done for this price.', + 'price' => 3941, + 'specs' => { 'material' => 'alloy', 'weight' => 11.6 } + } + ] + } +} +# HIDE_END + +res1 = r.json_set('bikes:inventory', '$', inventory_json) +puts res1 # >>> OK +# STEP_END + +# STEP_START get_bikes +res2 = r.json_get('bikes:inventory', '$.inventory.*') +p res2 +# >>> [[{"id"=>"bike:1", "model"=>"Phoebe", +# >>> "description"=>"This is a mid-travel trail slayer... +# STEP_END + +# STEP_START get_mtnbikes +res3 = r.json_get('bikes:inventory', '$.inventory.mountain_bikes[*].model') +p res3 # >>> ["Phoebe", "Quaoar", "Weywot"] + +res4 = r.json_get('bikes:inventory', '$.inventory["mountain_bikes"][*].model') +p res4 # >>> ["Phoebe", "Quaoar", "Weywot"] + +res5 = r.json_get('bikes:inventory', '$..mountain_bikes[*].model') +p res5 # >>> ["Phoebe", "Quaoar", "Weywot"] +# STEP_END + +# REMOVE_START +assert_equal(%w[Phoebe Quaoar Weywot], res3) +assert_equal(%w[Phoebe Quaoar Weywot], res4) +assert_equal(%w[Phoebe Quaoar Weywot], res5) +# REMOVE_END + +# STEP_START get_models +res6 = r.json_get('bikes:inventory', '$..model') +p res6 # >>> ["Phoebe", "Quaoar", "Weywot", "Salacia", "Mimas"] +# STEP_END + +# REMOVE_START +assert_equal(%w[Phoebe Quaoar Weywot Salacia Mimas], res6) +# REMOVE_END + +# STEP_START get2mtnbikes +res7 = r.json_get('bikes:inventory', '$..mountain_bikes[0:2].model') +p res7 # >>> ["Phoebe", "Quaoar"] +# STEP_END + +# REMOVE_START +assert_equal(%w[Phoebe Quaoar], res7) +# REMOVE_END + +# STEP_START filter1 +res8 = r.json_get( + 'bikes:inventory', + '$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]' +) +p res8 +# >>> [{"id"=>"bike:2", "model"=>"Quaoar", +# >>> "description"=>"Redesigned for the 2020 model year... +# STEP_END + +# REMOVE_START +assert_equal( + [ + { + 'id' => 'bike:2', + 'model' => 'Quaoar', + 'description' => 'Redesigned for the 2020 model year, this bike impressed ' \ + "our testers and is the best all-around trail bike we've ever tested. " \ + 'The Shimano gear system effectively does away with an external cassette, ' \ + "so is super low maintenance in terms of wear and tear. All in all it's " \ + 'an impressive package for the price, making it very competitive.', + 'price' => 2072, + 'specs' => { 'material' => 'aluminium', 'weight' => 7.9 }, + 'colors' => %w[black white] + } + ], + res8 +) +# REMOVE_END + +# STEP_START filter2 +res9 = r.json_get('bikes:inventory', "$..[?(@.specs.material == 'alloy')].model") +p res9 # >>> ["Weywot", "Mimas"] +# STEP_END + +# REMOVE_START +assert_equal(%w[Weywot Mimas], res9) +# REMOVE_END + +# STEP_START filter3 +res10 = r.json_get('bikes:inventory', "$..[?(@.specs.material =~ '(?i)al')].model") +p res10 # >>> ["Quaoar", "Weywot", "Salacia", "Mimas"] +# STEP_END + +# REMOVE_START +assert_equal(%w[Quaoar Weywot Salacia Mimas], res10) +# REMOVE_END + +# STEP_START filter4 +res11 = r.json_set( + 'bikes:inventory', '$.inventory.mountain_bikes[0].regex_pat', '(?i)al' +) +res12 = r.json_set( + 'bikes:inventory', '$.inventory.mountain_bikes[1].regex_pat', '(?i)al' +) +res13 = r.json_set( + 'bikes:inventory', '$.inventory.mountain_bikes[2].regex_pat', '(?i)al' +) + +res14 = r.json_get( + 'bikes:inventory', + '$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model' +) +p res14 # >>> ["Quaoar", "Weywot"] +# STEP_END + +# REMOVE_START +assert_equal(%w[Quaoar Weywot], res14) +# REMOVE_END + +# STEP_START update_bikes +res15 = r.json_get('bikes:inventory', '$..price') +p res15 # >>> [1920, 2072, 3264, 1475, 3941] + +res16 = r.json_numincrby('bikes:inventory', '$..price', -100) +p res16 # >>> [1820, 1972, 3164, 1375, 3841] + +res17 = r.json_numincrby('bikes:inventory', '$..price', 100) +p res17 # >>> [1920, 2072, 3264, 1475, 3941] +# STEP_END + +# REMOVE_START +assert_equal([1920, 2072, 3264, 1475, 3941], res15) +assert_equal([1820, 1972, 3164, 1375, 3841], res16) +assert_equal([1920, 2072, 3264, 1475, 3941], res17) +# REMOVE_END + +# STEP_START update_filters1 +res18 = r.json_set('bikes:inventory', '$.inventory.*[?(@.price<2000)].price', 1500) +res19 = r.json_get('bikes:inventory', '$..price') +p res19 # >>> [1500, 2072, 3264, 1500, 3941] +# STEP_END + +# REMOVE_START +assert_equal([1500, 2072, 3264, 1500, 3941], res19) +# REMOVE_END + +# STEP_START update_filters2 +res20 = r.json_arrappend( + 'bikes:inventory', '$.inventory.*[?(@.price<2000)].colors', 'pink' +) +p res20 # >>> [3, 3] + +res21 = r.json_get('bikes:inventory', '$..[*].colors') +p res21 +# >>> [["black", "silver", "pink"], ["black", "white"], ["black", "silver", "pink"]] +# STEP_END + +# REMOVE_START +assert_equal( + [%w[black silver pink], %w[black white], %w[black silver pink]], + res21 +) +# REMOVE_END