#!/usr/bin/env ruby
# A small script to import a production gzip'ed dump
require "yaml"
require File.expand_path(File.dirname(__FILE__) + "/../../config/environment")
class DatabaseLoader
attr_reader :db_dump_filename
def initialize(filename, run_migrations=false)
@db_dump_filename = filename.dup
@run_migrations = run_migrations ? true : false
end
def load
# gunzip
# import
redefine_views
# run_migrations
end
def gunzip
if needs_unziping?
puts "* Gunzip'ing #{db_dump_filename}"
puts %x(gunzip #{db_dump_filename})
@db_dump_filename.gsub!(".gz", "")
end
end
def import
puts "* Importing db dump #{db_dump_filename} to #{database_name}"
%x(mysql -u root #{database_name} < #{db_dump_filename})
end
def run_migrations
if should_run_migrations?
puts "* Running migrations"
puts `rake db:migrate`
end
end
def redefine_views
puts "* Redefining views under the current database user"
ViewRedefiner.redefine_views!
end
private
def should_run_migrations?
@run_migrations == true
end
def needs_unziping?
db_dump_filename.include?(".gz")
end
def database_name
@database_name ||= development_config["database"]
end
def database_username
development_config["username"]
end
def database_host
development_config["host"]
end
def development_config
yaml_config["development"]
end
def yaml_config
@yaml_config ||= YAML.load(File.read("config/database.yml"))
end
def db_dump_contents(&blk)
File.open(db_dump_filename, "r+", &blk)
end
end
class ViewRedefiner
def self.redefine_views!
new.redefine_views
end
def redefine_views
views.each do |view|
redefine_view(view)
end
end
def redefine_view(view)
definition = get_view_definition(view)
definition.gsub(/ALGORITHM.*DEFINER=.*SQL SECURITY DEFINER\s+/, "")
drop_view(view)
create_view(definition)
end
def get_view_definition(view_name)
execute_returning_hash("SHOW CREATE TABLE `#{view_name}`").first["Create View"]
end
def drop_view(view_name)
execute "DROP VIEW `#{view_name}"
end
# [{"collation_connection"=>"utf8_general_ci",
# "character_set_client"=>"utf8",
# "Create View"=>
# "CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `causes_index` AS (select `causes`.`id` AS `id`,`causes`.`name` AS `name`,`categories`.`name` AS `category_name`,`causes`.`website` AS `website`,if((`causes`.`display_on_homepage` = 1),_utf8'Yes',_utf8'No') AS `homepage_bool`,`causes`.`image_id` AS `image_id`,`causes`.`slug` AS `slug` from (`causes` left join `categories` on((`causes`.`category_id` = `categories`.`id`))))",
# "View"=>"causes_index"}]
def create_view(definition)
execute definition
end
# >> pp hash
# [{"Table_type"=>"VIEW", "Tables_in_designcause_dev"=>"braintree_orders_index"},
# {"Table_type"=>"VIEW", "Tables_in_designcause_dev"=>"causes_index"},
# {"Table_type"=>"VIEW", "Tables_in_designcause_dev"=>"competitions_index"},
# {"Table_type"=>"VIEW", "Tables_in_designcause_dev"=>"pencil_orders_index"},
# {"Table_type"=>"VIEW", "Tables_in_designcause_dev"=>"products_index"},
# {"Table_type"=>"VIEW", "Tables_in_designcause_dev"=>"promo_code_index"},
# {"Table_type"=>"VIEW", "Tables_in_designcause_dev"=>"submissions_index"}]
def views
show_views.map { |x| x.to_a.last.last }
end
def show_views
execute_returning_hash("SHOW FULL TABLES WHERE table_type = 'view'")
end
def execute_returning_hash(stmt)
execute(stmt).all_hashes.dup
end
def execute(stmt)
puts "* Executing sql: #{stmt}"
ActiveRecord::Base.connection.execute(stmt)
end
end
db_loader = DatabaseLoader.new(ARGV[0], ARGV[1])
db_loader.load