activerecord-sqlserver-adapter 6.0.0.rc2 → 6.1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +26 -0
  3. data/CHANGELOG.md +20 -41
  4. data/README.md +32 -3
  5. data/RUNNING_UNIT_TESTS.md +1 -1
  6. data/VERSION +1 -1
  7. data/activerecord-sqlserver-adapter.gemspec +1 -1
  8. data/lib/active_record/connection_adapters/sqlserver/core_ext/calculations.rb +0 -9
  9. data/lib/active_record/connection_adapters/sqlserver/core_ext/explain.rb +7 -2
  10. data/lib/active_record/connection_adapters/sqlserver/database_limits.rb +0 -4
  11. data/lib/active_record/connection_adapters/sqlserver/database_statements.rb +28 -16
  12. data/lib/active_record/connection_adapters/sqlserver/quoting.rb +7 -7
  13. data/lib/active_record/connection_adapters/sqlserver/schema_creation.rb +22 -1
  14. data/lib/active_record/connection_adapters/sqlserver/schema_dumper.rb +9 -3
  15. data/lib/active_record/connection_adapters/sqlserver/schema_statements.rb +31 -8
  16. data/lib/active_record/connection_adapters/sqlserver/sql_type_metadata.rb +27 -7
  17. data/lib/active_record/connection_adapters/sqlserver/table_definition.rb +0 -1
  18. data/lib/active_record/connection_adapters/sqlserver/transaction.rb +2 -2
  19. data/lib/active_record/connection_adapters/sqlserver/type.rb +1 -0
  20. data/lib/active_record/connection_adapters/sqlserver/type/decimal_without_scale.rb +22 -0
  21. data/lib/active_record/connection_adapters/sqlserver/utils.rb +1 -1
  22. data/lib/active_record/connection_adapters/sqlserver_adapter.rb +100 -68
  23. data/lib/active_record/connection_adapters/sqlserver_column.rb +17 -0
  24. data/lib/active_record/sqlserver_base.rb +9 -15
  25. data/lib/active_record/tasks/sqlserver_database_tasks.rb +17 -14
  26. data/lib/arel/visitors/sqlserver.rb +111 -39
  27. data/test/cases/adapter_test_sqlserver.rb +48 -14
  28. data/test/cases/change_column_collation_test_sqlserver.rb +33 -0
  29. data/test/cases/coerced_tests.rb +598 -78
  30. data/test/cases/column_test_sqlserver.rb +5 -2
  31. data/test/cases/disconnected_test_sqlserver.rb +39 -0
  32. data/test/cases/execute_procedure_test_sqlserver.rb +9 -0
  33. data/test/cases/in_clause_test_sqlserver.rb +27 -0
  34. data/test/cases/lateral_test_sqlserver.rb +35 -0
  35. data/test/cases/migration_test_sqlserver.rb +51 -0
  36. data/test/cases/optimizer_hints_test_sqlserver.rb +72 -0
  37. data/test/cases/order_test_sqlserver.rb +7 -0
  38. data/test/cases/primary_keys_test_sqlserver.rb +103 -0
  39. data/test/cases/rake_test_sqlserver.rb +3 -2
  40. data/test/cases/schema_dumper_test_sqlserver.rb +20 -3
  41. data/test/migrations/create_clients_and_change_column_collation.rb +19 -0
  42. data/test/models/sqlserver/sst_string_collation.rb +3 -0
  43. data/test/schema/sqlserver_specific_schema.rb +17 -0
  44. data/test/support/marshal_compatibility_fixtures/SQLServer/rails_6_0_topic.dump +0 -0
  45. data/test/support/marshal_compatibility_fixtures/SQLServer/rails_6_0_topic_associations.dump +0 -0
  46. data/test/support/sql_counter_sqlserver.rb +14 -12
  47. metadata +32 -13
  48. data/.travis.yml +0 -23
@@ -27,6 +27,23 @@ module ActiveRecord
27
27
  def case_sensitive?
28
28
  collation && collation.match(/_CS/)
29
29
  end
