Skip to content

Commit dbbcc83

Browse files
committed
Merge pull request rails#15151 from sgrif/sg-add-type-to-column
Add a type object to Column constructor
2 parents 7359f81 + 4bd5dff commit dbbcc83

File tree

14 files changed

+86
-57
lines changed

14 files changed

+86
-57
lines changed

activerecord/lib/active_record/connection_adapters/abstract_adapter.rb

+5
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
require 'bigdecimal/util'
44
require 'active_support/core_ext/benchmark'
55
require 'active_record/connection_adapters/schema_cache'
6+
require 'active_record/connection_adapters/type'
67
require 'active_record/connection_adapters/abstract/schema_dumper'
78
require 'active_record/connection_adapters/abstract/schema_creation'
89
require 'monitor'
@@ -362,6 +363,10 @@ def close
362363

363364
protected
364365

366+
def lookup_cast_type(sql_type) # :nodoc:
367+
Type::Value.new
368+
end
369+
365370
def translate_exception_class(e, sql)
366371
message = "#{e.class.name}: #{e.message}: #{sql}"
367372
@logger.error message if @logger

activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb

+5-4
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,11 @@ def schema_creation
5656
class Column < ConnectionAdapters::Column # :nodoc:
5757
attr_reader :collation, :strict, :extra
5858

59-
def initialize(name, default, sql_type = nil, null = true, collation = nil, strict = false, extra = "")
59+
def initialize(name, default, cast_type, sql_type = nil, null = true, collation = nil, strict = false, extra = "")
6060
@strict = strict
6161
@collation = collation
6262
@extra = extra
63-
super(name, default, sql_type, null)
63+
super(name, default, cast_type, sql_type, null)
6464
end
6565

6666
def extract_default(default)
@@ -263,8 +263,9 @@ def each_hash(result) # :nodoc:
263263
end
264264

265265
# Overridden by the adapters to instantiate their specific Column type.
266-
def new_column(field, default, type, null, collation, extra = "") # :nodoc:
267-
Column.new(field, default, type, null, collation, extra)
266+
def new_column(field, default, sql_type, null, collation, extra = "") # :nodoc:
267+
cast_type = lookup_cast_type(sql_type)
268+
Column.new(field, default, cast_type, sql_type, null, collation, extra)
268269
end
269270

270271
# Must return the Mysql error number from the exception, if the exception has an

activerecord/lib/active_record/connection_adapters/column.rb

+3-1
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,14 @@ module Format
2222
#
2323
# +name+ is the column's name, such as <tt>supplier_id</tt> in <tt>supplier_id int(11)</tt>.
2424
# +default+ is the type-casted default value, such as +new+ in <tt>sales_stage varchar(20) default 'new'</tt>.
25+
# +cast_type+ is the object used for type casting and type information.
2526
# +sql_type+ is used to extract the column's length, if necessary. For example +60+ in
2627
# <tt>company_name varchar(60)</tt>.
2728
# It will be mapped to one of the standard Rails SQL types in the <tt>type</tt> attribute.
2829
# +null+ determines if this column allows +NULL+ values.
29-
def initialize(name, default, sql_type = nil, null = true)
30+
def initialize(name, default, cast_type, sql_type = nil, null = true)
3031
@name = name
32+
@cast_type = cast_type
3133
@sql_type = sql_type
3234
@null = null
3335
@limit = extract_limit(sql_type)

activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb

+3-2
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,9 @@ def each_hash(result) # :nodoc:
6969
end
7070
end
7171

72-
def new_column(field, default, type, null, collation, extra = "") # :nodoc:
73-
Column.new(field, default, type, null, collation, strict_mode?, extra)
72+
def new_column(field, default, sql_type, null, collation, extra = "") # :nodoc:
73+
cast_type = lookup_cast_type(sql_type)
74+
Column.new(field, default, cast_type, sql_type, null, collation, strict_mode?, extra)
7475
end
7576

7677
def error_number(exception)

activerecord/lib/active_record/connection_adapters/mysql_adapter.rb

