From fbfb52a7761dc00e90eaa1ed0063763b3a6e2eb3 Mon Sep 17 00:00:00 2001 From: Andy Date: Tue, 5 Jul 2022 09:58:03 -0400 Subject: [PATCH 1/2] Lazy load type mappings This appears to fix issue #2256. I believe it should have the same memory implications as the intention in #2199. The type maps are loaded once when they are first called. Only one instance of the mapping is ever created. Fortunately this was enough to solve the problem, but if there were a need, this could easily be worked into the clear_cache! API to reset it at a later point in the application just by setting the @type_map to nil. --- .../oracle_enhanced_adapter.rb | 18 +++++++++++++++--- .../oracle_enhanced/type/integer_spec.rb | 8 ++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb b/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb index 85296d9f5..8b170de47 100644 --- a/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb +++ b/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb @@ -459,6 +459,11 @@ def reconnect! # :nodoc: @logger.warn "#{adapter_name} automatic reconnection failed: #{e.message}" if @logger end + def clear_cache! + self.class.clear_type_map! + super + end + def reset! clear_cache! super @@ -697,6 +702,15 @@ def check_version end class << self + def type_map + @type_map ||= Type::TypeMap.new.tap { |m| initialize_type_map(m) } + @type_map + end + + def clear_type_map! + @type_map = nil + end + private def initialize_type_map(m) super @@ -730,10 +744,8 @@ def initialize_type_map(m) end end - TYPE_MAP = Type::TypeMap.new.tap { |m| initialize_type_map(m) } - def type_map - TYPE_MAP + self.class.type_map end def extract_value_from_default(default) diff --git a/spec/active_record/oracle_enhanced/type/integer_spec.rb b/spec/active_record/oracle_enhanced/type/integer_spec.rb index 6daeb8a80..fe49ad368 100644 --- a/spec/active_record/oracle_enhanced/type/integer_spec.rb +++ b/spec/active_record/oracle_enhanced/type/integer_spec.rb @@ -87,5 +87,13 @@ class ::Test2Employee < ActiveRecord::Base create_employee2 expect(@employee2.is_manager).to be_a(Integer) end + + it "should return Integer value from NUMBER(1) column if emulate_booleans is set to false" do + ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_booleans = false + ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.clear_type_map! + ActiveRecord::Base.clear_cache! + create_employee2 + expect(@employee2.is_manager).to be_a(Integer) + end end end From b61454741d3dca7f636aa3ccc6e0ca430ffef975 Mon Sep 17 00:00:00 2001 From: Andy Date: Wed, 6 Jul 2022 08:36:02 -0400 Subject: [PATCH 2/2] Pass along clear_cache! args. --- .../connection_adapters/oracle_enhanced_adapter.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb b/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb index 8b170de47..d623b5e84 100644 --- a/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb +++ b/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb @@ -459,9 +459,9 @@ def reconnect! # :nodoc: @logger.warn "#{adapter_name} automatic reconnection failed: #{e.message}" if @logger end - def clear_cache! - self.class.clear_type_map! + def clear_cache!(*args, **kwargs) super + self.class.clear_type_map! end def reset!