Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #6761 from freelancing-god/db-rake
Get logic out of db rake tasks, and into classes and objects
- Loading branch information
Showing
10 changed files
with
983 additions
and
156 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
class ActiveRecord::Tasks::DatabaseTasks | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong. |
||
TASKS_PATTERNS = { | ||
/mysql/ => ActiveRecord::Tasks::MySQLDatabaseTasks, | ||
/postgresql/ => ActiveRecord::Tasks::PostgreSQLDatabaseTasks, | ||
/sqlite/ => ActiveRecord::Tasks::SQLiteDatabaseTasks | ||
} | ||
LOCAL_HOSTS = ['127.0.0.1', 'localhost'] | ||
|
||
def self.create(*arguments) | ||
configuration = arguments.first | ||
class_for_adapter(configuration['adapter']).new(*arguments).create | ||
rescue Exception => error | ||
$stderr.puts error, *(error.backtrace) | ||
$stderr.puts "Couldn't create database for #{configuration.inspect}" | ||
end | ||
|
||
def self.create_all | ||
each_local_configuration { |configuration| create configuration } | ||
end | ||
|
||
def self.create_current(environment = Rails.env) | ||
each_current_configuration(environment) { |configuration| | ||
create configuration | ||
} | ||
ActiveRecord::Base.establish_connection environment | ||
end | ||
|
||
def self.drop(*arguments) | ||
configuration = arguments.first | ||
class_for_adapter(configuration['adapter']).new(*arguments).drop | ||
rescue Exception => error | ||
$stderr.puts error, *(error.backtrace) | ||
$stderr.puts "Couldn't drop #{configuration['database']}" | ||
end | ||
|
||
def self.drop_all | ||
each_local_configuration { |configuration| drop configuration } | ||
end | ||
|
||
def self.drop_current(environment = Rails.env) | ||
each_current_configuration(environment) { |configuration| | ||
drop configuration | ||
} | ||
end | ||
|
||
def self.purge(configuration) | ||
class_for_adapter(configuration['adapter']).new(configuration).purge | ||
end | ||
|
||
private | ||
|
||
def self.class_for_adapter(adapter) | ||
key = TASKS_PATTERNS.keys.detect { |pattern| adapter[pattern] } | ||
TASKS_PATTERNS[key] | ||
end | ||
|
||
def self.each_current_configuration(environment) | ||
environments = [environment] | ||
environments << 'test' if environment.development? | ||
|
||
configurations = ActiveRecord::Base.configurations.values_at(*environments) | ||
configurations.compact.each do |configuration| | ||
yield configuration unless configuration['database'].blank? | ||
end | ||
end | ||
|
||
def self.each_local_configuration | ||
ActiveRecord::Base.configurations.each_value do |configuration| | ||
next unless configuration['database'] | ||
|
||
if local_database?(configuration) | ||
yield configuration | ||
else | ||
$stderr.puts "This task only modifies local databases. #{configuration['database']} is on a remote host." | ||
end | ||
end | ||
end | ||
|
||
def self.local_database?(configuration) | ||
configuration['host'].in?(LOCAL_HOSTS) || configuration['host'].blank? | ||
end | ||
end |
88 changes: 88 additions & 0 deletions
88
activerecord/lib/active_record/tasks/mysql_database_tasks.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
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 | ||
|
||
def drop | ||
establish_connection configuration | ||
connection.drop_database configuration['database'] | ||
end | ||
|
||
def purge | ||
establish_connection :test | ||
connection.recreate_database configuration['database'], creation_options | ||
end | ||
|
||
private | ||
|
||
def configuration | ||
@configuration | ||
end | ||
|
||
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' | ||
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 |
Oops, something went wrong.
Hey @rafaelfranca, is this follow the coding conventions?