Skip to content

Commit 7c2fabb

Browse files
committed
Make sure basic Rails types match up in schema statements.
1 parent b59081e commit 7c2fabb

File tree

9 files changed

+68
-30
lines changed

9 files changed

+68
-30
lines changed

lib/active_record/connection_adapters/sqlserver/schema_creation.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ module ActiveRecord
22
module ConnectionAdapters
33
module SQLServer
44
class SchemaCreation < AbstractAdapter::SchemaCreation
5+
56
private
67

78
def visit_ColumnDefinition(o)
@@ -50,6 +51,7 @@ def visit_TableDefinition(o)
5051

5152
create_sql
5253
end
54+
5355
end
5456
end
5557
end

lib/active_record/connection_adapters/sqlserver/schema_statements.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ def initialize_native_database_types
168168
decimal: { name: 'decimal' },
169169
money: { name: 'money' },
170170
smallmoney: { name: 'smallmoney' },
171-
float: { name: 'float', limit: 8 },
171+
float: { name: 'float', limit: 24 },
172172
real: { name: 'real' },
173173
date: { name: 'date' },
174174
datetime: { name: 'datetime' },
@@ -402,7 +402,6 @@ def strip_ident_from_update(sql)
402402
# There has to be a better way to handle this, but this'll do for now.
403403
table_name = get_table_name(sql)
404404
id_column = identity_column(table_name)
405-
406405
if id_column
407406
regex_col_name = Regexp.quote(quote_column_name(id_column.name))
408407
if sql =~ /, #{regex_col_name} = @?[0-9]*/
@@ -437,10 +436,11 @@ def identity_column(table_name)
437436
schema_cache.columns(table_name).find(&:is_identity?)
438437
end
439438

439+
440440
private
441441

442442
def create_table_definition(name, temporary, options, as = nil)
443-
TableDefinition.new native_database_types, name, temporary, options, as
443+
SQLServer::TableDefinition.new native_database_types, name, temporary, options, as
444444
end
445445

446446
end

lib/active_record/connection_adapters/sqlserver/table_definition.rb

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ module ActiveRecord
22
module ConnectionAdapters
33
module SQLServer
44
class TableDefinition < ActiveRecord::ConnectionAdapters::TableDefinition
5+
56
def uuid(name, options = {})
67
column(name, 'uniqueidentifier', options)
78
end
@@ -13,10 +14,6 @@ def primary_key(name, type = :primary_key, options = {})
1314
column name, type, options
1415
end
1516

16-
def column(name, type = nil, options = {})
17-
super
18-
self
19-
end
2017
end
2118
end
2219
end

lib/active_record/connection_adapters/sqlserver/type/big_integer.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ module SQLServer
44
module Type
55
class BigInteger < Integer
66

7-
7+
def type
8+
:bigint
9+
end
810

911
end
1012
end

lib/active_record/connection_adapters/sqlserver/type/float.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ class Float < ActiveRecord::Type::Float
66

77
include Castable
88

9+
def initialize(options = {})
10+
super
11+
@limit ||= 24
12+
end
13+
914
end
1015
end
1116
end

test/cases/adapter_test_sqlserver.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ class AdapterTestSQLServer < ActiveRecord::TestCase
333333
end
334334

335335
it 'create floats when no limit supplied' do
336-
assert_equal 'float(8)', connection.type_to_sql(:float)
336+
assert_equal 'float(24)', connection.type_to_sql(:float)
337337
end
338338

339339
it 'create floats when limit is supplied' do

test/cases/column_test_sqlserver.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ def assert_obj_set_and_save(attribute, value)
3737
col.default_function.must_equal nil
3838
type = col.cast_type
3939
type.must_be_instance_of Type::BigInteger
40-
type.type.must_equal :integer
40+
type.type.must_equal :bigint
4141
type.must_be :number?
4242
type.limit.must_equal 8
4343
assert_obj_set_and_save :bigint, -9_223_372_036_854_775_808

test/cases/schema_dumper_test_sqlserver.rb

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ class SchemaDumperTestSQLServer < ActiveRecord::TestCase
1010
it 'sst_datatypes' do
1111
generate_schema_for_table 'sst_datatypes'
1212
# Exact Numerics
13-
assert_line :bigint, type: 'integer', limit: '8', precision: nil, scale: nil, default: '42'
13+
assert_line :bigint, type: 'bigint', limit: '8', precision: nil, scale: nil, default: '42'
1414
assert_line :int, type: 'integer', limit: '4', precision: nil, scale: nil, default: '42'
1515
assert_line :smallint, type: 'integer', limit: '2', precision: nil, scale: nil, default: '42'
1616
assert_line :tinyint, type: 'integer', limit: '1', precision: nil, scale: nil, default: '42'
@@ -46,6 +46,38 @@ class SchemaDumperTestSQLServer < ActiveRecord::TestCase
4646
assert_line :varbinary_max, type: 'binary', limit: '2147483647', precision: nil, scale: nil, default: nil
4747
end
4848

