提交 75714082 编写于 作者: J Jon Leighton

Merge pull request #6761 from freelancing-god/db-rake

Get logic out of db rake tasks, and into classes and objects
......@@ -137,6 +137,16 @@ module Scoping
end
end
module Tasks
extend ActiveSupport::Autoload
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
autoload :TestFixtures, 'active_record/fixtures'
end
......
......@@ -14,138 +14,27 @@ db_namespace = namespace :db do
end
namespace :create do
# desc 'Create all the local databases defined in config/database.yml'
task :all => :load_config do
ActiveRecord::Base.configurations.each_value do |config|
# Skip entries that don't have a database key, such as the first entry here:
#
# defaults: &defaults
# adapter: mysql
# username: root
# password:
# host: localhost
#
# development:
# database: blog_development
# *defaults
next unless config['database']
# Only connect to local databases
local_database?(config) { create_database(config) }
end
ActiveRecord::Tasks::DatabaseTasks.create_all
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) }
ActiveRecord::Base.establish_connection(configs_for_environment.first)
end
def mysql_creation_options(config)
@charset = ENV['CHARSET'] || 'utf8'
@collation = ENV['COLLATION'] || 'utf8_unicode_ci'
{:charset => (config['charset'] || @charset), :collation => (config['collation'] || @collation)}
end
def create_database(config)
begin
if config['adapter'] =~ /sqlite/
if File.exist?(config['database'])
$stderr.puts "#{config['database']} already exists"
else
begin
# Create the SQLite database
ActiveRecord::Base.establish_connection(config)
ActiveRecord::Base.connection
rescue Exception => e
$stderr.puts e, *(e.backtrace)
$stderr.puts "Couldn't create database for #{config.inspect}"
end
end
return # Skip the else clause of begin/rescue
else
ActiveRecord::Base.establish_connection(config)
ActiveRecord::Base.connection
end
rescue
case config['adapter']
when /mysql/
if config['adapter'] =~ /jdbc/
#FIXME After Jdbcmysql gives this class
require 'active_record/railties/jdbcmysql_error'
error_class = ArJdbcMySQL::Error
else
error_class = config['adapter'] =~ /mysql2/ ? Mysql2::Error : Mysql::Error
end
access_denied_error = 1045
begin
ActiveRecord::Base.establish_connection(config.merge('database' => nil))
ActiveRecord::Base.connection.create_database(config['database'], mysql_creation_options(config))
ActiveRecord::Base.establish_connection(config)
rescue error_class => sqlerr
if sqlerr.errno == access_denied_error
print "#{sqlerr.error}. \nPlease provide the root password for your mysql installation\n>"
root_password = $stdin.gets.strip
grant_statement = "GRANT ALL PRIVILEGES ON #{config['database']}.* " \
"TO '#{config['username']}'@'localhost' " \
"IDENTIFIED BY '#{config['password']}' WITH GRANT OPTION;"
ActiveRecord::Base.establish_connection(config.merge(
'database' => nil, 'username' => 'root', 'password' => root_password))
ActiveRecord::Base.connection.create_database(config['database'], mysql_creation_options(config))
ActiveRecord::Base.connection.execute grant_statement
ActiveRecord::Base.establish_connection(config)
else
$stderr.puts sqlerr.error
$stderr.puts "Couldn't create database for #{config.inspect}, charset: #{config['charset'] || @charset}, collation: #{config['collation'] || @collation}"
$stderr.puts "(if you set the charset manually, make sure you have a matching collation)" if config['charset']
end
end
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
ActiveRecord::Tasks::DatabaseTasks.create_current
end
namespace :drop do
# desc 'Drops all the local databases defined in config/database.yml'
task :all => :load_config do
ActiveRecord::Base.configurations.each_value do |config|
# Skip entries that don't have a database key
next unless config['database']
begin
# Only connect to local databases
local_database?(config) { drop_database(config) }
rescue Exception => e
$stderr.puts "Couldn't drop #{config['database']} : #{e.inspect}"
end
end
ActiveRecord::Tasks::DatabaseTasks.drop_all
end
end
desc 'Drops the database for the current Rails.env (use db:drop:all to drop all databases)'
task :drop => :load_config do
configs_for_environment.each { |config| drop_database_and_rescue(config) }
end
def local_database?(config, &block)
if config['host'].in?(['127.0.0.1', 'localhost']) || config['host'].blank?
yield
else
$stderr.puts "This task only modifies local databases. #{config['database']} is on a remote host."
end
ActiveRecord::Tasks::DatabaseTasks.drop_current
end
desc "Migrate the database (options: VERSION=x, VERBOSE=false)."
task :migrate => [:environment, :load_config] do
ActiveRecord::Migration.verbose = ENV["VERBOSE"] ? ENV["VERBOSE"] == "true" : true
......@@ -509,16 +398,8 @@ db_namespace = namespace :db do
task :purge => [:environment, :load_config] do
abcs = ActiveRecord::Base.configurations
case abcs['test']['adapter']
when /mysql/
ActiveRecord::Base.establish_connection(:test)
ActiveRecord::Base.connection.recreate_database(abcs['test']['database'], mysql_creation_options(abcs['test']))
when /postgresql/
ActiveRecord::Base.clear_active_connections!
drop_database(abcs['test'])
create_database(abcs['test'])
when /sqlite/
dbfile = abcs['test']['database']
File.delete(dbfile) if File.exist?(dbfile)
when /mysql/, /postgresql/, /sqlite/
ActiveRecord::Tasks::DatabaseTasks.purge abcs['test']
when 'sqlserver'
test = abcs.deep_dup['test']
test_database = test['database']
......@@ -592,37 +473,6 @@ end
task 'test:prepare' => 'db:test:prepare'
def drop_database(config)
case config['adapter']
when /mysql/
ActiveRecord::Base.establish_connection(config)
ActiveRecord::Base.connection.drop_database config['database']
when /sqlite/
require 'pathname'
path = Pathname.new(config['database'])
file = path.absolute? ? path.to_s : File.join(Rails.root, path)
FileUtils.rm(file)
when /postgresql/
ActiveRecord::Base.establish_connection(config.merge('database' => 'postgres', 'schema_search_path' => 'public'))
ActiveRecord::Base.connection.drop_database config['database']
end
end
def drop_database_and_rescue(config)
begin
drop_database(config)
rescue Exception => e
$stderr.puts "Couldn't drop #{config['database']} : #{e.inspect}"
end
end
def configs_for_environment
environments = [Rails.env]
environments << 'test' if Rails.env.development?
ActiveRecord::Base.configurations.values_at(*environments).compact.reject { |config| config['database'].blank? }
end
def session_table_name
ActiveRecord::SessionStore::Session.table_name
end
......
class ActiveRecord::Tasks::DatabaseTasks
TASKS_PATTERNS = {
/mysql/ => ActiveRecord::Tasks::MySQLDatabaseTasks,
/postgresql/ => ActiveRecord::Tasks::PostgreSQLDatabaseTasks,
/sqlite/ => ActiveRecord::Tasks::SQLiteDatabaseTasks
}
LOCAL_HOSTS = ['127.0.0.1', 'localhost']
def self.create(*arguments)
configuration = arguments.first
class_for_adapter(configuration['adapter']).new(*arguments).create
rescue Exception => error
$stderr.puts error, *(error.backtrace)
$stderr.puts "Couldn't create database for #{configuration.inspect}"
end
def self.create_all
each_local_configuration { |configuration| create configuration }
end
def self.create_current(environment = Rails.env)
each_current_configuration(environment) { |configuration|
create configuration
}
ActiveRecord::Base.establish_connection environment
end
def self.drop(*arguments)
configuration = arguments.first
class_for_adapter(configuration['adapter']).new(*arguments).drop
rescue Exception => error
$stderr.puts error, *(error.backtrace)
$stderr.puts "Couldn't drop #{configuration['database']}"
end
def self.drop_all
each_local_configuration { |configuration| drop configuration }
end
def self.drop_current(environment = Rails.env)
each_current_configuration(environment) { |configuration|
drop configuration
}
end
def self.purge(configuration)
class_for_adapter(configuration['adapter']).new(configuration).purge
end
private
def self.class_for_adapter(adapter)
key = TASKS_PATTERNS.keys.detect { |pattern| adapter[pattern] }
TASKS_PATTERNS[key]
end
def self.each_current_configuration(environment)
environments = [environment]
environments << 'test' if environment.development?
configurations = ActiveRecord::Base.configurations.values_at(*environments)
configurations.compact.each do |configuration|
yield configuration unless configuration['database'].blank?
end
end
def self.each_local_configuration
ActiveRecord::Base.configurations.each_value do |configuration|
next unless configuration['database']
if local_database?(configuration)
yield configuration
else
$stderr.puts "This task only modifies local databases. #{configuration['database']} is on a remote host."
end
end
end
def self.local_database?(configuration)
configuration['host'].in?(LOCAL_HOSTS) || configuration['host'].blank?
end
end
class ActiveRecord::Tasks::MySQLDatabaseTasks
DEFAULT_CHARSET = ENV['CHARSET'] || 'utf8'
DEFAULT_COLLATION = ENV['COLLATION'] || 'utf8_unicode_ci'
ACCESS_DENIED_ERROR = 1045
delegate :connection, :establish_connection, :to => ActiveRecord::Base
def initialize(configuration)
@configuration = configuration
end
def create
establish_connection configuration_without_database
connection.create_database configuration['database'], creation_options
establish_connection configuration
rescue error_class => error
raise error unless error.errno == ACCESS_DENIED_ERROR
$stdout.print error.error
establish_connection root_configuration_without_database
connection.create_database configuration['database'], creation_options
connection.execute grant_statement.gsub(/\s+/, ' ').strip
establish_connection configuration
rescue error_class => error
$stderr.puts error.error
$stderr.puts "Couldn't create database for #{configuration.inspect}, #{creation_options.inspect}"
$stderr.puts "(If you set the charset manually, make sure you have a matching collation)" if configuration['charset']
end
def drop
establish_connection configuration
connection.drop_database configuration['database']
end
def purge
establish_connection :test
connection.recreate_database configuration['database'], creation_options
end
private
def configuration
@configuration
end
def configuration_without_database
configuration.merge('database' => nil)
end
def creation_options
{
:charset => (configuration['charset'] || DEFAULT_CHARSET),
:collation => (configuration['collation'] || DEFAULT_COLLATION)
}
end
def error_class
case configuration['adapter']
when /jdbc/
require 'active_record/railties/jdbcmysql_error'
ArJdbcMySQL::Error
when /mysql2/
Mysql2::Error
else
Mysql::Error
end
end
def grant_statement
<<-SQL
GRANT ALL PRIVILEGES ON #{configuration['database']}.*
TO '#{configuration['username']}'@'localhost'
IDENTIFIED BY '#{configuration['password']}' WITH GRANT OPTION;
SQL
end
def root_configuration_without_database
configuration_without_database.merge(
'username' => 'root',
'password' => root_password
)
end
def root_password
$stdout.print "Please provide the root password for your mysql installation\n>"
$stdin.gets.strip
end
end
class ActiveRecord::Tasks::PostgreSQLDatabaseTasks
DEFAULT_ENCODING = ENV['CHARSET'] || 'utf8'
delegate :connection, :establish_connection, :clear_active_connections!,
:to => ActiveRecord::Base
def initialize(configuration)
@configuration = configuration
end
def create(master_established = false)
establish_master_connection unless master_established
connection.create_database configuration['database'],
configuration.merge('encoding' => encoding)
establish_connection configuration
end
def drop
establish_master_connection
connection.drop_database configuration['database']
end
def purge
clear_active_connections!
drop
create true
end
private
def configuration
@configuration
end
def encoding
configuration['encoding'] || DEFAULT_ENCODING
end
def establish_master_connection
establish_connection configuration.merge(
'database' => 'postgres',
'schema_search_path' => 'public'
)
end
end
class ActiveRecord::Tasks::SQLiteDatabaseTasks
delegate :connection, :establish_connection, :to => ActiveRecord::Base
def initialize(configuration, root = Rails.root)
@configuration, @root = configuration, root
end
def create
if File.exist? configuration['database']
$stderr.puts "#{configuration['database']} already exists"
return
end
establish_connection configuration
connection
end
def drop
require 'pathname'
path = Pathname.new configuration['database']
file = path.absolute? ? path.to_s : File.join(root, path)
FileUtils.rm(file)
end
alias :purge :drop
private
def configuration
@configuration
end
def root
@root
end
end
require 'cases/helper'
module ActiveRecord
class DatabaseTasksCreateTest < ActiveRecord::TestCase
def setup
@mysql_tasks, @postgresql_tasks, @sqlite_tasks = stub, stub, stub
ActiveRecord::Tasks::MySQLDatabaseTasks.stubs(:new).returns @mysql_tasks
ActiveRecord::Tasks::PostgreSQLDatabaseTasks.stubs(:new).
returns @postgresql_tasks
ActiveRecord::Tasks::SQLiteDatabaseTasks.stubs(:new).returns @sqlite_tasks
end
def test_mysql_create
@mysql_tasks.expects(:create)
ActiveRecord::Tasks::DatabaseTasks.create 'adapter' => 'mysql'
end
def test_mysql2_create
@mysql_tasks.expects(:create)
ActiveRecord::Tasks::DatabaseTasks.create 'adapter' => 'mysql2'
end
def test_postgresql_create
@postgresql_tasks.expects(:create)
ActiveRecord::Tasks::DatabaseTasks.create 'adapter' => 'postgresql'
end
def test_sqlite_create
@sqlite_tasks.expects(:create)
ActiveRecord::Tasks::DatabaseTasks.create 'adapter' => 'sqlite3'
end
end
class DatabaseTasksCreateAllTest < ActiveRecord::TestCase
def setup
@configurations = {'development' => {'database' => 'my-db'}}
ActiveRecord::Base.stubs(:configurations).returns(@configurations)
end
def test_ignores_configurations_without_databases
@configurations['development'].merge!('database' => nil)
ActiveRecord::Tasks::DatabaseTasks.expects(:create).never
ActiveRecord::Tasks::DatabaseTasks.create_all
end
def test_ignores_remote_databases
@configurations['development'].merge!('host' => 'my.server.tld')
$stderr.stubs(:puts).returns(nil)
ActiveRecord::Tasks::DatabaseTasks.expects(:create).never
ActiveRecord::Tasks::DatabaseTasks.create_all
end
def test_warning_for_remote_databases
@configurations['development'].merge!('host' => 'my.server.tld')
$stderr.expects(:puts).with('This task only modifies local databases. my-db is on a remote host.')
ActiveRecord::Tasks::DatabaseTasks.create_all
end
def test_creates_configurations_with_local_ip
@configurations['development'].merge!('host' => '127.0.0.1')
ActiveRecord::Tasks::DatabaseTasks.expects(:create)
ActiveRecord::Tasks::DatabaseTasks.create_all
end
def test_creates_configurations_with_local_host
@configurations['development'].merge!('host' => 'localhost')
ActiveRecord::Tasks::DatabaseTasks.expects(:create)
ActiveRecord::Tasks::DatabaseTasks.create_all
end
def test_creates_configurations_with_blank_hosts
@configurations['development'].merge!('host' => nil)
ActiveRecord::Tasks::DatabaseTasks.expects(:create)
ActiveRecord::Tasks::DatabaseTasks.create_all
end
end
class DatabaseTasksCreateCurrentTest < ActiveRecord::TestCase
def setup
@configurations = {
'development' => {'database' => 'dev-db'},
'test' => {'database' => 'test-db'},
'production' => {'database' => 'prod-db'}
}
ActiveRecord::Base.stubs(:configurations).returns(@configurations)
ActiveRecord::Base.stubs(:establish_connection).returns(true)
end
def test_creates_current_environment_database
ActiveRecord::Tasks::DatabaseTasks.expects(:create).
with('database' => 'prod-db')
ActiveRecord::Tasks::DatabaseTasks.create_current(
ActiveSupport::StringInquirer.new('production')
)
end
def test_creates_test_database_when_environment_is_database
ActiveRecord::Tasks::DatabaseTasks.expects(:create).
with('database' => 'dev-db')
ActiveRecord::Tasks::DatabaseTasks.expects(:create).
with('database' => 'test-db')
ActiveRecord::Tasks::DatabaseTasks.create_current(
ActiveSupport::StringInquirer.new('development')
)
end
def test_establishes_connection_for_the_given_environment
ActiveRecord::Tasks::DatabaseTasks.stubs(:create).returns true
ActiveRecord::Base.expects(:establish_connection).with('development')
ActiveRecord::Tasks::DatabaseTasks.create_current(
ActiveSupport::StringInquirer.new('development')
)
end
end
class DatabaseTasksDropTest < ActiveRecord::TestCase
def setup
@mysql_tasks, @postgresql_tasks, @sqlite_tasks = stub, stub, stub
ActiveRecord::Tasks::MySQLDatabaseTasks.stubs(:new).returns @mysql_tasks
ActiveRecord::Tasks::PostgreSQLDatabaseTasks.stubs(:new).
returns @postgresql_tasks
ActiveRecord::Tasks::SQLiteDatabaseTasks.stubs(:new).returns @sqlite_tasks
end
def test_mysql_create
@mysql_tasks.expects(:drop)
ActiveRecord::Tasks::DatabaseTasks.drop 'adapter' => 'mysql'
end
def test_mysql2_create
@mysql_tasks.expects(:drop)
ActiveRecord::Tasks::DatabaseTasks.drop 'adapter' => 'mysql2'
end
def test_postgresql_create
@postgresql_tasks.expects(:drop)
ActiveRecord::Tasks::DatabaseTasks.drop 'adapter' => 'postgresql'
end
def test_sqlite_create
@sqlite_tasks.expects(:drop)
ActiveRecord::Tasks::DatabaseTasks.drop 'adapter' => 'sqlite3'
end
end
class DatabaseTasksDropAllTest < ActiveRecord::TestCase
def setup
@configurations = {:development => {'database' => 'my-db'}}
ActiveRecord::Base.stubs(:configurations).returns(@configurations)
end
def test_ignores_configurations_without_databases
@configurations[:development].merge!('database' => nil)
ActiveRecord::Tasks::DatabaseTasks.expects(:drop).never
ActiveRecord::Tasks::DatabaseTasks.drop_all
end
def test_ignores_remote_databases
@configurations[:development].merge!('host' => 'my.server.tld')
$stderr.stubs(:puts).returns(nil)
ActiveRecord::Tasks::DatabaseTasks.expects(:drop).never
ActiveRecord::Tasks::DatabaseTasks.drop_all
end
def test_warning_for_remote_databases
@configurations[:development].merge!('host' => 'my.server.tld')
$stderr.expects(:puts).with('This task only modifies local databases. my-db is on a remote host.')
ActiveRecord::Tasks::DatabaseTasks.drop_all
end
def test_creates_configurations_with_local_ip
@configurations[:development].merge!('host' => '127.0.0.1')
ActiveRecord::Tasks::DatabaseTasks.expects(:drop)
ActiveRecord::Tasks::DatabaseTasks.drop_all
end
def test_creates_configurations_with_local_host
@configurations[:development].merge!('host' => 'localhost')
ActiveRecord::Tasks::DatabaseTasks.expects(:drop)
ActiveRecord::Tasks::DatabaseTasks.drop_all
end
def test_creates_configurations_with_blank_hosts
@configurations[:development].merge!('host' => nil)
ActiveRecord::Tasks::DatabaseTasks.expects(:drop)
ActiveRecord::Tasks::DatabaseTasks.drop_all
end
end
class DatabaseTasksDropCurrentTest < ActiveRecord::TestCase
def setup
@configurations = {
'development' => {'database' => 'dev-db'},
'test' => {'database' => 'test-db'},
'production' => {'database' => 'prod-db'}
}
ActiveRecord::Base.stubs(:configurations).returns(@configurations)
end
def test_creates_current_environment_database
ActiveRecord::Tasks::DatabaseTasks.expects(:drop).
with('database' => 'prod-db')
ActiveRecord::Tasks::DatabaseTasks.drop_current(
ActiveSupport::StringInquirer.new('production')
)
end
def test_creates_test_database_when_environment_is_database
ActiveRecord::Tasks::DatabaseTasks.expects(:drop).
with('database' => 'dev-db')
ActiveRecord::Tasks::DatabaseTasks.expects(:drop).
with('database' => 'test-db')
ActiveRecord::Tasks::DatabaseTasks.drop_current(
ActiveSupport::StringInquirer.new('development')
)
end
end
class DatabaseTasksPurgeTest < ActiveRecord::TestCase
def setup
@mysql_tasks, @postgresql_tasks, @sqlite_tasks = stub, stub, stub
ActiveRecord::Tasks::MySQLDatabaseTasks.stubs(:new).returns @mysql_tasks
ActiveRecord::Tasks::PostgreSQLDatabaseTasks.stubs(:new).
returns @postgresql_tasks
ActiveRecord::Tasks::SQLiteDatabaseTasks.stubs(:new).returns @sqlite_tasks
end
def test_mysql_create
@mysql_tasks.expects(:purge)
ActiveRecord::Tasks::DatabaseTasks.purge 'adapter' => 'mysql'
end
def test_mysql2_create
@mysql_tasks.expects(:purge)
ActiveRecord::Tasks::DatabaseTasks.purge 'adapter' => 'mysql2'
end
def test_postgresql_create
@postgresql_tasks.expects(:purge)
ActiveRecord::Tasks::DatabaseTasks.purge 'adapter' => 'postgresql'
end
def test_sqlite_create
@sqlite_tasks.expects(:purge)
ActiveRecord::Tasks::DatabaseTasks.purge 'adapter' => 'sqlite3'
end
end
end
require 'cases/helper'
require 'mysql'
module ActiveRecord
class MysqlDBCreateTest < ActiveRecord::TestCase
def setup
@connection = stub(:create_database => true)
@configuration = {
'adapter' => 'mysql',
'database' => 'my-app-db'
}
ActiveRecord::Base.stubs(:connection).returns(@connection)
ActiveRecord::Base.stubs(:establish_connection).returns(true)
end
def test_establishes_connection_without_database
ActiveRecord::Base.expects(:establish_connection).
with('adapter' => 'mysql', 'database' => nil)
ActiveRecord::Tasks::DatabaseTasks.create @configuration
end
def test_creates_database_with_default_options
@connection.expects(:create_database).
with('my-app-db', {:charset => 'utf8', :collation => 'utf8_unicode_ci'})
ActiveRecord::Tasks::DatabaseTasks.create @configuration
end
def test_creates_database_with_given_options
@connection.expects(:create_database).
with('my-app-db', {:charset => 'latin', :collation => 'latin_ci'})
ActiveRecord::Tasks::DatabaseTasks.create @configuration.merge(
'charset' => 'latin', 'collation' => 'latin_ci'
)
end
def test_establishes_connection_to_database
ActiveRecord::Base.expects(:establish_connection).with(@configuration)
ActiveRecord::Tasks::DatabaseTasks.create @configuration
end
end
class MysqlDBCreateAsRootTest < ActiveRecord::TestCase
def setup
@connection = stub(:create_database => true, :execute => true)
@error = Mysql::Error.new "Invalid permissions"
@configuration = {
'adapter' => 'mysql',
'database' => 'my-app-db',
'username' => 'pat',
'password' => 'wossname'
}
$stdin.stubs(:gets).returns("secret\n")
$stdout.stubs(:print).returns(nil)
@error.stubs(:errno).returns(1045)
ActiveRecord::Base.stubs(:connection).returns(@connection)
ActiveRecord::Base.stubs(:establish_connection).raises(@error).then.
returns(true)
end
def test_root_password_is_requested
$stdin.expects(:gets).returns("secret\n")
ActiveRecord::Tasks::DatabaseTasks.create @configuration
end
def test_connection_established_as_root
ActiveRecord::Base.expects(:establish_connection).with({
'adapter' => 'mysql',
'database' => nil,
'username' => 'root',
'password' => 'secret'
})
ActiveRecord::Tasks::DatabaseTasks.create @configuration
end
def test_database_created_by_root
@connection.expects(:create_database).
with('my-app-db', :charset => 'utf8', :collation => 'utf8_unicode_ci')
ActiveRecord::Tasks::DatabaseTasks.create @configuration
end
def test_grant_privileges_for_normal_user
@connection.expects(:execute).with("GRANT ALL PRIVILEGES ON my-app-db.* TO 'pat'@'localhost' IDENTIFIED BY 'wossname' WITH GRANT OPTION;")
ActiveRecord::Tasks::DatabaseTasks.create @configuration
end
def test_connection_established_as_normal_user
ActiveRecord::Base.expects(:establish_connection).returns do
ActiveRecord::Base.expects(:establish_connection).with({
'adapter' => 'mysql',
'database' => 'my-app-db',
'username' => 'pat',
'password' => 'secret'
})
raise @error
end
ActiveRecord::Tasks::DatabaseTasks.create @configuration
end
def test_sends_output_to_stderr_when_other_errors
@error.stubs(:errno).returns(42)
$stderr.expects(:puts).at_least_once.returns(nil)
ActiveRecord::Tasks::DatabaseTasks.create @configuration
end
end
class MySQLDBDropTest < ActiveRecord::TestCase
def setup
@connection = stub(:drop_database => true)
@configuration = {
'adapter' => 'mysql',
'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 @configuration
ActiveRecord::Tasks::DatabaseTasks.drop @configuration
end
def test_drops_database
@connection.expects(:drop_database).with('my-app-db')
ActiveRecord::Tasks::DatabaseTasks.drop @configuration
end
end
class MySQLTestPurge < ActiveRecord::TestCase
def setup
@connection = stub(:recreate_database => true)
@configuration = {
'adapter' => 'mysql',
'database' => 'test-db'
}
ActiveRecord::Base.stubs(:connection).returns(@connection)
ActiveRecord::Base.stubs(:establish_connection).returns(true)
end
def test_establishes_connection_to_test_database
ActiveRecord::Base.expects(:establish_connection).with(:test)
ActiveRecord::Tasks::DatabaseTasks.purge @configuration
end
def test_recreates_database_with_the_default_options
@connection.expects(:recreate_database).
with('test-db', {:charset => 'utf8', :collation => 'utf8_unicode_ci'})
ActiveRecord::Tasks::DatabaseTasks.purge @configuration
end
def test_recreates_database_with_the_given_options
@connection.expects(:recreate_database).
with('test-db', {:charset => 'latin', :collation => 'latin_ci'})
ActiveRecord::Tasks::DatabaseTasks.purge @configuration.merge(
'charset' => 'latin', 'collation' => 'latin_ci'
)
end
end
end
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
class PostgreSQLDBDropTest < ActiveRecord::TestCase
def setup
@connection = stub(:drop_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.drop @configuration
end
def test_drops_database
@connection.expects(:drop_database).with('my-app-db')
ActiveRecord::Tasks::DatabaseTasks.drop @configuration
end
end
class PostgreSQLPurgeTest < ActiveRecord::TestCase
def setup
@connection = stub(:create_database => true, :drop_database => true)
@configuration = {
'adapter' => 'postgresql',
'database' => 'my-app-db'
}
ActiveRecord::Base.stubs(:connection).returns(@connection)
ActiveRecord::Base.stubs(:clear_active_connections!).returns(true)
ActiveRecord::Base.stubs(:establish_connection).returns(true)
end
def test_clears_active_connections
ActiveRecord::Base.expects(:clear_active_connections!)
ActiveRecord::Tasks::DatabaseTasks.purge @configuration
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.purge @configuration
end
def test_drops_database
@connection.expects(:drop_database).with('my-app-db')
ActiveRecord::Tasks::DatabaseTasks.purge @configuration
end
def test_creates_database
@connection.expects(:create_database).
with('my-app-db', @configuration.merge('encoding' => 'utf8'))
ActiveRecord::Tasks::DatabaseTasks.purge @configuration
end
def test_establishes_connection
ActiveRecord::Base.expects(:establish_connection).with(@configuration)
ActiveRecord::Tasks::DatabaseTasks.purge @configuration
end
end
end
require 'cases/helper'
require 'pathname'
module ActiveRecord
class SqliteDBCreateTest < ActiveRecord::TestCase
def setup
@database = "db_create.sqlite3"
@connection = stub :connection
@configuration = {
'adapter' => 'sqlite3',
'database' => @database
}
File.stubs(:exist?).returns(false)
ActiveRecord::Base.stubs(:connection).returns(@connection)
ActiveRecord::Base.stubs(:establish_connection).returns(true)
end
def test_db_checks_database_exists
File.expects(:exist?).with(@database).returns(false)
ActiveRecord::Tasks::DatabaseTasks.create @configuration, '/rails/root'
end
def test_db_create_when_file_exists
File.stubs(:exist?).returns(true)
$stderr.expects(:puts).with("#{@database} already exists")
ActiveRecord::Tasks::DatabaseTasks.create @configuration, '/rails/root'
end
def test_db_create_with_file_does_nothing
File.stubs(:exist?).returns(true)
$stderr.stubs(:puts).returns(nil)
ActiveRecord::Base.expects(:establish_connection).never
ActiveRecord::Tasks::DatabaseTasks.create @configuration, '/rails/root'
end
def test_db_create_establishes_a_connection
ActiveRecord::Base.expects(:establish_connection).with(@configuration)
ActiveRecord::Tasks::DatabaseTasks.create @configuration, '/rails/root'
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, '/rails/root'
end
end
class SqliteDBDropTest < ActiveRecord::TestCase
def setup
@database = "db_create.sqlite3"
@path = stub(:to_s => '/absolute/path', :absolute? => true)
@configuration = {
'adapter' => 'sqlite3',
'database' => @database
}
Pathname.stubs(:new).returns(@path)
File.stubs(:join).returns('/former/relative/path')
FileUtils.stubs(:rm).returns(true)
end
def test_creates_path_from_database
Pathname.expects(:new).with(@database).returns(@path)
ActiveRecord::Tasks::DatabaseTasks.drop @configuration, '/rails/root'
end
def test_removes_file_with_absolute_path
@path.stubs(:absolute?).returns(true)
FileUtils.expects(:rm).with('/absolute/path')
ActiveRecord::Tasks::DatabaseTasks.drop @configuration, '/rails/root'
end
def test_generates_absolute_path_with_given_root
@path.stubs(:absolute?).returns(false)
File.expects(:join).with('/rails/root', @path).
returns('/former/relative/path')
ActiveRecord::Tasks::DatabaseTasks.drop @configuration, '/rails/root'
end
def test_removes_file_with_relative_path
@path.stubs(:absolute?).returns(false)
FileUtils.expects(:rm).with('/former/relative/path')
ActiveRecord::Tasks::DatabaseTasks.drop @configuration, '/rails/root'
end
end
end
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册