activerecord-sqlserver-adapter 6.0.0.rc1 → 6.1.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (149) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +26 -0
  3. data/.gitignore +1 -0
  4. data/.rubocop.yml +29 -0
  5. data/CHANGELOG.md +18 -23
  6. data/Gemfile +11 -5
  7. data/Guardfile +9 -8
  8. data/README.md +32 -3
  9. data/RUNNING_UNIT_TESTS.md +1 -1
  10. data/Rakefile +12 -16
  11. data/VERSION +1 -1
  12. data/activerecord-sqlserver-adapter.gemspec +4 -4
  13. data/lib/active_record/connection_adapters/sqlserver/core_ext/active_record.rb +0 -4
  14. data/lib/active_record/connection_adapters/sqlserver/core_ext/attribute_methods.rb +1 -4
  15. data/lib/active_record/connection_adapters/sqlserver/core_ext/calculations.rb +3 -13
  16. data/lib/active_record/connection_adapters/sqlserver/core_ext/explain.rb +8 -5
  17. data/lib/active_record/connection_adapters/sqlserver/core_ext/finder_methods.rb +2 -3
  18. data/lib/active_record/connection_adapters/sqlserver/core_ext/query_methods.rb +2 -3
  19. data/lib/active_record/connection_adapters/sqlserver/database_limits.rb +0 -4
  20. data/lib/active_record/connection_adapters/sqlserver/database_statements.rb +58 -43
  21. data/lib/active_record/connection_adapters/sqlserver/database_tasks.rb +7 -12
  22. data/lib/active_record/connection_adapters/sqlserver/errors.rb +0 -3
  23. data/lib/active_record/connection_adapters/sqlserver/quoting.rb +15 -15
  24. data/lib/active_record/connection_adapters/sqlserver/schema_creation.rb +22 -3
  25. data/lib/active_record/connection_adapters/sqlserver/schema_dumper.rb +16 -10
  26. data/lib/active_record/connection_adapters/sqlserver/schema_statements.rb +131 -105
  27. data/lib/active_record/connection_adapters/sqlserver/showplan.rb +6 -8
  28. data/lib/active_record/connection_adapters/sqlserver/showplan/printer_table.rb +2 -2
  29. data/lib/active_record/connection_adapters/sqlserver/showplan/printer_xml.rb +1 -1
  30. data/lib/active_record/connection_adapters/sqlserver/sql_type_metadata.rb +25 -7
  31. data/lib/active_record/connection_adapters/sqlserver/table_definition.rb +1 -5
  32. data/lib/active_record/connection_adapters/sqlserver/transaction.rb +6 -10
  33. data/lib/active_record/connection_adapters/sqlserver/type.rb +36 -35
  34. data/lib/active_record/connection_adapters/sqlserver/type/big_integer.rb +0 -2
  35. data/lib/active_record/connection_adapters/sqlserver/type/binary.rb +0 -2
  36. data/lib/active_record/connection_adapters/sqlserver/type/boolean.rb +0 -2
  37. data/lib/active_record/connection_adapters/sqlserver/type/char.rb +2 -2
  38. data/lib/active_record/connection_adapters/sqlserver/type/data.rb +0 -2
  39. data/lib/active_record/connection_adapters/sqlserver/type/date.rb +2 -3
  40. data/lib/active_record/connection_adapters/sqlserver/type/datetime.rb +2 -3
  41. data/lib/active_record/connection_adapters/sqlserver/type/datetime2.rb +0 -2
  42. data/lib/active_record/connection_adapters/sqlserver/type/datetimeoffset.rb +0 -2
  43. data/lib/active_record/connection_adapters/sqlserver/type/decimal.rb +0 -2
  44. data/lib/active_record/connection_adapters/sqlserver/type/decimal_without_scale.rb +22 -0
  45. data/lib/active_record/connection_adapters/sqlserver/type/float.rb +0 -2
  46. data/lib/active_record/connection_adapters/sqlserver/type/integer.rb +0 -2
  47. data/lib/active_record/connection_adapters/sqlserver/type/json.rb +0 -1
  48. data/lib/active_record/connection_adapters/sqlserver/type/money.rb +0 -2
  49. data/lib/active_record/connection_adapters/sqlserver/type/real.rb +0 -2
  50. data/lib/active_record/connection_adapters/sqlserver/type/small_integer.rb +0 -2
  51. data/lib/active_record/connection_adapters/sqlserver/type/small_money.rb +0 -2
  52. data/lib/active_record/connection_adapters/sqlserver/type/smalldatetime.rb +0 -2
  53. data/lib/active_record/connection_adapters/sqlserver/type/string.rb +0 -2
  54. data/lib/active_record/connection_adapters/sqlserver/type/text.rb +0 -2
  55. data/lib/active_record/connection_adapters/sqlserver/type/time.rb +2 -3
  56. data/lib/active_record/connection_adapters/sqlserver/type/time_value_fractional.rb +6 -9
  57. data/lib/active_record/connection_adapters/sqlserver/type/timestamp.rb +0 -2
  58. data/lib/active_record/connection_adapters/sqlserver/type/tiny_integer.rb +0 -2
  59. data/lib/active_record/connection_adapters/sqlserver/type/unicode_char.rb +1 -3
  60. data/lib/active_record/connection_adapters/sqlserver/type/unicode_string.rb +0 -2
  61. data/lib/active_record/connection_adapters/sqlserver/type/unicode_text.rb +0 -2
  62. data/lib/active_record/connection_adapters/sqlserver/type/unicode_varchar.rb +0 -2
  63. data/lib/active_record/connection_adapters/sqlserver/type/unicode_varchar_max.rb +0 -2
  64. data/lib/active_record/connection_adapters/sqlserver/type/uuid.rb +1 -2
  65. data/lib/active_record/connection_adapters/sqlserver/type/varbinary.rb +1 -3
  66. data/lib/active_record/connection_adapters/sqlserver/type/varbinary_max.rb +0 -2
  67. data/lib/active_record/connection_adapters/sqlserver/type/varchar.rb +1 -3
  68. data/lib/active_record/connection_adapters/sqlserver/type/varchar_max.rb +0 -2
  69. data/lib/active_record/connection_adapters/sqlserver/utils.rb +8 -11
  70. data/lib/active_record/connection_adapters/sqlserver/version.rb +0 -2
  71. data/lib/active_record/connection_adapters/sqlserver_adapter.rb +170 -136
  72. data/lib/active_record/connection_adapters/sqlserver_column.rb +16 -1
  73. data/lib/active_record/sqlserver_base.rb +9 -15
  74. data/lib/active_record/tasks/sqlserver_database_tasks.rb +36 -39
  75. data/lib/activerecord-sqlserver-adapter.rb +1 -1
  76. data/lib/arel/visitors/sqlserver.rb +126 -50
  77. data/lib/arel_sqlserver.rb +2 -2
  78. data/test/cases/adapter_test_sqlserver.rb +203 -190
  79. data/test/cases/change_column_collation_test_sqlserver.rb +33 -0
  80. data/test/cases/change_column_null_test_sqlserver.rb +12 -12
  81. data/test/cases/coerced_tests.rb +656 -318
  82. data/test/cases/column_test_sqlserver.rb +285 -284
  83. data/test/cases/connection_test_sqlserver.rb +15 -20
  84. data/test/cases/disconnected_test_sqlserver.rb +39 -0
  85. data/test/cases/execute_procedure_test_sqlserver.rb +26 -19
  86. data/test/cases/fetch_test_sqlserver.rb +14 -22
  87. data/test/cases/fully_qualified_identifier_test_sqlserver.rb +12 -18
  88. data/test/cases/helper_sqlserver.rb +13 -15
  89. data/test/cases/in_clause_test_sqlserver.rb +36 -9
  90. data/test/cases/index_test_sqlserver.rb +13 -15
  91. data/test/cases/json_test_sqlserver.rb +23 -25
  92. data/test/cases/lateral_test_sqlserver.rb +35 -0
  93. data/test/cases/migration_test_sqlserver.rb +71 -26
  94. data/test/cases/optimizer_hints_test_sqlserver.rb +72 -0
  95. data/test/cases/order_test_sqlserver.rb +57 -53
  96. data/test/cases/pessimistic_locking_test_sqlserver.rb +25 -33
  97. data/test/cases/primary_keys_test_sqlserver.rb +103 -0
  98. data/test/cases/rake_test_sqlserver.rb +33 -46
  99. data/test/cases/schema_dumper_test_sqlserver.rb +121 -108
  100. data/test/cases/schema_test_sqlserver.rb +18 -26
  101. data/test/cases/scratchpad_test_sqlserver.rb +2 -4
  102. data/test/cases/showplan_test_sqlserver.rb +24 -33
  103. data/test/cases/specific_schema_test_sqlserver.rb +66 -65
  104. data/test/cases/transaction_test_sqlserver.rb +16 -19
  105. data/test/cases/trigger_test_sqlserver.rb +12 -12
  106. data/test/cases/utils_test_sqlserver.rb +68 -70
  107. data/test/cases/uuid_test_sqlserver.rb +11 -13
  108. data/test/debug.rb +6 -6
  109. data/test/migrations/create_clients_and_change_column_collation.rb +19 -0
  110. data/test/migrations/create_clients_and_change_column_null.rb +1 -1
  111. data/test/migrations/transaction_table/1_table_will_never_be_created.rb +2 -4
  112. data/test/models/sqlserver/booking.rb +1 -1
  113. data/test/models/sqlserver/customers_view.rb +1 -1
  114. data/test/models/sqlserver/dollar_table_name.rb +1 -1
  115. data/test/models/sqlserver/edge_schema.rb +1 -3
  116. data/test/models/sqlserver/fk_has_fk.rb +1 -1
  117. data/test/models/sqlserver/fk_has_pk.rb +1 -1
  118. data/test/models/sqlserver/natural_pk_data.rb +2 -2
  119. data/test/models/sqlserver/natural_pk_int_data.rb +1 -1
  120. data/test/models/sqlserver/no_pk_data.rb +1 -1
  121. data/test/models/sqlserver/object_default.rb +1 -1
  122. data/test/models/sqlserver/quoted_table.rb +2 -2
  123. data/test/models/sqlserver/quoted_view_1.rb +1 -1
  124. data/test/models/sqlserver/quoted_view_2.rb +1 -1
  125. data/test/models/sqlserver/sst_memory.rb +1 -1
  126. data/test/models/sqlserver/sst_string_collation.rb +3 -0
  127. data/test/models/sqlserver/string_default.rb +1 -1
  128. data/test/models/sqlserver/string_defaults_big_view.rb +1 -1
  129. data/test/models/sqlserver/string_defaults_view.rb +1 -1
  130. data/test/models/sqlserver/tinyint_pk.rb +1 -1
  131. data/test/models/sqlserver/trigger.rb +2 -2
  132. data/test/models/sqlserver/trigger_history.rb +1 -1
  133. data/test/models/sqlserver/upper.rb +1 -1
  134. data/test/models/sqlserver/uppered.rb +1 -1
  135. data/test/models/sqlserver/uuid.rb +1 -1
  136. data/test/schema/sqlserver_specific_schema.rb +36 -21
  137. data/test/support/coerceable_test_sqlserver.rb +1 -4
  138. data/test/support/connection_reflection.rb +1 -2
  139. data/test/support/core_ext/query_cache.rb +1 -1
  140. data/test/support/load_schema_sqlserver.rb +3 -5
  141. data/test/support/marshal_compatibility_fixtures/SQLServer/rails_6_0_topic.dump +0 -0
  142. data/test/support/marshal_compatibility_fixtures/SQLServer/rails_6_0_topic_associations.dump +0 -0
  143. data/test/support/minitest_sqlserver.rb +1 -1
  144. data/test/support/paths_sqlserver.rb +9 -11
  145. data/test/support/rake_helpers.rb +12 -10
  146. data/test/support/sql_counter_sqlserver.rb +14 -16
  147. data/test/support/test_in_memory_oltp.rb +7 -7
  148. metadata +31 -11
  149. data/.travis.yml +0 -23
