mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Merge pull request #16055 from sgrif/sg-refactor-sqlite3-strings
Use a type object for type casting behavior on SQLite3
This commit is contained in:
commit
dc4945dde9
2 changed files with 29 additions and 14 deletions
|
@ -50,6 +50,16 @@ module ActiveRecord
|
|||
end
|
||||
end
|
||||
|
||||
class SQLite3String < Type::String # :nodoc:
|
||||
def type_cast_for_database(value)
|
||||
if value.is_a?(::String) && value.encoding == Encoding::ASCII_8BIT
|
||||
value.encode(Encoding::UTF_8)
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# The SQLite3 adapter works SQLite 3.6.16 or newer
|
||||
# with the sqlite3-ruby drivers (available as gem from https://rubygems.org/gems/sqlite3).
|
||||
#
|
||||
|
@ -220,13 +230,23 @@ module ActiveRecord
|
|||
# QUOTING ==================================================
|
||||
|
||||
def _quote(value) # :nodoc:
|
||||
if value.is_a?(Type::Binary::Data)
|
||||
case value
|
||||
when Type::Binary::Data
|
||||
"x'#{value.hex}'"
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
def _type_cast(value) # :nodoc:
|
||||
case value
|
||||
when BigDecimal
|
||||
value.to_f
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
def quote_string(s) #:nodoc:
|
||||
@connection.class.quote(s)
|
||||
end
|
||||
|
@ -249,19 +269,6 @@ module ActiveRecord
|
|||
end
|
||||
end
|
||||
|
||||
def type_cast(value, column) # :nodoc:
|
||||
return value.to_f if BigDecimal === value
|
||||
return super unless String === value
|
||||
return super unless column && value
|
||||
|
||||
value = super
|
||||
if column.type == :string && value.encoding == Encoding::ASCII_8BIT
|
||||
logger.error "Binary data inserted for `string` type on column `#{column.name}`" if logger
|
||||
value = value.encode Encoding::UTF_8
|
||||
end
|
||||
value
|
||||
end
|
||||
|
||||
# DATABASE STATEMENTS ======================================
|
||||
|
||||
def explain(arel, binds = [])
|
||||
|
@ -503,6 +510,7 @@ module ActiveRecord
|
|||
def initialize_type_map(m)
|
||||
super
|
||||
m.register_type(/binary/i, SQLite3Binary.new)
|
||||
register_class_with_limit m, %r(char)i, SQLite3String
|
||||
end
|
||||
|
||||
def select(sql, name = nil, binds = []) #:nodoc:
|
||||
|
|
|
@ -103,6 +103,13 @@ module ActiveRecord
|
|||
}.new
|
||||
assert_raise(TypeError) { @conn.type_cast(quoted_id_obj, nil) }
|
||||
end
|
||||
|
||||
def test_quoting_binary_strings
|
||||
value = "hello".encode('ascii-8bit')
|
||||
column = Column.new(nil, 1, SQLite3String.new)
|
||||
|
||||
assert_equal "'hello'", @conn.quote(value, column)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue