redis-copy 0.0.6 → 1.0.0.rc.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -3,7 +3,7 @@
3
3
  module RedisCopy
4
4
  module UI
5
5
  class AutoRun
6
- include UI
6
+ implements UI
7
7
 
8
8
  def confirm?(prompt)
9
9
  $stderr.puts(prompt)
@@ -3,7 +3,9 @@
3
3
  module RedisCopy
4
4
  module UI
5
5
  class CommandLine
6
- include UI
6
+ implements UI do |options|
7
+ options[:ui].to_s.underscore.dasherize == 'command-line'
8
+ end
7
9
 
8
10
  def confirm?(prompt)
9
11
  $stderr.puts(prompt)
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module RedisCopy
4
- VERSION = '0.0.6'
4
+ VERSION = '1.0.0.rc.0'
5
5
  end
data/redis-copy.gemspec CHANGED
@@ -27,10 +27,13 @@ Gem::Specification.new do |spec|
27
27
  spec.test_files = spec.files.grep(/^(test|spec|features)\//)
28
28
  spec.require_paths = ['lib']
29
29
 
30
+ spec.required_ruby_version = '>= 1.9.3'
31
+
30
32
  spec.add_development_dependency 'bundler', '~> 1.3'
31
33
  spec.add_development_dependency 'rake'
32
34
  spec.add_development_dependency 'rspec', '~> 2.14'
33
35
 
34
36
  spec.add_runtime_dependency 'redis'
35
37
  spec.add_runtime_dependency 'activesupport'
38
+ spec.add_runtime_dependency 'implements', '~> 0.0.2'
36
39
  end
@@ -1,35 +1,8 @@
1
1
  # encoding: utf-8
2
- require 'redis-copy'
3
- require_relative '../spec_helper.rb'
4
-
5
- shared_examples_for RedisCopy::KeyEmitter do
6
- let(:emitter_klass) { described_class }
7
- let(:redis) { Redis.new(REDIS_OPTIONS) }
8
- let(:ui) { double.as_null_object }
9
- let(:instance) { emitter_klass.new(redis, ui)}
10
- let(:key_count) { 1 }
11
- let(:keys) { key_count.times.map{|i| i.to_s(16) } }
12
-
13
- before(:each) do
14
- unless emitter_klass.compatible?(redis)
15
- pending "#{emitter_klass} not supported in your environment"
16
- end
17
- key_count.times.each_slice(50) do |keys|
18
- kv = keys.map{|x| x.to_s(16)}.zip(keys)
19
- redis.mset(*kv.flatten)
20
- end
21
- ui.stub(:debug).with(anything)
22
- end
23
- after(:each) { redis.flushdb }
2
+ require_relative '../../spec_helper.rb'
24
3
 
25
- context '#keys' do
26
- let(:key_count) { 64 }
27
- context 'the result' do
28
- subject { instance.keys }
29
- its(:to_a) { should =~ keys }
30
- end
31
- end
32
- end
4
+ require 'redis-copy'
5
+ require 'redis-copy/key-emitter/interface.spec'
33
6
 
34
7
  describe RedisCopy::KeyEmitter::Keys do
35
8
  it_should_behave_like RedisCopy::KeyEmitter do
@@ -61,7 +34,3 @@ describe RedisCopy::KeyEmitter::Keys do
61
34
  end
62
35
  end
63
36
  end
64
-
65
- describe RedisCopy::KeyEmitter::Scan do
66
- it_should_behave_like RedisCopy::KeyEmitter
67
- end
@@ -0,0 +1,9 @@
1
+ # encoding: utf-8
2
+ require_relative '../../spec_helper.rb'
3
+
4
+ require 'redis-copy'
5
+ require 'redis-copy/key-emitter/interface.spec'
6
+
7
+ describe RedisCopy::KeyEmitter::Scan do
8
+ it_should_behave_like RedisCopy::KeyEmitter
9
+ end
@@ -0,0 +1,27 @@
1
+ # encoding: utf-8
2
+ require_relative '../../spec_helper'
3
+
4
+ require 'redis-copy'
5
+ require 'redis-copy/strategy/interface.spec'
6
+
7
+ describe RedisCopy::Strategy::Classic do
8
+ it_should_behave_like RedisCopy::Strategy do
9
+ context '#maybe_pipeline' do
10
+ it 'should not pipeline' do
11
+ source.should_not_receive(:pipelined)
12
+ strategy.maybe_pipeline(source) { }
13
+ end
14
+ end
15
+
16
+ context 'with pipeline enabled' do
17
+ let(:options) { Hash.new(pipeline: true) }
18
+ it_should_behave_like RedisCopy::Strategy
19
+ context '#maybe_pipeline' do
20
+ it 'should pipeline' do
21
+ source.should_receive(:pipelined)
22
+ strategy.maybe_pipeline(source) { }
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,9 @@
1
+ # encoding: utf-8
2
+ require_relative '../../spec_helper'
3
+
4
+ require 'redis-copy'
5
+ require 'redis-copy/strategy/interface.spec'
6
+
7
+ describe RedisCopy::Strategy::DumpRestore do
8
+ it_should_behave_like RedisCopy::Strategy
9
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  REDIS_PORT = 6381
2
4
  REDIS_OPTIONS = {
3
5
  :port => REDIS_PORT,
metadata CHANGED
@@ -1,8 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redis-copy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
5
- prerelease:
4
+ version: 1.0.0.rc.0
5
+ prerelease: 6
6
6
  platform: ruby
7
7
  authors:
8
8
  - Ryan Biesemeyer
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-11-13 00:00:00.000000000 Z
13
+ date: 2013-11-15 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: bundler
@@ -92,6 +92,22 @@ dependencies:
92
92
  - - ! '>='
93
93
  - !ruby/object:Gem::Version
94
94
  version: '0'
95
+ - !ruby/object:Gem::Dependency
96
+ name: implements
97
+ requirement: !ruby/object:Gem::Requirement
98
+ none: false
99
+ requirements:
100
+ - - ~>
101
+ - !ruby/object:Gem::Version
102
+ version: 0.0.2
103
+ type: :runtime
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ none: false
107
+ requirements:
108
+ - - ~>
109
+ - !ruby/object:Gem::Version
110
+ version: 0.0.2
95
111
  description: A command-line utility built for copying the contents of one redis db
96
112
  to another over a network. Supports all data types, persists ttls, and attempts
97
113
  to be as efficient as possible.
@@ -105,9 +121,7 @@ files:
105
121
  - .gitignore
106
122
  - .travis.yml
107
123
  - .travis/Gemfile.redis-gem-3.0
108
- - .travis/Gemfile.redis-gem-3.0.lock
109
124
  - .travis/Gemfile.redis-gem-master
110
- - .travis/Gemfile.redis-gem-master.lock
111
125
  - Gemfile
112
126
  - LICENSE.txt
113
127
  - README.md
@@ -117,9 +131,13 @@ files:
117
131
  - lib/redis-copy/cli.rb
118
132
  - lib/redis-copy/core_ext.rb
119
133
  - lib/redis-copy/key-emitter.rb
134
+ - lib/redis-copy/key-emitter/interface.spec.rb
135
+ - lib/redis-copy/key-emitter/keys.rb
136
+ - lib/redis-copy/key-emitter/scan.rb
120
137
  - lib/redis-copy/strategy.rb
121
138
  - lib/redis-copy/strategy/classic.rb
122
- - lib/redis-copy/strategy/new.rb
139
+ - lib/redis-copy/strategy/dump-restore.rb
140
+ - lib/redis-copy/strategy/interface.spec.rb
123
141
  - lib/redis-copy/ui.rb
124
142
  - lib/redis-copy/ui/auto_run.rb
125
143
  - lib/redis-copy/ui/command_line.rb
@@ -127,8 +145,10 @@ files:
127
145
  - redis-copy.gemspec
128
146
  - redis-copy_spec.rb
129
147
  - spec/db/.gitkeep
130
- - spec/redis-copy/key-emitter_spec.rb
131
- - spec/redis-copy/strategy_spec.rb
148
+ - spec/redis-copy/key-emitter/keys_spec.rb
149
+ - spec/redis-copy/key-emitter/scan_spec.rb
150
+ - spec/redis-copy/strategy/classic_spec.rb
151
+ - spec/redis-copy/strategy/dump-restore_spec.rb
132
152
  - spec/redis.spec.conf
133
153
  - spec/spec_helper.rb
134
154
  homepage: https://github.com/yaauie/redis-copy
@@ -143,19 +163,13 @@ required_ruby_version: !ruby/object:Gem::Requirement
143
163
  requirements:
144
164
  - - ! '>='
145
165
  - !ruby/object:Gem::Version
146
- version: '0'
147
- segments:
148
- - 0
149
- hash: 2506344141455451823
166
+ version: 1.9.3
150
167
  required_rubygems_version: !ruby/object:Gem::Requirement
151
168
  none: false
152
169
  requirements:
153
- - - ! '>='
170
+ - - ! '>'
154
171
  - !ruby/object:Gem::Version
155
- version: '0'
156
- segments:
157
- - 0
158
- hash: 2506344141455451823
172
+ version: 1.3.1
159
173
  requirements: []
160
174
  rubyforge_project:
161
175
  rubygems_version: 1.8.24
@@ -164,7 +178,10 @@ specification_version: 3
164
178
  summary: Copy the contents of one redis db to another
165
179
  test_files:
166
180
  - spec/db/.gitkeep
167
- - spec/redis-copy/key-emitter_spec.rb
168
- - spec/redis-copy/strategy_spec.rb
181
+ - spec/redis-copy/key-emitter/keys_spec.rb
182
+ - spec/redis-copy/key-emitter/scan_spec.rb
183
+ - spec/redis-copy/strategy/classic_spec.rb
184
+ - spec/redis-copy/strategy/dump-restore_spec.rb
169
185
  - spec/redis.spec.conf
170
186
  - spec/spec_helper.rb
187
+ has_rdoc:
@@ -1,44 +0,0 @@
1
- PATH
2
- remote: ../
3
- specs:
4
- redis-copy (0.0.5)
5
- activesupport
6
- redis
7
-
8
- GEM
9
- remote: https://rubygems.org/
10
- specs:
11
- activesupport (4.0.1)
12
- i18n (~> 0.6, >= 0.6.4)
13
- minitest (~> 4.2)
14
- multi_json (~> 1.3)
15
- thread_safe (~> 0.1)
16
- tzinfo (~> 0.3.37)
17
- atomic (1.1.14)
18
- diff-lcs (1.2.5)
19
- i18n (0.6.5)
20
- minitest (4.7.5)
21
- multi_json (1.8.2)
22
- rake (10.1.0)
23
- redis (3.0.5)
24
- rspec (2.14.1)
25
- rspec-core (~> 2.14.0)
26
- rspec-expectations (~> 2.14.0)
27
- rspec-mocks (~> 2.14.0)
28
- rspec-core (2.14.7)
29
- rspec-expectations (2.14.4)
30
- diff-lcs (>= 1.1.3, < 2.0)
31
- rspec-mocks (2.14.4)
32
- thread_safe (0.1.3)
33
- atomic
34
- tzinfo (0.3.38)
35
-
36
- PLATFORMS
37
- ruby
38
-
39
- DEPENDENCIES
40
- bundler (~> 1.3)
41
- rake
42
- redis (~> 3.0)
43
- redis-copy!
44
- rspec (~> 2.14)
@@ -1,49 +0,0 @@
1
- GIT
2
- remote: https://github.com/redis/redis-rb.git
3
- revision: 9bb4156dcd43105b68e24e5efc579dddb12cf260
4
- specs:
5
- redis (3.0.6)
6
-
7
- PATH
8
- remote: ../
9
- specs:
10
- redis-copy (0.0.5)
11
- activesupport
12
- redis
13
-
14
- GEM
15
- remote: https://rubygems.org/
16
- specs:
17
- activesupport (4.0.1)
18
- i18n (~> 0.6, >= 0.6.4)
19
- minitest (~> 4.2)
20
- multi_json (~> 1.3)
21
- thread_safe (~> 0.1)
22
- tzinfo (~> 0.3.37)
23
- atomic (1.1.14)
24
- diff-lcs (1.2.5)
25
- i18n (0.6.5)
26
- minitest (4.7.5)
27
- multi_json (1.8.2)
28
- rake (10.1.0)
29
- rspec (2.14.1)
30
- rspec-core (~> 2.14.0)
31
- rspec-expectations (~> 2.14.0)
32
- rspec-mocks (~> 2.14.0)
33
- rspec-core (2.14.7)
34
- rspec-expectations (2.14.4)
35
- diff-lcs (>= 1.1.3, < 2.0)
36
- rspec-mocks (2.14.4)
37
- thread_safe (0.1.3)
38
- atomic
39
- tzinfo (0.3.38)
40
-
41
- PLATFORMS
42
- ruby
43
-
44
- DEPENDENCIES
45
- bundler (~> 1.3)
46
- rake
47
- redis!
48
- redis-copy!
49
- rspec (~> 2.14)
@@ -1,314 +0,0 @@
1
- # encoding: utf-8
2
- require_relative '../spec_helper'
3
-
4
- shared_examples_for(:no_ttl) do
5
- # key, redis,
6
- subject { redis.ttl(key) }
7
- it { should be < 0 }
8
- end
9
-
10
- shared_examples_for(:ttl_set) do
11
- # key, redis, ttl
12
- subject { redis.ttl(key) }
13
- it { should eq ttl }
14
- end
15
-
16
- shared_examples_for '#verify?' do
17
- before(:each) do
18
- ui.stub(:debug).and_call_original
19
- ui.stub(:notify) do |message|
20
- puts message
21
- end
22
- end
23
- it 'should verify successfully' do
24
- strategy.verify?(key).should be_true
25
- end
26
- end
27
-
28
- shared_examples_for(RedisCopy::Strategy) do
29
- let(:strategy_class) { described_class }
30
- let(:options) { Hash.new } # append using before(:each) { options.update(foo: true) }
31
- # let(:ui) { double.as_null_object }
32
- let(:ui) { RedisCopy::UI::CommandLine.new(options) }
33
- let(:strategy) { strategy_class.new(source, destination, ui, options)}
34
- let(:multiplex) { RedisMultiplex.new(source, destination) }
35
- let(:source) { Redis.new(REDIS_OPTIONS.merge(db: 14)) }
36
- let(:destination) { Redis.new(REDIS_OPTIONS.merge(db: 15)) }
37
-
38
- let(:key) { rand(16**128).to_s(16) }
39
- after(:each) { multiplex.both { |redis| redis.del(key) } }
40
- let(:ttl) { 100 }
41
-
42
- before(:each) do
43
- unless [source, destination].all?{|redis| strategy_class.compatible?(redis) }
44
- pending "#{strategy_class} not supported in your environment"
45
- end
46
- end
47
-
48
- context '#copy' do
49
- before(:each) { populate.call }
50
- context 'string' do
51
- let(:source_string) { rand(16**256).to_s(16) }
52
- let(:populate) { proc {source.set(key, source_string)} }
53
- [true,false].each do |with_expiry|
54
- context "with_expiry(#{with_expiry})" do
55
- before(:each) { source.expire(key, ttl) } if with_expiry
56
- context 'before' do
57
- context 'source' do
58
- let(:redis) { source }
59
- subject { source.get(key) }
60
- it { should_not be_nil }
61
- it { should eq source_string }
62
- it_should_behave_like (with_expiry ? :ttl_set : :no_ttl)
63
- end
64
- context 'destination' do
65
- let(:redis) { destination }
66
- subject { destination.get(key) }
67
- it { should be_nil }
68
- it_should_behave_like :no_ttl
69
- end
70
- end
71
-
72
- context 'after' do
73
- before(:each) { strategy.copy(key) }
74
- context 'source' do
75
- let(:redis) { source }
76
- subject { source.get(key) }
77
- it { should_not be_nil }
78
- it { should eq source_string }
79
- it_should_behave_like (with_expiry ? :ttl_set : :no_ttl)
80
- end
81
- context 'destination' do
82
- let(:redis) { destination }
83
- subject { destination.get(key) }
84
- it { should_not be_nil }
85
- it { should eq source_string }
86
- it_should_behave_like (with_expiry ? :ttl_set : :no_ttl)
87
- end
88
- it_should_behave_like '#verify?'
89
- end
90
- end
91
- end
92
- end
93
-
94
- context 'list' do
95
- let(:source_list) do
96
- %w(foo bar baz buz bingo jango)
97
- end
98
- let(:populate) { proc { source_list.each{|x| source.rpush(key, x)} } }
99
- [true,false].each do |with_expiry|
100
- context "with_expiry(#{with_expiry})" do
101
- before(:each) { source.expire(key, 100) } if with_expiry
102
- context 'before' do
103
- context 'source' do
104
- let(:redis) { source }
105
- subject { source.lrange(key, 0, -1) }
106
- it { should_not be_empty }
107
- it { should eq source_list }
108
- it_should_behave_like (with_expiry ? :ttl_set : :no_ttl)
109
- end
110
- context 'destination' do
111
- let(:redis) { destination }
112
- subject { destination.lrange(key, 0, -1) }
113
- it { should be_empty }
114
- it_should_behave_like :no_ttl
115
- end
116
- end
117
-
118
- context 'after' do
119
- before(:each) { strategy.copy(key) }
120
- context 'source' do
121
- let(:redis) { source }
122
- subject { source.lrange(key, 0, -1) }
123
- it { should_not be_empty }
124
- it { should eq source_list }
125
- it_should_behave_like (with_expiry ? :ttl_set : :no_ttl)
126
- end
127
- context 'destination' do
128
- let(:redis) { destination }
129
- subject { destination.lrange(key, 0, -1) }
130
- it { should_not be_empty }
131
- it { should eq source_list }
132
- it_should_behave_like (with_expiry ? :ttl_set : :no_ttl)
133
- end
134
- it_should_behave_like '#verify?'
135
- end
136
- end
137
- end
138
- end
139
-
140
- context 'set' do
141
- let(:source_list) do
142
- %w(foo bar baz buz bingo jango)
143
- end
144
- let(:populate) { proc { source_list.each{|x| source.sadd(key, x)} } }
145
- [true,false].each do |with_expiry|
146
- context "with_expiry(#{with_expiry})" do
147
- before(:each) { source.expire(key, 100) } if with_expiry
148
- context 'before' do
149
- context 'source' do
150
- let(:redis) { source }
151
- subject { source.smembers(key) }
152
- it { should_not be_empty }
153
- it { should =~ source_list }
154
- it_should_behave_like (with_expiry ? :ttl_set : :no_ttl)
155
- end
156
- context 'destination' do
157
- let(:redis) { destination }
158
- subject { destination.smembers(key) }
159
- it { should be_empty }
160
- it_should_behave_like :no_ttl
161
- end
162
- end
163
-
164
- context 'after' do
165
- before(:each) { strategy.copy(key) }
166
- context 'source' do
167
- let(:redis) { source }
168
- subject { source.smembers(key) }
169
- it { should_not be_empty }
170
- it { should =~ source_list }
171
- it_should_behave_like (with_expiry ? :ttl_set : :no_ttl)
172
- end
173
- context 'destination' do
174
- let(:redis) { destination }
175
- subject { destination.smembers(key) }
176
- it { should_not be_empty }
177
- it { should =~ source_list }
178
- it_should_behave_like (with_expiry ? :ttl_set : :no_ttl)
179
- end
180
- end
181
- end
182
- end
183
- end
184
-
185
- context 'hash' do
186
- let(:source_hash) do
187
- {
188
- 'foo' => 'bar',
189
- 'baz' => 'buz'
190
- }
191
- end
192
- let(:populate) { proc { source.mapped_hmset(key, source_hash) } }
193
- [true,false].each do |with_expiry|
194
- context "with_expiry(#{with_expiry})" do
195
- before(:each) { source.expire(key, 100) } if with_expiry
196
- context 'before' do
197
- context 'source' do
198
- let(:redis) { source }
199
- subject { source.hgetall(key) }
200
- it { should_not be_empty }
201
- it { should eq source_hash }
202
- it_should_behave_like (with_expiry ? :ttl_set : :no_ttl)
203
- end
204
- context 'destination' do
205
- let(:redis) { destination }
206
- subject { destination.hgetall(key) }
207
- it { should be_empty }
208
- it_should_behave_like :no_ttl
209
- end
210
- end
211
-
212
- context 'after' do
213
- before(:each) { strategy.copy(key) }
214
- context 'source' do
215
- let(:redis) { source }
216
- subject { source.hgetall(key) }
217
- it { should_not be_empty }
218
- it { should eq source_hash }
219
- it_should_behave_like (with_expiry ? :ttl_set : :no_ttl)
220
- end
221
- context 'destination' do
222
- let(:redis) { destination }
223
- subject { destination.hgetall(key) }
224
- it { should_not be_empty }
225
- it { should eq source_hash }
226
- it_should_behave_like (with_expiry ? :ttl_set : :no_ttl)
227
- end
228
- it_should_behave_like '#verify?'
229
- end
230
- end
231
- end
232
- end
233
-
234
- context 'zset' do
235
- let(:source_zset) do
236
- {
237
- 'foo' => 1.0,
238
- 'baz' => 2.5,
239
- 'bar' => 1.1,
240
- 'buz' => 2.7
241
- }
242
- end
243
- let(:vs_source_zset) { source_zset.to_a }
244
- let(:sv_source_zset) { vs_source_zset.map(&:reverse) }
245
- let(:populate) { proc { source.zadd(key, sv_source_zset) } }
246
- [true,false].each do |with_expiry|
247
- context "with_expiry(#{with_expiry})" do
248
- before(:each) { source.expire(key, 100) } if with_expiry
249
- context 'before' do
250
- context 'source' do
251
- let(:redis) { source }
252
- subject { source.zrange(key, 0, -1, :with_scores => true) }
253
- it { should_not be_empty }
254
- it { should =~ vs_source_zset }
255
- it_should_behave_like (with_expiry ? :ttl_set : :no_ttl)
256
- end
257
- context 'destination' do
258
- let(:redis) { destination }
259
- subject { destination.zrange(key, 0, -1, :with_scores => true) }
260
- it { should be_empty }
261
- it_should_behave_like :no_ttl
262
- end
263
- end
264
-
265
- context 'after' do
266
- before(:each) { strategy.copy(key) }
267
- context 'source' do
268
- let(:redis) { source }
269
- subject { source.zrange(key, 0, -1, :with_scores => true) }
270
- it { should_not be_empty }
271
- it { should =~ vs_source_zset }
272
- it_should_behave_like (with_expiry ? :ttl_set : :no_ttl)
273
- end
274
- context 'destination' do
275
- let(:redis) { destination }
276
- subject { destination.zrange(key, 0, -1, :with_scores => true) }
277
- it { should_not be_empty }
278
- it { should =~ vs_source_zset }
279
- it_should_behave_like (with_expiry ? :ttl_set : :no_ttl)
280
- end
281
- it_should_behave_like '#verify?'
282
- end
283
- end
284
- end
285
- end
286
- end
287
- end
288
-
289
-
290
- describe RedisCopy::Strategy::New do
291
- it_should_behave_like RedisCopy::Strategy
292
- end
293
-
294
- describe RedisCopy::Strategy::Classic do
295
- it_should_behave_like RedisCopy::Strategy do
296
- context '#maybe_pipeline' do
297
- it 'should not pipeline' do
298
- source.should_not_receive(:pipelined)
299
- strategy.maybe_pipeline(source) { }
300
- end
301
- end
302
-
303
- context 'with pipeline enabled' do
304
- before(:each) { options.update pipeline: true }
305
- it_should_behave_like RedisCopy::Strategy
306
- context '#maybe_pipeline' do
307
- it 'should pipeline' do
308
- source.should_receive(:pipelined)
309
- strategy.maybe_pipeline(source) { }
310
- end
311
- end
312
- end
313
- end
314
- end