Skip to content

Commit 235d658

Browse files
Merge pull request #55 from RedisJSON/json.toggle_and_json.clear
JSON.TOGGLE and JSON.CLEAR
2 parents 5e25a8f + f5272a1 commit 235d658

File tree

2 files changed

+51
-2
lines changed

2 files changed

+51
-2
lines changed

rejson/client.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,13 @@ def __init__(self, encoder=None, decoder=None, *args, **kwargs):
5151
# Set the module commands' callbacks
5252
MODULE_CALLBACKS = {
5353
'JSON.DEL': long,
54+
'JSON.CLEAR': long,
5455
'JSON.GET': self._decode,
5556
'JSON.MGET': bulk_of_jsons(self._decode),
5657
'JSON.SET': lambda r: r and nativestr(r) == 'OK',
5758
'JSON.NUMINCRBY': self._decode,
5859
'JSON.NUMMULTBY': self._decode,
60+
'JSON.TOGGLE': lambda b: b == 'true',
5961
'JSON.STRAPPEND': long,
6062
'JSON.STRLEN': long,
6163
'JSON.ARRAPPEND': long,
@@ -65,10 +67,11 @@ def __init__(self, encoder=None, decoder=None, *args, **kwargs):
6567
'JSON.ARRPOP': self._decode,
6668
'JSON.ARRTRIM': long,
6769
'JSON.OBJLEN': long,
70+
'JSON.DEBUG': long,
6871
}
6972
for k, v in six.iteritems(MODULE_CALLBACKS):
7073
self.set_response_callback(k, v)
71-
74+
7275
def setEncoder(self, encoder):
7376
"""
7477
Sets the client's encoder
@@ -99,6 +102,14 @@ def jsondel(self, name, path=Path.rootPath()):
99102
"""
100103
return self.execute_command('JSON.DEL', name, str_path(path))
101104

105+
def jsonclear(self, name, path=Path.rootPath()):
106+
"""
107+
Emptying arrays and objects (to have zero slots/keys without
108+
deleting the array/object) returning the count of cleared paths
109+
(ignoring non-array and non-objects paths)
110+
"""
111+
return self.execute_command('JSON.CLEAR', name, str_path(path))
112+
102113
def jsonget(self, name, *args, no_escape=False):
103114
"""
104115
Get the object stored as a JSON value at key ``name``
@@ -166,6 +177,13 @@ def jsonnummultby(self, name, path, number):
166177
"""
167178
return self.execute_command('JSON.NUMMULTBY', name, str_path(path), self._encode(number))
168179

180+
def jsontoggle(self, name, path=Path.rootPath()):
181+
"""
182+
Toggle boolean value under ``path`` at key ``name``,
183+
Returning the new value.
184+
"""
185+
return self.execute_command('JSON.TOGGLE', name, str_path(path))
186+
169187
def jsonstrappend(self, name, string, path=Path.rootPath()):
170188
"""
171189
Appends to the string JSON value under ``path`` at key ``name`` the
@@ -243,6 +261,12 @@ def jsonobjlen(self, name, path=Path.rootPath()):
243261
"""
244262
return self.execute_command('JSON.OBJLEN', name, str_path(path))
245263

264+
def jsondebugmemory(self, name, path=Path.rootPath()):
265+
"""
266+
Returns the memory usage in bytes of a value under ``path`` from key ``name``.
267+
"""
268+
return self.execute_command("JSON.DEBUG", "MEMORY", name, str_path(path))
269+
246270
def pipeline(self, transaction=True, shard_hint=None):
247271
"""
248272
Return a new pipeline object that can queue multiple commands for

tests/test_rejson.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import redis
12
import six
23
import json
34
import unittest
@@ -36,7 +37,7 @@ def testJSONSetGetDelNonAsciiShouldSucceed(self):
3637
def testJSONSetExistentialModifiersShouldSucceed(self):
3738
"Test JSONSet's NX/XX flags"
3839

39-
obj = { 'foo': 'bar' }
40+
obj = {'foo': 'bar'}
4041
self.assertTrue(rj.jsonset('obj', Path.rootPath(), obj))
4142

4243
# Test that flags prevent updates when conditions are unmet
@@ -60,6 +61,13 @@ def testMGetShouldSucceed(self):
6061
e = [1, 2]
6162
self.assertListEqual(e, r)
6263

64+
def testClearShouldSucceed(self):
65+
"Test JSONClear"
66+
67+
rj.jsonset('arr', Path.rootPath(), [0, 1, 2, 3, 4])
68+
self.assertEqual(1, rj.jsonclear('arr', Path.rootPath()))
69+
self.assertEqual([], rj.jsonget('arr'))
70+
6371
def testTypeShouldSucceed(self):
6472
"Test JSONType"
6573

@@ -82,6 +90,17 @@ def testNumMultByShouldSucceed(self):
8290
self.assertEqual(5, rj.jsonnummultby('num', Path.rootPath(), 2.5))
8391
self.assertEqual(2.5, rj.jsonnummultby('num', Path.rootPath(), 0.5))
8492

93+
def testToggleShouldSucceed(self):
94+
"Test JSONToggle"
95+
96+
rj.jsonset('bool', Path.rootPath(), False)
97+
self.assertTrue(rj.jsontoggle('bool', Path.rootPath()))
98+
self.assertFalse(rj.jsontoggle('bool', Path.rootPath()))
99+
# check non-boolean value
100+
rj.jsonset('num', Path.rootPath(), 1)
101+
with self.assertRaises(redis.exceptions.ResponseError):
102+
rj.jsontoggle('num', Path.rootPath())
103+
85104
def testStrAppendShouldSucceed(self):
86105
"Test JSONStrAppend"
87106

@@ -161,6 +180,12 @@ def testObjLenShouldSucceed(self):
161180
rj.jsonset('obj', Path.rootPath(), obj)
162181
self.assertEqual(len(obj), rj.jsonobjlen('obj', Path.rootPath()))
163182

183+
def testDebugMemoryShouldSucceed(self):
184+
"Test JSONDebug"
185+
186+
rj.jsonset('str', Path.rootPath(), 'foo')
187+
self.assertEqual(24, rj.jsondebugmemory('str', Path.rootPath()))
188+
164189
def testPipelineShouldSucceed(self):
165190
"Test pipeline"
166191

0 commit comments

Comments
 (0)