protocol-redis 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: eaec89c45931d2380b65c26b642dc53cc65b0c2b93251c57fa9831fa8aa654a6
4
- data.tar.gz: 87be2b36ea8deeb9eef4ed56f2e833120a8641fa4256feb0decb4f8ee73b4f64
3
+ metadata.gz: 3a43936672dd294704fcfd56d9e30a0a7a8f3102fc87e6decdced5fe18c5247c
4
+ data.tar.gz: 1b18d65000b1d45d35b1f5b2ec8dff64672a78e316b2129c58d99c057af18aa6
5
5
  SHA512:
6
- metadata.gz: 9c4bf2da40ab8a0090e08428a26f2bdf1b02c1c210a805945d8ff001c5836d6bc3710e1889cd192f0f862bd17dfeb1a6c83dec2cae55ee407b216a96edfd9666
7
- data.tar.gz: 4a737e454c0fcdd0c2469f9770caa1e6c4bbe309c2a80a15b5a4937462c5628d175ab59390c075b4d2edd07497ff6bd6947396d0239b11859a89c95fb3962f03
6
+ metadata.gz: 94099bfe814a49a29a26d9eae937c6420a13bc1e0ae1f669dcd39a185581f8ba7ea309cdcc2d7ba53dd28e79fbfad1c4c69bc68302fac5d4a104b163d88e27eb
7
+ data.tar.gz: e5bd1cbdcb78bf4f2ca031d81b7b3504bea322be315265874cf61d9439ee554ea5fb96552cebf0612d65388379976174b4e35a7b631009286970377ccdd776a7
data/Rakefile CHANGED
@@ -1,6 +1,8 @@
1
1
  require "bundler/gem_tasks"
2
2
  require "rspec/core/rake_task"
3
3
 
4
- RSpec::Core::RakeTask.new(:test)
4
+ Dir.glob('tasks/**/*.rake').each{|path| load(path)}
5
5
 
6
- task :default => :test
6
+ RSpec::Core::RakeTask.new
7
+
8
+ task :default => :spec
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
4
  #
3
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright, 2019, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
4
  #
3
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -27,10 +29,16 @@ module Protocol
27
29
 
28
30
  def initialize(stream)
29
31
  @stream = stream
32
+
33
+ # Number of requests sent:
34
+ @count = 0
30
35
  end
31
36
 
32
37
  attr :stream
33
38
 
39
+ # @attr [Integer] Number of requests sent.
40
+ attr :count
41
+
34
42
  def close
35
43
  @stream.close
36
44
  end
@@ -51,6 +59,8 @@ module Protocol
51
59
  def write_request(arguments)
52
60
  write_lines("*#{arguments.size}")
53
61
 
62
+ @count += 1
63
+
54
64
  arguments.each do |argument|
55
65
  string = argument.to_s
56
66
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright, 2019, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
4
  #
3
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright, 2019, by Mikael Henriksson. <http://www.mhenrixon.com>
2
4
  #
3
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -18,20 +20,30 @@
18
20
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
21
  # THE SOFTWARE.
20
22
 
23
+ require_relative 'methods/generic'
24
+ require_relative 'methods/connection'
25
+ require_relative 'methods/server'
26
+ require_relative 'methods/geospatial'
27
+
28
+ require_relative 'methods/counting'
29
+
21
30
  require_relative 'methods/hashes'
22
- require_relative 'methods/keys'
23
31
  require_relative 'methods/lists'
24
- require_relative 'methods/server'
25
32
  require_relative 'methods/strings'
26
33
 
27
34
  module Protocol
28
35
  module Redis
29
36
  module Methods
30
37
  def self.included(klass)
38
+ klass.include Methods::Generic
39
+ klass.include Methods::Connection
40
+ klass.include Methods::Server
41
+ klass.include Methods::Geospatial
42
+
43
+ klass.include Methods::Counting
44
+
31
45
  klass.include Methods::Hashes
32
- klass.include Methods::Keys
33
46
  klass.include Methods::Lists
34
- klass.include Methods::Server
35
47
  klass.include Methods::Strings
36
48
  end
37
49
  end
