Skip to content
This repository

fixed support for DATABASE_URL for rake db tasks #8009

Closed
wants to merge 1 commit into from

3 participants

graceliu Rafael Mendonça França Steve Klabnik
graceliu

This is the backport for issue 7521.

  • 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).
  • updated ResolverTest to use current_adapter? to check the type of the current adapter.

(note: this backport is slightly different from master due to update to ResolverTest to make sure the tests get run when the adapter is mysql.)

graceliu fixed support for DATABASE_URL for rake db tasks
backport for #7521
- 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).
- updated ResolverTest to use current_adapter? to check the type of
  the current adapter.
24553b0
Rafael Mendonça França
Owner

Cool. Thank you so much. I'll review this one today.

Rafael Mendonça França rafaelfranca commented on the diff October 26, 2012
activerecord/lib/active_record/railties/databases.rake
@@ -377,25 +398,25 @@ db_namespace = namespace :db do
377 398
   namespace :structure do
378 399
     desc 'Dump the database structure to db/structure.sql. Specify another file with DB_STRUCTURE=db/my_structure.sql'
379 400
     task :dump => [:environment, :load_config] do
380  
-      abcs = ActiveRecord::Base.configurations
  401
+      current_config = current_config()
2
Rafael Mendonça França Owner

I think is better to use a different name instead use ()

Steve Klabnik Collaborator

Yeah, even just config = current_config would be fine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Rafael Mendonça França
Owner

Awesome job. I did a minor comment but the pull request is fine :heart:

Please fix it that I will merge.

Rafael Mendonça França rafaelfranca commented on the diff October 26, 2012
activerecord/lib/active_record/railties/databases.rake
@@ -2,6 +2,24 @@ require 'active_support/core_ext/object/inclusion'
2 2
 require 'active_record'
3 3
 
4 4
 db_namespace = namespace :db do
  5
+  def database_url_config
  6
+    @database_url_config ||=
  7
+        ActiveRecord::Base::ConnectionSpecification::Resolver.new(ENV["DATABASE_URL"], {}).spec.config.stringify_keys
  8
+  end
  9
+
  10
+  def current_config(options = {})
  11
+    options.reverse_merge! :env => Rails.env
1
Rafael Mendonça França Owner

Please change to

{ :env => Rails.env }.merge! options
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Rafael Mendonça França rafaelfranca commented on the diff October 26, 2012
activerecord/lib/active_record/railties/databases.rake
@@ -2,6 +2,24 @@ require 'active_support/core_ext/object/inclusion'
2 2
 require 'active_record'
3 3
 
4 4
 db_namespace = namespace :db do
  5
+  def database_url_config
  6
+    @database_url_config ||=
  7
+        ActiveRecord::Base::ConnectionSpecification::Resolver.new(ENV["DATABASE_URL"], {}).spec.config.stringify_keys
  8
+  end
  9
+
  10
+  def current_config(options = {})
  11
+    options.reverse_merge! :env => Rails.env
  12
+    if options.has_key?(:config)
2
Rafael Mendonça França Owner

Put a blank line above

Rafael Mendonça França Owner

Can not we use?

if options[:config]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Rafael Mendonça França rafaelfranca commented on the diff October 26, 2012
railties/test/application/initializers/frameworks_test.rb
@@ -193,5 +193,37 @@ def from_bar_helper
193 193
       require "#{app_path}/config/environment"
194 194
       assert_nil defined?(ActiveRecord::Base)
195 195
     end
  196
+
  197
+    test "active record establish_connection uses Rails.env if DATABASE_URL is not set" do
  198
+      begin
  199
+        require "#{app_path}/config/environment"
  200
+          orig_database_url = ENV.delete("DATABASE_URL")
1
Rafael Mendonça França Owner

Fix the indentation

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Rafael Mendonça França rafaelfranca commented on the diff October 26, 2012
railties/test/application/initializers/frameworks_test.rb
@@ -193,5 +193,37 @@ def from_bar_helper
193 193
       require "#{app_path}/config/environment"
