class Dumpr::Driver::Base
abstract interface for all drivers
Attributes
database[R]
destination[R]
destination_dumpfile[R]
destination_host[R]
dump_options[R]
dumpdir[R]
dumpfile[R]
gzip[R]
gzip_options[R]
host[R]
import_options[R]
opts[R]
password[R]
port[R]
tables[R]
user[R]
Public Class Methods
new(opts)
click to toggle source
# File lib/dumpr/driver.rb, line 37 def initialize(opts) self.configure(opts) end
Public Instance Methods
configure(opts)
click to toggle source
# File lib/dumpr/driver.rb, line 41 def configure(opts) opts = (@opts||{}).merge(opts) # db connection settings @host = opts[:host] || "localhost" @port = opts[:port] @user = opts[:user] or raise BadConfig.new "user is required" @password = (opts[:password] || opts[:pass]) # or raise BadConfig.new "password is required" # dump all_databases or specific database(s) @all_databases = nil @database = nil @databases = nil @tables = nil if (opts[:database] || opts[:db]) @database = (opts[:database] || opts[:db]) @tables = [opts[:table], opts[:tables]].flatten.uniq.compact elsif opts[:databases] @databases = [opts[:databases]].flatten.uniq.compact # not used/supported yet elsif opts[:all_databases] @all_databases = true else #raise BadConfig.new "database is required" end # dump settings @gzip = opts[:gzip].nil? ? true : opts[:gzip] @gzip_options = opts[:gzip_options] || "-9" @dumpdir = opts[:dumpdir] || Dir.pwd #"./" @dumpfile = (opts[:file] || opts[:dumpfile] || opts[:filename]) or raise BadConfig.new "[file] is required" @dumpfile = @dumpfile.to_s.dup # this is frozen? @dumpfile = @dumpfile[0].chr == "/" ? @dumpfile : File.join(@dumpdir, @dumpfile) @dumpfile.chomp!(".gz") # (optional) :destination is where dumps are exported to, and can be a remote host:path @destination = opts[:destination] || @dumpfile if @destination.include?(":") @destination_host, @destination_dumpfile = @destination.split(":")[0], @destination.split(":")[1] else @destination_host, @destination_dumpfile = "localhost", @destination end # destination might be a path only, so build the entire filepath if File.extname(@destination_dumpfile) == "" @destination_dumpfile = File.join(@destination_dumpfile, File.basename(@dumpfile)) end @destination_dumpfile.chomp!(".gz") @dump_options = opts[:dump_options] @import_options = opts[:import_options] # set / update logger if opts[:logger] @logger = opts[:logger] elsif opts[:log_file] @logger = Logger.new(opts[:log_file]) end @logger = Logger.new(STDOUT) if !@logger @logger.level = opts[:log_level] if opts[:log_level] # expects integer @opts = opts end
decompress()
click to toggle source
# File lib/dumpr/driver.rb, line 185 def decompress if File.exists?(@dumpfile + ".gz") if File.exists?(@dumpfile) && !@opts[:force] logger.warn "skipping decompress because #{@dumpfile} already exists." else logger.debug "decompressing..." run "gzip -d -f #{@dumpfile}.gz" end else logger.warn "decompress failed. #{@dumpfile}.gz does not exist!" end end
dump()
click to toggle source
creates @dumpfile pipes :dump_cmd to gzip, rather than write the file to disk twice if @destination is defined, it then moves the dump to the @destination, which can be a remote host:path
# File lib/dumpr/driver.rb, line 125 def dump logger.debug("begin dump") if dump_installed? != true raise MissingDriver.new "#{self.class} does not appear to be installed.\nCould not find command `#{dump_cmd.to_s.split.first}`" end dumpfn = @dumpfile + (@gzip ? ".gz" : "") Util.with_lockfile("localhost", dumpfn, @opts[:force]) do logger.debug "preparing dump..." if !File.exists?(File.dirname(dumpfn)) run "mkdir -p #{File.dirname(dumpfn)}" end # avoid overwriting dump files.. if File.exists?(dumpfn) if @opts[:force] logger.warn "#{dumpfn} exists, moving it to #{dumpfn}.1" #run "rm -f #{dumpfn}.1;" run "mv #{dumpfn} #{dumpfn}.1" else logger.warn "#{dumpfn} already exists!" raise DumpFileExists.new "#{dumpfn} already exists!" end end logger.debug "dumping..." if @gzip run "#{dump_cmd} | gzip #{gzip_options} > #{dumpfn}" else run "#{dump_cmd} > #{dumpfn}" end dumpsize = Util.human_file_size("localhost", dumpfn) logger.info("generated #{dumpfn} (#{dumpsize})") if @destination if remote_destination? logger.debug "exporting to #{@destination_host}..." Util.with_lockfile(@destination_host, @destination_dumpfile, @opts[:force]) do run "scp #{dumpfn} #{@destination_host}:#{@destination_dumpfile}#{@gzip ? '.gz' : ''}" end elsif @destination_dumpfile && @destination_dumpfile+(@gzip ? '.gz' : '') != dumpfn logger.debug "exporting..." destdir = File.dirname(@destination_dumpfile) run "mkdir -p #{destdir}" if !Util.dir_exists?("localhost", destdir) Util.with_lockfile("localhost", @destination_dumpfile, @opts[:force]) do run "mv #{dumpfn} #{@destination_dumpfile}#{@gzip ? '.gz' : ''}" end end end end # with_lockfile logger.debug("end dump") end
dump_cmd()
click to toggle source
# File lib/dumpr/driver.rb, line 112 def dump_cmd raise BadConfig.new "#{self.class} has not defined dump_cmd" end
dump_installed?()
click to toggle source
# File lib/dumpr/driver.rb, line 104 def dump_installed? raise BadConfig.new "#{self.class} has not defined dump_installed?" end
import()
click to toggle source
# File lib/dumpr/driver.rb, line 198 def import if import_installed? != true raise MissingDriver.new "#{self.class} does not appear to be installed.\nCould not find command `#{import_cmd.to_s.split.first}`" end Util.with_lockfile("localhost", @dumpfile, @opts[:force]) do decompress if @gzip if !File.exists?(@dumpfile) raise "Cannot import #{@dumpfile} because it does not exist!" else dumpsize = Util.human_file_size("localhost", @dumpfile) logger.info("importing #{@dumpfile} (#{dumpsize})") run import_cmd end end # with_lockfile end
import_cmd()
click to toggle source
IMPORTING
# File lib/dumpr/driver.rb, line 181 def import_cmd raise BadConfig.new "#{self.class} has not defined import_cmd!" end
import_installed?()
click to toggle source
# File lib/dumpr/driver.rb, line 108 def import_installed? raise BadConfig.new "#{self.class} has not defined import_installed?" end
logger()
click to toggle source
# File lib/dumpr/driver.rb, line 100 def logger @logger end
remote_destination?()
click to toggle source
DUMPING + EXPORTING
# File lib/dumpr/driver.rb, line 118 def remote_destination? @destination_host && @destination_host != "localhost" end
Protected Instance Methods
run(cmd)
click to toggle source
# File lib/dumpr/driver.rb, line 222 def run(cmd) start_time = Time.now logger.info "running command: #{scrub_cmd cmd}" stdout = `#{cmd}` took_sec = (Time.now - start_time).round() if $?.success? logger.info "finished (took #{took_sec}s)" else logger.error "failed (took #{took_sec}s) status: #{$?.exitstatus}" raise CommandFailure.new("Aborting because the following command failed: #{scrub_cmd cmd}") end end
scrub_cmd(cmd)
click to toggle source
# File lib/dumpr/driver.rb, line 218 def scrub_cmd(cmd) cmd.gsub(/password=[^\s]+/, 'password=xxxxxx') end