Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Changeset 4351

Show
Ignore:
Timestamp:
05/21/06 15:13:28 (3 years ago)
Author:
marcel
Message:

Fix Oracle boolean support and tests. Closes #5139. [schoenm@earthlink.net]

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/activerecord/CHANGELOG

    r4348 r4351  
    11*SVN* 
     2 
     3* Fix Oracle boolean support and tests. Closes #5139. [schoenm@earthlink.net] 
    24 
    35* create! no longer blows up when no attributes are passed and a :create scope is in effect (e.g. foo.bars.create! failed whereas foo.bars.create!({}) didn't.) [Jeremy Kemper] 
  • trunk/activerecord/lib/active_record/associations.rb

    r4342 r4351  
    11841184          end 
    11851185          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| 
    11871187            condition_table_name != table_name 
    11881188          end 
     
    11931193          order = options[:order] 
    11941194          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| 
    11961196            order_table_name != table_name 
    11971197          end 
     
    13921392              @reflection         = reflection 
    13931393              @aliased_prefix     = "t#{ join_dependency.joins.size }" 
    1394               @aliased_table_name = table_name # start with the table name 
     1394              @aliased_table_name = table_name #.tr('.', '_') # start with the table name, sub out any .'s 
    13951395              @parent_table_name  = parent.active_record.table_name 
    13961396 
  • trunk/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb

    r4327 r4351  
    1515      # +null+ determines if this column allows +NULL+ values. 
    1616      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) 
    2021        @default = type_cast(default) 
    21         @limit   = extract_limit(sql_type) unless sql_type.nil? 
     22 
    2223        @primary = nil 
    2324        @text    = [:string, :text].include? @type 
     
    134135    private 
    135136        def extract_limit(sql_type) 
     137          return unless sql_type 
    136138          $1.to_i if sql_type =~ /\((.*)\)/ 
    137139        end 
  • trunk/activerecord/lib/active_record/connection_adapters/oracle_adapter.rb

    r4284 r4351  
    7676    module ConnectionAdapters #:nodoc: 
    7777      class OracleColumn < Column #:nodoc: 
    78         attr_reader :sql_type 
    79  
     78 
     79        alias_method :super_initialize, :initialize 
    8080        # overridden to add the concept of scale, required to differentiate 
    8181        # 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) 
    9185        end 
    9286 
     
    9690          when :string   then value 
    9791          when :integer  then defined?(value.to_i) ? value.to_i : (value ? 1 : 0) 
     92          when :boolean  then cast_to_boolean(value) 
    9893          when :float    then value.to_f 
    9994          when :datetime then cast_to_date_or_time(value) 
     
    105100        private 
    106101        def simplified_type(field_type) 
     102          return :boolean if (OracleAdapter.emulate_booleans && field_type =~ /num/i && @limit == 1) 
    107103          case field_type 
    108104          when /char/i                          : :string 
    109105          when /num|float|double|dec|real|int/i : @scale == 0 ? :integer : :float 
    110106          when /date|time/i                     : @name =~ /_at$/ ? :time : :datetime 
    111           when /clob/i                           : :text 
    112           when /blob/i                           : :binary 
    113           end 
     107          when /clob/i                          : :text 
     108          when /blob/i                          : :binary 
     109          end 
     110        end 
     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 
    114115        end 
    115116 
     
    117118          return value if value.is_a? Date 
    118119          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)
    120121        end 
    121122 
     
    168169      class OracleAdapter < AbstractAdapter 
    169170 
     171        @@emulate_booleans = true 
     172        cattr_accessor :emulate_booleans 
     173 
    170174        def adapter_name #:nodoc: 
    171175          'Oracle' 
     
    278282            log(sql, name) { @connection.exec sql } 
    279283          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 } 
    282286          end 
    283287 
     
    362366 
    363367          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, 
    365369                   decode(data_type, 'NUMBER', data_precision, 
    366370                                     'VARCHAR2', data_length, 
    367                                       null) as length
     371                                      null) as limit
    368372                   decode(data_type, 'NUMBER', data_scale, null) as scale 
    369373              from all_tab_columns 
     
    374378 
    375379          select_all(table_cols, name).map do |row| 
     380            row['sql_type'] += "(#{row['limit'].to_i})" if row['limit'] 
    376381            if row['data_default'] 
    377382              row['data_default'].sub!(/^(.*?)\s*$/, '\1') 
    378383              row['data_default'].sub!(/^'(.*)'$/, '\1') 
    379384            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) 
    388390          end 
    389391        end 
  • trunk/activerecord/test/fixtures/db_definitions/oracle.sql

    r3718 r4351  
    3838    last_read timestamp default null, 
    3939    content varchar(4000), 
    40     approved integer default 1, 
     40    approved number(1) default 1, 
    4141    replies_count integer default 0, 
    4242    parent_id integer references topics initially deferred disable, 
     
    5454    last_read date default null, 
    5555    content varchar(4000), 
    56     approved integer default 1, 
     56    approved number(1) default 1, 
    5757    replies_count integer default 0, 
    5858    parent_id integer references topics initially deferred disable, 
  • trunk/activerecord/test/migration_test.rb

    r4340 r4351  
    107107 
    108108      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 
    117111      assert_equal 1, four.default 
    118112 
     
    148142        assert_equal 'integer', four.sql_type 
    149143        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 
    150149      end 
    151150    ensure 
     
    329328      assert_nil new_columns.find { |c| c.name == 'approved' and c.type == :boolean and c.default == true } 
    330329      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 } 
    331331    end     
    332332