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
|
||||||
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:
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue