Skip to content

Commit

Permalink
Python: adds JSON.STRLEN, JSON.STRAPPEND commands (#2372)
Browse files Browse the repository at this point in the history
---------

Signed-off-by: Shoham Elias <[email protected]>
Signed-off-by: Shoham Elias <[email protected]>
Co-authored-by: Andrew Carbonetto <[email protected]>
Co-authored-by: jonathanl-bq <[email protected]>
  • Loading branch information
3 people authored and BoazBD committed Oct 27, 2024
1 parent a14aca2 commit e2eadbc
Show file tree
Hide file tree
Showing 3 changed files with 1 addition and 88 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
* Node: Added `FT.DROPINDEX` ([#2516](https://github.com/valkey-io/valkey-glide/pull/2516))
* Python: Add `JSON.STRAPPEND` , `JSON.STRLEN` commands ([#2372](https://github.com/valkey-io/valkey-glide/pull/2372))
* Python: Add `JSON.OBJKEYS` command ([#2395](https://github.com/valkey-io/valkey-glide/pull/2395))
* Python: Add `JSON.STRAPPEND` , `JSON.STRLEN` commands ([#2372](https://github.com/valkey-io/valkey-glide/pull/2372))

#### Breaking Changes

Expand Down
49 changes: 0 additions & 49 deletions python/python/glide/async_commands/server_modules/json.py
Original file line number Diff line number Diff line change
Expand Up @@ -548,55 +548,6 @@ async def strlen(
)


async def objkeys(
client: TGlideClient,
key: TEncodable,
path: Optional[TEncodable] = None,
) -> Optional[Union[List[bytes], List[List[bytes]]]]:
"""
Retrieves key names in the object values at the specified `path` within the JSON document stored at `key`.
Args:
client (TGlideClient): The client to execute the command.
key (TEncodable): The key of the JSON document.
path (Optional[TEncodable]): Represents the path within the JSON document where the key names will be retrieved.
Defaults to None.
Returns:
Optional[Union[List[bytes], List[List[bytes]]]]:
For JSONPath (`path` starts with `$`):
Returns a list of arrays containing key names for each matching object.
If a value matching the path is not an object, an empty array is returned.
If `path` doesn't exist, an empty array is returned.
For legacy path (`path` starts with `.`):
Returns a list of key names for the object value matching the path.
If multiple objects match the path, the key names of the first object are returned.
If a value matching the path is not an object, an error is raised.
If `path` doesn't exist, None is returned.
If `key` doesn't exist, None is returned.
Examples:
>>> from glide import json
>>> await json.set(client, "doc", "$", '{"a": 1.0, "b": {"a": {"x": 1, "y": 2}, "b": 2.5, "c": true}}')
b'OK' # Indicates successful setting of the value at the root path '$' in the key `doc`.
>>> await json.objkeys(client, "doc", "$")
[[b"a", b"b"]] # Returns a list of arrays containing the key names for objects matching the path '$'.
>>> await json.objkeys(client, "doc", ".")
[b"a", b"b"] # Returns key names for the object matching the path '.' as it is the only match.
>>> await json.objkeys(client, "doc", "$.b")
[[b"a", b"b", b"c"]] # Returns key names as a nested list for objects matching the JSONPath '$.b'.
>>> await json.objkeys(client, "doc", ".b")
[b"a", b"b", b"c"] # Returns key names for the nested object at path '.b'.
"""
args = ["JSON.OBJKEYS", key]
if path:
args.append(path)
return cast(
Optional[Union[List[bytes], List[List[bytes]]]],
await client.custom_command(args),
)


async def toggle(
client: TGlideClient,
key: TEncodable,
Expand Down
39 changes: 0 additions & 39 deletions python/python/tests/tests_server_modules/test_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -330,45 +330,6 @@ async def test_json_forget(self, glide_client: TGlideClient):
assert await json.forget(glide_client, "non_existing_key", "$") == 0
assert await json.forget(glide_client, "non_existing_key", ".") == 0

@pytest.mark.parametrize("cluster_mode", [True, False])
@pytest.mark.parametrize("protocol", [ProtocolVersion.RESP2, ProtocolVersion.RESP3])
async def test_json_objkeys(self, glide_client: TGlideClient):
key = get_random_string(5)

json_value = {"a": 1.0, "b": {"a": {"x": 1, "y": 2}, "b": 2.5, "c": True}}
assert await json.set(glide_client, key, "$", OuterJson.dumps(json_value)) == OK

keys = await json.objkeys(glide_client, key, "$")
assert keys == [[b"a", b"b"]]

keys = await json.objkeys(glide_client, key, ".")
assert keys == [b"a", b"b"]

keys = await json.objkeys(glide_client, key, "$..")
assert keys == [[b"a", b"b"], [b"a", b"b", b"c"], [b"x", b"y"]]

keys = await json.objkeys(glide_client, key, "..")
assert keys == [b"a", b"b"]

keys = await json.objkeys(glide_client, key, "$..b")
assert keys == [[b"a", b"b", b"c"], []]

keys = await json.objkeys(glide_client, key, "..b")
assert keys == [b"a", b"b", b"c"]

# path doesn't exist
assert await json.objkeys(glide_client, key, "$.non_existing_path") == []
assert await json.objkeys(glide_client, key, "non_existing_path") == None

# Value at path isnt an object
assert await json.objkeys(glide_client, key, "$.a") == [[]]
with pytest.raises(RequestError):
assert await json.objkeys(glide_client, key, ".a")

# Non-existing key
assert await json.objkeys(glide_client, "non_exiting_key", "$") == None
assert await json.objkeys(glide_client, "non_exiting_key", ".") == None

@pytest.mark.parametrize("cluster_mode", [True, False])
@pytest.mark.parametrize("protocol", [ProtocolVersion.RESP2, ProtocolVersion.RESP3])
async def test_json_toggle(self, glide_client: TGlideClient):
Expand Down

0 comments on commit e2eadbc

Please sign in to comment.