@@ -0,0 +1,56 @@
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 Connection
27
+ # Authenticate to the server.
28
+ # @see https://redis.io/commands/auth
29
+ # @param password [String]
30
+ def auth(password)
31
+ call("AUTH", password)
32
+ end
33
+
34
+ # Echo the given string.
35
+ # @see https://redis.io/commands/echo
36
+ # @param message [String]
37
+ def echo(message)
38
+ call("ECHO", message)
39
+ end
40
+
41
+ # Ping the server.
42
+ # @see https://redis.io/commands/ping
43
+ # @param message [String]
44
+ def ping(message)
45
+ call("PING", message)
46
+ end
47
+
48
+ # Close the connection.
49
+ # @see https://redis.io/commands/quit
50
+ def quit
51
+ call("QUIT")
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,52 @@
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 Counting
27
+ # Adds the specified elements to the specified HyperLogLog. O(1) to add every element.
28
+ # @see https://redis.io/commands/pfadd
29
+ # @param key [Key]
30
+ # @param element [String]
31
+ def pfadd(key, element, *elements)
32
+ call("PFADD", key, element, *elements)
33
+ end
34
+
35
+ # Return the approximated cardinality of the set(s) observed by the HyperLogLog at key(s). O(1) with a very small average constant time when called with a single key. O(N) with N being the number of keys, and much bigger constant times, when called with multiple keys.
36
+ # @see https://redis.io/commands/pfcount
37
+ # @param key [Key]
38
+ def pfcount(key, *keys)
39
+ call("PFCOUNT", key, *keys)
40
+ end
41
+
42
+ # Merge N different HyperLogLogs into a single one. O(N) to merge N HyperLogLogs, but with high constant times.
43
+ # @see https://redis.io/commands/pfmerge
44
+ # @param destkey [Key]
45
+ # @param sourcekey [Key]
46
+ def pfmerge(destkey, sourcekey, *sourcekeys)
47
+ call("PFMERGE", destkey, sourcekey, *sourcekeys)
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,304 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
+ # Copyright, 2018, by Huba Nagy.
5
+ #
6
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ # of this software and associated documentation files (the "Software"), to deal
8
+ # in the Software without restriction, including without limitation the rights
9
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ # copies of the Software, and to permit persons to whom the Software is
11
+ # furnished to do so, subject to the following conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be included in
14
+ # all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ # THE SOFTWARE.
23
+
24
+ require 'date'
25
+
26
+ module Protocol
27
+ module Redis
28
+ module Methods
29
+ module Generic
30
+ # Delete a key. O(N) where N is the number of keys that will be removed. When a key to remove holds a value other than a string, the individual complexity for this key is O(M) where M is the number of elements in the list, set, sorted set or hash. Removing a single key that holds a string value is O(1).
31
+ # @see https://redis.io/commands/del
32
+ # @param key [Key]
33
+ def del(*keys)
34
+ if keys.any?
35
+ return call('DEL', *keys)
36
+ end
37
+ end
38
+
39
+ # Return a serialized version of the value stored at the specified key. O(1) to access the key and additional O(N*M) to serialized it, where N is the number of Redis objects composing the value and M their average size. For small string values the time complexity is thus O(1)+O(1*M) where M is small, so simply O(1).
40
+ # @see https://redis.io/commands/dump
41
+ # @param key [Key]
42
+ def dump(key)
43
+ return call('DUMP', key)
44
+ end
45
+
46
+ # Determine if a key exists. O(1).
47
+ # @see https://redis.io/commands/exists
48
+ # @param key [Key]
49
+ def exists(key, *keys)
50
+ return call('EXISTS', key, *keys)
51
+ end
52
+
53
+ # Set a key's time to live in seconds. O(1).
54
+ # @see https://redis.io/commands/expire
55
+ # @param key [Key]
56
+ # @param seconds [Integer]
57
+ def expire(key, seconds)
58
+ return call('EXPIRE', key, seconds)
59
+ end
60
+
61
+ # Set the expiration for a key as a UNIX timestamp. O(1).
62
+ # @see https://redis.io/commands/expireat
63
+ # @param key [Key]
64
+ # @param timestamp [Posix time]
65
+ def expireat(key, time)
66
+ case time
67
+ when DateTime, Time, Date
68
+ timestamp = time.strftime('%s').to_i
69
+ else
70
+ timestamp = time
71
+ end
72
+
73
+ return call('EXPIREAT', key, timestamp)
74
+ end
75
+
76
+ # Find all keys matching the given pattern. O(N) with N being the number of keys in the database, under the assumption that the key names in the database and the given pattern have limited length.
77
+ # @see https://redis.io/commands/keys
78
+ # @param pattern [Pattern]
79
+ def keys(pattern)
80
+ return call('KEYS', pattern)
81
+ end
82
+
83
+ # Atomically transfer a key from a Redis instance to another one. This command actually executes a DUMP+DEL in the source instance, and a RESTORE in the target instance. See the pages of these commands for time complexity. Also an O(N) data transfer between the two instances is performed.
84
+ # @see https://redis.io/commands/migrate
85
+ # @param host [String]
86
+ # @param port [String]
87
+ # @param key [Enum]
88
+ # @param destination-db [Integer]
89
+ # @param timeout [Integer]
90
+ # @param copy [Enum]
91
+ # @param replace [Enum]
92
+ def migrate(host, port, destination = 0, keys:, timeout: 0, copy: false, replace: false, auth: nil)
93
+ raise ArgumentError, "Must provide keys" if keys.empty?
94
+
95
+ arguments = [host, port]
96
+
97
+ if keys.size == 1
98
+ arguments.append(*keys)
99
+ else
100
+ arguments.append("")
101
+ end
102
+
103
+ arguments.append(destination, timeout)
104
+
105
+ if copy
106
+ arguments.append("COPY")
107
+ end
108
+
109
+ if replace
110
+ arguments.append("REPLACE")
111
+ end
112
+
113
+ if auth
114
+ arguments.append("AUTH", auth)
115
+ end
116
+
117
+ if keys.size > 1
118
+ arguments.append("KEYS", *keys)
119
+ end
120
+
121
+ return call("MIGRATE", *arguments)
122
+ end
123
+
124
+ # Move a key to another database. O(1).
125
+ # @see https://redis.io/commands/move
126
+ # @param key [Key]
127
+ # @param db [Integer]
128
+ def move(key, db)
129
+ return call('MOVE', key, db)
130
+ end
131
+
132
+ # Inspect the internals of Redis objects. O(1) for all the currently implemented subcommands.
133
+ # @see https://redis.io/commands/object
134
+ # @param subcommand [String]
135
+ # @param arguments [String]
136
+ def object(subcommand, *arguments)
137
+ call('OBJECT', subcommand, *arguments)
138
+ end
139
+
140
+ # Remove the expiration from a key. O(1).
141
+ # @see https://redis.io/commands/persist
142
+ # @param key [Key]
143
+ def persist(key)
144
+ return call('PERSIST', key)
145
+ end
146
+
147
+ # Set a key's time to live in milliseconds. O(1).
148
+ # @see https://redis.io/commands/pexpire
149
+ # @param key [Key]
150
+ # @param milliseconds [Integer]
151
+ def pexpire(key, milliseconds)
152
+ return call('PEXPIRE', milliseconds)
153
+ end
154
+
155
+ # Set the expiration for a key as a UNIX timestamp specified in milliseconds. O(1).
156
+ # @see https://redis.io/commands/pexpireat
157
+ # @param key [Key]
158
+ # @param milliseconds-timestamp [Posix time]
159
+ def pexpireat(key, time)
160
+ case time.class
161
+ when DateTime, Time, Date
162
+ timestamp = time.strftime('%Q').to_i
163
+ else
164
+ timestamp = time
165
+ end
166
+
167
+ return call('PEXPIREAT', key, timestamp)
168
+ end
169
+
170
+ # Get the time to live for a key in milliseconds. O(1).
171
+ # @see https://redis.io/commands/pttl
172
+ # @param key [Key]
173
+ def pttl(key)
174
+ return call('PTTL', key)
175
+ end
176
+
177
+ # Return a random key from the keyspace. O(1).
178
+ # @see https://redis.io/commands/randomkey
179
+ def randomkey
180
+ return call('RANDOMKEY')
181
+ end
182
+
183
+ # Rename a key. O(1).
184
+ # @see https://redis.io/commands/rename
185
+ # @param key [Key]
186
+ # @param newkey [Key]
187
+ def rename(key, new_key)
188
+ return call('RENAME', key, new_key)
189
+ end
190
+
191
+ # Rename a key, only if the new key does not exist. O(1).
192
+ # @see https://redis.io/commands/renamenx
193
+ # @param key [Key]
194
+ # @param newkey [Key]
195
+ def renamenx(key, new_key)
196
+ return call('RENAMENX', key, new_key)
197
+ end
198
+
199
+ # Create a key using the provided serialized value, previously obtained using DUMP. O(1) to create the new key and additional O(N*M) to reconstruct the serialized value, where N is the number of Redis objects composing the value and M their average size. For small string values the time complexity is thus O(1)+O(1*M) where M is small, so simply O(1). However for sorted set values the complexity is O(N*M*log(N)) because inserting values into sorted sets is O(log(N)).
200
+ # @see https://redis.io/commands/restore
201
+ # @param key [Key]
202
+ # @param ttl [Integer]
203
+ # @param serialized-value [String]
204
+ # @param replace [Enum]
205
+ # @param absttl [Enum]
206
+ def restore(key, serialized_value, ttl=0)
207
+ return call('RESTORE', key, ttl, serialized_value)
208
+ end
209
+
210
+ # Incrementally iterate the keys space. 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.
211
+ # @see https://redis.io/commands/scan
212
+ # @param cursor [Integer]
213
+ def scan(cursor, match: nil, count: nil, type: nil)
214
+ arguments = [cursor]
215
+
216
+ if match
217
+ arguments.append("MATCH", match)
218
+ end
219
+
220
+ if count
221
+ arguments.append("COUNT", count)
222
+ end
223
+
224
+ if type
225
+ arguments.append("TYPE", type)
226
+ end
227
+
228
+ return call("SCAN", *arguments)
229
+ end
230
+
231
+ # Sort the elements in a list, set or sorted set. O(N+M*log(M)) where N is the number of elements in the list or set to sort, and M the number of returned elements. When the elements are not sorted, complexity is currently O(N) as there is a copy step that will be avoided in next releases.
232
+ # @see https://redis.io/commands/sort
233
+ # @param key [Key]
234
+ # @param order [Enum]
235
+ # @param sorting [Enum]
236
+ def sort(key, by: nil, offset: nil, count: nil, get: nil, order: 'ASC', alpha: false, store: nil)
237
+ arguments = []
238
+
239
+ if by
240
+ arguments.append("BY", by)
241
+ end
242
+
243
+ if offset and count
244
+ arguments.append("LIMIT", offset, count)
245
+ end
246
+
247
+ get&.each do |pattern|
248
+ arguments.append("GET", pattern)
249
+ end
250
+
251
+ if order
252
+ arguments.append(order)
253
+ end
254
+
255
+ if alpha
256
+ arguments.append("ALPHA")
257
+ end
258
+
259
+ if store
260
+ arguments.append("STORE", store)
261
+ end
262
+
263
+ return call('SORT', *arguments)
264
+ end
265
+
266
+ # Alters the last access time of a key(s). Returns the number of existing keys specified. O(N) where N is the number of keys that will be touched.
267
+ # @see https://redis.io/commands/touch
268
+ # @param key [Key]
269
+ def touch(key, *keys)
270
+ return call('TOUCH', key, *keys)
271
+ end
272
+
273
+ # Get the time to live for a key. O(1).
274
+ # @see https://redis.io/commands/ttl
275
+ # @param key [Key]
276
+ def ttl(key)
277
+ return call('TTL', key)
278
+ end
279
+
280
+ # Determine the type stored at key. O(1).
281
+ # @see https://redis.io/commands/type
282
+ # @param key [Key]
283
+ def type(key)
284
+ return call('TYPE', key)
285
+ end
286
+
287
+ # Delete a key asynchronously in another thread. Otherwise it is just as DEL, but non blocking. O(1) for each key removed regardless of its size. Then the command does O(N) work in a different thread in order to reclaim memory, where N is the number of allocations the deleted objects where composed of.
288
+ # @see https://redis.io/commands/unlink
289
+ # @param key [Key]
290
+ def unlink(key)
291
+ return call('UNLINK', key)
292
+ end
293
+
294
+ # Wait for the synchronous replication of all the write commands sent in the context of the current connection. O(1).
295
+ # @see https://redis.io/commands/wait
296
+ # @param numreplicas [Integer]
297
+ # @param timeout [Integer]
298
+ def wait(newreplicas, timeout = 0)
299
+ return call("WAIT", numreplicas, timeout)
300
+ end
301
+ end
302
+ end
303
+ end
304
+ end