mysql_database_tasks.rb 2.4 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
class ActiveRecord::Tasks::MySQLDatabaseTasks
  DEFAULT_CHARSET     = ENV['CHARSET']   || 'utf8'
  DEFAULT_COLLATION   = ENV['COLLATION'] || 'utf8_unicode_ci'
  ACCESS_DENIED_ERROR = 1045

  delegate :connection, :establish_connection, :to => ActiveRecord::Base

  def initialize(configuration)
    @configuration = configuration
  end

  def create
    establish_connection configuration_without_database
    connection.create_database configuration['database'], creation_options
    establish_connection configuration
  rescue error_class => error
    raise error unless error.errno == ACCESS_DENIED_ERROR

    $stdout.print error.error
    establish_connection root_configuration_without_database
    connection.create_database configuration['database'], creation_options
    connection.execute grant_statement.gsub(/\s+/, ' ').strip
    establish_connection configuration
  rescue error_class => error
    $stderr.puts error.error
    $stderr.puts "Couldn't create database for #{configuration.inspect}, #{creation_options.inspect}"
    $stderr.puts "(If you set the charset manually, make sure you have a matching collation)" if configuration['charset']
  end

P
Pat Allan 已提交
30 31 32 33 34 35 36 37 38 39
  def drop
    establish_connection configuration
    connection.drop_database configuration['database']
  end

  def purge
    establish_connection :test
    connection.recreate_database configuration['database'], creation_options
  end

40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
  private

  attr_reader :configuration

  def configuration_without_database
    configuration.merge('database' => nil)
  end

  def creation_options
    {
      :charset   => (configuration['charset']   || DEFAULT_CHARSET),
      :collation => (configuration['collation'] || DEFAULT_COLLATION)
    }
  end

  def error_class
    case configuration['adapter']
    when /jdbc/
      require 'active_record/railties/jdbcmysql_error'
      error_class = ArJdbcMySQL::Error
    when /mysql2/
      Mysql2::Error
    else
      Mysql::Error
    end
  end

  def grant_statement
    <<-SQL
GRANT ALL PRIVILEGES ON #{configuration['database']}.*
  TO '#{configuration['username']}'@'localhost'
IDENTIFIED BY '#{configuration['password']}' WITH GRANT OPTION;
    SQL
  end

  def root_configuration_without_database
    configuration_without_database.merge(
      'username' => 'root',
      'password' => root_password
    )
  end

  def root_password
    $stdout.print "Please provide the root password for your mysql installation\n>"
    $stdin.gets.strip
  end
end