aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--railties/lib/rails/commands/dbconsole.rb56
-rw-r--r--railties/test/commands/dbconsole_test.rb128
2 files changed, 162 insertions, 22 deletions
diff --git a/railties/lib/rails/commands/dbconsole.rb b/railties/lib/rails/commands/dbconsole.rb
index 6fc127efae..25a8caeec3 100644
--- a/railties/lib/rails/commands/dbconsole.rb
+++ b/railties/lib/rails/commands/dbconsole.rb
@@ -5,12 +5,15 @@ require 'rbconfig'
module Rails
class DBConsole
+ attr_reader :arguments
+
def self.start(app)
new(app).start
end
- def initialize(app)
+ def initialize(app, arguments = ARGV)
@app = app
+ @arguments = arguments
end
def start
@@ -31,8 +34,8 @@ module Rails
options['header'] = h
end
- opt.parse!(ARGV)
- abort opt.to_s unless (0..1).include?(ARGV.size)
+ opt.parse!(arguments)
+ abort opt.to_s unless (0..1).include?(arguments.size)
end
unless config = @app.config.database_configuration[Rails.env]
@@ -40,20 +43,6 @@ module Rails
end
- def find_cmd(*commands)
- dirs_on_path = ENV['PATH'].to_s.split(File::PATH_SEPARATOR)
- commands += commands.map{|cmd| "#{cmd}.exe"} if RbConfig::CONFIG['host_os'] =~ /mswin|mingw/
-
- full_path_command = nil
- found = commands.detect do |cmd|
- dir = dirs_on_path.detect do |path|
- full_path_command = File.join(path, cmd)
- File.executable? full_path_command
- end
- end
- found ? full_path_command : abort("Couldn't find database client: #{commands.join(', ')}. Check your $PATH and try again.")
- end
-
case config["adapter"]
when /^mysql/
args = {
@@ -72,17 +61,17 @@ module Rails
args << config['database']
- exec(find_cmd('mysql', 'mysql5'), *args)
+ find_cmd_and_exec(['mysql', 'mysql5'], *args)
when "postgresql", "postgres"
ENV['PGUSER'] = config["username"] if config["username"]
ENV['PGHOST'] = config["host"] if config["host"]
ENV['PGPORT'] = config["port"].to_s if config["port"]
ENV['PGPASSWORD'] = config["password"].to_s if config["password"] && include_password
- exec(find_cmd('psql'), config["database"])
+ find_cmd_and_exec('psql', config["database"])
when "sqlite"
- exec(find_cmd('sqlite'), config["database"])
+ find_cmd_and_exec('sqlite', config["database"])
when "sqlite3"
args = []
@@ -91,7 +80,7 @@ module Rails
args << "-header" if options['header']
args << config['database']
- exec(find_cmd('sqlite3'), *args)
+ find_cmd_and_exec('sqlite3', *args)
when "oracle", "oracle_enhanced"
logon = ""
@@ -102,12 +91,35 @@ module Rails
logon << "@#{config['database']}" if config['database']
end
- exec(find_cmd('sqlplus'), logon)
+ find_cmd_and_exec('sqlplus', logon)
else
abort "Unknown command-line client for #{config['database']}. Submit a Rails patch to add support!"
end
end
+
+ protected
+
+ def find_cmd_and_exec(commands, *args)
+ commands = Array(commands)
+
+ dirs_on_path = ENV['PATH'].to_s.split(File::PATH_SEPARATOR)
+ commands += commands.map{|cmd| "#{cmd}.exe"} if RbConfig::CONFIG['host_os'] =~ /mswin|mingw/
+
+ full_path_command = nil
+ found = commands.detect do |cmd|
+ dir = dirs_on_path.detect do |path|
+ full_path_command = File.join(path, cmd)
+ File.executable? full_path_command
+ end
+ end
+
+ if found
+ exec full_path_command, *args
+ else
+ abort("Couldn't find database client: #{commands.join(', ')}. Check your $PATH and try again.")
+ end
+ end
end
end
diff --git a/railties/test/commands/dbconsole_test.rb b/railties/test/commands/dbconsole_test.rb
new file mode 100644
index 0000000000..0bf417c014
--- /dev/null
+++ b/railties/test/commands/dbconsole_test.rb
@@ -0,0 +1,128 @@
+require 'abstract_unit'
+require 'rails/commands/dbconsole'
+
+class Rails::DBConsoleTest < ActiveSupport::TestCase
+ def teardown
+ %w[PGUSER PGHOST PGPORT PGPASSWORD'].each{|key| ENV.delete(key)}
+ end
+
+ def test_no_database_configured
+ start [], false
+ assert aborted
+ assert_match /No database is configured for the environment '\w+'/, output
+ end
+
+ def test_mysql
+ dbconsole.expects(:find_cmd_and_exec).with(%w[mysql mysql5], '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'}
+ 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'}
+ assert !aborted
+ end
+
+ def test_postgresql
+ dbconsole.expects(:find_cmd_and_exec).with('psql', '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}
+ assert !aborted
+ assert_equal 'user', ENV['PGUSER']
+ assert_equal 'host', ENV['PGHOST']
+ assert_equal '5432', ENV['PGPORT']
+ assert_not_equal 'q1w2e3', ENV['PGPASSWORD']
+ end
+
+ def test_postgresql_include_password
+ dbconsole.expects(:find_cmd_and_exec).with('psql', 'db')
+ start ['-p'], {adapter: 'postgresql', database: 'db', username: 'user', password: 'q1w2e3'}
+ assert !aborted
+ assert_equal 'user', ENV['PGUSER']
+ assert_equal 'q1w2e3', ENV['PGPASSWORD']
+ end
+
+ def test_sqlite
+ dbconsole.expects(:find_cmd_and_exec).with('sqlite', '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'}
+ assert !aborted
+ end
+
+ def test_sqlite3_mode
+ dbconsole.expects(:find_cmd_and_exec).with('sqlite3', '-html', 'db')
+ start ['--mode', 'html'], {adapter: 'sqlite3', database: 'db'}
+ assert !aborted
+ end
+
+ def test_sqlite3_header
+ dbconsole.expects(:find_cmd_and_exec).with('sqlite3', '-header', 'db')
+ start ['--header'], {adapter: 'sqlite3', database: 'db'}
+ 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'}
+ 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'}
+ assert !aborted
+ end
+
+ def test_unknown_command_line_client
+ start [], {adapter: 'unknown', database: 'db'}
+ assert aborted
+ assert_match /Unknown command-line client for db/, output
+ end
+
+ private
+ attr_reader :aborted, :output
+
+ def dbconsole
+ @dbconsole ||= Rails::DBConsole.new(app)
+ 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
+ })
+
+ @aborted = false
+ @output = capture(:stderr) do
+ begin
+ dbconsole.start
+ rescue SystemExit
+ @aborted = true
+ end
+ end
+ end
+
+ def app
+ @app ||= begin
+ config = mock("config")
+ stub("app", config: config)
+ end
+ end
+end