activerecord-sqlserver-adapter 8.0.10 → 8.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/.devcontainer/Dockerfile +1 -1
  3. data/.github/workflows/ci.yml +34 -3
  4. data/CHANGELOG.md +14 -68
  5. data/Dockerfile.ci +1 -1
  6. data/Gemfile +7 -9
  7. data/Guardfile +2 -2
  8. data/README.md +33 -13
  9. data/Rakefile +1 -1
  10. data/VERSION +1 -1
  11. data/activerecord-sqlserver-adapter.gemspec +15 -16
  12. data/compose.ci.yaml +8 -1
  13. data/lib/active_record/connection_adapters/sqlserver/core_ext/attribute_methods.rb +1 -1
  14. data/lib/active_record/connection_adapters/sqlserver/core_ext/explain.rb +1 -2
  15. data/lib/active_record/connection_adapters/sqlserver/core_ext/explain_subscriber.rb +1 -1
  16. data/lib/active_record/connection_adapters/sqlserver/core_ext/finder_methods.rb +4 -4
  17. data/lib/active_record/connection_adapters/sqlserver/database_statements.rb +118 -83
  18. data/lib/active_record/connection_adapters/sqlserver/database_tasks.rb +3 -4
  19. data/lib/active_record/connection_adapters/sqlserver/quoting.rb +7 -7
  20. data/lib/active_record/connection_adapters/sqlserver/schema_creation.rb +24 -12
  21. data/lib/active_record/connection_adapters/sqlserver/schema_dumper.rb +17 -8
  22. data/lib/active_record/connection_adapters/sqlserver/schema_statements.rb +162 -156
  23. data/lib/active_record/connection_adapters/sqlserver/showplan/printer_table.rb +2 -2
  24. data/lib/active_record/connection_adapters/sqlserver/showplan.rb +5 -5
  25. data/lib/active_record/connection_adapters/sqlserver/sql_type_metadata.rb +2 -7
  26. data/lib/active_record/connection_adapters/sqlserver/table_definition.rb +3 -1
  27. data/lib/active_record/connection_adapters/sqlserver/type/data.rb +3 -3
  28. data/lib/active_record/connection_adapters/sqlserver/type/date.rb +3 -3
  29. data/lib/active_record/connection_adapters/sqlserver/type/datetime.rb +3 -4
  30. data/lib/active_record/connection_adapters/sqlserver/type/smalldatetime.rb +1 -1
  31. data/lib/active_record/connection_adapters/sqlserver/type/time.rb +4 -6
  32. data/lib/active_record/connection_adapters/sqlserver/type/time_value_fractional.rb +1 -1
  33. data/lib/active_record/connection_adapters/sqlserver/type/uuid.rb +0 -2
  34. data/lib/active_record/connection_adapters/sqlserver/utils.rb +10 -12
  35. data/lib/active_record/connection_adapters/sqlserver_adapter.rb +118 -66
  36. data/lib/active_record/connection_adapters/sqlserver_column.rb +17 -9
  37. data/lib/active_record/tasks/sqlserver_database_tasks.rb +5 -5
  38. data/lib/arel/visitors/sqlserver.rb +55 -26
  39. data/test/cases/active_schema_test_sqlserver.rb +45 -23
  40. data/test/cases/adapter_test_sqlserver.rb +72 -59
  41. data/test/cases/coerced_tests.rb +365 -161
  42. data/test/cases/column_test_sqlserver.rb +328 -316
  43. data/test/cases/connection_test_sqlserver.rb +15 -11
  44. data/test/cases/enum_test_sqlserver.rb +8 -9
  45. data/test/cases/execute_procedure_test_sqlserver.rb +1 -1
  46. data/test/cases/fetch_test_sqlserver.rb +1 -1
  47. data/test/cases/helper_sqlserver.rb +7 -3
  48. data/test/cases/index_test_sqlserver.rb +8 -6
  49. data/test/cases/insert_all_test_sqlserver.rb +3 -28
  50. data/test/cases/json_test_sqlserver.rb +8 -8
  51. data/test/cases/lateral_test_sqlserver.rb +2 -2
  52. data/test/cases/migration_test_sqlserver.rb +12 -12
  53. data/test/cases/pessimistic_locking_test_sqlserver.rb +6 -6
  54. data/test/cases/primary_keys_test_sqlserver.rb +4 -4
  55. data/test/cases/rake_test_sqlserver.rb +15 -7
  56. data/test/cases/schema_dumper_test_sqlserver.rb +109 -113
  57. data/test/cases/schema_test_sqlserver.rb +7 -7
  58. data/test/cases/transaction_test_sqlserver.rb +6 -8
  59. data/test/cases/trigger_test_sqlserver.rb +1 -1
  60. data/test/cases/utils_test_sqlserver.rb +3 -3
  61. data/test/cases/view_test_sqlserver.rb +12 -8
  62. data/test/cases/virtual_column_test_sqlserver.rb +113 -0
  63. data/test/migrations/create_clients_and_change_column_collation.rb +2 -2
  64. data/test/models/sqlserver/edge_schema.rb +2 -2
  65. data/test/schema/sqlserver_specific_schema.rb +49 -37
  66. data/test/support/coerceable_test_sqlserver.rb +10 -10
  67. data/test/support/connection_reflection.rb +0 -5
  68. data/test/support/core_ext/backtrace_cleaner.rb +36 -0
  69. data/test/support/query_assertions.rb +6 -6
  70. data/test/support/rake_helpers.rb +6 -10
  71. metadata +12 -107
