namespace :mysqldump do
task :default do on roles(:db) do dump import end end def setup_variables @mysqldump_config = fetch :mysqldump_config, YAML.load_file("config/database.yml")[fetch(:rails_env).to_s] unless @mysqldump_config raise "Cannot load database config for #{fetch(:rails_env)} environment" end host = @mysqldump_config["host"] # overwrite these if necessary @mysqldump_bin = fetch :mysqldump_bin, "`which mysqldump`" mysqldump_remote_tmp_dir = fetch :mysqldump_remote_tmp_dir, "/tmp" mysqldump_local_tmp_dir = fetch :mysqldump_local_tmp_dir, "/tmp" @mysqldump_location = fetch :mysqldump_location, host && !host.empty? && host != "localhost" ? :remote : :local @mysqldump_options = fetch :mysqldump_options, {} # for convenience mysqldump_filename = "%s-%s.sql" % [fetch(:application), Time.now.to_i] mysqldump_filename_gz = "%s.gz" % mysqldump_filename @mysqldump_remote_filename = File.join( mysqldump_remote_tmp_dir, mysqldump_filename_gz ) @mysqldump_local_filename = File.join( mysqldump_local_tmp_dir, mysqldump_filename ) @mysqldump_local_filename_gz = File.join( mysqldump_local_tmp_dir, mysqldump_filename_gz ) @mysqldump_ignore_tables = fetch :mysqldump_ignore_tables, [] @mysqldump_tables = fetch :mysqldump_tables, [] end def default_options setup_variables username, password, host = @mysqldump_config.values_at *%w( username password host ) { :h => host, :quick => true, "single-transaction" => true, }.tap do |options| password = true if @mysqldump_location == :remote if @mysqldump_ignore_tables.any? options['ignore-tables'] = [@mysqldump_ignore_tables].flatten.join ' ' end options.merge! mysqldump_credential_options(username, password) end end task :dump do options = default_options options.merge! @mysqldump_options password, database = @mysqldump_config.values_at *%w( password database ) mysqldump_cmd = "#{@mysqldump_bin} #{mysqldump_options_string(options)} #{database} #{[@mysqldump_tables].flatten.compact.join ' '}" case @mysqldump_location when :remote # TODO: use `set` instead of binding to local variables remote_filename = @mysqldump_remote_filename local_filename_gz = @mysqldump_local_filename_gz mysqldump_cmd += " | gzip > %s" % @mysqldump_remote_filename on roles(:db) do execute( mysqldump_cmd, interaction_handler: { /^Enter password:/ => "#{password}\n" }) download! remote_filename, local_filename_gz execute "rm #{remote_filename}" end `gunzip #{@mysqldump_local_filename_gz}` when :local mysqldump_cmd += " > %s" % @mysqldump_local_filename `#{mysqldump_cmd}` end end task :import do config = YAML.load_file("config/database.yml")["development"] username, password, database = config.values_at *%w( username password database ) credentials_string = mysqldump_options_string mysqldump_credential_options(username, password) mysql_cmd = "mysql #{credentials_string}" `#{mysql_cmd} -e "drop database #{database}; create database #{database}"` `#{mysql_cmd} #{database} < #{@mysqldump_local_filename}` `rm #{@mysqldump_local_filename}` end
end