Skip to content

Commit

Permalink
PostgreSQL: support microsecond time resolution. Closes #5492.
Browse files Browse the repository at this point in the history
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@4494 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
  • Loading branch information
jeremy committed Jun 25, 2006
1 parent d912509 commit 4277568
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 7 deletions.
2 changes: 2 additions & 0 deletions activerecord/CHANGELOG
Original file line number Original file line Diff line number Diff line change
@@ -1,5 +1,7 @@
*SVN* *SVN*


* PostgreSQL: support microsecond time resolution. #5492 [alex@msgpad.com]

* Add AssociationCollection#sum since the method_missing invokation has been shadowed by Enumerable#sum. * Add AssociationCollection#sum since the method_missing invokation has been shadowed by Enumerable#sum.


* Added find_or_initialize_by_X which works like find_or_create_by_X but doesn't save the newly instantiated record. [Sam Stephenson] * Added find_or_initialize_by_X which works like find_or_create_by_X but doesn't save the newly instantiated record. [Sam Stephenson]
Expand Down
Original file line number Original file line Diff line number Diff line change
@@ -1,4 +1,4 @@
require 'parsedate' require 'date'


module ActiveRecord module ActiveRecord
module ConnectionAdapters #:nodoc: module ConnectionAdapters #:nodoc:
Expand Down Expand Up @@ -109,17 +109,21 @@ def self.string_to_date(string)


def self.string_to_time(string) def self.string_to_time(string)
return string unless string.is_a?(String) return string unless string.is_a?(String)
time_array = ParseDate.parsedate(string)[0..5] time_hash = Date._parse(string)
time_hash[:sec_fraction] = microseconds(time_hash)
time_array = time_hash.values_at(:year, :mon, :mday, :hour, :min, :sec, :sec_fraction)
# treat 0000-00-00 00:00:00 as nil # treat 0000-00-00 00:00:00 as nil
Time.send(Base.default_timezone, *time_array) rescue nil Time.send(Base.default_timezone, *time_array) rescue nil
end end


def self.string_to_dummy_time(string) def self.string_to_dummy_time(string)
return string unless string.is_a?(String) return string unless string.is_a?(String)
return nil if string.empty? return nil if string.empty?
time_array = ParseDate.parsedate(string) time_hash = Date._parse(string)
time_hash[:sec_fraction] = microseconds(time_hash)
# pad the resulting array with dummy date information # pad the resulting array with dummy date information
time_array[0] = 2000; time_array[1] = 1; time_array[2] = 1; time_array = [2000, 1, 1]
time_array += time_hash.values_at(:hour, :min, :sec, :sec_fraction)
Time.send(Base.default_timezone, *time_array) rescue nil Time.send(Base.default_timezone, *time_array) rescue nil
end end


Expand All @@ -132,7 +136,13 @@ def self.value_to_boolean(value)
end end
end end


private private
# '0.123456' -> 123456
# '1.123456' -> 123456
def self.microseconds(time)
((time[:sec_fraction].to_f % 1) * 1_000_000).to_i
end

def extract_limit(sql_type) def extract_limit(sql_type)
return unless sql_type return unless sql_type
$1.to_i if sql_type =~ /\((.*)\)/ $1.to_i if sql_type =~ /\((.*)\)/
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -124,6 +124,10 @@ def quote_column_name(name)
%("#{name}") %("#{name}")
end end


def quoted_date(value)
value.strftime("%Y-%m-%d %H:%M:%S.#{value.usec}")
end



# DATABASE STATEMENTS ====================================== # DATABASE STATEMENTS ======================================


Expand Down Expand Up @@ -526,7 +530,7 @@ def default_value(value)
def cast_to_time(value) def cast_to_time(value)
return value unless value.class == DateTime return value unless value.class == DateTime
v = value v = value
time_array = [v.year, v.month, v.day, v.hour, v.min, v.sec] time_array = [v.year, v.month, v.day, v.hour, v.min, v.sec, v.usec]
Time.send(Base.default_timezone, *time_array) rescue nil Time.send(Base.default_timezone, *time_array) rescue nil
end end
end end
Expand Down
6 changes: 6 additions & 0 deletions activerecord/test/base_test.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -315,6 +315,12 @@ def test_preserving_time_objects
Time, Topic.find(1).written_on, Time, Topic.find(1).written_on,
"The written_on attribute should be of the Time class" "The written_on attribute should be of the Time class"
) )

# For adapters which support microsecond resolution.
if current_adapter?(:PostgreSQLAdapter)
assert_equal 11, Topic.find(1).written_on.sec
assert_equal 223300, Topic.find(1).written_on.usec
end
end end


def test_destroy def test_destroy
Expand Down
2 changes: 1 addition & 1 deletion activerecord/test/fixtures/topics.yml
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ first:
title: The First Topic title: The First Topic
author_name: David author_name: David
author_email_address: david@loudthinking.com author_email_address: david@loudthinking.com
written_on: 2003-07-16t15:28:00.00+01:00 written_on: 2003-07-16t15:28:11.2233+01:00
last_read: 2004-04-15 last_read: 2004-04-15
bonus_time: 2005-01-30t15:28:00.00+01:00 bonus_time: 2005-01-30t15:28:00.00+01:00
content: Have a nice day content: Have a nice day
Expand Down

0 comments on commit 4277568

Please sign in to comment.