diff options
author | Aaron Patterson <aaron.patterson@gmail.com> | 2011-08-25 16:07:44 -0700 |
---|---|---|
committer | Aaron Patterson <aaron.patterson@gmail.com> | 2011-08-25 16:07:54 -0700 |
commit | 42a7979cf1810c75343b18007858b81718b90678 (patch) | |
tree | 98a7724f5de7f31984acfc910cf12b9ae54ee20b | |
parent | 635b9d4ca8447aeb7c90807b469b605ff1a064ff (diff) | |
download | rails-42a7979cf1810c75343b18007858b81718b90678.tar.gz rails-42a7979cf1810c75343b18007858b81718b90678.tar.bz2 rails-42a7979cf1810c75343b18007858b81718b90678.zip |
Force binary data inserted for a string data type to utf-8 and log an
error. Strings tagged as binary will be stored in sqlite3 as blobs. It
is an error to insert binary data to a string column, so an error is
emitted in the log file. People are highly encouraged to track down the
source of the binary strings and make sure that the encoding is set
correctly before inserting to the database.
-rw-r--r-- | activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb | 21 | ||||
-rw-r--r-- | activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb | 16 |
2 files changed, 34 insertions, 3 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb index da86957028..1996e49296 100644 --- a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb @@ -161,10 +161,25 @@ module ActiveRecord end end - def type_cast(value, column) # :nodoc: - return super unless BigDecimal === value + if "<3".encoding_aware? + 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}`" + value.encode! 'utf-8' + end + value + end + else + def type_cast(value, column) # :nodoc: + return super unless BigDecimal === value - value.to_f + value.to_f + end end # DATABASE STATEMENTS ====================================== diff --git a/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb b/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb index 6ff04e3eb3..2b598220ee 100644 --- a/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb +++ b/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb @@ -1,5 +1,6 @@ # encoding: utf-8 require "cases/helper" +require 'models/owner' module ActiveRecord module ConnectionAdapters @@ -19,6 +20,21 @@ module ActiveRecord eosql end + def test_column_types + return skip('only test encoding on 1.9') unless "<3".encoding_aware? + + owner = Owner.create!(:name => "hello".encode('ascii-8bit')) + owner.reload + select = Owner.columns.map { |c| "typeof(#{c.name})" }.join ', ' + result = Owner.connection.exec_query <<-esql + SELECT #{select} + FROM #{Owner.table_name} + WHERE #{Owner.primary_key} = #{owner.id} + esql + + assert(!result.rows.first.include?("blob"), "should not store blobs") + end + def test_exec_insert column = @conn.columns('items').find { |col| col.name == 'number' } vals = [[column, 10]] |