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(Book.connection) do |params|
  Book.where(name: "my book").where("author_id > 3")
end

The cached statement is executed by using the [connection.execute]ConnectionAdapters::DatabaseStatements#execute method:

cache.execute([], Book, Book.connection)

The relation returned by the block is cached, and for each [execute]ConnectionAdapters::DatabaseStatements#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(Book.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"], Book, Book.connection)

Defined Under Namespace

Classes: BindMap, Params, PartialQuery, Query, Substitute

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(query_builder, bind_map) ⇒ StatementCache

Returns a new instance of StatementCache.



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

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

Instance Attribute Details

#bind_mapObject (readonly)

Returns the value of attribute bind_map.



90
91
92
# File 'lib/active_record/statement_cache.rb', line 90

def bind_map
  @bind_map
end

#query_builderObject (readonly)

Returns the value of attribute query_builder.



90
91
92
# File 'lib/active_record/statement_cache.rb', line 90

def query_builder
  @query_builder
end

Class Method Details

.create(connection, block = Proc.new) ⇒ Object



92
93
94
95
96
97
# File 'lib/active_record/statement_cache.rb', line 92

def self.create(connection, block = Proc.new)
  relation      = block.call Params.new
  bind_map      = BindMap.new relation.bound_attributes
  query_builder = connection.cacheable_query relation.arel
  new query_builder, bind_map
end

.partial_query(visitor, ast, collector) ⇒ Object



62
63
64
65
# File 'lib/active_record/statement_cache.rb', line 62

def self.partial_query(visitor, ast, collector)
  collected = visitor.accept(ast, collector).value
  PartialQuery.new collected
end

.query(visitor, ast) ⇒ Object



58
59
60
# File 'lib/active_record/statement_cache.rb', line 58

def self.query(visitor, ast)
  Query.new visitor.accept(ast, Arel::Collectors::SQLString.new).value
end

Instance Method Details

#execute(params, klass, connection, &block) ⇒ Object Also known as: call



104
105
106
107
108
109
110
# File 'lib/active_record/statement_cache.rb', line 104

def execute(params, klass, connection, &block)
  bind_values = bind_map.bind params

  sql = query_builder.sql_for bind_values, connection

  klass.find_by_sql(sql, bind_values, preparable: true, &block)
end