@@ -1,11 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'cases/helper_sqlserver'
4
- require 'models/person'
5
- require 'models/reader'
3
+ require "cases/helper_sqlserver"
4
+ require "models/person"
5
+ require "models/reader"
6
6
 
7
7
  class PessimisticLockingTestSQLServer < ActiveRecord::TestCase
8
-
9
8
  fixtures :people, :readers
10
9
 
11
10
  before do
@@ -13,15 +12,14 @@ class PessimisticLockingTestSQLServer < ActiveRecord::TestCase
13
12
  Reader.columns
14
13
  end
15
14
 
16
- it 'uses with updlock by default' do
15
+ it "uses with updlock by default" do
17
16
  assert_sql %r|SELECT \[people\]\.\* FROM \[people\] WITH\(UPDLOCK\)| do
18
17
  _(Person.lock(true).to_a).must_equal Person.all.to_a
19
18
  end
20
19
  end
21
20
 
22
- describe 'For simple finds with default lock option' do
23
-
24
- it 'lock with simple find' do
21
+ describe "For simple finds with default lock option" do
22
+ it "lock with simple find" do
25
23
  assert_nothing_raised do
26
24
  Person.transaction do
27
25
  _(Person.lock(true).find(1)).must_equal Person.find(1)
@@ -29,7 +27,7 @@ class PessimisticLockingTestSQLServer < ActiveRecord::TestCase
29
27
  end
30
28
  end
31
29
 
32
- it 'lock with scoped find' do
30
+ it "lock with scoped find" do
33
31
  assert_nothing_raised do
34
32
  Person.transaction do
35
33
  Person.lock(true).scoping do
@@ -39,8 +37,8 @@ class PessimisticLockingTestSQLServer < ActiveRecord::TestCase
39
37
  end
40
38
  end
41
39
 
42
- it 'lock with eager find' do
43
- assert_nothing_raised do
40
+ it "lock with eager find" do
41
+ assert_nothing_raised do
44
42
  Person.transaction do