30
+
31
+ private
32
+
33
+ # In the Rails version of this method there is an assumption that the `default` value will always be a
34
+ # `String` class, which must be true for the MySQL/PostgreSQL/SQLite adapters. However, in the SQL Server
35
+ # adapter the `default` value can also be Boolean/Date/Time/etc. Changed the implementation of this method
36
+ # to handle non-String `default` objects.
37
+ def deduplicated
38
+ @name = -name
39
+ @sql_type_metadata = sql_type_metadata.deduplicate if sql_type_metadata
40
+ @default = (default.is_a?(String) ? -default : default.dup.freeze) if default
41
+ @default_function = -default_function if default_function
42
+ @collation = -collation if collation
43
+ @comment = -comment if comment
44
+
45
+ freeze
46
+ end
30
47
  end
31
48
  end
32
49
  end
@@ -4,21 +4,15 @@ module ActiveRecord
4
4
  module ConnectionHandling
5
5
  def sqlserver_connection(config) #:nodoc:
6
6
  config = config.symbolize_keys
7
- config.reverse_merge! mode: :dblib
8
- mode = config[:mode].to_s.downcase.underscore.to_sym
9
- case mode
10
- when :dblib
11
- require "tiny_tds"
12
- else
13
- raise ArgumentError, "Unknown connection mode in #{config.inspect}."
14
- end
15
- ConnectionAdapters::SQLServerAdapter.new(nil, nil, config.merge(mode: mode))
16
- rescue TinyTds::Error => e
17
- if e.message.match(/database .* does not exist/i)
18
- raise ActiveRecord::NoDatabaseError
19
- else
20
- raise
21
- end
7
+ config.reverse_merge!(mode: :dblib)
8
+ config[:mode] = config[:mode].to_s.downcase.underscore.to_sym
9
+
10
+ ConnectionAdapters::SQLServerAdapter.new(
11
+ ConnectionAdapters::SQLServerAdapter.new_client(config),
12
+ logger,
13
+ nil,
14
+ config
15
+ )
22
16
  end
23
17
  end
24
18
  end
@@ -13,13 +13,18 @@ module ActiveRecord
13
13
  delegate :connection, :establish_connection, :clear_active_connections!,
14
14
  to: ActiveRecord::Base
15
15
 
16
+ def self.using_database_configurations?
17
+ true
18
+ end
19
+
16
20
  def initialize(configuration)
17
21
  @configuration = configuration
22
+ @configuration_hash = @configuration.configuration_hash
18
23
  end
19
24
 
20
25
  def create(master_established = false)
21
26
  establish_master_connection unless master_established
22
- connection.create_database configuration["database"], configuration.merge("collation" => default_collation)
27
+ connection.create_database configuration.database, configuration_hash.merge(collation: default_collation)
23
28
  establish_connection configuration
24
29
  rescue ActiveRecord::StatementInvalid => e
25
30
  if /database .* already exists/i === e.message
@@ -31,7 +36,7 @@ module ActiveRecord
31
36
 
32
37
  def drop
33
38
  establish_master_connection
34
- connection.drop_database configuration["database"]
39
+ connection.drop_database configuration.database
35
40
  end
36
41
 
37
42
  def charset
@@ -49,14 +54,14 @@ module ActiveRecord
49
54
  end
50
55
 
51
56
  def structure_dump(filename, extra_flags)
52
- server_arg = "-S #{Shellwords.escape(configuration['host'])}"
53
- server_arg += ":#{Shellwords.escape(configuration['port'])}" if configuration["port"]
57
+ server_arg = "-S #{Shellwords.escape(configuration_hash[:host])}"
58
+ server_arg += ":#{Shellwords.escape(configuration_hash[:port])}" if configuration_hash[:port]
54
59
  command = [
55
60
  "defncopy-ttds",
56
61
  server_arg,
57
- "-D #{Shellwords.escape(configuration['database'])}",
58
- "-U #{Shellwords.escape(configuration['username'])}",
59
- "-P #{Shellwords.escape(configuration['password'])}",
62
+ "-D #{Shellwords.escape(configuration_hash[:database])}",
63
+ "-U #{Shellwords.escape(configuration_hash[:username])}",
64
+ "-P #{Shellwords.escape(configuration_hash[:password])}",
60
65
  "-o #{Shellwords.escape(filename)}",
61
66
  ]
62
67
  table_args = connection.tables.map { |t| Shellwords.escape(t) }
@@ -80,16 +85,14 @@ module ActiveRecord
80
85
 
