protocol-redis 0.2.0 → 0.3.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: 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