Skip to content

Commit 34ca92b

Browse files
koicyahonda
authored andcommitted
Define adapter type maps statically when possible
rails/rails@d79fb96
1 parent 8289378 commit 34ca92b

File tree

2 files changed

+86
-83
lines changed

2 files changed

+86
-83
lines changed

lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,6 @@ def execute(sql, name = nil, async: false)
1313
log(sql, name, async: async) { @connection.exec(sql) }
1414
end
1515

16-
def clear_cache! # :nodoc:
17-
reload_type_map
18-
super
19-
end
20-
2116
def exec_query(sql, name = "SQL", binds = [], prepare: false, async: false)
2217
type_casted_binds = type_casted_binds(binds)
2318

lib/active_record/connection_adapters/oracle_enhanced_adapter.rb

Lines changed: 86 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -690,98 +690,106 @@ def check_version
690690
end
691691
end
692692

693-
private
694-
def initialize_type_map(m = type_map)
695-
super
696-
# oracle
697-
register_class_with_precision m, %r(WITH TIME ZONE)i, Type::OracleEnhanced::TimestampTz
698-
register_class_with_precision m, %r(WITH LOCAL TIME ZONE)i, Type::OracleEnhanced::TimestampLtz
699-
register_class_with_limit m, %r(raw)i, Type::OracleEnhanced::Raw
700-
register_class_with_limit m, %r{^(char)}i, Type::OracleEnhanced::CharacterString
701-
register_class_with_limit m, %r{^(nchar)}i, Type::OracleEnhanced::String
702-
register_class_with_limit m, %r(varchar)i, Type::OracleEnhanced::String
703-
register_class_with_limit m, %r(clob)i, Type::OracleEnhanced::Text
704-
register_class_with_limit m, %r(nclob)i, Type::OracleEnhanced::NationalCharacterText
705-
706-
m.register_type "NCHAR", Type::OracleEnhanced::NationalCharacterString.new
707-
m.alias_type %r(NVARCHAR2)i, "NCHAR"
708-
709-
m.register_type(%r(NUMBER)i) do |sql_type|
710-
scale = extract_scale(sql_type)
711-
precision = extract_precision(sql_type)
712-
limit = extract_limit(sql_type)
713-
if scale == 0
714-
Type::OracleEnhanced::Integer.new(precision: precision, limit: limit)
715-
else
716-
Type::Decimal.new(precision: precision, scale: scale)
693+
class << self
694+
private
695+
def initialize_type_map(m)
696+
super
697+
# oracle
698+
register_class_with_precision m, %r(WITH TIME ZONE)i, Type::OracleEnhanced::TimestampTz
699+
register_class_with_precision m, %r(WITH LOCAL TIME ZONE)i, Type::OracleEnhanced::TimestampLtz
700+
register_class_with_limit m, %r(raw)i, Type::OracleEnhanced::Raw
701+
register_class_with_limit m, %r{^(char)}i, Type::OracleEnhanced::CharacterString
702+
register_class_with_limit m, %r{^(nchar)}i, Type::OracleEnhanced::String
703+
register_class_with_limit m, %r(varchar)i, Type::OracleEnhanced::String
704+
register_class_with_limit m, %r(clob)i, Type::OracleEnhanced::Text
705+
register_class_with_limit m, %r(nclob)i, Type::OracleEnhanced::NationalCharacterText
706+
707+
m.register_type "NCHAR", Type::OracleEnhanced::NationalCharacterString.new
708+
m.alias_type %r(NVARCHAR2)i, "NCHAR"
709+
710+
m.register_type(%r(NUMBER)i) do |sql_type|
711+
scale = extract_scale(sql_type)
712+
precision = extract_precision(sql_type)
713+
limit = extract_limit(sql_type)
714+
if scale == 0
715+
Type::OracleEnhanced::Integer.new(precision: precision, limit: limit)
716+
else
717+
Type::Decimal.new(precision: precision, scale: scale)
718+
end
717719
end
718-
end
719720

720-
if OracleEnhancedAdapter.emulate_booleans
721-
m.register_type %r(^NUMBER\(1\))i, Type::Boolean.new
721+
if OracleEnhancedAdapter.emulate_booleans
722+
m.register_type %r(^NUMBER\(1\))i, Type::Boolean.new
723+
end
722724
end
723-
end
725+
end
724726

725-
def extract_value_from_default(default)
726-
case default
727-
when String
728-
default.gsub("''", "'")
729-
else
730-
default
731-
end
732-
end
727+
TYPE_MAP = Type::TypeMap.new.tap { |m| initialize_type_map(m) }
733728

