From 0ada76cb7c879261e76bc96d02b60d81f86a6f5f Mon Sep 17 00:00:00 2001 From: Sean Griffin Date: Tue, 1 Jul 2014 08:11:59 -0600 Subject: Use a type object for type casting behavior on SQLite3 Note: I'm not sure we actually need to be logging when this happens. This code would be a fair bit cleaner if we didn't need to log it. --- .../connection_adapters/sqlite3_adapter.rb | 50 ++++++++++++++++------ 1 file changed, 37 insertions(+), 13 deletions(-) (limited to 'activerecord/lib/active_record') diff --git a/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb index e6163771e8..360922dfaa 100644 --- a/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb @@ -50,6 +50,34 @@ module ActiveRecord end end + class SQLite3String < Type::String # :nodoc: + def initialize(logger, *args) + @logger = logger + super(*args) + end + + def type_cast_for_database(value) + return unless value + + if value.encoding == Encoding::ASCII_8BIT + @logger.error "Binary data inserted for `string` type" if @logger + value.encode Encoding::UTF_8 + else + value + end + end + + class Factory + def initialize(logger) + @logger = logger + end + + def new(*args) + SQLite3String.new(@logger, *args) + 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). # @@ -227,6 +255,14 @@ module ActiveRecord end end + def _type_cast(value) # :nodoc: + if value.is_a?(BigDecimal) + value.to_f + else + super + end + end + def quote_string(s) #:nodoc: @connection.class.quote(s) end @@ -249,19 +285,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 +526,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::Factory.new(logger) end def select(sql, name = nil, binds = []) #:nodoc: -- cgit v1.2.3