提交 f814585b 编写于 作者: R Ryuta Kamizono

Pass `type_casted_binds` to log subscriber for logging bind values properly

Address to https://github.com/rails/rails/commit/5a302bf553af0e6fedfc63299fc5cd6e79599ef3#commitcomment-18288388.
上级 5a302bf5
......@@ -579,14 +579,15 @@ def translate_exception_class(e, sql)
exception
end
def log(sql, name = "SQL", binds = [], statement_name = nil)
def log(sql, name = "SQL", binds = [], type_casted_binds = [], statement_name = nil)
@instrumenter.instrument(
"sql.active_record",
:sql => sql,
:name => name,
:connection_id => object_id,
:statement_name => statement_name,
:binds => binds) { yield }
sql: sql,
name: name,
binds: binds,
type_casted_binds: type_casted_binds,
statement_name: statement_name,
connection_id: object_id) { yield }
rescue => e
raise translate_exception_class(e, sql)
end
......
......@@ -79,7 +79,7 @@ def exec_stmt_and_free(sql, name, binds, cache_stmt: false)
type_casted_binds = binds.map { |attr| type_cast(attr.value_for_database) }
log(sql, name, binds) do
log(sql, name, binds, type_casted_binds) do
if cache_stmt
cache = @statements[sql] ||= {
stmt: @connection.prepare(sql)
......
......@@ -598,14 +598,14 @@ def execute_and_clear(sql, name, binds, prepare: false)
def exec_no_cache(sql, name, binds)
type_casted_binds = binds.map { |attr| type_cast(attr.value_for_database) }
log(sql, name, binds) { @connection.async_exec(sql, type_casted_binds) }
log(sql, name, binds, type_casted_binds) { @connection.async_exec(sql, type_casted_binds) }
end
def exec_cache(sql, name, binds)
stmt_key = prepare_statement(sql)
type_casted_binds = binds.map { |attr| type_cast(attr.value_for_database) }
log(sql, name, binds, stmt_key) do
log(sql, name, binds, type_casted_binds, stmt_key) do
@connection.exec_prepared(stmt_key, type_casted_binds)
end
rescue ActiveRecord::StatementInvalid => e
......
......@@ -190,7 +190,7 @@ def explain(arel, binds = [])
def exec_query(sql, name = nil, binds = [], prepare: false)
type_casted_binds = binds.map { |attr| type_cast(attr.value_for_database) }
log(sql, name, binds) do
log(sql, name, binds, type_casted_binds) do
# Don't cache statements if they are not prepared
unless prepare
stmt = @connection.prepare(sql)
......
......@@ -20,18 +20,14 @@ def initialize
@odd = false
end
def render_bind(attribute)
value = if attribute.type.binary? && attribute.value
if attribute.value.is_a?(Hash)
"<#{attribute.value_for_database.to_s.bytesize} bytes of binary data>"
else
"<#{attribute.value.bytesize} bytes of binary data>"
end
def render_bind(attr, type_casted_value)
value = if attr.type.binary? && attr.value
"<#{attr.value_for_database.to_s.bytesize} bytes of binary data>"
else
type_cast(attribute.value_for_database)
type_casted_value
end
[attribute.name, value]
[attr.name, value]
end
def sql(event)
......@@ -48,7 +44,9 @@ def sql(event)
binds = nil
unless (payload[:binds] || []).empty?
binds = " " + payload[:binds].map { |attr| render_bind(attr) }.inspect
binds = " " + payload[:binds].zip(payload[:type_casted_binds]).map { |attr, value|
render_bind(attr, value)
}.inspect
end
name = colorize_payload_name(name, payload[:name])
......@@ -91,10 +89,6 @@ def sql_color(sql)
def logger
ActiveRecord::Base.logger
end
def type_cast(value)
ActiveRecord::Base.connection.type_cast(value)
end
end
end
......
......@@ -57,10 +57,13 @@ def test_find_one_uses_binds
end
def test_logs_bind_vars_after_type_cast
binds = [Relation::QueryAttribute.new("id", "10", Type::Integer.new)]
type_casted_binds = binds.map { |attr| type_cast(attr.value_for_database) }
payload = {
:name => 'SQL',
:sql => 'select * from topics where id = ?',
:binds => [Relation::QueryAttribute.new("id", "10", Type::Integer.new)]
:binds => binds,
:type_casted_binds => type_casted_binds
}
event = ActiveSupport::Notifications::Event.new(
'foo',
......@@ -84,6 +87,12 @@ def debug str
logger.sql event
assert_match([[@pk.name, 10]].inspect, logger.debugs.first)
end
private
def type_cast(value)
ActiveRecord::Base.connection.type_cast(value)
end
end
end
end
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册