redis-copy 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
data/lib/redis-copy/cli.rb
CHANGED
@@ -10,8 +10,10 @@ module RedisCopy
|
|
10
10
|
ui: :command_line,
|
11
11
|
key_emitter: :default,
|
12
12
|
strategy: :auto,
|
13
|
+
pipeline: :true,
|
13
14
|
fail_fast: false,
|
14
|
-
|
15
|
+
prompt: true,
|
16
|
+
trace: false,
|
15
17
|
allow_nonempty: false,
|
16
18
|
}.freeze unless defined?(DEFAULTS)
|
17
19
|
|
@@ -44,30 +46,36 @@ module RedisCopy
|
|
44
46
|
options[:strategy] = strategy
|
45
47
|
end
|
46
48
|
|
47
|
-
opts.on('--[no-]
|
48
|
-
|
49
|
+
opts.on('--[no-]pipeline',
|
50
|
+
"Use redis pipeline where available (default #{DEFAULTS[:pipeline]})"
|
51
|
+
) do |pipeline|
|
52
|
+
options[:pipeline] = pipeline
|
49
53
|
end
|
50
54
|
|
51
|
-
opts.on('-d', '--[no-]debug',
|
55
|
+
opts.on('-d', '--[no-]debug', "Write debug output (default #{DEFAULTS[:debug]})") do |debug|
|
52
56
|
options[:debug] = debug
|
53
57
|
end
|
54
58
|
|
55
|
-
opts.on('-t', '--[no-]trace',
|
59
|
+
opts.on('-t', '--[no-]trace', "Enable backtrace on failure (default #{DEFAULTS[:trace]})") do |trace|
|
56
60
|
options[:trace] = trace
|
57
61
|
end
|
58
62
|
|
59
|
-
opts.on('-f', '--[no-]fail-fast',
|
63
|
+
opts.on('-f', '--[no-]fail-fast', "Abort on first failure (default #{DEFAULTS[:fail_fast]})") do |ff|
|
60
64
|
options[:fail_fast] = ff
|
61
65
|
end
|
62
66
|
|
63
|
-
opts.on('-
|
64
|
-
options[:
|
67
|
+
opts.on('--[no-]prompt', "Prompt for confirmation (default #{DEFAULTS[:prompt]})") do
|
68
|
+
options[:prompt] = true
|
65
69
|
end
|
66
70
|
|
67
|
-
opts.on('--[no-]allow-nonempty',
|
71
|
+
opts.on('--[no-]allow-nonempty', "Allow non-empty destination (default #{DEFAULTS[:allow_nonempty]})") do |allow_nonempty|
|
68
72
|
options[:allow_nonempty] = allow_nonempty
|
69
73
|
end
|
70
74
|
|
75
|
+
opts.on('--[no-]dry-run', 'Output configuration and exit') do |d|
|
76
|
+
options[:dry_run] = true
|
77
|
+
end
|
78
|
+
|
71
79
|
opts.parse!(argv)
|
72
80
|
unless argv.size == 2
|
73
81
|
opts.abort "Source and Destination must be specified\n\n" +
|
@@ -17,22 +17,30 @@ module RedisCopy
|
|
17
17
|
list = @src.lrange(key, 0, -1)
|
18
18
|
if list.length == 0
|
19
19
|
# Empty list special case
|
20
|
-
@dst
|
21
|
-
|
20
|
+
maybe_pipeline(@dst) do |dst|
|
21
|
+
dst.lpush(key, '')
|
22
|
+
dst.lpop(key)
|
23
|
+
end
|
22
24
|
else
|
23
|
-
|
24
|
-
|
25
|
+
maybe_pipeline(@dst) do |dst|
|
26
|
+
list.each do |ele|
|
27
|
+
dst.rpush(key, ele)
|
28
|
+
end
|
25
29
|
end
|
26
30
|
end
|
27
31
|
when "set"
|
28
32
|
set = @src.smembers(key)
|
29
33
|
if set.length == 0
|
30
34
|
# Empty set special case
|
31
|
-
@dst
|
32
|
-
|
35
|
+
maybe_pipeline(@dst) do |dst|
|
36
|
+
dst.sadd(key, '')
|
37
|
+
dst.srem(key, '')
|
38
|
+
end
|
33
39
|
else
|
34
|
-
|
35
|
-
|
40
|
+
maybe_pipeline(@dst) do |dst|
|
41
|
+
set.each do |ele|
|
42
|
+
dst.sadd(key,ele)
|
43
|
+
end
|
36
44
|
end
|
37
45
|
end
|
38
46
|
when 'hash'
|
@@ -50,6 +58,18 @@ module RedisCopy
|
|
50
58
|
|
51
59
|
return true
|
52
60
|
end
|
61
|
+
|
62
|
+
def maybe_pipeline(redis, &block)
|
63
|
+
if pipeline_enabled? && redis.respond_to?(:pipelined)
|
64
|
+
redis.pipelined(&block)
|
65
|
+
else
|
66
|
+
yield(redis)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def pipeline_enabled?
|
71
|
+
@pipeline_enabled ||= (false | @opt[:pipeline])
|
72
|
+
end
|
53
73
|
end
|
54
74
|
end
|
55
75
|
end
|
data/lib/redis-copy/version.rb
CHANGED
@@ -32,11 +32,6 @@ class RedisMultiplex < Struct.new(:source, :destination)
|
|
32
32
|
end
|
33
33
|
|
34
34
|
shared_examples_for(RedisCopy::Strategy) do
|
35
|
-
let(:ui) { double.as_null_object }
|
36
|
-
let(:strategy) { strategy_class.new(source, destination, ui)}
|
37
|
-
let(:source) { Redis.new(db: 14) }
|
38
|
-
let(:destination) { Redis.new(db: 15) }
|
39
|
-
let(:multiplex) { RedisMultiplex.new(source, destination) }
|
40
35
|
let(:key) { rand(16**128).to_s(16) }
|
41
36
|
after(:each) { multiplex.both { |redis| redis.del(key) } }
|
42
37
|
|
@@ -332,6 +327,13 @@ shared_examples_for(RedisCopy::Strategy) do
|
|
332
327
|
end
|
333
328
|
|
334
329
|
describe RedisCopy::Strategy do
|
330
|
+
let(:options) { Hash.new } # append using before(:each) { options.update(foo: true) }
|
331
|
+
let(:ui) { double.as_null_object }
|
332
|
+
let(:strategy) { strategy_class.new(source, destination, ui, options)}
|
333
|
+
let(:multiplex) { RedisMultiplex.new(source, destination) }
|
334
|
+
let(:source) { Redis.new(db: 14) }
|
335
|
+
let(:destination) { Redis.new(db: 15) }
|
336
|
+
|
335
337
|
describe :New do
|
336
338
|
let(:strategy_class) { RedisCopy::Strategy::New }
|
337
339
|
it_should_behave_like RedisCopy::Strategy
|
@@ -339,5 +341,22 @@ describe RedisCopy::Strategy do
|
|
339
341
|
describe :Classic do
|
340
342
|
let(:strategy_class) { RedisCopy::Strategy::Classic }
|
341
343
|
it_should_behave_like RedisCopy::Strategy
|
344
|
+
context '#maybe_pipeline' do
|
345
|
+
it 'should not pipeline' do
|
346
|
+
source.should_not_receive(:pipelined)
|
347
|
+
strategy.maybe_pipeline(source) { }
|
348
|
+
end
|
349
|
+
end
|
350
|
+
|
351
|
+
context 'with pipeline enabled' do
|
352
|
+
before(:each) { options.update pipeline: true }
|
353
|
+
it_should_behave_like RedisCopy::Strategy
|
354
|
+
context '#maybe_pipeline' do
|
355
|
+
it 'should pipeline' do
|
356
|
+
source.should_receive(:pipelined)
|
357
|
+
strategy.maybe_pipeline(source) { }
|
358
|
+
end
|
359
|
+
end
|
360
|
+
end
|
342
361
|
end
|
343
362
|
end
|