81
86
  private
82
87
 
83
- def configuration
84
- @configuration
85
- end
88
+ attr_reader :configuration, :configuration_hash
86
89
 
87
90
  def default_collation
88
- configuration["collation"] || DEFAULT_COLLATION
91
+ configuration_hash[:collation] || DEFAULT_COLLATION
89
92
  end
90
93
 
91
94
  def establish_master_connection
92
- establish_connection configuration.merge("database" => "master")
95
+ establish_connection configuration_hash.merge(database: "master")
93
96
  end
94
97
  end
95
98
 
@@ -110,9 +113,9 @@ module ActiveRecord
110
113
  end
111
114
 
112
115
  def configuration_host_ip(configuration)
113
- return nil unless configuration["host"]
116
+ return nil unless configuration.host
114
117
 
115
- Socket::getaddrinfo(configuration["host"], "echo", Socket::AF_INET)[0][3]
118
+ Socket::getaddrinfo(configuration.host, "echo", Socket::AF_INET)[0][3]
116
119
  end
117
120
 
118
121
  def local_ipaddr?(host_ip)
@@ -11,13 +11,14 @@ module Arel
11
11
 
12
12
  private
13
13
 
14
- # SQLServer ToSql/Visitor (Overides)
14
+ # SQLServer ToSql/Visitor (Overrides)
15
15
 
16
- def visit_Arel_Nodes_BindParam o, collector
17
- collector.add_bind(o.value) { |i| "@#{i - 1}" }
18
- end
16
+ BIND_BLOCK = proc { |i| "@#{i - 1}" }
17
+ private_constant :BIND_BLOCK
18
+
19
+ def bind_block; BIND_BLOCK; end
19
20
 
20
- def visit_Arel_Nodes_Bin o, collector
21
+ def visit_Arel_Nodes_Bin(o, collector)
21
22
  visit o.expr, collector
22
23
  collector << " #{ActiveRecord::ConnectionAdapters::SQLServerAdapter.cs_equality_operator} "
23
24
  end
@@ -28,26 +29,26 @@ module Arel
28
29
  visit o.right, collector
29
30
  end
30
31
 
31
- def visit_Arel_Nodes_UpdateStatement(o, a)
32
+ def visit_Arel_Nodes_UpdateStatement(o, collector)
32
33
  if o.orders.any? && o.limit.nil?
33
34
  o.limit = Nodes::Limit.new(9_223_372_036_854_775_807)
34
35
  end
35
36
  super
36
37
  end
37
38
 
38
- def visit_Arel_Nodes_Lock o, collector
39
+ def visit_Arel_Nodes_Lock(o, collector)
39
40
  o.expr = Arel.sql("WITH(UPDLOCK)") if o.expr.to_s =~ /FOR UPDATE/
40
41
  collector << " "
41
42
  visit o.expr, collector
42
43
  end
43
44
 
44
- def visit_Arel_Nodes_Offset o, collector
45
+ def visit_Arel_Nodes_Offset(o, collector)
45
46
  collector << OFFSET
46
47
  visit o.expr, collector
47
48
  collector << ROWS
48
49
  end
49
50
 
50
- def visit_Arel_Nodes_Limit o, collector
51
+ def visit_Arel_Nodes_Limit(o, collector)
51
52
  if node_value(o) == 0
52
53
  collector << FETCH0
53
54
  collector << ROWS_ONLY
@@ -63,7 +64,38 @@ module Arel
63
64
  super
64
65
  end
65
66
 
66
- def visit_Arel_Nodes_SelectStatement o, collector
67
+ def visit_Arel_Nodes_HomogeneousIn(o, collector)
68
+ collector.preparable = false
69
+
70
+ collector << quote_table_name(o.table_name) << "." << quote_column_name(o.column_name)
71
+
72
+ if o.type == :in
73
+ collector << " IN ("
74
+ else
75
+ collector << " NOT IN ("
76
+ end
77
+
78
+ values = o.casted_values
79
+
80
+ if values.empty?
81
+ collector << @connection.quote(nil)
82
+ elsif @connection.prepared_statements
83
+ # Monkey-patch start. Add query attribute bindings rather than just values.
84
+ column_name = o.column_name
85
+ column_type = o.attribute.relation.type_for_attribute(o.column_name)
86
+ attrs = values.map { |value| ActiveRecord::Relation::QueryAttribute.new(column_name, value, column_type) }
87
+
88
+ collector.add_binds(attrs, &bind_block)
89
+ # Monkey-patch end.
90
+ else
91
+ collector.add_binds(values, &bind_block)
92
+ end
93
+
94
+ collector << ")"
95
+ collector
96
+ end
97
+
98
+ def visit_Arel_Nodes_SelectStatement(o, collector)
67
99
  @select_statement = o
