redis-copy 0.0.1 → 0.0.2

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/README.md CHANGED
@@ -1,24 +1,59 @@
1
1
  # Redis::Copy
2
2
 
3
- TODO: Write a gem description
3
+ This utility provides a way to move the contents of one redis DB to another
4
+ redis DB. It is inspired by the [redis-copy.rb script][original] included in
5
+ the redis source, but supports the following additional features:
6
+
7
+ - all known data types (original supported `set`, `list`, and `string`,
8
+ dropping the others without warning)
9
+ - if available on both dbs, will use `DUMP`/`RESTORE` commands (redis v2.6+)
10
+ - support for more than just db0
11
+
12
+ [original]: https://github.com/antirez/redis/commits/unstable/utils/redis-copy.rb
4
13
 
5
14
  ## Installation
6
15
 
7
- Add this line to your application's Gemfile:
16
+ $ gem install redis-copy
8
17
 
9
- gem 'redis-copy'
18
+ ## Usage
10
19
 
11
- And then execute:
20
+ The current options can be grabbed using the `--help` flag.
12
21
 
13
- $ bundle
22
+ ```
23
+ $ redis-copy --help
24
+ redis-copy v0.0.2
25
+ Usage: redis-copy [options] <source> <destination>
26
+ <source> and <destination> must be redis connection uris
27
+ like [redis://]<hostname>[:<port>][/<db>]
14
28
 
15
- Or install it yourself as:
29
+ Specific options:
30
+ --strategy STRATEGY Select strategy (auto, new, classic) (default auto)
31
+ auto: uses new if available, otherwise fallback
32
+ new: use redis DUMP and RESTORE commands (faster)
33
+ classic: migrates via multiple type-specific commands
34
+ --[no-]dry-run Output configuration and exit
35
+ -d, --[no-]debug Write debug output
36
+ -t, --[no-]trace Enable backtrace on failure
37
+ -f, --[no-]fail-fast Abort on first failure
38
+ -y, --yes Automatically accept any prompts
39
+ --[no-]allow-nonempty Allow non-empty destination
16
40
 
17
- $ gem install redis-copy
41
+ ```
18
42
 
19
- ## Usage
43
+ ## Example:
20
44
 
21
- TODO: Write usage instructions here
45
+ ```
46
+ $ redis-copy --fail-fast --yes old.redis.host/9 new.redis.host:6380/3
47
+ Source: redis://old.redis.host:6379/9
48
+ Destination: redis://new.redis.host:6380/3 (empty)
49
+ Key Emitter: Default
50
+ Strategy: New
51
+ PROGRESS {:success=>1000, :attempt=>1000}
52
+ PROGRESS {:success=>2000, :attempt=>2000}
53
+ PROGRESS {:success=>3000, :attempt=>3000}
54
+ PROGRESS {:success=>4000, :attempt=>4000}
55
+ DONE: {:success=>4246, :attempt=>4246}
56
+ ```
22
57
 
23
58
  ## Contributing
24
59
 
data/lib/redis-copy.rb CHANGED
@@ -15,7 +15,6 @@ module RedisCopy
15
15
  # @param destination [String]
16
16
  # @options options [Hash<Symbol,Object>]
17
17
  def copy(source, destination, options = {})
18
- puts options.inspect
19
18
  ui = UI.load(options)
20
19
 
21
20
  source = redis_from(source)
@@ -35,7 +34,7 @@ module RedisCopy
35
34
  Strategy: #{strategem}
36
35
  EODESC
37
36
 
38
- ui.abort('Destination not empty!') unless dest_empty
37
+ ui.abort('Destination not empty!') unless dest_empty or options[:allow_nonempty]
39
38
 
40
39
  key_emitter.keys.each_with_object(Hash.new {0}) do |key, stats|
41
40
  success = strategem.copy(key)
@@ -46,7 +45,7 @@ module RedisCopy
46
45
  ui.notify("FAIL: #{key.dump}")
47
46
  ui.abort if options[:fail_fast]
48
47
  end
49
- ui.notify(stats.inspect) if (stats[:attempt] % 1000).zero?
48
+ ui.notify("PROGRESS: #{stats.inspect}") if (stats[:attempt] % 1000).zero?
50
49
  end.tap do |stats|
51
50
  ui.notify("DONE: #{stats.inspect}")
52
51
  end
@@ -7,11 +7,12 @@ module RedisCopy
7
7
  class CLI
8
8
  REDIS_URI = (/\A(?:redis:\/\/)?([a-z0-9\-.]+)(:[0-9]{1,5})?(\/(?:(?:1[0-5])|[0-9]))?\z/i).freeze