194 194
       assert_nil defined?(ActiveRecord::Base)
195 195
     end
  196
+
  197
+    test "active record establish_connection uses Rails.env if DATABASE_URL is not set" do
  198
+      begin
  199
+        require "#{app_path}/config/environment"
  200
+          orig_database_url = ENV.delete("DATABASE_URL")
  201
+          orig_rails_env, Rails.env = Rails.env, 'development'
1
Rafael Mendonça França Owner

put a blank line bellow

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Rafael Mendonça França rafaelfranca commented on the diff October 26, 2012
railties/test/application/initializers/frameworks_test.rb
@@ -193,5 +193,37 @@ def from_bar_helper
193 193
       require "#{app_path}/config/environment"
194 194
       assert_nil defined?(ActiveRecord::Base)
195 195
     end
  196
+
  197
+    test "active record establish_connection uses Rails.env if DATABASE_URL is not set" do
  198
+      begin
  199
+        require "#{app_path}/config/environment"
  200
+          orig_database_url = ENV.delete("DATABASE_URL")
  201
+          orig_rails_env, Rails.env = Rails.env, 'development'
  202
+        ActiveRecord::Base.establish_connection
  203
+        assert ActiveRecord::Base.connection
1
Rafael Mendonça França Owner

put a blank line above

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Rafael Mendonça França rafaelfranca commented on the diff October 26, 2012
railties/test/application/initializers/frameworks_test.rb
((12 lines not shown))
  204
+        assert_match /#{ActiveRecord::Base.configurations[Rails.env]['database']}/, ActiveRecord::Base.connection_config[:database]
  205
+      ensure
  206
+        ActiveRecord::Base.remove_connection
  207
+        ENV["DATABASE_URL"] = orig_database_url if orig_database_url
  208
+        Rails.env = orig_rails_env if orig_rails_env
  209
+      end
  210
+    end
  211
+
  212
+    test "active record establish_connection uses DATABASE_URL even if Rails.env is set" do
  213
+      begin
  214
+        require "#{app_path}/config/environment"
  215
+        orig_database_url = ENV.delete("DATABASE_URL")
  216
+        orig_rails_env, Rails.env = Rails.env, 'development'
  217
+        database_url_db_name = "db/database_url_db.sqlite3"
  218
+        ENV["DATABASE_URL"] = "sqlite3://:@localhost/#{database_url_db_name}"
  219
+        ActiveRecord::Base.establish_connection
1
Rafael Mendonça França Owner

put a blank line above

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Rafael Mendonça França rafaelfranca commented on the diff October 26, 2012
railties/test/application/initializers/frameworks_test.rb
((13 lines not shown))
  205
+      ensure
  206
+        ActiveRecord::Base.remove_connection
  207
+        ENV["DATABASE_URL"] = orig_database_url if orig_database_url
  208
+        Rails.env = orig_rails_env if orig_rails_env
  209
+      end
  210
+    end
  211
+
  212
+    test "active record establish_connection uses DATABASE_URL even if Rails.env is set" do
  213
+      begin
  214
+        require "#{app_path}/config/environment"
  215
+        orig_database_url = ENV.delete("DATABASE_URL")
  216
+        orig_rails_env, Rails.env = Rails.env, 'development'
  217
+        database_url_db_name = "db/database_url_db.sqlite3"
  218
+        ENV["DATABASE_URL"] = "sqlite3://:@localhost/#{database_url_db_name}"
  219
+        ActiveRecord::Base.establish_connection
  220
+        assert ActiveRecord::Base.connection
1
Rafael Mendonça França Owner

put a blank line above

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Rafael Mendonça França rafaelfranca commented on the diff October 26, 2012
railties/CHANGELOG.md
... ...
@@ -1,5 +1,6 @@
1 1
 ## Rails 3.2.9 (unreleased)
2 2
 
  3
+*   Fixed support for DATABASE_URL environment variable for rake db tasks. *Grace Liu*
1
Rafael Mendonça França Owner