@@ -16,7 +16,9 @@ module Arel
16
16
  BIND_BLOCK = proc { |i| "@#{i - 1}" }
17
17
  private_constant :BIND_BLOCK
18
18
 
19
- def bind_block; BIND_BLOCK; end
19
+ def bind_block
20
+ BIND_BLOCK
21
+ end
20
22
 
21
23
  def visit_Arel_Nodes_Bin(o, collector)
22
24
  visit o.expr, collector
@@ -29,10 +31,49 @@ module Arel
29
31
  visit o.right, collector
30
32
  end
31
33
 
34
+ # Same as SQLite and PostgreSQL.
32
35
  def visit_Arel_Nodes_UpdateStatement(o, collector)
33
- if has_join_and_composite_primary_key?(o)
34
- update_statement_using_join(o, collector)
36
+ collector.retryable = false
37
+ o = prepare_update_statement(o)
38
+
39
+ collector << "UPDATE "
40
+
41
+ # UPDATE with JOIN is in the form of:
42
+ #
43
+ # UPDATE t1
44
+ # SET ..
45
+ # FROM t1 JOIN t2 ON t2.join_id = t1.join_id ..
46
+ # WHERE ..
47
+ if has_join_sources?(o)
48
+ collector = visit o.relation.left, collector
49
+ collect_nodes_for o.values, collector, " SET "
50
+ collector << " FROM "
51
+ collector = inject_join o.relation.right, collector, " "
52
+ else
53
+ collector = visit o.relation, collector
54
+ collect_nodes_for o.values, collector, " SET "
55
+ end
56
+
57
+ collect_nodes_for o.wheres, collector, " WHERE ", " AND "
58
+ collect_nodes_for o.orders, collector, " ORDER BY "
59
+ maybe_visit o.limit, collector
60
+ maybe_visit o.comment, collector
61
+ end
62
+
63
+ # Similar to PostgreSQL and SQLite.
64
+ def prepare_update_statement(o)
65
+ if o.key && has_join_sources?(o) && !has_group_by_and_having?(o) && !has_limit_or_offset_or_orders?(o)
66
+ # Join clauses cannot reference the target table, so alias the
67
+ # updated table, place the entire relation in the FROM clause, and
68
+ # add a self-join (which requires the primary key)
69
+ stmt = o.clone
70
+
71
+ stmt.relation, stmt.wheres = o.relation.clone, o.wheres.clone
72
+ stmt.relation.right = [stmt.relation.left, *stmt.relation.right]
73
+ # Don't need to use alias
74
+ stmt
35
75
  else
76
+ # If using subquery, we need to add limit
36
77
  o.limit = Nodes::Limit.new(9_223_372_036_854_775_807) if o.orders.any? && o.limit.nil?
37
78
 
38
79
  super
@@ -61,19 +102,8 @@ module Arel
61
102
  collect_nodes_for o.wheres, collector, " WHERE ", " AND "
62
103
  end
63
104
 
64
- def update_statement_using_join(o, collector)
65
- collector.retryable = false
66
-
67
- collector << "UPDATE "
68
- visit o.relation.left, collector
69
- collect_nodes_for o.values, collector, " SET "
70
- collector << " FROM "
71
- visit o.relation, collector
72
- collect_nodes_for o.wheres, collector, " WHERE ", " AND "
73
- end
74
-
75
105
  def visit_Arel_Nodes_Lock(o, collector)
