oxblood 0.1.0.dev7 → 0.1.0.dev8

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
  SHA1:
3
- metadata.gz: 007983f13baaa6978b6db2a3fe4fc821abaa8f56
4
- data.tar.gz: e96fbcaca9bcb69f95ddbae0d2ae606bf8fc0954
3
+ metadata.gz: 5de6f805e09661746b328df9a6654848a4937307
4
+ data.tar.gz: 8a6f7be7ff52ec6eeda55d852fbd7809c746224f
5
5
  SHA512:
6
- metadata.gz: 553a57f8b85f9407758c60cab222bbbfcc7804d74d1daad993bd46aec2099449159a3f8911bcb55e4957a62ae64d945ef7e6064bb121035ed7f09f683aa95b25
7
- data.tar.gz: 0f7a5078313ffde39c70c4ffc2a87089881fcf4e8968591eaaf35bf4ee93c139a505e6572c924afb59eed75fe0e9308a78692c9a9e8fdac7d3f753116885e4c6
6
+ metadata.gz: 34d5e0b3b3547205df5d72388b81a24f862f6887d90ff87672304fdebf62bed3eb8c5bf097274df1f5ff13aa84154eeb130f3e4768eaac3c141a2543c6a793c2
7
+ data.tar.gz: 74a234ad3c08837d61c6e355188190f6af04f0bb4df7245d6cf8edaecaf5b799fb49f49fdc962a22c71f13cd1e05cd9e1fc8831a53374a45b978fb16d771ab5c
data/README.md CHANGED
@@ -17,21 +17,22 @@ An experimental Redis Ruby client.
17
17
 
18
18
  - Commands:
19
19
  - Cluster (0/20)
20
- - Connection (4/5)
20
+ - Connection
21
21
  - Geo (0/6)
