redis-objects 1.7.0 → 2.0.0.alpha

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: a34d5bd684e2dfb04c3216b84fc8c0d0ac4b8037919ba6f887bd1930e3eca727
4
- data.tar.gz: e3b4c9df6c48b594850948dd437cec9acecb9a7622102f71d57a4f17068e7fd8
3
+ metadata.gz: 22b6b39234249ccd4c9485061bb918a211c539b3612d1a916a56eab0e13e031f
4
+ data.tar.gz: 9465be0b72fb8d160421eae75cf5cc5996a2aaa6b507bac6492f6a0b66fad788
5
5
  SHA512:
6
- metadata.gz: 99d33225c4326dec14e62b14e2c0735ac688b7c1d7a86f767d0141fe3a49782e2fc41e02c80cf8c16a79e0c570249e4e3f758e86d1c652688566b4392890abd8
7
- data.tar.gz: d1c6831c0d327fa3f6b2e5e8b3ed45deacdc4373836565084ed16e7492219c7de73e5d79ccc61f0bf28863ad10ef185284c81799369a27fa1cd3f375e426b61c
6
+ metadata.gz: ff4f516b5618e2a010c32ee0360dbfdbc172d400d3570cae3e5078aff845188171f3900849bdbb9c9c8cc869cc419d1995c9162b79e09a2a7d750d05b0591987
7
+ data.tar.gz: 75677a0da407ad97925c69ea51a55d51d4fc3b7a036768e4c5cb2457adbeefdeb924160d3ec8656949b4d2369785c8de4a272a4284ccc12f379eb89b3a7496b3
data/README.md CHANGED
@@ -5,6 +5,56 @@ Redis::Objects - Map Redis types directly to Ruby objects
5
5
  [![Code Coverage](https://codecov.io/gh/nateware/redis-objects/branch/master/graph/badge.svg)](https://codecov.io/gh/nateware/redis-objects)
6
6
  [![Donate](https://www.paypalobjects.com/en_US/i/btn/btn_donate_SM.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=MJF7JU5M7F8VL)
7
7
 
8
+ Important 2.0 changes
9
+ ---------------------
10
+ Redis::Objects 2.0 introduces several important backwards incompatible changes.
11
+ Currently 2.0 can be installed with `gem install redis-objects --pre` or by listing it
12
+ explicitly in your Gemfile:
13
+ ~~~ruby
14
+ # Gemfile
15
+ gem 'redis-objects', '>= 2.0.0.alpha'
16
+ ~~~
17
+ You're encouraged to try it out in test code (not production) to ensure it works for you.
18
+ Official release is expected later in 2022.
19
+
20
+ Key Naming Changes
21
+ ==================
22
+ The internal key naming scheme has changed for `Nested::Class::Namespaces` to fix a longstanding bug.
23
+ **This means your existing data in Redis will not be accessible until you call `migrate_redis_legacy_keys`.**
24
+
25
+ To fix this (only needed once), create a script like this:
26
+
27
+ ~~~ruby
28
+ class YouClassNameHere < ActiveRecord::Base
29
+ include Redis::Objects
30
+ # ... your relevant definitions here ...
31
+ end
32
+
33
+ YourClassName.migrate_redis_legacy_keys
34
+ ~~~
35
+
36
+ Then, you need to find a time when you can temporarily pause writes to your redis server
37
+ so that you can run that script. It uses `redis.scan` internally so it should be able to
38
+ handle a high number of keys. For large data sets, it could take a while.
39
+
40
+ For more details on the issue and fix refer to [#213](https://github.com/nateware/redis-objects/issues/231).
41
+
42
+ Rename of `lock` Method
43
+ =======================
44
+ The `lock` method that collided with `ActiveRecord::Base` has been renamed `redis_lock`.
45
+ This means your classes need to be updated to call `redis_lock` instead:
46
+
47
+ ~~~ruby
48
+ class YouClassNameHere < ActiveRecord::Base
49
+ include Redis::Objects
50
+ redis_lock :mylock # formerly just "lock"
51
+ end
52
+ ~~~
53
+
54
+ For more details on the issue and fix refer to [#213](https://github.com/nateware/redis-objects/issues/231).
55
+
56
+ Overview
57
+ --------
8
58
  This is **not** an ORM. People that are wrapping ORM’s around Redis are missing the point.
9
59
 
10
60
  The killer feature of Redis is that it allows you to perform _atomic_ operations
@@ -119,7 +169,7 @@ Here's an example that integrates several data types with an ActiveRecord model:
119
169
  class Team < ActiveRecord::Base
120
170
  include Redis::Objects
121
171
 
122
- lock :trade_players, :expiration => 15 # sec
172
+ redis_lock :trade_players, :expiration => 15 # sec
123
173
  value :at_bat
124
174
  counter :hits
125
175
  counter :runs
@@ -524,7 +574,7 @@ Locks work similarly. On completion or exception the lock is released:
524
574
 
525
575
  ~~~ruby
526
576
  class Team < ActiveRecord::Base
527
- lock :reorder # declare a lock
577
+ redis_lock :reorder # declare a lock
528
578
  end
529
579
 
530
580
  @team.reorder_lock.lock do
@@ -548,7 +598,7 @@ lock time.
548
598
 
549
599
  ~~~ruby
550
600
  class Team < ActiveRecord::Base
551
- lock :reorder, :expiration => 15.minutes
601
+ redis_lock :reorder, :expiration => 15.minutes
552
602
  end
553
603
  ~~~
554
604
 
@@ -596,5 +646,5 @@ end
596
646
 
597
647
  Author
598
648
  =======
599
- Copyright (c) 2009-2019 [Nate Wiger](http://nateware.com). All Rights Reserved.
649
+ Copyright (c) 2009-2022 [Nate Wiger](http://nateware.com). All Rights Reserved.
600
650
  Released under the [Artistic License](http://www.opensource.org/licenses/artistic-license-2.0.php).
@@ -14,7 +14,7 @@ class Redis
14
14
  module ClassMethods
15
15
  # Define a new lock. It will function like a model attribute,
16
16
  # so it can be used alongside ActiveRecord/DataMapper, etc.
17
- def lock(name, options={})
17
+ def redis_lock(name, options={})
18
18
  options[:timeout] ||= 5 # seconds
19
19
  lock_name = "#{name}_lock"
20
20
  redis_objects[lock_name.to_sym] = options.merge(:type => :lock)
@@ -1,5 +1,5 @@
1
1
  class Redis
2
2
  module Objects
3
- VERSION = "1.7.0"
3
+ VERSION = "2.0.0.alpha"
4
4
  end
5
5
  end
data/lib/redis/objects.rb CHANGED
@@ -101,16 +101,93 @@ class Redis
101
101
  @redis_objects ||= {}
102
102
  end
103
103
 
104
- # Set the Redis redis_prefix to use. Defaults to model_name
105
- def redis_prefix=(redis_prefix) @redis_prefix = redis_prefix end
104
+ # Toggles whether to use the legacy redis key naming scheme, which causes
105
+ # naming conflicts in certain cases.
106
+ attr_accessor :redis_legacy_naming
107
+ attr_accessor :redis_silence_warnings
108
+
109
+ # Set the Redis redis_prefix to use. Defaults to class_name.
110
+ def redis_prefix=(redis_prefix)
111
+ @silence_warnings_as_redis_prefix_was_set_manually = true
112
+ @redis_prefix = redis_prefix
113
+ end
114
+
106
115
  def redis_prefix(klass = self) #:nodoc:
107
- @redis_prefix ||= klass.name.to_s.
108
- sub(%r{(.*::)}, '').
109
- gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
110
- gsub(/([a-z\d])([A-Z])/,'\1_\2').
116
+ @redis_prefix ||=
117
+ if redis_legacy_naming
118
+ redis_legacy_prefix(klass)
119
+ else
120
+ redis_legacy_naming_warning_message(klass)
121
+ redis_modern_prefix(klass)
122
+ end
123
+
124
+ @redis_prefix
125
+ end
126
+
127
+ def redis_modern_prefix(klass = self) #:nodoc:
128
+ klass.name.to_s.
129
+ gsub(/::/, '__'). # Nested::Class => Nested__Class
130
+ gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2'). # ClassName => Class_Name
131
+ gsub(/([a-z\d])([A-Z])/,'\1_\2'). # className => class_Name
132
+ downcase
133
+ end
134
+
135
+ def redis_legacy_prefix(klass = self) #:nodoc:
136
+ klass.name.to_s.
137
+ sub(%r{(.*::)}, ''). # Nested::Class => Class (problematic)
138
+ gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2'). # ClassName => Class_Name
139
+ gsub(/([a-z\d])([A-Z])/,'\1_\2'). # className => class_Name
111
140
  downcase
112
141
  end
113
142
 
143
+ # Temporary warning to help with migrating key names
144
+ def redis_legacy_naming_warning_message(klass)
145
+ # warn @silence_warnings_as_redis_prefix_was_set_manually.inspect
146
+ unless redis_legacy_naming || redis_silence_warnings || @silence_warnings_as_redis_prefix_was_set_manually
147
+ modern = redis_modern_prefix(klass)
148
+ legacy = redis_legacy_prefix(klass)
149
+ if modern != legacy
150
+ warn <<EOW
151
+ WARNING: In redis-objects 2.0.0, key naming will change to fix longstanding bugs.
152
+ Your class #{klass.name.to_s} will be affected by this change!
153
+ Current key prefix: #{legacy.inspect}
154
+ Future key prefix: #{modern.inspect}
155
+ Read more at https://github.com/nateware/redis-objects/issues/231
156
+ EOW
157
+ end
158
+ end
159
+ end
160
+
161
+ def migrate_redis_legacy_keys
162
+ cursor = 0
163
+ legacy = redis_legacy_prefix
164
+ total_keys = 0
165
+ if legacy == redis_prefix
166
+ raise "Failed to migrate keys for #{self.name.to_s} as legacy and new redis_prefix are the same (#{redis_prefix})"
167
+ end
168
+ warn "Migrating keys from #{legacy} prefix to #{redis_prefix}"
169
+
170
+ loop do
171
+ cursor, keys = redis.scan(cursor, :match => "#{legacy}:*")
172
+ total_keys += keys.length
173
+ keys.each do |key|
174
+ # Split key name apart on ':'
175
+ base_class, id, name = key.split(':')
176
+
177
+ # Figure out the new name
178
+ new_key = redis_field_key(name, id=id, context=self)
179
+
180
+ # Rename the key
181
+ warn "Rename '#{key}', '#{new_key}'"
182
+ ok = redis.rename(key, new_key)
183
+ warn "Warning: Rename '#{key}', '#{new_key}' failed: #{ok}" if ok != 'OK'
184
+ end
185
+ break if cursor == "0"
186
+ end
187
+
188
+ warn "Migrated #{total_keys} total number of redis keys"
189
+ end
190
+
114
191
  def redis_options(name)
115
192
  klass = first_ancestor_with(name)
116
193
  return klass.redis_objects[name.to_sym] || {}
@@ -0,0 +1,419 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ require 'redis/objects'
4
+ Redis::Objects.redis = REDIS_HANDLE
5
+
6
+ require 'securerandom'
7
+
8
+ require "stringio"
9
+
10
+ def capture_stderr
11
+ # The output stream must be an IO-like object. In this case we capture it in
12
+ # an in-memory IO object so we can return the string value. You can assign any
13
+ # IO object here.
14
+ previous_stderr, $stderr = $stderr, StringIO.new
15
+ yield
16
+ $stderr.string
17
+ ensure
18
+ # Restore the previous value of stderr (typically equal to STDERR).
19
+ $stderr = previous_stderr
20
+ end
21
+
22
+ describe 'Legacy redis key prefix naming compatibility' do
23
+ it 'verifies single level classes work the same' do
24
+ class SingleLevelOne
25
+ include Redis::Objects
26
+
27
+ def id
28
+ 1
29
+ end
30
+ end
31
+
32
+ obj = SingleLevelOne.new
33
+ obj.class.redis_prefix.should == 'single_level_one'
34
+ end
35
+
36
+ it 'verifies single level classes obey the legacy naming flag' do
37
+ class SingleLevelTwo
38
+ include Redis::Objects
39
+ self.redis_legacy_naming = true
40
+
41
+ def id
42
+ 1
43
+ end
44
+ end
45
+
46
+ obj = SingleLevelTwo.new
47
+ obj.class.redis_prefix.should == 'single_level_two'
48
+ end
49
+
50
+ it 'verifies nested classes do NOT work the same' do
51
+ module Nested
52
+ class NamingOne
53
+ include Redis::Objects
54
+ self.redis_silence_warnings = true
55
+
56
+ def id
57
+ 1
58
+ end
59
+ end
60
+ end
61
+
62
+ obj = Nested::NamingOne.new
63
+ obj.class.redis_prefix.should == 'nested__naming_one'
64
+ end
65
+
66
+ it 'verifies the legacy naming flag is respected' do
67
+ module Nested
68
+ class NamingTwo
69
+ include Redis::Objects
70
+ self.redis_legacy_naming = true
71
+ self.redis_silence_warnings = true
72
+
73
+ def id
74
+ 1
75
+ end
76
+ end
77
+ end
78
+
79
+ Nested::NamingTwo.redis_legacy_naming.should == true
80
+ obj = Nested::NamingTwo.new
81
+ obj.class.redis_prefix.should == 'naming_two'
82
+ end
83
+
84
+ it 'verifies that multiple levels respect __ vs _' do
85
+ module NestedLevel
86
+ module Further
87
+ class NamingThree
88
+ include Redis::Objects
89
+ self.redis_silence_warnings = true
90
+
91
+ def id
92
+ 1
93
+ end
94
+ end
95
+ end
96
+ end
97
+
98
+ obj = NestedLevel::Further::NamingThree.new
99
+ obj.class.redis_prefix.should == 'nested_level__further__naming_three'
100
+ end
101
+
102
+ it 'verifies that multiple levels respect the legacy naming' do
103
+ module NestedLevel
104
+ module Further
105
+ class NamingFour
106
+ include Redis::Objects
107
+ self.redis_legacy_naming = true
108
+
109
+ def id
110
+ 1
111
+ end
112
+
113
+ redis_handle = Redis.new(:host => REDIS_HOST, :port => REDIS_PORT, :db => 31)
114
+ value :redis_value, :redis => redis_handle
115
+ end
116
+ end
117
+ end
118
+
119
+ NestedLevel::Further::NamingFour.redis_legacy_naming.should == true
120
+ obj = NestedLevel::Further::NamingFour.new
121
+ obj.class.redis_prefix.should == 'naming_four'
122
+ val = SecureRandom.hex(10)
123
+ obj.redis_value = val
124
+ obj.redis_value.should == val
125
+ obj.redis_value.key.should == 'naming_four:1:redis_value'
126
+ end
127
+
128
+ it 'verifies that multiple levels do not conflict 1' do
129
+ module NestedLevel
130
+ module Further
131
+ class NamingFive
132
+ include Redis::Objects
133
+ self.redis = Redis.new(:host => REDIS_HOST, :port => REDIS_PORT)
134
+ self.redis_silence_warnings = true
135
+
136
+ def id
137
+ 1
138
+ end
139
+
140
+ value :redis_value
141
+ end
142
+ end
143
+ end
144
+
145
+ obj = NestedLevel::Further::NamingFive.new
146
+ obj.class.redis_prefix.should == 'nested_level__further__naming_five'
147
+ val = SecureRandom.hex(10)
148
+ obj.redis_value = val
149
+ obj.redis_value.should == val
150
+ obj.redis_value.key.should == 'nested_level__further__naming_five:1:redis_value'
151
+ obj.redis_value.redis.should == obj.redis
152
+ obj.redis.get('nested_level__further__naming_five:1:redis_value').should == val
153
+ end
154
+
155
+ it 'verifies that multiple levels do not conflict 2' do
156
+ module Nested
157
+ module LevelFurtherNaming
158
+ class Five
159
+ include Redis::Objects
160
+ self.redis = Redis.new(:host => REDIS_HOST, :port => REDIS_PORT)
161
+ self.redis_silence_warnings = true
162
+
163
+ def id
164
+ 1
165
+ end
166
+
167
+ value :redis_value
168
+ end
169
+ end
170
+ end
171
+
172
+ obj = Nested::LevelFurtherNaming::Five.new
173
+ obj.class.redis_prefix.should == 'nested__level_further_naming__five'
174
+ val = SecureRandom.hex(10)
175
+ obj.redis_value = val
176
+ obj.redis_value.should == val
177
+ obj.redis_value.key.should == 'nested__level_further_naming__five:1:redis_value'
178
+ obj.redis.get('nested__level_further_naming__five:1:redis_value').should == val
179
+ end
180
+
181
+ it 'verifies that multiple levels do not conflict 3' do
182
+ module Nested
183
+ module LevelFurther
184
+ class NamingFive
185
+ include Redis::Objects
186
+ self.redis = Redis.new(:host => REDIS_HOST, :port => REDIS_PORT)
187
+ self.redis_silence_warnings = true
188
+
189
+ def id
190
+ 1
191
+ end
192
+
193
+ value :redis_value
194
+ end
195
+ end
196
+ end
197
+
198
+ obj = Nested::LevelFurther::NamingFive.new
199
+ obj.class.redis_prefix.should == 'nested__level_further__naming_five'
200
+ val = SecureRandom.hex(10)
201
+ obj.redis_value = val
202
+ obj.redis_value.should == val
203
+ obj.redis_value.key.should == 'nested__level_further__naming_five:1:redis_value'
204
+ obj.redis.get('nested__level_further__naming_five:1:redis_value').should == val
205
+ end
206
+
207
+ it 'handles dynamically created classes correctly' do
208
+ module Nested
209
+ class LevelSix
210
+ include Redis::Objects
211
+ self.redis = Redis.new(:host => REDIS_HOST, :port => REDIS_PORT)
212
+ self.redis_silence_warnings = true
213
+
214
+ def id
215
+ 1
216
+ end
217
+
218
+ value :redis_value
219
+ end
220
+ end
221
+
222
+ obj = Nested::LevelSix.new
223
+ obj.class.redis_prefix.should == 'nested__level_six'
224
+ val = SecureRandom.hex(10)
225
+ obj.redis_value = val
226
+ obj.redis_value.should == val
227
+ obj.redis_value.key.should == 'nested__level_six:1:redis_value'
228
+ obj.redis.get('nested__level_six:1:redis_value').should == val
229
+
230
+ DynamicClass = Class.new(Nested::LevelSix)
231
+ DynamicClass.value :redis_value2
232
+ obj2 = DynamicClass.new
233
+ DynamicClass.redis_prefix.should == 'dynamic_class'
234
+ obj2.redis_value.should.be.kind_of(Redis::Value)
235
+ obj2.redis_value2.should.be.kind_of(Redis::Value)
236
+ obj2.redis_value.key.should == 'dynamic_class:1:redis_value'
237
+ obj2.redis_value2.key.should == 'dynamic_class:1:redis_value2'
238
+
239
+ end
240
+
241
+ it 'handles dynamically created classes correctly in legacy mode' do
242
+ module Nested
243
+ class LevelSeven
244
+ include Redis::Objects
245
+ self.redis = Redis.new(:host => REDIS_HOST, :port => REDIS_PORT)
246
+ self.redis_legacy_naming = true
247
+
248
+ def id
249
+ 1
250
+ end
251
+
252
+ value :redis_value
253
+ end
254
+ end
255
+
256
+ obj = Nested::LevelSeven.new
257
+ obj.class.redis_prefix.should == 'level_seven'
258
+ val = SecureRandom.hex(10)
259
+ obj.redis_value = val
260
+ obj.redis_value.should == val
261
+ obj.redis_value.key.should == 'level_seven:1:redis_value'
262
+ obj.redis.get('level_seven:1:redis_value').should == val
263
+
264
+ DynamicClass2 = Class.new(Nested::LevelSeven)
265
+ DynamicClass2.value :redis_value2
266
+ obj2 = DynamicClass2.new
267
+ DynamicClass2.redis_prefix.should == 'dynamic_class2'
268
+ obj2.redis_value.should.be.kind_of(Redis::Value)
269
+ obj2.redis_value2.should.be.kind_of(Redis::Value)
270
+ obj2.redis_value.key.should == 'dynamic_class2:1:redis_value'
271
+ obj2.redis_value2.key.should == 'dynamic_class2:1:redis_value2'
272
+ end
273
+
274
+ it 'prints a warning message if the key name changes' do
275
+ module Nested
276
+ class LevelNine
277
+ include Redis::Objects
278
+ self.redis = Redis.new(:host => REDIS_HOST, :port => REDIS_PORT)
279
+
280
+ def id
281
+ 1
282
+ end
283
+
284
+ value :redis_value
285
+ end
286
+ end
287
+
288
+ captured_output = capture_stderr do
289
+ # Does not output anything directly.
290
+ obj = Nested::LevelNine.new
291
+ val = SecureRandom.hex(10)
292
+ obj.redis_value = val
293
+ obj.redis_value.should == val
294
+ end
295
+
296
+ captured_output.should =~ /Warning:/i
297
+ end
298
+
299
+ it 'supports a method to migrate legacy key names' do
300
+ module Nested
301
+ class Legacy
302
+ include Redis::Objects
303
+ self.redis = Redis.new(:host => REDIS_HOST, :port => REDIS_PORT)
304
+ self.redis_legacy_naming = true
305
+
306
+ # override this for testing - need two classes as if we imagine an old and new one
307
+ # also use the legacy flat prefix that ignores the nested class name
308
+ self.redis_prefix = 'modern'
309
+
310
+ def initialize(id)
311
+ @id = id
312
+ end
313
+ def id
314
+ @id
315
+ end
316
+
317
+ value :redis_value
318
+ counter :redis_counter
319
+ hash_key :redis_hash
320
+ list :redis_list
321
+ set :redis_set
322
+ sorted_set :redis_sorted_set
323
+
324
+ # global class counters
325
+ value :global_value, :global => true
326
+ counter :global_counter, :global => true
327
+ hash_key :global_hash_key, :global => true
328
+ list :global_list, :global => true
329
+ set :global_set, :global => true
330
+ sorted_set :global_sorted_set, :global => true
331
+
332
+ #callable as key
333
+ value :global_proc_value, :global => true, :key => Proc.new { |roster| "#{roster.name}:#{Time.now.strftime('%Y-%m-%dT%H')}:daily" }
334
+ end
335
+ end
336
+
337
+ module Nested
338
+ class Modern
339
+ include Redis::Objects
340
+ self.redis = Redis.new(:host => REDIS_HOST, :port => REDIS_PORT)
341
+
342
+ def initialize(id)
343
+ @id = id
344
+ end
345
+ def id
346
+ @id
347
+ end
348
+
349
+ value :redis_value
350
+ counter :redis_counter
351
+ hash_key :redis_hash
352
+ list :redis_list
353
+ set :redis_set
354
+ sorted_set :redis_sorted_set
355
+
356
+ # global class counters
357
+ value :global_value, :global => true
358
+ counter :global_counter, :global => true
359
+ hash_key :global_hash_key, :global => true
360
+ list :global_list, :global => true
361
+ set :global_set, :global => true
362
+ sorted_set :global_sorted_set, :global => true
363
+
364
+ #callable as key
365
+ value :global_proc_value, :global => true, :key => Proc.new { |roster| "#{roster.name}:#{Time.now.strftime('%Y-%m-%dT%H')}:daily" }
366
+ end
367
+ end
368
+
369
+ # Iterate over them
370
+ Nested::Modern.redis_objects.length.should == 13
371
+ Nested::Modern.redis_objects.length.should == Nested::Legacy.redis_objects.length.should
372
+ Nested::Legacy.redis_prefix.should == 'modern'
373
+ Nested::Modern.redis_prefix.should == 'nested__modern'
374
+
375
+ # Create a whole bunch of keys using the legacy names
376
+ 30.times do |i|
377
+ # warn i.inspect
378
+ obj = Nested::Legacy.new(i)
379
+ obj.redis_value = i
380
+ obj.redis_value.to_i.should == i
381
+ obj.redis_counter.increment
382
+ obj.redis_hash[:key] = i
383
+ obj.redis_list << i
384
+ obj.redis_set << i
385
+ obj.redis_sorted_set[i] = i
386
+ end
387
+
388
+ obj = Nested::Legacy.new(99)
389
+ obj.global_value = 42
390
+ obj.global_counter.increment
391
+ obj.global_counter.increment
392
+ obj.global_counter.increment
393
+ obj.global_hash_key[:key] = 'value'
394
+ obj.global_set << 'a' << 'b'
395
+ obj.global_sorted_set[:key] = 2.2
396
+
397
+ Nested::Modern.migrate_redis_legacy_keys
398
+
399
+ # Try to access the keys through modern names now
400
+ 30.times do |i|
401
+ # warn i.inspect
402
+ obj = Nested::Modern.new(i)
403
+ obj.redis_value.to_i.should == i
404
+ obj.redis_counter.to_i.should == 1
405
+ obj.redis_hash[:key].to_i.should == i
406
+ obj.redis_list[0].to_i.should == i
407
+ obj.redis_set.include?(i).should == true
408
+ obj.redis_sorted_set[i].should == i
409
+ end
410
+
411
+ obj = Nested::Modern.new(99)
412
+ obj.global_value.to_i.should == 42
413
+ obj.global_counter.to_i.should == 3
414
+ obj.global_hash_key[:key].should == 'value'
415
+ obj.global_set.should.include?('a').should == true
416
+ obj.global_set.should.include?('b').should == true
417
+ obj.global_sorted_set[:key].should == 2.2
418
+ end
419
+ end
@@ -34,8 +34,8 @@ describe 'Connection tests' do
34
34
  obj.redis_value.value.should == nil
35
35
 
36
36
  obj.default_redis_value.clear
37
- obj.redis_value.value = 'foo'
38
- obj.redis_value.value.should == 'foo'
37
+ obj.redis_value.value = 'bar'
38
+ obj.redis_value.value.should == 'bar'
39
39
  obj.default_redis_value.value.should == nil
40
40
 
41
41
  obj.redis_value.clear
@@ -10,18 +10,18 @@ class Roster
10
10
  counter :pitchers, :limit => :max_pitchers
11
11
  counter :basic
12
12
  hash_key :contact_information, :marshal_keys=>{'updated_at'=>true}
13
- lock :resort, :timeout => 2
13
+ redis_lock :resort, :timeout => 2
14
14
  value :starting_pitcher, :marshal => true
15
15
  list :player_stats, :marshal => true
16
16
  set :outfielders, :marshal => true
17
17
  sorted_set :rank
18
- lock :per_field
18
+ redis_lock :per_field
19
19
 
20
20
  # global class counters
21
21
  counter :total_players_online, :global => true
22
22
  set :all_players_online, :global => true
23
23
  value :last_player, :global => true
24
- lock :nasty_global_mutex, :global => true # remember it appends "_lock"
24
+ redis_lock :nasty_global_mutex, :global => true # remember it appends "_lock"
25
25
  sorted_set :global_player_leaderboard, :global => true
26
26
  hash_key :global_player_online_status, :global => true
27
27
 
@@ -966,9 +966,13 @@ describe Redis::Objects do
966
966
  end
967
967
 
968
968
  it "should pick up class methods from superclass automatically" do
969
+ Roster.redis_prefix.should == 'roster'
969
970
  CounterRoster = Class.new(Roster)
971
+ CounterRoster.redis_prefix.should == 'counter_roster'
970
972
  CounterRoster.counter :extended_counter
971
973
  extended_roster = CounterRoster.new
974
+ Roster.redis_prefix.should == 'roster'
975
+ extended_roster.class.redis_prefix.should == 'counter_roster'
972
976
  extended_roster.basic.should.be.kind_of(Redis::Counter)
973
977
  extended_roster.extended_counter.should.be.kind_of(Redis::Counter)
974
978
  @roster.respond_to?(:extended_counter).should == false
@@ -981,7 +985,7 @@ describe Redis::Objects do
981
985
  @roster.respond_to?(:extended_hash_key).should == false
982
986
 
983
987
  LockRoster = Class.new(Roster)
984
- LockRoster.lock :extended
988
+ LockRoster.redis_lock :extended
985
989
  extended_roster = LockRoster.new
986
990
  extended_roster.resort_lock.should.be.kind_of(Redis::Lock)
987
991
  extended_roster.extended_lock.should.be.kind_of(Redis::Lock)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redis-objects
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.0
4
+ version: 2.0.0.alpha
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nate Wiger
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-06-22 00:00:00.000000000 Z
11
+ date: 2022-06-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redis
@@ -188,6 +188,7 @@ files:
188
188
  - lib/redis/value.rb
189
189
  - redis-objects.gemspec
190
190
  - spec/redis_autoload_objects_spec.rb
191
+ - spec/redis_legacy_key_naming_spec.rb
191
192
  - spec/redis_namespace_compat_spec.rb
192
193
  - spec/redis_objects_active_record_spec.rb
193
194
  - spec/redis_objects_conn_spec.rb
@@ -210,9 +211,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
210
211
  version: '0'
211
212
  required_rubygems_version: !ruby/object:Gem::Requirement
212
213
  requirements:
213
- - - ">="
214
+ - - ">"
214
215
  - !ruby/object:Gem::Version
215
- version: '0'
216
+ version: 1.3.1
216
217
  requirements: []
217
218
  rubygems_version: 3.3.7
218
219
  signing_key:
@@ -220,6 +221,7 @@ specification_version: 4
220
221
  summary: Map Redis types directly to Ruby objects
221
222
  test_files:
222
223
  - spec/redis_autoload_objects_spec.rb
224
+ - spec/redis_legacy_key_naming_spec.rb
223
225
  - spec/redis_namespace_compat_spec.rb
224
226
  - spec/redis_objects_active_record_spec.rb
225
227
  - spec/redis_objects_conn_spec.rb