Class: Scrooge::Optimizations::ResultSets::UpdateableResultSet
- Inherits:
-
Object
- Object
- Scrooge::Optimizations::ResultSets::UpdateableResultSet
- Defined in:
- lib/optimizations/result_sets/updateable_result_set.rb
Instance Attribute Summary collapse
-
#updaters_attributes ⇒ Object
Contains a weak referernce to the result set, and can update from DB.
Instance Method Summary collapse
-
#default_attributes ⇒ Object
When called from after_find and after_initialize, the object being accessed (and causing the reload) is not in the result set yet.
-
#hash_by_primary_key(rows) ⇒ Object
Make an efficient data structure to access items when the primary key is known.
-
#initialize(result_set_array, klass) ⇒ UpdateableResultSet
constructor
A new instance of UpdateableResultSet.
- #primary_key_name ⇒ Object
-
#reload_columns!(columns_to_fetch) ⇒ Object
Called by a ScroogedAttributes hash when it is asked for a column that was not fetched from the DB.
- #reload_columns_for_ids(columns_to_fetch, result_ids_to_fetch) ⇒ Object
-
#result_set ⇒ Object
The result set is weak referenced by its object_id So we check that a unique id matches what we have remembered to make sure that we got the right object (object ids are recycled by ruby).
- #result_set_attributes ⇒ Object
-
#result_set_ids ⇒ Object
Ids of the items to be reloaded.
-
#update_with(remaining_attributes) ⇒ Object
Update the result set with attributes provided, as returned by the sql server.
Constructor Details
#initialize(result_set_array, klass) ⇒ UpdateableResultSet
Returns a new instance of UpdateableResultSet.
11 12 13 14 15 16 17 |
# File 'lib/optimizations/result_sets/updateable_result_set.rb', line 11 def initialize(result_set_array, klass) if result_set_array @result_set_object_id = result_set_array.object_id @unique_id = result_set_array.unique_id ||= "#{Time.now.to_f}#{object_id}" # avoid recycled object ids end @klass = klass # expected class of items in the array end |
Instance Attribute Details
#updaters_attributes ⇒ Object
Contains a weak referernce to the result set, and can update from DB
9 10 11 |
# File 'lib/optimizations/result_sets/updateable_result_set.rb', line 9 def updaters_attributes @updaters_attributes end |
Instance Method Details
#default_attributes ⇒ Object
When called from after_find and after_initialize, the object being accessed (and causing the reload) is not in the result set yet. We make sure that we add its attributes to result_set_attributes so it gets reloaded too
63 64 65 |
# File 'lib/optimizations/result_sets/updateable_result_set.rb', line 63 def default_attributes [@updaters_attributes] end |
#hash_by_primary_key(rows) ⇒ Object
Make an efficient data structure to access items when the primary key is known
94 95 96 |
# File 'lib/optimizations/result_sets/updateable_result_set.rb', line 94 def hash_by_primary_key(rows) rows.inject({}) {|memo, row| memo[row[primary_key_name]] = row; memo} end |
#primary_key_name ⇒ Object
98 99 100 |
# File 'lib/optimizations/result_sets/updateable_result_set.rb', line 98 def primary_key_name @klass.primary_key end |
#reload_columns!(columns_to_fetch) ⇒ Object
Called by a ScroogedAttributes hash when it is asked for a column that was not fetched from the DB
22 23 24 25 26 27 28 29 |
# File 'lib/optimizations/result_sets/updateable_result_set.rb', line 22 def reload_columns!(columns_to_fetch) reloaded_columns = hash_by_primary_key(reload_columns_for_ids(columns_to_fetch, result_set_ids)) if !reloaded_columns.has_key?(@updaters_attributes[primary_key_name]) raise ActiveRecord::MissingAttributeError, "scrooge cannot fetch missing attribute(s) #{columns_to_fetch.to_a.join(', ')} because record went away" else update_with(reloaded_columns) end end |
#reload_columns_for_ids(columns_to_fetch, result_ids_to_fetch) ⇒ Object
31 32 33 |
# File 'lib/optimizations/result_sets/updateable_result_set.rb', line 31 def reload_columns_for_ids(columns_to_fetch, result_ids_to_fetch) @klass.scrooge_reload(result_ids_to_fetch, columns_to_fetch + [primary_key_name]) end |
#result_set ⇒ Object
The result set is weak referenced by its object_id So we check that a unique id matches what we have remembered to make sure that we got the right object (object ids are recycled by ruby)
50 51 52 53 54 55 56 |
# File 'lib/optimizations/result_sets/updateable_result_set.rb', line 50 def result_set return nil unless @result_set_object_id result_set = ObjectSpace._id2ref(@result_set_object_id) result_set.is_a?(ResultArray) && result_set.unique_id == @unique_id ? result_set : nil rescue RangeError nil end |
#result_set_attributes ⇒ Object
35 36 37 38 39 40 41 42 43 44 |
# File 'lib/optimizations/result_sets/updateable_result_set.rb', line 35 def result_set_attributes rs = result_set return default_attributes unless rs rs.inject(default_attributes) do |memo, r| if r.is_a?(@klass) memo << r.instance_variable_get(:@attributes) end memo end.uniq end |
#result_set_ids ⇒ Object
Ids of the items to be reloaded
69 70 71 72 73 74 75 76 |
# File 'lib/optimizations/result_sets/updateable_result_set.rb', line 69 def result_set_ids result_set_attributes.inject([]) do |memo, attributes| unless attributes.fully_fetched memo << attributes[primary_key_name] end memo end end |
#update_with(remaining_attributes) ⇒ Object
Update the result set with attributes provided, as returned by the sql server
81 82 83 84 85 86 87 88 89 |
# File 'lib/optimizations/result_sets/updateable_result_set.rb', line 81 def update_with(remaining_attributes) current_attributes = hash_by_primary_key(result_set_attributes) remaining_attributes.each do |r_id, r_att| old_attributes = current_attributes[r_id] if old_attributes old_attributes.update(r_att.merge(old_attributes)) # must call update, do not use reverse_update end end end |