aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
authorAaron Patterson <aaron.patterson@gmail.com>2011-08-25 16:07:44 -0700
committerAaron Patterson <aaron.patterson@gmail.com>2011-08-25 16:07:54 -0700
commit42a7979cf1810c75343b18007858b81718b90678 (patch)
tree98a7724f5de7f31984acfc910cf12b9ae54ee20b /activerecord
parent635b9d4ca8447aeb7c90807b469b605ff1a064ff (diff)
downloadrails-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.
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb21
-rw-r--r--activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb16
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]]