Use fast date/time parsing by default. Closes #9811.

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@7780 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
This commit is contained in:
Jeremy Kemper
2007-10-07 22:01:59 +00:00
parent 459cc1ecb8
commit bd087e6716
3 changed files with 34 additions and 35 deletions

View File

@@ -2,7 +2,7 @@
* Raise ProtectedAttributeAssignmentError in development and test environments when mass-assigning to an attr_protected attribute. #9802 [Henrik N]
* MySQL: speedup date/time parsing. [Jeremy Kemper]
* Speedup database date/time parsing. [Jeremy Kemper, Tarmo Tänav]
* Fix calling .clear on a has_many :dependent=>:delete_all association. [tarmo]

View File

@@ -6,6 +6,11 @@ module ActiveRecord
module ConnectionAdapters #:nodoc:
# An abstract definition of a column in a table.
class Column
module Format
ISO_DATE = /\A(\d{4})-(\d\d)-(\d\d)\z/
ISO_DATETIME = /\A(\d{4})-(\d\d)-(\d\d) (\d\d):(\d\d):(\d\d)(\.\d+)?\z/
end
attr_reader :name, :default, :type, :limit, :null, :sql_type, :precision, :scale
attr_accessor :primary
@@ -109,18 +114,16 @@ module ActiveRecord
def string_to_date(string)
return string unless string.is_a?(String)
return nil if string.empty?
new_date *ParseDate.parsedate(string)[0..2]
fast_string_to_date(string) || fallback_string_to_date(string)
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)
fast_string_to_time(string) || fallback_string_to_time(string)
end
def string_to_dummy_time(string)
@@ -174,6 +177,31 @@ module ActiveRecord
# Append zero calendar reform start to account for dates skipped by calendar reform
DateTime.new(year, mon, mday, hour, min, sec, zone_offset, 0) rescue nil
end
def fast_string_to_date(string)
if string =~ Format::ISO_DATE
new_date $1.to_i, $2.to_i, $3.to_i
end
end
# Doesn't handle time zones.
def fast_string_to_time(string)
if string =~ Format::ISO_DATETIME
microsec = ($7.to_f * 10e6).to_i
new_time $1.to_i, $2.to_i, $3.to_i, $4.to_i, $5.to_i, $6.to_i, microsec
end
end
def fallback_string_to_date(string)
new_date *ParseDate.parsedate(string)[0..2]
end
def fallback_string_to_time(string)
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
end
private

View File

@@ -91,11 +91,6 @@ module ActiveRecord
module ConnectionAdapters
class MysqlColumn < Column #:nodoc:
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 extract_default(default)
if type == :binary || type == :text
if default.blank?
@@ -110,30 +105,6 @@ module ActiveRecord
end
end
class << self
def string_to_date(string)
return string unless string.is_a?(String)
return nil if string.empty?
if string =~ Format::DATE
new_date $1.to_i, $2.to_i, $3.to_i
else
super
end
end
def string_to_time(string)
return string unless string.is_a?(String)
return nil if string.empty?
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
super
end
end
end
private
def simplified_type(field_type)
return :boolean if MysqlAdapter.emulate_booleans && field_type.downcase.index("tinyint(1)")