76
- o.expr = Arel.sql("WITH(UPDLOCK)") if o.expr.to_s =~ /FOR UPDATE/
106
+ o.expr = Arel.sql("WITH(UPDLOCK)") if /FOR UPDATE/.match?(o.expr.to_s)
77
107
  collector << " "
78
108
  visit o.expr, collector
79
109
  end
@@ -87,12 +117,11 @@ module Arel
87
117
  def visit_Arel_Nodes_Limit(o, collector)
88
118
  if node_value(o) == 0
89
119
  collector << FETCH0
90
- collector << ROWS_ONLY
91
120
  else
92
121
  collector << FETCH
93
122
  visit o.expr, collector
94
- collector << ROWS_ONLY
95
123
  end
124
+ collector << ROWS_ONLY
96
125
  end
97
126
 
98
127
  def visit_Arel_Nodes_Grouping(o, collector)
@@ -105,10 +134,10 @@ module Arel
105
134
 
106
135
  visit o.left, collector
107
136
 
108
- if o.type == :in
109
- collector << " IN ("
137
+ collector << if o.type == :in
138
+ " IN ("
110
139
  else
111
- collector << " NOT IN ("
140
+ " NOT IN ("
112
141
  end
113
142
 
114
143
  values = o.casted_values
@@ -170,14 +199,14 @@ module Arel
170
199
  quote_table_name(o.name)
171
200
  end
172
201
  end
173
- rescue Exception
202
+ rescue
174
203
  quote_table_name(o.name)
175
204
  end
176
205
 
177
- if o.table_alias
178
- collector << "#{table_name} #{quote_table_name o.table_alias}"
206
+ collector << if o.table_alias
207
+ "#{table_name} #{quote_table_name o.table_alias}"
179
208
  else
180
- collector << table_name
209
+ table_name
181
210
  end
182
211
  end
183
212
 
@@ -297,7 +326,7 @@ module Arel
297
326
  end
298
327
 
299
328
  def select_statement_lock?
300
- @select_statement && @select_statement.lock
329
+ @select_statement&.lock
301
330
  end
302
331
 
303
332
  def make_Fetch_Possible_And_Deterministic(o)
@@ -330,7 +359,7 @@ module Arel
330
359
  elsif Arel::Nodes::SqlLiteral === core.from
331
360
  Arel::Table.new(core.from)
332
361
  elsif Arel::Nodes::JoinSource === core.source
333
- Arel::Nodes::SqlLiteral === core.source.left ? Arel::Table.new(core.source.left, @engine) : core.source.left.left
362
+ (Arel::Nodes::SqlLiteral === core.source.left) ? Arel::Table.new(core.source.left, @engine) : core.source.left.left
334
363
  end
335
364
  end
336
365
 
@@ -12,48 +12,50 @@ class ActiveSchemaTestSQLServer < ActiveRecord::TestCase
12
12
  end
13
13
 
14
14
  after do
15
- connection.drop_table :schema_test_table rescue nil
15
+ connection.drop_table :schema_test_table
16
+ rescue
17
+ nil
16
18
  end
17
19
 
18
- it 'default index' do
19
- assert_queries_match('CREATE INDEX [index_schema_test_table_on_foo] ON [schema_test_table] ([foo])') do
20
+ it "default index" do
21
+ assert_queries_match("CREATE INDEX [index_schema_test_table_on_foo] ON [schema_test_table] ([foo])") do
20
22
  connection.add_index :schema_test_table, "foo"
21
23
  end
22
24
  end
23
25
 
24
- it 'unique index' do
25
- assert_queries_match('CREATE UNIQUE INDEX [index_schema_test_table_on_foo] ON [schema_test_table] ([foo])') do
26
+ it "unique index" do
27
+ assert_queries_match("CREATE UNIQUE INDEX [index_schema_test_table_on_foo] ON [schema_test_table] ([foo])") do
26
28
  connection.add_index :schema_test_table, "foo", unique: true
27
29
  end
28
30
  end
29
31
 
30
- it 'where condition on index' do
32
+ it "where condition on index" do
31
33
  assert_queries_match("CREATE INDEX [index_schema_test_table_on_foo] ON [schema_test_table] ([foo]) WHERE state = 'active'") do
32
34
  connection.add_index :schema_test_table, "foo", where: "state = 'active'"
33
35
  end
34
36
  end
35
37
 
