aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--activemodel/lib/active_model/type.rb59
-rw-r--r--activemodel/lib/active_model/type/big_integer.rb (renamed from activerecord/lib/active_record/type/big_integer.rb)4
-rw-r--r--activemodel/lib/active_model/type/binary.rb (renamed from activerecord/lib/active_record/type/binary.rb)2
-rw-r--r--activemodel/lib/active_model/type/boolean.rb (renamed from activerecord/lib/active_record/type/boolean.rb)6
-rw-r--r--activemodel/lib/active_model/type/date.rb (renamed from activerecord/lib/active_record/type/date.rb)5
-rw-r--r--activemodel/lib/active_model/type/date_time.rb (renamed from activerecord/lib/active_record/type/date_time.rb)2
-rw-r--r--activemodel/lib/active_model/type/decimal.rb (renamed from activerecord/lib/active_record/type/decimal.rb)2
-rw-r--r--activemodel/lib/active_model/type/decimal_without_scale.rb (renamed from activerecord/lib/active_record/type/decimal_without_scale.rb)4
-rw-r--r--activemodel/lib/active_model/type/float.rb (renamed from activerecord/lib/active_record/type/float.rb)2
-rw-r--r--activemodel/lib/active_model/type/hash_lookup_type_map.rb (renamed from activerecord/lib/active_record/type/hash_lookup_type_map.rb)2
-rw-r--r--activemodel/lib/active_model/type/helpers.rb4
-rw-r--r--activemodel/lib/active_model/type/helpers/accepts_multiparameter_time.rb (renamed from activerecord/lib/active_record/type/helpers/accepts_multiparameter_time.rb)7
-rw-r--r--activemodel/lib/active_model/type/helpers/mutable.rb (renamed from activerecord/lib/active_record/type/helpers/mutable.rb)2
-rw-r--r--activemodel/lib/active_model/type/helpers/numeric.rb (renamed from activerecord/lib/active_record/type/helpers/numeric.rb)2
-rw-r--r--activemodel/lib/active_model/type/helpers/time_value.rb (renamed from activerecord/lib/active_record/type/helpers/time_value.rb)21
-rw-r--r--activemodel/lib/active_model/type/integer.rb (renamed from activerecord/lib/active_record/type/integer.rb)2
-rw-r--r--activemodel/lib/active_model/type/registry.rb151
-rw-r--r--activemodel/lib/active_model/type/string.rb (renamed from activerecord/lib/active_record/type/string.rb)2
-rw-r--r--activemodel/lib/active_model/type/text.rb (renamed from activerecord/lib/active_record/type/text.rb)4
-rw-r--r--activemodel/lib/active_model/type/time.rb (renamed from activerecord/lib/active_record/type/time.rb)2
-rw-r--r--activemodel/lib/active_model/type/type_map.rb (renamed from activerecord/lib/active_record/type/type_map.rb)2
-rw-r--r--activemodel/lib/active_model/type/unsigned_integer.rb (renamed from activerecord/lib/active_record/type/unsigned_integer.rb)2
-rw-r--r--activemodel/lib/active_model/type/value.rb (renamed from activerecord/lib/active_record/type/value.rb)2
-rw-r--r--activerecord/lib/active_record/attribute_methods/query.rb2
-rw-r--r--activerecord/lib/active_record/connection_adapters/column.rb7
-rw-r--r--activerecord/lib/active_record/type.rb66
-rw-r--r--activerecord/lib/active_record/type/adapter_specific_registry.rb39
-rw-r--r--activerecord/lib/active_record/type/helpers.rb4
-rw-r--r--activerecord/lib/active_record/type/internal/abstract_json.rb4
-rw-r--r--activerecord/lib/active_record/type/internal/timezone.rb15
-rw-r--r--activerecord/lib/active_record/type/serialized.rb4
31 files changed, 336 insertions, 96 deletions
diff --git a/activemodel/lib/active_model/type.rb b/activemodel/lib/active_model/type.rb
new file mode 100644
index 0000000000..64346bcab2
--- /dev/null
+++ b/activemodel/lib/active_model/type.rb
@@ -0,0 +1,59 @@
+require 'active_model/type/helpers'
+require 'active_model/type/value'
+
+require 'active_model/type/big_integer'
+require 'active_model/type/binary'
+require 'active_model/type/boolean'
+require 'active_model/type/date'
+require 'active_model/type/date_time'
+require 'active_model/type/decimal'
+require 'active_model/type/decimal_without_scale'
+require 'active_model/type/float'
+require 'active_model/type/integer'
+require 'active_model/type/string'
+require 'active_model/type/text'
+require 'active_model/type/time'
+require 'active_model/type/unsigned_integer'
+
+require 'active_model/type/registry'
+require 'active_model/type/type_map'
+require 'active_model/type/hash_lookup_type_map'
+
+module ActiveModel
+ module Type
+ @registry = Registry.new
+
+ class << self
+ attr_accessor :registry # :nodoc:
+ delegate :add_modifier, to: :registry
+
+ # Add a new type to the registry, allowing it to be referenced as a
+ # symbol by ActiveModel::Attributes::ClassMethods#attribute. If your
+ # type is only meant to be used with a specific database adapter, you can
+ # do so by passing +adapter: :postgresql+. If your type has the same
+ # name as a native type for the current adapter, an exception will be
+ # raised unless you specify an +:override+ option. +override: true+ will
+ # cause your type to be used instead of the native type. +override:
+ # false+ will cause the native type to be used over yours if one exists.
+ def register(type_name, klass = nil, **options, &block)
+ registry.register(type_name, klass, **options, &block)
+ end
+
+ def lookup(*args, **kwargs) # :nodoc:
+ registry.lookup(*args, **kwargs)
+ end
+ end
+
+ register(:big_integer, Type::BigInteger, override: false)
+ register(:binary, Type::Binary, override: false)
+ register(:boolean, Type::Boolean, override: false)
+ register(:date, Type::Date, override: false)
+ register(:date_time, Type::DateTime, override: false)
+ register(:decimal, Type::Decimal, override: false)
+ register(:float, Type::Float, override: false)
+ register(:integer, Type::Integer, override: false)
+ register(:string, Type::String, override: false)
+ register(:text, Type::Text, override: false)
+ register(:time, Type::Time, override: false)
+ end
+end
diff --git a/activerecord/lib/active_record/type/big_integer.rb b/activemodel/lib/active_model/type/big_integer.rb
index 0c72d8914f..4168cbfce7 100644
--- a/activerecord/lib/active_record/type/big_integer.rb
+++ b/activemodel/lib/active_model/type/big_integer.rb
@@ -1,6 +1,6 @@
-require 'active_record/type/integer'
+require 'active_model/type/integer'
-module ActiveRecord
+module ActiveModel
module Type
class BigInteger < Integer # :nodoc:
private
diff --git a/activerecord/lib/active_record/type/binary.rb b/activemodel/lib/active_model/type/binary.rb
index 0baf8c63ad..a0cc45b4c3 100644
--- a/activerecord/lib/active_record/type/binary.rb
+++ b/activemodel/lib/active_model/type/binary.rb
@@ -1,4 +1,4 @@
-module ActiveRecord
+module ActiveModel
module Type
class Binary < Value # :nodoc:
def type
diff --git a/activerecord/lib/active_record/type/boolean.rb b/activemodel/lib/active_model/type/boolean.rb
index f6a75512fd..c1bce98c87 100644
--- a/activerecord/lib/active_record/type/boolean.rb
+++ b/activemodel/lib/active_model/type/boolean.rb
@@ -1,6 +1,8 @@
-module ActiveRecord
+module ActiveModel
module Type
class Boolean < Value # :nodoc:
+ FALSE_VALUES = [false, 0, '0', 'f', 'F', 'false', 'FALSE', 'off', 'OFF'].to_set
+
def type
:boolean
end
@@ -11,7 +13,7 @@ module ActiveRecord
if value == ''
nil
else
- !ConnectionAdapters::Column::FALSE_VALUES.include?(value)
+ !FALSE_VALUES.include?(value)
end
end
end
diff --git a/activerecord/lib/active_record/type/date.rb b/activemodel/lib/active_model/type/date.rb
index 3ceab59ebb..f74243a22c 100644
--- a/activerecord/lib/active_record/type/date.rb
+++ b/activemodel/lib/active_model/type/date.rb
@@ -1,4 +1,4 @@
-module ActiveRecord
+module ActiveModel
module Type
class Date < Value # :nodoc:
include Helpers::AcceptsMultiparameterTime.new
@@ -24,8 +24,9 @@ module ActiveRecord
end
end
+ ISO_DATE = /\A(\d{4})-(\d\d)-(\d\d)\z/
def fast_string_to_date(string)
- if string =~ ConnectionAdapters::Column::Format::ISO_DATE
+ if string =~ ISO_DATE
new_date $1.to_i, $2.to_i, $3.to_i
end
end
diff --git a/activerecord/lib/active_record/type/date_time.rb b/activemodel/lib/active_model/type/date_time.rb
index a5199959b9..b068cfc672 100644
--- a/activerecord/lib/active_record/type/date_time.rb
+++ b/activemodel/lib/active_model/type/date_time.rb
@@ -1,4 +1,4 @@
-module ActiveRecord
+module ActiveModel
module Type
class DateTime < Value # :nodoc:
include Helpers::TimeValue
diff --git a/activerecord/lib/active_record/type/decimal.rb b/activemodel/lib/active_model/type/decimal.rb
index f5b145230d..83a16018ea 100644
--- a/activerecord/lib/active_record/type/decimal.rb
+++ b/activemodel/lib/active_model/type/decimal.rb
@@ -1,4 +1,4 @@
-module ActiveRecord
+module ActiveModel
module Type
class Decimal < Value # :nodoc:
include Helpers::Numeric
diff --git a/activerecord/lib/active_record/type/decimal_without_scale.rb b/activemodel/lib/active_model/type/decimal_without_scale.rb
index ff5559e300..129baa0c10 100644
--- a/activerecord/lib/active_record/type/decimal_without_scale.rb
+++ b/activemodel/lib/active_model/type/decimal_without_scale.rb
@@ -1,6 +1,6 @@
-require 'active_record/type/big_integer'
+require 'active_model/type/big_integer'
-module ActiveRecord
+module ActiveModel
module Type
class DecimalWithoutScale < BigInteger # :nodoc:
def type
diff --git a/activerecord/lib/active_record/type/float.rb b/activemodel/lib/active_model/type/float.rb
index d88482b85d..0f925bc7e1 100644
--- a/activerecord/lib/active_record/type/float.rb
+++ b/activemodel/lib/active_model/type/float.rb
@@ -1,4 +1,4 @@
-module ActiveRecord
+module ActiveModel
module Type
class Float < Value # :nodoc:
include Helpers::Numeric
diff --git a/activerecord/lib/active_record/type/hash_lookup_type_map.rb b/activemodel/lib/active_model/type/hash_lookup_type_map.rb
index 3b01e3f8ca..45d3515aad 100644
--- a/activerecord/lib/active_record/type/hash_lookup_type_map.rb
+++ b/activemodel/lib/active_model/type/hash_lookup_type_map.rb
@@ -1,4 +1,4 @@
-module ActiveRecord
+module ActiveModel
module Type
class HashLookupTypeMap < TypeMap # :nodoc:
def alias_type(type, alias_type)
diff --git a/activemodel/lib/active_model/type/helpers.rb b/activemodel/lib/active_model/type/helpers.rb
new file mode 100644
index 0000000000..a805a359ab
--- /dev/null
+++ b/activemodel/lib/active_model/type/helpers.rb
@@ -0,0 +1,4 @@
+require 'active_model/type/helpers/accepts_multiparameter_time'
+require 'active_model/type/helpers/numeric'
+require 'active_model/type/helpers/mutable'
+require 'active_model/type/helpers/time_value'
diff --git a/activerecord/lib/active_record/type/helpers/accepts_multiparameter_time.rb b/activemodel/lib/active_model/type/helpers/accepts_multiparameter_time.rb
index be571fc1c7..fa1ccd057e 100644
--- a/activerecord/lib/active_record/type/helpers/accepts_multiparameter_time.rb
+++ b/activemodel/lib/active_model/type/helpers/accepts_multiparameter_time.rb
@@ -1,4 +1,4 @@
-module ActiveRecord
+module ActiveModel
module Type
module Helpers
class AcceptsMultiparameterTime < Module # :nodoc:
@@ -17,10 +17,7 @@ module ActiveRecord
end
return unless values_hash[1] && values_hash[2] && values_hash[3]
values = values_hash.sort.map(&:last)
- ::Time.send(
- ActiveRecord::Base.default_timezone,
- *values
- )
+ ::Time.send(default_timezone, *values)
end
private :value_from_multiparameter_assignment
end
diff --git a/activerecord/lib/active_record/type/helpers/mutable.rb b/activemodel/lib/active_model/type/helpers/mutable.rb
index 88a9099277..4dddbe4e5e 100644
--- a/activerecord/lib/active_record/type/helpers/mutable.rb
+++ b/activemodel/lib/active_model/type/helpers/mutable.rb
@@ -1,4 +1,4 @@
-module ActiveRecord
+module ActiveModel
module Type
module Helpers
module Mutable # :nodoc:
diff --git a/activerecord/lib/active_record/type/helpers/numeric.rb b/activemodel/lib/active_model/type/helpers/numeric.rb
index a755a02a59..c883010506 100644
--- a/activerecord/lib/active_record/type/helpers/numeric.rb
+++ b/activemodel/lib/active_model/type/helpers/numeric.rb
@@ -1,4 +1,4 @@
-module ActiveRecord
+module ActiveModel
module Type
module Helpers
module Numeric # :nodoc:
diff --git a/activerecord/lib/active_record/type/helpers/time_value.rb b/activemodel/lib/active_model/type/helpers/time_value.rb
index 7eb41557cb..5a899d43ec 100644
--- a/activerecord/lib/active_record/type/helpers/time_value.rb
+++ b/activemodel/lib/active_model/type/helpers/time_value.rb
@@ -1,4 +1,4 @@
-module ActiveRecord
+module ActiveModel
module Type
module Helpers
module TimeValue # :nodoc:
@@ -10,7 +10,7 @@ module ActiveRecord
end
if value.acts_like?(:time)
- zone_conversion_method = ActiveRecord::Base.default_timezone == :utc ? :getutc : :getlocal
+ zone_conversion_method = is_utc? ? :getutc : :getlocal
if value.respond_to?(zone_conversion_method)
value = value.send(zone_conversion_method)
@@ -19,6 +19,14 @@ module ActiveRecord
value
end
+
+ def is_utc?
+ ::Time.zone_default =~ 'UTC'
+ end
+
+ def default_timezone
+ ::Time.zone_default
+ end
def type_cast_for_schema(value)
"'#{value.to_s(:db)}'"
@@ -33,21 +41,24 @@ module ActiveRecord
def new_time(year, mon, mday, hour, min, sec, microsec, offset = nil)
# Treat 0000-00-00 00:00:00 as nil.
return if year.nil? || (year == 0 && mon == 0 && mday == 0)
+
if offset
time = ::Time.utc(year, mon, mday, hour, min, sec, microsec) rescue nil
return unless time
time -= offset
- Base.default_timezone == :utc ? time : time.getlocal
+ is_utc? ? time : time.getlocal
else
- ::Time.public_send(Base.default_timezone, year, mon, mday, hour, min, sec, microsec) rescue nil
+ ::Time.public_send(default_timezone, year, mon, mday, hour, min, sec, microsec) rescue nil
end
end
+
+ ISO_DATETIME = /\A(\d{4})-(\d\d)-(\d\d) (\d\d):(\d\d):(\d\d)(\.\d+)?\z/
# Doesn't handle time zones.
def fast_string_to_time(string)
- if string =~ ConnectionAdapters::Column::Format::ISO_DATETIME
+ if string =~ ISO_DATETIME
microsec = ($7.to_r * 1_000_000).to_i
new_time $1.to_i, $2.to_i, $3.to_i, $4.to_i, $5.to_i, $6.to_i, microsec
end
diff --git a/activerecord/lib/active_record/type/integer.rb b/activemodel/lib/active_model/type/integer.rb
index c5040c6d3b..2f73ede009 100644
--- a/activerecord/lib/active_record/type/integer.rb
+++ b/activemodel/lib/active_model/type/integer.rb
@@ -1,4 +1,4 @@
-module ActiveRecord
+module ActiveModel
module Type
class Integer < Value # :nodoc:
include Helpers::Numeric
diff --git a/activemodel/lib/active_model/type/registry.rb b/activemodel/lib/active_model/type/registry.rb
new file mode 100644
index 0000000000..8070a4bd38
--- /dev/null
+++ b/activemodel/lib/active_model/type/registry.rb
@@ -0,0 +1,151 @@
+module ActiveModel
+ # :stopdoc:
+ module Type
+ class Registry
+ def initialize
+ @registrations = []
+ end
+
+ def register(type_name, klass = nil, **options, &block)
+ block ||= proc { |_, *args| klass.new(*args) }
+ registrations << registration_klass.new(type_name, block, **options)
+ end
+
+ def lookup(symbol, *args)
+ registration = registrations
+ .select { |r| r.matches?(symbol, *args) }
+ .max
+
+ if registration
+ registration.call(self, symbol, *args)
+ else
+ raise ArgumentError, "Unknown type #{symbol.inspect}"
+ end
+ end
+
+ def add_modifier(options, klass, **args)
+ registrations << decoration_registration_klass.new(options, klass, **args)
+ end
+
+ protected
+
+ attr_reader :registrations
+
+ private
+
+ def registration_klass
+ Registration
+ end
+
+ def decoration_registration_klass
+ DecorationRegistration
+ end
+ end
+
+ class Registration
+ def initialize(name, block, override: nil)
+ @name = name
+ @block = block
+ @override = override
+ end
+
+ def call(_registry, *args, **kwargs)
+ if kwargs.any? # https://bugs.ruby-lang.org/issues/10856
+ block.call(*args, **kwargs)
+ else
+ block.call(*args)
+ end
+ end
+
+ def matches?(type_name, *args, **kwargs)
+ type_name == name# && matches_adapter?(**kwargs)
+ end
+
+ def <=>(other)
+ # if conflicts_with?(other)
+ # raise TypeConflictError.new("Type #{name} was registered for all
+ # adapters, but shadows a native type with
+ # the same name for #{other.adapter}".squish)
+ # end
+ priority <=> other.priority
+ end
+
+ protected
+
+ attr_reader :name, :block, :override
+
+ def priority
+ result = 0
+ # if adapter
+ # result |= 1
+ # end
+ if override
+ result |= 2
+ end
+ result
+ end
+
+ # def priority_except_adapter
+ # priority & 0b111111100
+ # end
+
+ private
+
+ # def matches_adapter?(adapter: nil, **)
+ # (self.adapter.nil? || adapter == self.adapter)
+ # end
+
+ # def conflicts_with?(other)
+ # same_priority_except_adapter?(other) &&
+ # has_adapter_conflict?(other)
+ # end
+
+ # def same_priority_except_adapter?(other)
+ # priority_except_adapter == other.priority_except_adapter
+ # end
+
+ # def has_adapter_conflict?(other)
+ # (override.nil? && other.adapter) ||
+ # (adapter && other.override.nil?)
+ # end
+ end
+
+ class DecorationRegistration < Registration
+ def initialize(options, klass)
+ @options = options
+ @klass = klass
+ # @adapter = adapter
+ end
+
+ def call(registry, *args, **kwargs)
+ subtype = registry.lookup(*args, **kwargs.except(*options.keys))
+ klass.new(subtype)
+ end
+
+ def matches?(*args, **kwargs)
+ matches_options?(**kwargs)
+ end
+
+ def priority
+ super | 4
+ end
+
+ protected
+
+ attr_reader :options, :klass
+
+ private
+
+ def matches_options?(**kwargs)
+ options.all? do |key, value|
+ kwargs[key] == value
+ end
+ end
+ end
+ end
+
+ class TypeConflictError < StandardError
+ end
+
+ # :startdoc:
+end
diff --git a/activerecord/lib/active_record/type/string.rb b/activemodel/lib/active_model/type/string.rb
index 2662b7e874..fd1630c751 100644
--- a/activerecord/lib/active_record/type/string.rb
+++ b/activemodel/lib/active_model/type/string.rb
@@ -1,4 +1,4 @@
-module ActiveRecord
+module ActiveModel
module Type
class String < Value # :nodoc:
def type
diff --git a/activerecord/lib/active_record/type/text.rb b/activemodel/lib/active_model/type/text.rb
index 26f980f060..1ad04daba4 100644
--- a/activerecord/lib/active_record/type/text.rb
+++ b/activemodel/lib/active_model/type/text.rb
@@ -1,6 +1,6 @@
-require 'active_record/type/string'
+require 'active_model/type/string'
-module ActiveRecord
+module ActiveModel
module Type
class Text < String # :nodoc:
def type
diff --git a/activerecord/lib/active_record/type/time.rb b/activemodel/lib/active_model/type/time.rb
index 19a10021bc..7101bad566 100644
--- a/activerecord/lib/active_record/type/time.rb
+++ b/activemodel/lib/active_model/type/time.rb
@@ -1,4 +1,4 @@
-module ActiveRecord
+module ActiveModel
module Type
class Time < Value # :nodoc:
include Helpers::TimeValue
diff --git a/activerecord/lib/active_record/type/type_map.rb b/activemodel/lib/active_model/type/type_map.rb
index 8ce36cc9af..402b660a71 100644
--- a/activerecord/lib/active_record/type/type_map.rb
+++ b/activemodel/lib/active_model/type/type_map.rb
@@ -1,6 +1,6 @@
require 'concurrent'
-module ActiveRecord
+module ActiveModel
module Type
class TypeMap # :nodoc:
def initialize
diff --git a/activerecord/lib/active_record/type/unsigned_integer.rb b/activemodel/lib/active_model/type/unsigned_integer.rb
index ed3e527483..3f49f9f5f7 100644
--- a/activerecord/lib/active_record/type/unsigned_integer.rb
+++ b/activemodel/lib/active_model/type/unsigned_integer.rb
@@ -1,4 +1,4 @@
-module ActiveRecord
+module ActiveModel
module Type
class UnsignedInteger < Integer # :nodoc:
private
diff --git a/activerecord/lib/active_record/type/value.rb b/activemodel/lib/active_model/type/value.rb
index 6b9d147ecc..c7d1197d69 100644
--- a/activerecord/lib/active_record/type/value.rb
+++ b/activemodel/lib/active_model/type/value.rb
@@ -1,4 +1,4 @@
-module ActiveRecord
+module ActiveModel
module Type
class Value
attr_reader :precision, :scale, :limit
diff --git a/activerecord/lib/active_record/attribute_methods/query.rb b/activerecord/lib/active_record/attribute_methods/query.rb
index 553122a5fc..10498f4322 100644
--- a/activerecord/lib/active_record/attribute_methods/query.rb
+++ b/activerecord/lib/active_record/attribute_methods/query.rb
@@ -19,7 +19,7 @@ module ActiveRecord
if Numeric === value || value !~ /[^0-9]/
!value.to_i.zero?
else
- return false if ActiveRecord::ConnectionAdapters::Column::FALSE_VALUES.include?(value)
+ return false if ActiveModel::Type::Boolean::FALSE_VALUES.include?(value)
!value.blank?
end
elsif value.respond_to?(:zero?)
diff --git a/activerecord/lib/active_record/connection_adapters/column.rb b/activerecord/lib/active_record/connection_adapters/column.rb
index 8222811e0c..5e31efec4a 100644
--- a/activerecord/lib/active_record/connection_adapters/column.rb
+++ b/activerecord/lib/active_record/connection_adapters/column.rb
@@ -5,13 +5,6 @@ module ActiveRecord
module ConnectionAdapters
# An abstract definition of a column in a table.
class Column
- FALSE_VALUES = [false, 0, '0', 'f', 'F', 'false', 'FALSE', 'off', 'OFF'].to_set
-
- 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, :null, :sql_type_metadata, :default, :default_function, :collation
delegate :precision, :scale, :limit, :type, :sql_type, to: :sql_type_metadata, allow_nil: true
diff --git a/activerecord/lib/active_record/type.rb b/activerecord/lib/active_record/type.rb
index 53f3b53bec..165043021b 100644
--- a/activerecord/lib/active_record/type.rb
+++ b/activerecord/lib/active_record/type.rb
@@ -1,26 +1,28 @@
-require 'active_record/type/helpers'
-require 'active_record/type/value'
+require 'active_model/type/helpers'
+require 'active_model/type/value'
-require 'active_record/type/big_integer'
-require 'active_record/type/binary'
-require 'active_record/type/boolean'
-require 'active_record/type/date'
-require 'active_record/type/date_time'
-require 'active_record/type/decimal'
-require 'active_record/type/decimal_without_scale'
-require 'active_record/type/float'
-require 'active_record/type/integer'
-require 'active_record/type/serialized'
-require 'active_record/type/string'
-require 'active_record/type/text'
-require 'active_record/type/time'
-require 'active_record/type/unsigned_integer'
+require 'active_model/type/big_integer'
+require 'active_model/type/binary'
+require 'active_model/type/boolean'
+require 'active_model/type/date'
+require 'active_model/type/date_time'
+require 'active_model/type/decimal'
+require 'active_model/type/decimal_without_scale'
+require 'active_model/type/float'
+require 'active_model/type/integer'
+require 'active_model/type/string'
+require 'active_model/type/text'
+require 'active_model/type/time'
+require 'active_model/type/unsigned_integer'
-require 'active_record/type/adapter_specific_registry'
-require 'active_record/type/type_map'
-require 'active_record/type/hash_lookup_type_map'
+require 'active_model/type/registry'
+require 'active_model/type/type_map'
+require 'active_model/type/hash_lookup_type_map'
require 'active_record/type/internal/abstract_json'
+require 'active_record/type/internal/timezone'
+require 'active_record/type/serialized'
+require 'active_record/type/adapter_specific_registry'
module ActiveRecord
module Type
@@ -53,6 +55,32 @@ module ActiveRecord
end
end
+ class Date < ActiveModel::Type::Date
+ include Internal::Timezone
+ end
+
+ class DateTime < ActiveModel::Type::DateTime
+ include Internal::Timezone
+ end
+ class Time < ActiveModel::Type::Time
+ include Internal::Timezone
+ end
+
+ Helpers = ActiveModel::Type::Helpers
+ BigInteger = ActiveModel::Type::BigInteger
+ Binary = ActiveModel::Type::Binary
+ Boolean = ActiveModel::Type::Boolean
+ Decimal = ActiveModel::Type::Decimal
+ DecimalWithoutScale = ActiveModel::Type::DecimalWithoutScale
+ Float = ActiveModel::Type::Float
+ Integer = ActiveModel::Type::Integer
+ String = ActiveModel::Type::String
+ Text = ActiveModel::Type::Text
+ UnsignedInteger = ActiveModel::Type::UnsignedInteger
+ Value = ActiveModel::Type::Value
+ TypeMap = ActiveModel::Type::TypeMap
+ HashLookupTypeMap = ActiveModel::Type::HashLookupTypeMap
+
register(:big_integer, Type::BigInteger, override: false)
register(:binary, Type::Binary, override: false)
register(:boolean, Type::Boolean, override: false)
diff --git a/activerecord/lib/active_record/type/adapter_specific_registry.rb b/activerecord/lib/active_record/type/adapter_specific_registry.rb
index 5f71b3cb94..3509429058 100644
--- a/activerecord/lib/active_record/type/adapter_specific_registry.rb
+++ b/activerecord/lib/active_record/type/adapter_specific_registry.rb
@@ -1,35 +1,18 @@
+require 'active_model/type/registry'
+
module ActiveRecord
# :stopdoc:
module Type
- class AdapterSpecificRegistry
- def initialize
- @registrations = []
- end
-
- def register(type_name, klass = nil, **options, &block)
- block ||= proc { |_, *args| klass.new(*args) }
- registrations << Registration.new(type_name, block, **options)
- end
-
- def lookup(symbol, *args)
- registration = registrations
- .select { |r| r.matches?(symbol, *args) }
- .max
-
- if registration
- registration.call(self, symbol, *args)
- else
- raise ArgumentError, "Unknown type #{symbol.inspect}"
- end
+ class AdapterSpecificRegistry < ActiveModel::Type::Registry
+ private
+
+ def registration_klass
+ Registration
end
-
- def add_modifier(options, klass, **args)
- registrations << DecorationRegistration.new(options, klass, **args)
+
+ def decoration_registration_klass
+ DecorationRegistration
end
-
- protected
-
- attr_reader :registrations
end
class Registration
@@ -135,7 +118,7 @@ module ActiveRecord
end
end
- class TypeConflictError < StandardError
+ class TypeConflictError < ::ActiveModel::TypeConflictError
end
# :startdoc:
diff --git a/activerecord/lib/active_record/type/helpers.rb b/activerecord/lib/active_record/type/helpers.rb
deleted file mode 100644
index 634d417d13..0000000000
--- a/activerecord/lib/active_record/type/helpers.rb
+++ /dev/null
@@ -1,4 +0,0 @@
-require 'active_record/type/helpers/accepts_multiparameter_time'
-require 'active_record/type/helpers/numeric'
-require 'active_record/type/helpers/mutable'
-require 'active_record/type/helpers/time_value'
diff --git a/activerecord/lib/active_record/type/internal/abstract_json.rb b/activerecord/lib/active_record/type/internal/abstract_json.rb
index 963a8245d0..097d1bd363 100644
--- a/activerecord/lib/active_record/type/internal/abstract_json.rb
+++ b/activerecord/lib/active_record/type/internal/abstract_json.rb
@@ -1,8 +1,8 @@
module ActiveRecord
module Type
module Internal # :nodoc:
- class AbstractJson < Type::Value # :nodoc:
- include Type::Helpers::Mutable
+ class AbstractJson < ActiveModel::Type::Value # :nodoc:
+ include ActiveModel::Type::Helpers::Mutable
def type
:json
diff --git a/activerecord/lib/active_record/type/internal/timezone.rb b/activerecord/lib/active_record/type/internal/timezone.rb
new file mode 100644
index 0000000000..07dbb0b2c6
--- /dev/null
+++ b/activerecord/lib/active_record/type/internal/timezone.rb
@@ -0,0 +1,15 @@
+module ActiveRecord
+ module Type
+ module Internal
+ module Timezone
+ def is_utc?
+ ActiveRecord::Base.default_timezone == :utc
+ end
+
+ def default_timezone
+ ActiveRecord::Base.default_timezone
+ end
+ end
+ end
+ end
+end
diff --git a/activerecord/lib/active_record/type/serialized.rb b/activerecord/lib/active_record/type/serialized.rb
index ea3e0d6a45..203a395415 100644
--- a/activerecord/lib/active_record/type/serialized.rb
+++ b/activerecord/lib/active_record/type/serialized.rb
@@ -1,7 +1,7 @@
module ActiveRecord
module Type
- class Serialized < DelegateClass(Type::Value) # :nodoc:
- include Helpers::Mutable
+ class Serialized < DelegateClass(ActiveModel::Type::Value) # :nodoc:
+ include ActiveModel::Type::Helpers::Mutable
attr_reader :subtype, :coder