redis-dump 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES.txt +6 -0
- data/README.rdoc +36 -2
- data/VERSION.yml +1 -1
- data/bin/redis-dump +76 -0
- data/bin/redis-load +74 -0
- data/lib/redis/dump.rb +35 -2
- data/try/10_redis_dump_try.rb +1 -1
- data/try/db0.json +5 -0
- metadata +9 -5
data/CHANGES.txt
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
REDIS-DUMP, CHANGES
|
2
2
|
|
3
|
+
#### 0.1.1 (2010-11-15) ###############################
|
4
|
+
|
5
|
+
* ADDED: redis-load and redis-dump executables
|
6
|
+
* ADDED: Redis::Dump.host, Redis::Dump.port
|
7
|
+
|
8
|
+
|
3
9
|
#### 0.1.0 (2010-11-15) ###############################
|
4
10
|
|
5
11
|
Initial public release.
|
data/README.rdoc
CHANGED
@@ -2,14 +2,48 @@
|
|
2
2
|
|
3
3
|
<i>Backup and restore your Redis data to and from JSON.</i>
|
4
4
|
|
5
|
-
<b>NOTE: This is alpha software. DO NOT RELY ON IT!!</b>
|
5
|
+
<b>NOTE: This is alpha software. DO NOT RELY ON IT FOR PRECIOUS THINGS!!</b>
|
6
|
+
|
7
|
+
|
8
|
+
== Usage
|
9
|
+
|
10
|
+
There are two executables: <tt>redis-dump</tt> and <tt>redis-load</tt>.
|
11
|
+
|
12
|
+
$ redis-dump
|
13
|
+
$ redis-dump -u 127.0.0.1:6371 > db_full.json
|
14
|
+
$ redis-dump -u 127.0.0.1:6371 -d 15 > db_db15.json
|
15
|
+
|
16
|
+
$ < db_full.json redis-load
|
17
|
+
$ < db_db15.json redis-load -d 15
|
18
|
+
|
19
|
+
== Output format
|
20
|
+
|
21
|
+
All redis datatypes are output to a simple JSON object. All objects have the following 5 fields:
|
22
|
+
|
23
|
+
* db (Integer)
|
24
|
+
* key (String)
|
25
|
+
* ttl (Integer): The amount of time in seconds that the key will live . If no expire is set, it's -1.
|
26
|
+
* type (String), one of: string, list, set, zset, hash, none.
|
27
|
+
* value (String): A JSON-encoded string. For keys of type list, set, zset, and hash, the data is given a specific structure (see below).
|
28
|
+
|
29
|
+
Here are examples of each datatype:
|
30
|
+
|
31
|
+
{"db":0,"key":"hashkey","ttl":-1,"type":"hash","value":{"field_a":"value_a","field_b":"value_b","field_c":"value_c"},"size":42}
|
32
|
+
{"db":0,"key":"listkey","ttl":-1,"type":"list","value":["value_0","value_1","value_2","value_0","value_1","value_2"],"size":42}
|
33
|
+
{"db":0,"key":"setkey","ttl":-1,"type":"set","value":["value_2","value_0","value_1","value_3"],"size":28}
|
34
|
+
{"db":0,"key":"zsetkey","ttl":-1,"type":"zset","value":[["value_0","100"],["value_1","100"],["value_2","200"],["value_3","300"],["value_4","400"]],"size":50}
|
35
|
+
{"db":0,"key":"stringkey","ttl":79,"type":"string","value":"stringvalue","size":11}
|
36
|
+
|
37
|
+
=== Important note about TTLs
|
38
|
+
|
39
|
+
One of the purposes of redis-dump is the ability to restore the database to a known state. When you restore a redis database from a redis-dump file, <em>expires are reset to their values at the time the dump was created</em>. This is different from restoring from Redis' native .rdb or .aof files (expires are stored relative to the actual time they were set).
|
6
40
|
|
7
41
|
|
8
42
|
== Installation
|
9
43
|
|
10
44
|
One of:
|
11
45
|
|
12
|
-
$ gem install
|
46
|
+
$ gem install redis-dump
|
13
47
|
|
14
48
|
|
15
49
|
== More Info
|
data/VERSION.yml
CHANGED
data/bin/redis-dump
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
# = Redis-Dump
|
4
|
+
#
|
5
|
+
#
|
6
|
+
# Usage:
|
7
|
+
#
|
8
|
+
# $ redis-dump -h
|
9
|
+
# $ redis-dump > dumpfile_full.json
|
10
|
+
# $ redis-dump -d 15 > dumpfile_db15.json
|
11
|
+
#
|
12
|
+
#--
|
13
|
+
|
14
|
+
RD_HOME = File.expand_path File.join(File.dirname(__FILE__), '..')
|
15
|
+
lib_dir = File.join(RD_HOME, 'lib')
|
16
|
+
$:.unshift lib_dir
|
17
|
+
|
18
|
+
require 'redis/dump'
|
19
|
+
require 'drydock'
|
20
|
+
|
21
|
+
# Command-line interface for bin/redis-dump
|
22
|
+
class Redis::Dump::CLI
|
23
|
+
extend Drydock
|
24
|
+
|
25
|
+
default :dump
|
26
|
+
trawler :dump
|
27
|
+
|
28
|
+
global :u, :uri, String, "Redis URI (e.g. redis://hostname[:port])"
|
29
|
+
global :d, :database, Integer, "Redis database (e.g. -d 15)"
|
30
|
+
global :V, :version, "Display version" do
|
31
|
+
puts "Version: #{Redis::Dump::VERSION.to_s}"
|
32
|
+
exit 0
|
33
|
+
end
|
34
|
+
global :D, :debug do
|
35
|
+
Redis::Dump.debug = true
|
36
|
+
end
|
37
|
+
global :nosafe do
|
38
|
+
Redis::Dump.safe = false
|
39
|
+
end
|
40
|
+
|
41
|
+
before do |obj|
|
42
|
+
obj.global.uri ||= 'redis://%s:%s' % [Redis::Dump.host, Redis::Dump.port]
|
43
|
+
obj.global.uri = 'redis://' << obj.global.uri unless obj.global.uri.match(/^redis:\/\//)
|
44
|
+
obj.global.database &&= obj.global.database.to_i
|
45
|
+
obj.global.database ||= (0..15)
|
46
|
+
Redis::Dump.ld " redis_uri: #{obj.global.uri} (#{obj.global.database})"
|
47
|
+
end
|
48
|
+
|
49
|
+
usage "redis-dump > dumpfile_full.json"
|
50
|
+
usage "redis-dump -d 15 > dumpfile_db15.json"
|
51
|
+
command :dump do |obj|
|
52
|
+
rd = Redis::Dump.new obj.global.database, obj.global.uri
|
53
|
+
rd.dump do |record|
|
54
|
+
puts record
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
begin
|
62
|
+
Drydock.run!(ARGV, STDIN) if Drydock.run? && !Drydock.has_run?
|
63
|
+
rescue Drydock::ArgError, Drydock::OptError => ex
|
64
|
+
STDERR.puts ex.message
|
65
|
+
STDERR.puts ex.usage
|
66
|
+
rescue Drydock::InvalidArgument => ex
|
67
|
+
STDERR.puts ex.message
|
68
|
+
rescue Drydock::UnknownCommand => ex
|
69
|
+
STDERR.puts "Unknown command: %s" % ex.name
|
70
|
+
rescue Interrupt
|
71
|
+
puts $/, "Exiting... "
|
72
|
+
exit 1
|
73
|
+
rescue => ex
|
74
|
+
STDERR.puts "ERROR (#{ex.class.to_s}): #{ex.message}"
|
75
|
+
STDERR.puts ex.backtrace if Redis::Dump.debug
|
76
|
+
end
|
data/bin/redis-load
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
# = Redis-Dump
|
4
|
+
#
|
5
|
+
#
|
6
|
+
# Usage:
|
7
|
+
#
|
8
|
+
# $ redis-load -h
|
9
|
+
# $ <dumpfile_full.json redis-load
|
10
|
+
# $ <dumpfile_db15.json redis-load -d 15
|
11
|
+
#
|
12
|
+
#--
|
13
|
+
|
14
|
+
RD_HOME = File.expand_path File.join(File.dirname(__FILE__), '..')
|
15
|
+
lib_dir = File.join(RD_HOME, 'lib')
|
16
|
+
$:.unshift lib_dir
|
17
|
+
|
18
|
+
require 'redis/dump'
|
19
|
+
require 'drydock'
|
20
|
+
|
21
|
+
# Command-line interface for bin/redis-dump
|
22
|
+
class Redis::Dump::CLI
|
23
|
+
extend Drydock
|
24
|
+
|
25
|
+
default :load
|
26
|
+
trawler :load
|
27
|
+
|
28
|
+
global :u, :uri, String, "Redis URI (e.g. redis://hostname[:port])"
|
29
|
+
global :d, :database, Integer, "Redis database (e.g. -d 15)"
|
30
|
+
global :V, :version, "Display version" do
|
31
|
+
puts "Version: #{Redis::Dump::VERSION.to_s}"
|
32
|
+
exit 0
|
33
|
+
end
|
34
|
+
global :D, :debug do
|
35
|
+
Redis::Dump.debug = true
|
36
|
+
end
|
37
|
+
global :nosafe do
|
38
|
+
Redis::Dump.safe = false
|
39
|
+
end
|
40
|
+
|
41
|
+
before do |obj|
|
42
|
+
obj.global.uri ||= 'redis://%s:%s' % [Redis::Dump.host, Redis::Dump.port]
|
43
|
+
obj.global.uri = 'redis://' << obj.global.uri unless obj.global.uri.match(/^redis:\/\//)
|
44
|
+
obj.global.database &&= obj.global.database.to_i
|
45
|
+
obj.global.database ||= (0..15)
|
46
|
+
Redis::Dump.ld " redis_uri: #{obj.global.uri} (#{obj.global.database})"
|
47
|
+
end
|
48
|
+
|
49
|
+
usage "<dumpfile_full.json redis-load"
|
50
|
+
usage "<dumpfile_db15.json redis-load -d 15"
|
51
|
+
command :load do |obj|
|
52
|
+
rd = Redis::Dump.new obj.global.database, obj.global.uri
|
53
|
+
rd.load STDIN
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
begin
|
60
|
+
Drydock.run!(ARGV, STDIN) if Drydock.run? && !Drydock.has_run?
|
61
|
+
rescue Drydock::ArgError, Drydock::OptError => ex
|
62
|
+
STDERR.puts ex.message
|
63
|
+
STDERR.puts ex.usage
|
64
|
+
rescue Drydock::InvalidArgument => ex
|
65
|
+
STDERR.puts ex.message
|
66
|
+
rescue Drydock::UnknownCommand => ex
|
67
|
+
STDERR.puts "Unknown command: %s" % ex.name
|
68
|
+
rescue Interrupt
|
69
|
+
puts $/, "Exiting... "
|
70
|
+
exit 1
|
71
|
+
rescue => ex
|
72
|
+
STDERR.puts "ERROR (#{ex.class.to_s}): #{ex.message}"
|
73
|
+
STDERR.puts ex.backtrace if Redis::Dump.debug
|
74
|
+
end
|
data/lib/redis/dump.rb
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
unless defined?(RD_HOME)
|
2
|
+
RD_HOME = File.expand_path(File.join(File.dirname(__FILE__), '..', '..') )
|
3
|
+
end
|
4
|
+
|
1
5
|
require 'redis'
|
2
6
|
require 'yajl'
|
3
7
|
|
@@ -6,19 +10,21 @@ class Redis
|
|
6
10
|
unless defined?(Redis::Dump::VALID_TYPES)
|
7
11
|
VALID_TYPES = ['string', 'set', 'list', 'zset', 'hash', 'none'].freeze
|
8
12
|
end
|
13
|
+
@host = '127.0.0.1'
|
14
|
+
@port = 6379
|
9
15
|
@debug = false
|
10
16
|
@encoder = Yajl::Encoder.new
|
11
17
|
@parser = Yajl::Parser.new
|
12
18
|
@safe = true
|
13
19
|
class << self
|
14
|
-
attr_accessor :debug, :encoder, :parser, :safe
|
20
|
+
attr_accessor :debug, :encoder, :parser, :safe, :host, :port
|
15
21
|
def ld(msg)
|
16
22
|
STDERR.puts "#{'%.4f' % Time.now.utc.to_f}: #{msg}" if @debug
|
17
23
|
end
|
18
24
|
end
|
19
25
|
attr_accessor :dbs, :uri
|
20
26
|
attr_reader :redis_connections
|
21
|
-
def initialize(dbs=nil,uri="redis
|
27
|
+
def initialize(dbs=nil,uri="redis://#{Redis::Dump.host}:#{Redis::Dump.port}")
|
22
28
|
@redis_connections = {}
|
23
29
|
@uri = uri
|
24
30
|
unless dbs.nil?
|
@@ -157,6 +163,33 @@ class Redis
|
|
157
163
|
def stringify_none (this_redis, key, v=nil) (v || '') end
|
158
164
|
end
|
159
165
|
extend Redis::Dump::ClassMethods
|
166
|
+
|
167
|
+
module VERSION
|
168
|
+
def self.stamp
|
169
|
+
@info[:STAMP].to_i
|
170
|
+
end
|
171
|
+
def self.owner
|
172
|
+
@info[:OWNER]
|
173
|
+
end
|
174
|
+
def self.to_s
|
175
|
+
[@info[:MAJOR], @info[:MINOR], @info[:PATCH], @info[:BUILD]].join('.')
|
176
|
+
end
|
177
|
+
def self.path
|
178
|
+
File.join(RD_HOME, 'VERSION.yml')
|
179
|
+
end
|
180
|
+
def self.load_config
|
181
|
+
require 'yaml'
|
182
|
+
@info ||= YAML.load_file(path)
|
183
|
+
end
|
184
|
+
load_config
|
185
|
+
end
|
186
|
+
|
187
|
+
class Problem < RuntimeError
|
188
|
+
def initialize(*args)
|
189
|
+
@args = args.flatten.compact
|
190
|
+
end
|
191
|
+
def message() @args && @args.first end
|
192
|
+
end
|
160
193
|
end
|
161
194
|
end
|
162
195
|
|
data/try/10_redis_dump_try.rb
CHANGED
data/try/db0.json
ADDED
@@ -0,0 +1,5 @@
|
|
1
|
+
{"db":0,"key":"hashkey","ttl":-1,"type":"hash","value":{"field_a":"value_a","field_b":"value_b","field_c":"value_c"},"size":42}
|
2
|
+
{"db":0,"key":"listkey","ttl":-1,"type":"list","value":["value_0","value_1","value_2","value_0","value_1","value_2"],"size":42}
|
3
|
+
{"db":0,"key":"setkey","ttl":-1,"type":"set","value":["value_2","value_0","value_1","value_3"],"size":28}
|
4
|
+
{"db":0,"key":"zsetkey","ttl":-1,"type":"zset","value":[["value_0","100"],["value_1","100"],["value_2","200"],["value_3","300"],["value_4","400"]],"size":50}
|
5
|
+
{"db":0,"key":"stringkey","ttl":79,"type":"string","value":"stringvalue","size":11}
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: redis-dump
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 25
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
9
|
+
- 1
|
10
|
+
version: 0.1.1
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Delano Mandelbaum
|
@@ -50,8 +50,9 @@ dependencies:
|
|
50
50
|
version_requirements: *id002
|
51
51
|
description: Backup and restore your Redis data to and from JSON.
|
52
52
|
email: delano@solutious.com
|
53
|
-
executables:
|
54
|
-
|
53
|
+
executables:
|
54
|
+
- redis-dump
|
55
|
+
- redis-load
|
55
56
|
extensions: []
|
56
57
|
|
57
58
|
extra_rdoc_files:
|
@@ -63,8 +64,11 @@ files:
|
|
63
64
|
- README.rdoc
|
64
65
|
- Rakefile
|
65
66
|
- VERSION.yml
|
67
|
+
- bin/redis-dump
|
68
|
+
- bin/redis-load
|
66
69
|
- lib/redis/dump.rb
|
67
70
|
- try/10_redis_dump_try.rb
|
71
|
+
- try/db0.json
|
68
72
|
- try/redis-server.conf
|
69
73
|
has_rdoc: true
|
70
74
|
homepage: http://github.com/delano/redis-dump
|