36
- it 'if index does not exist' do
38
+ it "if index does not exist" do
37
39
  assert_queries_match("IF NOT EXISTS (SELECT name FROM sysindexes WHERE name = 'index_schema_test_table_on_foo') " \
38
40
  "CREATE INDEX [index_schema_test_table_on_foo] ON [schema_test_table] ([foo])") do
39
41
  connection.add_index :schema_test_table, "foo", if_not_exists: true
40
42
  end
41
43
  end
42
44
 
43
- it 'clustered index' do
44
- assert_queries_match('CREATE CLUSTERED INDEX [index_schema_test_table_on_foo] ON [schema_test_table] ([foo])') do
45
+ it "clustered index" do
46
+ assert_queries_match("CREATE CLUSTERED INDEX [index_schema_test_table_on_foo] ON [schema_test_table] ([foo])") do
45
47
  connection.add_index :schema_test_table, "foo", type: :clustered
46
48
  end
47
49
  end
48
50
 
49
- it 'nonclustered index' do
50
- assert_queries_match('CREATE NONCLUSTERED INDEX [index_schema_test_table_on_foo] ON [schema_test_table] ([foo])') do
51
+ it "nonclustered index" do
52
+ assert_queries_match("CREATE NONCLUSTERED INDEX [index_schema_test_table_on_foo] ON [schema_test_table] ([foo])") do
51
53
  connection.add_index :schema_test_table, "foo", type: :nonclustered
52
54
  end
53
55
  end
54
56
  end
55
57
 
56
- describe 'collation' do
58
+ describe "collation" do
57
59
  it "create column with NOT NULL and COLLATE" do
58
60
  assert_nothing_raised do
59
61
  connection.create_table :not_null_with_collation_table, force: true, id: false do |t|
@@ -61,12 +63,16 @@ class ActiveSchemaTestSQLServer < ActiveRecord::TestCase
61
63
  end
62
64
  end
63
65
  ensure
64
- connection.drop_table :not_null_with_collation_table rescue nil
66
+ begin
67
+ connection.drop_table :not_null_with_collation_table
68
+ rescue
69
+ nil
70
+ end
65
71
  end
66
72
  end
67
73
 
68
- describe 'datetimeoffset precision' do
69
- it 'valid precisions are correct' do
74
+ describe "datetimeoffset precision" do
75
+ it "valid precisions are correct" do
70
76
  assert_nothing_raised do
71
77
  connection.create_table :datetimeoffset_precisions do |t|
72
78
  t.datetimeoffset :precision_default
@@ -81,22 +87,30 @@ class ActiveSchemaTestSQLServer < ActiveRecord::TestCase
81
87
  assert_equal columns.find { |column| column.name == "precision_5" }.precision, 5
82
88
  assert_equal columns.find { |column| column.name == "precision_7" }.precision, 7
83
89
  ensure
84
- connection.drop_table :datetimeoffset_precisions rescue nil
90
+ begin
91
+ connection.drop_table :datetimeoffset_precisions
92
+ rescue
93
+ nil
94
+ end
85
95
  end
86
96
 
87
- it 'invalid precision raises exception' do
97
+ it "invalid precision raises exception" do
88
98
  assert_raise(ActiveRecord::ActiveRecordError) do
89
99
  connection.create_table :datetimeoffset_precisions do |t|
90
100
  t.datetimeoffset :precision_8, precision: 8
91
101
  end
92
102
  end
93
103
  ensure
94
- connection.drop_table :datetimeoffset_precisions rescue nil
104
+ begin
105
+ connection.drop_table :datetimeoffset_precisions
106
+ rescue
107
+ nil
108
+ end
95
109
  end
96
110
  end
97
111
 
98
- describe 'time precision' do
99
- it 'valid precisions are correct' do
112
+ describe "time precision" do
113
+ it "valid precisions are correct" do
100
114
  assert_nothing_raised do
101
115
  connection.create_table :time_precisions do |t|
102
116
  t.time :precision_default
@@ -111,17 +125,25 @@ class ActiveSchemaTestSQLServer < ActiveRecord::TestCase
111
125
  assert_equal columns.find { |column| column.name == "precision_5" }.precision, 5
112
126
  assert_equal columns.find { |column| column.name == "precision_7" }.precision, 7
113
127
  ensure
114
- connection.drop_table :time_precisions rescue nil
128
+ begin
129
+ connection.drop_table :time_precisions
130
+ rescue
131
+ nil
132
+ end
115
133
  end
116
134
 
117
- it 'invalid precision raises exception' do
135
+ it "invalid precision raises exception" do
118
136
  assert_raise(ActiveRecord::ActiveRecordError) do
