Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove IdentityMap #5261

Merged
merged 4 commits into from Mar 13, 2012
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion .travis.yml
Expand Up @@ -5,7 +5,7 @@ rvm:
- 1.9.3
env:
- "GEM=railties"
- "GEM=ap,am,amo,ares,as"
- "GEM=ap,am,amo,as"
- "GEM=ar:mysql"
- "GEM=ar:mysql2"
- "GEM=ar:sqlite3"
Expand Down
11 changes: 11 additions & 0 deletions activerecord/CHANGELOG.md
@@ -1,5 +1,16 @@
## Rails 4.0.0 (unreleased) ##

* Remove IdentityMap

IdentityMap has never graduated to be an "enabled-by-default" feature, due
to some inconsistencies with associations, as described in this commit:

https://github.com/rails/rails/commit/302c912bf6bcd0fa200d964ec2dc4a44abe328a6

Hence the removal from the codebase, until such issues are fixed.

*Carlos Antonio da Silva*

* Added the schema cache dump feature.

`Schema cache dump` feature was implemetend. This feature can dump/load internal state of `SchemaCache` instance
Expand Down
7 changes: 0 additions & 7 deletions activerecord/RUNNING_UNIT_TESTS
Expand Up @@ -26,13 +26,6 @@ You can run all the tests for a given database via rake:

The 'rake test' task will run all the tests for mysql, mysql2, sqlite3 and postgresql.

== Identity Map

By default the tests run with the Identity Map turned off. But all tests should pass whether or
not the identity map is on or off. You can turn it on using the IM env variable:

$ IM=true ruby -Itest test/case/base_test.rb

== Config file

By default, the config file is expected to be at the path test/config.yml. You can specify a
Expand Down
1 change: 0 additions & 1 deletion activerecord/lib/active_record.rb
Expand Up @@ -65,7 +65,6 @@ module ActiveRecord
autoload :DynamicFinderMatch
autoload :DynamicScopeMatch
autoload :Explain
autoload :IdentityMap
autoload :Inheritance
autoload :Integration
autoload :Migration
Expand Down
13 changes: 1 addition & 12 deletions activerecord/lib/active_record/associations/association.rb
Expand Up @@ -45,7 +45,6 @@ def aliased_table_name
# Resets the \loaded flag to +false+ and sets the \target to +nil+.
def reset
@loaded = false
IdentityMap.remove(target) if IdentityMap.enabled? && target
@target = nil
end

Expand Down Expand Up @@ -135,17 +134,7 @@ def target_scope
# ActiveRecord::RecordNotFound is rescued within the method, and it is
# not reraised. The proxy is \reset and +nil+ is the return value.
def load_target
if find_target?
begin
if IdentityMap.enabled? && association_class && association_class.respond_to?(:base_class)
@target = IdentityMap.get(association_class, owner[reflection.foreign_key])
end
rescue NameError
nil
ensure
@target ||= find_target
end
end
@target ||= find_target if find_target?
loaded! unless loaded?
target
rescue ActiveRecord::RecordNotFound
Expand Down
5 changes: 0 additions & 5 deletions activerecord/lib/active_record/attribute_methods/dirty.rb
Expand Up @@ -22,8 +22,6 @@ def save(*) #:nodoc:
if status = super
@previously_changed = changes
@changed_attributes.clear
elsif IdentityMap.enabled?
IdentityMap.remove(self)
end
status
end
Expand All @@ -34,9 +32,6 @@ def save!(*) #:nodoc:
@previously_changed = changes
@changed_attributes.clear
end
rescue
IdentityMap.remove(self) if IdentityMap.enabled?
raise
end

# <tt>reload</tt> the record and clears changed attributes.
Expand Down
6 changes: 0 additions & 6 deletions activerecord/lib/active_record/autosave_association.rb
Expand Up @@ -328,7 +328,6 @@ def save_collection_association(reflection)
autosave = reflection.options[:autosave]

if records = associated_records_to_validate_or_save(association, @new_record_before_save, autosave)
begin
records.each do |record|
next if record.destroyed?

Expand All @@ -348,11 +347,6 @@ def save_collection_association(reflection)

raise ActiveRecord::Rollback unless saved
end
rescue
records.each {|x| IdentityMap.remove(x) } if IdentityMap.enabled?
raise
end

end

# reconstruct the scope now that we know the owner's id
Expand Down
2 changes: 0 additions & 2 deletions activerecord/lib/active_record/counter_cache.rb
Expand Up @@ -69,8 +69,6 @@ def update_counters(id, counters)
"#{quoted_column} = COALESCE(#{quoted_column}, 0) #{operator} #{value.abs}"
end

IdentityMap.remove_by_id(symbolized_base_class, id) if IdentityMap.enabled?

update_all(updates.join(', '), primary_key => id)
end