45
43
  person = Person.lock(true).includes(:readers).find(1)
46
44
  _(person).must_equal Person.find(1)
@@ -48,62 +46,56 @@ class PessimisticLockingTestSQLServer < ActiveRecord::TestCase
48
46
  end
49
47
  end
50
48
 
51
- it 'can add a custom lock directive' do
49
+ it "can add a custom lock directive" do
52
50
  assert_sql %r|SELECT \[people\]\.\* FROM \[people\] WITH\(HOLDLOCK, ROWLOCK\)| do
53
- Person.lock('WITH(HOLDLOCK, ROWLOCK)').load
51
+ Person.lock("WITH(HOLDLOCK, ROWLOCK)").load
54
52
  end
55
53
  end
56
54
 
57
- describe 'joining tables' do
58
-
59
- it 'joined tables use updlock by default' do
55
+ describe "joining tables" do
56
+ it "joined tables use updlock by default" do
60
57
  assert_sql %r|SELECT \[people\]\.\* FROM \[people\] WITH\(UPDLOCK\) INNER JOIN \[readers\] WITH\(UPDLOCK\)\s+ON \[readers\]\.\[person_id\] = \[people\]\.\[id\]| do
61
58
  Person.lock(true).joins(:readers).load
62
59
  end
63
60
  end
64
61
 
65
- it 'joined tables can use custom lock directive' do
62
+ it "joined tables can use custom lock directive" do
66
63
  assert_sql %r|SELECT \[people\]\.\* FROM \[people\] WITH\(NOLOCK\) INNER JOIN \[readers\] WITH\(NOLOCK\)\s+ON \[readers\]\.\[person_id\] = \[people\]\.\[id\]| do
67
- Person.lock('WITH(NOLOCK)').joins(:readers).load
64
+ Person.lock("WITH(NOLOCK)").joins(:readers).load
68
65
  end
69
66
  end
70
67
 
71
- it 'left joined tables use updlock by default' do
68
+ it "left joined tables use updlock by default" do
72
69
  assert_sql %r|SELECT \[people\]\.\* FROM \[people\] WITH\(UPDLOCK\) LEFT OUTER JOIN \[readers\] WITH\(UPDLOCK\)\s+ON \[readers\]\.\[person_id\] = \[people\]\.\[id\]| do
73
70
  Person.lock(true).left_joins(:readers).load
74
71
  end
75
72
  end
76
73
 
77
- it 'left joined tables can use custom lock directive' do
74
+ it "left joined tables can use custom lock directive" do
78
75
  assert_sql %r|SELECT \[people\]\.\* FROM \[people\] WITH\(NOLOCK\) LEFT OUTER JOIN \[readers\] WITH\(NOLOCK\)\s+ON \[readers\]\.\[person_id\] = \[people\]\.\[id\]| do
79
- Person.lock('WITH(NOLOCK)').left_joins(:readers).load
76
+ Person.lock("WITH(NOLOCK)").left_joins(:readers).load
80
77
  end
81
78
  end
82
-
83
79
  end
84
-
85
80
  end
86
81
 
87
- describe 'For paginated finds' do
88
-
82
+ describe "For paginated finds" do
89
83
  before do
90
84
  Person.delete_all
91
85
  20.times { |n| Person.create!(first_name: "Thing_#{n}") }
92
86
  end
93
87
 
94
- it 'copes with eager loading un-locked paginated' do
88
+ it "copes with eager loading un-locked paginated" do
95
89
  eager_ids_sql = /SELECT\s+DISTINCT \[people\].\[id\] FROM \[people\] WITH\(UPDLOCK\) LEFT OUTER JOIN \[readers\] WITH\(UPDLOCK\)\s+ON \[readers\].\[person_id\] = \[people\].\[id\]\s+ORDER BY \[people\].\[id\] ASC OFFSET @0 ROWS FETCH NEXT @1 ROWS ONLY/
96
90
  loader_sql = /SELECT.*FROM \[people\] WITH\(UPDLOCK\).*WHERE \[people\]\.\[id\] IN/
97
91
  assert_sql(eager_ids_sql, loader_sql) do
98
92
  people = Person.lock(true).limit(5).offset(10).includes(:readers).references(:readers).to_a
99
- _(people[0].first_name).must_equal 'Thing_10'
100
- _(people[1].first_name).must_equal 'Thing_11'
101
- _(people[2].first_name).must_equal 'Thing_12'
102
- _(people[3].first_name).must_equal 'Thing_13'
103
- _(people[4].first_name).must_equal 'Thing_14'
93
+ _(people[0].first_name).must_equal "Thing_10"
94
+ _(people[1].first_name).must_equal "Thing_11"
95
+ _(people[2].first_name).must_equal "Thing_12"
96
+ _(people[3].first_name).must_equal "Thing_13"
97
+ _(people[4].first_name).must_equal "Thing_14"
104
98
  end
105
99
  end
106
-
107
100
  end
108
-
109
101
  end
@@ -0,0 +1,103 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cases/helper_sqlserver"
4
+ require "support/schema_dumping_helper"
5
+
6
+ class PrimaryKeyUuidTypeTest < ActiveRecord::TestCase
7
+ include SchemaDumpingHelper
8
+
9
+ self.use_transactional_tests = false
10
+
11
+ class Barcode < ActiveRecord::Base
12
+ end
13
+
14
+ setup do
15
+ @connection = ActiveRecord::Base.connection
16
+ @connection.create_table(:barcodes, primary_key: "code", id: :uuid, force: true)
17
+ end
18
+
19
+ teardown do
20
+ @connection.drop_table(:barcodes, if_exists: true)
21
+ end
22
+
23
+ def test_any_type_primary_key
24
+ assert_equal "code", Barcode.primary_key
25
+
26
+ column = Barcode.column_for_attribute(Barcode.primary_key)
27
+ assert_not column.null
28
+ assert_equal :uuid, column.type
29
+ assert_not_predicate column, :is_identity?
30
+ assert_predicate column, :is_primary?
31
+ ensure
32
+ Barcode.reset_column_information
33
+ end
34
+
35
+ test "schema dump primary key includes default" do
36
+ schema = dump_table_schema "barcodes"
37
+ assert_match %r/create_table "barcodes", primary_key: "code", id: :uuid, default: -> { "newid\(\)" }/, schema
38
+ end
39
+ end
40
+
41
+ class PrimaryKeyIntegerTest < ActiveRecord::TestCase
42
+ include SchemaDumpingHelper
43
+
44
+ self.use_transactional_tests = false
45
+
46
+ class Barcode < ActiveRecord::Base
47
+ end
48
+
49
+ class Widget < ActiveRecord::Base
50
+ end
51
+
52
+ setup do
53
+ @connection = ActiveRecord::Base.connection
54
+ end
55
+
56
+ teardown do
57
+ @connection.drop_table :barcodes, if_exists: true
58
+ @connection.drop_table :widgets, if_exists: true
59
+ end
60
+
61
+ test "integer primary key without default" do
62
+ @connection.create_table(:widgets, id: :integer, force: true)
63
+ column = @connection.columns(:widgets).find { |c| c.name == "id" }
64
+ assert_predicate column, :is_primary?
65
+ assert_predicate column, :is_identity?
66
+ assert_equal :integer, column.type
67
+ assert_not_predicate column, :bigint?
68
+
69
+ schema = dump_table_schema "widgets"
70
+ assert_match %r/create_table "widgets", id: :integer, force: :cascade do/, schema
71
+ end
72
+
73
+ test "bigint primary key without default" do
74
+ @connection.create_table(:widgets, id: :bigint, force: true)
75
+ column = @connection.columns(:widgets).find { |c| c.name == "id" }
76
+ assert_predicate column, :is_primary?
77
+ assert_predicate column, :is_identity?
78
+ assert_equal :integer, column.type
79
+ assert_predicate column, :bigint?
80
+
81
+ schema = dump_table_schema "widgets"
82
+ assert_match %r/create_table "widgets", force: :cascade do/, schema
83
+ end
84
+
85
+ test "don't set identity to integer and bigint when there is a default" do
86
+ @connection.create_table(:barcodes, id: :integer, default: nil, force: true)
87
+ @connection.create_table(:widgets, id: :bigint, default: nil, force: true)
88
+
89
+ column = @connection.columns(:widgets).find { |c| c.name == "id" }
90
+ assert_predicate column, :is_primary?
91
+ assert_not_predicate column, :is_identity?
92
+
93
+ schema = dump_table_schema "widgets"
94
+ assert_match %r/create_table "widgets", id: :bigint, default: nil, force: :cascade do/, schema
95
+
96
+ column = @connection.columns(:barcodes).find { |c| c.name == "id" }
97
+ assert_predicate column, :is_primary?
98
+ assert_not_predicate column, :is_identity?
99
+
100
+ schema = dump_table_schema "barcodes"
101
+ assert_match %r/create_table "barcodes", id: :integer, default: nil, force: :cascade do/, schema
102
+ end
103
+ end
@@ -1,20 +1,20 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'cases/helper_sqlserver'
3
+ require "cases/helper_sqlserver"
4
4
 
