summaryrefslogtreecommitdiff
path: root/lib/backup/database.rb
diff options
context:
space:
mode:
authorValery Sizov <vsv2711@gmail.com>2015-05-06 18:27:00 +0300
committerValery Sizov <vsv2711@gmail.com>2015-05-06 18:27:00 +0300
commit24a1c4789a2d04d26a4100066433d966e4ad5407 (patch)
treed58cd58c53795b160e5c1f544aca3e57b4b8fb50 /lib/backup/database.rb
parentafcdd6f1030880ac107afefde02cd3c03f364195 (diff)
downloadgitlab-ci-24a1c4789a2d04d26a4100066433d966e4ad5407.tar.gz
backup/restore rake task
Diffstat (limited to 'lib/backup/database.rb')
-rw-r--r--lib/backup/database.rb92
1 files changed, 92 insertions, 0 deletions
diff --git a/lib/backup/database.rb b/lib/backup/database.rb
new file mode 100644
index 0000000..3ef5f44
--- /dev/null
+++ b/lib/backup/database.rb
@@ -0,0 +1,92 @@
+require 'yaml'
+
+module Backup
+ class Database
+ attr_reader :config, :db_dir
+
+ def initialize
+ @config = YAML.load_file(File.join(Rails.root,'config','database.yml'))[Rails.env]
+ @db_dir = File.join(GitlabCi.config.backup.path, 'db')
+ FileUtils.mkdir_p(@db_dir) unless Dir.exists?(@db_dir)
+ end
+
+ def dump
+ success = case config["adapter"]
+ when /^mysql/ then
+ $progress.print "Dumping MySQL database #{config['database']} ... "
+ system('mysqldump', *mysql_args, config['database'], out: db_file_name)
+ when "postgresql" then
+ $progress.print "Dumping PostgreSQL database #{config['database']} ... "
+ pg_env
+ system('pg_dump', config['database'], out: db_file_name)
+ end
+ report_success(success)
+ abort 'Backup failed' unless success
+ end
+
+ def restore
+ success = case config["adapter"]
+ when /^mysql/ then
+ $progress.print "Restoring MySQL database #{config['database']} ... "
+ system('mysql', *mysql_args, config['database'], in: db_file_name)
+ when "postgresql" then
+ $progress.print "Restoring PostgreSQL database #{config['database']} ... "
+ # Drop all tables because PostgreSQL DB dumps do not contain DROP TABLE
+ # statements like MySQL.
+ drop_all_tables
+ drop_all_postgres_sequences
+ pg_env
+ system('psql', config['database'], '-f', db_file_name)
+ end
+ report_success(success)
+ abort 'Restore failed' unless success
+ end
+
+ protected
+
+ def db_file_name
+ File.join(db_dir, 'database.sql')
+ end
+
+ def mysql_args
+ args = {
+ 'host' => '--host',
+ 'port' => '--port',
+ 'socket' => '--socket',
+ 'username' => '--user',
+ 'encoding' => '--default-character-set',
+ 'password' => '--password'
+ }
+ args.map { |opt, arg| "#{arg}=#{config[opt]}" if config[opt] }.compact
+ end
+
+ def pg_env
+ ENV['PGUSER'] = config["username"] if config["username"]
+ ENV['PGHOST'] = config["host"] if config["host"]
+ ENV['PGPORT'] = config["port"].to_s if config["port"]
+ ENV['PGPASSWORD'] = config["password"].to_s if config["password"]
+ end
+
+ def report_success(success)
+ if success
+ $progress.puts '[DONE]'.green
+ else
+ $progress.puts '[FAILED]'.red
+ end
+ end
+
+ def drop_all_tables
+ connection = ActiveRecord::Base.connection
+ connection.tables.each do |table|
+ connection.drop_table(table)
+ end
+ end
+
+ def drop_all_postgres_sequences
+ connection = ActiveRecord::Base.connection
+ connection.execute("SELECT c.relname FROM pg_class c WHERE c.relkind = 'S';").each do |sequence|
+ connection.execute("DROP SEQUENCE #{sequence['relname']}")
+ end
+ end
+ end
+end