db_rocket 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/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
+