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:
Matthew Draper 2014-07-12 01:16:08 +09:30
commit dc4945dde9
2 changed files with 29 additions and 14 deletions

@ -50,6 +50,16 @@ def cast_value(value)
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 @@ def supports_explain?
# 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 @@ def quoted_date(value) #:nodoc:
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 @@ def rename_column(table_name, column_name, new_column_name) #:nodoc:
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 @@ def quoted_id
}.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