This should be in the Active Record CHANGELOG

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Rafael Mendonça França
Owner

I did the changes and merged @ e6b4184.

But was not in time to 3.2.9. :cry: Sorry

Rafael Mendonça França rafaelfranca closed this October 29, 2012
graceliu
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Showing 1 unique commit by 1 author.

Oct 22, 2012
graceliu fixed support for DATABASE_URL for rake db tasks
backport for #7521
- 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).
- updated ResolverTest to use current_adapter? to check the type of
  the current adapter.
24553b0
This page is out of date. Refresh to see the latest.
2  activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb
@@ -67,7 +67,7 @@ def connection_url_to_hash(url) # :nodoc:
67 67
                    :port     => config.port,
68 68
                    :database => config.path.sub(%r{^/},""),
69 69
                    :host     => config.host }
70  
-          spec.reject!{ |_,value| !value }
  70
+          spec.reject!{ |_,value| value.blank? }
71 71
           if config.query
72 72
             options = Hash[config.query.split("&").map{ |pair| pair.split("=") }].symbolize_keys
73 73
             spec.merge!(options)
87  activerecord/lib/active_record/railties/databases.rake
@@ -2,6 +2,24 @@ require 'active_support/core_ext/object/inclusion'
2 2
 require 'active_record'
3 3
 
4 4
 db_namespace = namespace :db do
  5
+  def database_url_config
  6
+    @database_url_config ||=
  7
+        ActiveRecord::Base::ConnectionSpecification::Resolver.new(ENV["DATABASE_URL"], {}).spec.config.stringify_keys
  8
+  end
  9
+
  10
+  def current_config(options = {})
  11
+    options.reverse_merge! :env => Rails.env
  12
+    if options.has_key?(:config)
  13
+      @current_config = options[:config]
  14
+    else
  15
+      @current_config ||= if ENV['DATABASE_URL']
  16
+                            database_url_config
  17
+                          else
  18
+                            ActiveRecord::Base.configurations[options[:env]]
  19
+                          end
  20
+    end
  21
+  end
  22
+
5 23
   task :load_config do
6 24
     ActiveRecord::Base.configurations = Rails.application.config.database_configuration
7 25
     ActiveRecord::Migrator.migrations_paths = Rails.application.paths['db/migrate'].to_a
@@ -35,10 +53,14 @@ db_namespace = namespace :db do
35 53
     end
36 54
   end
37 55
 
38  
-  desc 'Create the database from config/database.yml for the current Rails.env (use db:create:all to create all dbs in the config)'
  56
+  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)'
39 57
   task :create => [:load_config, :rails_env] do
40  
-    configs_for_environment.each { |config| create_database(config) }
41  
-    ActiveRecord::Base.establish_connection(configs_for_environment.first)
  58
+    if ENV['DATABASE_URL']
  59
+      create_database(database_url_config)
  60
+    else
  61
+      configs_for_environment.each { |config| create_database(config) }
  62
+      ActiveRecord::Base.establish_connection(configs_for_environment.first)
  63
+    end
42 64
   end
43 65
 
44 66
   def mysql_creation_options(config)
@@ -133,9 +155,13 @@ db_namespace = namespace :db do
133 155
     end
134 156
   end
135 157
 
136  
-  desc 'Drops the database for the current Rails.env (use db:drop:all to drop all databases)'
  158
+  desc 'Drops the database using DATABASE_URL or the current Rails.env (use db:drop:all to drop all databases)'
137 159
   task :drop => [:load_config, :rails_env] do
138  
-    configs_for_environment.each { |config| drop_database_and_rescue(config) }
  160
+    if ENV['DATABASE_URL']
  161
+      drop_database_and_rescue(database_url_config)
  162
+    else
  163
+      configs_for_environment.each { |config| drop_database_and_rescue(config) }
  164
+    end
139 165
   end
140 166
 
141 167
   def local_database?(config, &block)
