activerecord/lib/active_record/connection_adapters/mysql/quoting.rb
# frozen_string_literal: true
require "active_support/time_with_zone"
module ActiveRecord
module ConnectionAdapters
module MySQL
module Quoting # :nodoc:
extend ActiveSupport::Concern
QUOTED_COLUMN_NAMES = Concurrent::Map.new # :nodoc:
QUOTED_TABLE_NAMES = Concurrent::Map.new # :nodoc:
module ClassMethods # :nodoc:
def column_name_matcher
/
\A
(
(?:
# `table_name`.`column_name` | function(one or no argument)
((?:\w+\.|`\w+`\.)?(?:\w+|`\w+`) | \w+\((?:|\g<2>)\))
)
(?:(?:\s+AS)?\s+(?:\w+|`\w+`))?
)
(?:\s*,\s*\g<1>)*
\z
/ix
end
def column_name_with_order_matcher
/
\A
(
(?:
# `table_name`.`column_name` | function(one or no argument)
((?:\w+\.|`\w+`\.)?(?:\w+|`\w+`) | \w+\((?:|\g<2>)\))
)
(?:\s+COLLATE\s+(?:\w+|"\w+"))?
(?:\s+ASC|\s+DESC)?
)
(?:\s*,\s*\g<1>)*
\z
/ix
end
def quote_column_name(name)
QUOTED_COLUMN_NAMES[name] ||= "`#{name.to_s.gsub('`', '``')}`".freeze
end
def quote_table_name(name)
QUOTED_TABLE_NAMES[name] ||= "`#{name.to_s.gsub('`', '``').gsub(".", "`.`")}`".freeze
end
end
def cast_bound_value(value)
case value
when Rational
value.to_f.to_s
when Numeric
value.to_s
when BigDecimal
value.to_s("F")
when true
"1"
when false
"0"
else
value
end
end
def unquoted_true
1
end
def unquoted_false
0
end
def quoted_date(value)
if supports_datetime_with_precision?
super
else
super.sub(/\.\d{6}\z/, "")
end
end
def quoted_binary(value)
"x'#{value.hex}'"
end
def unquote_identifier(identifier)
if identifier && identifier.start_with?("`")
identifier[1..-2]
else
identifier
end
end
# Override +type_cast+ we pass to mysql2 Date and Time objects instead
# of Strings since MySQL adapters are able to handle those classes more efficiently.
def type_cast(value) # :nodoc:
case value
when ActiveSupport::TimeWithZone
# We need to check explicitly for ActiveSupport::TimeWithZone because
# we need to transform it to Time objects but we don't want to
# transform Time objects to themselves.
if default_timezone == :utc
value.getutc
else
value.getlocal
end
when Date, Time
value
else
super
end
end
end
end
end
end