1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Passing klass to StatementCache.new

Actually `StatementCache#execute` is always passed the same klass that
the owner klass of the connection when the statement cache is created.
So passing `klass` to `StatementCache.new` will make more DRY.
This commit is contained in:
Ryuta Kamizono 2017-08-03 06:35:20 +09:00
parent c6dcee4770
commit 510428ff64
6 changed files with 31 additions and 32 deletions

View file

@ -304,15 +304,13 @@ module ActiveRecord
return scope.to_a if skip_statement_cache?(scope)
conn = klass.connection
sc = reflection.association_scope_cache(conn, owner) do
StatementCache.create(conn) { |params|
as = AssociationScope.create { params.bind }
target_scope.merge!(as.scope(self))
}
sc = reflection.association_scope_cache(conn, owner) do |params|
as = AssociationScope.create { params.bind }
target_scope.merge!(as.scope(self))
end
binds = AssociationScope.get_bind_values(owner, reflection.chain)
sc.execute(binds, klass, conn) do |record|
sc.execute(binds, conn) do |record|
set_inverse_instance(record)
end
end

View file

@ -41,15 +41,13 @@ module ActiveRecord
return scope.take if skip_statement_cache?(scope)
conn = klass.connection
sc = reflection.association_scope_cache(conn, owner) do
StatementCache.create(conn) { |params|
as = AssociationScope.create { params.bind }
target_scope.merge!(as.scope(self)).limit(1)
}
sc = reflection.association_scope_cache(conn, owner) do |params|
as = AssociationScope.create { params.bind }
target_scope.merge!(as.scope(self)).limit(1)
end
binds = AssociationScope.get_bind_values(owner, reflection.chain)
sc.execute(binds, klass, conn) do |record|
sc.execute(binds, conn) do |record|
set_inverse_instance record
end.first
rescue ::RangeError

View file

@ -176,7 +176,7 @@ module ActiveRecord
where(key => params.bind).limit(1)
}
record = statement.execute([id], self, connection).first
record = statement.execute([id], connection).first
unless record
raise RecordNotFound.new("Couldn't find #{name} with '#{primary_key}'=#{id}",
name, primary_key, id)
@ -208,7 +208,7 @@ module ActiveRecord
where(wheres).limit(1)
}
begin
statement.execute(hash.values, self, connection).first
statement.execute(hash.values, connection).first
rescue TypeError
raise ActiveRecord::StatementInvalid
rescue ::RangeError

View file

@ -458,13 +458,13 @@ module ActiveRecord
end
end
def association_scope_cache(conn, owner)
def association_scope_cache(conn, owner, &block)
key = conn.prepared_statements
if polymorphic?
key = [key, owner._read_attribute(@foreign_type)]
end
@association_scope_cache[key] ||= @scope_lock.synchronize {
@association_scope_cache[key] ||= yield
@association_scope_cache[key] ||= StatementCache.create(conn, &block)
}
end

View file

@ -11,7 +11,7 @@ module ActiveRecord
# The cached statement is executed by using the
# {connection.execute}[rdoc-ref:ConnectionAdapters::DatabaseStatements#execute] method:
#
# cache.execute([], Book, Book.connection)
# cache.execute([], Book.connection)
#
# The relation returned by the block is cached, and for each
# {execute}[rdoc-ref:ConnectionAdapters::DatabaseStatements#execute]
@ -26,7 +26,7 @@ module ActiveRecord
#
# And pass the bind values as the first argument of +execute+ call.
#
# cache.execute(["my book"], Book, Book.connection)
# cache.execute(["my book"], Book.connection)
class StatementCache # :nodoc:
class Substitute; end # :nodoc:
@ -87,21 +87,20 @@ module ActiveRecord
end
end
attr_reader :bind_map, :query_builder
def self.create(connection, block = Proc.new)
relation = block.call Params.new
query_builder, binds = connection.cacheable_query(self, relation.arel)
bind_map = BindMap.new(binds)
new query_builder, bind_map
new(query_builder, bind_map, relation.klass)
end
def initialize(query_builder, bind_map)
def initialize(query_builder, bind_map, klass)
@query_builder = query_builder
@bind_map = bind_map
@bind_map = bind_map
@klass = klass
end
def execute(params, klass, connection, &block)
def execute(params, connection, &block)
bind_values = bind_map.bind params
sql = query_builder.sql_for bind_values, connection
@ -114,5 +113,9 @@ module ActiveRecord
when NilClass, Array, Range, Hash, Relation, Base then true
end
end
protected
attr_reader :query_builder, :bind_map, :klass
end
end

View file

@ -21,9 +21,9 @@ module ActiveRecord
Book.where(name: params.bind)
end
b = cache.execute([ "my book" ], Book, Book.connection)
b = cache.execute([ "my book" ], Book.connection)
assert_equal "my book", b[0].name
b = cache.execute([ "my other book" ], Book, Book.connection)
b = cache.execute([ "my other book" ], Book.connection)
assert_equal "my other book", b[0].name
end
@ -35,9 +35,9 @@ module ActiveRecord
Book.where(id: params.bind)
end
b = cache.execute([ b1.id ], Book, Book.connection)
b = cache.execute([ b1.id ], Book.connection)
assert_equal b1.name, b[0].name
b = cache.execute([ b2.id ], Book, Book.connection)
b = cache.execute([ b2.id ], Book.connection)
assert_equal b2.name, b[0].name
end
@ -60,7 +60,7 @@ module ActiveRecord
Book.create(name: "my book", author_id: 4)
books = cache.execute([], Book, Book.connection)
books = cache.execute([], Book.connection)
assert_equal "my book", books[0].name
end
@ -73,7 +73,7 @@ module ActiveRecord
molecule = salty.molecules.create(name: "dioxane")
molecule.electrons.create(name: "lepton")
liquids = cache.execute([], Book, Book.connection)
liquids = cache.execute([], Book.connection)
assert_equal "salty", liquids[0].name
end
@ -86,13 +86,13 @@ module ActiveRecord
Book.create(name: "my book")
end
first_books = cache.execute([], Book, Book.connection)
first_books = cache.execute([], Book.connection)
3.times do
Book.create(name: "my book")
end
additional_books = cache.execute([], Book, Book.connection)
additional_books = cache.execute([], Book.connection)
assert first_books != additional_books
end