aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
authorGrace Liu <graceliu@yahoo.com>2012-08-30 18:50:30 -0700
committerGrace Liu <graceliu@yahoo.com>2012-09-11 20:40:13 -0700
commit148c50b49a3db5e7516e8c465de4f68056912562 (patch)
tree3124b49a1320243152213d0bbb785e0e9088acfb /activerecord
parent34b23e7110a3a13cf157608cefc9b5701017bf39 (diff)
downloadrails-148c50b49a3db5e7516e8c465de4f68056912562.tar.gz
rails-148c50b49a3db5e7516e8c465de4f68056912562.tar.bz2
rails-148c50b49a3db5e7516e8c465de4f68056912562.zip
fixed support for DATABASE_URL for rake db tasks
- added tests to confirm establish_connection uses DATABASE_URL and Rails.env correctly even when no arguments are passed in. - updated rake db tasks to support DATABASE_URL, and added tests to confirm correct behavior for these rake tasks. (Removed establish_connection call from some tasks since in those cases the :environment task already made sure the function would be called) - updated Resolver so that when it resolves the database url, it removes hash values with empty strings from the config spec (e.g. to support connection to postgresql when no username is specified).
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/lib/active_record/connection_adapters/connection_specification.rb2
-rw-r--r--activerecord/lib/active_record/railties/databases.rake60
-rw-r--r--activerecord/lib/active_record/tasks/database_tasks.rb28
-rw-r--r--activerecord/test/cases/connection_specification/resolver_test.rb2
4 files changed, 60 insertions, 32 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/connection_specification.rb b/activerecord/lib/active_record/connection_adapters/connection_specification.rb
index dd40351a38..b9a61f7d91 100644
--- a/activerecord/lib/active_record/connection_adapters/connection_specification.rb
+++ b/activerecord/lib/active_record/connection_adapters/connection_specification.rb
@@ -72,7 +72,7 @@ module ActiveRecord
:port => config.port,
:database => config.path.sub(%r{^/},""),
:host => config.host }
- spec.reject!{ |_,value| !value }
+ spec.reject!{ |_,value| value.blank? }
if config.query
options = Hash[config.query.split("&").map{ |pair| pair.split("=") }].symbolize_keys
spec.merge!(options)
diff --git a/activerecord/lib/active_record/railties/databases.rake b/activerecord/lib/active_record/railties/databases.rake
index ae24542521..bcb26f72c8 100644
--- a/activerecord/lib/active_record/railties/databases.rake
+++ b/activerecord/lib/active_record/railties/databases.rake
@@ -18,9 +18,13 @@ db_namespace = namespace :db do
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)'
+ desc 'Create the database from DATABASE_URL or config/database.yml for the current Rails.env (use db:create:all to create all dbs in the config)'
task :create => [:load_config] do
- ActiveRecord::Tasks::DatabaseTasks.create_current
+ if ENV['DATABASE_URL']
+ ActiveRecord::Tasks::DatabaseTasks.create_database_url
+ else
+ ActiveRecord::Tasks::DatabaseTasks.create_current
+ end
end
namespace :drop do
@@ -29,9 +33,13 @@ db_namespace = namespace :db do
end
end
- desc 'Drops the database for the current Rails.env (use db:drop:all to drop all databases)'
+ desc 'Drops the database using DATABASE_URL or the current Rails.env (use db:drop:all to drop all databases)'
task :drop => [:load_config] do
- ActiveRecord::Tasks::DatabaseTasks.drop_current
+ if ENV['DATABASE_URL']
+ ActiveRecord::Tasks::DatabaseTasks.drop_database_url
+ else
+ ActiveRecord::Tasks::DatabaseTasks.drop_current
+ end
end
desc "Migrate the database (options: VERSION=x, VERBOSE=false, SCOPE=blog)."
@@ -88,8 +96,6 @@ db_namespace = namespace :db do
desc 'Display status of migrations'
task :status => [:environment, :load_config] do
- config = ActiveRecord::Base.configurations[Rails.env]
- ActiveRecord::Base.establish_connection(config)
unless ActiveRecord::Base.connection.table_exists?(ActiveRecord::Migrator.schema_migrations_table_name)
puts 'Schema migrations table does not exist yet.'
next # means "return" for rake task
@@ -110,7 +116,7 @@ db_namespace = namespace :db do
['up', version, '********** NO FILE **********']
end
# output
- puts "\ndatabase: #{config['database']}\n\n"
+ puts "\ndatabase: #{ActiveRecord::Base.connection_config[:database]}\n\n"
puts "#{'Status'.center(8)} #{'Migration ID'.ljust(14)} Migration Name"
puts "-" * 50
(db_list + file_list).sort_by {|migration| migration[1]}.each do |migration|
@@ -186,7 +192,6 @@ db_namespace = namespace :db do
task :load => [:environment, :load_config] do
require 'active_record/fixtures'
- ActiveRecord::Base.establish_connection(Rails.env)
base_dir = File.join [Rails.root, ENV['FIXTURES_PATH'] || %w{test fixtures}].flatten
fixtures_dir = File.join [base_dir, ENV['FIXTURES_DIR']].compact
@@ -225,7 +230,6 @@ db_namespace = namespace :db do
require 'active_record/schema_dumper'
filename = ENV['SCHEMA'] || "#{Rails.root}/db/schema.rb"
File.open(filename, "w:utf-8") do |file|
- ActiveRecord::Base.establish_connection(Rails.env)
ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, file)
end
db_namespace['schema:dump'].reenable
@@ -277,22 +281,22 @@ db_namespace = namespace :db do
desc 'Dump the database structure to db/structure.sql. Specify another file with DB_STRUCTURE=db/my_structure.sql'
task :dump => [:environment, :load_config] do
- abcs = ActiveRecord::Base.configurations
filename = ENV['DB_STRUCTURE'] || File.join(Rails.root, "db", "structure.sql")
- case abcs[Rails.env]['adapter']
+ current_config = ActiveRecord::Tasks::DatabaseTasks.current_config
+ case current_config['adapter']
when /mysql/, /postgresql/, /sqlite/
- ActiveRecord::Tasks::DatabaseTasks.structure_dump(abcs[Rails.env], filename)
+ ActiveRecord::Tasks::DatabaseTasks.structure_dump(current_config, filename)
when 'oci', 'oracle'
- ActiveRecord::Base.establish_connection(abcs[Rails.env])
+ ActiveRecord::Base.establish_connection(current_config)
File.open(filename, "w:utf-8") { |f| f << ActiveRecord::Base.connection.structure_dump }
when 'sqlserver'
- `smoscript -s #{abcs[Rails.env]['host']} -d #{abcs[Rails.env]['database']} -u #{abcs[Rails.env]['username']} -p #{abcs[Rails.env]['password']} -f #{filename} -A -U`
+ `smoscript -s #{current_config['host']} -d #{current_config['database']} -u #{current_config['username']} -p #{current_config['password']} -f #{filename} -A -U`
when "firebird"
- set_firebird_env(abcs[Rails.env])
- db_string = firebird_db_string(abcs[Rails.env])
+ set_firebird_env(current_config)
+ db_string = firebird_db_string(current_config)
sh "isql -a #{db_string} > #{filename}"
else
- raise "Task not supported by '#{abcs[Rails.env]["adapter"]}'"
+ raise "Task not supported by '#{current_config["adapter"]}'"
end
if ActiveRecord::Base.connection.supports_migrations?
@@ -303,26 +307,24 @@ db_namespace = namespace :db do
# desc "Recreate the databases from the structure.sql file"
task :load => [:environment, :load_config] do
- env = ENV['RAILS_ENV'] || 'test'
-
- abcs = ActiveRecord::Base.configurations
+ current_config = ActiveRecord::Tasks::DatabaseTasks.current_config(:env => (ENV['RAILS_ENV'] || 'test'))
filename = ENV['DB_STRUCTURE'] || File.join(Rails.root, "db", "structure.sql")
- case abcs[env]['adapter']
+ case current_config['adapter']
when /mysql/, /postgresql/, /sqlite/
- ActiveRecord::Tasks::DatabaseTasks.structure_load(abcs[env], filename)
+ ActiveRecord::Tasks::DatabaseTasks.structure_load(current_config, filename)
when 'sqlserver'
- `sqlcmd -S #{abcs[env]['host']} -d #{abcs[env]['database']} -U #{abcs[env]['username']} -P #{abcs[env]['password']} -i #{filename}`
+ `sqlcmd -S #{current_config['host']} -d #{current_config['database']} -U #{current_config['username']} -P #{current_config['password']} -i #{filename}`
when 'oci', 'oracle'
- ActiveRecord::Base.establish_connection(abcs[env])
+ ActiveRecord::Base.establish_connection(current_config)
IO.read(filename).split(";\n\n").each do |ddl|
ActiveRecord::Base.connection.execute(ddl)
end
when 'firebird'
- set_firebird_env(abcs[env])
- db_string = firebird_db_string(abcs[env])
+ set_firebird_env(current_config)
+ db_string = firebird_db_string(current_config)
sh "isql -i #{filename} #{db_string}"
else
- raise "Task not supported by '#{abcs[env]['adapter']}'"
+ raise "Task not supported by '#{current_config['adapter']}'"
end
end
@@ -353,10 +355,10 @@ db_namespace = namespace :db do
# desc "Recreate the test database from an existent structure.sql file"
task :load_structure => 'db:test:purge' do
begin
- old_env, ENV['RAILS_ENV'] = ENV['RAILS_ENV'], 'test'
+ ActiveRecord::Tasks::DatabaseTasks.current_config(:config => ActiveRecord::Base.configurations['test'])
db_namespace["structure:load"].invoke
ensure
- ENV['RAILS_ENV'] = old_env
+ ActiveRecord::Tasks::DatabaseTasks.current_config(:config => nil)
end
end
diff --git a/activerecord/lib/active_record/tasks/database_tasks.rb b/activerecord/lib/active_record/tasks/database_tasks.rb
index b41cc68b6a..fda51b3d76 100644
--- a/activerecord/lib/active_record/tasks/database_tasks.rb
+++ b/activerecord/lib/active_record/tasks/database_tasks.rb
@@ -3,6 +3,8 @@ module ActiveRecord
module DatabaseTasks # :nodoc:
extend self
+ attr_writer :current_config
+
LOCAL_HOSTS = ['127.0.0.1', 'localhost']
def register_task(pattern, task)
@@ -14,6 +16,19 @@ module ActiveRecord
register_task(/postgresql/, ActiveRecord::Tasks::PostgreSQLDatabaseTasks)
register_task(/sqlite/, ActiveRecord::Tasks::SQLiteDatabaseTasks)
+ def current_config(options = {})
+ options.reverse_merge! :env => Rails.env
+ if options.has_key?(:config)
+ @current_config = options[:config]
+ else
+ @current_config ||= if ENV['DATABASE_URL']
+ database_url_config
+ else
+ ActiveRecord::Base.configurations[options[:env]]
+ end
+ end
+ end
+
def create(*arguments)
configuration = arguments.first
class_for_adapter(configuration['adapter']).new(*arguments).create
@@ -33,6 +48,10 @@ module ActiveRecord
ActiveRecord::Base.establish_connection environment
end
+ def create_database_url
+ create database_url_config
+ end
+
def drop(*arguments)
configuration = arguments.first
class_for_adapter(configuration['adapter']).new(*arguments).drop
@@ -51,6 +70,10 @@ module ActiveRecord
}
end
+ def drop_database_url
+ drop database_url_config
+ end
+
def charset_current(environment = Rails.env)
charset ActiveRecord::Base.configurations[environment]
end
@@ -87,6 +110,11 @@ module ActiveRecord
private
+ def database_url_config
+ @database_url_config ||=
+ ConnectionAdapters::ConnectionSpecification::Resolver.new(ENV["DATABASE_URL"], {}).spec.config.stringify_keys
+ end
+
def class_for_adapter(adapter)
key = @tasks.keys.detect { |pattern| adapter[pattern] }
@tasks[key]
diff --git a/activerecord/test/cases/connection_specification/resolver_test.rb b/activerecord/test/cases/connection_specification/resolver_test.rb
index 673a2b2b88..434d2b7ba5 100644
--- a/activerecord/test/cases/connection_specification/resolver_test.rb
+++ b/activerecord/test/cases/connection_specification/resolver_test.rb
@@ -13,7 +13,6 @@ module ActiveRecord
spec = resolve 'mysql://foo?encoding=utf8'
assert_equal({
:adapter => "mysql",
- :database => "",
:host => "foo",
:encoding => "utf8" }, spec)
end
@@ -33,7 +32,6 @@ module ActiveRecord
spec = resolve 'mysql://foo:123?encoding=utf8'
assert_equal({
:adapter => "mysql",
- :database => "",
:port => 123,
:host => "foo",
:encoding => "utf8" }, spec)