5
5
  class SQLServerRakeTest < ActiveRecord::TestCase
6
-
7
6
  self.use_transactional_tests = false
8
7
 
9
8
  cattr_accessor :azure_skip
10
9
  self.azure_skip = connection_sqlserver_azure?
11
10
 
12
11
  let(:db_tasks) { ActiveRecord::Tasks::DatabaseTasks }
13
- let(:new_database) { 'activerecord_unittest_tasks' }
14
- let(:default_configuration) { ARTest.connection_config['arunit'] }
15
- let(:configuration) { default_configuration.merge('database' => new_database) }
12
+ let(:new_database) { "activerecord_unittest_tasks" }
13
+ let(:default_configuration) { ARTest.test_configuration_hashes["arunit"] }
14
+ let(:configuration) { default_configuration.merge("database" => new_database) }
15
+ let(:db_config) { ActiveRecord::Base.configurations.resolve(configuration) }
16
16
 
17
- before { skip 'on azure' if azure_skip }
17
+ before { skip "on azure" if azure_skip }
18
18
  before { disconnect! unless azure_skip }
19
19
  after { reconnect unless azure_skip }
20
20
 
@@ -27,7 +27,7 @@ class SQLServerRakeTest < ActiveRecord::TestCase
27
27
  def reconnect
28
28
  config = default_configuration
29
29
  if connection_sqlserver_azure?
30
- ActiveRecord::Base.establish_connection(config.merge('database' => 'master'))
30
+ ActiveRecord::Base.establish_connection(config.merge("database" => "master"))
31
31
  connection.drop_database(new_database) rescue nil
32
32
  disconnect!
33
33
  ActiveRecord::Base.establish_connection(config)
@@ -36,57 +36,51 @@ class SQLServerRakeTest < ActiveRecord::TestCase
36
36
  connection.drop_database(new_database) rescue nil
37
37
  end
38
38
  end
39
-
40
39
  end
41
40
 
42
41
  class SQLServerRakeCreateTest < SQLServerRakeTest
43
-
44
42
  self.azure_skip = false
45
43
 
46
- it 'establishes connection to database after create ' do
44
+ it "establishes connection to database after create " do
47
45
  quietly { db_tasks.create configuration }
48
46
  _(connection.current_database).must_equal(new_database)
49
47
  end
50
48
 
51
- it 'creates database with default collation' do
49
+ it "creates database with default collation" do
52
50
  quietly { db_tasks.create configuration }
53
- _(connection.collation).must_equal 'SQL_Latin1_General_CP1_CI_AS'
51
+ _(connection.collation).must_equal "SQL_Latin1_General_CP1_CI_AS"
54
52
  end
55
53
 
56
- it 'creates database with given collation' do
57
- quietly { db_tasks.create configuration.merge('collation' => 'Latin1_General_CI_AS') }
58
- _(connection.collation).must_equal 'Latin1_General_CI_AS'
54
+ it "creates database with given collation" do
55
+ quietly { db_tasks.create configuration.merge("collation" => "Latin1_General_CI_AS") }
56
+ _(connection.collation).must_equal "Latin1_General_CI_AS"
59
57
  end
60
58
 
61
- it 'prints error message when database exists' do
59
+ it "prints error message when database exists" do
62
60
  quietly { db_tasks.create configuration }
63
61
  message = capture(:stderr) { db_tasks.create configuration }
64
62
  _(message).must_match %r{activerecord_unittest_tasks.*already exists}
65
63
  end
66
-
67
64
  end
68
65
 
69
66
  class SQLServerRakeDropTest < SQLServerRakeTest
70
-
71
67
  self.azure_skip = false
72
68
 
73
- it 'drops database and uses master' do
69
+ it "drops database and uses master" do
74
70
  quietly do
75
71
  db_tasks.create configuration
76
72
  db_tasks.drop configuration
77
73
  end
78
- _(connection.current_database).must_equal 'master'
74
+ _(connection.current_database).must_equal "master"
79
75
  end
80
76
 
81
- it 'prints error message when database does not exist' do
82
- message = capture(:stderr) { db_tasks.drop configuration.merge('database' => 'doesnotexist') }
77
+ it "prints error message when database does not exist" do
78
+ message = capture(:stderr) { db_tasks.drop configuration.merge("database" => "doesnotexist") }
83
79
  _(message).must_match %r{'doesnotexist' does not exist}
84
80
  end
85
-
86
81
  end
87
82
 
88
83
  class SQLServerRakePurgeTest < SQLServerRakeTest
89
-
90
84
  before do
91
85
  quietly { db_tasks.create(configuration) }
92
86
  connection.create_table :users, force: true do |t|
@@ -95,43 +89,37 @@ class SQLServerRakePurgeTest < SQLServerRakeTest
95
89
  end
96
90
  end
97
91
 
98
- it 'clears active connections, drops database, and recreates with established connection' do
92
+ it "clears active connections, drops database, and recreates with established connection" do
99
93
  _(connection.current_database).must_equal(new_database)