+3-2
Original file line numberDiff line numberDiff line change
@@ -156,8 +156,9 @@ def each_hash(result) # :nodoc:
156156
end
157157
end
158158

159-
def new_column(field, default, type, null, collation, extra = "") # :nodoc:
160-
Column.new(field, default, type, null, collation, strict_mode?, extra)
159+
def new_column(field, default, sql_type, null, collation, extra = "") # :nodoc:
160+
cast_type = lookup_cast_type(sql_type)
161+
Column.new(field, default, cast_type, sql_type, null, collation, strict_mode?, extra)
161162
end
162163

163164
def error_number(exception) # :nodoc:

activerecord/lib/active_record/connection_adapters/postgresql/column.rb

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ def initialize(name, default, oid_type, sql_type = nil, null = true)
1212

1313
if sql_type =~ /\[\]$/
1414
@array = true
15-
super(name, default_value, sql_type[0..sql_type.length - 3], null)
15+
super(name, default_value, oid_type, sql_type[0..sql_type.length - 3], null)
1616
else
1717
@array = false
18-
super(name, default_value, sql_type, null)
18+
super(name, default_value, oid_type, sql_type, null)
1919
end
2020

2121
@default_function = default if has_default_function?(default_value, default)

activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb

+3-1
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,9 @@ def columns(table_name) #:nodoc:
394394
field["dflt_value"] = $1.gsub('""', '"')
395395
end
396396

397-
SQLite3Column.new(field['name'], field['dflt_value'], field['type'], field['notnull'].to_i == 0)
397+
sql_type = field['type']
398+
cast_type = lookup_cast_type(sql_type)
399+
SQLite3Column.new(field['name'], field['dflt_value'], cast_type, sql_type, field['notnull'].to_i == 0)
398400
end
399401
end
400402

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
require 'active_record/connection_adapters/type/value'
2+
3+
module ActiveRecord
4+
module ConnectionAdapters
5+
module Type # :nodoc:
6+
end
7+
end
8+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
module ActiveRecord
2+
module ConnectionAdapters
3+
module Type
4+
class Value # :nodoc:
5+
end
6+
end
7+
end
8+
end

activerecord/test/active_record/connection_adapters/fake_adapter.rb

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ def merge_column(table_name, name, sql_type = nil, options = {})
2929
@columns[table_name] << ActiveRecord::ConnectionAdapters::Column.new(
3030
name.to_s,
3131
options[:default],
32+
lookup_cast_type(sql_type.to_s),
3233
sql_type.to_s,
3334
options[:null])
3435
end

activerecord/test/cases/adapters/mysql/quoting_test.rb

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@ def setup
99
end
1010

1111
def test_type_cast_true
12-
c = Column.new(nil, 1, 'boolean')
12+
c = Column.new(nil, 1, Type::Value.new, 'boolean')
1313
assert_equal 1, @conn.type_cast(true, nil)
1414
assert_equal 1, @conn.type_cast(true, c)
1515
end
1616

1717
def test_type_cast_false
18-
c = Column.new(nil, 1, 'boolean')
18+
c = Column.new(nil, 1, Type::Value.new, 'boolean')
1919
assert_equal 0, @conn.type_cast(false, nil)
2020
assert_equal 0, @conn.type_cast(false, c)
2121
end

activerecord/test/cases/adapters/sqlite3/quoting_test.rb

+6-6
Original file line numberDiff line numberDiff line change
@@ -47,30 +47,30 @@ def test_type_cast_nil
4747
end
4848

4949
def test_type_cast_true
50-
c = Column.new(nil, 1, 'int')
50+
c = Column.new(nil, 1, Type::Value.new, 'int')
5151
assert_equal 't', @conn.type_cast(true, nil)
5252
assert_equal 1, @conn.type_cast(true, c)
5353
end
5454

5555
def test_type_cast_false
56-
c = Column.new(nil, 1, 'int')
56+
c = Column.new(nil, 1, Type::Value.new, 'int')
5757
assert_equal 'f', @conn.type_cast(false, nil)
5858
assert_equal 0, @conn.type_cast(false, c)
5959
end
6060

