Class: ActiveRecord::StatementCache

Inherits:
Object
  • Object
show all
Defined in:
lib/active_record/statement_cache.rb

Overview

Statement cache is used to cache a single statement in order to avoid creating the AST again. Initializing the cache is done by passing the statement in the create block:

cache = StatementCache.create(ClothingItem.lease_connection) do |params|
  Book.where(name: "my book").where("author_id > 3")
end

The cached statement is executed by using the connection.execute method:

cache.execute([], ClothingItem.lease_connection)

The relation returned by the block is cached, and for each execute call the cached relation gets duped. Database is queried when to_a is called on the relation.

If you want to cache the statement without the values you can use the bind method of the block parameter.

cache = StatementCache.create(ClothingItem.lease_connection) do |params|
  Book.where(name: params.bind)
end

And pass the bind values as the first argument of execute call.

cache.execute(["my book"], ClothingItem.lease_connection)

Defined Under Namespace

Classes: BindMap, Params, PartialQuery, PartialQueryCollector, Query, Substitute

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(query_builder, bind_map, model) ⇒ StatementCache

Returns a new instance of StatementCache.



139
140
141
142
143
# File 'lib/active_record/statement_cache.rb', line 139

def initialize(query_builder, bind_map, model)
  @query_builder = query_builder
  @bind_map = bind_map
  @model = model
end

Class Method Details

.create(connection, callable = nil, &block) ⇒ Object



132
133
134
135
136
137
# File 'lib/active_record/statement_cache.rb', line 132

def self.create(connection, callable = nil, &block)
  relation = (callable || block).call Params.new
  query_builder, binds = connection.cacheable_query(self, relation.arel)
  bind_map = BindMap.new(binds)
  new(query_builder, bind_map, relation.model)
end

.partial_query(values) ⇒ Object



101
102
103
# File 'lib/active_record/statement_cache.rb', line 101

def self.partial_query(values)
  PartialQuery.new(values)
end

.partial_query_collectorObject



105
106
107
# File 'lib/active_record/statement_cache.rb', line 105

def self.partial_query_collector
  PartialQueryCollector.new
end

.query(sql) ⇒ Object



97
98
99
# File 'lib/active_record/statement_cache.rb', line 97

def self.query(sql)
  Query.new(sql)
end

.unsupported_value?(value) ⇒ Boolean

Returns:

  • (Boolean)


158
159
160
161
162
# File 'lib/active_record/statement_cache.rb', line 158

def self.unsupported_value?(value)
  case value
  when NilClass, Array, Range, Hash, Relation, Base then true
  end
end

Instance Method Details

#execute(params, connection, allow_retry: false, async: false, &block) ⇒ Object



145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/active_record/statement_cache.rb', line 145

def execute(params, connection, allow_retry: false, async: false, &block)
  bind_values = @bind_map.bind params
  sql = @query_builder.sql_for bind_values, connection

  if async
    @model.async_find_by_sql(sql, bind_values, preparable: true, allow_retry: allow_retry, &block)
  else
    @model.find_by_sql(sql, bind_values, preparable: true, allow_retry: allow_retry, &block)
  end
rescue ::RangeError
  async ? Promise.wrap([]) : []
end