100
- _(connection.tables).must_include 'users'
94
+ _(connection.tables).must_include "users"
101
95
  quietly { db_tasks.purge(configuration) }
102
96
  _(connection.current_database).must_equal(new_database)
103
- _(connection.tables).wont_include 'users'
97
+ _(connection.tables).wont_include "users"
104
98
  end
105
-
106
99
  end
107
100
 
108
101
  class SQLServerRakeCharsetTest < SQLServerRakeTest
109
-
110
102
  before do
111
103
  quietly { db_tasks.create(configuration) }
112
104
  end
113
105
 
114
- it 'retrieves charset' do
115
- _(db_tasks.charset(configuration)).must_equal 'iso_1'
106
+ it "retrieves charset" do
107
+ _(db_tasks.charset(configuration)).must_equal "iso_1"
116
108
  end
117
-
118
109
  end
119
110
 
120
111
  class SQLServerRakeCollationTest < SQLServerRakeTest
121
-
122
112
  before do
123
113
  quietly { db_tasks.create(configuration) }
124
114
  end
125
115
 
126
- it 'retrieves collation' do
127
- _(db_tasks.collation(configuration)).must_equal 'SQL_Latin1_General_CP1_CI_AS'
116
+ it "retrieves collation" do
117
+ _(db_tasks.collation(configuration)).must_equal "SQL_Latin1_General_CP1_CI_AS"
128
118
  end
129
-
130
119
  end
131
120
 
132
121
  class SQLServerRakeStructureDumpLoadTest < SQLServerRakeTest
133
-
134
- let(:filename) { File.join ARTest::SQLServer.migrations_root, 'structure.sql' }
122
+ let(:filename) { File.join ARTest::SQLServer.migrations_root, "structure.sql" }
135
123
  let(:filedata) { File.read(filename) }
136
124
 
137
125
  before do
@@ -148,8 +136,8 @@ class SQLServerRakeStructureDumpLoadTest < SQLServerRakeTest
148
136
  FileUtils.rm_rf(filename)
149
137
  end
150
138
 
151
- it 'dumps structure and accounts for defncopy oddities' do
152
- skip 'debug defncopy on windows later' if host_windows?
139
+ it "dumps structure and accounts for defncopy oddities" do
140
+ skip "debug defncopy on windows later" if host_windows?
153
141
  quietly { db_tasks.structure_dump configuration, filename }
154
142
  _(filedata).wont_match %r{\AUSE.*\z}
155
143
  _(filedata).wont_match %r{\AGO.*\z}
@@ -158,14 +146,13 @@ class SQLServerRakeStructureDumpLoadTest < SQLServerRakeTest
158
146
  _(filedata).must_match %r{background2\s+text\s+}
159
147
  end
160
148
 
161
- it 'can load dumped structure' do
162
- skip 'debug defncopy on windows later' if host_windows?
149
+ it "can load dumped structure" do
150
+ skip "debug defncopy on windows later" if host_windows?
163
151
  quietly { db_tasks.structure_dump configuration, filename }
164
152
  _(filedata).must_match %r{CREATE TABLE dbo\.users}
165
153
  db_tasks.purge(configuration)
166
- _(connection.tables).wont_include 'users'
167
- db_tasks.load_schema configuration, :sql, filename
168
- _(connection.tables).must_include 'users'
154
+ _(connection.tables).wont_include "users"
155
+ db_tasks.load_schema db_config, :sql, filename
156
+ _(connection.tables).must_include "users"
169
157
  end
170
-
171
158
  end
@@ -1,146 +1,159 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'cases/helper_sqlserver'
3
+ require "cases/helper_sqlserver"
4
4
 
5
5
  class SchemaDumperTestSQLServer < ActiveRecord::TestCase
6
-
7
6
  before { all_tables }
8
7
 
9
8
  let(:all_tables) { ActiveRecord::Base.connection.tables }
10
9
  let(:schema) { @generated_schema }
11
10
 
12
- it 'sst_datatypes' do
13
- generate_schema_for_table 'sst_datatypes'
14
- assert_line :bigint, type: 'bigint', limit: nil, precision: nil, scale: nil, default: 42
15
- assert_line :int, type: 'integer', limit: nil, precision: nil, scale: nil, default: 42
16
- assert_line :smallint, type: 'integer', limit: 2, precision: nil, scale: nil, default: 42
17
- assert_line :tinyint, type: 'integer', limit: 1, precision: nil, scale: nil, default: 42
18
- assert_line :bit, type: 'boolean', limit: nil, precision: nil, scale: nil, default: true
19
- assert_line :decimal_9_2, type: 'decimal', limit: nil, precision: 9, scale: 2, default: 12345.01
20
- assert_line :numeric_18_0, type: 'decimal', limit: nil, precision: 18, scale: 0, default: 191.0
21
- assert_line :numeric_36_2, type: 'decimal', limit: nil, precision: 36, scale: 2, default: 12345678901234567890.01
22
- assert_line :money, type: 'money', limit: nil, precision: 19, scale: 4, default: 4.2
23
- assert_line :smallmoney, type: 'smallmoney', limit: nil, precision: 10, scale: 4, default: 4.2
11
+ it "sst_datatypes" do
12
+ generate_schema_for_table "sst_datatypes"
13
+ assert_line :bigint, type: "bigint", limit: nil, precision: nil, scale: nil, default: 42
14
+ assert_line :int, type: "integer", limit: nil, precision: nil, scale: nil, default: 42
15
+ assert_line :smallint, type: "integer", limit: 2, precision: nil, scale: nil, default: 42
16
+ assert_line :tinyint, type: "integer", limit: 1, precision: nil, scale: nil, default: 42
17
+ assert_line :bit, type: "boolean", limit: nil, precision: nil, scale: nil, default: true
18
+ assert_line :decimal_9_2, type: "decimal", limit: nil, precision: 9, scale: 2, default: 12345.01
19
+ assert_line :numeric_18_0, type: "decimal", limit: nil, precision: 18, scale: nil, default: 191
20
+ assert_line :numeric_36_2, type: "decimal", limit: nil, precision: 36, scale: 2, default: 12345678901234567890.01
21
+ assert_line :money, type: "money", limit: nil, precision: 19, scale: 4, default: 4.2
22
+ assert_line :smallmoney, type: "smallmoney", limit: nil, precision: 10, scale: 4, default: 4.2
24
23
  # Approximate Numerics
25
- assert_line :float, type: 'float', limit: nil, precision: nil, scale: nil, default: 123.00000001
26
- assert_line :real, type: 'real', limit: nil, precision: nil, scale: nil, default: 123.45
24
+ assert_line :float, type: "float", limit: nil, precision: nil, scale: nil, default: 123.00000001
25
+ assert_line :real, type: "real", limit: nil, precision: nil, scale: nil, default: 123.45
27
26
  # Date and Time
28
- assert_line :date, type: 'date', limit: nil, precision: nil, scale: nil, default: "01-01-0001"
29
- assert_line :datetime, type: 'datetime', limit: nil, precision: nil, scale: nil, default: "01-01-1753 00:00:00.123"
27
+ assert_line :date, type: "date", limit: nil, precision: nil, scale: nil, default: "01-01-0001"
28
+ assert_line :datetime, type: "datetime", limit: nil, precision: nil, scale: nil, default: "01-01-1753 00:00:00.123"
30
29
  if connection_dblib_73?
