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

Changeset 7771

Show
Ignore:
Timestamp:
10/07/07 06:27:39 (1 year ago)
Author:
bitsweat
Message:

Reinstate failsafe date/time parsing rescues. Head off some obvious failures like year == 0 or nil.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb

    r7769 r7771  
    2020        @limit, @precision, @scale  = extract_limit(sql_type), extract_precision(sql_type), extract_scale(sql_type)  
    2121        @type = simplified_type(sql_type) 
    22         @default = type_cast(default) 
     22        @default = extract_default(default) 
    2323 
    2424        @primary = nil 
     
    9393      end 
    9494 
     95      def extract_default(default) 
     96        type_cast(default) 
     97      end 
     98 
    9599      class << self 
    96100        # Used to convert from Strings to BLOBs 
     
    106110        def string_to_date(string) 
    107111          return string unless string.is_a?(String) 
     112 
    108113          new_date *ParseDate.parsedate(string)[0..2] 
    109114        end 
     
    112117          return string unless string.is_a?(String) 
    113118          return nil if string.empty? 
     119 
    114120          time_hash = Date._parse(string) 
    115121          time_hash[:sec_fraction] = microseconds(time_hash) 
     122 
    116123          new_time *time_hash.values_at(:year, :mon, :mday, :hour, :min, :sec, :sec_fraction) 
    117124        end 
     
    152159 
    153160          def new_date(year, mon, mday) 
    154             Date.new(year, mon, mday) unless year == 0 
     161            if year && year != 0 
     162              Date.new(year, mon, mday) rescue nil 
     163            end 
    155164          end 
    156165 
    157166          def new_time(year, mon, mday, hour, min, sec, microsec) 
    158167            # Treat 0000-00-00 00:00:00 as nil. 
    159             return nil if year == 0 
     168            return nil if year.nil? || year == 0 
    160169 
    161170            Time.send(Base.default_timezone, year, mon, mday, hour, min, sec, microsec) 
     
    164173            zone_offset = if Base.default_timezone == :local then DateTime.now.offset else 0 end 
    165174            # Append zero calendar reform start to account for dates skipped by calendar reform 
    166             DateTime.new(year, mon, mday, hour, min, sec, zone_offset, 0) 
     175            DateTime.new(year, mon, mday, hour, min, sec, zone_offset, 0) rescue nil 
    167176          end 
    168177      end 
  • trunk/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb

    r7769 r7771  
    9292  module ConnectionAdapters 
    9393    class MysqlColumn < Column #:nodoc: 
    94       TYPES_DISALLOWING_DEFAULT = Set.new([:binary, :text]) 
    95       TYPES_ALLOWING_EMPTY_STRING_DEFAULT = Set.new([:string]) 
    96  
    9794      module Format 
    9895        DATE = /\A(\d{4})-(\d\d)-(\d\d)\z/ 
     
    10097      end 
    10198 
    102       def initialize(name, default, sql_type = nil, null = true) 
    103         @original_default = default 
    104         super 
    105         @default = nil if no_default_allowed? || missing_default_forged_as_empty_string? 
    106         @default = '' if @original_default == '' && no_default_allowed? 
     99      def extract_default(default) 
     100        if type == :binary || type == :text 
     101          if default.blank? 
     102            default 
     103          else 
     104            raise ArgumentError, "#{type} columns cannot have a default value: #{default.inspect}" 
     105          end 
     106        elsif missing_default_forged_as_empty_string?(default) 
     107          nil 
     108        else 
     109          super 
     110        end 
    107111      end 
    108112 
     
    115119            new_date $1.to_i, $2.to_i, $3.to_i 
    116120          else 
    117             new_date *ParseDate.parsedate(string)[0..2] 
     121            super 
    118122          end 
    119123        end 
     
    126130            new_time $1.to_i, $2.to_i, $3.to_i, $4.to_i, $5.to_i, $6.to_i, $7.to_i 
    127131          else 
    128             time_hash = Date._parse(string) 
    129             new_time *(time_hash.values_at(:year, :mon, :mday, :hour, :min, :sec) << microseconds(time_hash)) 
     132            super 
    130133          end 
    131134        end 
     
    146149        # Test whether the column has default '', is not null, and is not 
    147150        # a type allowing default ''. 
    148         def missing_default_forged_as_empty_string? 
    149           !null && @original_default == '' && !TYPES_ALLOWING_EMPTY_STRING_DEFAULT.include?(type) 
    150         end 
    151  
    152         # MySQL 5.0 does not allow text and binary columns to have defaults 
    153         def no_default_allowed? 
    154           TYPES_DISALLOWING_DEFAULT.include?(type) 
     151        def missing_default_forged_as_empty_string?(default) 
     152          type != :string && !null && default == '' 
    155153        end 
    156154    end