From 64df7b769b556d529efa926a2356b7fffbba3cab Mon Sep 17 00:00:00 2001 From: AvitalFineRedis Date: Thu, 19 Aug 2021 15:14:43 +0300 Subject: [PATCH 1/7] MINID and LIMIT --- redis/commands.py | 43 ++++++++++++++++++++++++++++++++++++++++-- tests/test_commands.py | 43 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+), 2 deletions(-) diff --git a/redis/commands.py b/redis/commands.py index 003b0f1bcc..5750e76b58 100644 --- a/redis/commands.py +++ b/redis/commands.py @@ -1640,7 +1640,7 @@ def xack(self, name, groupname, *ids): return self.execute_command('XACK', name, groupname, *ids) def xadd(self, name, fields, id='*', maxlen=None, approximate=True, - nomkstream=False): + nomkstream=False, minid=None, limit=None): """ Add to a stream. name: name of the stream @@ -1649,6 +1649,8 @@ def xadd(self, name, fields, id='*', maxlen=None, approximate=True, maxlen: truncate old stream members beyond this size approximate: actual stream length may be slightly more than maxlen nomkstream: When set to true, do not make a stream + minid: the minimum id in the stream to query + limit: specifies the maximum number of entries to retrieve """ pieces = [] if maxlen is not None: @@ -1658,6 +1660,17 @@ def xadd(self, name, fields, id='*', maxlen=None, approximate=True, if approximate: pieces.append(b'~') pieces.append(str(maxlen)) + if minid is not None: + pieces.append(b'MINID') + if approximate: + pieces.append(b'~') + pieces.append(minid) + if limit is not None: + if maxlen is None and minid is None: + raise DataError("approximate must be provided with one of " + "```maxlen``` or ```minid```.") + pieces.append(b"LIMIT") + pieces.append(limit) if nomkstream: pieces.append(b'NOMKSTREAM') pieces.append(id) @@ -1667,6 +1680,32 @@ def xadd(self, name, fields, id='*', maxlen=None, approximate=True, pieces.extend(pair) return self.execute_command('XADD', name, *pieces) + + + """if maxlen is not None: + pieces.append(b'MAXLEN') + if minid is not None: + pieces.append(b'MINID') + if approximate: + pieces.append(b'~') + if maxlen is not None: + if not isinstance(maxlen, int) or maxlen < 1: + raise DataError('XADD maxlen must be a positive integer') + pieces.append(str(maxlen)) + if minid is not None: + pieces.append(minid) + if limit is not None: + pieces.append(b"LIMIT") + pieces.append(limit) + if nomkstream: + pieces.append(b'NOMKSTREAM') + pieces.append(id) + if not isinstance(fields, dict) or len(fields) == 0: + raise DataError('XADD fields must be a non-empty dict') + for pair in fields.items(): + pieces.extend(pair) + return self.execute_command('XADD', name, *pieces)""" + def xautoclaim(self, name, groupname, consumername, min_idle_time, start_id=0, count=None, justid=False): """ @@ -2002,7 +2041,7 @@ def xtrim(self, name, maxlen=None, approximate=True, minid=None, name: name of the stream. maxlen: truncate old stream messages beyond this size approximate: actual stream length may be slightly more than maxlen - minin: the minimum id in the stream to query + minid: the minimum id in the stream to query limit: specifies the maximum number of entries to retrieve """ pieces = [] diff --git a/tests/test_commands.py b/tests/test_commands.py index 3c87dd9dd6..595803daa2 100644 --- a/tests/test_commands.py +++ b/tests/test_commands.py @@ -2422,6 +2422,49 @@ def test_xadd_nomkstream(self, r): r.xadd(stream, {'some': 'other'}, nomkstream=True) assert r.xlen(stream) == 3 + @skip_if_server_version_lt('6.2.0') + def test_xadd_minlen_and_length_args(self, r): + stream = 'stream' + + r.xadd(stream, {'foo': 'bar'}) + r.xadd(stream, {'foo': 'bar'}) + r.xadd(stream, {'foo': 'bar'}) + r.xadd(stream, {'foo': 'bar'}) + + # Future self: No limits without approximate, according to the api + with pytest.raises(redis.ResponseError): + assert r.xadd(stream, {'foo': 'bar'}, maxlen=3, approximate=False, limit=2) + + # maxlen with a limit + assert r.xadd(stream, {'foo': 'bar'}, maxlen=3, approximate=True, limit=2) + r.delete(stream) + + # maxlen and minid can not be provided together + with pytest.raises(redis.ResponseError): + assert r.xadd(stream, {'foo': 'bar'}, maxlen=3, minid="sometestvalue") + + # minid with a limit + m1 = r.xadd(stream, {'foo': 'bar'}) + r.xadd(stream, {'foo': 'bar'}) + r.xadd(stream, {'foo': 'bar'}) + r.xadd(stream, {'foo': 'bar'}) + assert r.xadd(stream, {'foo': 'bar'}, approximate=True, minid=m1, limit=3) + + # pure minid + r.xadd(stream, {'foo': 'bar'}) + r.xadd(stream, {'foo': 'bar'}) + r.xadd(stream, {'foo': 'bar'}) + m4 = r.xadd(stream, {'foo': 'bar'}) + assert r.xadd(stream, {'foo': 'bar'}, approximate=False, minid=m4) + + + # minid approximate + r.xadd(stream, {'foo': 'bar'}) + r.xadd(stream, {'foo': 'bar'}) + m3 = r.xadd(stream, {'foo': 'bar'}) + r.xadd(stream, {'foo': 'bar'}) + assert r.xadd(stream, {'foo': 'bar'}, approximate=True, minid=m3) + @skip_if_server_version_lt('6.2.0') def test_xautoclaim(self, r): stream = 'stream' From a4b95e02dca9b4758e3fadd27c90e830e72148f1 Mon Sep 17 00:00:00 2001 From: AvitalFineRedis Date: Thu, 19 Aug 2021 18:23:33 +0300 Subject: [PATCH 2/7] flake8 --- redis/commands.py | 26 -------------------------- tests/test_commands.py | 13 ++++++++----- 2 files changed, 8 insertions(+), 31 deletions(-) diff --git a/redis/commands.py b/redis/commands.py index 5750e76b58..e1b0708411 100644 --- a/redis/commands.py +++ b/redis/commands.py @@ -1680,32 +1680,6 @@ def xadd(self, name, fields, id='*', maxlen=None, approximate=True, pieces.extend(pair) return self.execute_command('XADD', name, *pieces) - - - """if maxlen is not None: - pieces.append(b'MAXLEN') - if minid is not None: - pieces.append(b'MINID') - if approximate: - pieces.append(b'~') - if maxlen is not None: - if not isinstance(maxlen, int) or maxlen < 1: - raise DataError('XADD maxlen must be a positive integer') - pieces.append(str(maxlen)) - if minid is not None: - pieces.append(minid) - if limit is not None: - pieces.append(b"LIMIT") - pieces.append(limit) - if nomkstream: - pieces.append(b'NOMKSTREAM') - pieces.append(id) - if not isinstance(fields, dict) or len(fields) == 0: - raise DataError('XADD fields must be a non-empty dict') - for pair in fields.items(): - pieces.extend(pair) - return self.execute_command('XADD', name, *pieces)""" - def xautoclaim(self, name, groupname, consumername, min_idle_time, start_id=0, count=None, justid=False): """ diff --git a/tests/test_commands.py b/tests/test_commands.py index 595803daa2..6160495465 100644 --- a/tests/test_commands.py +++ b/tests/test_commands.py @@ -2433,22 +2433,26 @@ def test_xadd_minlen_and_length_args(self, r): # Future self: No limits without approximate, according to the api with pytest.raises(redis.ResponseError): - assert r.xadd(stream, {'foo': 'bar'}, maxlen=3, approximate=False, limit=2) + assert r.xadd(stream, {'foo': 'bar'}, maxlen=3, + approximate=False, limit=2) # maxlen with a limit - assert r.xadd(stream, {'foo': 'bar'}, maxlen=3, approximate=True, limit=2) + assert r.xadd(stream, {'foo': 'bar'}, maxlen=3, + approximate=True, limit=2) r.delete(stream) # maxlen and minid can not be provided together with pytest.raises(redis.ResponseError): - assert r.xadd(stream, {'foo': 'bar'}, maxlen=3, minid="sometestvalue") + assert r.xadd(stream, {'foo': 'bar'}, maxlen=3, + minid="sometestvalue") # minid with a limit m1 = r.xadd(stream, {'foo': 'bar'}) r.xadd(stream, {'foo': 'bar'}) r.xadd(stream, {'foo': 'bar'}) r.xadd(stream, {'foo': 'bar'}) - assert r.xadd(stream, {'foo': 'bar'}, approximate=True, minid=m1, limit=3) + assert r.xadd(stream, {'foo': 'bar'}, approximate=True, + minid=m1, limit=3) # pure minid r.xadd(stream, {'foo': 'bar'}) @@ -2457,7 +2461,6 @@ def test_xadd_minlen_and_length_args(self, r): m4 = r.xadd(stream, {'foo': 'bar'}) assert r.xadd(stream, {'foo': 'bar'}, approximate=False, minid=m4) - # minid approximate r.xadd(stream, {'foo': 'bar'}) r.xadd(stream, {'foo': 'bar'}) From 1777cbac251029f0e56603a22c9913379733fa21 Mon Sep 17 00:00:00 2001 From: AvitalFineRedis Date: Thu, 19 Aug 2021 18:35:03 +0300 Subject: [PATCH 3/7] test limit error --- redis/commands.py | 3 --- tests/test_commands.py | 6 +++++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/redis/commands.py b/redis/commands.py index e1b0708411..29471acf09 100644 --- a/redis/commands.py +++ b/redis/commands.py @@ -1666,9 +1666,6 @@ def xadd(self, name, fields, id='*', maxlen=None, approximate=True, pieces.append(b'~') pieces.append(minid) if limit is not None: - if maxlen is None and minid is None: - raise DataError("approximate must be provided with one of " - "```maxlen``` or ```minid```.") pieces.append(b"LIMIT") pieces.append(limit) if nomkstream: diff --git a/tests/test_commands.py b/tests/test_commands.py index 6160495465..aeffda9491 100644 --- a/tests/test_commands.py +++ b/tests/test_commands.py @@ -2423,7 +2423,7 @@ def test_xadd_nomkstream(self, r): assert r.xlen(stream) == 3 @skip_if_server_version_lt('6.2.0') - def test_xadd_minlen_and_length_args(self, r): + def test_xadd_minlen_and_limit(self, r): stream = 'stream' r.xadd(stream, {'foo': 'bar'}) @@ -2436,6 +2436,10 @@ def test_xadd_minlen_and_length_args(self, r): assert r.xadd(stream, {'foo': 'bar'}, maxlen=3, approximate=False, limit=2) + # limit can not be provided without maxlen or minid + with pytest.raises(redis.ResponseError): + assert r.xadd(stream, {'foo': 'bar'}, limit=2) + # maxlen with a limit assert r.xadd(stream, {'foo': 'bar'}, maxlen=3, approximate=True, limit=2) From 3ed46c1fb8d60b474812ad396ffbd9d1a23dd0dc Mon Sep 17 00:00:00 2001 From: AvitalFineRedis Date: Mon, 23 Aug 2021 17:39:54 +0300 Subject: [PATCH 4/7] change docstring --- redis/commands.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/redis/commands.py b/redis/commands.py index 29471acf09..3ffa95559e 100644 --- a/redis/commands.py +++ b/redis/commands.py @@ -1646,10 +1646,10 @@ def xadd(self, name, fields, id='*', maxlen=None, approximate=True, name: name of the stream fields: dict of field/value pairs to insert into the stream id: Location to insert this record. By default it is appended. - maxlen: truncate old stream members beyond this size + maxlen: truncate old stream members beyond this size. Can't be specify with minid. + minid: the minimum id in the stream to query. Can't be specify with maxlen. approximate: actual stream length may be slightly more than maxlen nomkstream: When set to true, do not make a stream - minid: the minimum id in the stream to query limit: specifies the maximum number of entries to retrieve """ pieces = [] From 9167bd2b327197a435cc199b2a54dbb622694242 Mon Sep 17 00:00:00 2001 From: AvitalFineRedis Date: Sun, 29 Aug 2021 08:52:53 +0300 Subject: [PATCH 5/7] mutually exclusive --- redis/commands.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/redis/commands.py b/redis/commands.py index 3ffa95559e..3ebdf87007 100644 --- a/redis/commands.py +++ b/redis/commands.py @@ -1653,6 +1653,10 @@ def xadd(self, name, fields, id='*', maxlen=None, approximate=True, limit: specifies the maximum number of entries to retrieve """ pieces = [] + if maxlen is not None and minid is not None: + raise DataError("Only one of ```maxlen``` or ```minid```", + "may be specified") + if maxlen is not None: if not isinstance(maxlen, int) or maxlen < 1: raise DataError('XADD maxlen must be a positive integer') From e857a9274c8b439249255e28d11cb1e4605d97ac Mon Sep 17 00:00:00 2001 From: AvitalFineRedis Date: Sun, 29 Aug 2021 09:44:34 +0300 Subject: [PATCH 6/7] fix test --- tests/test_commands.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_commands.py b/tests/test_commands.py index aeffda9491..d22d72abcf 100644 --- a/tests/test_commands.py +++ b/tests/test_commands.py @@ -2446,7 +2446,7 @@ def test_xadd_minlen_and_limit(self, r): r.delete(stream) # maxlen and minid can not be provided together - with pytest.raises(redis.ResponseError): + with pytest.raises(redis.DataError): assert r.xadd(stream, {'foo': 'bar'}, maxlen=3, minid="sometestvalue") From b29441b022ab503f7b6f51141130d4d7811fcd88 Mon Sep 17 00:00:00 2001 From: AvitalFineRedis Date: Sun, 29 Aug 2021 10:04:11 +0300 Subject: [PATCH 7/7] flake8 --- redis/commands.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/redis/commands.py b/redis/commands.py index 3ebdf87007..12add0878d 100644 --- a/redis/commands.py +++ b/redis/commands.py @@ -1646,8 +1646,10 @@ def xadd(self, name, fields, id='*', maxlen=None, approximate=True, name: name of the stream fields: dict of field/value pairs to insert into the stream id: Location to insert this record. By default it is appended. - maxlen: truncate old stream members beyond this size. Can't be specify with minid. - minid: the minimum id in the stream to query. Can't be specify with maxlen. + maxlen: truncate old stream members beyond this size. + Can't be specify with minid. + minid: the minimum id in the stream to query. + Can't be specify with maxlen. approximate: actual stream length may be slightly more than maxlen nomkstream: When set to true, do not make a stream limit: specifies the maximum number of entries to retrieve