31
- assert_line :datetime2_7, type: 'datetime', limit: nil, precision: 7, scale: nil, default: "12-31-9999 23:59:59.9999999"
32
- assert_line :datetime2_3, type: 'datetime', limit: nil, precision: 3, scale: nil, default: nil
33
- assert_line :datetime2_1, type: 'datetime', limit: nil, precision: 1, scale: nil, default: nil
30
+ assert_line :datetime2_7, type: "datetime", limit: nil, precision: 7, scale: nil, default: "12-31-9999 23:59:59.9999999"
31
+ assert_line :datetime2_3, type: "datetime", limit: nil, precision: 3, scale: nil, default: nil
32
+ assert_line :datetime2_1, type: "datetime", limit: nil, precision: 1, scale: nil, default: nil
34
33
  end
35
- assert_line :smalldatetime, type: 'smalldatetime',limit: nil, precision: nil, scale: nil, default: "01-01-1901 15:45:00.0"
34
+ assert_line :smalldatetime, type: "smalldatetime", limit: nil, precision: nil, scale: nil, default: "01-01-1901 15:45:00.0"
36
35
  if connection_dblib_73?
37
- assert_line :time_7, type: 'time', limit: nil, precision: 7, scale: nil, default: "04:20:00.2883215"
38
- assert_line :time_2, type: 'time', limit: nil, precision: 2, scale: nil, default: nil
39
- assert_line :time_default, type: 'time', limit: nil, precision: 7, scale: nil, default: "15:03:42.0621978"
36
+ assert_line :time_7, type: "time", limit: nil, precision: 7, scale: nil, default: "04:20:00.2883215"
37
+ assert_line :time_2, type: "time", limit: nil, precision: 2, scale: nil, default: nil
38
+ assert_line :time_default, type: "time", limit: nil, precision: 7, scale: nil, default: "15:03:42.0621978"
40
39
  end
41
40
  # Character Strings
42
- assert_line :char_10, type: 'char', limit: 10, precision: nil, scale: nil, default: "1234567890", collation: nil
43
- assert_line :varchar_50, type: 'varchar', limit: 50, precision: nil, scale: nil, default: "test varchar_50", collation: nil
44
- assert_line :varchar_max, type: 'varchar_max', limit: nil, precision: nil, scale: nil, default: "test varchar_max", collation: nil
45
- assert_line :text, type: 'text_basic', limit: nil, precision: nil, scale: nil, default: "test text", collation: nil
41
+ assert_line :char_10, type: "char", limit: 10, precision: nil, scale: nil, default: "1234567890", collation: nil
42
+ assert_line :varchar_50, type: "varchar", limit: 50, precision: nil, scale: nil, default: "test varchar_50", collation: nil
43
+ assert_line :varchar_max, type: "varchar_max", limit: nil, precision: nil, scale: nil, default: "test varchar_max", collation: nil
44
+ assert_line :text, type: "text_basic", limit: nil, precision: nil, scale: nil, default: "test text", collation: nil
46
45
  # Unicode Character Strings
47
- assert_line :nchar_10, type: 'nchar', limit: 10, precision: nil, scale: nil, default: "12345678åå", collation: nil
48
- assert_line :nvarchar_50, type: 'string', limit: 50, precision: nil, scale: nil, default: "test nvarchar_50 åå", collation: nil
49
- assert_line :nvarchar_max, type: 'text', limit: nil, precision: nil, scale: nil, default: "test nvarchar_max åå", collation: nil
50
- assert_line :ntext, type: 'ntext', limit: nil, precision: nil, scale: nil, default: "test ntext åå", collation: nil
46
+ assert_line :nchar_10, type: "nchar", limit: 10, precision: nil, scale: nil, default: "12345678åå", collation: nil
47
+ assert_line :nvarchar_50, type: "string", limit: 50, precision: nil, scale: nil, default: "test nvarchar_50 åå", collation: nil
48
+ assert_line :nvarchar_max, type: "text", limit: nil, precision: nil, scale: nil, default: "test nvarchar_max åå", collation: nil
49
+ assert_line :ntext, type: "ntext", limit: nil, precision: nil, scale: nil, default: "test ntext åå", collation: nil
51
50
  # Binary Strings
52
- assert_line :binary_49, type: 'binary_basic', limit: 49, precision: nil, scale: nil, default: nil
53
- assert_line :varbinary_49, type: 'varbinary', limit: 49, precision: nil, scale: nil, default: nil
54
- assert_line :varbinary_max, type: 'binary', limit: nil, precision: nil, scale: nil, default: nil
51
+ assert_line :binary_49, type: "binary_basic", limit: 49, precision: nil, scale: nil, default: nil
52
+ assert_line :varbinary_49, type: "varbinary", limit: 49, precision: nil, scale: nil, default: nil
53
+ assert_line :varbinary_max, type: "binary", limit: nil, precision: nil, scale: nil, default: nil
55
54
  # Other Data Types
56
- assert_line :uniqueidentifier, type: 'uuid', limit: nil, precision: nil, scale: nil, default: -> { "newid()" }
57
- assert_line :timestamp, type: 'ss_timestamp', limit: nil, precision: nil, scale: nil, default: nil
55
+ assert_line :uniqueidentifier, type: "uuid", limit: nil, precision: nil, scale: nil, default: -> { "newid()" }
56
+ assert_line :timestamp, type: "ss_timestamp", limit: nil, precision: nil, scale: nil, default: nil
58
57
  end
59
58
 
60
- it 'sst_datatypes_migration' do
59
+ it "sst_datatypes_migration" do
61
60
  columns = SSTestDatatypeMigration.columns_hash
62
- generate_schema_for_table 'sst_datatypes_migration'
61
+ generate_schema_for_table "sst_datatypes_migration"
63
62
  # Simple Rails conventions