@@ -146,7 +172,6 @@ db_namespace = namespace :db do
146 172
     end
147 173
   end
148 174
 
149  
-
150 175
   desc "Migrate the database (options: VERSION=x, VERBOSE=false)."
151 176
   task :migrate => [:environment, :load_config] do
152 177
     ActiveRecord::Migration.verbose = ENV["VERBOSE"] ? ENV["VERBOSE"] == "true" : true
@@ -201,8 +226,6 @@ db_namespace = namespace :db do
201 226
 
202 227
     desc 'Display status of migrations'
203 228
     task :status => [:environment, :load_config] do
204  
-      config = ActiveRecord::Base.configurations[Rails.env]
205  
-      ActiveRecord::Base.establish_connection(config)
206 229
       unless ActiveRecord::Base.connection.table_exists?(ActiveRecord::Migrator.schema_migrations_table_name)
207 230
         puts 'Schema migrations table does not exist yet.'
208 231
         next  # means "return" for rake task
@@ -222,7 +245,7 @@ db_namespace = namespace :db do
222 245
         ['up', version, '********** NO FILE **********']
223 246
       end
224 247
       # output
225  
-      puts "\ndatabase: #{config['database']}\n\n"
  248
+      puts "\ndatabase: #{ActiveRecord::Base.connection_config[:database]}\n\n"
226 249
       puts "#{'Status'.center(8)}  #{'Migration ID'.ljust(14)}  Migration Name"
227 250
       puts "-" * 50
228 251
       (db_list + file_list).sort_by {|migration| migration[1]}.each do |migration|
@@ -314,7 +337,6 @@ db_namespace = namespace :db do
314 337
     task :load => [:environment, :load_config] do
315 338
       require 'active_record/fixtures'
316 339
 
317  
-      ActiveRecord::Base.establish_connection(Rails.env)
318 340
       base_dir     = File.join [Rails.root, ENV['FIXTURES_PATH'] || %w{test fixtures}].flatten
319 341
       fixtures_dir = File.join [base_dir, ENV['FIXTURES_DIR']].compact
320 342
 
@@ -353,7 +375,6 @@ db_namespace = namespace :db do
353 375
       require 'active_record/schema_dumper'
354 376
       filename = ENV['SCHEMA'] || "#{Rails.root}/db/schema.rb"
355 377
       File.open(filename, "w:utf-8") do |file|
356  
-        ActiveRecord::Base.establish_connection(Rails.env)
357 378
         ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, file)
358 379
       end
359 380
       db_namespace['schema:dump'].reenable
@@ -377,25 +398,25 @@ db_namespace = namespace :db do
377 398
   namespace :structure do
378 399
     desc 'Dump the database structure to db/structure.sql. Specify another file with DB_STRUCTURE=db/my_structure.sql'
379 400
     task :dump => [:environment, :load_config] do
380  
-      abcs = ActiveRecord::Base.configurations
  401
+      current_config = current_config()
381 402
       filename = ENV['DB_STRUCTURE'] || File.join(Rails.root, "db", "structure.sql")
382  
-      case abcs[Rails.env]['adapter']
  403
+      case current_config['adapter']
383 404
       when /mysql/, 'oci', 'oracle'
384  
-        ActiveRecord::Base.establish_connection(abcs[Rails.env])
  405
+        ActiveRecord::Base.establish_connection(current_config)
385 406
         File.open(filename, "w:utf-8") { |f| f << ActiveRecord::Base.connection.structure_dump }
386 407
       when /postgresql/
387  
-        set_psql_env(abcs[Rails.env])
388  
-        search_path = abcs[Rails.env]['schema_search_path']
  408
+        set_psql_env(current_config)
  409
+        search_path = current_config['schema_search_path']
389 410
         unless search_path.blank?
390 411
           search_path = search_path.split(",").map{|search_path_part| "--schema=#{Shellwords.escape(search_path_part.strip)}" }.join(" ")
391 412
         end
