diff options
8 files changed, 243 insertions, 52 deletions
diff --git a/activerecord/lib/active_record/railties/databases.rake b/activerecord/lib/active_record/railties/databases.rake index 3d9b1770ed..d3137be38c 100644 --- a/activerecord/lib/active_record/railties/databases.rake +++ b/activerecord/lib/active_record/railties/databases.rake @@ -57,19 +57,18 @@ db_namespace = namespace :db do ActiveRecord::Base.configurations.each_value do |config| # Skip entries that don't have a database key next unless config['database'] - begin - # Only connect to local databases - local_database?(config) { drop_database(config) } - rescue Exception => e - $stderr.puts "Couldn't drop #{config['database']} : #{e.inspect}" - end + local_database?(config) { + ActiveRecord::Tasks::DatabaseTasks.drop config + } end end end desc 'Drops the database for the current Rails.env (use db:drop:all to drop all databases)' task :drop => :load_config do - configs_for_environment.each { |config| drop_database_and_rescue(config) } + configs_for_environment.each { |config| + ActiveRecord::Tasks::DatabaseTasks.drop config + } end def local_database?(config, &block) @@ -444,16 +443,8 @@ db_namespace = namespace :db do task :purge => :environment do abcs = ActiveRecord::Base.configurations case abcs['test']['adapter'] - when /mysql/ - ActiveRecord::Base.establish_connection(:test) - ActiveRecord::Base.connection.recreate_database(abcs['test']['database'], mysql_creation_options(abcs['test'])) - when /postgresql/ - ActiveRecord::Base.clear_active_connections! - drop_database(abcs['test']) - ActiveRecord::Tasks::DatabaseTasks.create abcs['test'] - when /sqlite/ - dbfile = abcs['test']['database'] - File.delete(dbfile) if File.exist?(dbfile) + when /mysql/, /postgresql/, /sqlite/ + ActiveRecord::Tasks::DatabaseTasks.purge abcs['test'] when 'sqlserver' test = abcs.deep_dup['test'] test_database = test['database'] @@ -527,31 +518,6 @@ end task 'test:prepare' => 'db:test:prepare' -def drop_database(config) - case config['adapter'] - when /mysql/ - ActiveRecord::Base.establish_connection(config) - ActiveRecord::Base.connection.drop_database config['database'] - when /sqlite/ - require 'pathname' - path = Pathname.new(config['database']) - file = path.absolute? ? path.to_s : File.join(Rails.root, path) - - FileUtils.rm(file) - when /postgresql/ - ActiveRecord::Base.establish_connection(config.merge('database' => 'postgres', 'schema_search_path' => 'public')) - ActiveRecord::Base.connection.drop_database config['database'] - end -end - -def drop_database_and_rescue(config) - begin - drop_database(config) - rescue Exception => e - $stderr.puts "Couldn't drop #{config['database']} : #{e.inspect}" - end -end - def configs_for_environment environments = [Rails.env] environments << 'test' if Rails.env.development? diff --git a/activerecord/lib/active_record/tasks/database_tasks.rb b/activerecord/lib/active_record/tasks/database_tasks.rb index 6b9115f214..1d70d6100c 100644 --- a/activerecord/lib/active_record/tasks/database_tasks.rb +++ b/activerecord/lib/active_record/tasks/database_tasks.rb @@ -7,11 +7,22 @@ class ActiveRecord::Tasks::DatabaseTasks def self.create(configuration) class_for_adapter(configuration['adapter']).new(configuration).create - rescue Exception => e - $stderr.puts e, *(e.backtrace) + rescue Exception => error + $stderr.puts error, *(error.backtrace) $stderr.puts "Couldn't create database for #{configuration.inspect}" end + def self.drop(configuration) + class_for_adapter(configuration['adapter']).new(configuration).drop + rescue Exception => error + $stderr.puts error, *(error.backtrace) + $stderr.puts "Couldn't drop #{configuration['database']}" + end + + def self.purge(configuration) + class_for_adapter(configuration['adapter']).new(configuration).purge + end + def self.class_for_adapter(adapter) key = TASKS_PATTERNS.keys.detect { |key| adapter[key] } TASKS_PATTERNS[key] diff --git a/activerecord/lib/active_record/tasks/mysql_database_tasks.rb b/activerecord/lib/active_record/tasks/mysql_database_tasks.rb index 16d606d6fb..a1d36f0855 100644 --- a/activerecord/lib/active_record/tasks/mysql_database_tasks.rb +++ b/activerecord/lib/active_record/tasks/mysql_database_tasks.rb @@ -27,6 +27,16 @@ class ActiveRecord::Tasks::MySQLDatabaseTasks $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 attr_reader :configuration diff --git a/activerecord/lib/active_record/tasks/postgresql_database_tasks.rb b/activerecord/lib/active_record/tasks/postgresql_database_tasks.rb index 4e64a5e346..c3c5b2f2f5 100644 --- a/activerecord/lib/active_record/tasks/postgresql_database_tasks.rb +++ b/activerecord/lib/active_record/tasks/postgresql_database_tasks.rb @@ -1,22 +1,31 @@ class ActiveRecord::Tasks::PostgreSQLDatabaseTasks DEFAULT_ENCODING = ENV['CHARSET'] || 'utf8' - delegate :connection, :establish_connection, :to => ActiveRecord::Base + delegate :connection, :establish_connection, :clear_active_connections!, + :to => ActiveRecord::Base def initialize(configuration) @configuration = configuration end - def create - establish_connection configuration.merge( - 'database' => 'postgres', - 'schema_search_path' => 'public' - ) + def create(master_established = false) + establish_master_connection unless master_established connection.create_database configuration['database'], configuration.merge('encoding' => encoding) establish_connection configuration end + def drop + establish_master_connection + connection.drop_database configuration['database'] + end + + def purge + clear_active_connections! + drop + create true + end + private attr_reader :configuration @@ -24,4 +33,11 @@ class ActiveRecord::Tasks::PostgreSQLDatabaseTasks def encoding configuration['encoding'] || DEFAULT_ENCODING end + + def establish_master_connection + establish_connection configuration.merge( + 'database' => 'postgres', + 'schema_search_path' => 'public' + ) + end end diff --git a/activerecord/lib/active_record/tasks/sqlite_database_tasks.rb b/activerecord/lib/active_record/tasks/sqlite_database_tasks.rb index dd43414d79..fff763421b 100644 --- a/activerecord/lib/active_record/tasks/sqlite_database_tasks.rb +++ b/activerecord/lib/active_record/tasks/sqlite_database_tasks.rb @@ -15,6 +15,16 @@ class ActiveRecord::Tasks::SQLiteDatabaseTasks connection end + def drop + require 'pathname' + path = Pathname.new configuration['database'] + file = path.absolute? ? path.to_s : File.join(Rails.root, path) + + FileUtils.rm(file) + end + + alias :purge :drop + private attr_reader :configuration diff --git a/activerecord/test/cases/mysql_rake_test.rb b/activerecord/test/cases/mysql_rake_test.rb index fc49a16553..cdb0968bb6 100644 --- a/activerecord/test/cases/mysql_rake_test.rb +++ b/activerecord/test/cases/mysql_rake_test.rb @@ -1,4 +1,5 @@ require 'cases/helper' +require 'mysql' module ActiveRecord class MysqlDBCreateTest < ActiveRecord::TestCase @@ -45,8 +46,6 @@ module ActiveRecord class MysqlDBCreateAsRootTest < ActiveRecord::TestCase def setup - require 'mysql' - @connection = stub(:create_database => true, :execute => true) @error = Mysql::Error.new "Invalid permissions" @configuration = { @@ -117,4 +116,64 @@ module ActiveRecord ActiveRecord::Tasks::DatabaseTasks.create @configuration end end + + class MySQLDBDropTest < ActiveRecord::TestCase + def setup + @connection = stub(:drop_database => true) + @configuration = { + 'adapter' => 'mysql', + 'database' => 'my-app-db' + } + + ActiveRecord::Base.stubs(:connection).returns(@connection) + ActiveRecord::Base.stubs(:establish_connection).returns(true) + end + + def test_establishes_connection_to_postgresql_database + ActiveRecord::Base.expects(:establish_connection).with @configuration + + ActiveRecord::Tasks::DatabaseTasks.drop @configuration + end + + def test_drops_database + @connection.expects(:drop_database).with('my-app-db') + + ActiveRecord::Tasks::DatabaseTasks.drop @configuration + end + end + + class MySQLTestPurge < ActiveRecord::TestCase + def setup + @connection = stub(:recreate_database => true) + @configuration = { + 'adapter' => 'mysql', + 'database' => 'test-db' + } + + ActiveRecord::Base.stubs(:connection).returns(@connection) + ActiveRecord::Base.stubs(:establish_connection).returns(true) + end + + def test_establishes_connection_to_test_database + ActiveRecord::Base.expects(:establish_connection).with(:test) + + ActiveRecord::Tasks::DatabaseTasks.purge @configuration + end + + def test_recreates_database_with_the_default_options + @connection.expects(:recreate_database). + with('test-db', {:charset => 'utf8', :collation => 'utf8_unicode_ci'}) + + ActiveRecord::Tasks::DatabaseTasks.purge @configuration + end + + def test_recreates_database_with_the_given_options + @connection.expects(:recreate_database). + with('test-db', {:charset => 'latin', :collation => 'latin_ci'}) + + ActiveRecord::Tasks::DatabaseTasks.purge @configuration.merge( + 'charset' => 'latin', 'collation' => 'latin_ci' + ) + end + end end diff --git a/activerecord/test/cases/postgresql_rake_test.rb b/activerecord/test/cases/postgresql_rake_test.rb index b2f7c2e8ba..6d6ede354d 100644 --- a/activerecord/test/cases/postgresql_rake_test.rb +++ b/activerecord/test/cases/postgresql_rake_test.rb @@ -54,4 +54,82 @@ module ActiveRecord ActiveRecord::Tasks::DatabaseTasks.create @configuration end end + + class PostgreSQLDBDropTest < ActiveRecord::TestCase + def setup + @connection = stub(:drop_database => true) + @configuration = { + 'adapter' => 'postgresql', + 'database' => 'my-app-db' + } + + ActiveRecord::Base.stubs(:connection).returns(@connection) + ActiveRecord::Base.stubs(:establish_connection).returns(true) + end + + def test_establishes_connection_to_postgresql_database + ActiveRecord::Base.expects(:establish_connection).with( + 'adapter' => 'postgresql', + 'database' => 'postgres', + 'schema_search_path' => 'public' + ) + + ActiveRecord::Tasks::DatabaseTasks.drop @configuration + end + + def test_drops_database + @connection.expects(:drop_database).with('my-app-db') + + ActiveRecord::Tasks::DatabaseTasks.drop @configuration + end + end + + class PostgreSQLPurgeTest < ActiveRecord::TestCase + def setup + @connection = stub(:create_database => true, :drop_database => true) + @configuration = { + 'adapter' => 'postgresql', + 'database' => 'my-app-db' + } + + ActiveRecord::Base.stubs(:connection).returns(@connection) + ActiveRecord::Base.stubs(:clear_active_connections!).returns(true) + ActiveRecord::Base.stubs(:establish_connection).returns(true) + end + + def test_clears_active_connections + ActiveRecord::Base.expects(:clear_active_connections!) + + ActiveRecord::Tasks::DatabaseTasks.purge @configuration + end + + def test_establishes_connection_to_postgresql_database + ActiveRecord::Base.expects(:establish_connection).with( + 'adapter' => 'postgresql', + 'database' => 'postgres', + 'schema_search_path' => 'public' + ) + + ActiveRecord::Tasks::DatabaseTasks.purge @configuration + end + + def test_drops_database + @connection.expects(:drop_database).with('my-app-db') + + ActiveRecord::Tasks::DatabaseTasks.purge @configuration + end + + def test_creates_database + @connection.expects(:create_database). + with('my-app-db', @configuration.merge('encoding' => 'utf8')) + + ActiveRecord::Tasks::DatabaseTasks.purge @configuration + end + + def test_establishes_connection + ActiveRecord::Base.expects(:establish_connection).with(@configuration) + + ActiveRecord::Tasks::DatabaseTasks.purge @configuration + end + end end diff --git a/activerecord/test/cases/sqlite_rake_test.rb b/activerecord/test/cases/sqlite_rake_test.rb index 12cd965fd5..c6f533d375 100644 --- a/activerecord/test/cases/sqlite_rake_test.rb +++ b/activerecord/test/cases/sqlite_rake_test.rb @@ -1,4 +1,7 @@ require 'cases/helper' +require 'pathname' + +module Rails; end unless defined?(Rails) module ActiveRecord class SqliteDBCreateTest < ActiveRecord::TestCase @@ -59,4 +62,42 @@ module ActiveRecord ActiveRecord::Tasks::DatabaseTasks.create(@configuration) end end + + class SqliteDBDropTest < ActiveRecord::TestCase + def setup + @database = "db_create.sqlite3" + @path = stub(:to_s => '/absolute/path', :absolute? => true) + @configuration = { + 'adapter' => 'sqlite3', + 'database' => @database + } + + Rails.stubs(:root).returns('/rails/root') + Pathname.stubs(:new).returns(@path) + File.stubs(:join).returns('/former/relative/path') + FileUtils.stubs(:rm).returns(true) + end + + def test_creates_path_from_database + Pathname.expects(:new).with(@database).returns(@path) + + ActiveRecord::Tasks::DatabaseTasks.drop @configuration + end + + def test_removes_file_with_absolute_path + @path.stubs(:absolute?).returns(true) + + FileUtils.expects(:rm).with('/absolute/path') + + ActiveRecord::Tasks::DatabaseTasks.drop @configuration + end + + def test_removes_file_with_relative_path + @path.stubs(:absolute?).returns(false) + + FileUtils.expects(:rm).with('/former/relative/path') + + ActiveRecord::Tasks::DatabaseTasks.drop @configuration + end + end end |