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

Use a type object for type casting behavior on SQLite3

This commit is contained in:
Sean Griffin 2014-07-01 08:11:59 -06:00
parent 898bc73a53
commit d739dd1627
2 changed files with 29 additions and 14 deletions

View file

@ -50,6 +50,16 @@ module ActiveRecord
end end
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 # The SQLite3 adapter works SQLite 3.6.16 or newer
# with the sqlite3-ruby drivers (available as gem from https://rubygems.org/gems/sqlite3). # with the sqlite3-ruby drivers (available as gem from https://rubygems.org/gems/sqlite3).
# #
@ -220,13 +230,23 @@ module ActiveRecord
# QUOTING ================================================== # QUOTING ==================================================
def _quote(value) # :nodoc: def _quote(value) # :nodoc:
if value.is_a?(Type::Binary::Data) case value
when Type::Binary::Data
"x'#{value.hex}'" "x'#{value.hex}'"
else else
super super
end end
end end
def _type_cast(value) # :nodoc:
case value
when BigDecimal
value.to_f
else
super
end
end
def quote_string(s) #:nodoc: def quote_string(s) #:nodoc:
@connection.class.quote(s) @connection.class.quote(s)
end end
@ -249,19 +269,6 @@ module ActiveRecord
end end
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 ====================================== # DATABASE STATEMENTS ======================================
def explain(arel, binds = []) def explain(arel, binds = [])
@ -503,6 +510,7 @@ module ActiveRecord
def initialize_type_map(m) def initialize_type_map(m)
super super
m.register_type(/binary/i, SQLite3Binary.new) m.register_type(/binary/i, SQLite3Binary.new)
register_class_with_limit m, %r(char)i, SQLite3String
end end
def select(sql, name = nil, binds = []) #:nodoc: def select(sql, name = nil, binds = []) #:nodoc:

View file

@ -103,6 +103,13 @@ module ActiveRecord
}.new }.new
assert_raise(TypeError) { @conn.type_cast(quoted_id_obj, nil) } assert_raise(TypeError) { @conn.type_cast(quoted_id_obj, nil) }
end 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 end
end end