redis-objects 1.3.1 → 1.5.1

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
- SHA1:
3
- metadata.gz: ae3bd1cf4a81eca5bbb34a027f066b2dcbd233d5
4
- data.tar.gz: 03ec3b26287e799061232c37a9604b0b65e52219
2
+ SHA256:
3
+ metadata.gz: 5c7bc592d203647a8b7e9fd574a78eec1ec466e85fef95d30fac6d831f5d086a
4
+ data.tar.gz: e89a8a50ddac32cc8b0fd5692697c21620ef97bac6f28c1841c0e50e9a833429
5
5
  SHA512:
6
- metadata.gz: af1e410ca8fdb1251e4b67c6ff6e051a76ea78804c729b82cc7ba90ced750cc9139c9fbf86d78b2e79476a55c66a7c59733c150f6ff9adb9a9e16bf94ee7daf7
7
- data.tar.gz: 9e8deeb4e39b6ccf713f461eae512870c3fac18d211984583d3ad10814b231515d724aee6c22b9cecd7306b29d2e20f68de77f4f794c3deae3b6fa4d74153a1b
6
+ metadata.gz: 7a91ab932b94a4a36ab4da40d173804b71c46b21c28e917acefb5f1720da1dd60fe3e4c0d06e124c172118789c31fa11f0f4b96b7b27da97cbd8f7a90f01dd6c
7
+ data.tar.gz: d92e900d1fcec537a439e99ad7d311a83ad23c1e5c28ecc84e8922a0c7da56b4fdcfc9cadcb48aca382c4a6c8045dd24ecbeb81d681aa4fcad2c9d13b3cf9a8f
data/.travis.yml CHANGED
@@ -5,9 +5,7 @@ before_install:
5
5
  - gem install bundler
6
6
 
7
7
  rvm:
8
- - 1.9.3
9
- - 2.0.0
10
- - 2.1
11
- - 2.2
12
8
  - 2.3.3
13
9
  - 2.4.0
10
+ - 2.5.1
11
+ - 2.6.4
data/CHANGELOG.rdoc CHANGED
@@ -1,5 +1,104 @@
1
1
  = Changelog for Redis::Objects
2
2
 