22
- - Hashes (14/15)
22
+ - Hashes (14/15) (See [#3](https://github.com/etehtsea/oxblood/issues/3))
23
23
  - HyperLogLog (0/3)
24
- - Keys (18/22)
25
- - Lists (6/17)
24
+ - Keys (18/22) (See [#4], [#6], [#7], [#8])
25
+ - Lists (14/17) (See [#11](https://github.com/etehtsea/oxblood/issues/11))
26
26
  - Pub/Sub (0/6)
27
27
  - Scripting (0/7)
28
28
  - Server (2/31)
29
- - Sets (5/15)
30
- - Sorted Sets (6/21)
31
- - Strings (5/24)
29
+ - Sets (14/15) (See [#10](https://github.com/etehtsea/oxblood/issues/10))
30
+ - Sorted Sets (15/21) (See [#12], [#13], [#14], [#15])
31
+ - Strings (23/24) (See [#16](https://github.com/etehtsea/oxblood/issues/16))
32
32
  - Transaction (0/5)
33
33
  - [Pipeling](http://www.rubydoc.info/github/etehtsea/oxblood/master/Oxblood/Pipeline)
34
34
  - [Connection pooling](http://www.rubydoc.info/github/etehtsea/oxblood/master/Oxblood/Pool)
35
+ - [Connection resiliency](http://www.rubydoc.info/github/etehtsea/oxblood/master/Oxblood/RSocket)
35
36
 
36
37
  ## Usage
37
38
  As a starting point please look at [Oxblood::Pool](http://www.rubydoc.info/github/etehtsea/oxblood/master/Oxblood/Pool) documentation.
@@ -50,3 +51,12 @@ Bug reports and pull requests are welcome on [GitHub](https://github.com/etehtse
50
51
  ## License
51
52
 
52
53
  The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
54
+
55
+ [#4]: https://github.com/etehtsea/oxblood/issues/4
56
+ [#6]: https://github.com/etehtsea/oxblood/issues/6
57
+ [#7]: https://github.com/etehtsea/oxblood/issues/7
58
+ [#8]: https://github.com/etehtsea/oxblood/issues/8
59
+ [#12]: https://github.com/etehtsea/oxblood/issues/12
60
+ [#13]: https://github.com/etehtsea/oxblood/issues/13
61
+ [#14]: https://github.com/etehtsea/oxblood/issues/14
62
+ [#15]: https://github.com/etehtsea/oxblood/issues/15
@@ -8,6 +8,15 @@ module Oxblood
8
8
  class RSocket
9
9
  TimeoutError = Class.new(RuntimeError)
10
10
 
11
+ # JRuby don't properly support SO_LINGER setting
12
+ # @see https://github.com/jruby/jruby/issues/4040
13
+ LINGER_OPTION = if RUBY_ENGINE == 'jruby'
14
+ [Socket::SOL_SOCKET, :LINGER, 0].freeze
15
+ else
16
+ Socket::Option.linger(true, 0)
17
+ end
18
+ private_constant :LINGER_OPTION
19
+
11
20
  # @!attribute [rw] timeout
12
21
  # @return [Numeric] timeout in seconds
13
22
  attr_accessor :timeout
@@ -77,15 +86,15 @@ module Oxblood
77
86
  # @return [nil] always return nil
78
87
  def close
79
88
  @buffer.clear
80
- socket.close
89
+ @socket && @socket.close
81
90
  rescue IOError
82
91
  ;
83
92
  ensure
84
93
  @socket = nil
85
94
  end
86
95
 
87
- # True if connection is established
88
- # @return [Boolean] connection status
96
+ # True if socket exists
97
+ # @return [Boolean] socket exists or not
89
98
  def connected?
90
99
  !!@socket
91
100
  end
@@ -124,6 +133,8 @@ module Oxblood
124
133
 
125
134
 
126
135
  def fail_with_timeout!
136
+ # In case of failure close socket ASAP
137
+ socket.setsockopt(*LINGER_OPTION)
127
138
  close
128
139
  raise TimeoutError
129
140
  end
@@ -187,6 +187,78 @@ module Oxblood
187
187
  # Strings
188
188
  #
189
189
 
190
+ # Append a value to a key
191
+ # @see http://redis.io/commands/append
192
+ #
193
+ # @param [String] key
194
+ # @param [String] value
195
+ #
196
+ # @return [Integer] the length of the string after the append operation
197
+ def append(key, value)
198
+ run(:APPEND, key, value)
199
+ end
200
+
201
+ # Count set bits in a string
202
+ # @see http://redis.io/commands/bitcount
203
+ #
204
+ # @param [String] key
205
+ # @param [Array] interval to count in
206
+ #
207
+ # @return [Integer] the number of bits set to 1
208
+ def bitcount(key, *interval)
209
+ run(*interval.unshift(:BITCOUNT, key))
210
+ end
211
+
212
+ # Perform bitwise operations between strings
213
+ # @see http://redis.io/commands/bitop
214
+ #
215
+ # @param [String] operation
216
+ # @param [String] destkey
217
+ # @param [Array] keys
218
+ #
219
+ # @return [Integer] the size of the string stored in the destination key,
220
+ # that is equal to the size of the longest input string
221
+ def bitop(operation, destkey, *keys)
222
+ run(*keys.unshift(:BITOP, operation, destkey))
223
+ end
224
+
225
+ # Find first bit set or clear in a string
226
+ # @see http://redis.io/commands/bitpos
227
+ #
228
+ # @param [String] key
229
+ # @param [Integer] bit
230
+ # @param [Array] interval
231
+ #
232
+ # @return [Integer] the command returns the position of the first bit set to
233
+ # 1 or 0 according to the request
234
+ def bitpos(key, bit, *interval)
235
+ run(*interval.unshift(:BITPOS, key, bit))
236
+ end
237
+
238
+ # Decrement the integer value of a key by one
239
+ # @see http://redis.io/commands/decr
240
+ #
241
+ # @param [String] key
242
+ #
243
+ # @return [Integer] the value of key after the decrement
244
+ # @return [RError] if value is not an integer or out of range
245
+ def decr(key)
246
+ run(:DECR, key)
247
+ end
248
+
249
+ # Decrement the integer value of a key by the given number
250
+ # @see http://redis.io/commands/decrby
251
+ #
252
+ # @param [String] key
253
+ # @param [Integer] decrement
254
+ #
255
+ # @return [Integer] the value of key after the decrement
256
+ # @return [RError] if the key contains a value of the wrong type or contains
257
+ # a string that can not be represented as integer
258
+ def decrby(key, decrement)
259
+ run(:DECRBY, key, decrement)
260
+ end
261
+
190
262
  # Get the value of a key
191
263
  # @see http://redis.io/commands/get
192
264
  #
@@ -197,6 +269,41 @@ module Oxblood
197
269
  run(:GET, key)
198
270
  end
199
271
 
272
+ # Returns the bit value at offset in the string value stored at key
273
+ # @see http://redis.io/commands/getbit
274
+ #
275
+ # @param [String] key
276
+ # @param [Integer] offset
277
+ #
278
+ # @return [Integer] the bit value stored at offset
279
+ def getbit(key, offset)
280
+ run(:GETBIT, key, offset)
281
+ end
282
+
283
+ # Get a substring of the string stored at a key
284
+ # @see http://redis.io/commands/getrange
285
+ #
286
+ # @param [String] key
287
+ # @param [Integer] start_pos
288
+ # @param [Integer] end_pos
289
+ #
290
+ # @return [String] substring
291
+ def getrange(key, start_pos, end_pos)
292
+ run(:GETRANGE, key, start_pos, end_pos)
293
+ end
294
+
295
+ # Set the string value of a key and return its old value
296
+ # @see http://redis.io/commands/getset
297
+ #
298
+ # @param [String] key
299
+ # @param [String] value
300
+ #
301
+ # @return [String, nil] the old value stored at key, or nil when
302
+ # key did not exist
303
+ def getset(key, value)
304
+ run(:GETSET, key, value)
305
+ end
306
+
200
307
  # Increment the integer value of a key by one
201
308
  # @see http://redis.io/commands/incr
202
309
  #
@@ -220,6 +327,17 @@ module Oxblood
220
327
  run(:INCRBY, key, increment)
221
328
  end
222
329
 
330
+ # Increment the float value of a key by the given amount
331
+ # @see http://redis.io/commands/incrbyfloat
332
+ #
333
+ # @param [String] key
334
+ # @param [Float] increment
335
+ #
336
+ # @return [String] the value of key after the increment
337
+ def incrbyfloat(key, increment)
338
+ run(:INCRBYFLOAT, key, increment)
339
+ end
340
+
223
341
  # Get the values of all the given keys
224
342
  # @see http://redis.io/commands/mget
225
343
  #
@@ -230,6 +348,39 @@ module Oxblood
230
348
  run(*keys.unshift(:MGET))
231
349
  end
232
350
 
351
+ # Set multiple keys to multiple values
352
+ # @see http://redis.io/commands/mset
353
+ #
354
+ # @param [Array] keys_and_values
355
+ #
356
+ # @return [String] 'OK'
357
+ def mset(*keys_and_values)
358
+ run(*keys_and_values.unshift(:MSET))
359
+ end
360
+
361
+ # Set multiple keys to multiple values, only if none of the keys exist
362
+ # @see http://redis.io/commands/msetnx
363
+ #
364
+ # @param [Array] keys_and_values
365
+ #
366
+ # @return [Integer] 1 if the all the keys were set, or
367
+ # 0 if no key was set (at least one key already existed)
368
+ def msetnx(*keys_and_values)
369
+ run(*keys_and_values.unshift(:MSETNX))
370
+ end
371
+
372
+ # Set the value and expiration in milliseconds of a key
373
+ # @see http://redis.io/commands/psetex
374
+ #
375
+ # @param [String] key
376
+ # @param [Integer] milliseconds expire time
377
+ # @param [String] value
378
+ #
379
+ # @return [String] 'OK'
380
+ def psetex(key, milliseconds, value)
381
+ run(:PSETEX, key, milliseconds, value)
382
+ end
383
+
233
384
  # Set the string value of a key
234
385
  # @see http://redis.io/commands/set
235
386
  #
@@ -244,6 +395,65 @@ module Oxblood
244
395
  run(:SET, key, value)
245
396
  end
246
397
 
398
+ # Set or clear the bit at offset in the string value stored at key
399
+ # @see http://redis.io/commands/setbit
400
+ #
401
+ # @param [String] key
402
+ # @param [Integer] offset
403
+ # @param [String] value
404
+ #
405
+ # @return [Integer] the original bit value stored at offset
406
+ def setbit(key, offset, value)
407
+ run(:SETBIT, key, offset, value)
408
+ end
409
+
410
+ # Set the value and expiration of a key
411
+ # @see http://redis.io/commands/setex
412
+ #
413
+ # @param [String] key
414
+ # @param [Integer] seconds expire time
415
+ # @param [String] value
416
+ #
417
+ # @return [String] 'OK'
418
+ def setex(key, seconds, value)
419
+ run(:SETEX, key, seconds, value)
420
+ end
421
+
422
+ # Set the value of a key, only if the key does not exist
423
+ # @see http://redis.io/commands/setnx
424
+ #
425
+ # @param [String] key
426
+ # @param [String] value
427
+ #
428
+ # @return [Integer] 1 if the key was set, or 0 if the key was not set
429
+ def setnx(key, value)
430
+ run(:SETNX, key, value)
431
+ end
432
+
433
+ # Overwrite part of a string at key starting at the specified offset
434
+ # @see http://redis.io/commands/setrange
435
+ #
436
+ # @param [String] key
437
+ # @param [Integer] offset
438
+ # @param [String] value
439
+ #
440
+ # @return [Integer] the length of the string after it was modified by
441
+ # the command
442
+ def setrange(key, offset, value)
443
+ run(:SETRANGE, key, offset, value)
444
+ end
445
+
446
+ # Get the length of the value stored in a key
447
+ # @see http://redis.io/commands/strlen
448
+ #
449
+ # @param [String] key
450
+ #
451
+ # @return [Integer] the length of the string at key,
452
+ # or 0 when key does not exist
453
+ def strlen(key)
454
+ run(:STRLEN, key)
455
+ end
456
+
247
457
  #
248
458
  # Connection
249
459
  #
@@ -304,6 +514,16 @@ module Oxblood
304
514
  run(:SELECT, index)
305
515
  end
306
516
 
517
+ # Close the connection
518
+ # @see http://redis.io/commands/quit
519
+ #
520
+ # @return [String] 'OK'
521
+ def quit
522
+ run(:QUIT)
523
+ ensure
524
+ @connection.socket.close
525
+ end
526
+
307
527
  #
308
528
  # Server
309
529
  #
@@ -543,6 +763,31 @@ module Oxblood
543
763
  # Lists
544
764
  #
545
765
 
766
+ # Get an element from a list by its index
767
+ # @see http://www.redis.io/commands/lindex
768
+ #
769
+ # @param [String] key
770
+ # @param [Integer] index zero-based of element in the list
771
+ #
772
+ # @return [String] the requested element, or nil when index is out of range.
773
+ def lindex(key, index)
774
+ run(:LINDEX, key, index)
775
+ end
776
+
777
+ # Insert an element before or after another element in a list
778
+ # @see http://www.redis.io/commands/linsert
779
+ #
780
+ # @param [String] key
781
+ # @param [Symbol] place could be :before or :after
782
+ # @param [String] pivot reference value
783
+ # @param [String] value to insert
784
+ #
785
+ # @return [Integer] the length of the list after the insert operation,
786
+ # or -1 when the value pivot was not found
787
+ def linsert(key, place, pivot, value)
788
+ run(:LINSERT, key, place, pivot, value)
789
+ end
790
+
546
791
  # Get the length of a list
547
792
  # @see http://redis.io/commands/llen
548
793
  #
@@ -576,6 +821,17 @@ module Oxblood
576
821
  run(*values.unshift(:LPUSH, key))
577
822
  end
578
823
 
824
+ # Prepend a value to a list, only if the list exists
825
+ # @see http://www.redis.io/commands/lpushx
826
+ #
827
+ # @param [String] key
828
+ # @param [String] value
829
+ #
830
+ # @return [Integer] the length of the list after the push operation
831
+ def lpushx(key, value)
832
+ run(:LPUSHX, key, value)
833
+ end
834
+
579
835
  # Get a range of elements from a list
580
836
  # @see http://redis.io/commands/lrange
581
837
  #
@@ -588,6 +844,43 @@ module Oxblood
588
844
  run(:LRANGE, key, start, stop)
589
845
  end
590
846
 
847
+ # Remove elements from a list
848
+ # @see http://www.redis.io/commands/lrem
849
+ #
850
+ # @param [String] key
851
+ # @param [Integer] count (please look into official docs for more info)
852
+ # @param [String] value to remove
853
+ #
854
+ # @return [Integer] the number of removed elements
855
+ def lrem(key, count, value)
856
+ run(:LREM, key, count, value)
857
+ end
858
+
859
+ # Set the value of an element in a list by its index
860
+ # @see http://www.redis.io/commands/lset
861
+ #
862
+ # @param [String] key
863
+ # @param [Integer] index
864
+ # @param [String] value
865
+ #
866
+ # @return [String] 'OK'
867
+ # @return [RError] if index is out of range
868
+ def lset(key, index, value)
869
+ run(:LSET, key, index, value)
870
+ end
871
+
872
+ # Trim a list to the specified range
873
+ # @see http://www.redis.io/commands/ltrim
874
+ #
875
+ # @param [String] key
876
+ # @param [Integer] start
877
+ # @param [Integer] stop
878
+ #
879
+ # @return [String] 'OK'
880
+ def ltrim(key, start, stop)
881
+ run(:LTRIM, key, start, stop)
882
+ end
883
+
591
884
  # Remove and get the last element in a list
592
885
  # @see http://redis.io/commands/rpop
593
886
  #
@@ -599,6 +892,18 @@ module Oxblood
599
892
  run(:RPOP, key)
600
893
  end
601
894
 
895
+ # Remove the last element in a list, prepend it to another list and return
896
+ # @see http://www.redis.io/commands/rpoplpush
897
+ #
898
+ # @param [String] source
899
+ # @param [String] destination
900
+ #
901
+ # @return [String, nil] the element being popped and pushed, or nil when
902
+ # source does not exist
903
+ def rpoplpush(source, destination)
904
+ run(:RPOPLPUSH, source, destination)
905
+ end
906
+
602
907
  # Append one or multiple values to a list
603
908
  # @see http://redis.io/commands/rpush
604
909
  #
@@ -611,6 +916,17 @@ module Oxblood
611
916
  run(*values.unshift(:RPUSH, key))
612
917
  end
613
918
 
919
+ # Append a value to a list, only if the list exists
920
+ # @see http://www.redis.io/commands/rpushx
921
+ #
922
+ # @param [String] key
923
+ # @param [String] value
924
+ #
925
+ # @return [Integer] the length of the list after the push operation
926
+ def rpushx(key, value)
927
+ run(:RPUSHX, key, value)
928
+ end
929
+
614
930
  #
615
931
  # Sets
616
932
  #
@@ -638,6 +954,60 @@ module Oxblood
638
954
  run(:SCARD, key)
639
955
  end
640
956
 
957
+ # Subtract multiple sets
958
+ # @see http://redis.io/commands/sdiff
959
+ #
960
+ # @param [String, Array<String>] keys
961
+ #
962
+ # @return [Array] array with members of the resulting set
963
+ def sdiff(*keys)
964
+ run(*keys.unshift(:SDIFF))
965
+ end
966
+
967
+ # Subtract multiple sets and store the resulting set in a key
968
+ # @see http://redis.io/commands/sdiffstore
969
+ #
970
+ # @param [String] destination key
971
+ # @param [String, Array<String>] keys of sets to diff
972
+ #
973
+ # @return [Integer] the number of elements in the resulting set
974
+ def sdiffstore(destination, *keys)
975
+ run(*keys.unshift(:SDIFFSTORE, destination))
976
+ end
977
+
978
+ # Intersect multiple sets
979
+ # @see http://redis.io/commands/sinter
980
+ #
981
+ # @param [String, Array<String>] keys to intersect
982
+ #
983
+ # @return [Array] array with members of the resulting set
984
+ def sinter(*keys)
985
+ run(*keys.unshift(:SINTER))
986
+ end
987
+
988
+ # Intersect multiple sets and store the resulting key in a key
989
+ # @see http://redis.io/commands/sinterstore
990
+ #
991
+ # @param [String] destination key
992
+ # @param [String, Array<String>] keys of sets to intersect
993
+ #
994
+ # @return [Integer] the number of elements in the resulting set
995
+ def sinterstore(destination, *keys)
996
+ run(*keys.unshift(:SINTERSTORE, destination))
997
+ end
998
+
999
+ # Determine if a given value is a member of a set
1000
+ # @see http://redis.io/commands/sismember
1001
+ #
1002
+ # @param [String] key
1003
+ # @param [String] member
1004
+ #
1005
+ # @return [Integer] 1 if the element is a member of the set or
1006
+ # 0 if the element is not a member of the set, or if key does not exist
1007
+ def sismember(key, member)
1008
+ run(:SISMEMBER, key, member)
1009
+ end
1010
+
641
1011
  # Get all the members in a set
642
1012
  # @see http://redis.io/commands/smembers
643
1013
  #
@@ -648,6 +1018,53 @@ module Oxblood
648
1018
  run(:SMEMBERS, key)
649
1019
  end
650
1020
 
1021
+ # Move a member from one set to another
1022
+ # @see http://redis.io/commands/smove
1023
+ #
1024
+ # @param [String] source
1025
+ # @param [String] destination
1026
+ # @param [String] member
1027
+ #
1028
+ # @return [Integer] 1 if the element is moved, or 0 if the element is not
1029
+ # a member of source and no operation was performed
1030
+ def smove(source, destination, member)
1031
+ run(:SMOVE, source, destination, member)
1032
+ end
1033
+
1034
+ # Remove and return one or multiple random members from a set
1035
+ # @see http://redis.io/commands/spop
1036
+ #
1037
+ # @param [String] key
1038
+ # @param [Integer] count
1039
+ #
1040
+ # @return [String] without the additional count argument the command returns
1041
+ # the removed element, or nil when key does not exist
1042
+ # @return [Array] when the additional count argument is passed the command
1043
+ # returns an array of removed elements, or an empty array when key does
1044
+ # not exist.
1045
+ def spop(key, count = nil)
1046
+ args = [:SPOP, key]
1047
+ args << count if count
1048
+ run(*args)
1049
+ end
1050
+
1051
+ # Get one or multiple random members from a set
1052
+ # @see http://redis.io/commands/srandmember
1053
+ #
1054
+ # @param [String] key
1055
+ # @param [Integer] count
1056
+ #
1057
+ # @return [String, nil] without the additional count argument the command
1058
+ # returns string with the randomly selected element, or nil when key
1059
+ # does not exist
1060
+ # @return [Array] when the additional count argument is passed the command
1061
+ # returns an array of elements, or an empty array when key does not exist
1062
+ def srandmember(key, count = nil)
1063
+ args = [:SRANDMEMBER, key]
1064
+ args << count if count
1065
+ run(*args)
1066
+ end
1067
+
651
1068
  # Remove one or more members from a set
652
1069
  # @see http://redis.io/commands/srem
653
1070
  #
@@ -670,6 +1087,17 @@ module Oxblood
670
1087
  run(*keys.unshift(:SUNION))
671
1088
  end
672
1089
 
1090
+ # Add multipe sets and store the resulting set in a key
1091
+ # @see http://redis.io/commands/sunionstore
1092
+ #
1093
+ # @param [String] destination
1094
+ # @param [String, Array<String>] keys
1095
+ #
1096
+ # @return [Integer] the number of elements in the resulting set
1097
+ def sunionstore(destination, *keys)
1098
+ run(*keys.unshift(:SUNIONSTORE, destination))
1099
+ end
1100
+
673
1101
  #
674
1102
  # Sorted Sets
675
1103
  #
@@ -701,6 +1129,44 @@ module Oxblood
701
1129
  run(:ZCARD, key)
702
1130
  end
703
1131
 
1132
+ # Count the members in a sorted set with scores within the given values
1133
+ # @see http://redis.io/commands/zcount
1134
+ #
1135
+ # @param [String] key
1136
+ # @param [String] min
1137
+ # @param [String] max
1138
+ #
1139
+ # @return [Integer] the number of elements in the specified score range
1140
+ def zcount(key, min, max)
1141
+ run(:ZCOUNT, key, min, max)
1142
+ end
1143
+
1144
+ # Increment the score of a member in a sorted set
1145
+ # @see http://redis.io/commands/zincrby
1146
+ #
1147
+ # @param [String] key
1148
+ # @param [Float] increment
1149
+ # @param [String] member
1150
+ #
1151
+ # @return [String] the new score of member (a double precision floating
1152
+ # point number), represented as string
1153
+ def zincrby(key, increment, member)
1154
+ run(:ZINCRBY, key, increment, member)
1155
+ end
1156
+
1157
+ # Count the number of members in a sorted set between a given
1158
+ # lexicographical range
1159
+ # @see http://redis.io/commands/zlexcount
1160
+ #
1161
+ # @param [String] key
1162
+ # @param [String] min
1163
+ # @param [String] max
1164
+ #
1165
+ # @return the number of elements in the specified score range
1166
+ def zlexcount(key, min, max)
1167
+ run(:ZLEXCOUNT, key, min, max)
1168
+ end
1169
+
704
1170
  # Return a range of members in a sorted set, by index
705
1171
  # @see http://redis.io/commands/zrange
706
1172
  #
@@ -731,15 +1197,49 @@ module Oxblood
731
1197
  # Return a range of members in a sorted set, by score
732
1198
  # @see http://redis.io/commands/zrangebyscore
733
1199
  #
734
- # @todo Support optional args (WITHSCORES/LIMIT)
735
- #
736
1200
  # @param [String] key under which set is stored
737
1201
  # @param [String] min score
738
1202
  # @param [String] max score
1203
+ # @param [Hash] opts
1204
+ #
1205
+ # @option opts [Boolean] :withscores (false) Return the scores of
1206
+ # the elements together with the elements
1207
+ # @option opts [Array<Integer, Integer>] :limit Get a range of the matching
1208
+ # elements (similar to SELECT LIMIT offset, count in SQL)
1209
+ #
1210
+ # @example
1211
+ # session.zrangebyscore('myzset', '-inf', '+inf')
1212
+ # # => ['one', 'two', 'three']
1213
+ #
1214
+ # @example
1215
+ # session.zrangebyscore('myzset', '(1', 2, withscores: true)
1216
+ # # => [['two', '2']]
1217
+ #
1218
+ # @example
1219
+ # opts = { withscores: true, limit: [1, 1] }
1220
+ # session.zrangebyscore('myzset', '-inf', '+inf', opts)
1221
+ # # => [['two', '2']]
1222
+ #
1223
+ # @return [Array] list of elements in the specified score range (optionally
1224
+ # with their scores, in case the :withscores option is given)
1225
+ def zrangebyscore(key, min, max, opts = {})
1226
+ args = [:ZRANGEBYSCORE, key, min, max]
1227
+ args << :WITHSCORES if opts[:withscores]
1228
+ args.push(:LIMIT).concat(opts[:limit]) if opts[:limit].is_a?(Array)
1229
+
1230
+ run(*args)
1231
+ end
1232
+
1233
+ # Determine the index of a member in a sorted set
1234
+ # @see http://redis.io/commands/zrank
739
1235
  #
740
- # @return [Array] list of elements in the specified score range
741
- def zrangebyscore(key, min, max)
742
- run(:ZRANGEBYSCORE, key, min, max)
1236
+ # @param [String] key
1237
+ # @param [String] member
1238
+ #
1239
+ # @return [Integer, nil] the rank of member or nil if member does not exist
1240
+ # in the sorted set or key does not exist
1241
+ def zrank(key, member)
1242
+ run(:ZRANK, key, member)
743
1243
  end
744
1244
 
745
1245
  # Remove one or more members from a sorted set
@@ -754,6 +1254,18 @@ module Oxblood
754
1254
  run(*members.unshift(:ZREM, key))
755
1255
  end
756
1256
 
1257
+ # Remove all members in a sorted set within the given indexes
1258
+ # @see http://redis.io/commands/zremrangebyrank
1259
+ #
1260
+ # @param [String] key
1261
+ # @param [String] start
1262
+ # @param [String] stop
1263
+ #
1264
+ # @return [Integer] the number of elements removed
1265
+ def zremrangebyrank(key, start, stop)
1266
+ run(:ZREMRANGEBYRANK, key, start, stop)
1267
+ end
1268
+
757
1269
  # Remove all members in a sorted set within the given scores
758
1270
  # @see http://redis.io/commands/zremrangebyscore
759
1271
  #
@@ -766,6 +1278,97 @@ module Oxblood
766
1278
  run(:ZREMRANGEBYSCORE, key, min, max)
767
1279
  end
768
1280
 
1281
+ # Return a range of members in a sorted set, by index, with scores ordered
1282
+ # from high to low
1283
+ # @see http://redis.io/commands/zrevrange
1284
+ #
1285
+ # @example
1286
+ # session.zrevrange('myzset', 0, -1)
1287
+ # # => ['two', 'one']
1288
+ #
1289
+ # @example
1290
+ # session.zrevrange('myzset', 0, -1, withscores: true)
1291
+ # # => [['two', '2'], ['one', '1']]
1292
+ #
1293
+ # @param [String] key
1294
+ # @param [Integer] start index
1295
+ # @param [Integer] stop index
1296
+ # @param [Hash] opts
1297
+ #
1298
+ # @option opts [Boolean] :withscores (false) Return the scores of
1299
+ # the elements together with the elements
1300
+ #
1301
+ # @return [Array] list of elements in the specified range (optionally with
1302
+ # their scores, in case the :withscores option is given)
1303
+ def zrevrange(key, start, stop, opts = {})
1304
+ args = [:ZREVRANGE, key, start, stop]
1305
+ args << :WITHSCORES if opts[:withscores]
1306
+ run(*args)
1307
+ end
1308
+
1309
+ # Return a range of members in a sorted set, by score, with scores ordered
1310
+ # from high to low
1311
+ # @see http://redis.io/commands/zrevrangebyscore
1312
+ #
1313
+ # @param [String] key under which set is stored
1314
+ # @param [String] min score
1315
+ # @param [String] max score
1316
+ # @param [Hash] opts
1317
+ #
1318
+ # @option opts [Boolean] :withscores (false) Return the scores of
1319
+ # the elements together with the elements
1320
+ # @option opts [Array<Integer, Integer>] :limit Get a range of the matching
1321
+ # elements (similar to SELECT LIMIT offset, count in SQL)
1322
+ #
1323
+ # @example
1324
+ # session.zrevrangebyscore('myzset', '+inf', '-inf')
1325
+ # # => ['three', 'two', 'one']
1326
+ #
1327
+ # @example
1328
+ # session.zrevrangebyscore('myzset', 2, '(1', withscores: true)
1329
+ # # => [['two', '2']]
1330
+ #
1331
+ # @example
1332
+ # opts = { withscores: true, limit: [1, 1] }
1333
+ # session.zrevrangebyscore('myzset', '+inf', '-inf', opts)
1334
+ # # => [['two', '2']]
1335
+ #
1336
+ # @return [Array] list of elements in the specified score range (optionally
1337
+ # with their scores, in case the :withscores option is given)
1338
+ def zrevrangebyscore(key, min, max, opts = {})
1339
+ args = [:ZREVRANGEBYSCORE, key, min, max]
1340
+ args << :WITHSCORES if opts[:withscores]
1341
+ args.push(:LIMIT).concat(opts[:limit]) if opts[:limit].is_a?(Array)
1342
+
1343
+ run(*args)
1344
+ end
1345
+
1346
+ # Determine the index of a member in a sorted set, with scores ordered from
1347
+ # high to low
1348
+ # @see http://redis.io/commands/zrevrank
1349
+ #
1350
+ # @param [String] key
1351
+ # @param [String] member
1352
+ #
1353
+ # @return [Integer, nil] the rank of member, or nil if member does not
1354
+ # exists in the sorted set or key does not exists
1355
+ def zrevrank(key, member)
1356
+ run(:ZREVRANK, key, member)
1357
+ end
1358
+
1359
+ # Get the score associated with the given member in a sorted set
1360
+ # @see http://redis.io/commands/zscore
1361
+ #
1362
+ # @param [String] key
1363
+ # @param [String] member
1364
+ #
1365
+ # @return [String, nil] the score of member (a double precision floating
1366
+ # point number), represented as string, or nil if member does not exist in
1367
+ # the sorted set, or key does not exists
1368
+ def zscore(key, member)
1369
+ run(:ZSCORE, key, member)
1370
+ end
1371
+
769
1372
  protected
770
1373
 
771
1374
  def serialize(*command)
@@ -1,3 +1,3 @@
1
1
  module Oxblood
2
- VERSION = '0.1.0.dev7'
2
+ VERSION = '0.1.0.dev8'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oxblood
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0.dev7
4
+ version: 0.1.0.dev8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Konstantin Shabanov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-07-28 00:00:00.000000000 Z
11
+ date: 2016-08-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: connection_pool
@@ -114,7 +114,6 @@ files:
114
114
  - benchmarks/pipeline.rb
115
115
  - benchmarks/serializer.rb
116
116
  - lib/oxblood.rb
117
- - lib/oxblood/buffered_io.rb
118
117
  - lib/oxblood/connection.rb
119
118
  - lib/oxblood/pipeline.rb
120
119
  - lib/oxblood/pool.rb
@@ -1,12 +0,0 @@
1
- module Oxblood
2
- # @private
3
- class BufferedIO
4
- def initialize(socket)
5
- @socket = socket
6
- @buffer = String.new
7
- end
8
-
9
-
10
- private
11
- end
12
- end