aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/connection_adapters
diff options
context:
space:
mode:
authorSean Griffin <sean@thoughtbot.com>2015-02-10 11:52:01 -0700
committerSean Griffin <sean@thoughtbot.com>2015-02-10 11:55:59 -0700
commitf1a0fa9e19b7e4ccaea191fc6cf0613880222ee7 (patch)
tree655c1e521e1bbe2a6c3cec8b8178bd7dc843c187 /activerecord/lib/active_record/connection_adapters
parentf926c1c953df6037654732c57a6c6b23db91c9fa (diff)
downloadrails-f1a0fa9e19b7e4ccaea191fc6cf0613880222ee7.tar.gz
rails-f1a0fa9e19b7e4ccaea191fc6cf0613880222ee7.tar.bz2
rails-f1a0fa9e19b7e4ccaea191fc6cf0613880222ee7.zip
Refactor microsecond precision to be database agnostic
The various databases don't actually need significantly different handling for this behavior, and they can achieve it without knowing about the type of the object. The old implementation was returning a string, which will cause problems such as breaking TZ aware attributes, and making it impossible for the adapters to supply their logic for time objects.
Diffstat (limited to 'activerecord/lib/active_record/connection_adapters')
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/quoting.rb7
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/schema_dumper.rb2
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract_adapter.rb37
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb23
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/oid/date_time.rb9
5 files changed, 32 insertions, 46 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb b/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb
index 55d3360070..29d85d82cb 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb
@@ -127,7 +127,12 @@ module ActiveRecord
end
end
- value.to_s(:db)
+ result = value.to_s(:db)
+ if value.respond_to?(:usec) && value.usec > 0
+ "#{result}.#{sprintf("%06d", value.usec)}"
+ else
+ result
+ end
end
def prepare_binds_for_database(binds) # :nodoc:
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_dumper.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_dumper.rb
index 932aaf7aa7..4f6a1ec67b 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/schema_dumper.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_dumper.rb
@@ -29,7 +29,7 @@ module ActiveRecord
limit = column.limit || native_database_types[column.type][:limit]
spec[:limit] = limit.inspect if limit
- spec[:precision] = column.precision.inspect if column.precision
+ spec[:precision] = column.precision.inspect if column.precision && column.precision != 0
spec[:scale] = column.scale.inspect if column.scale
default = schema_default(column) if column.has_default?
diff --git a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
index 9392bcb473..ee11c0efa4 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
@@ -263,18 +263,6 @@ module ActiveRecord
{}
end
- # QUOTING ==================================================
-
- # Quote date/time values for use in SQL input. Includes microseconds
- # if the value is a Time responding to usec.
- def quoted_date(value) #:nodoc:
- if value.acts_like?(:time) && value.respond_to?(:usec)
- "#{super}.#{sprintf("%06d", value.usec)}"
- else
- super
- end
- end
-
# Returns a bind substitution value given a bind +column+
# NOTE: The column param is currently being used by the sqlserver-adapter
def substitute_at(column, _unused = 0)
@@ -409,15 +397,15 @@ module ActiveRecord
protected
def initialize_type_map(m) # :nodoc:
- register_class_with_limit m, %r(boolean)i, Type::Boolean
- register_class_with_limit m, %r(char)i, Type::String
- register_class_with_limit m, %r(binary)i, Type::Binary
- register_class_with_limit m, %r(text)i, Type::Text
- register_class_with_limit m, %r(date)i, Type::Date
- register_class_with_limit m, %r(time)i, Type::Time
- register_class_with_limit m, %r(datetime)i, Type::DateTime
- register_class_with_limit m, %r(float)i, Type::Float
- register_class_with_limit m, %r(int)i, Type::Integer
+ register_class_with_limit m, %r(boolean)i, Type::Boolean
+ register_class_with_limit m, %r(char)i, Type::String
+ register_class_with_limit m, %r(binary)i, Type::Binary
+ register_class_with_limit m, %r(text)i, Type::Text
+ register_class_with_precision m, %r(date)i, Type::Date
+ register_class_with_precision m, %r(time)i, Type::Time
+ register_class_with_precision m, %r(datetime)i, Type::DateTime
+ register_class_with_limit m, %r(float)i, Type::Float
+ register_class_with_limit m, %r(int)i, Type::Integer
m.alias_type %r(blob)i, 'binary'
m.alias_type %r(clob)i, 'text'
@@ -451,6 +439,13 @@ module ActiveRecord
end
end
+ def register_class_with_precision(mapping, key, klass) # :nodoc:
+ mapping.register_type(key) do |*args|
+ precision = extract_precision(args.last)
+ klass.new(precision: precision)
+ end
+ end
+
def extract_scale(sql_type) # :nodoc:
case sql_type
when /\((\d+)\)/ then 0
diff --git a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
index c29692d6ca..054c59ef5c 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
@@ -712,11 +712,6 @@ module ActiveRecord
m.alias_type %r(year)i, 'integer'
m.alias_type %r(bit)i, 'binary'
- m.register_type(%r(datetime)i) do |sql_type|
- precision = extract_precision(sql_type)
- MysqlDateTime.new(precision: precision)
- end
-
m.register_type(%r(enum)i) do |sql_type|
limit = sql_type[/^enum\((.+)\)/i, 1]
.split(',').map{|enum| enum.strip.length - 2}.max
@@ -734,6 +729,14 @@ module ActiveRecord
end
end
+ def extract_precision(sql_type)
+ if /datetime/ === sql_type
+ super || 0
+ else
+ super
+ end
+ end
+
def fetch_type_metadata(sql_type, collation = "", extra = "")
MysqlTypeMetadata.new(super(sql_type), collation: collation, extra: extra, strict: strict_mode?)
end
@@ -916,14 +919,6 @@ module ActiveRecord
TableDefinition.new(native_database_types, name, temporary, options, as)
end
- class MysqlDateTime < Type::DateTime # :nodoc:
- private
-
- def has_precision?
- precision || 0
- end
- end
-
class MysqlString < Type::String # :nodoc:
def type_cast_for_database(value)
case value
@@ -945,7 +940,7 @@ module ActiveRecord
end
def type_classes_with_standard_constructor
- super.merge(string: MysqlString, date_time: MysqlDateTime)
+ super.merge(string: MysqlString)
end
end
end
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid/date_time.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid/date_time.rb
index 2fe61eeb77..b9e7894e5c 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/oid/date_time.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid/date_time.rb
@@ -5,15 +5,6 @@ module ActiveRecord
class DateTime < Type::DateTime # :nodoc:
include Infinity
- def type_cast_for_database(value)
- if has_precision? && value.acts_like?(:time) && value.year <= 0
- bce_year = format("%04d", -value.year + 1)
- super.sub(/^-?\d+/, bce_year) + " BC"
- else
- super
- end
- end
-
def cast_value(value)
if value.is_a?(::String)
case value