Ticket #5139: oracle_boolean_plus.patch
| File oracle_boolean_plus.patch, 12.8 kB (added by mschoen, 4 years ago) |
|---|
-
activesupport/lib/active_support/inflector.rb
old new 146 146 end 147 147 148 148 def classify(table_name) 149 camelize(singularize(table_name)) 149 # strip out any leading schema name 150 camelize(singularize(table_name.sub(/.*\./, ''))) 150 151 end 151 152 152 153 def foreign_key(class_name, separate_class_name_and_id_with_underscore = true) -
activerecord/test/migration_test.rb
old new 106 106 four = columns.detect { |c| c.name == "four" } 107 107 108 108 assert_equal "hello", one.default 109 if current_adapter?(:OracleAdapter) 110 # Oracle doesn't support native booleans 111 assert_equal true, two.default == 1 112 assert_equal false, three.default != 0 113 else 114 assert_equal true, two.default 115 assert_equal false, three.default 116 end 109 assert_equal true, two.default 110 assert_equal false, three.default 117 111 assert_equal 1, four.default 118 112 119 113 ensure … … 147 141 assert_equal 'smallint', one.sql_type 148 142 assert_equal 'integer', four.sql_type 149 143 assert_equal 'bigint', eight.sql_type 144 elsif current_adapter?(:OracleAdapter) 145 assert_equal 'NUMBER(38)', default.sql_type 146 assert_equal 'NUMBER(1)', one.sql_type 147 assert_equal 'NUMBER(4)', four.sql_type 148 assert_equal 'NUMBER(8)', eight.sql_type 150 149 end 151 150 ensure 152 151 Person.connection.drop_table :testings rescue nil … … 328 327 new_columns = Topic.connection.columns(Topic.table_name, "#{name} Columns") 329 328 assert_nil new_columns.find { |c| c.name == 'approved' and c.type == :boolean and c.default == true } 330 329 assert new_columns.find { |c| c.name == 'approved' and c.type == :boolean and c.default == false } 330 assert_nothing_raised { Topic.connection.change_column :topics, :approved, :boolean, :default => true } 331 331 end 332 332 333 333 def test_change_column_with_new_default -
activerecord/test/fixtures/db_definitions/oracle.sql
old new 37 37 bonus_time timestamp default null, 38 38 last_read timestamp default null, 39 39 content varchar(4000), 40 approved integerdefault 1,40 approved number(1) default 1, 41 41 replies_count integer default 0, 42 42 parent_id integer references topics initially deferred disable, 43 43 type varchar(50) default null, … … 53 53 bonus_time date default null, 54 54 last_read date default null, 55 55 content varchar(4000), 56 approved integerdefault 1,56 approved number(1) default 1, 57 57 replies_count integer default 0, 58 58 parent_id integer references topics initially deferred disable, 59 59 type varchar(50) default null, -
activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb
old new 14 14 # +sql_type+ is only used to extract the column's length, if necessary. For example, <tt>company_name varchar(<b>60</b>)</tt>. 15 15 # +null+ determines if this column allows +NULL+ values. 16 16 def initialize(name, default, sql_type = nil, null = true) 17 @name, @type, @null = name, simplified_type(sql_type), null 18 @sql_type = sql_type 19 # have to do this one separately because type_cast depends on #type 17 @name, @sql_type, @null, @limit = name, sql_type, null, extract_limit(sql_type) 18 19 # simplified_type may depend on #limit, type_cast depends on #type 20 @type = simplified_type(sql_type) 20 21 @default = type_cast(default) 21 @limit = extract_limit(sql_type) unless sql_type.nil? 22 22 23 @primary = nil 23 24 @text = [:string, :text].include? @type 24 25 @number = [:float, :integer].include? @type … … 133 134 134 135 private 135 136 def extract_limit(sql_type) 137 return unless sql_type 136 138 $1.to_i if sql_type =~ /\((.*)\)/ 137 139 end 138 140 -
activerecord/lib/active_record/connection_adapters/oracle_adapter.rb
old new 75 75 76 76 module ConnectionAdapters #:nodoc: 77 77 class OracleColumn < Column #:nodoc: 78 attr_reader :sql_type79 78 79 alias_method :super_initialize, :initialize 80 80 # overridden to add the concept of scale, required to differentiate 81 81 # between integer and float fields 82 def initialize(name, default, sql_type, limit, scale, null) 83 @name, @limit, @sql_type, @scale, @null = name, limit, sql_type, scale, null 84 85 @type = simplified_type(sql_type) 86 @default = type_cast(default) 87 88 @primary = nil 89 @text = [:string, :text].include? @type 90 @number = [:float, :integer].include? @type 82 def initialize(name, default, sql_type = nil, null = true, scale = nil) 83 @scale = scale 84 super_initialize(name, default, sql_type, null) 91 85 end 92 86 93 87 def type_cast(value) … … 95 89 case type 96 90 when :string then value 97 91 when :integer then defined?(value.to_i) ? value.to_i : (value ? 1 : 0) 92 when :boolean then cast_to_boolean(value) 98 93 when :float then value.to_f 99 94 when :datetime then cast_to_date_or_time(value) 100 95 when :time then cast_to_time(value) … … 104 99 105 100 private 106 101 def simplified_type(field_type) 102 return :boolean if (OracleAdapter.emulate_booleans && field_type =~ /num/i && @limit == 1) 107 103 case field_type 108 104 when /char/i : :string 109 105 when /num|float|double|dec|real|int/i : @scale == 0 ? :integer : :float 110 106 when /date|time/i : @name =~ /_at$/ ? :time : :datetime 111 when /clob/i : :text112 when /blob/i : :binary107 when /clob/i : :text 108 when /blob/i : :binary 113 109 end 114 110 end 115 111 112 def cast_to_boolean(value) 113 return value if value.is_a? TrueClass or value.is_a? FalseClass 114 value.to_i == 0 ? false : true 115 end 116 116 117 def cast_to_date_or_time(value) 117 118 return value if value.is_a? Date 118 119 return nil if value.blank? 119 guess_date_or_time (value.is_a? Time) ? value : cast_to_time(value)120 guess_date_or_time((value.is_a? Time) ? value : cast_to_time(value)) 120 121 end 121 122 122 123 def cast_to_time(value) … … 167 168 # * <tt>:database</tt> 168 169 class OracleAdapter < AbstractAdapter 169 170 171 @@emulate_booleans = true 172 cattr_accessor :emulate_booleans 173 170 174 def adapter_name #:nodoc: 171 175 'Oracle' 172 176 end … … 277 281 elsif id_value # Pre-assigned id 278 282 log(sql, name) { @connection.exec sql } 279 283 else # Assume the sql contains a bind-variable for the id 280 id_value = select_one("select #{sequence_name}.nextval id from dual")['id'] 281 log(sql , name) { @connection.exec sql, id_value }284 id_value = select_one("select #{sequence_name}.nextval id from dual")['id'].to_i 285 log(sql.sub(/\B:id\b/, id_value.to_s), name) { @connection.exec sql, id_value } 282 286 end 283 287 284 288 id_value … … 361 365 (owner, table_name) = @connection.describe(table_name) 362 366 363 367 table_cols = %Q{ 364 select column_name , data_type, data_default, nullable,368 select column_name as name, data_type as sql_type, data_default, nullable, 365 369 decode(data_type, 'NUMBER', data_precision, 366 370 'VARCHAR2', data_length, 367 null) as l ength,371 null) as limit, 368 372 decode(data_type, 'NUMBER', data_scale, null) as scale 369 373 from all_tab_columns 370 374 where owner = '#{owner}' … … 373 377 } 374 378 375 379 select_all(table_cols, name).map do |row| 380 row['sql_type'] += "(#{row['limit'].to_i})" if row['limit'] 376 381 if row['data_default'] 377 382 row['data_default'].sub!(/^(.*?)\s*$/, '\1') 378 383 row['data_default'].sub!(/^'(.*)'$/, '\1') 379 384 end 380 OracleColumn.new( 381 oracle_downcase(row['column_name']), 382 row['data_default'], 383 row['data_type'], 384 (l = row['length']).nil? ? nil : l.to_i, 385 (s = row['scale']).nil? ? nil : s.to_i, 386 row['nullable'] == 'Y' 387 ) 385 OracleColumn.new(oracle_downcase(row['name']), 386 row['data_default'], 387 row['sql_type'], 388 row['nullable'] == 'Y', 389 (s = row['scale']).nil? ? nil : s.to_i) 388 390 end 389 391 end 390 392 -
activerecord/lib/active_record/associations.rb
old new 1183 1183 end 1184 1184 end 1185 1185 return false unless conditions.any? 1186 conditions.join(' ').scan(/( \w+)\.\w+/).flatten.any? do |condition_table_name|1186 conditions.join(' ').scan(/([\.\w]+)\.\w+/).flatten.any? do |condition_table_name| 1187 1187 condition_table_name != table_name 1188 1188 end 1189 1189 end … … 1192 1192 def include_eager_order?(options) 1193 1193 order = options[:order] 1194 1194 return false unless order 1195 order.scan(/( \w+)\.\w+/).flatten.any? do |order_table_name|1195 order.scan(/([\.\w]+)\.\w+/).flatten.any? do |order_table_name| 1196 1196 order_table_name != table_name 1197 1197 end 1198 1198 end … … 1391 1391 @parent = parent 1392 1392 @reflection = reflection 1393 1393 @aliased_prefix = "t#{ join_dependency.joins.size }" 1394 @aliased_table_name = table_name # start with the table name1394 @aliased_table_name = table_name #.tr('.', '_') # start with the table name, sub out any .'s 1395 1395 @parent_table_name = parent.active_record.table_name 1396 1396 1397 1397 if !parent.table_joins.blank? && parent.table_joins.to_s.downcase =~ %r{join(\s+\w+)?\s+#{aliased_table_name.downcase}\son} -
railties/lib/tasks/databases.rake
old new 37 37 task :dump => :environment do 38 38 abcs = ActiveRecord::Base.configurations 39 39 case abcs[RAILS_ENV]["adapter"] 40 when "mysql", "oci" 40 when "mysql", "oci", "oracle" 41 41 ActiveRecord::Base.establish_connection(abcs[RAILS_ENV]) 42 42 File.open("db/#{RAILS_ENV}_structure.sql", "w+") { |f| f << ActiveRecord::Base.connection.structure_dump } 43 43 when "postgresql" … … 93 93 `#{abcs["test"]["adapter"]} #{dbfile} < db/#{RAILS_ENV}_structure.sql` 94 94 when "sqlserver" 95 95 `osql -E -S #{abcs["test"]["host"]} -d #{abcs["test"]["database"]} -i db\\#{RAILS_ENV}_structure.sql` 96 when "oci" 96 when "oci", "oracle" 97 97 ActiveRecord::Base.establish_connection(:test) 98 98 IO.readlines("db/#{RAILS_ENV}_structure.sql").join.split(";\n\n").each do |ddl| 99 99 ActiveRecord::Base.connection.execute(ddl) … … 124 124 dropfkscript = "#{abcs["test"]["host"]}.#{abcs["test"]["database"]}.DP1".gsub(/\\/,'-') 125 125 `osql -E -S #{abcs["test"]["host"]} -d #{abcs["test"]["database"]} -i db\\#{dropfkscript}` 126 126 `osql -E -S #{abcs["test"]["host"]} -d #{abcs["test"]["database"]} -i db\\#{RAILS_ENV}_structure.sql` 127 when "oci" 127 when "oci", "oracle" 128 128 ActiveRecord::Base.establish_connection(:test) 129 129 ActiveRecord::Base.connection.structure_drop.split(";\n\n").each do |ddl| 130 130 ActiveRecord::Base.connection.execute(ddl)