redis-copy 1.0.0.rc.0 → 1.0.0.rc.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.
- data/.travis.yml +0 -3
- data/README.md +5 -5
- data/lib/redis-copy/cli.rb +23 -23
- data/lib/redis-copy/strategy.rb +37 -20
- data/lib/redis-copy/version.rb +1 -1
- data/redis-copy.gemspec +1 -1
- metadata +10 -6
- data/.travis/Gemfile.redis-gem-3.0 +0 -6
- data/.travis/Gemfile.redis-gem-master +0 -6
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -26,18 +26,18 @@ Usage: redis-copy [options] <source> <destination>
|
|
26
26
|
like [redis://][<username>:<password>@]<hostname>[:<port>][/<db>]
|
27
27
|
|
28
28
|
Specific options:
|
29
|
-
|
29
|
+
-p, --pattern PATTERN Only transfer matching keys (default *)
|
30
30
|
See http://redis.io/commands/keys for more info.
|
31
|
-
|
31
|
+
-v, --[no-]verify [PERCENT] Verify percentage of transfers -- VERY SLOW (default 0)
|
32
|
+
-n, --[no-]allow-nonempty Allow non-empty destination (default false)
|
33
|
+
-f, --[no-]fail-fast Abort on first failure (default false)
|
34
|
+
--[no-]pipeline Pipeline redis commands where available (default true)
|
32
35
|
-r, --require FILENAME Require a script; useful for loading third-party
|
33
36
|
implementations of key-emitter or copy strategies.
|
34
37
|
Relative paths *must* begin with `../' or `./'.
|
35
38
|
-d, --[no-]debug Write debug output (default false)
|
36
39
|
-t, --[no-]trace Enable backtrace on failure (default false)
|
37
|
-
-f, --[no-]fail-fast Abort on first failure (default false)
|
38
|
-
--[no-]verify [PERCENT] Verify percentage of transfers -- VERY SLOW (default 0)
|
39
40
|
--[no-]prompt Prompt for confirmation (default true)
|
40
|
-
--[no-]allow-nonempty Allow non-empty destination (default false)
|
41
41
|
--[no-]dry-run Output configuration and exit
|
42
42
|
```
|
43
43
|
|
data/lib/redis-copy/cli.rb
CHANGED
@@ -36,15 +36,36 @@ module RedisCopy
|
|
36
36
|
opts.separator ''
|
37
37
|
opts.separator "Specific options:"
|
38
38
|
|
39
|
-
opts.on('--pattern PATTERN', indent_desc[
|
39
|
+
opts.on('-p', '--pattern PATTERN', indent_desc[
|
40
40
|
"Only transfer matching keys (default #{DEFAULTS[:pattern]})\n" +
|
41
41
|
"See http://redis.io/commands/keys for more info."
|
42
42
|
]) do |pattern|
|
43
43
|
options[:pattern] = pattern
|
44
44
|
end
|
45
45
|
|
46
|
+
opts.on('-v', '--[no-]verify [PERCENT]',
|
47
|
+
"Verify percentage of transfers -- VERY SLOW (default #{DEFAULTS[:verify]})"
|
48
|
+
) do |verify|
|
49
|
+
options[:verify] = case verify
|
50
|
+
when /\A1?[0-9]{2}\z/
|
51
|
+
verify.to_i
|
52
|
+
when false, 'false', 'none'
|
53
|
+
0
|
54
|
+
else
|
55
|
+
100
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
opts.on('-n', '--[no-]allow-nonempty', "Allow non-empty destination (default #{DEFAULTS[:allow_nonempty]})") do |allow_nonempty|
|
60
|
+
options[:allow_nonempty] = allow_nonempty
|
61
|
+
end
|
62
|
+
|
63
|
+
opts.on('-f', '--[no-]fail-fast', "Abort on first failure (default #{DEFAULTS[:fail_fast]})") do |ff|
|
64
|
+
options[:fail_fast] = ff
|
65
|
+
end
|
66
|
+
|
46
67
|
opts.on('--[no-]pipeline',
|
47
|
-
"
|
68
|
+
"Pipeline redis commands where available (default #{DEFAULTS[:pipeline]})"
|
48
69
|
) do |pipeline|
|
49
70
|
options[:pipeline] = pipeline
|
50
71
|
end
|
@@ -71,31 +92,10 @@ module RedisCopy
|
|
71
92
|
options[:trace] = trace
|
72
93
|
end
|
73
94
|
|
74
|
-
opts.on('-f', '--[no-]fail-fast', "Abort on first failure (default #{DEFAULTS[:fail_fast]})") do |ff|
|
75
|
-
options[:fail_fast] = ff
|
76
|
-
end
|
77
|
-
|
78
|
-
opts.on('--[no-]verify [PERCENT]',
|
79
|
-
"Verify percentage of transfers -- VERY SLOW (default #{DEFAULTS[:verify]})"
|
80
|
-
) do |verify|
|
81
|
-
options[:verify] = case verify
|
82
|
-
when /\A1?[0-9]{2}\z/
|
83
|
-
verify.to_i
|
84
|
-
when false, 'false', 'none'
|
85
|
-
0
|
86
|
-
else
|
87
|
-
100
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
95
|
opts.on('--[no-]prompt', "Prompt for confirmation (default #{DEFAULTS[:prompt]})") do |prompt|
|
92
96
|
options[:prompt] = prompt
|
93
97
|
end
|
94
98
|
|
95
|
-
opts.on('--[no-]allow-nonempty', "Allow non-empty destination (default #{DEFAULTS[:allow_nonempty]})") do |allow_nonempty|
|
96
|
-
options[:allow_nonempty] = allow_nonempty
|
97
|
-
end
|
98
|
-
|
99
99
|
opts.on('--[no-]dry-run', 'Output configuration and exit') do |d|
|
100
100
|
options[:dry_run] = true
|
101
101
|
end
|
data/lib/redis-copy/strategy.rb
CHANGED
@@ -27,41 +27,58 @@ module RedisCopy
|
|
27
27
|
def verify?(key)
|
28
28
|
@ui.debug("VERIFY: #{key.dump}")
|
29
29
|
type = @src.type(key)
|
30
|
-
proc = case type
|
31
|
-
when 'string' then proc { |r| r.get key }
|
32
|
-
when 'hash' then proc { |r| r.hgetall key }
|
33
|
-
when 'zset' then proc { |r| r.zrange(key, 0, -1, :with_scores => true) }
|
34
|
-
when 'set' then proc { |r| r.smembers(key).sort }
|
35
|
-
when 'list' then proc { |r| r.lrange(key, 0, -1) }
|
36
|
-
else
|
37
|
-
@ui.debug("BORK: #{key.dump} has unknown type #{type.dump}!")
|
38
|
-
return false
|
39
|
-
end
|
40
30
|
|
41
|
-
|
42
|
-
|
31
|
+
template = { args: [key],
|
32
|
+
proc: ->(x){ x },
|
33
|
+
test: ->(a, b) { a == b } }
|
34
|
+
|
35
|
+
export_command = case type
|
36
|
+
when 'string'
|
37
|
+
{ command: :get }
|
38
|
+
when 'hash'
|
39
|
+
{ command: :hgetall }
|
40
|
+
when 'zset'
|
41
|
+
{ command: :zrange,
|
42
|
+
args: [key, 0, -1, {with_scores: true}] }
|
43
|
+
when 'set'
|
44
|
+
{ command: :smembers,
|
45
|
+
proc: ->(x){ x.to_set} }
|
46
|
+
when 'list'
|
47
|
+
{ command: :lrange,
|
48
|
+
args: [key, 0, -1] }
|
49
|
+
else
|
50
|
+
@ui.debug("BORK: #{key.dump} has unknown type #{type.dump}!")
|
51
|
+
return false
|
52
|
+
end
|
53
|
+
|
54
|
+
# account for drift, ensure within 1 of each other.
|
55
|
+
ttl_command = {command: :ttl, test: ->(a,b){ (a - b).abs <= 1 } }
|
56
|
+
|
57
|
+
return false unless same_response?(template.merge export_command)
|
58
|
+
return false unless same_response?(template.merge ttl_command)
|
43
59
|
|
44
60
|
true
|
45
61
|
end
|
46
62
|
|
47
63
|
private
|
48
64
|
|
49
|
-
def same_response?(
|
65
|
+
def same_response?(hsh)
|
50
66
|
responses = {
|
51
|
-
source: capture_result(@src,
|
52
|
-
destination: capture_result(@dst,
|
67
|
+
source: capture_result(@src, hsh),
|
68
|
+
destination: capture_result(@dst, hsh)
|
53
69
|
}
|
54
|
-
if (responses[:source]
|
70
|
+
if (hsh[:test].call(responses[:source], responses[:destination]))
|
55
71
|
return true
|
56
72
|
else
|
57
|
-
@ui.debug("MISMATCH: #{
|
73
|
+
@ui.debug("MISMATCH: #{hsh.inspect} => #{responses.inspect}")
|
58
74
|
return false
|
59
75
|
end
|
60
76
|
end
|
61
77
|
|
62
|
-
def capture_result(redis,
|
63
|
-
|
64
|
-
|
78
|
+
def capture_result(redis, hsh)
|
79
|
+
result = redis.send(hsh[:command], *hsh[:args])
|
80
|
+
return hsh[:proc].call(result)
|
81
|
+
rescue Object => exception
|
65
82
|
return [:raised, exception]
|
66
83
|
end
|
67
84
|
end
|
data/lib/redis-copy/version.rb
CHANGED
data/redis-copy.gemspec
CHANGED
@@ -33,7 +33,7 @@ Gem::Specification.new do |spec|
|
|
33
33
|
spec.add_development_dependency 'rake'
|
34
34
|
spec.add_development_dependency 'rspec', '~> 2.14'
|
35
35
|
|
36
|
-
spec.add_runtime_dependency 'redis'
|
36
|
+
spec.add_runtime_dependency 'redis', '~> 3.0', '>= 3.0.6'
|
37
37
|
spec.add_runtime_dependency 'activesupport'
|
38
38
|
spec.add_runtime_dependency 'implements', '~> 0.0.2'
|
39
39
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: redis-copy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0.rc.
|
4
|
+
version: 1.0.0.rc.1
|
5
5
|
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2013-11-
|
13
|
+
date: 2013-11-18 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: bundler
|
@@ -65,17 +65,23 @@ dependencies:
|
|
65
65
|
requirement: !ruby/object:Gem::Requirement
|
66
66
|
none: false
|
67
67
|
requirements:
|
68
|
+
- - ~>
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: '3.0'
|
68
71
|
- - ! '>='
|
69
72
|
- !ruby/object:Gem::Version
|
70
|
-
version:
|
73
|
+
version: 3.0.6
|
71
74
|
type: :runtime
|
72
75
|
prerelease: false
|
73
76
|
version_requirements: !ruby/object:Gem::Requirement
|
74
77
|
none: false
|
75
78
|
requirements:
|
79
|
+
- - ~>
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '3.0'
|
76
82
|
- - ! '>='
|
77
83
|
- !ruby/object:Gem::Version
|
78
|
-
version:
|
84
|
+
version: 3.0.6
|
79
85
|
- !ruby/object:Gem::Dependency
|
80
86
|
name: activesupport
|
81
87
|
requirement: !ruby/object:Gem::Requirement
|
@@ -120,8 +126,6 @@ extra_rdoc_files: []
|
|
120
126
|
files:
|
121
127
|
- .gitignore
|
122
128
|
- .travis.yml
|
123
|
-
- .travis/Gemfile.redis-gem-3.0
|
124
|
-
- .travis/Gemfile.redis-gem-master
|
125
129
|
- Gemfile
|
126
130
|
- LICENSE.txt
|
127
131
|
- README.md
|