From ac4c1c3b0adabecdb1217594fed16db32b27ee9e Mon Sep 17 00:00:00 2001 From: Sean Griffin Date: Tue, 20 May 2014 08:07:02 -0700 Subject: Use the generic type map object for mysql field lookups --- .../connection_adapters/mysql_adapter.rb | 32 ++++++---------------- .../lib/active_record/connection_adapters/type.rb | 2 ++ .../type/hash_lookup_type_map.rb | 15 ++++++++++ .../connection_adapters/type/type_map_test.rb | 13 +++++++++ 4 files changed, 39 insertions(+), 23 deletions(-) create mode 100644 activerecord/lib/active_record/connection_adapters/type/hash_lookup_type_map.rb diff --git a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb index acf4015672..8beb869ce2 100644 --- a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb @@ -297,23 +297,17 @@ module ActiveRecord end end - TYPES = {} + class << self + TYPES = ConnectionAdapters::Type::HashLookupTypeMap.new # :nodoc: - # Register an MySQL +type_id+ with a typecasting object in - # +type+. - def self.register_type(type_id, type) - TYPES[type_id] = type - end - - def self.alias_type(new, old) - TYPES[new] = TYPES[old] - end + delegate :register_type, :alias_type, to: :TYPES - def self.find_type(field) - if field.type == Mysql::Field::TYPE_TINY && field.length > 1 - TYPES[Mysql::Field::TYPE_LONG] - else - TYPES.fetch(field.type) { Type::Value.new } + def find_type(field) + if field.type == Mysql::Field::TYPE_TINY && field.length > 1 + TYPES.lookup(Mysql::Field::TYPE_LONG) + else + TYPES.lookup(field.type) + end end end @@ -322,18 +316,10 @@ module ActiveRecord alias_type Mysql::Field::TYPE_LONGLONG, Mysql::Field::TYPE_LONG alias_type Mysql::Field::TYPE_NEWDECIMAL, Mysql::Field::TYPE_LONG - register_type Mysql::Field::TYPE_VAR_STRING, Type::Value.new - register_type Mysql::Field::TYPE_BLOB, Type::Value.new register_type Mysql::Field::TYPE_DATE, Type::Date.new register_type Mysql::Field::TYPE_DATETIME, Fields::DateTime.new register_type Mysql::Field::TYPE_TIME, Fields::Time.new register_type Mysql::Field::TYPE_FLOAT, Type::Float.new - - Mysql::Field.constants.grep(/TYPE/).map { |class_name| - Mysql::Field.const_get class_name - }.reject { |const| TYPES.key? const }.each do |const| - register_type const, Type::Value.new - end end def initialize_type_map(m) # :nodoc: diff --git a/activerecord/lib/active_record/connection_adapters/type.rb b/activerecord/lib/active_record/connection_adapters/type.rb index fbc4cd7e32..f215266560 100644 --- a/activerecord/lib/active_record/connection_adapters/type.rb +++ b/activerecord/lib/active_record/connection_adapters/type.rb @@ -11,7 +11,9 @@ require 'active_record/connection_adapters/type/integer' require 'active_record/connection_adapters/type/string' require 'active_record/connection_adapters/type/text' require 'active_record/connection_adapters/type/time' + require 'active_record/connection_adapters/type/type_map' +require 'active_record/connection_adapters/type/hash_lookup_type_map' module ActiveRecord module ConnectionAdapters diff --git a/activerecord/lib/active_record/connection_adapters/type/hash_lookup_type_map.rb b/activerecord/lib/active_record/connection_adapters/type/hash_lookup_type_map.rb new file mode 100644 index 0000000000..828ada00a7 --- /dev/null +++ b/activerecord/lib/active_record/connection_adapters/type/hash_lookup_type_map.rb @@ -0,0 +1,15 @@ +module ActiveRecord + module ConnectionAdapters + module Type + class HashLookupTypeMap < TypeMap # :nodoc: + def lookup(type) + @mapping.fetch(type, proc { default_value }).call(type) + end + + def alias_type(type, alias_type) + register_type(type) { lookup(alias_type) } + end + end + end + end +end diff --git a/activerecord/test/cases/connection_adapters/type/type_map_test.rb b/activerecord/test/cases/connection_adapters/type/type_map_test.rb index 300c2ed225..4b4d9f6b0f 100644 --- a/activerecord/test/cases/connection_adapters/type/type_map_test.rb +++ b/activerecord/test/cases/connection_adapters/type/type_map_test.rb @@ -95,6 +95,19 @@ module ActiveRecord mapping.register_type(/only key/i) end end + + def test_lookup_non_strings + mapping = HashLookupTypeMap.new + + mapping.register_type(1, 'string') + mapping.register_type(2, 'int') + mapping.alias_type(3, 1) + + assert_equal mapping.lookup(1), 'string' + assert_equal mapping.lookup(2), 'int' + assert_equal mapping.lookup(3), 'string' + assert_kind_of Type::Value, mapping.lookup(4) + end end end end -- cgit v1.2.3