class ArCache::Query
Attributes
relation[R]
table[R]
where_clause[R]
Public Class Methods
new(relation)
click to toggle source
# File lib/ar_cache/query.rb, line 9 def initialize(relation) @relation = relation @table = @relation.klass.ar_cache_table @where_clause = ArCache::WhereClause.new(@relation.klass, @relation.where_clause.send(:predicates)) end
Public Instance Methods
exec_queries(&block)
click to toggle source
# File lib/ar_cache/query.rb, line 15 def exec_queries(&block) # rubocop:disable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity return [] if relation.where_clause.contradiction? return ArCache.skip_cache { relation.send(:exec_queries, &block) } unless exec_queries_cacheable? records = table.read(where_clause, @select_values, &block) if where_clause.missed_hash.any? missed_relation = relation.rewhere(where_clause.missed_hash).reselect('*') missed_relation = missed_relation.lock(lock_statement) unless cache_lock? missed_relation.arel.singleton_class.attr_accessor(:klass_and_select_values) missed_relation.arel.klass_and_select_values = [relation.klass, @select_values] if cache_lock? records += missed_relation.find_by_sql(missed_relation.arel, &block) else missed_relation.connection.transaction do records += missed_relation.find_by_sql(missed_relation.arel, &block) end end end records_order(records) relation.preload_associations(records) unless relation.skip_preloading_value records.each(&:readonly!) if relation.readonly_value records.each(&:strict_loading!) if relation.strict_loading_value records end
exec_queries_cacheable?()
click to toggle source
# File lib/ar_cache/query.rb, line 45 def exec_queries_cacheable? # rubocop:disable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity return false if table.disabled? return false if relation.skip_query_cache_value return false if relation.lock_value return false if relation.distinct_value return false if relation.group_values.any? return false if relation.joins_values.any? return false if relation.left_outer_joins_values.any? return false if relation.offset_value return false if relation.eager_loading? return false if relation.connection.transaction_manager.transaction_table?(table.name) return false unless relation.from_clause.empty? return false unless where_clause.cacheable? return false unless select_values_cacheable? return false unless order_values_cacheable? return false unless limit_value_cacheable? true end
Private Instance Methods
limit_value_cacheable?()
click to toggle source
# File lib/ar_cache/query.rb, line 98 def limit_value_cacheable? where_clause.single? || relation.limit_value.nil? end
order_values_cacheable?()
click to toggle source
# File lib/ar_cache/query.rb, line 73 def order_values_cacheable? # rubocop:disable Metrics/CyclomaticComplexity return true if where_clause.single? size = relation.order_values.size return true if size.zero? return false if size > 1 first_order_value = relation.order_values.first case first_order_value when Arel::Nodes::Ordering @order_name = first_order_value.expr.name @order_desc = first_order_value.descending? when String @order_name, @order_desc = first_order_value.downcase.split return false unless table.column_names.include?(@order_name) return false unless ['asc', 'desc', nil].include?(@order_desc) @order_desc = @order_desc == 'desc' else return false end true end
records_order(records)
click to toggle source
# File lib/ar_cache/query.rb, line 102 def records_order(records) return records if records.size < 2 method = "#{@order_name || table.primary_key}_for_database" return records.sort! { |a, b| b.send(method) <=> a.send(method) } if @order_desc records.sort! { |a, b| a.send(method) <=> b.send(method) } end
select_values_cacheable?()
click to toggle source
# File lib/ar_cache/query.rb, line 65 def select_values_cacheable? return true if relation.select_values.empty? return false if table.select_disabled? @select_values = relation.select_values.map(&:to_s) (@select_values - table.column_names).empty? end