diff --git a/railties/lib/rails/commands.rb b/railties/lib/rails/commands.rb index 82cdd6053b8dc5906f58bfa351c21207cf1e29e2..7f473c237c9da95fd604293afc576fb8c3623bf9 100644 --- a/railties/lib/rails/commands.rb +++ b/railties/lib/rails/commands.rb @@ -57,8 +57,7 @@ when 'dbconsole' require 'rails/commands/dbconsole' - require APP_PATH - Rails::DBConsole.start(Rails.application) + Rails::DBConsole.start when 'application', 'runner' require "rails/commands/#{command}" diff --git a/railties/lib/rails/commands/dbconsole.rb b/railties/lib/rails/commands/dbconsole.rb index 25a8caeec3153caf4966aa13f30f3bd4de75a164..aaba47117f30c43b0e567ec1e343b08dbe587878 100644 --- a/railties/lib/rails/commands/dbconsole.rb +++ b/railties/lib/rails/commands/dbconsole.rb @@ -5,15 +5,37 @@ module Rails class DBConsole - attr_reader :arguments + attr_reader :arguments, :config - def self.start(app) - new(app).start + def self.start + new(config).start end - def initialize(app, arguments = ARGV) - @app = app - @arguments = arguments + def self.config + config = begin + YAML.load(ERB.new(IO.read("config/database.yml")).result) + rescue SyntaxError, StandardError + require APP_PATH + Rails.application.config.database_configuration + end + + unless config[env] + abort "No database is configured for the environment '#{env}'" + end + + config[env] + end + + def self.env + if Rails.respond_to?(:env) + Rails.env + else + ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development" + end + end + + def initialize(config, arguments = ARGV) + @config, @arguments = config, arguments end def start @@ -38,10 +60,6 @@ def start abort opt.to_s unless (0..1).include?(arguments.size) end - unless config = @app.config.database_configuration[Rails.env] - abort "No database is configured for the environment '#{Rails.env}'" - end - case config["adapter"] when /^mysql/ diff --git a/railties/test/commands/dbconsole_test.rb b/railties/test/commands/dbconsole_test.rb index 0bf417c0145fa98404e9c8e6e58867d8f725765e..5ef7ceef3bff58901b88fe829ff3eb0f4729e9cf 100644 --- a/railties/test/commands/dbconsole_test.rb +++ b/railties/test/commands/dbconsole_test.rb @@ -3,42 +3,70 @@ class Rails::DBConsoleTest < ActiveSupport::TestCase def teardown - %w[PGUSER PGHOST PGPORT PGPASSWORD'].each{|key| ENV.delete(key)} + %w[PGUSER PGHOST PGPORT PGPASSWORD].each{|key| ENV.delete(key)} end - def test_no_database_configured - start [], false + def test_config + Rails::DBConsole.const_set(:APP_PATH, "erb") + + app_config({}) + capture_abort { Rails::DBConsole.config } assert aborted assert_match /No database is configured for the environment '\w+'/, output + + app_config(development: "with_init") + assert_equal Rails::DBConsole.config, "with_init" + + app_db_file("development:\n without_init") + assert_equal Rails::DBConsole.config, "without_init" + + app_db_file("development:\n <%= Rails.something_app_specific %>") + assert_equal Rails::DBConsole.config, "with_init" + + app_db_file("development:\n\ninvalid") + assert_equal Rails::DBConsole.config, "with_init" + end + + def test_env + assert_equal Rails::DBConsole.env, "development" + + Rails.stubs(:respond_to?).with(:env).returns(false) + assert_equal Rails::DBConsole.env, "development" + + ENV['RACK_ENV'] = "rack_env" + assert_equal Rails::DBConsole.env, "rack_env" + + ENV['RAILS_ENV'] = "rails_env" + assert_equal Rails::DBConsole.env, "rails_env" end def test_mysql dbconsole.expects(:find_cmd_and_exec).with(%w[mysql mysql5], 'db') - start [], {adapter: 'mysql', database: 'db'} + start(adapter: 'mysql', database: 'db') assert !aborted end def test_mysql_full dbconsole.expects(:find_cmd_and_exec).with(%w[mysql mysql5], '--host=locahost', '--port=1234', '--socket=socket', '--user=user', '--default-character-set=UTF-8', '-p', 'db') - start [], {adapter: 'mysql', database: 'db', host: 'locahost', port: 1234, socket: 'socket', username: 'user', password: 'qwerty', encoding: 'UTF-8'} + start(adapter: 'mysql', database: 'db', host: 'locahost', port: 1234, socket: 'socket', username: 'user', password: 'qwerty', encoding: 'UTF-8') assert !aborted end def test_mysql_include_password dbconsole.expects(:find_cmd_and_exec).with(%w[mysql mysql5], '--user=user', '--password=qwerty', 'db') - start ['-p'], {adapter: 'mysql', database: 'db', username: 'user', password: 'qwerty'} + start({adapter: 'mysql', database: 'db', username: 'user', password: 'qwerty'}, ['-p']) assert !aborted end def test_postgresql dbconsole.expects(:find_cmd_and_exec).with('psql', 'db') - start [], {adapter: 'postgresql', database: 'db'} + start(adapter: 'postgresql', database: 'db') assert !aborted end def test_postgresql_full dbconsole.expects(:find_cmd_and_exec).with('psql', 'db') - start [], {adapter: 'postgresql', database: 'db', username: 'user', password: 'q1w2e3', host: 'host', port: 5432} + start(adapter: 'postgresql', database: 'db', username: 'user', password: 'q1w2e3', host: 'host', port: 5432) assert !aborted assert_equal 'user', ENV['PGUSER'] assert_equal 'host', ENV['PGHOST'] @@ -48,7 +76,7 @@ def test_postgresql_full def test_postgresql_include_password dbconsole.expects(:find_cmd_and_exec).with('psql', 'db') - start ['-p'], {adapter: 'postgresql', database: 'db', username: 'user', password: 'q1w2e3'} + start({adapter: 'postgresql', database: 'db', username: 'user', password: 'q1w2e3'}, ['-p']) assert !aborted assert_equal 'user', ENV['PGUSER'] assert_equal 'q1w2e3', ENV['PGPASSWORD'] @@ -56,42 +84,42 @@ def test_postgresql_include_password def test_sqlite dbconsole.expects(:find_cmd_and_exec).with('sqlite', 'db') - start [], {adapter: 'sqlite', database: 'db'} + start(adapter: 'sqlite', database: 'db') assert !aborted end def test_sqlite3 dbconsole.expects(:find_cmd_and_exec).with('sqlite3', 'db') - start [], {adapter: 'sqlite3', database: 'db'} + start(adapter: 'sqlite3', database: 'db') assert !aborted end def test_sqlite3_mode dbconsole.expects(:find_cmd_and_exec).with('sqlite3', '-html', 'db') - start ['--mode', 'html'], {adapter: 'sqlite3', database: 'db'} + start({adapter: 'sqlite3', database: 'db'}, ['--mode', 'html']) assert !aborted end def test_sqlite3_header dbconsole.expects(:find_cmd_and_exec).with('sqlite3', '-header', 'db') - start ['--header'], {adapter: 'sqlite3', database: 'db'} + start({adapter: 'sqlite3', database: 'db'}, ['--header']) assert !aborted end def test_oracle dbconsole.expects(:find_cmd_and_exec).with('sqlplus', 'user@db') - start [], {adapter: 'oracle', database: 'db', username: 'user', password: 'secret'} + start(adapter: 'oracle', database: 'db', username: 'user', password: 'secret') assert !aborted end def test_oracle_include_password dbconsole.expects(:find_cmd_and_exec).with('sqlplus', 'user/secret@db') - start ['-p'], {adapter: 'oracle', database: 'db', username: 'user', password: 'secret'} + start({adapter: 'oracle', database: 'db', username: 'user', password: 'secret'}, ['-p']) assert !aborted end def test_unknown_command_line_client - start [], {adapter: 'unknown', database: 'db'} + start(adapter: 'unknown', database: 'db') assert aborted assert_match /Unknown command-line client for db/, output end @@ -100,29 +128,30 @@ def test_unknown_command_line_client attr_reader :aborted, :output def dbconsole - @dbconsole ||= Rails::DBConsole.new(app) + @dbconsole ||= Rails::DBConsole.new(nil) end - def start(argv = [], database_configuration = {}) - dbconsole.stubs(arguments: argv) - app.config.stubs(database_configuration: { - Rails.env => database_configuration ? database_configuration.stringify_keys : database_configuration - }) + def start(config = {}, argv = []) + dbconsole.stubs(config: config.stringify_keys, arguments: argv) + capture_abort { dbconsole.start } + end + def capture_abort @aborted = false @output = capture(:stderr) do begin - dbconsole.start + yield rescue SystemExit @aborted = true end end end - def app - @app ||= begin - config = mock("config") - stub("app", config: config) - end + def app_db_file(result) + IO.stubs(:read).with("config/database.yml").returns(result) + end + + def app_config(result) + Rails.application.config.stubs(:database_configuration).returns(result.stringify_keys) end end