redis-copy 0.0.2 → 0.0.3
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.
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
|