Expand Down
4 changes: 1 addition & 3 deletions activerecord/lib/active_record/fixtures.rb
Expand Up @@ -796,9 +796,7 @@ def setup_fixture_accessors(fixture_names = nil)
@fixture_cache[fixture_name].delete(fixture) if force_reload

if @loaded_fixtures[fixture_name][fixture.to_s]
ActiveRecord::IdentityMap.without do
@fixture_cache[fixture_name][fixture] ||= @loaded_fixtures[fixture_name][fixture.to_s].find
end
@fixture_cache[fixture_name][fixture] ||= @loaded_fixtures[fixture_name][fixture.to_s].find
else
raise StandardError, "No entry named '#{fixture}' found for fixture collection '#{fixture_name}'"
end
Expand Down
144 changes: 0 additions & 144 deletions activerecord/lib/active_record/identity_map.rb

This file was deleted.

23 changes: 3 additions & 20 deletions activerecord/lib/active_record/inheritance.rb
Expand Up @@ -63,26 +63,9 @@ def sti_name
# single-table inheritance model that makes it possible to create
# objects of different types from the same table.
def instantiate(record, column_types = {})
sti_class = find_sti_class(record[inheritance_column])
record_id = sti_class.primary_key && record[sti_class.primary_key]

if ActiveRecord::IdentityMap.enabled? && record_id
if (column = sti_class.columns_hash[sti_class.primary_key]) && column.number?
record_id = record_id.to_i
end
if instance = IdentityMap.get(sti_class, record_id)
instance.reinit_with('attributes' => record)
else
instance = sti_class.allocate.init_with('attributes' => record)
IdentityMap.add(instance)
end
else
column_types = sti_class.decorate_columns(column_types)
instance = sti_class.allocate.init_with('attributes' => record,
'column_types' => column_types)
end

instance
sti_class = find_sti_class(record[inheritance_column])
column_types = sti_class.decorate_columns(column_types)
sti_class.allocate.init_with('attributes' => record, 'column_types' => column_types)
end

# For internal use.
Expand Down
1 change: 0 additions & 1 deletion activerecord/lib/active_record/model.rb
Expand Up @@ -60,7 +60,6 @@ def self.extend(*modules)
include AttributeMethods
include Callbacks, ActiveModel::Observing, Timestamp
include Associations
include IdentityMap
include ActiveModel::SecurePassword
include AutosaveAssociation, NestedAttributes
include Aggregations, Transactions, Reflection, Serialization, Store
Expand Down
16 changes: 4 additions & 12 deletions activerecord/lib/active_record/persistence.rb
Expand Up @@ -115,10 +115,7 @@ def save!(*)
# callbacks, Observer methods, or any <tt>:dependent</tt> association
# options, use <tt>#destroy</tt>.
def delete
if persisted?
self.class.delete(id)
IdentityMap.remove(self) if IdentityMap.enabled?
end
self.class.delete(id) if persisted?
@destroyed = true
freeze
end
Expand All @@ -129,7 +126,6 @@ def destroy
destroy_associations

if persisted?
IdentityMap.remove(self) if IdentityMap.enabled?
pk = self.class.primary_key
column = self.class.columns_hash[pk]
substitute = connection.substitute_at(column, 0)
Expand Down Expand Up @@ -284,11 +280,9 @@ def reload(options = nil)
clear_aggregation_cache
clear_association_cache

IdentityMap.without do
fresh_object = self.class.unscoped { self.class.find(id, options) }
@attributes.update(fresh_object.instance_variable_get('@attributes'))
@columns_hash = fresh_object.instance_variable_get('@columns_hash')
end
fresh_object = self.class.unscoped { self.class.find(id, options) }
@attributes.update(fresh_object.instance_variable_get('@attributes'))
@columns_hash = fresh_object.instance_variable_get('@columns_hash')

@attributes_cache = {}
self
Expand Down Expand Up @@ -363,10 +357,8 @@ def create
attributes_values = arel_attributes_with_values_for_create(!id.nil?)

new_id = self.class.unscoped.insert attributes_values

self.id ||= new_id if self.class.primary_key

IdentityMap.add(self) if IdentityMap.enabled?
@new_record = false
id
end
Expand Down
5 changes: 0 additions & 5 deletions activerecord/lib/active_record/railtie.rb
Expand Up @@ -53,11 +53,6 @@ class Railtie < Rails::Railtie
ActiveSupport.on_load(:active_record) { self.logger ||= ::Rails.logger }
end

initializer "active_record.identity_map" do |app|
config.app_middleware.insert_after "::ActionDispatch::Callbacks",
"ActiveRecord::IdentityMap::Middleware" if config.active_record.delete(:identity_map)
end

initializer "active_record.set_configs" do |app|
ActiveSupport.on_load(:active_record) do
if app.config.active_record.delete(:whitelist_attributes)
Expand Down