db_rocket 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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
+
@@ -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
+
@@ -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
+
@@ -0,0 +1,2 @@
1
+ require "db_rockets/db_rocket"
2
+
@@ -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
+
@@ -0,0 +1,8 @@
1
+ module DBRocket; end
2
+
3
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
4
+ $LOAD_PATH.unshift(File.dirname(__FILE__) + '/commands')
5
+
6
+ require "command"
7
+ require "base"
8
+
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
+