119
137
  connection.create_table :time_precisions do |t|
120
138
  t.time :precision_8, precision: 8
121
139
  end
122
140
  end
123
141
  ensure
124
- connection.drop_table :time_precisions rescue nil
142
+ begin
143
+ connection.drop_table :time_precisions
144
+ rescue
145
+ nil
146
+ end
125
147
  end
126
148
  end
127
149
  end
@@ -14,10 +14,10 @@ require "models/discount"
14
14
  class AdapterTestSQLServer < ActiveRecord::TestCase
15
15
  fixtures :tasks
16
16
 
17
- let(:arunit_connection) { Topic.lease_connection }
17
+ let(:arunit_connection) { Topic.lease_connection }
18
18
  let(:arunit2_connection) { College.lease_connection }
19
- let(:arunit_database) { arunit_connection.pool.db_config.database }
20
- let(:arunit2_database) { arunit2_connection.pool.db_config.database }
19
+ let(:arunit_database) { arunit_connection.pool.db_config.database }
20
+ let(:arunit2_database) { arunit2_connection.pool.db_config.database }
21
21
 
22
22
  let(:basic_insert_sql) { "INSERT INTO [funny_jokes] ([name]) VALUES('Knock knock')" }
23
23
  let(:basic_merge_sql) { "MERGE INTO [ships] WITH (UPDLOCK, HOLDLOCK) AS target USING ( SELECT * FROM ( SELECT [id], [name], ROW_NUMBER() OVER ( PARTITION BY [id] ORDER BY [id] DESC ) AS rn_0 FROM ( VALUES (101, N'RSS Sir David Attenborough') ) AS t1 ([id], [name]) ) AS ranked_source WHERE rn_0 = 1 ) AS source ON (target.[id] = source.[id]) WHEN MATCHED THEN UPDATE SET target.[name] = source.[name]" }
@@ -50,20 +50,18 @@ class AdapterTestSQLServer < ActiveRecord::TestCase
50
50
  end
51
51
 
52
52
  it "table exists works if table name prefixed by schema and owner" do
53
- begin
54
- assert_equal "topics", Topic.table_name
55
- assert Topic.table_exists?
56
-
57
- # Test when owner included in table name.
58
- Topic.table_name = "dbo.topics"
59
- assert Topic.table_exists?, "Topics table name of 'dbo.topics' should return true for exists."
60
-
61
- # Test when database and owner included in table name.
62
- Topic.table_name = "#{arunit_database}.dbo.topics"
63
- assert Topic.table_exists?, "Topics table name of '[DATABASE].dbo.topics' should return true for exists."
64
- ensure
65
- Topic.table_name = "topics"
66
- end
53
+ assert_equal "topics", Topic.table_name
54
+ assert Topic.table_exists?
55
+
56
+ # Test when owner included in table name.
57
+ Topic.table_name = "dbo.topics"
58
+ assert Topic.table_exists?, "Topics table name of 'dbo.topics' should return true for exists."
59
+
60
+ # Test when database and owner included in table name.
61
+ Topic.table_name = "#{arunit_database}.dbo.topics"
62
+ assert Topic.table_exists?, "Topics table name of '[DATABASE].dbo.topics' should return true for exists."
63
+ ensure
64
+ Topic.table_name = "topics"
67
65
  end
68
66
 
69
67
  it "test table existence across database schemas" do
@@ -77,18 +75,18 @@ class AdapterTestSQLServer < ActiveRecord::TestCase
77
75
  assert_not_equal arunit_database, arunit2_database
78
76
 
79
77
  # Assert that the Topics table exists when using the Topics connection.
80
- assert arunit_connection.table_exists?('topics'), 'Topics table exists using table name'
81
- assert arunit_connection.table_exists?('dbo.topics'), 'Topics table exists using owner and table name'
82
- assert arunit_connection.table_exists?("#{arunit_database}.dbo.topics"), 'Topics table exists using database, owner and table name'
78
+ assert arunit_connection.table_exists?("topics"), "Topics table exists using table name"
79
+ assert arunit_connection.table_exists?("dbo.topics"), "Topics table exists using owner and table name"
80
+ assert arunit_connection.table_exists?("#{arunit_database}.dbo.topics"), "Topics table exists using database, owner and table name"
83
81
 
84
82
  # Assert that the Colleges table exists when using the Colleges connection.