734-
def extract_limit(sql_type) # :nodoc:
735-
case sql_type
736-
when /^bigint/i
737-
19
738-
when /\((.*)\)/
739-
$1.to_i
740-
end
729+
def type_map
730+
TYPE_MAP
731+
end
732+
733+
def extract_value_from_default(default)
734+
case default
735+
when String
736+
default.gsub("''", "'")
737+
else
738+
default
741739
end
740+
end
742741

743-
def translate_exception(exception, message:, sql:, binds:) # :nodoc:
744-
case @connection.error_code(exception)
745-
when 1
746-
RecordNotUnique.new(message, sql: sql, binds: binds)
747-
when 60
748-
Deadlocked.new(message)
749-
when 900, 904, 942, 955, 1418, 2289, 2449, 17008
750-
ActiveRecord::StatementInvalid.new(message, sql: sql, binds: binds)
751-
when 1400
752-
ActiveRecord::NotNullViolation.new(message, sql: sql, binds: binds)
753-
when 2291, 2292
754-
InvalidForeignKey.new(message, sql: sql, binds: binds)
755-
when 12899
756-
ValueTooLong.new(message, sql: sql, binds: binds)
757-
else
758-
super
759-
end
742+
def extract_limit(sql_type) # :nodoc:
743+
case sql_type
744+
when /^bigint/i
745+
19
746+
when /\((.*)\)/
747+
$1.to_i
760748
end
749+
end
761750

762-
# create bind object for type String
763-
def bind_string(name, value)
764-
ActiveRecord::Relation::QueryAttribute.new(name, value, Type::OracleEnhanced::String.new)
751+
def translate_exception(exception, message:, sql:, binds:) # :nodoc:
752+
case @connection.error_code(exception)
753+
when 1
754+
RecordNotUnique.new(message, sql: sql, binds: binds)
755+
when 60
756+
Deadlocked.new(message)
757+
when 900, 904, 942, 955, 1418, 2289, 2449, 17008
758+
ActiveRecord::StatementInvalid.new(message, sql: sql, binds: binds)
759+
when 1400
760+
ActiveRecord::NotNullViolation.new(message, sql: sql, binds: binds)
761+
when 2291, 2292
762+
InvalidForeignKey.new(message, sql: sql, binds: binds)
763+
when 12899
764+
ValueTooLong.new(message, sql: sql, binds: binds)
765+
else
766+
super
765767
end
768+
end
766769

767-
# call select_values using binds even if surrounding SQL preparation/execution is done + # with conn.unprepared_statement (like AR.to_sql)
768-
def select_values_forcing_binds(arel, name, binds)
769-
# remove possible force of unprepared SQL during dictionary access
770-
unprepared_statement_forced = prepared_statements_disabled_cache.include?(object_id)
771-
prepared_statements_disabled_cache.delete(object_id) if unprepared_statement_forced
770+
# create bind object for type String
771+
def bind_string(name, value)
772+
ActiveRecord::Relation::QueryAttribute.new(name, value, Type::OracleEnhanced::String.new)
773+
end
772774

773-
select_values(arel, name, binds)
774-
ensure
775-
# Restore unprepared_statement setting for surrounding SQL
776-
prepared_statements_disabled_cache.add(object_id) if unprepared_statement_forced
777-
end
775+
# call select_values using binds even if surrounding SQL preparation/execution is done + # with conn.unprepared_statement (like AR.to_sql)
776+
def select_values_forcing_binds(arel, name, binds)
777+
# remove possible force of unprepared SQL during dictionary access
778+
unprepared_statement_forced = prepared_statements_disabled_cache.include?(object_id)
779+
prepared_statements_disabled_cache.delete(object_id) if unprepared_statement_forced
778780

779-
def select_value_forcing_binds(arel, name, binds)
780-
single_value_from_rows(select_values_forcing_binds(arel, name, binds))
781-
end
781+
select_values(arel, name, binds)
782+
ensure
783+
# Restore unprepared_statement setting for surrounding SQL
784+
prepared_statements_disabled_cache.add(object_id) if unprepared_statement_forced
785+
end
786+
787+
def select_value_forcing_binds(arel, name, binds)
788+
single_value_from_rows(select_values_forcing_binds(arel, name, binds))
789+
end
782790

783-
ActiveRecord::Type.register(:boolean, Type::OracleEnhanced::Boolean, adapter: :oracle_enhanced)
784-
ActiveRecord::Type.register(:json, Type::OracleEnhanced::Json, adapter: :oracle_enhanced)
791+
ActiveRecord::Type.register(:boolean, Type::OracleEnhanced::Boolean, adapter: :oracle_enhanced)
792+
ActiveRecord::Type.register(:json, Type::OracleEnhanced::Json, adapter: :oracle_enhanced)
785793
end
786794
end
787795
end

0 commit comments

Comments
 (0)