diff options
-rw-r--r-- | actioncable/lib/action_cable/connection/identification.rb | 2 | ||||
-rw-r--r-- | activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb | 10 | ||||
-rw-r--r-- | activerecord/lib/active_record/internal_metadata.rb | 5 | ||||
-rw-r--r-- | activerecord/lib/active_record/migration.rb | 48 | ||||
-rw-r--r-- | activerecord/lib/active_record/schema_migration.rb | 2 | ||||
-rw-r--r-- | activerecord/test/cases/migration_test.rb | 30 | ||||
-rw-r--r-- | activesupport/lib/active_support/cache/file_store.rb | 12 | ||||
-rw-r--r-- | activesupport/test/caching_test.rb | 8 | ||||
-rw-r--r-- | railties/CHANGELOG.md | 2 |
9 files changed, 79 insertions, 40 deletions
diff --git a/actioncable/lib/action_cable/connection/identification.rb b/actioncable/lib/action_cable/connection/identification.rb index 2d75ff8d6d..885ff3f102 100644 --- a/actioncable/lib/action_cable/connection/identification.rb +++ b/actioncable/lib/action_cable/connection/identification.rb @@ -11,7 +11,7 @@ module ActionCable end class_methods do - # Mark a key as being a connection identifier index that can then used to find the specific connection again later. + # Mark a key as being a connection identifier index that can then be used to find the specific connection again later. # Common identifiers are current_user and current_account, but could be anything really. # # Note that anything marked as an identifier will automatically create a delegate by the same name on any diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb index e313a34c3a..1c20e4700f 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -690,15 +690,7 @@ module ActiveRecord end # Returns the current ID of a table's sequence. - def last_insert_id(sequence_name) #:nodoc: - Integer(last_insert_id_value(sequence_name)) - end - - def last_insert_id_value(sequence_name) - last_insert_id_result(sequence_name).rows.first.first - end - - def last_insert_id_result(sequence_name) #:nodoc: + def last_insert_id_result(sequence_name) # :nodoc: exec_query("SELECT currval('#{sequence_name}')", 'SQL') end diff --git a/activerecord/lib/active_record/internal_metadata.rb b/activerecord/lib/active_record/internal_metadata.rb index 2e962f4218..e5c6e5c885 100644 --- a/activerecord/lib/active_record/internal_metadata.rb +++ b/activerecord/lib/active_record/internal_metadata.rb @@ -33,13 +33,12 @@ module ActiveRecord # Creates an internal metadata table with columns +key+ and +value+ def create_table unless table_exists? - connection.create_table(table_name, primary_key: :key, id: false ) do |t| + connection.create_table(table_name, id: false) do |t| t.column :key, :string t.column :value, :string t.timestamps + t.index :key, unique: true, name: index_name end - - connection.add_index table_name, :key, unique: true, name: index_name end end end diff --git a/activerecord/lib/active_record/migration.rb b/activerecord/lib/active_record/migration.rb index 4a6e9c12fe..f5b29c7f2e 100644 --- a/activerecord/lib/active_record/migration.rb +++ b/activerecord/lib/active_record/migration.rb @@ -1170,45 +1170,58 @@ module ActiveRecord private + # Used for running a specific migration. def run_without_lock migration = migrations.detect { |m| m.version == @target_version } raise UnknownMigrationVersionError.new(@target_version) if migration.nil? - unless (up? && migrated.include?(migration.version.to_i)) || (down? && !migrated.include?(migration.version.to_i)) - begin - execute_migration_in_transaction(migration, @direction) - rescue => e - canceled_msg = use_transaction?(migration) ? ", this migration was canceled" : "" - raise StandardError, "An error has occurred#{canceled_msg}:\n\n#{e}", e.backtrace - end - end + execute_migration_in_transaction(migration, @direction) + + record_environment end + # Used for running multiple migrations up to or down to a certain value. def migrate_without_lock - if !target && @target_version && @target_version > 0 + if invalid_target? raise UnknownMigrationVersionError.new(@target_version) end runnable.each do |migration| - Base.logger.info "Migrating to #{migration.name} (#{migration.version})" if Base.logger - - begin - execute_migration_in_transaction(migration, @direction) - rescue => e - canceled_msg = use_transaction?(migration) ? "this and " : "" - raise StandardError, "An error has occurred, #{canceled_msg}all later migrations canceled:\n\n#{e}", e.backtrace - end + execute_migration_in_transaction(migration, @direction) end + + record_environment + end + + # Stores the current environment in the database. + def record_environment + return if down? + ActiveRecord::InternalMetadata[:environment] = ActiveRecord::Migrator.current_environment end def ran?(migration) migrated.include?(migration.version.to_i) end + # Return true if a valid version is not provided. + def invalid_target? + !target && @target_version && @target_version > 0 + end + def execute_migration_in_transaction(migration, direction) + return if down? && !migrated.include?(migration.version.to_i) + return if up? && migrated.include?(migration.version.to_i) + + Base.logger.info "Migrating to #{migration.name} (#{migration.version})" if Base.logger + ddl_transaction(migration) do migration.migrate(direction) record_version_state_after_migrating(migration.version) end + rescue => e + msg = "An error has occurred, " + msg << "this and " if use_transaction?(migration) + msg << "all later migrations canceled:\n\n#{e}" + raise StandardError, msg, e.backtrace end def target @@ -1238,7 +1251,6 @@ module ActiveRecord else migrated << version ActiveRecord::SchemaMigration.create!(version: version.to_s) - ActiveRecord::InternalMetadata[:environment] = ActiveRecord::Migrator.current_environment end end diff --git a/activerecord/lib/active_record/schema_migration.rb b/activerecord/lib/active_record/schema_migration.rb index 3017ee0bbb..ee4c71f304 100644 --- a/activerecord/lib/active_record/schema_migration.rb +++ b/activerecord/lib/active_record/schema_migration.rb @@ -31,8 +31,8 @@ module ActiveRecord connection.create_table(table_name, id: false) do |t| t.column :version, :string, version_options + t.index :version, unique: true, name: index_name end - connection.add_index table_name, :version, unique: true, name: index_name end end diff --git a/activerecord/test/cases/migration_test.rb b/activerecord/test/cases/migration_test.rb index cfa223f93e..f51e366b1d 100644 --- a/activerecord/test/cases/migration_test.rb +++ b/activerecord/test/cases/migration_test.rb @@ -301,7 +301,7 @@ class MigrationTest < ActiveRecord::TestCase e = assert_raise(StandardError) { migrator.run } - assert_equal "An error has occurred, this migration was canceled:\n\nSomething broke", e.message + assert_equal "An error has occurred, this and all later migrations canceled:\n\nSomething broke", e.message assert_no_column Person, :last_name, "On error, the Migrator should revert schema changes but it did not." @@ -380,6 +380,33 @@ class MigrationTest < ActiveRecord::TestCase old_path = ActiveRecord::Migrator.migrations_paths ActiveRecord::Migrator.migrations_paths = migrations_path + ActiveRecord::Migrator.up(migrations_path) + assert_equal current_env, ActiveRecord::InternalMetadata[:environment] + + original_rails_env = ENV["RAILS_ENV"] + original_rack_env = ENV["RACK_ENV"] + ENV["RAILS_ENV"] = ENV["RACK_ENV"] = "foofoo" + new_env = ActiveRecord::ConnectionHandling::DEFAULT_ENV.call + + refute_equal current_env, new_env + + sleep 1 # mysql by default does not store fractional seconds in the database + ActiveRecord::Migrator.up(migrations_path) + assert_equal new_env, ActiveRecord::InternalMetadata[:environment] + ensure + ActiveRecord::Migrator.migrations_paths = old_path + ENV["RAILS_ENV"] = original_rails_env + ENV["RACK_ENV"] = original_rack_env + end + + + def test_migration_sets_internal_metadata_even_when_fully_migrated + current_env = ActiveRecord::ConnectionHandling::DEFAULT_ENV.call + migrations_path = MIGRATIONS_ROOT + "/valid" + old_path = ActiveRecord::Migrator.migrations_paths + ActiveRecord::Migrator.migrations_paths = migrations_path + + ActiveRecord::Migrator.up(migrations_path) assert_equal current_env, ActiveRecord::InternalMetadata[:environment] original_rails_env = ENV["RAILS_ENV"] @@ -390,6 +417,7 @@ class MigrationTest < ActiveRecord::TestCase refute_equal current_env, new_env sleep 1 # mysql by default does not store fractional seconds in the database + ActiveRecord::Migrator.up(migrations_path) assert_equal new_env, ActiveRecord::InternalMetadata[:environment] ensure diff --git a/activesupport/lib/active_support/cache/file_store.rb b/activesupport/lib/active_support/cache/file_store.rb index dff2443bc8..99c55b1aa4 100644 --- a/activesupport/lib/active_support/cache/file_store.rb +++ b/activesupport/lib/active_support/cache/file_store.rb @@ -17,6 +17,7 @@ module ActiveSupport FILENAME_MAX_SIZE = 228 # max filename size on file system is 255, minus room for timestamp and random characters appended by Tempfile (used by atomic write) FILEPATH_MAX_SIZE = 900 # max is 1024, plus some room EXCLUDED_DIRS = ['.', '..'].freeze + GITKEEP_FILES = ['.gitkeep', '.keep'].freeze def initialize(cache_path, options = nil) super(options) @@ -24,10 +25,10 @@ module ActiveSupport end # Deletes all items from the cache. In this case it deletes all the entries in the specified - # file store directory except for .gitkeep. Be careful which directory is specified in your + # file store directory except for .keep or .gitkeep. Be careful which directory is specified in your # config file when using +FileStore+ because everything in that directory will be deleted. def clear(options = nil) - root_dirs = Dir.entries(cache_path).reject {|f| (EXCLUDED_DIRS + [".gitkeep"]).include?(f)} + root_dirs = exclude_from(cache_path, EXCLUDED_DIRS + GITKEEP_FILES) FileUtils.rm_r(root_dirs.collect{|f| File.join(cache_path, f)}) rescue Errno::ENOENT end @@ -154,7 +155,7 @@ module ActiveSupport # Delete empty directories in the cache. def delete_empty_directories(dir) return if File.realpath(dir) == File.realpath(cache_path) - if Dir.entries(dir).reject {|f| EXCLUDED_DIRS.include?(f)}.empty? + if exclude_from(dir, EXCLUDED_DIRS).empty? Dir.delete(dir) rescue nil delete_empty_directories(File.dirname(dir)) end @@ -193,6 +194,11 @@ module ActiveSupport end end end + + # Exclude entries from source directory + def exclude_from(source, excludes) + Dir.entries(source).reject { |f| excludes.include?(f) } + end end end end diff --git a/activesupport/test/caching_test.rb b/activesupport/test/caching_test.rb index 2701dc2fe9..4a299429f3 100644 --- a/activesupport/test/caching_test.rb +++ b/activesupport/test/caching_test.rb @@ -780,10 +780,12 @@ class FileStoreTest < ActiveSupport::TestCase include AutoloadingCacheBehavior def test_clear - filepath = File.join(cache_dir, ".gitkeep") - FileUtils.touch(filepath) + gitkeep = File.join(cache_dir, ".gitkeep") + keep = File.join(cache_dir, ".keep") + FileUtils.touch([gitkeep, keep]) @cache.clear - assert File.exist?(filepath) + assert File.exist?(gitkeep) + assert File.exist?(keep) end def test_clear_without_cache_dir diff --git a/railties/CHANGELOG.md b/railties/CHANGELOG.md index 4a28074f2c..2c363c55da 100644 --- a/railties/CHANGELOG.md +++ b/railties/CHANGELOG.md @@ -6,7 +6,7 @@ Specify which logs to clear when using the `rake log:clear` task, e.g. `rake log:clear LOGS=test,staging` - Clear all logs from log/*.log e.g. `rake log:clear ENV['LOGS']=all` + Clear all logs from log/*.log e.g. `rake log:clear LOGS=all` By default `rake log:clear` clears standard environment log files i.e. 'development,test,production' |