6161
def test_type_cast_string
6262
assert_equal '10', @conn.type_cast('10', nil)
6363

64-
c = Column.new(nil, 1, 'int')
64+
c = Column.new(nil, 1, Type::Value.new, 'int')
6565
assert_equal 10, @conn.type_cast('10', c)
6666

67-
c = Column.new(nil, 1, 'float')
67+
c = Column.new(nil, 1, Type::Value.new, 'float')
6868
assert_equal 10.1, @conn.type_cast('10.1', c)
6969

70-
c = Column.new(nil, 1, 'binary')
70+
c = Column.new(nil, 1, Type::Value.new, 'binary')
7171
assert_equal '10.1', @conn.type_cast('10.1', c)
7272

73-
c = Column.new(nil, 1, 'date')
73+
c = Column.new(nil, 1, Type::Value.new, 'date')
7474
assert_equal '10.1', @conn.type_cast('10.1', c)
7575
end
7676

activerecord/test/cases/column_definition_test.rb

+22-22
Original file line numberDiff line numberDiff line change
@@ -12,45 +12,45 @@ def @adapter.native_database_types
1212
end
1313

1414
def test_can_set_coder
15-
column = Column.new("title", nil, "varchar(20)")
15+
column = Column.new("title", nil, Type::Value.new, "varchar(20)")
1616
column.coder = YAML
1717
assert_equal YAML, column.coder
1818
end
1919

2020
def test_encoded?
21-
column = Column.new("title", nil, "varchar(20)")
21+
column = Column.new("title", nil, Type::Value.new, "varchar(20)")
2222
assert !column.encoded?
2323

2424
column.coder = YAML
2525
assert column.encoded?
2626
end
2727

2828
def test_type_case_coded_column
29-
column = Column.new("title", nil, "varchar(20)")
29+
column = Column.new("title", nil, Type::Value.new, "varchar(20)")
3030
column.coder = YAML
3131
assert_equal "hello", column.type_cast("--- hello")
3232
end
3333

3434
# Avoid column definitions in create table statements like:
3535
# `title` varchar(255) DEFAULT NULL
3636
def test_should_not_include_default_clause_when_default_is_null
37-
column = Column.new("title", nil, "varchar(20)")
37+
column = Column.new("title", nil, Type::Value.new, "varchar(20)")
3838
column_def = ColumnDefinition.new(
3939
column.name, "string",
4040
column.limit, column.precision, column.scale, column.default, column.null)
4141
assert_equal "title varchar(20)", @viz.accept(column_def)
4242
end
4343

4444
def test_should_include_default_clause_when_default_is_present
45-
column = Column.new("title", "Hello", "varchar(20)")
45+
column = Column.new("title", "Hello", Type::Value.new, "varchar(20)")
4646
column_def = ColumnDefinition.new(
4747
column.name, "string",
4848
column.limit, column.precision, column.scale, column.default, column.null)
4949
assert_equal %Q{title varchar(20) DEFAULT 'Hello'}, @viz.accept(column_def)
5050
end
5151

5252
def test_should_specify_not_null_if_null_option_is_false
53-
column = Column.new("title", "Hello", "varchar(20)", false)
53+
column = Column.new("title", "Hello", Type::Value.new, "varchar(20)", false)
5454
column_def = ColumnDefinition.new(
5555
column.name, "string",
5656
column.limit, column.precision, column.scale, column.default, column.null)
@@ -59,68 +59,68 @@ def test_should_specify_not_null_if_null_option_is_false
5959

6060
if current_adapter?(:MysqlAdapter)
6161
def test_should_set_default_for_mysql_binary_data_types
62-
binary_column = MysqlAdapter::Column.new("title", "a", "binary(1)")
62+
binary_column = MysqlAdapter::Column.new("title", "a", Type::Value.new, "binary(1)")
6363
assert_equal "a", binary_column.default
6464