392  
-        `pg_dump -i -s -x -O -f #{Shellwords.escape(filename)} #{search_path} #{Shellwords.escape(abcs[Rails.env]['database'])}`
  413
+        `pg_dump -i -s -x -O -f #{Shellwords.escape(filename)} #{search_path} #{Shellwords.escape(current_config['database'])}`
393 414
         raise 'Error dumping database' if $?.exitstatus == 1
394 415
       when /sqlite/
395  
-        dbfile = abcs[Rails.env]['database']
  416
+        dbfile = current_config['database']
396 417
         `sqlite3 #{dbfile} .schema > #{filename}`
397 418
       when 'sqlserver'
398  
-        `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`
  419
+        `smoscript -s #{current_config['host']} -d #{current_config['database']} -u #{current_config['username']} -p #{current_config['password']} -f #{filename} -A -U`
399 420
       when "firebird"
400 421
         set_firebird_env(abcs[Rails.env])
401 422
         db_string = firebird_db_string(abcs[Rails.env])
@@ -412,36 +433,34 @@ db_namespace = namespace :db do
412 433
 
413 434
     # desc "Recreate the databases from the structure.sql file"
414 435
     task :load => [:environment, :load_config] do
415  
-      env = Rails.env
416  
-
417  
-      abcs = ActiveRecord::Base.configurations
  436
+      current_config = current_config()
418 437
       filename = ENV['DB_STRUCTURE'] || File.join(Rails.root, "db", "structure.sql")
419  
-      case abcs[env]['adapter']
  438
+      case current_config['adapter']
420 439
       when /mysql/
421  
-        ActiveRecord::Base.establish_connection(abcs[env])
  440
+        ActiveRecord::Base.establish_connection(current_config)
422 441
         ActiveRecord::Base.connection.execute('SET foreign_key_checks = 0')
423 442
         IO.read(filename).split("\n\n").each do |table|
424 443
           ActiveRecord::Base.connection.execute(table)
425 444
         end
426 445
       when /postgresql/
427  
-        set_psql_env(abcs[env])
428  
-        `psql -f "#{filename}" #{abcs[env]['database']}`
  446
+        set_psql_env(current_config)
  447
+        `psql -f "#{filename}" #{current_config['database']}`
429 448
       when /sqlite/
430  
-        dbfile = abcs[env]['database']
  449
+        dbfile = current_config['database']
431 450
         `sqlite3 #{dbfile} < "#{filename}"`
432 451
       when 'sqlserver'
433  
-        `sqlcmd -S #{abcs[env]['host']} -d #{abcs[env]['database']} -U #{abcs[env]['username']} -P #{abcs[env]['password']} -i #{filename}`
  452
+        `sqlcmd -S #{current_config['host']} -d #{current_config['database']} -U #{current_config['username']} -P #{current_config['password']} -i #{filename}`
434 453
       when 'oci', 'oracle'
435  
-        ActiveRecord::Base.establish_connection(abcs[env])
  454
+        ActiveRecord::Base.establish_connection(current_config)
436 455
         IO.read(filename).split(";\n\n").each do |ddl|
437 456
           ActiveRecord::Base.connection.execute(ddl)
438 457
         end
439 458
       when 'firebird'
440  
-        set_firebird_env(abcs[env])
441  
-        db_string = firebird_db_string(abcs[env])
  459
+        set_firebird_env(current_config)
  460
+        db_string = firebird_db_string(current_config)
442 461
         sh "isql -i #{filename} #{db_string}"
443 462
       else
444  
-        raise "Task not supported by '#{abcs[env]['adapter']}'"
  463
+        raise "Task not supported by '#{current_config['adapter']}'"
445 464
       end
446 465
     end
447 466
 
@@ -465,10 +484,10 @@ db_namespace = namespace :db do
465 484
     # desc "Recreate the test database from an existent structure.sql file"
466 485
     task :load_structure => 'db:test:purge' do
467 486
       begin
468  
-        old_env, ENV['RAILS_ENV'] = ENV['RAILS_ENV'], 'test'
  487