64
- _(columns['integer_col'].sql_type).must_equal 'int(4)'
65
- _(columns['bigint_col'].sql_type).must_equal 'bigint(8)'
66
- _(columns['boolean_col'].sql_type).must_equal 'bit'
67
- _(columns['decimal_col'].sql_type).must_equal 'decimal(18,0)'
68
- _(columns['float_col'].sql_type).must_equal 'float'
69
- _(columns['string_col'].sql_type).must_equal 'nvarchar(4000)'
70
- _(columns['text_col'].sql_type).must_equal 'nvarchar(max)'
71
- _(columns['datetime_col'].sql_type).must_equal 'datetime'
72
- _(columns['timestamp_col'].sql_type).must_equal 'datetime'
73
- _(columns['time_col'].sql_type).must_equal 'time(7)'
74
- _(columns['date_col'].sql_type).must_equal 'date'
75
- _(columns['binary_col'].sql_type).must_equal 'varbinary(max)'
76
- assert_line :integer_col, type: 'integer', limit: nil, precision: nil, scale: nil, default: nil
77
- assert_line :bigint_col, type: 'bigint', limit: nil, precision: nil, scale: nil, default: nil
78
- assert_line :boolean_col, type: 'boolean', limit: nil, precision: nil, scale: nil, default: nil
79
- assert_line :decimal_col, type: 'decimal', limit: nil, precision: 18, scale: 0, default: nil
80
- assert_line :float_col, type: 'float', limit: nil, precision: nil, scale: nil, default: nil
81
- assert_line :string_col, type: 'string', limit: nil, precision: nil, scale: nil, default: nil
82
- assert_line :text_col, type: 'text', limit: nil, precision: nil, scale: nil, default: nil
83
- assert_line :datetime_col, type: 'datetime', limit: nil, precision: nil, scale: nil, default: nil
84
- assert_line :timestamp_col, type: 'datetime', limit: nil, precision: nil, scale: nil, default: nil
85
- assert_line :time_col, type: 'time', limit: nil, precision: 7, scale: nil, default: nil
86
- assert_line :date_col, type: 'date', limit: nil, precision: nil, scale: nil, default: nil
87
- assert_line :binary_col, type: 'binary', limit: nil, precision: nil, scale: nil, default: nil
63
+ _(columns["integer_col"].sql_type).must_equal "int(4)"
64
+ _(columns["bigint_col"].sql_type).must_equal "bigint(8)"
65
+ _(columns["boolean_col"].sql_type).must_equal "bit"
66
+ _(columns["decimal_col"].sql_type).must_equal "decimal(18,0)"
67
+ _(columns["float_col"].sql_type).must_equal "float"
68
+ _(columns["string_col"].sql_type).must_equal "nvarchar(4000)"
69
+ _(columns["text_col"].sql_type).must_equal "nvarchar(max)"
70
+ _(columns["datetime_col"].sql_type).must_equal "datetime"
71
+ _(columns["timestamp_col"].sql_type).must_equal "datetime"
72
+ _(columns["time_col"].sql_type).must_equal "time(7)"
73
+ _(columns["date_col"].sql_type).must_equal "date"
74
+ _(columns["binary_col"].sql_type).must_equal "varbinary(max)"
75
+ assert_line :integer_col, type: "integer", limit: nil, precision: nil, scale: nil, default: nil
76
+ assert_line :bigint_col, type: "bigint", limit: nil, precision: nil, scale: nil, default: nil
77
+ assert_line :boolean_col, type: "boolean", limit: nil, precision: nil, scale: nil, default: nil
78
+ assert_line :decimal_col, type: "decimal", limit: nil, precision: 18, scale: nil, default: nil
79
+ assert_line :float_col, type: "float", limit: nil, precision: nil, scale: nil, default: nil
80
+ assert_line :string_col, type: "string", limit: nil, precision: nil, scale: nil, default: nil
81
+ assert_line :text_col, type: "text", limit: nil, precision: nil, scale: nil, default: nil
82
+ assert_line :datetime_col, type: "datetime", limit: nil, precision: nil, scale: nil, default: nil
83
+ assert_line :timestamp_col, type: "datetime", limit: nil, precision: nil, scale: nil, default: nil
84
+ assert_line :time_col, type: "time", limit: nil, precision: 7, scale: nil, default: nil
85
+ assert_line :date_col, type: "date", limit: nil, precision: nil, scale: nil, default: nil
86
+ assert_line :binary_col, type: "binary", limit: nil, precision: nil, scale: nil, default: nil
88
87
  # Our type methods.
89
- _(columns['real_col'].sql_type).must_equal 'real'
90
- _(columns['money_col'].sql_type).must_equal 'money'
91
- _(columns['smalldatetime_col'].sql_type).must_equal 'smalldatetime'
92
- _(columns['datetime2_col'].sql_type).must_equal 'datetime2(7)'
93
- _(columns['datetimeoffset'].sql_type).must_equal 'datetimeoffset(7)'
94
- _(columns['smallmoney_col'].sql_type).must_equal 'smallmoney'
95
- _(columns['char_col'].sql_type).must_equal 'char(1)'
96
- _(columns['varchar_col'].sql_type).must_equal 'varchar(8000)'
97
- _(columns['text_basic_col'].sql_type).must_equal 'text'
98
- _(columns['nchar_col'].sql_type).must_equal 'nchar(1)'
99
- _(columns['ntext_col'].sql_type).must_equal 'ntext'
100
- _(columns['binary_basic_col'].sql_type).must_equal 'binary(1)'
101
- _(columns['varbinary_col'].sql_type).must_equal 'varbinary(8000)'
102
- _(columns['uuid_col'].sql_type).must_equal 'uniqueidentifier'
103
- _(columns['sstimestamp_col'].sql_type).must_equal 'timestamp'
104
- _(columns['json_col'].sql_type).must_equal 'nvarchar(max)'
105
- assert_line :real_col, type: 'real', limit: nil, precision: nil, scale: nil, default: nil
106
- assert_line :money_col, type: 'money', limit: nil, precision: 19, scale: 4, default: nil
107
- assert_line :smalldatetime_col, type: 'smalldatetime', limit: nil, precision: nil, scale: nil, default: nil
108
- assert_line :datetime2_col, type: 'datetime', limit: nil, precision: 7, scale: nil, default: nil
109
- assert_line :datetimeoffset, type: 'datetimeoffset', limit: nil, precision: 7, scale: nil, default: nil
110
- assert_line :smallmoney_col, type: 'smallmoney', limit: nil, precision: 10, scale: 4, default: nil
111
- assert_line :char_col, type: 'char', limit: 1, precision: nil, scale: nil, default: nil
112
- assert_line :varchar_col, type: 'varchar', limit: nil, precision: nil, scale: nil, default: nil
113
- assert_line :text_basic_col, type: 'text_basic', limit: nil, precision: nil, scale: nil, default: nil
114
- assert_line :nchar_col, type: 'nchar', limit: 1, precision: nil, scale: nil, default: nil
115
- assert_line :ntext_col, type: 'ntext', limit: nil, precision: nil, scale: nil, default: nil
116
- assert_line :binary_basic_col, type: 'binary_basic', limit: 1, precision: nil, scale: nil, default: nil
117
- assert_line :varbinary_col, type: 'varbinary', limit: nil, precision: nil, scale: nil, default: nil
118
- assert_line :uuid_col, type: 'uuid', limit: nil, precision: nil, scale: nil, default: nil
119
- assert_line :sstimestamp_col, type: 'ss_timestamp', limit: nil, precision: nil, scale: nil, default: nil
120
- assert_line :json_col, type: 'text', limit: nil, precision: nil, scale: nil, default: nil
88
+ _(columns["real_col"].sql_type).must_equal "real"
89
+ _(columns["money_col"].sql_type).must_equal "money"
90
+ _(columns["smalldatetime_col"].sql_type).must_equal "smalldatetime"
91
+ _(columns["datetime2_col"].sql_type).must_equal "datetime2(7)"
92
+ _(columns["datetimeoffset"].sql_type).must_equal "datetimeoffset(7)"
93
+ _(columns["smallmoney_col"].sql_type).must_equal "smallmoney"
94
+ _(columns["char_col"].sql_type).must_equal "char(1)"
95
+ _(columns["varchar_col"].sql_type).must_equal "varchar(8000)"
96
+ _(columns["text_basic_col"].sql_type).must_equal "text"
97
+ _(columns["nchar_col"].sql_type).must_equal "nchar(1)"
98
+ _(columns["ntext_col"].sql_type).must_equal "ntext"
99
+ _(columns["binary_basic_col"].sql_type).must_equal "binary(1)"
100
+ _(columns["varbinary_col"].sql_type).must_equal "varbinary(8000)"
101
+ _(columns["uuid_col"].sql_type).must_equal "uniqueidentifier"
102
+ _(columns["sstimestamp_col"].sql_type).must_equal "timestamp"
103
+ _(columns["json_col"].sql_type).must_equal "nvarchar(max)"
104
+ assert_line :real_col, type: "real", limit: nil, precision: nil, scale: nil, default: nil
105
+ assert_line :money_col, type: "money", limit: nil, precision: 19, scale: 4, default: nil
106
+ assert_line :smalldatetime_col, type: "smalldatetime", limit: nil, precision: nil, scale: nil, default: nil
107
+ assert_line :datetime2_col, type: "datetime", limit: nil, precision: 7, scale: nil, default: nil
108
+ assert_line :datetimeoffset, type: "datetimeoffset", limit: nil, precision: 7, scale: nil, default: nil
109
+ assert_line :smallmoney_col, type: "smallmoney", limit: nil, precision: 10, scale: 4, default: nil
110
+ assert_line :char_col, type: "char", limit: 1, precision: nil, scale: nil, default: nil
111
+ assert_line :varchar_col, type: "varchar", limit: nil, precision: nil, scale: nil, default: nil
112
+ assert_line :text_basic_col, type: "text_basic", limit: nil, precision: nil, scale: nil, default: nil
113
+ assert_line :nchar_col, type: "nchar", limit: 1, precision: nil, scale: nil, default: nil
114
+ assert_line :ntext_col, type: "ntext", limit: nil, precision: nil, scale: nil, default: nil
115
+ assert_line :binary_basic_col, type: "binary_basic", limit: 1, precision: nil, scale: nil, default: nil
116
+ assert_line :varbinary_col, type: "varbinary", limit: nil, precision: nil, scale: nil, default: nil
117
+ assert_line :uuid_col, type: "uuid", limit: nil, precision: nil, scale: nil, default: nil
118
+ assert_line :sstimestamp_col, type: "ss_timestamp", limit: nil, precision: nil, scale: nil, default: nil
119
+ assert_line :json_col, type: "text", limit: nil, precision: nil, scale: nil, default: nil
120
+ end
121
+
122
+ it "dump column collation" do
123
+ generate_schema_for_table('sst_string_collation')
124
+
125
+ assert_line :string_without_collation, type: "string", limit: nil, default: nil, collation: nil
126
+ assert_line :string_default_collation, type: "varchar", limit: nil, default: nil, collation: nil
127
+ assert_line :string_with_collation, type: "varchar", limit: nil, default: nil, collation: "SQL_Latin1_General_CP1_CS_AS"
128
+ assert_line :varchar_with_collation, type: "varchar", limit: nil, default: nil, collation: "SQL_Latin1_General_CP1_CS_AS"
121
129
  end