68
100
  distinct_One_As_One_Is_So_Not_Fetch o
69
101
  if o.with
@@ -80,7 +112,17 @@ module Arel
80
112
  @select_statement = nil
81
113
  end
82
114
 
83
- def visit_Arel_Table o, collector
115
+ def visit_Arel_Nodes_SelectCore(o, collector)
116
+ collector = super
117
+ maybe_visit o.optimizer_hints, collector
118
+ end
119
+
120
+ def visit_Arel_Nodes_OptimizerHints(o, collector)
121
+ hints = o.expr.map { |v| sanitize_as_option_clause(v) }.join(", ")
122
+ collector << "OPTION (#{hints})"
123
+ end
124
+
125
+ def visit_Arel_Table(o, collector)
84
126
  # Apparently, o.engine.connection can actually be a different adapter
85
127
  # than sqlserver. Can be removed if fixed in ActiveRecord. See:
86
128
  # github.com/rails-sqlserver/activerecord-sqlserver-adapter/issues/450
@@ -102,7 +144,7 @@ module Arel
102
144
  end
103
145
  end
104
146
 
105
- def visit_Arel_Nodes_JoinSource o, collector
147
+ def visit_Arel_Nodes_JoinSource(o, collector)
106
148
  if o.left
107
149
  collector = visit o.left, collector
108
150
  collector = visit_Arel_Nodes_SelectStatement_SQLServer_Lock collector
@@ -114,39 +156,53 @@ module Arel
114
156
  collector
115
157
  end
116
158
 
117
- def visit_Arel_Nodes_InnerJoin o, collector
118
- collector << "INNER JOIN "
119
- collector = visit o.left, collector
120
- collector = visit_Arel_Nodes_SelectStatement_SQLServer_Lock collector, space: true
121
- if o.right
122
- collector << " "
123
- visit(o.right, collector)
159
+ def visit_Arel_Nodes_InnerJoin(o, collector)
160
+ if o.left.is_a?(Arel::Nodes::As) && o.left.left.is_a?(Arel::Nodes::Lateral)
161
+ collector << "CROSS "
162
+ visit o.left, collector
124
163
  else
125
- collector
164
+ collector << "INNER JOIN "
165
+ collector = visit o.left, collector
166
+ collector = visit_Arel_Nodes_SelectStatement_SQLServer_Lock collector, space: true
167
+ if o.right
168
+ collector << " "
169
+ visit(o.right, collector)
170
+ else
171
+ collector
172
+ end
126
173
  end
127
174
  end
128
175
 
129
- def visit_Arel_Nodes_OuterJoin o, collector
130
- collector << "LEFT OUTER JOIN "
131
- collector = visit o.left, collector
132
- collector = visit_Arel_Nodes_SelectStatement_SQLServer_Lock collector, space: true
133
- collector << " "
134
- visit o.right, collector
176
+ def visit_Arel_Nodes_OuterJoin(o, collector)
177
+ if o.left.is_a?(Arel::Nodes::As) && o.left.left.is_a?(Arel::Nodes::Lateral)
178
+ collector << "OUTER "
179
+ visit o.left, collector
180
+ else
181
+ collector << "LEFT OUTER JOIN "
182
+ collector = visit o.left, collector
183
+ collector = visit_Arel_Nodes_SelectStatement_SQLServer_Lock collector, space: true
184
+ collector << " "
185
+ visit o.right, collector
186
+ end
135
187
  end
136
188
 
137
- def collect_in_clause(left, right, collector)
138
- if Array === right
139
- right.each { |node| remove_invalid_ordering_from_select_statement(node) }
189
+ def visit_Arel_Nodes_In(o, collector)
190
+ if Array === o.right
191
+ o.right.each { |node| remove_invalid_ordering_from_select_statement(node) }
140
192
  else
