From 38d23c0e5f816937047c9326f9dd33fb10490032 Mon Sep 17 00:00:00 2001
From: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
Date: Fri, 5 Apr 2013 15:55:02 +0300
Subject: [PATCH] Replace db:backup/restore with native mysq/pg solution

---
 lib/backup.rb                | 56 ++++++++++++++++++++++++++++++++++++
 lib/tasks/gitlab/backup.rake | 47 ++++--------------------------
 2 files changed, 62 insertions(+), 41 deletions(-)
 create mode 100644 lib/backup.rb

diff --git a/lib/backup.rb b/lib/backup.rb
new file mode 100644
index 00000000000..ad80ab1c7f7
--- /dev/null
+++ b/lib/backup.rb
@@ -0,0 +1,56 @@
+require 'yaml'
+
+class Backup
+  attr_reader :config, :db_dir
+
+  def initialize
+    @config = YAML.load_file(File.join(Rails.root,'config','database.yml'))[Rails.env]
+    @db_dir = File.join(Gitlab.config.backup.path, 'db')
+    FileUtils.mkdir_p(@db_dir) unless Dir.exists?(@db_dir)
+  end
+
+  def backup_db
+    case config["adapter"]
+    when /^mysql/ then
+      system("mysqldump #{mysql_args} #{config['database']} > #{db_file_name}")
+    when "postgresql" then
+      pg_env
+      system("pg_dump #{config['database']} > #{db_file_name}")
+    end
+  end
+
+  def restore_db
+    case config["adapter"]
+    when /^mysql/ then
+      system("mysql #{mysql_args} #{config['database']} < #{db_file_name}")
+    when "postgresql" then
+      pg_env
+      system("pg_restore #{config['database']} #{db_file_name}")
+    end
+  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.join(' ')
+  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
+end
diff --git a/lib/tasks/gitlab/backup.rake b/lib/tasks/gitlab/backup.rake
index 32acdcf56b5..393f8166877 100644
--- a/lib/tasks/gitlab/backup.rake
+++ b/lib/tasks/gitlab/backup.rake
@@ -109,11 +109,6 @@ namespace :gitlab do
       end
     end
 
-    ################################################################################
-    ################################# invoked tasks ################################
-
-    ################################# REPOSITORIES #################################
-
     namespace :repo do
       task :create => :environment do
         backup_path_repo = File.join(Gitlab.config.backup.path, "repositories")
@@ -167,48 +162,18 @@ namespace :gitlab do
       end
     end
 
-    ###################################### DB ######################################
-
     namespace :db do
       task :create => :environment do
-        backup_path_db = File.join(Gitlab.config.backup.path, "db")
-        FileUtils.mkdir_p(backup_path_db) unless Dir.exists?(backup_path_db)
-
-        puts "Dumping database tables ... ".blue
-        ActiveRecord::Base.connection.tables.each do |tbl|
-          print " * #{tbl.yellow} ... "
-          count = 1
-          safe_tablename = ActiveRecord::Base.connection.quote_table_name(tbl)
-          File.open(File.join(backup_path_db, tbl + ".yml"), "w+") do |file|
-            ActiveRecord::Base.connection.select_all("SELECT * FROM #{safe_tablename}").each do |line|
-              line.delete_if{|k,v| v.blank?}
-              output = {tbl + '_' + count.to_s => line}
-              file << output.to_yaml.gsub(/^---\n/,'') + "\n"
-              count += 1
-            end
-            puts "done".green
-          end
-        end
+        puts "Dumping database ... ".blue
+        Backup.new.backup_db
+        puts "done".green
       end
 
       task :restore => :environment do
-        backup_path_db = File.join(Gitlab.config.backup.path, "db")
-
-        puts "Restoring database tables (loading fixtures) ... "
-        Rake::Task["db:reset"].invoke
-
-        Dir.glob(File.join(backup_path_db, "*.yml") ).each do |dir|
-          fixture_file = File.basename(dir, ".*" )
-          print "#{fixture_file.yellow} ... "
-          if File.size(dir) > 0
-            ActiveRecord::Fixtures.create_fixtures(backup_path_db, fixture_file)
-            puts "done".green
-          else
-            puts "skipping".yellow
-          end
-        end
+        puts "Restoring database ... ".blue
+        Backup.new.restore_db
+        puts "done".green
       end
     end
-
   end # namespace end: backup
 end # namespace end: gitlab
-- 
GitLab