protocol-redis 0.4.2 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b27fc5c9284df516083590216e58a3a16aa1013c90c86414989b29323f818d7c
4
- data.tar.gz: f30c545712ff3f82e8eb7de43c4351acf2fdd468e42fd187db2b759580d33fef
3
+ metadata.gz: 1be06c92dd3aa593fd22a8e4a437c93d3d74b8cf5308ec7a7721ce48f74d88c5
4
+ data.tar.gz: eaa6c565377014ffae9c6bcd20b02437f6c83126da57cd12c4d768e54a320c3a
5
5
  SHA512:
6
- metadata.gz: 4fd00040f3332fa804f1870e4458731fcb3a1275a31bb87cefc6d85fc3036fa4190adc1040bf012f4feeb7655a37b2b5cef0c90ecbced7facc2ce07502556562
7
- data.tar.gz: 0a1c2700b7e5655be9822e5166cd433a9c4c4d93f29fa1cea095bca72ce29af065378f25f6fef9d0b832a517af6595c33b08605298f848d562bede903381bb3f
6
+ metadata.gz: 6f473cf7bacd6bc990bd412c544f6911248c1a392412a0c85201b33dd60706e50f4cf6fe84c10f82d6018e3952733491aee1bb0113058201af250979cc6091da
7
+ data.tar.gz: 468ddc3e83d7da8165bfebacc1c4860407647c5f8ac66129b0c889742da1da35d97e480cfee2007db172000a685d423840a1fffd81d98a4c9ceb44111486173e
@@ -0,0 +1,34 @@
1
+ name: Development
2
+
3
+ on: [push, pull_request]
4
+
5
+ jobs:
6
+ test:
7
+ strategy:
8
+ matrix:
9
+ os:
10
+ - ubuntu
11
+ - macos
12
+
13
+ ruby:
14
+ - 2.4
15
+ - 2.5
16
+ - 2.6
17
+ - 2.7
18
+
19
+ include:
20
+ - os: 'ubuntu'
21
+ ruby: '2.6'
22
+ env: COVERAGE=PartialSummary,Coveralls
23
+
24
+ runs-on: ${{matrix.os}}-latest
25
+
26
+ steps:
27
+ - uses: actions/checkout@v1
28
+ - uses: ruby/setup-ruby@v1
29
+ with:
30
+ ruby-version: ${{matrix.ruby}}
31
+ - name: Install dependencies
32
+ run: bundle install
33
+ - name: Run tests
34
+ run: ${{matrix.env}} bundle exec rspec
data/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Implements the RESP2 and [RESP3](https://github.com/antirez/RESP3) Redis protocols.
4
4
 
5
- [![Build Status](https://travis-ci.com/socketry/protocol-redis.svg?branch=master)](https://travis-ci.com/socketry/protocol-redis)
5
+ [![Actions Status](https://github.com/socketry/protocol-redis/workflows/Development/badge.svg)](https://github.com/socketry/protocol-redis/actions?workflow=Development)
6
6
 
7
7
  ## Installation
8
8
 
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
22
+
23
+ module Protocol
24
+ module Redis
25
+ module Methods
26
+ module Scripting
27
+ # Execute a Lua script server side. Depends on the script that is executed.
28
+ # @see https://redis.io/commands/eval
29
+ # @param script [String]
30
+ # @param numkeys [Integer]
31
+ # @param key [Key]
32
+ # @param arg [String]
33
+ def eval(*arguments)
34
+ call("EVAL", *arguments)
35
+ end
36
+
37
+ # Execute a Lua script server side. Depends on the script that is executed.
38
+ # @see https://redis.io/commands/evalsha
39
+ # @param sha1 [String]
40
+ # @param numkeys [Integer]
41
+ # @param key [Key]
42
+ # @param arg [String]
43
+ def evalsha(*arguments)
44
+ call("EVALSHA", *arguments)
45
+ end
46
+
47
+ # Set the debug mode for executed scripts. O(1).
48
+ # @see https://redis.io/commands/script debug
49
+ # @param mode [Enum]
50
+ def script_debug(*arguments)
51
+ call("SCRIPT DEBUG", *arguments)
52
+ end
53
+
54
+ # Check existence of scripts in the script cache. O(N) with N being the number of scripts to check (so checking a single script is an O(1) operation).
55
+ # @see https://redis.io/commands/script exists
56
+ # @param sha1 [String]
57
+ def script_exists(*arguments)
58
+ call("SCRIPT EXISTS", *arguments)
59
+ end
60
+
61
+ # Remove all the scripts from the script cache. O(N) with N being the number of scripts in cache.
62
+ # @see https://redis.io/commands/script flush
63
+ def script_flush(*arguments)
64
+ call("SCRIPT FLUSH", *arguments)
65
+ end
66
+
67
+ # Kill the script currently in execution. O(1).
68
+ # @see https://redis.io/commands/script kill
69
+ def script_kill(*arguments)
70
+ call("SCRIPT KILL", *arguments)
71
+ end
72
+
73
+ # Load the specified Lua script into the script cache. O(N) with N being the length in bytes of the script body.
74
+ # @see https://redis.io/commands/script load
75
+ # @param script [String]
76
+ def script_load(*arguments)
77
+ call("SCRIPT LOAD", *arguments)
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,145 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
22
+
23
+ module Protocol
24
+ module Redis
25
+ module Methods
26
+ module Sets
27
+ # Add one or more members to a set. O(1) for each element added, so O(N) to add N elements when the command is called with multiple arguments.
28
+ # @see https://redis.io/commands/sadd
29
+ # @param key [Key]
30
+ # @param member [String]
31
+ def sadd(*arguments)
32
+ call("SADD", *arguments)
33
+ end
34
+
35
+ # Get the number of members in a set. O(1).
36
+ # @see https://redis.io/commands/scard
37
+ # @param key [Key]
38
+ def scard(*arguments)
39
+ call("SCARD", *arguments)
40
+ end
41
+
42
+ # Subtract multiple sets. O(N) where N is the total number of elements in all given sets.
43
+ # @see https://redis.io/commands/sdiff
44
+ # @param key [Key]
45
+ def sdiff(*arguments)
46
+ call("SDIFF", *arguments)
47
+ end
48
+
49
+ # Subtract multiple sets and store the resulting set in a key. O(N) where N is the total number of elements in all given sets.
50
+ # @see https://redis.io/commands/sdiffstore
51
+ # @param destination [Key]
52
+ # @param key [Key]
53
+ def sdiffstore(*arguments)
54
+ call("SDIFFSTORE", *arguments)
55
+ end
56
+
57
+ # Intersect multiple sets. O(N*M) worst case where N is the cardinality of the smallest set and M is the number of sets.
58
+ # @see https://redis.io/commands/sinter
59
+ # @param key [Key]
60
+ def sinter(*arguments)
61
+ call("SINTER", *arguments)
62
+ end
63
+
64
+ # Intersect multiple sets and store the resulting set in a key. O(N*M) worst case where N is the cardinality of the smallest set and M is the number of sets.
65
+ # @see https://redis.io/commands/sinterstore
66
+ # @param destination [Key]
67
+ # @param key [Key]
68
+ def sinterstore(*arguments)
69
+ call("SINTERSTORE", *arguments)
70
+ end
71
+
72
+ # Determine if a given value is a member of a set. O(1).
73
+ # @see https://redis.io/commands/sismember
74
+ # @param key [Key]
75
+ # @param member [String]
76
+ def sismember(*arguments)
77
+ call("SISMEMBER", *arguments)
78
+ end
79
+
80
+ # Get all the members in a set. O(N) where N is the set cardinality.
81
+ # @see https://redis.io/commands/smembers
82
+ # @param key [Key]
83
+ def smembers(*arguments)
84
+ call("SMEMBERS", *arguments)
85
+ end
86
+
87
+ # Move a member from one set to another. O(1).
88
+ # @see https://redis.io/commands/smove
89
+ # @param source [Key]
90
+ # @param destination [Key]
91
+ # @param member [String]
92
+ def smove(*arguments)
93
+ call("SMOVE", *arguments)
94
+ end
95
+
96
+ # Remove and return one or multiple random members from a set. O(1).
97
+ # @see https://redis.io/commands/spop
98
+ # @param key [Key]
99
+ # @param count [Integer]
100
+ def spop(*arguments)
101
+ call("SPOP", *arguments)
102
+ end
103
+
104
+ # Get one or multiple random members from a set. Without the count argument O(1), otherwise O(N) where N is the absolute value of the passed count.
105
+ # @see https://redis.io/commands/srandmember
106
+ # @param key [Key]
107
+ # @param count [Integer]
108
+ def srandmember(*arguments)
109
+ call("SRANDMEMBER", *arguments)
110
+ end
111
+
112
+ # Remove one or more members from a set. O(N) where N is the number of members to be removed.
113
+ # @see https://redis.io/commands/srem
114
+ # @param key [Key]
115
+ # @param member [String]
116
+ def srem(*arguments)
117
+ call("SREM", *arguments)
118
+ end
119
+
120
+ # Add multiple sets. O(N) where N is the total number of elements in all given sets.
121
+ # @see https://redis.io/commands/sunion
122
+ # @param key [Key]
123
+ def sunion(*arguments)
124
+ call("SUNION", *arguments)
125
+ end
126
+
127
+ # Add multiple sets and store the resulting set in a key. O(N) where N is the total number of elements in all given sets.
128
+ # @see https://redis.io/commands/sunionstore
129
+ # @param destination [Key]
130
+ # @param key [Key]
131
+ def sunionstore(*arguments)
132
+ call("SUNIONSTORE", *arguments)
133
+ end
134
+
135
+ # Incrementally iterate Set elements. O(1) for every call. O(N) for a complete iteration, including enough command calls for the cursor to return back to 0. N is the number of elements inside the collection..
136
+ # @see https://redis.io/commands/sscan
137
+ # @param key [Key]
138
+ # @param cursor [Integer]
139
+ def sscan(*arguments)
140
+ call("SSCAN", *arguments)
141
+ end
142
+ end
143
+ end
144
+ end
145
+ end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
3
4
  # Copyright, 2020, by Dimitry Chopey.
4
- # Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
5
5
  #
6
6
  # Permission is hereby granted, free of charge, to any person obtaining a copy
7
7
  # of this software and associated documentation files (the "Software"), to deal
@@ -25,6 +25,22 @@ module Protocol
25
25
  module Redis
26
26
  module Methods
27
27
  module SortedSets
28
+ # Remove and return the member with the lowest score from one or more sorted sets, or block until one is available. O(log(N)) with N being the number of elements in the sorted set.
29
+ # @see https://redis.io/commands/bzpopmin
30
+ # @param key [Key]
31
+ # @param timeout [Integer]
32
+ def bzpopmin(*keys, timeout: 0)
33
+ call("BZPOPMIN", *keys, timeout)
34
+ end
35
+
36
+ # Remove and return the member with the highest score from one or more sorted sets, or block until one is available. O(log(N)) with N being the number of elements in the sorted set.
37
+ # @see https://redis.io/commands/bzpopmax
38
+ # @param key [Key]
39
+ # @param timeout [Integer]
40
+ def bzpopmax(*keys, timeout: 0)
41
+ call("BZPOPMAX", *keys, timeout: 0)
42
+ end
43
+
28
44
  # Add one or more members to a sorted set, or update its score if it already exists. O(log(N)) for each item added, where N is the number of elements in the sorted set.
29
45
  # @see https://redis.io/commands/zadd
30
46
  # @param key [Key]
@@ -41,20 +57,95 @@ module Protocol
41
57
  arguments = ["ZADD", key]
42
58
 
43
59
  if update == true
44
- arguments << "XX"
60
+ arguments.push("XX")
45
61
  elsif update == false
46
- arguments << "NX"
62
+ arguments.push("NX")
47
63
  end
48
64
 
49
- arguments << "CH" if change
50
- arguments << "INCR" if increment
65
+ arguments.push("CH") if change
66
+ arguments.push("INCR") if increment
51
67
 
52
- arguments << score << member
53
- arguments.concat(others)
68
+ arguments.push(score, member)
69
+ arguments.push(*others)
54
70
 
55
71
  call(*arguments)
56
72
  end
57
-
73
+
74
+ # Get the number of members in a sorted set. O(1).
75
+ # @see https://redis.io/commands/zcard
76
+ # @param key [Key]
77
+ def zcard(key)
78
+ call("ZCARD", key)
79
+ end
80
+
81
+ # Count the members in a sorted set with scores within the given values. O(log(N)) with N being the number of elements in the sorted set.
82
+ # @see https://redis.io/commands/zcount
83
+ # @param key [Key]
84
+ # @param min [Double]
85
+ # @param max [Double]
86
+ def zcount(key, min, max)
87
+ call("ZCOUNT", key, min, max)
88
+ end
89
+
90
+ # Increment the score of a member in a sorted set. O(log(N)) where N is the number of elements in the sorted set.
91
+ # @see https://redis.io/commands/zincrby
92
+ # @param key [Key]
93
+ # @param increment [Integer]
94
+ # @param member [String]
95
+ def zincrby(key, increment, member)
96
+ call("ZINCRBY", key, amount, member)
97
+ end
98
+
99
+ # Intersect multiple sorted sets and store the resulting sorted set in a new key. O(N*K)+O(M*log(M)) worst case with N being the smallest input sorted set, K being the number of input sorted sets and M being the number of elements in the resulting sorted set.
100
+ # @see https://redis.io/commands/zinterstore
101
+ # @param destination [Key]
102
+ # @param keys [Array<Key>]
103
+ # @param weights [Array<Integer>]
104
+ # @param aggregate [Enum] one of sum, min, max.
105
+ def zinterstore(destination, keys, weights = nil, aggregate: nil)
106
+ arguments = []
107
+
108
+ if weights
109
+ if weights.size != keys.size
110
+ raise ArgumentError, "#{weights.size} weights given for #{keys.size} keys!"
111
+ end
112
+
113
+ arguments.push("WEIGHTS")
114
+ arguments.concat(weights)
115
+ end
116
+
117
+ if aggregate
118
+ arguments.push("AGGREGATE", aggregate)
119
+ end
120
+
121
+ call("ZINTERSTORE", destination, keys.size, *keys, *arguments)
122
+ end
123
+
124
+ # Count the number of members in a sorted set between a given lexicographical range. O(log(N)) with N being the number of elements in the sorted set.
125
+ # @see https://redis.io/commands/zlexcount
126
+ # @param key [Key]
127
+ # @param min [String]
128
+ # @param max [String]
129
+ def zlexcount(key, min, max)
130
+ call("ZLEXCOUNT", key, min, max)
131
+ end
132
+
133
+ # Remove and return members with the highest scores in a sorted set. O(log(N)*M) with N being the number of elements in the sorted set, and M being the number of elements popped.
134
+ # @see https://redis.io/commands/zpopmax
135
+ # @param key [Key]
136
+ # @param count [Integer]
137
+ def zpopmax(key, count = 1)
138
+ call("ZPOPMAX", key, count)
139
+ end
140
+
141
+ # Remove and return members with the lowest scores in a sorted set. O(log(N)*M) with N being the number of elements in the sorted set, and M being the number of elements popped.
142
+ # @see https://redis.io/commands/zpopmin
143
+ # @param key [Key]
144
+ # @param count [Integer]
145
+ def zpopmin(key, count = 1)
146
+ call("ZPOPMIN", key, count = 1)
147
+ end
148
+
58
149
  # Return a range of members in a sorted set, by index. O(log(N)+M) with N being the number of elements in the sorted set and M the number of elements returned.
59
150
  # @see https://redis.io/commands/zrange
60
151
  # @param key [Key]
@@ -64,11 +155,65 @@ module Protocol
64
155
  def zrange(key, start, stop, with_scores: false)
65
156
  arguments = [start, stop]
66
157
 
67
- arguments << "WITHSCORES" if with_scores
158
+ arguments.push("WITHSCORES") if with_scores
68
159
 
69
160
  call("ZRANGE", key, *arguments)
70
161
  end
71
162
 
163
+ # Return a range of members in a sorted set, by lexicographical range. O(log(N)+M) with N being the number of elements in the sorted set and M the number of elements being returned. If M is constant (e.g. always asking for the first 10 elements with LIMIT), you can consider it O(log(N)).
164
+ # @see https://redis.io/commands/zrangebylex
165
+ # @param key [Key]
166
+ # @param min [String]
167
+ # @param max [String]
168
+ # @param limit [Tuple<offset, count>] Limit the results to the specified `offset` and `count` items.
169
+ def zrangebylex(key, min, max, limit: nil)
170
+ if limit
171
+ arguments = ["LIMIT", *limit]
172
+ end
173
+
174
+ call("ZRANGEBYLEX", key, min, max, *arguments)
175
+ end
176
+
177
+ # Return a range of members in a sorted set, by lexicographical range, ordered from higher to lower strings. O(log(N)+M) with N being the number of elements in the sorted set and M the number of elements being returned. If M is constant (e.g. always asking for the first 10 elements with LIMIT), you can consider it O(log(N)).
178
+ # @see https://redis.io/commands/zrevrangebylex
179
+ # @param key [Key]
180
+ # @param max [String]
181
+ # @param min [String]
182
+ def zrevrangebylex(key, min, max, limit: nil)
183
+ if limit
184
+ arguments = ["LIMIT", *limit]
185
+ end
186
+
187
+ call("ZREVRANGEBYLEX", key, min, max, *arguments)
188
+ end
189
+
190
+ # Return a range of members in a sorted set, by score. O(log(N)+M) with N being the number of elements in the sorted set and M the number of elements being returned. If M is constant (e.g. always asking for the first 10 elements with LIMIT), you can consider it O(log(N)).
191
+ # @see https://redis.io/commands/zrangebyscore
192
+ # @param key [Key]
193
+ # @param min [Integer]
194
+ # @param max [Integer]
195
+ # @param with_scores [Boolean] Return the scores of the elements together with the elements.
196
+ # @param limit [Tuple<offset, count>] Limit the results to the specified `offset` and `count` items.
197
+ #
198
+ # @example Retrieve the first 10 members with score `>= 0` and `<= 100`
199
+ # redis.zrangebyscore("zset", "0", "100", limit: [0, 10])
200
+ def zrangebyscore(key, min, max, with_scores: false, limit: nil)
201
+ arguments = [min, max]
202
+
203
+ arguments.push('WITHSCORES') if with_scores
204
+ arguments.push('LIMIT', *limit) if limit
205
+
206
+ call('ZRANGEBYSCORE', key, *arguments)
207
+ end
208
+
209
+ # Determine the index of a member in a sorted set. O(log(N)).
210
+ # @see https://redis.io/commands/zrank
211
+ # @param key [Key]
212
+ # @param member [String]
213
+ def zrank(key, member)
214
+ call("ZRANK", key, member)
215
+ end
216
+
72
217
  # Remove one or more members from a sorted set. O(M*log(N)) with N being the number of elements in the sorted set and M the number of elements to be removed.
73
218
  # @see https://redis.io/commands/zrem
74
219
  # @param key [Key]
@@ -76,6 +221,105 @@ module Protocol
76
221
  def zrem(key, member)
77
222
  call("ZREM", key, member)
78
223
  end
224
+
225
+ # Remove all members in a sorted set between the given lexicographical range. O(log(N)+M) with N being the number of elements in the sorted set and M the number of elements removed by the operation.
226
+ # @see https://redis.io/commands/zremrangebylex
227
+ # @param key [Key]
228
+ # @param min [String]
229
+ # @param max [String]
230
+ def zremrangebylex(key, min, max)
231
+ call("ZREMRANGEBYLEX", key, min, max)
232
+ end
233
+
234
+ # Remove all members in a sorted set within the given indexes. O(log(N)+M) with N being the number of elements in the sorted set and M the number of elements removed by the operation.
235
+ # @see https://redis.io/commands/zremrangebyrank
236
+ # @param key [Key]
237
+ # @param start [Integer]
238
+ # @param stop [Integer]
239
+ def zremrangebyrank(key, start, stop)
240
+ call("ZREMRANGEBYRANK", key, start, stop)
241
+ end
242
+
243
+ # Remove all members in a sorted set within the given scores. O(log(N)+M) with N being the number of elements in the sorted set and M the number of elements removed by the operation.
244
+ # @see https://redis.io/commands/zremrangebyscore
245
+ # @param key [Key]
246
+ # @param min [Double]
247
+ # @param max [Double]
248
+ def zremrangebyscore(key, min, max)
249
+ call("ZREMRANGEBYSCORE", key, min, max)
250
+ end
251
+
252
+ # Return a range of members in a sorted set, by index, with scores ordered from high to low. O(log(N)+M) with N being the number of elements in the sorted set and M the number of elements returned.
253
+ # @see https://redis.io/commands/zrevrange
254
+ # @param key [Key]
255
+ # @param start [Integer]
256
+ # @param stop [Integer]
257
+ # @param withscores [Enum]
258
+ def zrevrange(key, min, max, with_scores: false)
259
+ arguments = [min, max]
260
+
261
+ arguments.push('WITHSCORES') if with_scores
262
+
263
+ call("ZREVRANGE", key, *arguments)
264
+ end
265
+
266
+ # Return a range of members in a sorted set, by score, with scores ordered from high to low. O(log(N)+M) with N being the number of elements in the sorted set and M the number of elements being returned. If M is constant (e.g. always asking for the first 10 elements with LIMIT), you can consider it O(log(N)).
267
+ # @see https://redis.io/commands/zrevrangebyscore
268
+ # @param key [Key]
269
+ # @param max [Double]
270
+ # @param min [Double]
271
+ # @param withscores [Enum]
272
+ def zrevrangebyscore(key, min, max, with_scores: false, limit: nil)
273
+ arguments = [min, max]
274
+
275
+ arguments.push('WITHSCORES') if with_scores
276
+ arguments.push('LIMIT', *limit) if limit
277
+
278
+ call("ZREVRANGEBYSCORE", key, *arguments)
279
+ end
280
+
281
+ # Determine the index of a member in a sorted set, with scores ordered from high to low. O(log(N)).
282
+ # @see https://redis.io/commands/zrevrank
283
+ # @param key [Key]
284
+ # @param member [String]
285
+ def zrevrank(key, member)
286
+ call("ZREVRANK", key, member)
287
+ end
288
+
289
+ # Get the score associated with the given member in a sorted set. O(1).
290
+ # @see https://redis.io/commands/zscore
291
+ # @param key [Key]
292
+ # @param member [String]
293
+ def zscore(key, member)
294
+ call("ZSCORE", key, member)
295
+ end
296
+
297
+ # Add multiple sorted sets and store the resulting sorted set in a new key. O(N)+O(M log(M)) with N being the sum of the sizes of the input sorted sets, and M being the number of elements in the resulting sorted set.
298
+ # @see https://redis.io/commands/zunionstore
299
+ # @param destination [Key]
300
+ # @param numkeys [Integer]
301
+ # @param key [Key]
302
+ def zunionstore(*arguments)
303
+ call("ZUNIONSTORE", *arguments)
304
+ end
305
+
306
+ # Incrementally iterate sorted sets elements and associated scores. O(1) for every call. O(N) for a complete iteration, including enough command calls for the cursor to return back to 0. N is the number of elements inside the collection..
307
+ # @see https://redis.io/commands/zscan
308
+ # @param key [Key]
309
+ # @param cursor [Integer]
310
+ def zscan(key, cursor = 0, match: nil, count: nil)
311
+ arguments = [key, cursor]
312
+
313
+ if match
314
+ arguments.push("MATCH", match)
315
+ end
316
+
317
+ if count
318
+ arguments.push("COUNT", count)
319
+ end
320
+
321
+ call("ZSCAN", *arguments)
322
+ end
79
323
  end
80
324
  end
81
325
  end
@@ -0,0 +1,141 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
22
+
23
+ module Protocol
24
+ module Redis
25
+ module Methods
26
+ module Streams
27
+ # Get information on streams and consumer groups. O(N) with N being the number of returned items for the subcommands CONSUMERS and GROUPS. The STREAM subcommand is O(log N) with N being the number of items in the stream.
28
+ # @see https://redis.io/commands/xinfo
29
+ # @param help [Enum]
30
+ def xinfo(*arguments)
31
+ call("XINFO", *arguments)
32
+ end
33
+
34
+ # Appends a new entry to a stream. O(1).
35
+ # @see https://redis.io/commands/xadd
36
+ # @param key [Key]
37
+ # @param ID [String]
38
+ def xadd(*arguments)
39
+ call("XADD", *arguments)
40
+ end
41
+
42
+ # Trims the stream to (approximately if '~' is passed) a certain size. O(N), with N being the number of evicted entries. Constant times are very small however, since entries are organized in macro nodes containing multiple entries that can be released with a single deallocation.
43
+ # @see https://redis.io/commands/xtrim
44
+ # @param key [Key]
45
+ # @param strategy [Enum]
46
+ # @param approx [Enum]
47
+ # @param count [Integer]
48
+ def xtrim(*arguments)
49
+ call("XTRIM", *arguments)
50
+ end
51
+
52
+ # Removes the specified entries from the stream. Returns the number of items actually deleted, that may be different from the number of IDs passed in case certain IDs do not exist. O(1) for each single item to delete in the stream, regardless of the stream size.
53
+ # @see https://redis.io/commands/xdel
54
+ # @param key [Key]
55
+ # @param ID [String]
56
+ def xdel(*arguments)
57
+ call("XDEL", *arguments)
58
+ end
59
+
60
+ # Return a range of elements in a stream, with IDs matching the specified IDs interval. O(N) with N being the number of elements being returned. If N is constant (e.g. always asking for the first 10 elements with COUNT), you can consider it O(1).
61
+ # @see https://redis.io/commands/xrange
62
+ # @param key [Key]
63
+ # @param start [String]
64
+ # @param end [String]
65
+ def xrange(*arguments)
66
+ call("XRANGE", *arguments)
67
+ end
68
+
69
+ # Return a range of elements in a stream, with IDs matching the specified IDs interval, in reverse order (from greater to smaller IDs) compared to XRANGE. O(N) with N being the number of elements returned. If N is constant (e.g. always asking for the first 10 elements with COUNT), you can consider it O(1).
70
+ # @see https://redis.io/commands/xrevrange
71
+ # @param key [Key]
72
+ # @param end [String]
73
+ # @param start [String]
74
+ def xrevrange(*arguments)
75
+ call("XREVRANGE", *arguments)
76
+ end
77
+
78
+ # Return the number of entires in a stream. O(1).
79
+ # @see https://redis.io/commands/xlen
80
+ # @param key [Key]
81
+ def xlen(*arguments)
82
+ call("XLEN", *arguments)
83
+ end
84
+
85
+ # Return never seen elements in multiple streams, with IDs greater than the ones reported by the caller for each stream. Can block. For each stream mentioned: O(N) with N being the number of elements being returned, it means that XREAD-ing with a fixed COUNT is O(1). Note that when the BLOCK option is used, XADD will pay O(M) time in order to serve the M clients blocked on the stream getting new data.
86
+ # @see https://redis.io/commands/xread
87
+ # @param streams [Enum]
88
+ # @param key [Key]
89
+ # @param id [String]
90
+ def xread(*arguments)
91
+ call("XREAD", *arguments)
92
+ end
93
+
94
+ # Create, destroy, and manage consumer groups. O(1) for all the subcommands, with the exception of the DESTROY subcommand which takes an additional O(M) time in order to delete the M entries inside the consumer group pending entries list (PEL).
95
+ # @see https://redis.io/commands/xgroup
96
+ def xgroup(*arguments)
97
+ call("XGROUP", *arguments)
98
+ end
99
+
100
+ # Return new entries from a stream using a consumer group, or access the history of the pending entries for a given consumer. Can block. For each stream mentioned: O(M) with M being the number of elements returned. If M is constant (e.g. always asking for the first 10 elements with COUNT), you can consider it O(1). On the other side when XREADGROUP blocks, XADD will pay the O(N) time in order to serve the N clients blocked on the stream getting new data.
101
+ # @see https://redis.io/commands/xreadgroup
102
+ # @param noack [Enum]
103
+ # @param streams [Enum]
104
+ # @param key [Key]
105
+ # @param ID [String]
106
+ def xreadgroup(*arguments)
107
+ call("XREADGROUP", *arguments)
108
+ end
109
+
110
+ # Marks a pending message as correctly processed, effectively removing it from the pending entries list of the consumer group. Return value of the command is the number of messages successfully acknowledged, that is, the IDs we were actually able to resolve in the PEL. O(1) for each message ID processed.
111
+ # @see https://redis.io/commands/xack
112
+ # @param key [Key]
113
+ # @param group [String]
114
+ # @param ID [String]
115
+ def xack(*arguments)
116
+ call("XACK", *arguments)
117
+ end
118
+
119
+ # Changes (or acquires) ownership of a message in a consumer group, as if the message was delivered to the specified consumer. O(log N) with N being the number of messages in the PEL of the consumer group.
120
+ # @see https://redis.io/commands/xclaim
121
+ # @param key [Key]
122
+ # @param group [String]
123
+ # @param consumer [String]
124
+ # @param min-idle-time [String]
125
+ # @param ID [String]
126
+ def xclaim(*arguments)
127
+ call("XCLAIM", *arguments)
128
+ end
129
+
130
+ # Return information and entries from a stream consumer group pending entries list, that are messages fetched but never acknowledged. O(N) with N being the number of elements returned, so asking for a small fixed number of entries per call is O(1). When the command returns just the summary it runs in O(1) time assuming the list of consumers is small, otherwise there is additional O(N) time needed to iterate every consumer.
131
+ # @see https://redis.io/commands/xpending
132
+ # @param key [Key]
133
+ # @param group [String]
134
+ # @param consumer [String]
135
+ def xpending(*arguments)
136
+ call("XPENDING", *arguments)
137
+ end
138
+ end
139
+ end
140
+ end
141
+ end
@@ -22,6 +22,6 @@
22
22
 
23
23
  module Protocol
24
24
  module Redis
25
- VERSION = "0.4.2"
25
+ VERSION = "0.5.0"
26
26
  end
27
27
  end
@@ -2,19 +2,18 @@
2
2
  require_relative 'lib/protocol/redis/version'
3
3
 
4
4
  Gem::Specification.new do |spec|
5
- spec.name = "protocol-redis"
6
- spec.version = Protocol::Redis::VERSION
7
- spec.authors = ["Samuel Williams", "Huba Nagy"]
8
- spec.email = ["samuel.williams@oriontransfer.co.nz", "12huba@gmail.com"]
9
-
10
- spec.summary = "A RESP protocol client/server parser."
11
- spec.homepage = "https://github.com/socketry/protocol-redis"
12
-
13
- spec.files = `git ls-files -z`.split("\x0").reject do |f|
5
+ spec.name = "protocol-redis"
6
+ spec.version = Protocol::Redis::VERSION
7
+ spec.authors = ["Samuel Williams", "Huba Nagy"]
8
+ spec.email = ["samuel.williams@oriontransfer.co.nz", "12huba@gmail.com"]
9
+
10
+ spec.summary = "A transport agnostic RESP protocol client/server."
11
+ spec.homepage = "https://github.com/socketry/protocol-redis"
12
+
13
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
14
14
  f.match(%r{^(test|spec|features)/})
15
15
  end
16
16
 
17
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
17
  spec.require_paths = ["lib"]
19
18
 
20
19
  spec.add_development_dependency "async-http"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: protocol-redis
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2020-02-11 00:00:00.000000000 Z
12
+ date: 2020-02-22 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: async-http
@@ -118,9 +118,9 @@ extensions: []
118
118
  extra_rdoc_files: []
119
119
  files:
120
120
  - ".editorconfig"
121
+ - ".github/workflows/development.yml"
121
122
  - ".gitignore"
122
123
  - ".rspec"
123
- - ".travis.yml"
124
124
  - Gemfile
125
125
  - README.md
126
126
  - Rakefile
@@ -135,8 +135,11 @@ files:
135
135
  - lib/protocol/redis/methods/geospatial.rb
136
136
  - lib/protocol/redis/methods/hashes.rb
137
137
  - lib/protocol/redis/methods/lists.rb
138
+ - lib/protocol/redis/methods/scripting.rb
138
139
  - lib/protocol/redis/methods/server.rb
140
+ - lib/protocol/redis/methods/sets.rb
139
141
  - lib/protocol/redis/methods/sorted_sets.rb
142
+ - lib/protocol/redis/methods/streams.rb
140
143
  - lib/protocol/redis/methods/strings.rb
141
144
  - lib/protocol/redis/version.rb
142
145
  - protocol-redis.gemspec
@@ -160,8 +163,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
160
163
  - !ruby/object:Gem::Version
161
164
  version: '0'
162
165
  requirements: []
163
- rubygems_version: 3.0.6
166
+ rubygems_version: 3.1.2
164
167
  signing_key:
165
168
  specification_version: 4
166
- summary: A RESP protocol client/server parser.
169
+ summary: A transport agnostic RESP protocol client/server.
167
170
  test_files: []
@@ -1,22 +0,0 @@
1
- language: ruby
2
- dist: xenial
3
- cache: bundler
4
-
5
- services:
6
- - redis-server
7
-
8
- matrix:
9
- include:
10
- - rvm: 2.5
11
- - rvm: 2.6
12
- - rvm: 2.7
13
- - rvm: 2.6
14
- env: COVERAGE=BriefSummary,Coveralls
15
- - rvm: ruby-head
16
- - rvm: truffleruby
17
- - rvm: jruby-head
18
- env: JRUBY_OPTS="--debug -X+O"
19
- allow_failures:
20
- - rvm: ruby-head
21
- - rvm: truffleruby
22
- - rvm: jruby-head