diff --git a/activerecord/lib/active_record.rb b/activerecord/lib/active_record.rb index 3b37b001f7..8526e224da 100644 --- a/activerecord/lib/active_record.rb +++ b/activerecord/lib/active_record.rb @@ -143,6 +143,8 @@ module ActiveRecord autoload :DatabaseTasks autoload :SQLiteDatabaseTasks, 'active_record/tasks/sqlite_database_tasks' autoload :MySQLDatabaseTasks, 'active_record/tasks/mysql_database_tasks' + autoload :PostgreSQLDatabaseTasks, + 'active_record/tasks/postgresql_database_tasks' end autoload :TestCase diff --git a/activerecord/lib/active_record/railties/databases.rake b/activerecord/lib/active_record/railties/databases.rake index 662c84bfda..3d9b1770ed 100644 --- a/activerecord/lib/active_record/railties/databases.rake +++ b/activerecord/lib/active_record/railties/databases.rake @@ -30,14 +30,18 @@ db_namespace = namespace :db do # *defaults next unless config['database'] # Only connect to local databases - local_database?(config) { create_database(config) } + local_database?(config) { + ActiveRecord::Tasks::DatabaseTasks.create config + } end end end desc 'Create the database from config/database.yml for the current Rails.env (use db:create:all to create all dbs in the config)' task :create => :load_config do - configs_for_environment.each { |config| create_database(config) } + configs_for_environment.each { |config| + ActiveRecord::Tasks::DatabaseTasks.create config + } ActiveRecord::Base.establish_connection(configs_for_environment.first) end @@ -47,35 +51,6 @@ db_namespace = namespace :db do {:charset => (config['charset'] || @charset), :collation => (config['collation'] || @collation)} end - def create_database(config) - begin - if config['adapter'] =~ /sqlite/ - ActiveRecord::Tasks::DatabaseTasks.create config - return # Skip the else clause of begin/rescue - else - ActiveRecord::Base.establish_connection(config) - ActiveRecord::Base.connection - end - rescue - case config['adapter'] - when /mysql/ - ActiveRecord::Tasks::DatabaseTasks.create config - when /postgresql/ - @encoding = config['encoding'] || ENV['CHARSET'] || 'utf8' - begin - ActiveRecord::Base.establish_connection(config.merge('database' => 'postgres', 'schema_search_path' => 'public')) - ActiveRecord::Base.connection.create_database(config['database'], config.merge('encoding' => @encoding)) - ActiveRecord::Base.establish_connection(config) - rescue Exception => e - $stderr.puts e, *(e.backtrace) - $stderr.puts "Couldn't create database for #{config.inspect}" - end - end - else - $stderr.puts "#{config['database']} already exists" - end - end - namespace :drop do # desc 'Drops all the local databases defined in config/database.yml' task :all => :load_config do @@ -475,7 +450,7 @@ db_namespace = namespace :db do when /postgresql/ ActiveRecord::Base.clear_active_connections! drop_database(abcs['test']) - create_database(abcs['test']) + ActiveRecord::Tasks::DatabaseTasks.create abcs['test'] when /sqlite/ dbfile = abcs['test']['database'] File.delete(dbfile) if File.exist?(dbfile) diff --git a/activerecord/lib/active_record/tasks/database_tasks.rb b/activerecord/lib/active_record/tasks/database_tasks.rb index d0d3ea12dd..6b9115f214 100644 --- a/activerecord/lib/active_record/tasks/database_tasks.rb +++ b/activerecord/lib/active_record/tasks/database_tasks.rb @@ -1,7 +1,7 @@ class ActiveRecord::Tasks::DatabaseTasks TASKS_PATTERNS = { /mysql/ => ActiveRecord::Tasks::MySQLDatabaseTasks, - # /postgresql/ => ActiveRecord::Tasks::PostgreSQLTasker, + /postgresql/ => ActiveRecord::Tasks::PostgreSQLDatabaseTasks, /sqlite/ => ActiveRecord::Tasks::SQLiteDatabaseTasks } diff --git a/activerecord/lib/active_record/tasks/postgresql_database_tasks.rb b/activerecord/lib/active_record/tasks/postgresql_database_tasks.rb new file mode 100644 index 0000000000..4e64a5e346 --- /dev/null +++ b/activerecord/lib/active_record/tasks/postgresql_database_tasks.rb @@ -0,0 +1,27 @@ +class ActiveRecord::Tasks::PostgreSQLDatabaseTasks + DEFAULT_ENCODING = ENV['CHARSET'] || 'utf8' + + delegate :connection, :establish_connection, :to => ActiveRecord::Base + + def initialize(configuration) + @configuration = configuration + end + + def create + establish_connection configuration.merge( + 'database' => 'postgres', + 'schema_search_path' => 'public' + ) + connection.create_database configuration['database'], + configuration.merge('encoding' => encoding) + establish_connection configuration + end + + private + + attr_reader :configuration + + def encoding + configuration['encoding'] || DEFAULT_ENCODING + 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 882a4f98a9..dd43414d79 100644 --- a/activerecord/lib/active_record/tasks/sqlite_database_tasks.rb +++ b/activerecord/lib/active_record/tasks/sqlite_database_tasks.rb @@ -1,16 +1,18 @@ class ActiveRecord::Tasks::SQLiteDatabaseTasks + delegate :connection, :establish_connection, :to => ActiveRecord::Base + def initialize(configuration) @configuration = configuration end def create - if File.exist?(configuration['database']) + if File.exist? configuration['database'] $stderr.puts "#{configuration['database']} already exists" return end - ActiveRecord::Base.establish_connection(configuration) - ActiveRecord::Base.connection + establish_connection configuration + connection end private diff --git a/activerecord/test/cases/postgresql_rake_test.rb b/activerecord/test/cases/postgresql_rake_test.rb new file mode 100644 index 0000000000..b2f7c2e8ba --- /dev/null +++ b/activerecord/test/cases/postgresql_rake_test.rb @@ -0,0 +1,57 @@ +require 'cases/helper' + +module ActiveRecord + class PostgreSQLDBCreateTest < ActiveRecord::TestCase + def setup + @connection = stub(:create_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.create @configuration + end + + def test_creates_database_with_default_encoding + @connection.expects(:create_database). + with('my-app-db', @configuration.merge('encoding' => 'utf8')) + + ActiveRecord::Tasks::DatabaseTasks.create @configuration + end + + def test_creates_database_with_given_encoding + @connection.expects(:create_database). + with('my-app-db', @configuration.merge('encoding' => 'latin')) + + ActiveRecord::Tasks::DatabaseTasks.create @configuration. + merge('encoding' => 'latin') + end + + def test_establishes_connection_to_new_database + ActiveRecord::Base.expects(:establish_connection).with(@configuration) + + ActiveRecord::Tasks::DatabaseTasks.create @configuration + end + + def test_db_create_with_error_prints_message + ActiveRecord::Base.stubs(:establish_connection).raises(Exception) + + $stderr.stubs(:puts).returns(true) + $stderr.expects(:puts). + with("Couldn't create database for #{@configuration.inspect}") + + ActiveRecord::Tasks::DatabaseTasks.create @configuration + end + end +end