141
- remove_invalid_ordering_from_select_statement(right)
193
+ remove_invalid_ordering_from_select_statement(o.right)
142
194
  end
143
195
 
144
196
  super
145
197
  end
146
198
 
199
+ def collect_optimizer_hints(o, collector)
200
+ collector
201
+ end
202
+
147
203
  # SQLServer ToSql/Visitor (Additions)
148
204
 
149
- def visit_Arel_Nodes_SelectStatement_SQLServer_Lock collector, options = {}
205
+ def visit_Arel_Nodes_SelectStatement_SQLServer_Lock(collector, options = {})
150
206
  if select_statement_lock?
151
207
  collector = visit @select_statement.lock, collector
152
208
  collector << " " if options[:space]
@@ -154,7 +210,7 @@ module Arel
154
210
  collector
155
211
  end
156
212
 
157
- def visit_Orders_And_Let_Fetch_Happen o, collector
213
+ def visit_Orders_And_Let_Fetch_Happen(o, collector)
158
214
  make_Fetch_Possible_And_Deterministic o
159
215
  unless o.orders.empty?
160
216
  collector << " ORDER BY "
@@ -167,13 +223,25 @@ module Arel
167
223
  collector
168
224
  end
169
225
 
170
- def visit_Make_Fetch_Happen o, collector
226
+ def visit_Make_Fetch_Happen(o, collector)
171
227
  o.offset = Nodes::Offset.new(0) if o.limit && !o.offset
172
228
  collector = visit o.offset, collector if o.offset
173
229
  collector = visit o.limit, collector if o.limit
174
230
  collector
175
231
  end
176
232
 
233
+ def visit_Arel_Nodes_Lateral(o, collector)
234
+ collector << "APPLY"
235
+ collector << " "
236
+ if o.expr.is_a?(Arel::Nodes::SelectStatement)
237
+ collector << "("
238
+ visit(o.expr, collector)
239
+ collector << ")"
240
+ else
241
+ visit(o.expr, collector)
242
+ end
243
+ end
244
+
177
245
  # SQLServer Helpers
178
246
 
179
247
  def node_value(node)
@@ -190,7 +258,7 @@ module Arel
190
258
  @select_statement && @select_statement.lock
191
259
  end
192
260
 
193
- def make_Fetch_Possible_And_Deterministic o
261
+ def make_Fetch_Possible_And_Deterministic(o)
194
262
  return if o.limit.nil? && o.offset.nil?
195
263
 
196
264
  t = table_From_Statement o
@@ -203,7 +271,7 @@ module Arel
203
271
  end
204
272
  end
205
273
 
206
- def distinct_One_As_One_Is_So_Not_Fetch o
274
+ def distinct_One_As_One_Is_So_Not_Fetch(o)
207
275
  core = o.cores.first
208
276
  distinct = Nodes::Distinct === core.set_quantifier
209
277
  oneasone = core.projections.all? { |x| x == ActiveRecord::FinderMethods::ONE_AS_ONE }
@@ -214,7 +282,7 @@ module Arel
214
282
  end
215
283
  end
216
284
 
217
- def table_From_Statement o
285
+ def table_From_Statement(o)
218
286
  core = o.cores.first
219
287
  if Arel::Table === core.from
220
288
  core.from
@@ -225,15 +293,15 @@ module Arel
225
293
  end
226
294
  end
227
295
 
228
- def primary_Key_From_Table t
296
+ def primary_Key_From_Table(t)
229
297
  return unless t
230
298
 
231
299
  column_name = @connection.schema_cache.primary_keys(t.name) ||
232
- @connection.schema_cache.columns_hash(t.name).first.try(:second).try(:name)
300
+ @connection.schema_cache.columns_hash(t.name).first.try(:second).try(:name)
233
301
  column_name ? t[column_name] : nil
234
302
  end
235
303
 
236
- def remote_server_table_name o
304
+ def remote_server_table_name(o)
237
305
  ActiveRecord::ConnectionAdapters::SQLServer::Utils.extract_identifiers(
238
306
  "#{o.class.engine.connection.database_prefix}#{o.name}"
239
307
  ).quoted
