aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract_adapter.rb5
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb9
-rw-r--r--activerecord/lib/active_record/connection_adapters/column.rb4
-rw-r--r--activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb5
-rw-r--r--activerecord/lib/active_record/connection_adapters/mysql_adapter.rb5
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/column.rb4
-rw-r--r--activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb4
-rw-r--r--activerecord/lib/active_record/connection_adapters/type.rb8
-rw-r--r--activerecord/lib/active_record/connection_adapters/type/value.rb8
-rw-r--r--activerecord/test/active_record/connection_adapters/fake_adapter.rb1
-rw-r--r--activerecord/test/cases/adapters/mysql/quoting_test.rb4
-rw-r--r--activerecord/test/cases/adapters/sqlite3/quoting_test.rb12
-rw-r--r--activerecord/test/cases/column_definition_test.rb44
-rw-r--r--activerecord/test/cases/column_test.rb30
14 files changed, 86 insertions, 57 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
index 3b3b03ff6e..d9c939689f 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
@@ -3,6 +3,7 @@ require 'bigdecimal'
require 'bigdecimal/util'
require 'active_support/core_ext/benchmark'
require 'active_record/connection_adapters/schema_cache'
+require 'active_record/connection_adapters/type'
require 'active_record/connection_adapters/abstract/schema_dumper'
require 'active_record/connection_adapters/abstract/schema_creation'
require 'monitor'
@@ -362,6 +363,10 @@ module ActiveRecord
protected
+ def lookup_cast_type(sql_type) # :nodoc:
+ Type::Value.new
+ end
+
def translate_exception_class(e, sql)
message = "#{e.class.name}: #{e.message}: #{sql}"
@logger.error message if @logger
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 35045b5258..7074f69583 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
@@ -56,11 +56,11 @@ module ActiveRecord
class Column < ConnectionAdapters::Column # :nodoc:
attr_reader :collation, :strict, :extra
- def initialize(name, default, sql_type = nil, null = true, collation = nil, strict = false, extra = "")
+ def initialize(name, default, cast_type, sql_type = nil, null = true, collation = nil, strict = false, extra = "")
@strict = strict
@collation = collation
@extra = extra
- super(name, default, sql_type, null)
+ super(name, default, cast_type, sql_type, null)
end
def extract_default(default)
@@ -263,8 +263,9 @@ module ActiveRecord
end
# Overridden by the adapters to instantiate their specific Column type.
- def new_column(field, default, type, null, collation, extra = "") # :nodoc:
- Column.new(field, default, type, null, collation, extra)
+ def new_column(field, default, sql_type, null, collation, extra = "") # :nodoc:
+ cast_type = lookup_cast_type(sql_type)
+ Column.new(field, default, cast_type, sql_type, null, collation, extra)
end
# Must return the Mysql error number from the exception, if the exception has an
diff --git a/activerecord/lib/active_record/connection_adapters/column.rb b/activerecord/lib/active_record/connection_adapters/column.rb
index 38efebeaf3..3bab325e42 100644
--- a/activerecord/lib/active_record/connection_adapters/column.rb
+++ b/activerecord/lib/active_record/connection_adapters/column.rb
@@ -22,12 +22,14 @@ module ActiveRecord
#
# +name+ is the column's name, such as <tt>supplier_id</tt> in <tt>supplier_id int(11)</tt>.
# +default+ is the type-casted default value, such as +new+ in <tt>sales_stage varchar(20) default 'new'</tt>.
+ # +cast_type+ is the object used for type casting and type information.
# +sql_type+ is used to extract the column's length, if necessary. For example +60+ in
# <tt>company_name varchar(60)</tt>.
# It will be mapped to one of the standard Rails SQL types in the <tt>type</tt> attribute.
# +null+ determines if this column allows +NULL+ values.
- def initialize(name, default, sql_type = nil, null = true)
+ def initialize(name, default, cast_type, sql_type = nil, null = true)
@name = name
+ @cast_type = cast_type
@sql_type = sql_type
@null = null
@limit = extract_limit(sql_type)
diff --git a/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb b/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb
index 233af252d6..2e39168374 100644
--- a/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb
@@ -69,8 +69,9 @@ module ActiveRecord
end
end
- def new_column(field, default, type, null, collation, extra = "") # :nodoc:
- Column.new(field, default, type, null, collation, strict_mode?, extra)
+ def new_column(field, default, sql_type, null, collation, extra = "") # :nodoc:
+ cast_type = lookup_cast_type(sql_type)
+ Column.new(field, default, cast_type, sql_type, null, collation, strict_mode?, extra)
end
def error_number(exception)
diff --git a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
index e6aa2ba921..69e2b0ab2b 100644
--- a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
@@ -156,8 +156,9 @@ module ActiveRecord
end
end
- def new_column(field, default, type, null, collation, extra = "") # :nodoc:
- Column.new(field, default, type, null, collation, strict_mode?, extra)
+ def new_column(field, default, sql_type, null, collation, extra = "") # :nodoc:
+ cast_type = lookup_cast_type(sql_type)
+ Column.new(field, default, cast_type, sql_type, null, collation, strict_mode?, extra)
end
def error_number(exception) # :nodoc:
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/column.rb b/activerecord/lib/active_record/connection_adapters/postgresql/column.rb
index 97a93ce87a..77fdebbbc9 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/column.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/column.rb
@@ -12,10 +12,10 @@ module ActiveRecord
if sql_type =~ /\[\]$/
@array = true
- super(name, default_value, sql_type[0..sql_type.length - 3], null)
+ super(name, default_value, oid_type, sql_type[0..sql_type.length - 3], null)
else
@array = false
- super(name, default_value, sql_type, null)
+ super(name, default_value, oid_type, sql_type, null)
end
@default_function = default if has_default_function?(default_value, default)
diff --git a/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb
index 737f2daa63..0330fa762c 100644
--- a/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb
@@ -394,7 +394,9 @@ module ActiveRecord
field["dflt_value"] = $1.gsub('""', '"')
end
- SQLite3Column.new(field['name'], field['dflt_value'], field['type'], field['notnull'].to_i == 0)
+ sql_type = field['type']
+ cast_type = lookup_cast_type(sql_type)
+ SQLite3Column.new(field['name'], field['dflt_value'], cast_type, sql_type, field['notnull'].to_i == 0)
end
end
diff --git a/activerecord/lib/active_record/connection_adapters/type.rb b/activerecord/lib/active_record/connection_adapters/type.rb
new file mode 100644
index 0000000000..1b27377cde
--- /dev/null
+++ b/activerecord/lib/active_record/connection_adapters/type.rb
@@ -0,0 +1,8 @@
+require 'active_record/connection_adapters/type/value'
+
+module ActiveRecord
+ module ConnectionAdapters
+ module Type # :nodoc:
+ 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
new file mode 100644
index 0000000000..36f680050f
--- /dev/null
+++ b/activerecord/lib/active_record/connection_adapters/type/value.rb
@@ -0,0 +1,8 @@
+module ActiveRecord
+ module ConnectionAdapters
+ module Type
+ class Value # :nodoc:
+ end
+ end
+ end
+end
diff --git a/activerecord/test/active_record/connection_adapters/fake_adapter.rb b/activerecord/test/active_record/connection_adapters/fake_adapter.rb
index 59324c4857..64cde143a1 100644
--- a/activerecord/test/active_record/connection_adapters/fake_adapter.rb
+++ b/activerecord/test/active_record/connection_adapters/fake_adapter.rb
@@ -29,6 +29,7 @@ module ActiveRecord
@columns[table_name] << ActiveRecord::ConnectionAdapters::Column.new(
name.to_s,
options[:default],
+ lookup_cast_type(sql_type.to_s),
sql_type.to_s,
options[:null])
end
diff --git a/activerecord/test/cases/adapters/mysql/quoting_test.rb b/activerecord/test/cases/adapters/mysql/quoting_test.rb
index 3d1330efb8..f650e3fde8 100644
--- a/activerecord/test/cases/adapters/mysql/quoting_test.rb
+++ b/activerecord/test/cases/adapters/mysql/quoting_test.rb
@@ -9,13 +9,13 @@ module ActiveRecord
end
def test_type_cast_true
- c = Column.new(nil, 1, 'boolean')
+ c = Column.new(nil, 1, Type::Value.new, 'boolean')
assert_equal 1, @conn.type_cast(true, nil)
assert_equal 1, @conn.type_cast(true, c)
end
def test_type_cast_false
- c = Column.new(nil, 1, 'boolean')
+ c = Column.new(nil, 1, Type::Value.new, 'boolean')
assert_equal 0, @conn.type_cast(false, nil)
assert_equal 0, @conn.type_cast(false, c)
end
diff --git a/activerecord/test/cases/adapters/sqlite3/quoting_test.rb b/activerecord/test/cases/adapters/sqlite3/quoting_test.rb
index e4b69fdf7b..63170e710e 100644
--- a/activerecord/test/cases/adapters/sqlite3/quoting_test.rb
+++ b/activerecord/test/cases/adapters/sqlite3/quoting_test.rb
@@ -47,13 +47,13 @@ module ActiveRecord
end
def test_type_cast_true
- c = Column.new(nil, 1, 'int')
+ c = Column.new(nil, 1, Type::Value.new, 'int')
assert_equal 't', @conn.type_cast(true, nil)
assert_equal 1, @conn.type_cast(true, c)
end
def test_type_cast_false
- c = Column.new(nil, 1, 'int')
+ c = Column.new(nil, 1, Type::Value.new, 'int')
assert_equal 'f', @conn.type_cast(false, nil)
assert_equal 0, @conn.type_cast(false, c)
end
@@ -61,16 +61,16 @@ module ActiveRecord
def test_type_cast_string
assert_equal '10', @conn.type_cast('10', nil)
- c = Column.new(nil, 1, 'int')
+ c = Column.new(nil, 1, Type::Value.new, 'int')
assert_equal 10, @conn.type_cast('10', c)
- c = Column.new(nil, 1, 'float')
+ c = Column.new(nil, 1, Type::Value.new, 'float')
assert_equal 10.1, @conn.type_cast('10.1', c)
- c = Column.new(nil, 1, 'binary')
+ c = Column.new(nil, 1, Type::Value.new, 'binary')
assert_equal '10.1', @conn.type_cast('10.1', c)
- c = Column.new(nil, 1, 'date')
+ c = Column.new(nil, 1, Type::Value.new, 'date')
assert_equal '10.1', @conn.type_cast('10.1', c)
end
diff --git a/activerecord/test/cases/column_definition_test.rb b/activerecord/test/cases/column_definition_test.rb
index c1dd1f1c69..33aba6421e 100644
--- a/activerecord/test/cases/column_definition_test.rb
+++ b/activerecord/test/cases/column_definition_test.rb
@@ -12,13 +12,13 @@ module ActiveRecord
end
def test_can_set_coder
- column = Column.new("title", nil, "varchar(20)")
+ column = Column.new("title", nil, Type::Value.new, "varchar(20)")
column.coder = YAML
assert_equal YAML, column.coder
end
def test_encoded?
- column = Column.new("title", nil, "varchar(20)")
+ column = Column.new("title", nil, Type::Value.new, "varchar(20)")
assert !column.encoded?
column.coder = YAML
@@ -26,7 +26,7 @@ module ActiveRecord
end
def test_type_case_coded_column
- column = Column.new("title", nil, "varchar(20)")
+ column = Column.new("title", nil, Type::Value.new, "varchar(20)")
column.coder = YAML
assert_equal "hello", column.type_cast("--- hello")
end
@@ -34,7 +34,7 @@ module ActiveRecord
# Avoid column definitions in create table statements like:
# `title` varchar(255) DEFAULT NULL
def test_should_not_include_default_clause_when_default_is_null
- column = Column.new("title", nil, "varchar(20)")
+ column = Column.new("title", nil, Type::Value.new, "varchar(20)")
column_def = ColumnDefinition.new(
column.name, "string",
column.limit, column.precision, column.scale, column.default, column.null)
@@ -42,7 +42,7 @@ module ActiveRecord
end
def test_should_include_default_clause_when_default_is_present
- column = Column.new("title", "Hello", "varchar(20)")
+ column = Column.new("title", "Hello", Type::Value.new, "varchar(20)")
column_def = ColumnDefinition.new(
column.name, "string",
column.limit, column.precision, column.scale, column.default, column.null)
@@ -50,7 +50,7 @@ module ActiveRecord
end
def test_should_specify_not_null_if_null_option_is_false
- column = Column.new("title", "Hello", "varchar(20)", false)
+ column = Column.new("title", "Hello", Type::Value.new, "varchar(20)", false)
column_def = ColumnDefinition.new(
column.name, "string",
column.limit, column.precision, column.scale, column.default, column.null)
@@ -59,68 +59,68 @@ module ActiveRecord
if current_adapter?(:MysqlAdapter)
def test_should_set_default_for_mysql_binary_data_types
- binary_column = MysqlAdapter::Column.new("title", "a", "binary(1)")
+ binary_column = MysqlAdapter::Column.new("title", "a", Type::Value.new, "binary(1)")
assert_equal "a", binary_column.default
- varbinary_column = MysqlAdapter::Column.new("title", "a", "varbinary(1)")
+ varbinary_column = MysqlAdapter::Column.new("title", "a", Type::Value.new, "varbinary(1)")
assert_equal "a", varbinary_column.default
end
def test_should_not_set_default_for_blob_and_text_data_types
assert_raise ArgumentError do
- MysqlAdapter::Column.new("title", "a", "blob")
+ MysqlAdapter::Column.new("title", "a", Type::Value.new, "blob")
end
assert_raise ArgumentError do
- MysqlAdapter::Column.new("title", "Hello", "text")
+ MysqlAdapter::Column.new("title", "Hello", Type::Value.new, "text")
end
- text_column = MysqlAdapter::Column.new("title", nil, "text")
+ text_column = MysqlAdapter::Column.new("title", nil, Type::Value.new, "text")
assert_equal nil, text_column.default
- not_null_text_column = MysqlAdapter::Column.new("title", nil, "text", false)
+ not_null_text_column = MysqlAdapter::Column.new("title", nil, Type::Value.new, "text", false)
assert_equal "", not_null_text_column.default
end
def test_has_default_should_return_false_for_blob_and_text_data_types
- blob_column = MysqlAdapter::Column.new("title", nil, "blob")
+ blob_column = MysqlAdapter::Column.new("title", nil, Type::Value.new, "blob")
assert !blob_column.has_default?
- text_column = MysqlAdapter::Column.new("title", nil, "text")
+ text_column = MysqlAdapter::Column.new("title", nil, Type::Value.new, "text")
assert !text_column.has_default?
end
end
if current_adapter?(:Mysql2Adapter)
def test_should_set_default_for_mysql_binary_data_types
- binary_column = Mysql2Adapter::Column.new("title", "a", "binary(1)")
+ binary_column = Mysql2Adapter::Column.new("title", "a", Type::Value.new, "binary(1)")
assert_equal "a", binary_column.default
- varbinary_column = Mysql2Adapter::Column.new("title", "a", "varbinary(1)")
+ varbinary_column = Mysql2Adapter::Column.new("title", "a", Type::Value.new, "varbinary(1)")
assert_equal "a", varbinary_column.default
end
def test_should_not_set_default_for_blob_and_text_data_types
assert_raise ArgumentError do
- Mysql2Adapter::Column.new("title", "a", "blob")
+ Mysql2Adapter::Column.new("title", "a", Type::Value.new, "blob")
end
assert_raise ArgumentError do
- Mysql2Adapter::Column.new("title", "Hello", "text")
+ Mysql2Adapter::Column.new("title", "Hello", Type::Value.new, "text")
end
- text_column = Mysql2Adapter::Column.new("title", nil, "text")
+ text_column = Mysql2Adapter::Column.new("title", nil, Type::Value.new, "text")
assert_equal nil, text_column.default
- not_null_text_column = Mysql2Adapter::Column.new("title", nil, "text", false)
+ not_null_text_column = Mysql2Adapter::Column.new("title", nil, Type::Value.new, "text", false)
assert_equal "", not_null_text_column.default
end
def test_has_default_should_return_false_for_blob_and_text_data_types
- blob_column = Mysql2Adapter::Column.new("title", nil, "blob")
+ blob_column = Mysql2Adapter::Column.new("title", nil, Type::Value.new, "blob")
assert !blob_column.has_default?
- text_column = Mysql2Adapter::Column.new("title", nil, "text")
+ text_column = Mysql2Adapter::Column.new("title", nil, Type::Value.new, "text")
assert !text_column.has_default?
end
end
diff --git a/activerecord/test/cases/column_test.rb b/activerecord/test/cases/column_test.rb
index 39489c3718..c2135d75da 100644
--- a/activerecord/test/cases/column_test.rb
+++ b/activerecord/test/cases/column_test.rb
@@ -5,7 +5,7 @@ module ActiveRecord
module ConnectionAdapters
class ColumnTest < ActiveRecord::TestCase
def test_type_cast_boolean
- column = Column.new("field", nil, "boolean")
+ column = Column.new("field", nil, Type::Value.new, "boolean")
assert column.type_cast('').nil?
assert column.type_cast(nil).nil?
@@ -36,14 +36,14 @@ module ActiveRecord
end
def test_type_cast_string
- column = Column.new("field", nil, "varchar")
+ column = Column.new("field", nil, Type::Value.new, "varchar")
assert_equal "1", column.type_cast(true)
assert_equal "0", column.type_cast(false)
assert_equal "123", column.type_cast(123)
end
def test_type_cast_integer
- column = Column.new("field", nil, "integer")
+ column = Column.new("field", nil, Type::Value.new, "integer")
assert_equal 1, column.type_cast(1)
assert_equal 1, column.type_cast('1')
assert_equal 1, column.type_cast('1ignore')
@@ -56,50 +56,50 @@ module ActiveRecord
end
def test_type_cast_non_integer_to_integer
- column = Column.new("field", nil, "integer")
+ column = Column.new("field", nil, Type::Value.new, "integer")
assert_nil column.type_cast([1,2])
assert_nil column.type_cast({1 => 2})
assert_nil column.type_cast((1..2))
end
def test_type_cast_activerecord_to_integer
- column = Column.new("field", nil, "integer")
+ column = Column.new("field", nil, Type::Value.new, "integer")
firm = Firm.create(:name => 'Apple')
assert_nil column.type_cast(firm)
end
def test_type_cast_object_without_to_i_to_integer
- column = Column.new("field", nil, "integer")
+ column = Column.new("field", nil, Type::Value.new, "integer")
assert_nil column.type_cast(Object.new)
end
def test_type_cast_nan_and_infinity_to_integer
- column = Column.new("field", nil, "integer")
+ column = Column.new("field", nil, Type::Value.new, "integer")
assert_nil column.type_cast(Float::NAN)
assert_nil column.type_cast(1.0/0.0)
end
def test_type_cast_float
- column = Column.new("field", nil, "float")
+ column = Column.new("field", nil, Type::Value.new, "float")
assert_equal 1.0, column.type_cast("1")
end
def test_type_cast_decimal
- column = Column.new("field", nil, "decimal")
+ column = Column.new("field", nil, Type::Value.new, "decimal")
assert_equal BigDecimal.new("0"), column.type_cast(BigDecimal.new("0"))
assert_equal BigDecimal.new("123"), column.type_cast(123.0)
assert_equal BigDecimal.new("1"), column.type_cast(:"1")
end
def test_type_cast_binary
- column = Column.new("field", nil, "binary")
+ column = Column.new("field", nil, Type::Value.new, "binary")
assert_equal nil, column.type_cast(nil)
assert_equal "1", column.type_cast("1")
assert_equal 1, column.type_cast(1)
end
def test_type_cast_time
- column = Column.new("field", nil, "time")
+ column = Column.new("field", nil, Type::Value.new, "time")
assert_equal nil, column.type_cast(nil)
assert_equal nil, column.type_cast('')
assert_equal nil, column.type_cast('ABC')
@@ -109,7 +109,7 @@ module ActiveRecord
end
def test_type_cast_datetime_and_timestamp
- [Column.new("field", nil, "datetime"), Column.new("field", nil, "timestamp")].each do |column|
+ [Column.new("field", nil, Type::Value.new, "datetime"), Column.new("field", nil, Type::Value.new, "timestamp")].each do |column|
assert_equal nil, column.type_cast(nil)
assert_equal nil, column.type_cast('')
assert_equal nil, column.type_cast(' ')
@@ -121,7 +121,7 @@ module ActiveRecord
end
def test_type_cast_date
- column = Column.new("field", nil, "date")
+ column = Column.new("field", nil, Type::Value.new, "date")
assert_equal nil, column.type_cast(nil)
assert_equal nil, column.type_cast('')
assert_equal nil, column.type_cast(' ')
@@ -132,7 +132,7 @@ module ActiveRecord
end
def test_type_cast_duration_to_integer
- column = Column.new("field", nil, "integer")
+ column = Column.new("field", nil, Type::Value.new, "integer")
assert_equal 1800, column.type_cast(30.minutes)
assert_equal 7200, column.type_cast(2.hours)
end
@@ -147,7 +147,7 @@ module ActiveRecord
if current_adapter?(:SQLite3Adapter)
def test_binary_encoding
- column = SQLite3Column.new("field", nil, "binary")
+ column = SQLite3Column.new("field", nil, Type::Value.new, "binary")
utf8_string = "a string".encode(Encoding::UTF_8)
type_cast = column.type_cast(utf8_string)