From 619453d594187bc53b4c20d57e7821d8c166b71b Mon Sep 17 00:00:00 2001 From: Pat Allan Date: Sun, 17 Jun 2012 01:44:29 +0200 Subject: A beginning of sorts. Minimal implementation that supports db:create SQLite replacement --- activerecord/lib/active_record.rb | 6 ++++++ activerecord/lib/active_record/railties/databases.rake | 13 +------------ activerecord/lib/active_record/tasks/database_tasks.rb | 14 ++++++++++++++ 3 files changed, 21 insertions(+), 12 deletions(-) create mode 100644 activerecord/lib/active_record/tasks/database_tasks.rb (limited to 'activerecord/lib') diff --git a/activerecord/lib/active_record.rb b/activerecord/lib/active_record.rb index f8526bb691..c6dc7db2e8 100644 --- a/activerecord/lib/active_record.rb +++ b/activerecord/lib/active_record.rb @@ -137,6 +137,12 @@ module ActiveRecord end end + module Tasks + extend ActiveSupport::Autoload + + autoload :DatabaseTasks + end + autoload :TestCase autoload :TestFixtures, 'active_record/fixtures' end diff --git a/activerecord/lib/active_record/railties/databases.rake b/activerecord/lib/active_record/railties/databases.rake index d8d4834d22..b44d479fb6 100644 --- a/activerecord/lib/active_record/railties/databases.rake +++ b/activerecord/lib/active_record/railties/databases.rake @@ -50,18 +50,7 @@ db_namespace = namespace :db do 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 + ActiveRecord::Tasks::DatabaseTasks.create config return # Skip the else clause of begin/rescue else ActiveRecord::Base.establish_connection(config) diff --git a/activerecord/lib/active_record/tasks/database_tasks.rb b/activerecord/lib/active_record/tasks/database_tasks.rb new file mode 100644 index 0000000000..a72ec0175b --- /dev/null +++ b/activerecord/lib/active_record/tasks/database_tasks.rb @@ -0,0 +1,14 @@ +class ActiveRecord::Tasks::DatabaseTasks + def self.create(configuration) + if File.exist?(configuration['database']) + $stderr.puts "#{configuration['database']} already exists" + return + end + + ActiveRecord::Base.establish_connection(configuration) + ActiveRecord::Base.connection + rescue Exception => e + $stderr.puts e, *(e.backtrace) + $stderr.puts "Couldn't create database for #{configuration.inspect}" + end +end -- cgit v1.2.3 From d29727235ae967e1ae4880ddfa5fd37d726f779d Mon Sep 17 00:00:00 2001 From: Pat Allan Date: Sun, 17 Jun 2012 13:43:24 +0200 Subject: db:create for MySQL now much cleaner. --- activerecord/lib/active_record.rb | 2 + .../lib/active_record/railties/databases.rake | 31 +-------- .../lib/active_record/tasks/database_tasks.rb | 19 ++++-- .../active_record/tasks/mysql_database_tasks.rb | 76 ++++++++++++++++++++++ .../active_record/tasks/sqlite_database_tasks.rb | 19 ++++++ 5 files changed, 110 insertions(+), 37 deletions(-) create mode 100644 activerecord/lib/active_record/tasks/mysql_database_tasks.rb create mode 100644 activerecord/lib/active_record/tasks/sqlite_database_tasks.rb (limited to 'activerecord/lib') diff --git a/activerecord/lib/active_record.rb b/activerecord/lib/active_record.rb index c6dc7db2e8..3b37b001f7 100644 --- a/activerecord/lib/active_record.rb +++ b/activerecord/lib/active_record.rb @@ -141,6 +141,8 @@ module ActiveRecord extend ActiveSupport::Autoload autoload :DatabaseTasks + autoload :SQLiteDatabaseTasks, 'active_record/tasks/sqlite_database_tasks' + autoload :MySQLDatabaseTasks, 'active_record/tasks/mysql_database_tasks' end autoload :TestCase diff --git a/activerecord/lib/active_record/railties/databases.rake b/activerecord/lib/active_record/railties/databases.rake index b44d479fb6..662c84bfda 100644 --- a/activerecord/lib/active_record/railties/databases.rake +++ b/activerecord/lib/active_record/railties/databases.rake @@ -59,36 +59,7 @@ db_namespace = namespace :db do 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 + ActiveRecord::Tasks::DatabaseTasks.create config when /postgresql/ @encoding = config['encoding'] || ENV['CHARSET'] || 'utf8' begin diff --git a/activerecord/lib/active_record/tasks/database_tasks.rb b/activerecord/lib/active_record/tasks/database_tasks.rb index a72ec0175b..d0d3ea12dd 100644 --- a/activerecord/lib/active_record/tasks/database_tasks.rb +++ b/activerecord/lib/active_record/tasks/database_tasks.rb @@ -1,14 +1,19 @@ class ActiveRecord::Tasks::DatabaseTasks - def self.create(configuration) - if File.exist?(configuration['database']) - $stderr.puts "#{configuration['database']} already exists" - return - end + TASKS_PATTERNS = { + /mysql/ => ActiveRecord::Tasks::MySQLDatabaseTasks, + # /postgresql/ => ActiveRecord::Tasks::PostgreSQLTasker, + /sqlite/ => ActiveRecord::Tasks::SQLiteDatabaseTasks + } - ActiveRecord::Base.establish_connection(configuration) - ActiveRecord::Base.connection + def self.create(configuration) + class_for_adapter(configuration['adapter']).new(configuration).create rescue Exception => e $stderr.puts e, *(e.backtrace) $stderr.puts "Couldn't create database for #{configuration.inspect}" end + + def self.class_for_adapter(adapter) + key = TASKS_PATTERNS.keys.detect { |key| adapter[key] } + TASKS_PATTERNS[key] + end end diff --git a/activerecord/lib/active_record/tasks/mysql_database_tasks.rb b/activerecord/lib/active_record/tasks/mysql_database_tasks.rb new file mode 100644 index 0000000000..16d606d6fb --- /dev/null +++ b/activerecord/lib/active_record/tasks/mysql_database_tasks.rb @@ -0,0 +1,76 @@ +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 + + private + + attr_reader :configuration + + 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' + error_class = 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 diff --git a/activerecord/lib/active_record/tasks/sqlite_database_tasks.rb b/activerecord/lib/active_record/tasks/sqlite_database_tasks.rb new file mode 100644 index 0000000000..882a4f98a9 --- /dev/null +++ b/activerecord/lib/active_record/tasks/sqlite_database_tasks.rb @@ -0,0 +1,19 @@ +class ActiveRecord::Tasks::SQLiteDatabaseTasks + def initialize(configuration) + @configuration = configuration + end + + def create + if File.exist?(configuration['database']) + $stderr.puts "#{configuration['database']} already exists" + return + end + + ActiveRecord::Base.establish_connection(configuration) + ActiveRecord::Base.connection + end + + private + + attr_reader :configuration +end -- cgit v1.2.3 From e678d413bc14e9a38cd9818c7cf727339b2db9e7 Mon Sep 17 00:00:00 2001 From: Pat Allan Date: Sun, 17 Jun 2012 14:03:32 +0200 Subject: db:create for PostgreSQL pulled out into a class. --- activerecord/lib/active_record.rb | 2 ++ .../lib/active_record/railties/databases.rake | 39 ++++------------------ .../lib/active_record/tasks/database_tasks.rb | 2 +- .../tasks/postgresql_database_tasks.rb | 27 +++++++++++++++ .../active_record/tasks/sqlite_database_tasks.rb | 8 +++-- 5 files changed, 42 insertions(+), 36 deletions(-) create mode 100644 activerecord/lib/active_record/tasks/postgresql_database_tasks.rb (limited to 'activerecord/lib') diff --git a/activerecord/lib/active_record.rb b/activerecord/lib/active_record.rb index 3b37b001f7..8526e224da 100644 --- a/activerecord/lib/active_record.rb +++ b/activerecord/lib/active_record.rb @@ -143,6 +143,8 @@ module ActiveRecord 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 diff --git a/activerecord/lib/active_record/railties/databases.rake b/activerecord/lib/active_record/railties/databases.rake index 662c84bfda..3d9b1770ed 100644 --- a/activerecord/lib/active_record/railties/databases.rake +++ b/activerecord/lib/active_record/railties/databases.rake @@ -30,14 +30,18 @@ db_namespace = namespace :db do # *defaults next unless config['database'] # Only connect to local databases - local_database?(config) { create_database(config) } + local_database?(config) { + ActiveRecord::Tasks::DatabaseTasks.create config + } end 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) } + configs_for_environment.each { |config| + ActiveRecord::Tasks::DatabaseTasks.create config + } ActiveRecord::Base.establish_connection(configs_for_environment.first) end @@ -47,35 +51,6 @@ db_namespace = namespace :db do {:charset => (config['charset'] || @charset), :collation => (config['collation'] || @collation)} end - def create_database(config) - begin - if config['adapter'] =~ /sqlite/ - ActiveRecord::Tasks::DatabaseTasks.create config - return # Skip the else clause of begin/rescue - else - ActiveRecord::Base.establish_connection(config) - ActiveRecord::Base.connection - end - rescue - case config['adapter'] - when /mysql/ - ActiveRecord::Tasks::DatabaseTasks.create config - 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 - end - namespace :drop do # desc 'Drops all the local databases defined in config/database.yml' task :all => :load_config do @@ -475,7 +450,7 @@ db_namespace = namespace :db do when /postgresql/ ActiveRecord::Base.clear_active_connections! drop_database(abcs['test']) - create_database(abcs['test']) + ActiveRecord::Tasks::DatabaseTasks.create abcs['test'] when /sqlite/ dbfile = abcs['test']['database'] File.delete(dbfile) if File.exist?(dbfile) diff --git a/activerecord/lib/active_record/tasks/database_tasks.rb b/activerecord/lib/active_record/tasks/database_tasks.rb index d0d3ea12dd..6b9115f214 100644 --- a/activerecord/lib/active_record/tasks/database_tasks.rb +++ b/activerecord/lib/active_record/tasks/database_tasks.rb @@ -1,7 +1,7 @@ class ActiveRecord::Tasks::DatabaseTasks TASKS_PATTERNS = { /mysql/ => ActiveRecord::Tasks::MySQLDatabaseTasks, - # /postgresql/ => ActiveRecord::Tasks::PostgreSQLTasker, + /postgresql/ => ActiveRecord::Tasks::PostgreSQLDatabaseTasks, /sqlite/ => ActiveRecord::Tasks::SQLiteDatabaseTasks } diff --git a/activerecord/lib/active_record/tasks/postgresql_database_tasks.rb b/activerecord/lib/active_record/tasks/postgresql_database_tasks.rb new file mode 100644 index 0000000000..4e64a5e346 --- /dev/null +++ b/activerecord/lib/active_record/tasks/postgresql_database_tasks.rb @@ -0,0 +1,27 @@ +class ActiveRecord::Tasks::PostgreSQLDatabaseTasks + DEFAULT_ENCODING = ENV['CHARSET'] || 'utf8' + + delegate :connection, :establish_connection, :to => ActiveRecord::Base + + def initialize(configuration) + @configuration = configuration + end + + def create + establish_connection configuration.merge( + 'database' => 'postgres', + 'schema_search_path' => 'public' + ) + connection.create_database configuration['database'], + configuration.merge('encoding' => encoding) + establish_connection configuration + end + + private + + attr_reader :configuration + + def encoding + configuration['encoding'] || DEFAULT_ENCODING + end +end diff --git a/activerecord/lib/active_record/tasks/sqlite_database_tasks.rb b/activerecord/lib/active_record/tasks/sqlite_database_tasks.rb index 882a4f98a9..dd43414d79 100644 --- a/activerecord/lib/active_record/tasks/sqlite_database_tasks.rb +++ b/activerecord/lib/active_record/tasks/sqlite_database_tasks.rb @@ -1,16 +1,18 @@ class ActiveRecord::Tasks::SQLiteDatabaseTasks + delegate :connection, :establish_connection, :to => ActiveRecord::Base + def initialize(configuration) @configuration = configuration end def create - if File.exist?(configuration['database']) + if File.exist? configuration['database'] $stderr.puts "#{configuration['database']} already exists" return end - ActiveRecord::Base.establish_connection(configuration) - ActiveRecord::Base.connection + establish_connection configuration + connection end private -- cgit v1.2.3 From bca52b05af8ef757e9574f833217c0051ee21a50 Mon Sep 17 00:00:00 2001 From: Pat Allan Date: Sun, 17 Jun 2012 17:39:12 +0200 Subject: db:drop and some of db:test:purge. --- .../lib/active_record/railties/databases.rake | 50 ++++------------------ .../lib/active_record/tasks/database_tasks.rb | 15 ++++++- .../active_record/tasks/mysql_database_tasks.rb | 10 +++++ .../tasks/postgresql_database_tasks.rb | 28 +++++++++--- .../active_record/tasks/sqlite_database_tasks.rb | 10 +++++ 5 files changed, 63 insertions(+), 50 deletions(-) (limited to 'activerecord/lib') diff --git a/activerecord/lib/active_record/railties/databases.rake b/activerecord/lib/active_record/railties/databases.rake index 3d9b1770ed..d3137be38c 100644 --- a/activerecord/lib/active_record/railties/databases.rake +++ b/activerecord/lib/active_record/railties/databases.rake @@ -57,19 +57,18 @@ db_namespace = namespace :db 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 + local_database?(config) { + ActiveRecord::Tasks::DatabaseTasks.drop config + } end 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) } + configs_for_environment.each { |config| + ActiveRecord::Tasks::DatabaseTasks.drop config + } end def local_database?(config, &block) @@ -444,16 +443,8 @@ db_namespace = namespace :db do task :purge => :environment 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']) - ActiveRecord::Tasks::DatabaseTasks.create 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'] @@ -527,31 +518,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? diff --git a/activerecord/lib/active_record/tasks/database_tasks.rb b/activerecord/lib/active_record/tasks/database_tasks.rb index 6b9115f214..1d70d6100c 100644 --- a/activerecord/lib/active_record/tasks/database_tasks.rb +++ b/activerecord/lib/active_record/tasks/database_tasks.rb @@ -7,11 +7,22 @@ class ActiveRecord::Tasks::DatabaseTasks def self.create(configuration) class_for_adapter(configuration['adapter']).new(configuration).create - rescue Exception => e - $stderr.puts e, *(e.backtrace) + rescue Exception => error + $stderr.puts error, *(error.backtrace) $stderr.puts "Couldn't create database for #{configuration.inspect}" end + def self.drop(configuration) + class_for_adapter(configuration['adapter']).new(configuration).drop + rescue Exception => error + $stderr.puts error, *(error.backtrace) + $stderr.puts "Couldn't drop #{configuration['database']}" + end + + def self.purge(configuration) + class_for_adapter(configuration['adapter']).new(configuration).purge + end + def self.class_for_adapter(adapter) key = TASKS_PATTERNS.keys.detect { |key| adapter[key] } TASKS_PATTERNS[key] diff --git a/activerecord/lib/active_record/tasks/mysql_database_tasks.rb b/activerecord/lib/active_record/tasks/mysql_database_tasks.rb index 16d606d6fb..a1d36f0855 100644 --- a/activerecord/lib/active_record/tasks/mysql_database_tasks.rb +++ b/activerecord/lib/active_record/tasks/mysql_database_tasks.rb @@ -27,6 +27,16 @@ class ActiveRecord::Tasks::MySQLDatabaseTasks $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 attr_reader :configuration diff --git a/activerecord/lib/active_record/tasks/postgresql_database_tasks.rb b/activerecord/lib/active_record/tasks/postgresql_database_tasks.rb index 4e64a5e346..c3c5b2f2f5 100644 --- a/activerecord/lib/active_record/tasks/postgresql_database_tasks.rb +++ b/activerecord/lib/active_record/tasks/postgresql_database_tasks.rb @@ -1,22 +1,31 @@ class ActiveRecord::Tasks::PostgreSQLDatabaseTasks DEFAULT_ENCODING = ENV['CHARSET'] || 'utf8' - delegate :connection, :establish_connection, :to => ActiveRecord::Base + delegate :connection, :establish_connection, :clear_active_connections!, + :to => ActiveRecord::Base def initialize(configuration) @configuration = configuration end - def create - establish_connection configuration.merge( - 'database' => 'postgres', - 'schema_search_path' => 'public' - ) + 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 attr_reader :configuration @@ -24,4 +33,11 @@ class ActiveRecord::Tasks::PostgreSQLDatabaseTasks def encoding configuration['encoding'] || DEFAULT_ENCODING end + + def establish_master_connection + establish_connection configuration.merge( + 'database' => 'postgres', + 'schema_search_path' => 'public' + ) + end end diff --git a/activerecord/lib/active_record/tasks/sqlite_database_tasks.rb b/activerecord/lib/active_record/tasks/sqlite_database_tasks.rb index dd43414d79..fff763421b 100644 --- a/activerecord/lib/active_record/tasks/sqlite_database_tasks.rb +++ b/activerecord/lib/active_record/tasks/sqlite_database_tasks.rb @@ -15,6 +15,16 @@ class ActiveRecord::Tasks::SQLiteDatabaseTasks connection end + def drop + require 'pathname' + path = Pathname.new configuration['database'] + file = path.absolute? ? path.to_s : File.join(Rails.root, path) + + FileUtils.rm(file) + end + + alias :purge :drop + private attr_reader :configuration -- cgit v1.2.3 From 4422e0342612b581687e809149e8fa71ff719104 Mon Sep 17 00:00:00 2001 From: Pat Allan Date: Sun, 17 Jun 2012 18:09:20 +0200 Subject: One line db:create/db:drop tasks. Now isn't that better? And yes, I know that private has no impact on class methods - it's a visual distinction, not a technical one. --- .../lib/active_record/railties/databases.rake | 59 ++-------------------- .../lib/active_record/tasks/database_tasks.rb | 46 +++++++++++++++++ 2 files changed, 50 insertions(+), 55 deletions(-) (limited to 'activerecord/lib') diff --git a/activerecord/lib/active_record/railties/databases.rake b/activerecord/lib/active_record/railties/databases.rake index d3137be38c..d2dd218ba3 100644 --- a/activerecord/lib/active_record/railties/databases.rake +++ b/activerecord/lib/active_record/railties/databases.rake @@ -14,72 +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) { - ActiveRecord::Tasks::DatabaseTasks.create 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| - ActiveRecord::Tasks::DatabaseTasks.create 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)} + 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'] - local_database?(config) { - ActiveRecord::Tasks::DatabaseTasks.drop config - } - 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| - ActiveRecord::Tasks::DatabaseTasks.drop config - } + ActiveRecord::Tasks::DatabaseTasks.drop_current 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 - 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 @@ -518,12 +473,6 @@ end task 'test:prepare' => 'db:test:prepare' -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 diff --git a/activerecord/lib/active_record/tasks/database_tasks.rb b/activerecord/lib/active_record/tasks/database_tasks.rb index 1d70d6100c..7174c63b38 100644 --- a/activerecord/lib/active_record/tasks/database_tasks.rb +++ b/activerecord/lib/active_record/tasks/database_tasks.rb @@ -4,6 +4,7 @@ class ActiveRecord::Tasks::DatabaseTasks /postgresql/ => ActiveRecord::Tasks::PostgreSQLDatabaseTasks, /sqlite/ => ActiveRecord::Tasks::SQLiteDatabaseTasks } + LOCAL_HOSTS = ['127.0.0.1', 'localhost'] def self.create(configuration) class_for_adapter(configuration['adapter']).new(configuration).create @@ -12,6 +13,15 @@ class ActiveRecord::Tasks::DatabaseTasks $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 + each_current_configuration { |configuration| create configuration } + ActiveRecord::Base.establish_connection Rails.env.to_sym + end + def self.drop(configuration) class_for_adapter(configuration['adapter']).new(configuration).drop rescue Exception => error @@ -19,12 +29,48 @@ class ActiveRecord::Tasks::DatabaseTasks $stderr.puts "Couldn't drop #{configuration['database']}" end + def self.drop_all + each_local_configuration { |configuration| drop configuration } + end + + def self.drop_current + each_current_configuration { |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 { |key| adapter[key] } TASKS_PATTERNS[key] end + + def self.each_current_configuration + environments = [Rails.env] + environments << 'test' if Rails.env.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 -- cgit v1.2.3 From 8d5710c8987b9d624e276f4f47f91130b46b0440 Mon Sep 17 00:00:00 2001 From: Pat Allan Date: Sun, 17 Jun 2012 21:37:44 +0200 Subject: Cleaning up after some warnings, adding slightly higher-level tests. --- activerecord/lib/active_record/tasks/database_tasks.rb | 6 +++--- activerecord/lib/active_record/tasks/mysql_database_tasks.rb | 6 ++++-- activerecord/lib/active_record/tasks/postgresql_database_tasks.rb | 4 +++- activerecord/lib/active_record/tasks/sqlite_database_tasks.rb | 4 +++- 4 files changed, 13 insertions(+), 7 deletions(-) (limited to 'activerecord/lib') diff --git a/activerecord/lib/active_record/tasks/database_tasks.rb b/activerecord/lib/active_record/tasks/database_tasks.rb index 7174c63b38..e49af454b5 100644 --- a/activerecord/lib/active_record/tasks/database_tasks.rb +++ b/activerecord/lib/active_record/tasks/database_tasks.rb @@ -19,7 +19,7 @@ class ActiveRecord::Tasks::DatabaseTasks def self.create_current each_current_configuration { |configuration| create configuration } - ActiveRecord::Base.establish_connection Rails.env.to_sym + ActiveRecord::Base.establish_connection Rails.env end def self.drop(configuration) @@ -44,7 +44,7 @@ class ActiveRecord::Tasks::DatabaseTasks private def self.class_for_adapter(adapter) - key = TASKS_PATTERNS.keys.detect { |key| adapter[key] } + key = TASKS_PATTERNS.keys.detect { |pattern| adapter[pattern] } TASKS_PATTERNS[key] end @@ -52,7 +52,7 @@ class ActiveRecord::Tasks::DatabaseTasks environments = [Rails.env] environments << 'test' if Rails.env.development? - configurations = ActiveRecord::Base.configurations.values_at *environments + configurations = ActiveRecord::Base.configurations.values_at(*environments) configurations.compact.each do |configuration| yield configuration unless configuration['database'].blank? end diff --git a/activerecord/lib/active_record/tasks/mysql_database_tasks.rb b/activerecord/lib/active_record/tasks/mysql_database_tasks.rb index a1d36f0855..eb598629fa 100644 --- a/activerecord/lib/active_record/tasks/mysql_database_tasks.rb +++ b/activerecord/lib/active_record/tasks/mysql_database_tasks.rb @@ -39,7 +39,9 @@ class ActiveRecord::Tasks::MySQLDatabaseTasks private - attr_reader :configuration + def configuration + @configuration + end def configuration_without_database configuration.merge('database' => nil) @@ -56,7 +58,7 @@ class ActiveRecord::Tasks::MySQLDatabaseTasks case configuration['adapter'] when /jdbc/ require 'active_record/railties/jdbcmysql_error' - error_class = ArJdbcMySQL::Error + ArJdbcMySQL::Error when /mysql2/ Mysql2::Error else diff --git a/activerecord/lib/active_record/tasks/postgresql_database_tasks.rb b/activerecord/lib/active_record/tasks/postgresql_database_tasks.rb index c3c5b2f2f5..331825d3ec 100644 --- a/activerecord/lib/active_record/tasks/postgresql_database_tasks.rb +++ b/activerecord/lib/active_record/tasks/postgresql_database_tasks.rb @@ -28,7 +28,9 @@ class ActiveRecord::Tasks::PostgreSQLDatabaseTasks private - attr_reader :configuration + def configuration + @configuration + end def encoding configuration['encoding'] || DEFAULT_ENCODING diff --git a/activerecord/lib/active_record/tasks/sqlite_database_tasks.rb b/activerecord/lib/active_record/tasks/sqlite_database_tasks.rb index fff763421b..8f8021f47c 100644 --- a/activerecord/lib/active_record/tasks/sqlite_database_tasks.rb +++ b/activerecord/lib/active_record/tasks/sqlite_database_tasks.rb @@ -27,5 +27,7 @@ class ActiveRecord::Tasks::SQLiteDatabaseTasks private - attr_reader :configuration + def configuration + @configuration + end end -- cgit v1.2.3 From 55f8dfd99e20d991dee2d948120ce8955054acbf Mon Sep 17 00:00:00 2001 From: Pat Allan Date: Sun, 17 Jun 2012 22:16:45 +0200 Subject: Rails is the default (but now override able) source for environment and path. --- .../lib/active_record/tasks/database_tasks.rb | 30 +++++++++++++--------- .../active_record/tasks/sqlite_database_tasks.rb | 10 +++++--- 2 files changed, 25 insertions(+), 15 deletions(-) (limited to 'activerecord/lib') diff --git a/activerecord/lib/active_record/tasks/database_tasks.rb b/activerecord/lib/active_record/tasks/database_tasks.rb index e49af454b5..10cc679a05 100644 --- a/activerecord/lib/active_record/tasks/database_tasks.rb +++ b/activerecord/lib/active_record/tasks/database_tasks.rb @@ -6,8 +6,9 @@ class ActiveRecord::Tasks::DatabaseTasks } LOCAL_HOSTS = ['127.0.0.1', 'localhost'] - def self.create(configuration) - class_for_adapter(configuration['adapter']).new(configuration).create + 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}" @@ -17,13 +18,16 @@ class ActiveRecord::Tasks::DatabaseTasks each_local_configuration { |configuration| create configuration } end - def self.create_current - each_current_configuration { |configuration| create configuration } - ActiveRecord::Base.establish_connection Rails.env + def self.create_current(environment = Rails.env) + each_current_configuration(environment) { |configuration| + create configuration + } + ActiveRecord::Base.establish_connection environment end - def self.drop(configuration) - class_for_adapter(configuration['adapter']).new(configuration).drop + 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']}" @@ -33,8 +37,10 @@ class ActiveRecord::Tasks::DatabaseTasks each_local_configuration { |configuration| drop configuration } end - def self.drop_current - each_current_configuration { |configuration| drop configuration } + def self.drop_current(environment = Rails.env) + each_current_configuration(environment) { |configuration| + drop configuration + } end def self.purge(configuration) @@ -48,9 +54,9 @@ class ActiveRecord::Tasks::DatabaseTasks TASKS_PATTERNS[key] end - def self.each_current_configuration - environments = [Rails.env] - environments << 'test' if Rails.env.development? + 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| diff --git a/activerecord/lib/active_record/tasks/sqlite_database_tasks.rb b/activerecord/lib/active_record/tasks/sqlite_database_tasks.rb index 8f8021f47c..4d3cba8a50 100644 --- a/activerecord/lib/active_record/tasks/sqlite_database_tasks.rb +++ b/activerecord/lib/active_record/tasks/sqlite_database_tasks.rb @@ -1,8 +1,8 @@ class ActiveRecord::Tasks::SQLiteDatabaseTasks delegate :connection, :establish_connection, :to => ActiveRecord::Base - def initialize(configuration) - @configuration = configuration + def initialize(configuration, root = Rails.root) + @configuration, @root = configuration, root end def create @@ -18,7 +18,7 @@ class ActiveRecord::Tasks::SQLiteDatabaseTasks def drop require 'pathname' path = Pathname.new configuration['database'] - file = path.absolute? ? path.to_s : File.join(Rails.root, path) + file = path.absolute? ? path.to_s : File.join(root, path) FileUtils.rm(file) end @@ -30,4 +30,8 @@ class ActiveRecord::Tasks::SQLiteDatabaseTasks def configuration @configuration end + + def root + @root + end end -- cgit v1.2.3