85
- assert arunit2_connection.table_exists?('colleges'), 'College table exists using table name'
86
- assert arunit2_connection.table_exists?('dbo.colleges'), 'College table exists using owner and table name'
87
- assert arunit2_connection.table_exists?("#{arunit2_database}.dbo.colleges"), 'College table exists using database, owner and table name'
83
+ assert arunit2_connection.table_exists?("colleges"), "College table exists using table name"
84
+ assert arunit2_connection.table_exists?("dbo.colleges"), "College table exists using owner and table name"
85
+ assert arunit2_connection.table_exists?("#{arunit2_database}.dbo.colleges"), "College table exists using database, owner and table name"
88
86
 
89
87
  # Assert that the tables exist when using each others connection.
90
- assert arunit_connection.table_exists?("#{arunit2_database}.dbo.colleges"), 'Colleges table exists using Topics connection'
91
- assert arunit2_connection.table_exists?("#{arunit_database}.dbo.topics"), 'Topics table exists using Colleges connection'
88
+ assert arunit_connection.table_exists?("#{arunit2_database}.dbo.colleges"), "Colleges table exists using Topics connection"
89
+ assert arunit2_connection.table_exists?("#{arunit_database}.dbo.topics"), "Topics table exists using Colleges connection"
92
90
  end
93
91
 
94
92
  it "return true to insert sql query for inserts only" do
@@ -118,20 +116,20 @@ class AdapterTestSQLServer < ActiveRecord::TestCase
118
116
  db_config = ActiveRecord::Base.configurations.configs_for(env_name: "arunit", name: "primary")
119
117
  configuration = db_config.configuration_hash.merge(database: "nonexistent_activerecord_unittest")
120
118
  assert_not ActiveRecord::ConnectionAdapters::SQLServerAdapter.database_exists?(configuration),
121
- "expected database #{configuration[:database]} to not exist"
119
+ "expected database #{configuration[:database]} to not exist"
122
120
  end
123
121
 
124
122
  it "test database exists returns true when the database exists" do
125
123
  db_config = ActiveRecord::Base.configurations.configs_for(env_name: "arunit", name: "primary")
126
124
  assert ActiveRecord::ConnectionAdapters::SQLServerAdapter.database_exists?(db_config.configuration_hash),
127
- "expected database #{db_config.database} to exist"
125
+ "expected database #{db_config.database} to exist"
128
126
  end
129
127
 
130
128
  it "test primary key violation" do
131
- Post.create!(id: 0, title: 'Setup', body: 'Create post with primary key of zero')
129
+ Post.create!(id: 0, title: "Setup", body: "Create post with primary key of zero")
132
130
 
133
131
  assert_raise ActiveRecord::RecordNotUnique do
134
- Post.create!(id: 0, title: 'Test', body: 'Try to create another post with primary key of zero')
132
+ Post.create!(id: 0, title: "Test", body: "Try to create another post with primary key of zero")
135
133
  end
136
134
  end
137
135
 
@@ -141,12 +139,20 @@ class AdapterTestSQLServer < ActiveRecord::TestCase
141
139
  end
142
140
 
143
141
  after do
144
- connection.execute("SET LANGUAGE #{@default_language}") rescue nil
142
+ begin
143
+ connection.execute("SET LANGUAGE #{@default_language}")
144
+ rescue
145
+ nil
146
+ end
145
147
  connection.send :initialize_dateformatter
146
148
  end
147
149
 
148
150
  it "memos users dateformat" do
149
- connection.execute("SET LANGUAGE us_english") rescue nil
151
+ begin
152
+ connection.execute("SET LANGUAGE us_english")
153
+ rescue
154
+ nil
155
+ end
150
156
  dateformat = connection.instance_variable_get(:@database_dateformat)
151
157
  assert_equal "mdy", dateformat
152
158
  end
@@ -206,7 +212,7 @@ class AdapterTestSQLServer < ActiveRecord::TestCase
206
212
  connection.lowercase_schema_reflection = true
207
213
 
208
214
  assert_nothing_raised do
209
- post = Post.create!(title: 'Setup', body: 'Record to be deleted')
215
+ post = Post.create!(title: "Setup", body: "Record to be deleted")
210
216
  post.destroy!
211
217
  end
212
218
  end
@@ -237,12 +243,12 @@ class AdapterTestSQLServer < ActiveRecord::TestCase
237
243
  end
238
244
 
239
245
  it "return quoted table_name to #query_requires_identity_insert? when INSERT sql contains id column" do
