Permalink
Browse files

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
  • Loading branch information...
1 parent 459cc1e commit bd087e6716f8b48d48386c3d42e529849d7b68cd @jeremy jeremy committed Oct 7, 2007
View
@@ -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]
@@ -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 @@ def binary_to_string(value)
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 @@ def new_time(year, mon, mday, hour, min, sec, microsec)
# 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
@@ -91,11 +91,6 @@ def self.mysql_connection(config) # :nodoc:
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 @@ def extract_default(default)
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)")

0 comments on commit bd087e6

Please sign in to comment.