49+
it 'sst_datatypes_migration' do
50+
columns = SSTestDatatypeMigration.columns_hash
51+
generate_schema_for_table 'sst_datatypes_migration'
52+
# Simple Rails conventions
53+
columns['integer_col'].sql_type.must_equal 'int(4)'
54+
columns['bigint_col'].sql_type.must_equal 'bigint(8)'
55+
columns['boolean_col'].sql_type.must_equal 'bit'
56+
columns['decimal_col'].sql_type.must_equal 'decimal(18,0)'
57+
columns['float_col'].sql_type.must_equal 'real(24)'
58+
columns['string_col'].sql_type.must_equal 'nvarchar(4000)'
59+
columns['text_col'].sql_type.must_equal 'nvarchar(max)'
60+
columns['datetime_col'].sql_type.must_equal 'datetime'
61+
columns['timestamp_col'].sql_type.must_equal 'datetime'
62+
columns['time_col'].sql_type.must_equal 'time(7)'
63+
columns['date_col'].sql_type.must_equal 'date'
64+
columns['binary_col'].sql_type.must_equal 'varbinary(max)'
65+
assert_line :integer_col, type: 'integer', limit: '4', precision: nil, scale: nil, default: nil
66+
assert_line :bigint_col, type: 'bigint', limit: '8', precision: nil, scale: nil, default: nil
67+
assert_line :boolean_col, type: 'boolean', limit: nil, precision: nil, scale: nil, default: nil
68+
assert_line :decimal_col, type: 'decimal', limit: nil, precision: '18', scale: '0', default: nil
69+
assert_line :float_col, type: 'real', limit: '24', precision: nil, scale: nil, default: nil
70+
assert_line :string_col, type: 'string', limit: '4000', precision: nil, scale: nil, default: nil
71+
assert_line :text_col, type: 'text', limit: '2147483647', precision: nil, scale: nil, default: nil
72+
assert_line :datetime_col, type: 'datetime', limit: nil, precision: nil, scale: nil, default: nil
73+
assert_line :timestamp_col, type: 'datetime', limit: nil, precision: nil, scale: nil, default: nil
74+
assert_line :time_col, type: 'time', limit: nil, precision: '7', scale: nil, default: nil
75+
assert_line :date_col, type: 'date', limit: nil, precision: nil, scale: nil, default: nil
76+
assert_line :binary_col, type: 'binary', limit: '2147483647', precision: nil, scale: nil, default: nil
77+
end
78+
79+
# Special Cases
80+
4981
it 'primary_key' do
5082
generate_schema_for_table('movies') do |output|
5183
match = output.match(%r{create_table "movies"(.*)do})
@@ -54,18 +86,6 @@ class SchemaDumperTestSQLServer < ActiveRecord::TestCase
5486
end
5587
end
5688

57-
it 'a string type is nvarchar without a limit' do
58-
generate_schema_for_table 'sst_datatypes_migration'
59-
SSTestDatatypeMigration.columns_hash['string_col'].sql_type.must_equal 'nvarchar(4000)'
60-
assert_line :string_col, type: 'string', limit: '4000', precision: nil, scale: nil, default: nil
61-
end
62-
63-
it 'a text type is nvarchar max' do
64-
generate_schema_for_table 'sst_datatypes_migration'
65-
SSTestDatatypeMigration.columns_hash['text_col'].sql_type.must_equal 'nvarchar(max)'
66-
assert_line :text_col, type: 'text', limit: '2147483647', precision: nil, scale: nil, default: nil
67-
end
68-
6989

7090
private
7191

@@ -77,7 +97,7 @@ def generate_schema_for_table(*table_names)
7797
@generated_schema = stream.string
7898
yield @generated_schema if block_given?
7999
@schema_lines = Hash.new
80-
type_matcher = /\A\s+t\.\w+\s+"(.*?)",/
100+
type_matcher = /\A\s+t\.\w+\s+"(.*?)"[,\n]/
81101
@generated_schema.each_line do |line|
82102
next unless line =~ type_matcher
83103
@schema_lines[Regexp.last_match[1]] = SchemaLine.new(line)
@@ -91,7 +111,7 @@ def line(column_name)
91111

92112
def assert_line(column_name, options={})
93113
line = line(column_name)
94-
assert line, "Count not find line with column name: #{column_name.inspect}"
114+
assert line, "Count not find line with column name: #{column_name.inspect} in schema:\n#{schema}"
95115
line.type_method.must_equal options[:type], "Type of #{options[:type].inspect} not found in:\n #{line}" if options.key?(:type)
96116
line.limit.must_equal options[:limit], "Limit of #{options[:limit].inspect} not found in:\n #{line}" if options.key?(:limit)
97117
line.precision.must_equal options[:precision], "Precision of #{options[:precision].inspect} not found in:\n #{line}" if options.key?(:precision)

test/schema/sqlserver_specific_schema.rb

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,29 @@
55
execute File.read(ARTest::SQLServer.schema_datatypes_2012_file)
66

77
create_table :sst_datatypes_migration, force: true do |t|
8-
# Rails conventions
9-
t.string :string_col
10-
t.text :text_col
11-
# Our type methods
8+
# Simple Rails conventions.
9+
t.integer :integer_col
10+
t.bigint :bigint_col
11+
t.boolean :boolean_col
12+
t.decimal :decimal_col
13+
t.float :float_col
14+
t.string :string_col
15+
t.text :text_col
16+
t.datetime :datetime_col
17+
t.timestamp :timestamp_col
18+
t.time :time_col
19+
t.date :date_col
20+
t.binary :binary_col
21+
22+
23+
# Our type methods. Make sure we can reverse schema dump for [sst_datatypes] table.
1224
# ...
1325
end
1426

1527
# Edge Cases
1628

1729
create_table 'sst_my$strange_table', force: true do |t|
18-
t.column :number, :real
30+
t.string :name
1931
end
2032

2133
create_table :SST_UPPER_TESTS, force: true do |t|

0 commit comments

Comments
 (0)