122
130
 
123
131
  # Special Cases
124
132
 
125
- it 'honor nonstandard primary keys' do
126
- generate_schema_for_table('movies') do |output|
133
+ it "honor nonstandard primary keys" do
134
+ generate_schema_for_table("movies") do |output|
127
135
  match = output.match(%r{create_table "movies"(.*)do})
128
136
  assert_not_nil(match, "nonstandardpk table not found")
129
137
  assert_match %r(primary_key: "movieid"), match[1], "non-standard primary key not preserved"
130
138
  end
131
139
  end
132
140
 
133
- it 'no id with model driven primary key' do
134
- output = generate_schema_for_table 'sst_no_pk_data'
141
+ it "no id with model driven primary key" do
142
+ output = generate_schema_for_table "sst_no_pk_data"
135
143
  _(output).must_match %r{create_table "sst_no_pk_data".*id:\sfalse.*do}
136
- assert_line :name, type: 'string', limit: nil, default: nil, collation: nil
144
+ assert_line :name, type: "string", limit: nil, default: nil, collation: nil
137
145
  end
138
146
 
147
+ it "dumps field with unique key constraints only once" do
148
+ output = generate_schema_for_table "unique_key_dumped_table"
149
+
150
+ _(output.scan('t.integer "unique_field"').length).must_equal(1)
151
+ end
139
152
 
140
153
  private
141
154
 
142
155
  def generate_schema_for_table(*table_names)
143
- require 'stringio'
156
+ require "stringio"
144
157
  stream = StringIO.new
145
158
  ActiveRecord::SchemaDumper.ignore_tables = all_tables - table_names
146
159
  ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream)
@@ -150,6 +163,7 @@ class SchemaDumperTestSQLServer < ActiveRecord::TestCase
150
163
  type_matcher = /\A\s+t\.\w+\s+"(.*?)"[,\n]/
151
164
  @generated_schema.each_line do |line|
152
165
  next unless line =~ type_matcher
166
+
153
167
  @schema_lines[Regexp.last_match[1]] = SchemaLine.new(line)
154
168
  end
155
169
  @generated_schema
@@ -159,14 +173,17 @@ class SchemaDumperTestSQLServer < ActiveRecord::TestCase
159
173
  @schema_lines[column_name.to_s]
160
174
  end
161
175
 
162
- def assert_line(column_name, options={})
176
+ def assert_line(column_name, options = {})
163
177
  line = line(column_name)
164
- assert line, "Count not find line with column name: #{column_name.inspect} in schema:\n#{schema}"
178
+ assert line, "Could not find line with column name: #{column_name.inspect} in schema:\n#{schema}"
179
+
165
180
  [:type, :limit, :precision, :scale, :collation, :default].each do |key|
166
181
  next unless options.key?(key)
182
+
167
183
  actual = key == :type ? line.send(:type_method) : line.send(key)
168
184
  expected = options[key]
169
185
  message = "#{key.to_s.titleize} of #{expected.inspect} not found in:\n#{line}"
186
+
170
187
  if expected.nil?
171
188
  _(actual).must_be_nil message
172
189
  elsif expected.is_a?(Array)
@@ -182,7 +199,6 @@ class SchemaDumperTestSQLServer < ActiveRecord::TestCase
182
199
  end
183
200
 
184
201
  class SchemaLine
185
-
186
202
  LINE_PARSER = %r{t\.(\w+)\s+"(.*?)"[,\s+](.*)}
187
203
 
188
204
  attr_reader :line,
@@ -230,8 +246,5 @@ class SchemaDumperTestSQLServer < ActiveRecord::TestCase
230
246
  rescue SyntaxError
231
247
  {}
232
248
  end
233
-
234
249
  end
235
-
236
250
  end
237
-