diff options
author | Jeremy Kemper <jeremy@bitsweat.net> | 2007-10-07 06:27:39 +0000 |
---|---|---|
committer | Jeremy Kemper <jeremy@bitsweat.net> | 2007-10-07 06:27:39 +0000 |
commit | c7c3f73fd96e041c2565d75268544f2887b21a59 (patch) | |
tree | 0790adcaf6d2c92db96b026096d4d17aeab80fe9 | |
parent | 98f50607e18d111873c181ad75a28cf9be68f589 (diff) | |
download | rails-c7c3f73fd96e041c2565d75268544f2887b21a59.tar.gz rails-c7c3f73fd96e041c2565d75268544f2887b21a59.tar.bz2 rails-c7c3f73fd96e041c2565d75268544f2887b21a59.zip |
Reinstate failsafe date/time parsing rescues. Head off some obvious failures like year == 0 or nil.
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@7771 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
-rw-r--r-- | activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb | 17 | ||||
-rwxr-xr-x | activerecord/lib/active_record/connection_adapters/mysql_adapter.rb | 34 |
2 files changed, 29 insertions, 22 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb index b98a493a18..507ddd2499 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb @@ -19,7 +19,7 @@ module ActiveRecord @name, @sql_type, @null = name, sql_type, null @limit, @precision, @scale = extract_limit(sql_type), extract_precision(sql_type), extract_scale(sql_type) @type = simplified_type(sql_type) - @default = type_cast(default) + @default = extract_default(default) @primary = nil end @@ -92,6 +92,10 @@ module ActiveRecord Base.human_attribute_name(@name) end + def extract_default(default) + type_cast(default) + end + class << self # Used to convert from Strings to BLOBs def string_to_binary(value) @@ -105,14 +109,17 @@ module ActiveRecord def string_to_date(string) return string unless string.is_a?(String) + new_date *ParseDate.parsedate(string)[0..2] end def string_to_time(string) return string unless string.is_a?(String) return nil if string.empty? + time_hash = Date._parse(string) time_hash[:sec_fraction] = microseconds(time_hash) + new_time *time_hash.values_at(:year, :mon, :mday, :hour, :min, :sec, :sec_fraction) end @@ -151,19 +158,21 @@ module ActiveRecord end def new_date(year, mon, mday) - Date.new(year, mon, mday) unless year == 0 + if year && year != 0 + Date.new(year, mon, mday) rescue nil + end end def new_time(year, mon, mday, hour, min, sec, microsec) # Treat 0000-00-00 00:00:00 as nil. - return nil if year == 0 + return nil if year.nil? || year == 0 Time.send(Base.default_timezone, year, mon, mday, hour, min, sec, microsec) # Over/underflow to DateTime rescue ArgumentError, TypeError zone_offset = if Base.default_timezone == :local then DateTime.now.offset else 0 end # Append zero calendar reform start to account for dates skipped by calendar reform - DateTime.new(year, mon, mday, hour, min, sec, zone_offset, 0) + DateTime.new(year, mon, mday, hour, min, sec, zone_offset, 0) rescue nil end end diff --git a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb index 94ec5cf595..b385af7321 100755 --- a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb @@ -91,19 +91,23 @@ module ActiveRecord module ConnectionAdapters class MysqlColumn < Column #:nodoc: - TYPES_DISALLOWING_DEFAULT = Set.new([:binary, :text]) - TYPES_ALLOWING_EMPTY_STRING_DEFAULT = Set.new([:string]) - module Format DATE = /\A(\d{4})-(\d\d)-(\d\d)\z/ DATETIME = /\A(\d{4})-(\d\d)-(\d\d) (\d\d):(\d\d):(\d\d)(?:\.(\d{6}))?\z/ end - def initialize(name, default, sql_type = nil, null = true) - @original_default = default - super - @default = nil if no_default_allowed? || missing_default_forged_as_empty_string? - @default = '' if @original_default == '' && no_default_allowed? + def extract_default(default) + if type == :binary || type == :text + if default.blank? + default + else + raise ArgumentError, "#{type} columns cannot have a default value: #{default.inspect}" + end + elsif missing_default_forged_as_empty_string?(default) + nil + else + super + end end class << self @@ -114,7 +118,7 @@ module ActiveRecord if string =~ Format::DATE new_date $1.to_i, $2.to_i, $3.to_i else - new_date *ParseDate.parsedate(string)[0..2] + super end end @@ -125,8 +129,7 @@ module ActiveRecord if string =~ Format::DATETIME new_time $1.to_i, $2.to_i, $3.to_i, $4.to_i, $5.to_i, $6.to_i, $7.to_i else - time_hash = Date._parse(string) - new_time *(time_hash.values_at(:year, :mon, :mday, :hour, :min, :sec) << microseconds(time_hash)) + super end end end @@ -145,13 +148,8 @@ module ActiveRecord # # Test whether the column has default '', is not null, and is not # a type allowing default ''. - def missing_default_forged_as_empty_string? - !null && @original_default == '' && !TYPES_ALLOWING_EMPTY_STRING_DEFAULT.include?(type) - end - - # MySQL 5.0 does not allow text and binary columns to have defaults - def no_default_allowed? - TYPES_DISALLOWING_DEFAULT.include?(type) + def missing_default_forged_as_empty_string?(default) + type != :string && !null && default == '' end end |