240
- assert_equal "[funny_jokes]", connection.send(:query_requires_identity_insert?, @identity_insert_sql)
241
- assert_equal "[funny_jokes]", connection.send(:query_requires_identity_insert?, @identity_insert_sql_unquoted)
242
- assert_equal "[funny_jokes]", connection.send(:query_requires_identity_insert?, @identity_insert_sql_unordered)
243
- assert_equal "[funny_jokes]", connection.send(:query_requires_identity_insert?, @identity_insert_sql_sp)
244
- assert_equal "[funny_jokes]", connection.send(:query_requires_identity_insert?, @identity_insert_sql_unquoted_sp)
245
- assert_equal "[funny_jokes]", connection.send(:query_requires_identity_insert?, @identity_insert_sql_unordered_sp)
246
+ assert_equal "[funny_jokes]", connection.send(:query_requires_identity_insert?, @identity_insert_sql)
247
+ assert_equal "[funny_jokes]", connection.send(:query_requires_identity_insert?, @identity_insert_sql_unquoted)
248
+ assert_equal "[funny_jokes]", connection.send(:query_requires_identity_insert?, @identity_insert_sql_unordered)
249
+ assert_equal "[funny_jokes]", connection.send(:query_requires_identity_insert?, @identity_insert_sql_sp)
250
+ assert_equal "[funny_jokes]", connection.send(:query_requires_identity_insert?, @identity_insert_sql_unquoted_sp)
251
+ assert_equal "[funny_jokes]", connection.send(:query_requires_identity_insert?, @identity_insert_sql_unordered_sp)
246
252
 
247
253
  assert_equal "[ships]", connection.send(:query_requires_identity_insert?, @identity_merge_sql)
248
254
  assert_equal "[ships]", connection.send(:query_requires_identity_insert?, @identity_merge_sql_unquoted)
@@ -326,7 +332,10 @@ class AdapterTestSQLServer < ActiveRecord::TestCase
326
332
 
327
333
  describe "disabling referential integrity" do
328
334
  before do
329
- connection.disable_referential_integrity { SSTestHasPk.delete_all; SSTestHasFk.delete_all }
335
+ connection.disable_referential_integrity {
336
+ SSTestHasPk.delete_all
337
+ SSTestHasFk.delete_all
338
+ }
330
339
  @parent = SSTestHasPk.create!
331
340
  @member = SSTestHasFk.create!(fk_id: @parent.id)
332
341
  end
@@ -467,8 +476,8 @@ class AdapterTestSQLServer < ActiveRecord::TestCase
467
476
  assert_equal columns.size, SSTestCustomersView.columns.size
468
477
  columns.each do |colname|
469
478
  assert_instance_of ActiveRecord::ConnectionAdapters::SQLServer::Column,
470
- SSTestCustomersView.columns_hash[colname],
471
- "Column name #{colname.inspect} was not found in these columns #{SSTestCustomersView.columns.map(&:name).inspect}"
479
+ SSTestCustomersView.columns_hash[colname],
480
+ "Column name #{colname.inspect} was not found in these columns #{SSTestCustomersView.columns.map(&:name).inspect}"
472
481
  end
473
482
  end
474
483
 
@@ -494,8 +503,8 @@ class AdapterTestSQLServer < ActiveRecord::TestCase
494
503
  assert_equal columns.size, SSTestStringDefaultsView.columns.size
495
504
  columns.each do |colname|
496
505
  assert_instance_of ActiveRecord::ConnectionAdapters::SQLServer::Column,
497
- SSTestStringDefaultsView.columns_hash[colname],
498
- "Column name #{colname.inspect} was not found in these columns #{SSTestStringDefaultsView.columns.map(&:name).inspect}"
506
+ SSTestStringDefaultsView.columns_hash[colname],
507
+ "Column name #{colname.inspect} was not found in these columns #{SSTestStringDefaultsView.columns.map(&:name).inspect}"
499
508
  end
500
509
  end
501
510
 
@@ -507,7 +516,7 @@ class AdapterTestSQLServer < ActiveRecord::TestCase
507
516
 
508
517
  it "find default values" do
509
518
  assert_equal "null", SSTestStringDefaultsView.new.pretend_null,
510
- SSTestStringDefaultsView.columns_hash["pretend_null"].inspect
519
+ SSTestStringDefaultsView.columns_hash["pretend_null"].inspect
511
520
  end
512
521
 
513
522
  it "respond true to data_source_exists?" do
@@ -517,12 +526,12 @@ class AdapterTestSQLServer < ActiveRecord::TestCase
517
526
  # That have more than 4000 chars for their definition
