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
  private

42 43 44
  def configuration
    @configuration
  end
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60

  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'
61
      ArJdbcMySQL::Error
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 87 88
    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