@@ -247,6 +315,10 @@ module Arel
247
315
 
248
316
  node.orders = [] unless node.offset || node.limit
249
317
  end
318
+
319
+ def sanitize_as_option_clause(value)
320
+ value.gsub(%r{OPTION \s* \( (.+) \)}xi, "\\1")
321
+ end
250
322
  end
251
323
  end
252
324
  end
@@ -6,6 +6,7 @@ require "models/task"
6
6
  require "models/post"
7
7
  require "models/subscriber"
8
8
  require "models/minimalistic"
9
+ require "models/college"
9
10
 
10
11
  class AdapterTestSQLServer < ActiveRecord::TestCase
11
12
  fixtures :tasks
@@ -42,17 +43,49 @@ class AdapterTestSQLServer < ActiveRecord::TestCase
42
43
  assert connection.supports_ddl_transactions?
43
44
  end
44
45
 
45
- it "allow owner table name prefixs like dbo to still allow table exists to return true" do
46
+ it "table exists works if table name prefixed by schema and owner" do
46
47
  begin
47
48
  assert_equal "topics", Topic.table_name
48
49
  assert Topic.table_exists?
50
+
51
+ # Test when owner included in table name.
49
52
  Topic.table_name = "dbo.topics"
50
- assert Topic.table_exists?, "Tasks table name of dbo.topics should return true for exists."
53
+ assert Topic.table_exists?, "Topics table name of 'dbo.topics' should return true for exists."
54
+
55
+ # Test when database and owner included in table name.
56
+ db_config = ActiveRecord::Base.configurations.configs_for(env_name: "arunit", name: "primary")
57
+ Topic.table_name = "#{db_config.database}.dbo.topics"
58
+ assert Topic.table_exists?, "Topics table name of '[DATABASE].dbo.topics' should return true for exists."
51
59
  ensure
52
60
  Topic.table_name = "topics"
53
61
  end
54
62
  end
55
63
 
64
+ it "test table existence across database schemas" do
65
+ arunit_connection = Topic.connection
66
+ arunit2_connection = College.connection
67
+
68
+ arunit_database = arunit_connection.pool.db_config.database
69
+ arunit2_database = arunit2_connection.pool.db_config.database
70
+
71
+ # Assert that connections use different default databases schemas.
72
+ assert_not_equal arunit_database, arunit2_database
73
+
74
+ # Assert that the Topics table exists when using the Topics connection.
75
+ assert arunit_connection.table_exists?('topics'), 'Topics table exists using table name'
76
+ assert arunit_connection.table_exists?('dbo.topics'), 'Topics table exists using owner and table name'
77
+ assert arunit_connection.table_exists?("#{arunit_database}.dbo.topics"), 'Topics table exists using database, owner and table name'
78
+
79
+ # Assert that the Colleges table exists when using the Colleges connection.
80
+ assert arunit2_connection.table_exists?('colleges'), 'College table exists using table name'
81
+ assert arunit2_connection.table_exists?('dbo.colleges'), 'College table exists using owner and table name'
82
+ assert arunit2_connection.table_exists?("#{arunit2_database}.dbo.colleges"), 'College table exists using database, owner and table name'
83
+
84
+ # Assert that the tables exist when using each others connection.
85
+ assert arunit_connection.table_exists?("#{arunit2_database}.dbo.colleges"), 'Colleges table exists using Topics connection'
86
+ assert arunit2_connection.table_exists?("#{arunit_database}.dbo.topics"), 'Topics table exists using Colleges connection'
87
+ end
88
+
56
89
  it "return true to insert sql query for inserts only" do
57
90
  assert connection.send(:insert_sql?, "INSERT...")
58
91
  assert connection.send(:insert_sql?, "EXEC sp_executesql N'INSERT INTO [fk_test_has_fks] ([fk_id]) VALUES (@0); SELECT CAST(SCOPE_IDENTITY() AS bigint) AS Ident', N'@0 int', @0 = 0")
@@ -68,21 +101,23 @@ class AdapterTestSQLServer < ActiveRecord::TestCase
68
101
 
69
102
  it "test bad connection" do
70
103
  assert_raise ActiveRecord::NoDatabaseError do