518
527
 
519
528
  it "cope with null returned for the definition" do
520
- assert_nothing_raised() { SSTestStringDefaultsBigView.columns }
529
+ assert_nothing_raised { SSTestStringDefaultsBigView.columns }
521
530
  end
522
531
 
523
532
  it "using alternate view definition still be able to find real default" do
524
533
  assert_equal "null", SSTestStringDefaultsBigView.new.pretend_null,
525
- SSTestStringDefaultsBigView.columns_hash["pretend_null"].inspect
534
+ SSTestStringDefaultsBigView.columns_hash["pretend_null"].inspect
526
535
  end
527
536
  end
528
537
 
@@ -597,30 +606,30 @@ class AdapterTestSQLServer < ActiveRecord::TestCase
597
606
  end
598
607
  end
599
608
 
600
- describe 'table is in non-dbo schema' do
609
+ describe "table is in non-dbo schema" do
601
610
  it "records can be created successfully" do
602
611
  assert_difference("Alien.count", 1) do
603
- Alien.create!(name: 'Trisolarans')
612
+ Alien.create!(name: "Trisolarans")
604
613
  end
605
614
  end
606
615
 
607
- it 'records can be inserted using SQL' do
616
+ it "records can be inserted using SQL" do
608
617
  assert_difference("Alien.count", 2) do
609
618
  Alien.lease_connection.exec_insert("insert into [test].[aliens] (id, name) VALUES(1, 'Trisolarans'), (2, 'Xenomorph')")
610
619
  end
611
620
  end
612
621
  end
613
622
 
614
- describe 'table names contains spaces' do
615
- it 'records can be created successfully' do
623
+ describe "table names contains spaces" do
624
+ it "records can be created successfully" do
616
625
  assert_difference("TableWithSpaces.count", 1) do
617
- TableWithSpaces.create!(name: 'Bob')
626
+ TableWithSpaces.create!(name: "Bob")
618
627
  end
619
628
  end
620
629
  end
621
630
 
622
631
  describe "exec_insert" do
623
- it 'values clause should be case-insensitive' do
632
+ it "values clause should be case-insensitive" do
624
633
  assert_difference("Post.count", 4) do
625
634
  first_insert = connection.exec_insert("INSERT INTO [posts] ([id],[title],[body]) VALUES(100, 'Title', 'Body'), (102, 'Title', 'Body')")
626
635
  second_insert = connection.exec_insert("INSERT INTO [posts] ([id],[title],[body]) values(113, 'Body', 'Body'), (114, 'Body', 'Body')")
@@ -636,33 +645,37 @@ class AdapterTestSQLServer < ActiveRecord::TestCase
636
645
  @conn = ActiveRecord::Base.lease_connection
637
646
  end
638
647
 
639
- it 'raises an error when the foreign key is mismatched' do
648
+ it "raises an error when the foreign key is mismatched" do
640
649
  error = assert_raises(ActiveRecord::MismatchedForeignKey) do
641
650
  @conn.add_reference :engines, :old_car
642
651
  @conn.add_foreign_key :engines, :old_cars
643
652
  end
644
653
 
645
654
  assert_match(
646
- %r/Column 'old_cars\.id' is not the same data type as referencing column 'engines\.old_car_id' in foreign key '.*'/,
655
+ %r{Column 'old_cars\.id' is not the same data type as referencing column 'engines\.old_car_id' in foreign key '.*'},
647
656
  error.message
648
657
  )
649
658
  assert_not_nil error.cause
650
659
  assert_equal @conn.pool, error.connection_pool
651
660
  ensure
652
- @conn.execute("ALTER TABLE engines DROP COLUMN old_car_id") rescue nil
661
+ begin
662
+ @conn.execute("ALTER TABLE engines DROP COLUMN old_car_id")
663
+ rescue
664
+ nil
665
+ end
653
666
  end
654
667
  end
655
668
 
656
669
  describe "placeholder conditions" do
657
- it 'using time placeholder' do
670
+ it "using time placeholder" do
658
671
  assert_equal Task.where("starting < ?", Time.now).count, 1
659
672
  end
660
673
 
661
- it 'using date placeholder' do
674
+ it "using date placeholder" do
662
675
  assert_equal Task.where("starting < ?", Date.today).count, 1
663
676
  end
664
677
 
665
- it 'using date-time placeholder' do
678
+ it "using date-time placeholder" do
666
679
  assert_equal Task.where("starting < ?", DateTime.current).count, 1
667
680
  end
668
681
  end