+        current_config(:config => ActiveRecord::Base.configurations['test'])
469 488
         db_namespace["structure:load"].invoke
470 489
       ensure
471  
-        ENV['RAILS_ENV'] = old_env
  490
+        current_config(:config => nil)
472 491
       end
473 492
     end
474 493
 
8  activerecord/test/cases/connection_specification/resolver_test.rb
@@ -9,17 +9,16 @@ def resolve(spec)
9 9
         end
10 10
 
11 11
         def test_url_host_no_db
12  
-          skip "only if mysql is available" unless defined?(MysqlAdapter)
  12
+          skip "only if mysql is available" unless current_adapter?(:MysqlAdapter)
13 13
           spec = resolve 'mysql://foo?encoding=utf8'
14 14
           assert_equal({
15 15
             :adapter  => "mysql",
16  
-            :database => "",
17 16
             :host     => "foo",
18 17
             :encoding => "utf8" }, spec)
19 18
         end
20 19
 
21 20
         def test_url_host_db
22  
-          skip "only if mysql is available" unless defined?(MysqlAdapter)
  21
+          skip "only if mysql is available" unless current_adapter?(:MysqlAdapter)
23 22
           spec = resolve 'mysql://foo/bar?encoding=utf8'
24 23
           assert_equal({
25 24
             :adapter  => "mysql",
@@ -29,11 +28,10 @@ def test_url_host_db
29 28
         end
30 29
 
31 30
         def test_url_port
32  
-          skip "only if mysql is available" unless defined?(MysqlAdapter)
  31
+          skip "only if mysql is available" unless current_adapter?(:MysqlAdapter)
33 32
           spec = resolve 'mysql://foo:123?encoding=utf8'
34 33
           assert_equal({
35 34
             :adapter  => "mysql",
36  
-            :database => "",
37 35
             :port     => 123,
38 36
             :host     => "foo",
39 37
             :encoding => "utf8" }, spec)
1  railties/CHANGELOG.md
Source Rendered
... ...
@@ -1,5 +1,6 @@
1 1
 ## Rails 3.2.9 (unreleased)
2 2
 
  3
+*   Fixed support for DATABASE_URL environment variable for rake db tasks. *Grace Liu*
3 4
 *   Update supported ruby versions error message in ruby_version_check.rb *Lihan Li*
4 5
 
5 6
 ## Rails 3.2.8 (Aug 9, 2012) ##
32  railties/test/application/initializers/frameworks_test.rb
@@ -193,5 +193,37 @@ def from_bar_helper
193 193
       require "#{app_path}/config/environment"
194 194
       assert_nil defined?(ActiveRecord::Base)
195 195
     end
  196
+
  197
+    test "active record establish_connection uses Rails.env if DATABASE_URL is not set" do
  198
+      begin
  199
+        require "#{app_path}/config/environment"
  200
+          orig_database_url = ENV.delete("DATABASE_URL")
  201
+          orig_rails_env, Rails.env = Rails.env, 'development'
  202
+        ActiveRecord::Base.establish_connection
  203
+        assert ActiveRecord::Base.connection
  204
+        assert_match /#{ActiveRecord::Base.configurations[Rails.env]['database']}/, ActiveRecord::Base.connection_config[:database]
  205
+      ensure
  206
+        ActiveRecord::Base.remove_connection
  207
+        ENV["DATABASE_URL"] = orig_database_url if orig_database_url
  208
+        Rails.env = orig_rails_env if orig_rails_env
  209
+      end
  210
+    end
  211
+
  212
+    test "active record establish_connection uses DATABASE_URL even if Rails.env is set" do
  213
+      begin
  214
+        require "#{app_path}/config/environment"
  215
+        orig_database_url = ENV.delete("DATABASE_URL")
  216
+        orig_rails_env, Rails.env = Rails.env, 'development'
  217
+        database_url_db_name = "db/database_url_db.sqlite3"
  218
+        ENV["DATABASE_URL"] = "sqlite3://:@localhost/#{database_url_db_name}"
  219
+        ActiveRecord::Base.establish_connection
  220
+        assert ActiveRecord::Base.connection
  221
+        assert_match /#{database_url_db_name}/, ActiveRecord::Base.connection_config[:database]
  222
+      ensure
  223
+        ActiveRecord::Base.remove_connection
  224
+        ENV["DATABASE_URL"] = orig_database_url if orig_database_url
  225
+        Rails.env = orig_rails_env if orig_rails_env
  226
+      end
  227
+    end
196 228
   end
197 229
 end
182  railties/test/application/rake/dbs_test.rb
... ...
@@ -0,0 +1,182 @@
  1
+require "isolation/abstract_unit"
  2
+
  3
+module ApplicationTests
  4
+  module RakeTests
  5
+    class RakeDbsTest < Test::Unit::TestCase
  6
+      include ActiveSupport::Testing::Isolation
  7
+
  8
+      def setup
  9
+        build_app
  10
+        boot_rails
  11
+        FileUtils.rm_rf("#{app_path}/config/environments")
  12
+      end
  13
+
  14
+      def teardown
  15
+        teardown_app
  16
+      end
  17
+
  18
+      def database_url_db_name
  19
+        "db/database_url_db.sqlite3"
  20
+      end
  21
+
  22
+      def set_database_url
  23
+        ENV['DATABASE_URL'] = "sqlite3://:@localhost/#{database_url_db_name}"
  24
+      end
  25
+
  26
+      def expected
  27
+        @expected ||= {}
  28
+      end
  29
+
  30
+      def db_create_and_drop
  31
+        Dir.chdir(app_path) do
  32
+          output = `bundle exec rake db:create`
  33
+          assert_equal output, ""
  34
+          assert File.exists?(expected[:database])
  35
+          assert_equal expected[:database],
  36
+                        ActiveRecord::Base.connection_config[:database]
  37
+          output = `bundle exec rake db:drop`
  38
+          assert_equal output, ""
  39
+          assert !File.exists?(expected[:database])
  40
+        end
  41
+      end
  42
+
  43
+      test 'db:create and db:drop without database url' do
  44
+        require "#{app_path}/config/environment"
  45
+        expected[:database] = ActiveRecord::Base.configurations[Rails.env]['database']
  46
+        db_create_and_drop
  47
+      end
  48
+
  49
+      test 'db:create and db:drop with database url' do
  50
+        require "#{app_path}/config/environment"
  51
+        set_database_url
  52
+        expected[:database] = database_url_db_name
  53
+        db_create_and_drop
  54
+      end
  55
+
  56
+      def db_migrate_and_status
  57
+        Dir.chdir(app_path) do
  58
+          `rails generate model book title:string`
  59
+          `bundle exec rake db:migrate`
  60
+          output = `bundle exec rake db:migrate:status`
  61
+          assert_match(/database:\s+\S*#{expected[:database]}/, output)
  62
+          assert_match(/up\s+\d{14}\s+Create books/, output)
  63
+        end
  64
+      end
  65
+
  66
+      test 'db:migrate and db:migrate:status without database_url' do
  67
+        require "#{app_path}/config/environment"
  68
+        expected[:database] = ActiveRecord::Base.configurations[Rails.env]['database']
  69
+        db_migrate_and_status
  70
+      end
  71
+
  72
+      test 'db:migrate and db:migrate:status with database_url' do
  73
+        require "#{app_path}/config/environment"
  74
+        set_database_url
  75
+        expected[:database] = database_url_db_name
  76
+        db_migrate_and_status
  77
+      end
  78
+
  79
+      def db_schema_dump
  80
+        Dir.chdir(app_path) do
  81
+          `rails generate model book title:string`
  82
+          `rake db:migrate`
  83
+          `rake db:schema:dump`
  84
+          schema_dump = File.read("db/schema.rb")
  85
+          assert_match(/create_table \"books\"/, schema_dump)
  86
+        end
  87
+      end
  88
+
  89
+      test 'db:schema:dump without database_url' do
  90
+        db_schema_dump
  91
+      end
  92
+
  93
+      test 'db:schema:dump with database_url' do
  94
+        set_database_url
  95
+        db_schema_dump
  96
+      end
  97
+
  98
+      def db_fixtures_load
  99
+        Dir.chdir(app_path) do
  100
+          `rails generate model book title:string`
  101
+          `bundle exec rake db:migrate`
  102
+          `bundle exec rake db:fixtures:load`
  103
+          assert_match /#{expected[:database]}/,
  104
+                    ActiveRecord::Base.connection_config[:database]
  105
+          require "#{app_path}/app/models/book"
  106
+          assert_equal 2, Book.count
  107
+        end
  108
+      end
  109
+
  110
+      test 'db:fixtures:load without database_url' do
  111
+        require "#{app_path}/config/environment"
  112
+        expected[:database] =  ActiveRecord::Base.configurations[Rails.env]['database']
  113
+        db_fixtures_load
  114
+      end
  115
+
  116
+      test 'db:fixtures:load with database_url' do
  117
+        require "#{app_path}/config/environment"
  118
+        set_database_url
  119
+        expected[:database] = database_url_db_name
  120
+        db_fixtures_load
  121
+      end
  122
+
  123
+      def db_structure_dump_and_load
  124
+        Dir.chdir(app_path) do
  125
+          `rails generate model book title:string`
  126
+          `bundle exec rake db:create`
  127
+          `bundle exec rake db:migrate`
  128
+          `bundle exec rake db:structure:dump`
  129
+          structure_dump = File.read("db/structure.sql")
  130
+          assert_match /CREATE TABLE \"books\"/, structure_dump
  131
+          `bundle exec rake db:drop`
  132
+          `bundle exec rake db:structure:load`
  133
+          assert_match /#{expected[:database]}/,
  134
+                       ActiveRecord::Base.connection_config[:database]
  135
+          require "#{app_path}/app/models/book"
  136
+          #if structure is not loaded correctly, exception would be raised
  137
+          assert_equal Book.count, 0
  138
+        end
  139
+      end
  140
+
  141
+      test 'db:structure:dump and db:structure:load without database_url' do
  142
+        require "#{app_path}/config/environment"
  143
+        expected[:database] =  ActiveRecord::Base.configurations[Rails.env]['database']
  144
+        db_structure_dump_and_load
  145
+      end
  146
+
  147
+      test 'db:structure:dump and db:structure:load with database_url' do
  148
+        require "#{app_path}/config/environment"
  149
+        set_database_url
  150
+        expected[:database] = database_url_db_name
  151
+        db_structure_dump_and_load
  152
+      end
  153
+
  154
+      def db_test_load_structure
  155
+        Dir.chdir(app_path) do
  156
+          `rails generate model book title:string`
  157
+          `bundle exec rake db:migrate`
  158
+          `bundle exec rake db:structure:dump`
  159
+          `bundle exec rake db:test:load_structure`
  160
+          ActiveRecord::Base.configurations = Rails.application.config.database_configuration
  161
+          ActiveRecord::Base.establish_connection 'test'
  162
+          require "#{app_path}/app/models/book"
  163
+          #if structure is not loaded correctly, exception would be raised
  164
+          assert_equal Book.count, 0
  165
+          assert_match /#{ActiveRecord::Base.configurations['test']['database']}/,
  166
+                       ActiveRecord::Base.connection_config[:database]
  167
+        end
  168
+      end
  169
+
  170
+      test 'db:test:load_structure without database_url' do
  171
+        require "#{app_path}/config/environment"
  172
+        db_test_load_structure
  173
+      end
  174
+
  175
+      test 'db:test:load_structure with database_url' do
  176
+        require "#{app_path}/config/environment"
  177
+        set_database_url
  178
+        db_test_load_structure
  179
+      end
  180
+    end
  181
+  end
  182
+end
Commit_comment_tip

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.