71
- config = ActiveRecord::Base.configurations["arunit"].merge(database: "inexistent_activerecord_unittest")
72
- ActiveRecord::Base.sqlserver_connection config
104
+ db_config = ActiveRecord::Base.configurations.configs_for(env_name: "arunit", name: "primary")
105
+ configuration = db_config.configuration_hash.merge(database: "inexistent_activerecord_unittest")
106
+ ActiveRecord::Base.sqlserver_connection configuration
73
107
  end
74
108
  end
75
109
 
76
110
  it "test database exists returns false if database does not exist" do
77
- config = ActiveRecord::Base.configurations["arunit"].merge(database: "inexistent_activerecord_unittest")
78
- assert_not ActiveRecord::ConnectionAdapters::SQLServerAdapter.database_exists?(config),
111
+ db_config = ActiveRecord::Base.configurations.configs_for(env_name: "arunit", name: "primary")
112
+ configuration = db_config.configuration_hash.merge(database: "inexistent_activerecord_unittest")
113
+ assert_not ActiveRecord::ConnectionAdapters::SQLServerAdapter.database_exists?(configuration),
79
114
  "expected database to not exist"
80
115
  end
81
116
 
82
117
  it "test database exists returns true when the database exists" do
83
- config = ActiveRecord::Base.configurations["arunit"]
84
- assert ActiveRecord::ConnectionAdapters::SQLServerAdapter.database_exists?(config),
85
- "expected database #{config[:database]} to exist"
118
+ db_config = ActiveRecord::Base.configurations.configs_for(env_name: "arunit", name: "primary")
119
+ assert ActiveRecord::ConnectionAdapters::SQLServerAdapter.database_exists?(db_config.configuration_hash),
120
+ "expected database #{db_config.database} to exist"
86
121
  end
87
122
 
88
123
  describe "with different language" do
@@ -434,12 +469,11 @@ class AdapterTestSQLServer < ActiveRecord::TestCase
434
469
  describe "block writes to a database" do
435
470
  def setup
436
471
  @conn = ActiveRecord::Base.connection
437
- @connection_handler = ActiveRecord::Base.connection_handler
438
472
  end
439
473
 
440
474
  def test_errors_when_an_insert_query_is_called_while_preventing_writes
441
475
  assert_raises(ActiveRecord::ReadOnlyError) do
442
- @connection_handler.while_preventing_writes do
476
+ ActiveRecord::Base.while_preventing_writes do
443
477
  @conn.insert("INSERT INTO [subscribers] ([nick]) VALUES ('aido')")
444
478
  end
445
479
  end
@@ -449,7 +483,7 @@ class AdapterTestSQLServer < ActiveRecord::TestCase
449
483
  @conn.insert("INSERT INTO [subscribers] ([nick]) VALUES ('aido')")
450
484
 
451
485
  assert_raises(ActiveRecord::ReadOnlyError) do
452
- @connection_handler.while_preventing_writes do
486
+ ActiveRecord::Base.while_preventing_writes do
453
487
  @conn.update("UPDATE [subscribers] SET [subscribers].[name] = 'Aidan' WHERE [subscribers].[nick] = 'aido'")
454
488
  end
455
489
  end
@@ -459,7 +493,7 @@ class AdapterTestSQLServer < ActiveRecord::TestCase
459
493
  @conn.execute("INSERT INTO [subscribers] ([nick]) VALUES ('aido')")
460
494
 
461
495
  assert_raises(ActiveRecord::ReadOnlyError) do
462
- @connection_handler.while_preventing_writes do
496
+ ActiveRecord::Base.while_preventing_writes do
463
497
  @conn.execute("DELETE FROM [subscribers] WHERE [subscribers].[nick] = 'aido'")
464
498
  end
465
499
  end
@@ -468,7 +502,7 @@ class AdapterTestSQLServer < ActiveRecord::TestCase
468
502
  def test_doesnt_error_when_a_select_query_is_called_while_preventing_writes
469
503
  @conn.execute("INSERT INTO [subscribers] ([nick]) VALUES ('aido')")
470
504
 
471
- @connection_handler.while_preventing_writes do
505
+ ActiveRecord::Base.while_preventing_writes do
472
506
  assert_equal 1, @conn.execute("SELECT * FROM [subscribers] WHERE [subscribers].[nick] = 'aido'")
473
507
  end
474
508
  end