65-
varbinary_column = MysqlAdapter::Column.new("title", "a", "varbinary(1)")
65+
varbinary_column = MysqlAdapter::Column.new("title", "a", Type::Value.new, "varbinary(1)")
6666
assert_equal "a", varbinary_column.default
6767
end
6868

6969
def test_should_not_set_default_for_blob_and_text_data_types
7070
assert_raise ArgumentError do
71-
MysqlAdapter::Column.new("title", "a", "blob")
71+
MysqlAdapter::Column.new("title", "a", Type::Value.new, "blob")
7272
end
7373

7474
assert_raise ArgumentError do
75-
MysqlAdapter::Column.new("title", "Hello", "text")
75+
MysqlAdapter::Column.new("title", "Hello", Type::Value.new, "text")
7676
end
7777

78-
text_column = MysqlAdapter::Column.new("title", nil, "text")
78+
text_column = MysqlAdapter::Column.new("title", nil, Type::Value.new, "text")
7979
assert_equal nil, text_column.default
8080

81-
not_null_text_column = MysqlAdapter::Column.new("title", nil, "text", false)
81+
not_null_text_column = MysqlAdapter::Column.new("title", nil, Type::Value.new, "text", false)
8282
assert_equal "", not_null_text_column.default
8383
end
8484

8585
def test_has_default_should_return_false_for_blob_and_text_data_types
86-
blob_column = MysqlAdapter::Column.new("title", nil, "blob")
86+
blob_column = MysqlAdapter::Column.new("title", nil, Type::Value.new, "blob")
8787
assert !blob_column.has_default?
8888

89-
text_column = MysqlAdapter::Column.new("title", nil, "text")
89+
text_column = MysqlAdapter::Column.new("title", nil, Type::Value.new, "text")
9090
assert !text_column.has_default?
9191
end
9292
end
9393

9494
if current_adapter?(:Mysql2Adapter)
9595
def test_should_set_default_for_mysql_binary_data_types
96-
binary_column = Mysql2Adapter::Column.new("title", "a", "binary(1)")
96+
binary_column = Mysql2Adapter::Column.new("title", "a", Type::Value.new, "binary(1)")
9797
assert_equal "a", binary_column.default
9898

99-
varbinary_column = Mysql2Adapter::Column.new("title", "a", "varbinary(1)")
99+
varbinary_column = Mysql2Adapter::Column.new("title", "a", Type::Value.new, "varbinary(1)")
100100
assert_equal "a", varbinary_column.default
101101
end
102102

103103
def test_should_not_set_default_for_blob_and_text_data_types
104104
assert_raise ArgumentError do
105-
Mysql2Adapter::Column.new("title", "a", "blob")
105+
Mysql2Adapter::Column.new("title", "a", Type::Value.new, "blob")
106106
end
107107

108108
assert_raise ArgumentError do
109-
Mysql2Adapter::Column.new("title", "Hello", "text")
109+
Mysql2Adapter::Column.new("title", "Hello", Type::Value.new, "text")
110110
end
111111

112-
text_column = Mysql2Adapter::Column.new("title", nil, "text")
112+
text_column = Mysql2Adapter::Column.new("title", nil, Type::Value.new, "text")
113113
assert_equal nil, text_column.default
114114

115-
not_null_text_column = Mysql2Adapter::Column.new("title", nil, "text", false)
115+
not_null_text_column = Mysql2Adapter::Column.new("title", nil, Type::Value.new, "text", false)
116116
assert_equal "", not_null_text_column.default
117117
end
118118

119119
def test_has_default_should_return_false_for_blob_and_text_data_types
120-
blob_column = Mysql2Adapter::Column.new("title", nil, "blob")
120+
blob_column = Mysql2Adapter::Column.new("title", nil, Type::Value.new, "blob")
121121
assert !blob_column.has_default?
122122

123-
text_column = Mysql2Adapter::Column.new("title", nil, "text")
123+
text_column = Mysql2Adapter::Column.new("title", nil, Type::Value.new, "text")
124124
assert !text_column.has_default?
125125
end
126126
end

0 commit comments

Comments
 (0)