aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/lib/active_record')
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract_adapter.rb38
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb26
-rw-r--r--activerecord/lib/active_record/connection_adapters/column.rb41
-rw-r--r--activerecord/lib/active_record/connection_adapters/mysql_adapter.rb1
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/column.rb5
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/oid.rb13
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb9
-rw-r--r--activerecord/lib/active_record/connection_adapters/type.rb20
-rw-r--r--activerecord/lib/active_record/connection_adapters/type/binary.rb11
-rw-r--r--activerecord/lib/active_record/connection_adapters/type/boolean.rb11
-rw-r--r--activerecord/lib/active_record/connection_adapters/type/date.rb11
-rw-r--r--activerecord/lib/active_record/connection_adapters/type/date_time.rb13
-rw-r--r--activerecord/lib/active_record/connection_adapters/type/decimal.rb11
-rw-r--r--activerecord/lib/active_record/connection_adapters/type/float.rb11
-rw-r--r--activerecord/lib/active_record/connection_adapters/type/integer.rb11
-rw-r--r--activerecord/lib/active_record/connection_adapters/type/string.rb11
-rw-r--r--activerecord/lib/active_record/connection_adapters/type/text.rb13
-rw-r--r--activerecord/lib/active_record/connection_adapters/type/time.rb11
-rw-r--r--activerecord/lib/active_record/connection_adapters/type/timestamp.rb11
-rw-r--r--activerecord/lib/active_record/connection_adapters/type/type_map.rb50
-rw-r--r--activerecord/lib/active_record/connection_adapters/type/value.rb1
21 files changed, 258 insertions, 71 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
index d9c939689f..8a7a869eec 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
@@ -361,10 +361,46 @@ module ActiveRecord
pool.checkin self
end
+ def type_map # :nodoc:
+ @type_map ||= Type::TypeMap.new.tap do |mapping|
+ initialize_type_map(mapping)
+ end
+ end
+
protected
def lookup_cast_type(sql_type) # :nodoc:
- Type::Value.new
+ type_map.lookup(sql_type)
+ end
+
+ def initialize_type_map(m) # :nodoc:
+ m.register_type %r(boolean)i, Type::Boolean.new
+ m.register_type %r(char)i, Type::String.new
+ m.register_type %r(binary)i, Type::Binary.new
+ m.alias_type %r(blob)i, 'binary'
+ m.register_type %r(text)i, Type::Text.new
+ m.alias_type %r(clob)i, 'text'
+ m.register_type %r(date)i, Type::Date.new
+ m.register_type %r(time)i, Type::Time.new
+ m.register_type %r(timestamp)i, Type::Timestamp.new
+ m.register_type %r(datetime)i, Type::DateTime.new
+ m.alias_type %r(numeric)i, 'decimal'
+ m.alias_type %r(number)i, 'decimal'
+ m.register_type %r(float)i, Type::Float.new
+ m.alias_type %r(double)i, 'float'
+ m.register_type %r(int)i, Type::Integer.new
+ m.register_type(%r(decimal)i) do |sql_type|
+ if Type.extract_scale(sql_type) == 0
+ Type::Integer.new
+ else
+ Type::Decimal.new
+ end
+ end
+ end
+
+ def reload_type_map # :nodoc:
+ type_map.clear
+ initialize_type_map(type_map)
end
def translate_exception_class(e, sql)
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 7074f69583..5eb2e86d48 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
@@ -97,18 +97,6 @@ module ActiveRecord
private
- def simplified_type(field_type)
- return :boolean if adapter.emulate_booleans && field_type.downcase.index("tinyint(1)")
-
- case field_type
- when /enum/i, /set/i then :string
- when /year/i then :integer
- when /bit/i then :binary
- else
- super
- end
- end
-
def extract_limit(sql_type)
case sql_type
when /^enum\((.+)\)/i
@@ -318,6 +306,11 @@ module ActiveRecord
# DATABASE STATEMENTS ======================================
+ def clear_cache!
+ super
+ reload_type_map
+ end
+
# Executes the SQL statement in the context of this connection.
def execute(sql, name = nil)
log(sql, name) { @connection.query(sql) }
@@ -645,6 +638,15 @@ module ActiveRecord
protected
+ def initialize_type_map(m)
+ super
+ m.alias_type %r(tinyint\(1\))i, 'boolean' if emulate_booleans
+ m.alias_type %r(enum)i, 'varchar'
+ m.alias_type %r(set)i, 'varchar'
+ m.alias_type %r(year)i, 'integer'
+ m.alias_type %r(bit)i, 'binary'
+ end
+
# MySQL is too stupid to create a temporary table for use subquery, so we have
# to give it some prompting in the form of a subsubquery. Ugh!
def subquery_for(key, select)
diff --git a/activerecord/lib/active_record/connection_adapters/column.rb b/activerecord/lib/active_record/connection_adapters/column.rb
index 3bab325e42..0087c20b88 100644
--- a/activerecord/lib/active_record/connection_adapters/column.rb
+++ b/activerecord/lib/active_record/connection_adapters/column.rb
@@ -13,11 +13,13 @@ module ActiveRecord
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, :default_function
+ attr_reader :name, :default, :cast_type, :limit, :null, :sql_type, :precision, :scale, :default_function
attr_accessor :primary, :coder
alias :encoded? :coder
+ delegate :type, to: :cast_type
+
# Instantiates a new column in the table.
#
# +name+ is the column's name, such as <tt>supplier_id</tt> in <tt>supplier_id int(11)</tt>.
@@ -35,7 +37,6 @@ module ActiveRecord
@limit = extract_limit(sql_type)
@precision = extract_precision(sql_type)
@scale = extract_scale(sql_type)
- @type = simplified_type(sql_type)
@default = extract_default(default)
@default_function = nil
@primary = nil
@@ -256,6 +257,8 @@ module ActiveRecord
end
private
+ delegate :extract_scale, to: Type
+
def extract_limit(sql_type)
$1.to_i if sql_type =~ /\((.*)\)/
end
@@ -263,40 +266,6 @@ module ActiveRecord
def extract_precision(sql_type)
$2.to_i if sql_type =~ /^(numeric|decimal|number)\((\d+)(,\d+)?\)/i
end
-
- def extract_scale(sql_type)
- case sql_type
- when /^(numeric|decimal|number)\((\d+)\)/i then 0
- when /^(numeric|decimal|number)\((\d+)(,(\d+))\)/i then $4.to_i
- end
- end
-
- def simplified_type(field_type)
- case field_type
- when /int/i
- :integer
- when /float|double/i
- :float
- when /decimal|numeric|number/i
- extract_scale(field_type) == 0 ? :integer : :decimal
- when /datetime/i
- :datetime
- when /timestamp/i
- :timestamp
- when /time/i
- :time
- when /date/i
- :date
- when /clob/i, /text/i
- :text
- when /blob/i, /binary/i
- :binary
- when /char/i
- :string
- when /boolean/i
- :boolean
- end
- end
end
end
# :startdoc:
diff --git a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
index 69e2b0ab2b..bf09bfe217 100644
--- a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
@@ -223,6 +223,7 @@ module ActiveRecord
# Clears the prepared statements cache.
def clear_cache!
+ super
@statements.clear
end
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/column.rb b/activerecord/lib/active_record/connection_adapters/postgresql/column.rb
index 77fdebbbc9..1dd8acc257 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/column.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/column.rb
@@ -165,11 +165,6 @@ module ActiveRecord
super
end
end
-
- # Maps PostgreSQL-specific data types to logical Rails types.
- def simplified_type(field_type)
- @oid_type.simplified_type(field_type) || super
- end
end
end
end
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb
index a97c33ae6f..90bf6c6d1a 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb
@@ -2,10 +2,7 @@ module ActiveRecord
module ConnectionAdapters
module PostgreSQL
module OID # :nodoc:
- class Type
- def type; end
- def simplified_type(sql_type); type end
-
+ class Type < Type::Value
def infinity(options = {})
::Float::INFINITY * (options[:negative] ? -1 : 1)
end
@@ -136,11 +133,11 @@ module ActiveRecord
end
class Range < Type
- attr_reader :subtype
- def simplified_type(sql_type); sql_type.to_sym end
+ attr_reader :subtype, :type
- def initialize(subtype)
+ def initialize(subtype, type)
@subtype = subtype
+ @type = type
end
def extract_bounds(value)
@@ -412,7 +409,7 @@ This is not reliable and will be removed in the future.
def register_range_type(row)
if subtype = @store[row['rngsubtype'].to_i]
- register row['oid'], OID::Range.new(subtype)
+ register row['oid'], OID::Range.new(subtype, row['typname'].to_sym)
end
end
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
index 183d0c4ec6..59e157744f 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
@@ -539,10 +539,6 @@ module ActiveRecord
private
- def type_map
- @type_map
- end
-
def get_oid_type(oid, fmod, column_name)
if !type_map.key?(oid)
initialize_type_map(type_map, [oid])
@@ -554,11 +550,6 @@ module ActiveRecord
}
end
- def reload_type_map
- type_map.clear
- initialize_type_map(type_map)
- end
-
def initialize_type_map(type_map, oids = nil)
if supports_ranges?
query = <<-SQL
diff --git a/activerecord/lib/active_record/connection_adapters/type.rb b/activerecord/lib/active_record/connection_adapters/type.rb
index 1b27377cde..34b1e9e39e 100644
--- a/activerecord/lib/active_record/connection_adapters/type.rb
+++ b/activerecord/lib/active_record/connection_adapters/type.rb
@@ -1,8 +1,28 @@
require 'active_record/connection_adapters/type/value'
+require 'active_record/connection_adapters/type/binary'
+require 'active_record/connection_adapters/type/boolean'
+require 'active_record/connection_adapters/type/date'
+require 'active_record/connection_adapters/type/date_time'
+require 'active_record/connection_adapters/type/decimal'
+require 'active_record/connection_adapters/type/float'
+require 'active_record/connection_adapters/type/integer'
+require 'active_record/connection_adapters/type/string'
+require 'active_record/connection_adapters/type/text'
+require 'active_record/connection_adapters/type/time'
+require 'active_record/connection_adapters/type/timestamp'
+require 'active_record/connection_adapters/type/type_map'
module ActiveRecord
module ConnectionAdapters
module Type # :nodoc:
+ class << self
+ def extract_scale(sql_type)
+ case sql_type
+ when /^(numeric|decimal|number)\((\d+)\)/i then 0
+ when /^(numeric|decimal|number)\((\d+)(,(\d+))\)/i then $4.to_i
+ end
+ end
+ end
end
end
end
diff --git a/activerecord/lib/active_record/connection_adapters/type/binary.rb b/activerecord/lib/active_record/connection_adapters/type/binary.rb
new file mode 100644
index 0000000000..168d824d3d
--- /dev/null
+++ b/activerecord/lib/active_record/connection_adapters/type/binary.rb
@@ -0,0 +1,11 @@
+module ActiveRecord
+ module ConnectionAdapters
+ module Type
+ class Binary < Value # :nodoc:
+ def type
+ :binary
+ end
+ end
+ end
+ end
+end
diff --git a/activerecord/lib/active_record/connection_adapters/type/boolean.rb b/activerecord/lib/active_record/connection_adapters/type/boolean.rb
new file mode 100644
index 0000000000..938d227632
--- /dev/null
+++ b/activerecord/lib/active_record/connection_adapters/type/boolean.rb
@@ -0,0 +1,11 @@
+module ActiveRecord
+ module ConnectionAdapters
+ module Type
+ class Boolean < Value # :nodoc:
+ def type
+ :boolean
+ end
+ end
+ end
+ end
+end
diff --git a/activerecord/lib/active_record/connection_adapters/type/date.rb b/activerecord/lib/active_record/connection_adapters/type/date.rb
new file mode 100644
index 0000000000..1632f3c8f4
--- /dev/null
+++ b/activerecord/lib/active_record/connection_adapters/type/date.rb
@@ -0,0 +1,11 @@
+module ActiveRecord
+ module ConnectionAdapters
+ module Type
+ class Date < Value # :nodoc:
+ def type
+ :date
+ end
+ end
+ end
+ end
+end
diff --git a/activerecord/lib/active_record/connection_adapters/type/date_time.rb b/activerecord/lib/active_record/connection_adapters/type/date_time.rb
new file mode 100644
index 0000000000..1d7d3cfbbf
--- /dev/null
+++ b/activerecord/lib/active_record/connection_adapters/type/date_time.rb
@@ -0,0 +1,13 @@
+require 'active_record/connection_adapters/type/timestamp'
+
+module ActiveRecord
+ module ConnectionAdapters
+ module Type
+ class DateTime < Timestamp # :nodoc:
+ def type
+ :datetime
+ end
+ end
+ end
+ end
+end
diff --git a/activerecord/lib/active_record/connection_adapters/type/decimal.rb b/activerecord/lib/active_record/connection_adapters/type/decimal.rb
new file mode 100644
index 0000000000..5b39ea9e2f
--- /dev/null
+++ b/activerecord/lib/active_record/connection_adapters/type/decimal.rb
@@ -0,0 +1,11 @@
+module ActiveRecord
+ module ConnectionAdapters
+ module Type
+ class Decimal < Value # :nodoc:
+ def type
+ :decimal
+ end
+ end
+ end
+ end
+end
diff --git a/activerecord/lib/active_record/connection_adapters/type/float.rb b/activerecord/lib/active_record/connection_adapters/type/float.rb
new file mode 100644
index 0000000000..089169e7c9
--- /dev/null
+++ b/activerecord/lib/active_record/connection_adapters/type/float.rb
@@ -0,0 +1,11 @@
+module ActiveRecord
+ module ConnectionAdapters
+ module Type
+ class Float < Value # :nodoc:
+ def type
+ :float
+ end
+ end
+ end
+ end
+end
diff --git a/activerecord/lib/active_record/connection_adapters/type/integer.rb b/activerecord/lib/active_record/connection_adapters/type/integer.rb
new file mode 100644
index 0000000000..5510a11bd4
--- /dev/null
+++ b/activerecord/lib/active_record/connection_adapters/type/integer.rb
@@ -0,0 +1,11 @@
+module ActiveRecord
+ module ConnectionAdapters
+ module Type
+ class Integer < Value # :nodoc:
+ def type
+ :integer
+ end
+ end
+ end
+ end
+end
diff --git a/activerecord/lib/active_record/connection_adapters/type/string.rb b/activerecord/lib/active_record/connection_adapters/type/string.rb
new file mode 100644
index 0000000000..0feb4299f5
--- /dev/null
+++ b/activerecord/lib/active_record/connection_adapters/type/string.rb
@@ -0,0 +1,11 @@
+module ActiveRecord
+ module ConnectionAdapters
+ module Type
+ class String < Value # :nodoc:
+ def type
+ :string
+ end
+ end
+ end
+ end
+end
diff --git a/activerecord/lib/active_record/connection_adapters/type/text.rb b/activerecord/lib/active_record/connection_adapters/type/text.rb
new file mode 100644
index 0000000000..ee5842a3fc
--- /dev/null
+++ b/activerecord/lib/active_record/connection_adapters/type/text.rb
@@ -0,0 +1,13 @@
+require 'active_record/connection_adapters/type/string'
+
+module ActiveRecord
+ module ConnectionAdapters
+ module Type
+ class Text < String # :nodoc:
+ def type
+ :text
+ end
+ end
+ end
+ end
+end
diff --git a/activerecord/lib/active_record/connection_adapters/type/time.rb b/activerecord/lib/active_record/connection_adapters/type/time.rb
new file mode 100644
index 0000000000..a3a687a8ad
--- /dev/null
+++ b/activerecord/lib/active_record/connection_adapters/type/time.rb
@@ -0,0 +1,11 @@
+module ActiveRecord
+ module ConnectionAdapters
+ module Type
+ class Time < Value # :nodoc:
+ def type
+ :time
+ end
+ end
+ end
+ end
+end
diff --git a/activerecord/lib/active_record/connection_adapters/type/timestamp.rb b/activerecord/lib/active_record/connection_adapters/type/timestamp.rb
new file mode 100644
index 0000000000..92bf0a1954
--- /dev/null
+++ b/activerecord/lib/active_record/connection_adapters/type/timestamp.rb
@@ -0,0 +1,11 @@
+module ActiveRecord
+ module ConnectionAdapters
+ module Type
+ class Timestamp < Value # :nodoc:
+ def type
+ :timestamp
+ end
+ end
+ end
+ end
+end
diff --git a/activerecord/lib/active_record/connection_adapters/type/type_map.rb b/activerecord/lib/active_record/connection_adapters/type/type_map.rb
new file mode 100644
index 0000000000..d89171a820
--- /dev/null
+++ b/activerecord/lib/active_record/connection_adapters/type/type_map.rb
@@ -0,0 +1,50 @@
+module ActiveRecord
+ module ConnectionAdapters
+ module Type
+ class TypeMap # :nodoc:
+ def initialize
+ @mapping = {}
+ end
+
+ def lookup(lookup_key)
+ matching_pair = @mapping.reverse_each.detect do |key, _|
+ key === lookup_key
+ end
+
+ if matching_pair
+ matching_pair.last.call(lookup_key)
+ else
+ default_value
+ end
+ end
+
+ def register_type(key, value = nil, &block)
+ raise ::ArgumentError unless value || block
+
+ if block
+ @mapping[key] = block
+ else
+ @mapping[key] = proc { value }
+ end
+ end
+
+ def alias_type(key, target_key)
+ register_type(key) do |sql_type|
+ metadata = sql_type[/\(.*\)/, 0]
+ lookup("#{target_key}#{metadata}")
+ end
+ end
+
+ def clear
+ @mapping.clear
+ end
+
+ private
+
+ def default_value
+ @default_value ||= Value.new
+ end
+ end
+ end
+ end
+end
diff --git a/activerecord/lib/active_record/connection_adapters/type/value.rb b/activerecord/lib/active_record/connection_adapters/type/value.rb
index 36f680050f..f7d7b9351b 100644
--- a/activerecord/lib/active_record/connection_adapters/type/value.rb
+++ b/activerecord/lib/active_record/connection_adapters/type/value.rb
@@ -2,6 +2,7 @@ module ActiveRecord
module ConnectionAdapters
module Type
class Value # :nodoc:
+ def type; end
end
end
end