diff options
author | Sean Griffin <sean@thoughtbot.com> | 2014-07-01 08:11:59 -0600 |
---|---|---|
committer | Sean Griffin <sean@thoughtbot.com> | 2014-07-11 07:29:12 -0600 |
commit | d739dd1627d1b20bde417045558848fe92a82d6c (patch) | |
tree | c495fd9dc64bcf0db4ca32e57017ae47a818eddd /activerecord | |
parent | 898bc73a53f4a4ba7695ed1cc81e3d94ab62b253 (diff) | |
download | rails-d739dd1627d1b20bde417045558848fe92a82d6c.tar.gz rails-d739dd1627d1b20bde417045558848fe92a82d6c.tar.bz2 rails-d739dd1627d1b20bde417045558848fe92a82d6c.zip |
Use a type object for type casting behavior on SQLite3
Diffstat (limited to 'activerecord')
-rw-r--r-- | activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb | 36 | ||||
-rw-r--r-- | activerecord/test/cases/adapters/sqlite3/quoting_test.rb | 7 |
2 files changed, 29 insertions, 14 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb index e6163771e8..2905cf4a01 100644 --- a/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb @@ -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: diff --git a/activerecord/test/cases/adapters/sqlite3/quoting_test.rb b/activerecord/test/cases/adapters/sqlite3/quoting_test.rb index 3bd53aa278..ac8332e2fa 100644 --- a/activerecord/test/cases/adapters/sqlite3/quoting_test.rb +++ b/activerecord/test/cases/adapters/sqlite3/quoting_test.rb @@ -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 |