class NotSupportDatabaseAdapter < RuntimeError; end
namespace :toolbox do
namespace :db do desc <<-DESC load remote databse data to local, support adapter: mysql2, postgresql DESC task :load_remote do on roles(:db) do |server| info "make sure you are not connecting to the local database" local_config_path = 'config/database.yml' remote_config_path = "#{shared_path}/config/database.yml" puts <<-MSG
default local config path: #{local_config_path} default remote config path: #{remote_config_path}
MSG ask(:enter_path, "enter your custom config path?(Y/N)") if fetch(:enter_path) == 'Y' ask(:local_config_path, 'local database config path') ask(:remote_config_path, 'remote database config path') local_config_path = fetch(:local_config_path) remote_config_path = fetch(:remote_config_path) end remote_config = remote_db_config(remote_config_path) local_config = local_db_config(local_config_path) db_filename = "db_dump" dump_file_path = "#{fetch(:deploy_to)}/#{db_filename}" local_file_path = "/tmp/#{db_filename}" info "start dumping database from remote..." no_output do execute dump_cmd(remote_config, dump_file_path) end info "downloading..." download! dump_file_path, local_file_path info "reset local database" system "bundle exec rake db:drop" system "bundle exec rake db:create" info "loading data..." system import_cmd(local_config, local_file_path) info "removing dump file..." system "rm #{local_file_path}" execute "rm #{dump_file_path}" info "done!" end end def remote_db_config(path) remote_config = no_output do capture("cat #{path}") end YAML::load(remote_config)[fetch(:stage).to_s] end def local_db_config(path) YAML::load_file(path)["development"] end def dump_cmd(config, dump_file_path) case config['adapter'] when 'postgresql' cmd = "export PGPASSWORD=#{config['password']}; pg_dump #{config['database']}" + " --username=#{config['username']} --no-owner --no-acl --format=c" cmd << " --host=#{config['host']}" unless config['host'].nil? cmd << " --port=#{config['port']}" unless config['port'].nil? cmd + " > #{dump_file_path}" when 'mysql2' cmd = "mysqldump --routines --user=#{config['username']}" + " --password=#{config['password']}" cmd << " --host=#{config['host']}" unless config['host'].nil? cmd << " --port=#{config['port']}" unless config['port'].nil? cmd + " #{config['database']} > #{dump_file_path}" else raise NotSupportDatabaseAdapter.new end end def import_cmd(config, db_file_path) case config['adapter'] when 'postgresql' cmd = "export PGPASSWORD=#{config['password']}; pg_restore #{db_file_path}" + " --no-owner --no-acl -d #{config['database']}" cmd << " --host=#{config['host']}" unless config['host'].nil? cmd << " --port=#{config['port']}" unless config['port'].nil? cmd when 'mysql2' cmd = "mysql --user=#{config['username']} --password=#{config['password']}" cmd << " --host=#{config['host']}" unless config['host'].nil? cmd << " --port=#{config['port']}" unless config['port'].nil? cmd + " #{config['database']} < #{db_file_path}" else raise NotSupportDatabaseAdapter.new end end def no_output default = SSHKit.config.output SSHKit.config.output = SSHKit::Formatter::Pretty.new(String.new) result = yield SSHKit.config.output = default result end def db_config_path_msg "enter your custom config path?(Y/N)" end end
end