diff options
author | Aaron Patterson <aaron.patterson@gmail.com> | 2014-02-17 14:55:54 -0800 |
---|---|---|
committer | Aaron Patterson <aaron.patterson@gmail.com> | 2014-02-17 14:55:54 -0800 |
commit | 77b18d7ef47f4dd6bf39853ac83cc19a3593406f (patch) | |
tree | d5d7f6d993fe363bf0bbd79d642d9c860abcbc99 | |
parent | 23ce2f61b5a7699af8213bf1b5d581da194ab8f4 (diff) | |
download | rails-77b18d7ef47f4dd6bf39853ac83cc19a3593406f.tar.gz rails-77b18d7ef47f4dd6bf39853ac83cc19a3593406f.tar.bz2 rails-77b18d7ef47f4dd6bf39853ac83cc19a3593406f.zip |
add AST cache to the find_by method
-rw-r--r-- | activerecord/lib/active_record/core.rb | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/activerecord/lib/active_record/core.rb b/activerecord/lib/active_record/core.rb index d9aaf8597f..adc9383bdc 100644 --- a/activerecord/lib/active_record/core.rb +++ b/activerecord/lib/active_record/core.rb @@ -94,6 +94,7 @@ module ActiveRecord end class_attribute :default_connection_handler, instance_writer: false + class_attribute :find_by_statement_cache def self.connection_handler ActiveRecord::RuntimeRegistry.connection_handler || default_connection_handler @@ -107,6 +108,40 @@ module ActiveRecord end module ClassMethods + def initialize_find_by_cache + self.find_by_statement_cache = {}.extend(Mutex_m) + end + + def inherited(child_class) + child_class.initialize_find_by_cache + super + end + + def find_by(*args) + return super if current_scope || args.length > 1 || reflect_on_all_aggregations.any? + + hash = args.first + + return super if hash.values.any? { |v| v.nil? || Array === v } + + key = hash.keys + + klass = self + s = find_by_statement_cache[key] || find_by_statement_cache.synchronize { + find_by_statement_cache[key] ||= StatementCache.new { |params| + wheres = key.each_with_object({}) { |param,o| + o[param] = params[param] + } + klass.where(wheres).limit(1) + } + } + begin + s.execute(hash).first + rescue TypeError => e + raise ActiveRecord::StatementInvalid.new(e.message, e) + end + end + def initialize_generated_modules super |