3
+ == 1.5.1 (10 Jul 2021)
4
+
5
+ * Added double-splat for **options to account for Ruby 3.0 [Nate Wiger]
6
+
7
+ * Fix ConnectionPoolProxy Ruby 3.0 compatibility Fix: https://github.com/nateware/redis-objects/pull/258 [Jean byroot Boussier]
8
+
9
+ * Change Redis#exists to Redis#exists? * bump redis version to 4.2 [Alina Hryshchuk]
10
+
11
+ * Local variable `dir` is not in use since 98226b95f35ef455f231692fdb679dfd61200a78 [Akira Matsuda]
12
+
13
+ * Issue 249: when atomic decrbyfloat fails, increment back instead of decrementing again [Slava Samoliuk]
14
+
15
+ * Update documentation to reflect ability to assign values directly [Artin Boghosian]
16
+
17
+ * Allow directly assigning values of lists, hashes and sets [Artin Boghosian]
18
+
19
+
20
+ == 1.5.0 (18 Sep 2019)
21
+
22
+ * updated README on expireat [Nate Wiger]
23
+
24
+ * Add option for using a custom serializer [Tomás Rojas]
25
+
26
+ * DRY up objects to enable custom prefixing when desired [Tomás Rojas]
27
+
28
+ * Allow spop to return multiple members [Evan Paul]
29
+
30
+ * Rename #delete! to #redis_delete_objects [Mattias Pfeiffer]
31
+
32
+ * Make deletion simpler with just 1 call to Redis [Mattias Pfeiffer]
33
+
34
+ * Move `CoreCommands` inclusion to `BaseObject` [Tomás Rojas]
35
+
36
+ * Move `Enumerable` functionality to `EnumerableObject` [Tomás Rojas]
37
+
38
+ * Move `attr_reader`s to `Redis::BaseObject` [Tomás Rojas]
39
+
40
+ == 1.4.3 (7 Oct 2018)
41
+
42
+ * Merge pull request #235 from johnc219/fix/end-time-expiration Add expiration in seconds to obtain end_time [Nate Wiger]
43
+
44
+ * Merge pull request #223 from artinboghosian/compress-redis-value Allow compression of value stored in Redis::Value to save memory on R… [Nate Wiger]
45
+
46
+ * Merge pull request #224 from artinboghosian/sorted-set-missing-operations Fix set operation methods on SortedSets [Nate Wiger]
47
+
48
+ * Merge pull request #233 from tmattia/master Add SortedSet#count alias so it's consistent with Set#count [Nate Wiger]
49
+
50
+ * Merge pull request #236 from nateware/revert-220-threadsafe Revert "Make Redis::Objects.connection thread-safe" [Nate Wiger]
51
+
52
+ * Revert "Make Redis::Objects.connection thread-safe" [Nate Wiger]
53
+
54
+ == 1.4.2 (29 Aug 2018)
55
+
56
+ * Merge pull request #227 from D-system/optimise_lock Optimise lock [Nate Wiger]
57
+
58
+ * Merge pull request #228 from D-system/travis_ruby_2.5 Travis: test against ruby 2.5 [Nate Wiger]
59
+
60
+ * Travis: test against ruby 2.5 [Thomas Brennetot]
61
+
62
+ * Lock: update comment [Thomas Brennetot]
63
+
64
+ * Lock: add backward compatibility [Thomas Brennetot]
65
+
66
+ * Use SET with the NX and the expiration option in a single request [Thomas Brennetot]
67
+
68
+ * Merge pull request #218 from edwardbako/list_pushed_count Return count of lpush & rpush commands [Nate Wiger]
69
+
70
+ * Merge pull request #220 from gammons/threadsafe Make Redis::Objects.connection thread-safe [Nate Wiger]
71
+
72
+ * Make Redis::Objects.connection threadsafe [Grant Ammons]
73
+
74
+ * Return count of lpush & rpush commands [Edward Bako]
75
+
76
+ * Removed support for versions of Ruby < 2.2 [Nate Wiger]
77
+
78
+ == 1.4.1 (Unreleased)
79
+
80
+ * Buggy release that was removed
81
+
82
+ == 1.4.0 (7 Dec 2017)
83
+
84
+ * Bumped dependency to redis.rb 4.0 [Nate Wiger]
85
+
86
+ == 1.3.1 (29 Aug 2017)
87
+
88
+ * Merge pull request #213 from onk/feature/proc_expireat Allow to set proc for expireat [Nate Wiger]
89
+
90
+ * Merge pull request #212 from yuzixun/hotfix/counter modify Counter#nil? [Nate Wiger]
91
+
92
+ * Merge pull request #207 from i2bskn/improve_bulk_get Reduce query to Redis. [Nate Wiger]
93
+
94
+ * Merge pull request #209 from yuzixun/hotfix/hash_key/bulk_related fix error when fields/keys is an array [Nate Wiger]
95
+
96
+ * Use pre-calculated symbols for instance_variable_(get|set) for performance #211 [Nate Wiger]
97
+
98
+ * Weird inheriting from version AR::Migration thingy [Nate Wiger]
99
+
100
+ * Reduce query to Redis. Don't query to Redis if #bulk_get/#bulk_values arguments is empty. [i2bskn]
101
+
3
102
  == 1.3.0 (11 Mar 2017)
4
103
 
5
104
  * handle two Redis::Counter objects adding/subtracting [Nate Wiger]
data/README.md CHANGED
@@ -9,7 +9,7 @@ This is **not** an ORM. People that are wrapping ORM’s around Redis are missin
9
9
  The killer feature of Redis is that it allows you to perform _atomic_ operations
10
10
  on _individual_ data structures, like counters, lists, and sets. The **atomic** part is HUGE.
11
11
  Using an ORM wrapper that retrieves a "record", updates values, then sends those values back,
12
- _removes_ the atomicity, cutting the nuts off the major advantage of Redis. Just use MySQL, k?
12
+ _removes_ the atomicity, and thus the major advantage of Redis. Just use MySQL, k?
13
13
 
