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

90 lines
2.4 KiB
Ruby
Raw Normal View History

require 'cases/helper'
2011-02-10 12:56:50 -05:00
require 'models/topic'
require 'models/author'
require 'models/post'
2011-02-10 12:56:50 -05:00
module ActiveRecord
class BindParameterTest < ActiveRecord::TestCase
fixtures :topics, :authors, :posts
2011-02-10 12:56:50 -05:00
class LogListener
attr_accessor :calls
def initialize
@calls = []
end
def call(*args)
calls << args
end
end
def setup
super
@connection = ActiveRecord::Base.connection
@subscriber = LogListener.new
rm `Column#cast_type` The type from the column is never used, except when being passed to the attributes API. While leaving the type on the column wasn't necessarily a bad thing, I worry that it's existence there implies that it is something which should be used. During the design and implementation process of the attributes API, there have been plenty of cases where getting the "right" type object was hard, but I had easy access to the column objects. For any contributor who isn't intimately familiar with the intents behind the type casting system, grabbing the type from the column might easily seem like the "correct" thing to do. As such, the goal of this change is to express that the column is not something that should be used for type casting. The only places that are "valid" (at the time of this commit) uses of acquiring a type object from the column are fixtures (as the YAML file is going to mirror the database more closely than the AR object), and looking up the type during schema detection to pass to the attributes API Many of the failing tests were removed, as they've been made obsolete over the last year. All of the PG column tests were testing nothing beyond polymorphism. The Mysql2 tests were duplicating the mysql tests, since they now share a column class. The implementation is a little hairy, and slightly verbose, but it felt preferable to going back to 20 constructor options for the columns. If you are git blaming to figure out wtf I was thinking with them, and have a better idea, go for it. Just don't use a type object for this.
2015-02-03 12:06:10 -05:00
@pk = Topic.columns_hash[Topic.primary_key]
@subscription = ActiveSupport::Notifications.subscribe('sql.active_record', @subscriber)
2011-02-10 12:56:50 -05:00
end
teardown do
ActiveSupport::Notifications.unsubscribe(@subscription)
2011-02-10 12:56:50 -05:00
end
if ActiveRecord::Base.connection.supports_statement_cache? &&
ActiveRecord::Base.connection.prepared_statements
def test_bind_from_join_in_subquery
subquery = Author.joins(:thinking_posts).where(name: 'David')
scope = Author.from(subquery, 'authors').where(id: 1)
assert_equal 1, scope.count
end
def test_binds_are_logged
sub = Arel::Nodes::BindParam.new
binds = [Relation::QueryAttribute.new("id", 1, Type::Value.new)]
sql = "select * from topics where id = #{sub.to_sql}"
2011-02-10 12:56:50 -05:00
@connection.exec_query(sql, 'SQL', binds)
2011-02-10 12:56:50 -05:00
message = @subscriber.calls.find { |args| args[4][:sql] == sql }
assert_equal binds, message[4][:binds]
end
def test_find_one_uses_binds
Topic.find(1)
message = @subscriber.calls.find { |args| args[4][:binds].any? { |attr| attr.value == 1 } }
assert message, 'expected a message with binds'
end
def test_logs_bind_vars_after_type_cast
payload = {
:name => 'SQL',
:sql => 'select * from topics where id = ?',
:binds => [Relation::QueryAttribute.new("id", "10", Type::Integer.new)]
}
event = ActiveSupport::Notifications::Event.new(
'foo',
Time.now,
Time.now,
123,
payload)
logger = Class.new(ActiveRecord::LogSubscriber) {
attr_reader :debugs
def initialize
super
@debugs = []
end
def debug str
@debugs << str
end
}.new
logger.sql event
assert_match([[@pk.name, 10]].inspect, logger.debugs.first)
end
end
2011-02-10 12:56:50 -05:00
end
end