db_rocket 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +21 -0
- data/README.rdoc +36 -0
- data/bin/db_rocket +17 -0
- data/lib/db_rocket.rb +2 -0
- data/lib/db_rockets/cli/command.rb +50 -0
- data/lib/db_rockets/cli/commands/app.rb +36 -0
- data/lib/db_rockets/cli/commands/base.rb +226 -0
- data/lib/db_rockets/cli/commands/help.rb +31 -0
- data/lib/db_rockets/cli/commands/server.rb +64 -0
- data/lib/db_rockets/cli/init.rb +8 -0
- metadata +71 -0
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
Copyright (c) 2010 Mauro Torres
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
|
+
|
data/README.rdoc
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
== DB ROCKET
|
2
|
+
|
3
|
+
A simple database agnostic import/export app to transfer data to/from a remote database from Ruby on Rails APP based on TAPS.
|
4
|
+
|
5
|
+
== Usage: Server
|
6
|
+
|
7
|
+
The first thing that you need is create yaml configuration for add the data for access to the server, so into your app rails run:
|
8
|
+
|
9
|
+
#db_rocket create
|
10
|
+
|
11
|
+
this going to create yaml called config/db_rocket.yml. Fill this file and run
|
12
|
+
|
13
|
+
#db_rocket server:start
|
14
|
+
|
15
|
+
and this is all
|
16
|
+
|
17
|
+
== Usage: Client
|
18
|
+
|
19
|
+
for push your db to the server you can do:
|
20
|
+
|
21
|
+
#db_rocket push
|
22
|
+
|
23
|
+
or for get the db from your server you can do:
|
24
|
+
|
25
|
+
#db_rocket pull
|
26
|
+
|
27
|
+
== Options
|
28
|
+
|
29
|
+
--environment production - by default db_rocket get from RAILS_ENV
|
30
|
+
--tables logs,tags - specify the tables
|
31
|
+
--filter '^log_'
|
32
|
+
|
33
|
+
=== Copyright
|
34
|
+
|
35
|
+
Copyright (c) 2010 Mauro Torres. See LICENSE for details.
|
36
|
+
|
data/bin/db_rocket
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__) + '/../lib/db_rockets/cli/')
|
4
|
+
|
5
|
+
require 'rubygems'
|
6
|
+
require 'init'
|
7
|
+
|
8
|
+
args = ARGV.dup
|
9
|
+
ARGV.clear
|
10
|
+
command = args.shift.strip rescue 'help'
|
11
|
+
|
12
|
+
if File.exists?('config/environment.rb')
|
13
|
+
DBRocket::Command.run(command, args)
|
14
|
+
else
|
15
|
+
puts "app rails not found!, you need stay inside on the root of one rails app"
|
16
|
+
end
|
17
|
+
|
data/lib/db_rocket.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
module DBRocket
|
2
|
+
module Command
|
3
|
+
class InvalidCommand < RuntimeError; end
|
4
|
+
class CommandFailed < RuntimeError; end
|
5
|
+
|
6
|
+
class << self
|
7
|
+
def run(command, args)
|
8
|
+
run_internal(command, args)
|
9
|
+
rescue InvalidCommand
|
10
|
+
display "Unknown command. Run 'db_rocket help' for usage information."
|
11
|
+
end
|
12
|
+
|
13
|
+
def run_internal(command, args)
|
14
|
+
namespace, command = parse(command)
|
15
|
+
require "#{namespace}"
|
16
|
+
klass = DBRocket::Command.const_get(namespace.capitalize).new(args)
|
17
|
+
raise InvalidCommand unless klass.respond_to?(command)
|
18
|
+
klass.send(command)
|
19
|
+
end
|
20
|
+
|
21
|
+
def display(msg)
|
22
|
+
puts(msg)
|
23
|
+
end
|
24
|
+
|
25
|
+
def parse(command)
|
26
|
+
parts = command.split(':')
|
27
|
+
case parts.size
|
28
|
+
when 1
|
29
|
+
if namespaces.include? command
|
30
|
+
return command, 'index'
|
31
|
+
else
|
32
|
+
return 'app', command
|
33
|
+
end
|
34
|
+
when 2
|
35
|
+
raise InvalidCommand unless namespaces.include? parts[0]
|
36
|
+
return parts
|
37
|
+
else
|
38
|
+
raise InvalidCommand
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def namespaces
|
43
|
+
@@namespaces ||= Dir["#{File.dirname(__FILE__)}/commands/*"].map do |namespace|
|
44
|
+
namespace.gsub(/.*\//, '').gsub(/\.rb/, '')
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'logger'
|
3
|
+
|
4
|
+
module DBRocket::Command
|
5
|
+
class App < Base
|
6
|
+
def create
|
7
|
+
name = args.shift.downcase.strip rescue nil
|
8
|
+
if make_config_file == "y"
|
9
|
+
display "You can configurate db_rocket on config/db_rocket.yml"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def push
|
14
|
+
load_taps
|
15
|
+
opts = parse_taps_opts
|
16
|
+
|
17
|
+
display("Warning: Data in the app will be overwritten and will not be recoverable.")
|
18
|
+
|
19
|
+
if extract_option("--force") || confirm
|
20
|
+
taps_client(:push, opts)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def pull
|
25
|
+
load_taps
|
26
|
+
opts = parse_taps_opts
|
27
|
+
|
28
|
+
display("Warning: Data in the database '#{opts[:database_url]}' will be overwritten and will not be recoverable.")
|
29
|
+
|
30
|
+
if extract_option("--force") || confirm
|
31
|
+
taps_client(:pull, opts)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
@@ -0,0 +1,226 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
module DBRocket::Command
|
4
|
+
class Base
|
5
|
+
attr_accessor :args
|
6
|
+
def initialize(args)
|
7
|
+
@args = args
|
8
|
+
end
|
9
|
+
|
10
|
+
def extract_option(options, default=true)
|
11
|
+
values = options.is_a?(Array) ? options : [options]
|
12
|
+
return unless opt_index = args.select { |a| values.include? a }.first
|
13
|
+
opt_position = args.index(opt_index) + 1
|
14
|
+
if args.size > opt_position && opt_value = args[opt_position]
|
15
|
+
if opt_value.include?('--')
|
16
|
+
opt_value = nil
|
17
|
+
else
|
18
|
+
args.delete_at(opt_position)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
opt_value ||= default
|
22
|
+
args.delete(opt_index)
|
23
|
+
block_given? ? yield(opt_value) : opt_value
|
24
|
+
end
|
25
|
+
|
26
|
+
def display(msg, newline=true)
|
27
|
+
if newline
|
28
|
+
puts(msg)
|
29
|
+
else
|
30
|
+
print(msg)
|
31
|
+
STDOUT.flush
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def confirm(message="Are you sure you wish to continue? (y/n)?")
|
36
|
+
display("#{message} ", false)
|
37
|
+
ask.downcase == 'y'
|
38
|
+
end
|
39
|
+
|
40
|
+
def error(msg)
|
41
|
+
STDERR.puts(msg)
|
42
|
+
exit 1
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
def ask
|
47
|
+
gets.strip
|
48
|
+
end
|
49
|
+
|
50
|
+
def shell(cmd)
|
51
|
+
`#{cmd}`
|
52
|
+
end
|
53
|
+
|
54
|
+
def home_directory
|
55
|
+
running_on_windows? ? ENV['USERPROFILE'] : ENV['HOME']
|
56
|
+
end
|
57
|
+
|
58
|
+
def running_on_windows?
|
59
|
+
RUBY_PLATFORM =~ /mswin32/
|
60
|
+
end
|
61
|
+
|
62
|
+
def config_file
|
63
|
+
'config/db_rocket.yml'
|
64
|
+
end
|
65
|
+
|
66
|
+
def ask_for_config_file
|
67
|
+
if File.exists?(config_file)
|
68
|
+
print "The file config/db_rocket.yml exists, do you want overwrite this? (y/n): "
|
69
|
+
ask
|
70
|
+
else
|
71
|
+
"y"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def parse_database_yml(environment = nil)
|
76
|
+
return "" unless File.exists?(Dir.pwd + '/config/database.yml')
|
77
|
+
|
78
|
+
environment = ENV['RAILS_ENV'] || ENV['MERB_ENV'] || ENV['RACK_ENV'] if environment.nil?
|
79
|
+
environment = 'development' if environment.nil? or environment.empty?
|
80
|
+
|
81
|
+
conf = YAML.load(File.read(Dir.pwd + '/config/database.yml'))[environment]
|
82
|
+
case conf['adapter']
|
83
|
+
when 'sqlite3'
|
84
|
+
return "sqlite://#{conf['database']}"
|
85
|
+
when 'postgresql'
|
86
|
+
uri_hash = conf_to_uri_hash(conf)
|
87
|
+
uri_hash['scheme'] = 'postgres'
|
88
|
+
return uri_hash_to_url(uri_hash)
|
89
|
+
else
|
90
|
+
return uri_hash_to_url(conf_to_uri_hash(conf))
|
91
|
+
end
|
92
|
+
rescue Exception => ex
|
93
|
+
puts "Error parsing database.yml: #{ex.message}"
|
94
|
+
puts ex.backtrace
|
95
|
+
""
|
96
|
+
end
|
97
|
+
|
98
|
+
def conf_to_uri_hash(conf)
|
99
|
+
uri = {}
|
100
|
+
uri['scheme'] = conf['adapter']
|
101
|
+
uri['username'] = conf['user'] || conf['username']
|
102
|
+
uri['password'] = conf['password']
|
103
|
+
uri['host'] = conf['host'] || conf['hostname']
|
104
|
+
uri['port'] = conf['port']
|
105
|
+
uri['path'] = conf['database']
|
106
|
+
|
107
|
+
conf['encoding'] = 'utf8' if conf['encoding'] == 'unicode' or conf['encoding'].nil?
|
108
|
+
uri['query'] = "encoding=#{conf['encoding']}"
|
109
|
+
|
110
|
+
uri
|
111
|
+
end
|
112
|
+
|
113
|
+
def userinfo_from_uri(uri)
|
114
|
+
username = uri['username'].to_s
|
115
|
+
password = uri['password'].to_s
|
116
|
+
return nil if username == ''
|
117
|
+
|
118
|
+
userinfo = ""
|
119
|
+
userinfo << username
|
120
|
+
userinfo << ":" << password if password.length > 0
|
121
|
+
userinfo
|
122
|
+
end
|
123
|
+
|
124
|
+
def uri_hash_to_url(uri)
|
125
|
+
uri_parts = {
|
126
|
+
:scheme => uri['scheme'],
|
127
|
+
:userinfo => userinfo_from_uri(uri),
|
128
|
+
:password => uri['password'],
|
129
|
+
:host => uri['host'] || '127.0.0.1',
|
130
|
+
:port => uri['port'],
|
131
|
+
:path => "/%s" % uri['path'],
|
132
|
+
:query => uri['query'],
|
133
|
+
}
|
134
|
+
|
135
|
+
URI::Generic.build(uri_parts).to_s
|
136
|
+
end
|
137
|
+
|
138
|
+
def parse_taps_opts
|
139
|
+
opts = {}
|
140
|
+
opts[:default_chunksize] = extract_option("--chunksize") || 1000
|
141
|
+
opts[:default_chunksize] = opts[:default_chunksize].to_i rescue 1000
|
142
|
+
opts[:environment] = extract_option("--environment") || ENV['RAILS_ENV'] || ENV['MERB_ENV'] || ENV['RACK_ENV'] || 'development'
|
143
|
+
|
144
|
+
if filter = extract_option("--filter")
|
145
|
+
opts[:table_filter] = filter
|
146
|
+
elsif tables = extract_option("--tables")
|
147
|
+
r_tables = tables.split(",").collect { |t| "^#{t.strip}$" }
|
148
|
+
opts[:table_filter] = "(#{r_tables.join("|")})"
|
149
|
+
end
|
150
|
+
|
151
|
+
if extract_option("--disable-compression")
|
152
|
+
opts[:disable_compression] = true
|
153
|
+
end
|
154
|
+
|
155
|
+
if resume_file = extract_option("--resume-filename")
|
156
|
+
opts[:resume_filename] = resume_file
|
157
|
+
end
|
158
|
+
|
159
|
+
opts[:indexes_first] = !extract_option("--indexes-last")
|
160
|
+
|
161
|
+
opts[:database_url] = args.shift.strip rescue ''
|
162
|
+
if opts[:database_url] == ''
|
163
|
+
opts[:database_url] = parse_database_yml(opts[:environment])
|
164
|
+
display "Auto-detected local database: #{opts[:database_url]}" if opts[:database_url] != ''
|
165
|
+
end
|
166
|
+
raise(CommandFailed, "Invalid database url") if opts[:database_url] == ''
|
167
|
+
|
168
|
+
if extract_option("--debug")
|
169
|
+
Taps.log.level = Logger::DEBUG
|
170
|
+
end
|
171
|
+
|
172
|
+
#ENV['TZ'] = 'America/Los_Angeles'
|
173
|
+
opts
|
174
|
+
end
|
175
|
+
|
176
|
+
def taps_client(op, opts)
|
177
|
+
Taps::Config.verify_database_url(opts[:database_url])
|
178
|
+
if opts[:resume_filename]
|
179
|
+
Taps::Cli.new([]).clientresumexfer(op, opts)
|
180
|
+
else
|
181
|
+
opts[:remote_url] = make_url_from_config(opts[:environment])
|
182
|
+
Taps::Cli.new([]).clientxfer(op, opts)
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
def make_url_from_config environment
|
187
|
+
conf = YAML.load(File.read(Dir.pwd + "/#{config_file}"))[environment]
|
188
|
+
"http://#{conf['http_user']}:#{conf['http_password']}@#{conf['server']}:#{conf['port']}"
|
189
|
+
end
|
190
|
+
|
191
|
+
def load_taps
|
192
|
+
require 'taps/operation'
|
193
|
+
require 'taps/cli'
|
194
|
+
error "The db rocket gem requires taps 0.3" unless Taps.version =~ /^0.3/
|
195
|
+
display "Loaded Taps v#{Taps.version}"
|
196
|
+
rescue LoadError
|
197
|
+
message = "Taps 0.3 Load Error: #{$!.message}\n"
|
198
|
+
message << "You may need to install or update the taps gem to use db commands.\n"
|
199
|
+
message << "On most systems this will be:\n\nsudo gem install taps"
|
200
|
+
error message
|
201
|
+
end
|
202
|
+
|
203
|
+
|
204
|
+
def make_config_file
|
205
|
+
overwrite_or_create_file = ask_for_config_file
|
206
|
+
if overwrite_or_create_file == "y"
|
207
|
+
config_file_hash = <<EOFILE
|
208
|
+
common: &common
|
209
|
+
server: 127.0.0.1
|
210
|
+
port: 5555
|
211
|
+
http_user: user
|
212
|
+
http_password: password
|
213
|
+
development:
|
214
|
+
<<: *common
|
215
|
+
production:
|
216
|
+
<<: *common
|
217
|
+
EOFILE
|
218
|
+
File.open(config_file, 'w') do |f|
|
219
|
+
f.puts config_file_hash
|
220
|
+
end
|
221
|
+
end
|
222
|
+
overwrite_or_create_file
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module DBRocket::Command
|
2
|
+
class Help < Base
|
3
|
+
def index
|
4
|
+
display usage
|
5
|
+
end
|
6
|
+
|
7
|
+
def usage
|
8
|
+
usage = <<EOTXT
|
9
|
+
=== General Commands
|
10
|
+
|
11
|
+
help # show this usage
|
12
|
+
create # create config file for your app
|
13
|
+
push
|
14
|
+
pull
|
15
|
+
|
16
|
+
=== Server
|
17
|
+
|
18
|
+
server:start #run db_rocket server
|
19
|
+
server:stop #stop db_rocket server
|
20
|
+
|
21
|
+
=== Example story:
|
22
|
+
|
23
|
+
rails myapp
|
24
|
+
cd myapp
|
25
|
+
(...make edits...)
|
26
|
+
db_rocket create
|
27
|
+
EOTXT
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'logger'
|
3
|
+
|
4
|
+
module DBRocket::Command
|
5
|
+
class Server < Base
|
6
|
+
def start
|
7
|
+
if File.exists?(pid_file)
|
8
|
+
puts "db_rocket server is running...."
|
9
|
+
else
|
10
|
+
load_taps
|
11
|
+
opts = parse_server_taps_opts
|
12
|
+
Taps.log.level = Logger::DEBUG if opts[:debug]
|
13
|
+
Taps::Config.database_url = opts[:database_url]
|
14
|
+
Taps::Config.login = opts[:login]
|
15
|
+
Taps::Config.password = opts[:password]
|
16
|
+
|
17
|
+
Taps::Config.verify_database_url
|
18
|
+
require 'taps/server'
|
19
|
+
pid = fork do
|
20
|
+
Taps::Server.run!({
|
21
|
+
:port => opts[:port],
|
22
|
+
:environment => :production,
|
23
|
+
:logging => true,
|
24
|
+
:dump_errors => true,
|
25
|
+
})
|
26
|
+
end
|
27
|
+
File.open(pid_file, 'w') {|f| f.write(pid) }
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def stop
|
32
|
+
if File.exists?(pid_file)
|
33
|
+
process_id = File.open(pid_file,'r').readline
|
34
|
+
Process.kill 9, process_id.to_i
|
35
|
+
FileUtils.rm(pid_file)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def pid_file
|
40
|
+
'/tmp/db_rockets.pid'
|
41
|
+
end
|
42
|
+
|
43
|
+
def parse_server_taps_opts
|
44
|
+
opts = {}
|
45
|
+
opts[:environment] = extract_option("--environment") || ENV['RAILS_ENV'] || ENV['MERB_ENV'] || ENV['RACK_ENV'] || 'development'
|
46
|
+
opts[:database_url] = args.shift.strip rescue ''
|
47
|
+
if opts[:database_url] == ''
|
48
|
+
opts[:database_url] = parse_database_yml(opts[:environment])
|
49
|
+
display "Auto-detected local database: #{opts[:database_url]}" if opts[:database_url] != ''
|
50
|
+
end
|
51
|
+
raise(CommandFailed, "Invalid database url") if opts[:database_url] == ''
|
52
|
+
|
53
|
+
if extract_option("--debug")
|
54
|
+
opts[:debug] = true
|
55
|
+
end
|
56
|
+
conf = YAML.load(File.read(Dir.pwd + "/#{config_file}"))[opts[:environment]]
|
57
|
+
opts[:login] = conf['http_user']
|
58
|
+
opts[:password] = conf['http_password']
|
59
|
+
opts[:port] = conf['port']
|
60
|
+
opts
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
metadata
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: db_rocket
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 2
|
9
|
+
version: 0.0.2
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Mauro Torres
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-10-09 00:00:00 -03:00
|
18
|
+
default_executable: db_rocket
|
19
|
+
dependencies: []
|
20
|
+
|
21
|
+
description: Db Rocketa allows make your dump db very easy!
|
22
|
+
email: maurotorres@gmail.com
|
23
|
+
executables:
|
24
|
+
- db_rocket
|
25
|
+
extensions: []
|
26
|
+
|
27
|
+
extra_rdoc_files:
|
28
|
+
- LICENSE
|
29
|
+
- README.rdoc
|
30
|
+
files:
|
31
|
+
- lib/db_rocket.rb
|
32
|
+
- lib/db_rockets/cli/command.rb
|
33
|
+
- lib/db_rockets/cli/commands/app.rb
|
34
|
+
- lib/db_rockets/cli/commands/base.rb
|
35
|
+
- lib/db_rockets/cli/commands/help.rb
|
36
|
+
- lib/db_rockets/cli/commands/server.rb
|
37
|
+
- lib/db_rockets/cli/init.rb
|
38
|
+
- LICENSE
|
39
|
+
- README.rdoc
|
40
|
+
has_rdoc: true
|
41
|
+
homepage: http://github.com/chebyte/db_rocket
|
42
|
+
licenses: []
|
43
|
+
|
44
|
+
post_install_message:
|
45
|
+
rdoc_options:
|
46
|
+
- --charset=UTF-8
|
47
|
+
require_paths:
|
48
|
+
- lib
|
49
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
segments:
|
54
|
+
- 0
|
55
|
+
version: "0"
|
56
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
segments:
|
61
|
+
- 0
|
62
|
+
version: "0"
|
63
|
+
requirements: []
|
64
|
+
|
65
|
+
rubyforge_project:
|
66
|
+
rubygems_version: 1.3.6
|
67
|
+
signing_key:
|
68
|
+
specification_version: 3
|
69
|
+
summary: make your dump db very easy!
|
70
|
+
test_files: []
|
71
|
+
|