14
14
  This gem provides a Rubyish interface to Redis, by mapping [Redis data types](http://redis.io/commands)
15
15
  to Ruby objects, via a thin layer over the `redis` gem. It offers several advantages
@@ -144,6 +144,7 @@ Familiar Ruby array operations Just Work (TM):
144
144
  @team.on_base.shift
145
145
  @team.on_base.length # 1
146
146
  @team.on_base.delete('player2')
147
+ @team.on_base = ['player1', 'player2'] # ['player1', 'player2']
147
148
  ~~~
148
149
 
149
150
  Sets work too:
@@ -157,6 +158,15 @@ Sets work too:
157
158
  puts player
158
159
  end
159
160
  player = @team.outfielders.detect{|of| of == 'outfielder2'}
161
+ @team.outfielders = ['outfielder1', 'outfielder3'] # ['outfielder1', 'outfielder3']
162
+ ~~~
163
+
164
+ Hashes work too:
165
+
166
+ ~~~ruby
167
+ @team.pitchers_faced['player1'] = 'pitcher2'
168
+ @team.pitchers_faced['player2'] = 'pitcher1'
169
+ @team.pitchers_faced = { 'player1' => 'pitcher2', 'player2' => 'pitcher1' }
160
170
  ~~~
161
171
 
162
172
  And you can do unions and intersections between objects (kinda cool):
@@ -261,6 +271,18 @@ Complex data is no problem with :marshal => true:
261
271
  puts @newest.value['username']
262
272
  ~~~
263
273
 
274
+ Compress data to save memory usage on Redis with :compress => true:
275
+
276
+ ~~~ruby
277
+ @account = Account.create!(params[:account])
278
+ @marshaled_value = Redis::Value.new('marshaled', :marshal => true, :compress => true)
279
+ @marshaled_value.value = @account.attributes
280
+ @unmarshaled_value = Redis::Value.new('unmarshaled', :compress => true)
281
+ @unmarshaled_value = 'Really Long String'
282
+ puts @marshaled_value.value['username']
283
+ puts @unmarshaled_value.value
284
+ ~~~
285
+
264
286
  Lists
265
287
  -----
266
288
  Lists work just like Ruby arrays:
@@ -538,20 +560,40 @@ Use :expiration and :expireat options to set default expiration.
538
560
 
539
561
  ~~~ruby
540
562
  value :value_with_expiration, :expiration => 1.hour
541
- value :value_with_expireat, :expireat => Time.now + 1.hour
563
+ value :value_with_expireat, :expireat => lambda { Time.now + 1.hour }
542
564
  ~~~
543
565
 
544
- :warning: `expireat` is evaluated at class load time.
545
- In this example, it will be one hour after evaluating class, not after one hour after setting value.
566
+ :warning: In the above example, `expiration` is evaluated at class load time.
567
+ In this example, it will be one hour after loading the class, not after one hour
568
+ after setting a value. If you want to expire one hour after setting the value,
569
+ please use `:expireat` with `lambda`.
546
570
 
547
- If you want to expire one hour after setting the value. please use `lambda`.
571
+ Custom serialization
572
+ --------------------
573
+ You can customize how values are serialized by setting `serializer: CustomSerializer`.
574
+ The default is `Marshal` from the standard lib, but it can be anything that responds to `dump` and
575
+ `load`. `JSON` and `YAML` are popular options.
576
+
577
+ If you need to pass extra arguments to `dump` or `load`, you can set
578
+ `marshal_dump_args: { foo: 'bar' }` and `marshal_load_args: { foo: 'bar' }` respectively.
548
579
 
549
580
  ~~~ruby
550
- value :value_with_expireat, :expireat => lambda { Time.now + 1.hour }
581
+ class CustomSerializer
582
+ def self.dump(value)
583
+ # custom code for serializing
584
+ end
585
+
586
+ def self.load(value)
587
+ # custom code for deserializing
588
+ end
589
+ end
590
+
591
+ @account = Account.create!(params[:account])
592
+ @newest = Redis::Value.new('custom_serializer', marshal: true, serializer: CustomSerializer)
593
+ @newest.value = @account.attributes
551
594
  ~~~
552
595
 
553
596
  Author
554
597
  =======
555
- Copyright (c) 2009-2013 [Nate Wiger](http://nateware.com). All Rights Reserved.
598
+ Copyright (c) 2009-2019 [Nate Wiger](http://nateware.com). All Rights Reserved.
556
599
  Released under the [Artistic License](http://www.opensource.org/licenses/artistic-license-2.0.php).
557
-
@@ -1,6 +1,12 @@
1
+ require 'redis/helpers/core_commands'
2
+
1
3
  class Redis
2
4
  # Defines base functionality for all redis-objects.
3
5
  class BaseObject
6
+ include Redis::Helpers::CoreCommands
7
+
8
+ attr_reader :key, :options
9
+
4
10
  def initialize(key, *args)
5
11
  @key = key.is_a?(Array) ? key.flatten.join(':') : key
6
12
  @options = args.last.is_a?(Hash) ? args.pop : {}
data/lib/redis/counter.rb CHANGED
@@ -9,10 +9,6 @@ class Redis
9
9
  # class to define a counter.
10
10
  #
11
11
  class Counter < BaseObject
12
- require 'redis/helpers/core_commands'
13
- include Redis::Helpers::CoreCommands
14
-
15
- attr_reader :key, :options
16
12
  def initialize(key, *args)
17
13
  super(key, *args)
18
14
  @options[:start] ||= @options[:default] || 0
@@ -106,7 +102,7 @@ class Redis
106
102
  def decrbyfloat(by=1.0, &block)
107
103
  allow_expiration do
108
104
  val = redis.incrbyfloat(key, -by).to_f
109
- block_given? ? rewindable_block(:incrbyfloat, -by, val, &block) : val
105
+ block_given? ? rewindable_block(:incrbyfloat, by, val, &block) : val
110
106
  end
111
107
  end
112
108
 
@@ -116,7 +112,7 @@ class Redis
116
112
  alias_method :to_i, :value
117
113
 
118
114
  def nil?
119
- !redis.exists(key)
115
+ !redis.exists?(key)
120
116
  end
121
117
 
122
118
  ##
@@ -0,0 +1,28 @@
1
+ require File.dirname(__FILE__) + '/base_object'
2
+
3
+ class Redis
4
+ #
5
+ # Class representing a Redis enumerable type (list, set, sorted set, or hash).
6
+ #
7
+ class EnumerableObject < BaseObject
8
+ include Enumerable
9
+
10
+ # Iterate through each member. Redis::Objects mixes in Enumerable,
11
+ # so you can also use familiar methods like +collect+, +detect+, and so forth.
12
+ def each(&block)
13
+ value.each(&block)
14
+ end
15
+
16
+ def sort(options={})
17
+ return super() if block_given?
18
+ options[:order] = "asc alpha" if options.keys.count == 0 # compat with Ruby
19
+ val = redis.sort(key, **options)
20
+ val.is_a?(Array) ? val.map{|v| unmarshal(v)} : val
21
+ end
22
+
23
+ # ActiveSupport's core extension `Enumerable#as_json` implementation is incompatible with ours.
24
+ def as_json(*)
25
+ to_hash
26
+ end
27
+ end
28
+ end
@@ -1,16 +1,10 @@
1
- require File.dirname(__FILE__) + '/base_object'
1
+ require File.dirname(__FILE__) + '/enumerable_object'
2
2
 
3
3
  class Redis
4
4
  #
5
5
  # Class representing a Redis hash.
6
6
  #
7
- class HashKey < BaseObject
8
- require 'enumerator'
9
- include Enumerable
10
- require 'redis/helpers/core_commands'
11
- include Redis::Helpers::CoreCommands
12
-
13
- attr_reader :key, :options
7
+ class HashKey < EnumerableObject
14
8
  def initialize(key, *args)
15
9
  super
16
10
  @options[:marshal_keys] ||= {}
@@ -74,11 +68,6 @@ class Redis
74
68
  alias_method :clone, :all
75
69
  alias_method :value, :all
76
70
 
77
- # Enumerate through all fields. Redis: HGETALL
78
- def each(&block)
79
- all.each(&block)
80
- end
81
-
82
71
  # Enumerate through each keys. Redis: HKEYS
83
72
  def each_key(&block)
84
73
  keys.each(&block)
@@ -101,11 +90,6 @@ class Redis
101
90
  true if size == 0
102
91
  end
103
92
 
104
- # Clears the dict of all keys/values. Redis: DEL
105
- def clear
106
- redis.del(key)
107
- end
108
-
109
93
  # Set keys in bulk, takes a hash of field/values {'field1' => 'val1'}. Redis: HMSET
110
94
  def bulk_set(*args)
111
95
  raise ArgumentError, "Argument to bulk_set must be hash of key/value pairs" unless args.last.is_a?(::Hash)
@@ -183,9 +167,5 @@ class Redis
183
167
  def decrbyfloat(field, by=1.0)
184
168
  incrbyfloat(field, -by)
185
169
  end
186
-
187
- def as_json(*)
188
- to_hash
189
- end
190
170
  end
191
171
  end
@@ -3,15 +3,16 @@ class Redis
3
3
  # These are core commands that all types share (rename, etc)
4
4
  module CoreCommands
5
5
  def exists?
6
- redis.exists key
6
+ redis.exists? key
7
7
  end
8
-
8
+
9
+ # Delete key. Redis: DEL
9
10
  def delete
10
11
  redis.del key
11
12
  end
12
13
  alias_method :del, :delete
13
14
  alias_method :clear, :delete
14
-
15
+
15
16
  def type
16
17
  redis.type key
17
18
  end
@@ -29,7 +30,7 @@ class Redis
29
30
  @key = dest if ret && setkey
30
31
  ret
31
32
  end
32
-
33
+
33
34
  def expire(seconds)
34
35
  redis.expire key, seconds
35
36
  end
@@ -50,20 +51,19 @@ class Redis
50
51
  redis.move key, dbindex
51
52
  end
52
53
 
53
- def sort(options={})
54
- options[:order] = "asc alpha" if options.keys.count == 0 # compat with Ruby
55
- val = redis.sort(key, options)
56
- val.is_a?(Array) ? val.map{|v| unmarshal(v)} : val
54
+ def serializer
55
+ options[:serializer] || Marshal
57
56
  end
58
57
 
59
58
  def marshal(value, domarshal=false)
60
59
  if options[:marshal] || domarshal
61
- Marshal.dump(value)
60
+ dump_args = options[:marshal_dump_args] || []
61
+ serializer.dump(value, *(dump_args.is_a?(Array) ? dump_args : [dump_args]))
62
62
  else
63
63
  value
64
64
  end
65
65
  end
66
-
66
+
67
67
  def unmarshal(value, domarshal=false)
68
68
  if value.nil?
69
69
  nil
@@ -73,7 +73,8 @@ class Redis
73
73
  elsif !value.is_a?(String)
74
74
  value
75
75
  else
76
- Marshal.load(value)
76
+ load_args = options[:marshal_load_args] || []
77
+ serializer.load(value, *(load_args.is_a?(Array) ? load_args : [load_args]))
77
78
  end
78
79
  else
79
80
  value
data/lib/redis/list.rb CHANGED
@@ -1,18 +1,11 @@
1
- require File.dirname(__FILE__) + '/base_object'
1
+ require File.dirname(__FILE__) + '/enumerable_object'
2
2
 
3
3
  class Redis
4
4
  #
5
5
  # Class representing a Redis list. Instances of Redis::List are designed to
6
6
  # behave as much like Ruby arrays as possible.
7
7
  #
8
- class List < BaseObject
9
- require 'enumerator'
10
- include Enumerable
11
- require 'redis/helpers/core_commands'
12
- include Redis::Helpers::CoreCommands
13
-
14
- attr_reader :key, :options
15
-
8
+ class List < EnumerableObject
16
9
  # Works like push. Can chain together: list << 'a' << 'b'
17
10
  def <<(value)
18
11
  push(value) # marshal in push()
@@ -29,8 +22,9 @@ class Redis
29
22
  # Add a member to the end of the list. Redis: RPUSH
30
23
  def push(*values)
31
24
  allow_expiration do
32
- redis.rpush(key, values.map{|v| marshal(v) })
25
+ count = redis.rpush(key, values.map{|v| marshal(v) })
33
26
  redis.ltrim(key, -options[:maxlength], -1) if options[:maxlength]
27
+ count
34
28
  end
35
29
  end
36
30
 
@@ -62,8 +56,9 @@ class Redis
62
56
  # Add a member to the start of the list. Redis: LPUSH
63
57
  def unshift(*values)
64
58
  allow_expiration do
65
- redis.lpush(key, values.map{|v| marshal(v) })
59
+ count = redis.lpush(key, values.map{|v| marshal(v) })
66
60
  redis.ltrim(key, 0, options[:maxlength] - 1) if options[:maxlength]
61
+ count
67
62
  end
68
63
  end
69
64
 
@@ -121,12 +116,6 @@ class Redis
121
116
  redis.lrem(key, count, marshal(name)) # weird api
122
117
  end
123
118
 
124
- # Iterate through each member of the set. Redis::Objects mixes in Enumerable,
125
- # so you can also use familiar methods like +collect+, +detect+, and so forth.
126
- def each(&block)
127
- values.each(&block)
128
- end
129
-
130
119
  # Return a range of values from +start_index+ to +end_index+. Can also use
131
120
  # the familiar list[start,end] Ruby syntax. Redis: LRANGE
132
121
  def range(start_index, end_index)
@@ -167,9 +156,5 @@ class Redis
167
156
  def to_s
168
157
  values.join(', ')
169
158
  end
170
-
171
- def as_json(*)
172
- to_hash
173
- end
174
159
  end
175
160
  end