9
9
  DEFAULTS = {
10
- ui: :command_line,
11
- key_emitter: :default,
12
- strategy: :auto,
13
- fail_fast: false,
14
- yes: false,
10
+ ui: :command_line,
11
+ key_emitter: :default,
12
+ strategy: :auto,
13
+ fail_fast: false,
14
+ yes: false,
15
+ allow_nonempty: false,
15
16
  }.freeze unless defined?(DEFAULTS)
16
17
 
17
18
  def initialize(argv = ARGV)
@@ -19,8 +20,9 @@ module RedisCopy
19
20
  options = {}
20
21
 
21
22
  OptionParser.new do |opts|
22
- opts.banner = "Usage: #{opts.program_name} [options] <source> <destination>"
23
23
  opts.version = RedisCopy::VERSION
24
+ opts.banner = "#{opts.program_name} v#{opts.version}\n" +
25
+ "Usage: #{opts.program_name} [options] <source> <destination>"
24
26
 
25
27
  indent_desc = proc do |desc|
26
28
  desc.split("\n").join("\n#{opts.summary_indent}#{' '*opts.summary_width} ")
@@ -62,6 +64,10 @@ module RedisCopy
62
64
  options[:yes] = true
63
65
  end
64
66
 
67
+ opts.on('--[no-]allow-nonempty', 'Allow non-empty destination') do |allow_nonempty|
68
+ options[:allow_nonempty] = allow_nonempty
69
+ end
70
+
65
71
  opts.parse!(argv)
66
72
  unless argv.size == 2
67
73
  opts.abort "Source and Destination must be specified\n\n" +
@@ -36,6 +36,25 @@ module RedisCopy
36
36
  class Default
37
37
  include KeyEmitter
38
38
 
39
+ def initialize(redis, ui, options = {})
40
+ ui.abort unless ui.confirm? <<-EOWARNING.strip_heredoc
41
+ WARNING: #{self} key emitter uses redis.keys('*') to
42
+ get its list of keys.
43
+
44
+ The redis keys command [reference](http://redis.io/commands/keys)
45
+ says this:
46
+
47
+ > Warning: consider KEYS as a command that should only be used
48
+ > in production environments with extreme care. It may ruin
49
+ > performance when it is executed against large databases.
50
+ > This command is intended for debugging and special operations,
51
+ > such as changing your keyspace layout. Don't use KEYS in your
52
+ > regular application code. If you're looking for a way to find
53
+ > keys in a subset of your keyspace, consider using sets.
54
+ EOWARNING
55
+ super
56
+ end
57
+
39
58
  def keys
40
59
  @ui.debug "REDIS: #{@redis.client.id} KEYS *"
41
60
  @redis.keys('*').to_enum
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module RedisCopy
4
- VERSION = '0.0.1'
4
+ VERSION = '0.0.2'
5
5
  end
data/redis-copy.gemspec CHANGED
@@ -16,6 +16,10 @@ Gem::Specification.new do |spec|
16
16
  spec.authors = authors_and_emails.map(&:first)
17
17
  spec.email = authors_and_emails.map(&:last)
18
18
  spec.summary = 'Copy the contents of one redis db to another'
19
+ spec.description = 'A command-line utility built for copying the ' +
20
+ 'contents of one redis db to another over a ' +
21
+ 'network. Supports all data types, persists ttls, ' +
22
+ 'and attempts to be as efficient as possible.'
19
23
  spec.homepage = 'https://github.com/yaauie/redis-copy'
20
24
  spec.license = 'MIT'
21
25
 
@@ -3,7 +3,7 @@ require 'redis-copy'
3
3
 
4
4
  describe RedisCopy::KeyEmitter::Default do
5
5
  let(:redis) { double }
6
- let(:ui) { double }
6
+ let(:ui) { double.as_null_object }
7
7
  let(:instance) { RedisCopy::KeyEmitter::Default.new(redis, ui)}
8
8
  let(:connection_uri) { 'redis://12.34.56.78:9000/15' }
9
9
 
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: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -91,7 +91,9 @@ dependencies:
91
91
  - - ! '>='
92
92
  - !ruby/object:Gem::Version
93
93
  version: '0'
94
- description:
94
+ description: A command-line utility built for copying the contents of one redis db
95
+ to another over a network. Supports all data types, persists ttls, and attempts
96
+ to be as efficient as possible.
95
97
  email:
96
98
  - ryan@yaauie.com
97
99
  executables: