activerecord-sqlserver-adapter 7.0.5.1 → 7.1.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +3 -3
  3. data/.gitignore +3 -1
  4. data/CHANGELOG.md +38 -83
  5. data/Gemfile +3 -0
  6. data/README.md +16 -11
  7. data/RUNNING_UNIT_TESTS.md +24 -10
  8. data/Rakefile +2 -6
  9. data/VERSION +1 -1
  10. data/activerecord-sqlserver-adapter.gemspec +1 -1
  11. data/lib/active_record/connection_adapters/sqlserver/core_ext/abstract_adapter.rb +20 -0
  12. data/lib/active_record/connection_adapters/sqlserver/core_ext/calculations.rb +29 -6
  13. data/lib/active_record/connection_adapters/sqlserver/core_ext/explain.rb +4 -4
  14. data/lib/active_record/connection_adapters/sqlserver/core_ext/finder_methods.rb +10 -2
  15. data/lib/active_record/connection_adapters/sqlserver/core_ext/preloader.rb +15 -3
  16. data/lib/active_record/connection_adapters/sqlserver/database_limits.rb +0 -31
  17. data/lib/active_record/connection_adapters/sqlserver/database_statements.rb +86 -133
  18. data/lib/active_record/connection_adapters/sqlserver/database_tasks.rb +5 -5
  19. data/lib/active_record/connection_adapters/sqlserver/quoting.rb +3 -2
  20. data/lib/active_record/connection_adapters/sqlserver/savepoints.rb +24 -0
  21. data/lib/active_record/connection_adapters/sqlserver/schema_statements.rb +68 -29
  22. data/lib/active_record/connection_adapters/sqlserver/showplan.rb +3 -3
  23. data/lib/active_record/connection_adapters/sqlserver/table_definition.rb +6 -0
  24. data/lib/active_record/connection_adapters/sqlserver/transaction.rb +4 -6
  25. data/lib/active_record/connection_adapters/sqlserver/type/data.rb +10 -0
  26. data/lib/active_record/connection_adapters/sqlserver_adapter.rb +81 -114
  27. data/lib/active_record/connection_adapters/sqlserver_column.rb +1 -0
  28. data/lib/active_record/sqlserver_base.rb +1 -10
  29. data/lib/active_record/tasks/sqlserver_database_tasks.rb +5 -2
  30. data/lib/arel/visitors/sqlserver.rb +0 -33
  31. data/test/cases/adapter_test_sqlserver.rb +8 -7
  32. data/test/cases/coerced_tests.rb +526 -235
  33. data/test/cases/column_test_sqlserver.rb +6 -6
  34. data/test/cases/connection_test_sqlserver.rb +3 -6
  35. data/test/cases/disconnected_test_sqlserver.rb +5 -8
  36. data/test/cases/execute_procedure_test_sqlserver.rb +1 -1
  37. data/test/cases/rake_test_sqlserver.rb +1 -1
  38. data/test/cases/schema_dumper_test_sqlserver.rb +2 -2
  39. data/test/cases/transaction_test_sqlserver.rb +13 -8
  40. data/test/config.yml +1 -2
  41. data/test/support/connection_reflection.rb +2 -8
  42. data/test/support/core_ext/query_cache.rb +7 -1
  43. data/test/support/marshal_compatibility_fixtures/SQLServer/rails_6_1_topic_associations.dump +0 -0
  44. data/test/support/marshal_compatibility_fixtures/SQLServer/rails_7_1_topic.dump +0 -0
  45. data/test/support/marshal_compatibility_fixtures/SQLServer/rails_7_1_topic_associations.dump +0 -0
  46. data/test/support/sql_counter_sqlserver.rb +0 -15
  47. metadata +14 -8
@@ -277,7 +277,7 @@ class ColumnTestSQLServer < ActiveRecord::TestCase
277
277
  _(col.sql_type).must_equal "date"
278
278
  _(col.type).must_equal :date
279
279
  _(col.null).must_equal true
280
- _(col.default).must_equal connection_dblib_73? ? Date.civil(1, 1, 1) : "0001-01-01"
280
+ _(col.default).must_equal connection_tds_73 ? Date.civil(1, 1, 1) : "0001-01-01"
281
281
  _(obj.date).must_equal Date.civil(1, 1, 1)
282
282
  _(col.default_function).must_be_nil
283
283
  type = connection.lookup_cast_type_from_column(col)
@@ -357,7 +357,7 @@ class ColumnTestSQLServer < ActiveRecord::TestCase
357
357
  end
358
358
 
359
359
  it "datetime2" do
360
- skip "datetime2 not supported in this protocol version" unless connection_dblib_73?
360
+ skip "datetime2 not supported in this protocol version" unless connection_tds_73
361
361
  col = column("datetime2_7")
362
362
  _(col.sql_type).must_equal "datetime2(7)"
363
363
  _(col.type).must_equal :datetime
@@ -422,7 +422,7 @@ class ColumnTestSQLServer < ActiveRecord::TestCase
422
422
  end
423
423
 
424
424
  it "datetimeoffset" do
425
- skip "datetimeoffset not supported in this protocol version" unless connection_dblib_73?
425
+ skip "datetimeoffset not supported in this protocol version" unless connection_tds_73
426
426
  col = column("datetimeoffset_7")
427
427
  _(col.sql_type).must_equal "datetimeoffset(7)"
428
428
  _(col.type).must_equal :datetimeoffset
@@ -488,7 +488,7 @@ class ColumnTestSQLServer < ActiveRecord::TestCase
488
488
  end
489
489
 
490
490
  it "time(7)" do
491
- skip "time() not supported in this protocol version" unless connection_dblib_73?
491
+ skip "time() not supported in this protocol version" unless connection_tds_73
492
492
  col = column("time_7")
493
493
  _(col.sql_type).must_equal "time(7)"
494
494
  _(col.type).must_equal :time
@@ -520,7 +520,7 @@ class ColumnTestSQLServer < ActiveRecord::TestCase
520
520
  end
521
521
 
522
522
  it "time(2)" do
523
- skip "time() not supported in this protocol version" unless connection_dblib_73?
523
+ skip "time() not supported in this protocol version" unless connection_tds_73
524
524
  col = column("time_2")
525
525
  _(col.sql_type).must_equal "time(2)"
526
526
  _(col.type).must_equal :time
@@ -550,7 +550,7 @@ class ColumnTestSQLServer < ActiveRecord::TestCase
550
550
  end
551
551
 
552
552
  it "time using default precision" do
553
- skip "time() not supported in this protocol version" unless connection_dblib_73?
553
+ skip "time() not supported in this protocol version" unless connection_tds_73
554
554
  col = column("time_default")
555
555
  _(col.sql_type).must_equal "time(7)"
556
556
  _(col.type).must_equal :time
@@ -44,9 +44,9 @@ class ConnectionTestSQLServer < ActiveRecord::TestCase
44
44
  assert connection.spid.nil?
45
45
  end
46
46
 
47
- it "reset the connection" do
47
+ it "reset raw connection on disconnect!" do
48
48
  connection.disconnect!
49
- _(connection.raw_connection).must_be_nil
49
+ _(connection.instance_variable_get(:@raw_connection)).must_be_nil
50
50
  end
51
51
 
52
52
  it "be able to disconnect and reconnect at will" do
@@ -60,9 +60,6 @@ class ConnectionTestSQLServer < ActiveRecord::TestCase
60
60
  private
61
61
 
62
62
  def disconnect_raw_connection!
63
- case connection_options[:mode]
64
- when :dblib
65
- connection.raw_connection.close rescue nil
66
- end
63
+ connection.raw_connection.close rescue nil
67
64
  end
68
65
  end
@@ -5,6 +5,7 @@ require "cases/helper_sqlserver"
5
5
  class TestDisconnectedAdapter < ActiveRecord::TestCase
6
6
  self.use_transactional_tests = false
7
7
 
8
+ undef_method :setup
8
9
  def setup
9
10
  @connection = ActiveRecord::Base.connection
10
11
  end
@@ -15,15 +16,13 @@ class TestDisconnectedAdapter < ActiveRecord::TestCase
15
16
  ActiveRecord::Base.establish_connection(db_config)
16
17
  end
17
18
 
18
- test "can't execute procedures while disconnected" do
19
+ test "execute procedure after disconnect reconnects" do
19
20
  @connection.execute_procedure :sp_tables, "sst_datatypes"
20
21
  @connection.disconnect!
21
- assert_raises(ActiveRecord::ConnectionNotEstablished, 'SQL Server client is not connected') do
22
- @connection.execute_procedure :sp_tables, "sst_datatypes"
23
- end
22
+ @connection.execute_procedure :sp_tables, "sst_datatypes"
24
23
  end
25
24
 
26
- test "can't execute query while disconnected" do
25
+ test "execute query after disconnect reconnects" do
27
26
  sql = "SELECT count(*) from products WHERE id IN(@0, @1)"
28
27
  binds = [
29
28
  ActiveRecord::Relation::QueryAttribute.new("id", 2, ActiveRecord::Type::BigInteger.new),
@@ -32,8 +31,6 @@ class TestDisconnectedAdapter < ActiveRecord::TestCase
32
31
 
33
32
  @connection.exec_query sql, "TEST", binds
34
33
  @connection.disconnect!
35
- assert_raises(ActiveRecord::ConnectionNotEstablished, 'SQL Server client is not connected') do
36
- @connection.exec_query sql, "TEST", binds
37
- end
34
+ @connection.exec_query sql, "TEST", binds
38
35
  end
39
36
  end
@@ -43,7 +43,7 @@ class ExecuteProcedureTestSQLServer < ActiveRecord::TestCase
43
43
  end
44
44
 
45
45
  it 'test deprecation with transaction return when executing procedure' do
46
- assert_deprecated do
46
+ assert_deprecated(ActiveRecord.deprecator) do
47
47
  ActiveRecord::Base.transaction do
48
48
  connection.execute_procedure("my_getutcdate")
49
49
  return
@@ -177,7 +177,7 @@ class SQLServerRakeSchemaCacheDumpLoadTest < SQLServerRakeTest
177
177
  quietly { db_tasks.dump_schema_cache connection, filename }
178
178
 
179
179
  filedata = File.read(filename)
180
- schema_cache = YAML.respond_to?(:unsafe_load) ? YAML.unsafe_load(filedata) : YAML.load(filedata)
180
+ _schema_cache = YAML.respond_to?(:unsafe_load) ? YAML.unsafe_load(filedata) : YAML.load(filedata)
181
181
 
182
182
  col_id, col_name = connection.schema_cache.columns("users")
183
183
 
@@ -27,13 +27,13 @@ class SchemaDumperTestSQLServer < ActiveRecord::TestCase
27
27
  # Date and Time
28
28
  assert_line :date, type: "date", default: "01-01-0001"
29
29
  assert_line :datetime, type: "datetime", precision: nil, default: "01-01-1753 00:00:00.123"
30
- if connection_dblib_73?
30
+ if connection_tds_73
31
31
  assert_line :datetime2_7, type: "datetime", precision: 7, default: "12-31-9999 23:59:59.9999999"
32
32
  assert_line :datetime2_3, type: "datetime", precision: 3
33
33
  assert_line :datetime2_1, type: "datetime", precision: 1
34
34
  end
35
35
  assert_line :smalldatetime, type: "smalldatetime", default: "01-01-1901 15:45:00.0"
36
- if connection_dblib_73?
36
+ if connection_tds_73
37
37
  assert_line :time_7, type: "time", precision: 7, default: "04:20:00.2883215"
38
38
  assert_line :time_2, type: "time", precision: 2
39
39
  assert_line :time_default, type: "time", precision: 7, default: "15:03:42.0621978"
@@ -42,6 +42,9 @@ class TransactionTestSQLServer < ActiveRecord::TestCase
42
42
  after_level = connection.user_options_isolation_level
43
43
  _(in_level).must_match %r{serializable}i
44
44
  _(after_level).must_match %r{read committed}i
45
+ ensure
46
+ # Reset all connections. Otherwise, the next test may fail with error 'DBPROCESS is dead or not enabled'. Not sure why.
47
+ ActiveRecord::Base.connection_handler.clear_all_connections!(:all)
45
48
  end
46
49
 
47
50
  it "can use an isolation level and reverts back to starting isolation level under exceptions" do
@@ -50,20 +53,16 @@ class TransactionTestSQLServer < ActiveRecord::TestCase
50
53
  Ship.transaction(isolation: :serializable) { Ship.create! }
51
54
  }).must_raise(ActiveRecord::RecordInvalid)
52
55
  _(connection.user_options_isolation_level).must_match %r{read committed}i
56
+ ensure
57
+ # Reset all connections. Otherwise, the next test may fail with error 'DBPROCESS is dead or not enabled'. Not sure why.
58
+ ActiveRecord::Base.connection_handler.clear_all_connections!(:all)
53
59
  end
54
60
 
55
61
  describe "when READ_COMMITTED_SNAPSHOT is set" do
56
- before do
62
+ it "should use READ COMMITTED as an isolation level" do
57
63
  connection.execute "ALTER DATABASE [#{connection.current_database}] SET ALLOW_SNAPSHOT_ISOLATION ON"
58
64
  connection.execute "ALTER DATABASE [#{connection.current_database}] SET READ_COMMITTED_SNAPSHOT ON WITH ROLLBACK IMMEDIATE"
59
- end
60
-
61
- after do
62
- connection.execute "ALTER DATABASE [#{connection.current_database}] SET ALLOW_SNAPSHOT_ISOLATION OFF"
63
- connection.execute "ALTER DATABASE [#{connection.current_database}] SET READ_COMMITTED_SNAPSHOT OFF WITH ROLLBACK IMMEDIATE"
64
- end
65
65
 
66
- it "should use READ COMMITTED as an isolation level" do
67
66
  _(connection.user_options_isolation_level).must_match "read committed snapshot"
68
67
 
69
68
  Ship.transaction(isolation: :serializable) do
@@ -74,6 +73,12 @@ class TransactionTestSQLServer < ActiveRecord::TestCase
74
73
  # "READ COMMITTED", and that no exception was raised (it's reported back
75
74
  # by SQL Server as "read committed snapshot").
76
75
  _(connection.user_options_isolation_level).must_match "read committed snapshot"
76
+ ensure
77
+ connection.execute "ALTER DATABASE [#{connection.current_database}] SET ALLOW_SNAPSHOT_ISOLATION OFF"
78
+ connection.execute "ALTER DATABASE [#{connection.current_database}] SET READ_COMMITTED_SNAPSHOT OFF WITH ROLLBACK IMMEDIATE"
79
+
80
+ # Reset all connections. Otherwise, the next test may fail with error 'DBPROCESS is dead or not enabled'. Not sure why.
81
+ ActiveRecord::Base.connection_handler.clear_all_connections!(:all)
77
82
  end
78
83
  end
79
84
 
data/test/config.yml CHANGED
@@ -1,7 +1,6 @@
1
1
 
2
2
  default_connection_info: &default_connection_info
3
3
  adapter: sqlserver
4
- mode: <%= ENV['ARCONN'] || 'dblib' %>
5
4
  host: <%= ENV['ACTIVERECORD_UNITTEST_HOST'] || 'localhost' %>
6
5
  port: <%= ENV['ACTIVERECORD_UNITTEST_PORT'] %>
7
6
  database: activerecord_unittest
@@ -12,7 +11,7 @@ default_connection_info: &default_connection_info
12
11
 
13
12
  connections:
14
13
 
15
- dblib:
14
+ sqlserver:
16
15
  arunit:
17
16
  <<: *default_connection_info
18
17
  appname: SQLServerAdptrUnit
@@ -12,16 +12,10 @@ module ARTest
12
12
  end
13
13
 
14
14
  def connection_options
15
- connection.instance_variable_get :@connection_options
15
+ connection.instance_variable_get :@connection_parameters
16
16
  end
17
17
 
18
- def connection_dblib?
19
- connection_options[:mode] == :dblib
20
- end
21
-
22
- def connection_dblib_73?
23
- return false unless connection_dblib?
24
-
18
+ def connection_tds_73
25
19
  rc = connection.raw_connection
26
20
  rc.respond_to?(:tds_73?) && rc.tds_73?
27
21
  end
@@ -22,7 +22,13 @@ module SqlIgnoredCache
22
22
  # compromising cache outside tests.
23
23
  def cache_sql(sql, name, binds)
24
24
  result = super
25
- @query_cache.delete_if { |k, v| k =~ Regexp.union(IGNORED_SQL) }
25
+
26
+ @query_cache.delete_if do |cache_key, _v|
27
+ # Query cache key generated by `sql` or `[sql, binds]`, so need to retrieve `sql` for both cases.
28
+ cache_key_sql = Array(cache_key).first
29
+ Regexp.union(IGNORED_SQL).match?(cache_key_sql)
30
+ end
31
+
26
32
  result
27
33
  end
28
34
  end
@@ -10,20 +10,5 @@ module ARTest
10
10
  ActiveRecord::SQLCounter.log.dup
11
11
  end
12
12
  end
13
-
14
- # TODO: Delete the code below after all Rails 6.1 tests passing.
15
- #
16
- # ignored_sql = [
17
- # /INFORMATION_SCHEMA\.(TABLES|VIEWS|COLUMNS|KEY_COLUMN_USAGE)/im,
18
- # /sys.columns/i,
19
- # /SELECT @@version/,
20
- # /SELECT @@TRANCOUNT/,
21
- # /(BEGIN|COMMIT|ROLLBACK|SAVE) TRANSACTION/,
22
- # /SELECT CAST\(.* AS .*\) AS value/,
23
- # /SELECT DATABASEPROPERTYEX/im
24
- # ]
25
- #
26
- # sqlcounter = ObjectSpace.each_object(ActiveRecord::SQLCounter).to_a.first
27
- # sqlcounter.instance_variable_set :@ignore, Regexp.union(ignored_sql.push(sqlcounter.ignore))
28
13
  end
29
14
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerecord-sqlserver-adapter
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.0.5.1
4
+ version: 7.1.0.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ken Collins
@@ -15,7 +15,7 @@ authors:
15
15
  autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
- date: 2023-11-08 00:00:00.000000000 Z
18
+ date: 2023-11-09 00:00:00.000000000 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: activerecord
@@ -23,14 +23,14 @@ dependencies:
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 7.0.0
26
+ version: 7.1.1
27
27
  type: :runtime
28
28
  prerelease: false
29
29
  version_requirements: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 7.0.0
33
+ version: 7.1.1
34
34
  - !ruby/object:Gem::Dependency
35
35
  name: tiny_tds
36
36
  requirement: !ruby/object:Gem::Requirement
@@ -72,6 +72,7 @@ files:
72
72
  - appveyor.yml
73
73
  - docker-compose.ci.yml
74
74
  - guides/RELEASING.md
75
+ - lib/active_record/connection_adapters/sqlserver/core_ext/abstract_adapter.rb
75
76
  - lib/active_record/connection_adapters/sqlserver/core_ext/active_record.rb
76
77
  - lib/active_record/connection_adapters/sqlserver/core_ext/attribute_methods.rb
77
78
  - lib/active_record/connection_adapters/sqlserver/core_ext/calculations.rb
@@ -84,6 +85,7 @@ files:
84
85
  - lib/active_record/connection_adapters/sqlserver/database_tasks.rb
85
86
  - lib/active_record/connection_adapters/sqlserver/errors.rb
86
87
  - lib/active_record/connection_adapters/sqlserver/quoting.rb
88
+ - lib/active_record/connection_adapters/sqlserver/savepoints.rb
87
89
  - lib/active_record/connection_adapters/sqlserver/schema_creation.rb
88
90
  - lib/active_record/connection_adapters/sqlserver/schema_dumper.rb
89
91
  - lib/active_record/connection_adapters/sqlserver/schema_statements.rb
@@ -221,6 +223,8 @@ files:
221
223
  - test/support/load_schema_sqlserver.rb
222
224
  - test/support/marshal_compatibility_fixtures/SQLServer/rails_6_1_topic.dump
223
225
  - test/support/marshal_compatibility_fixtures/SQLServer/rails_6_1_topic_associations.dump
226
+ - test/support/marshal_compatibility_fixtures/SQLServer/rails_7_1_topic.dump
227
+ - test/support/marshal_compatibility_fixtures/SQLServer/rails_7_1_topic_associations.dump
224
228
  - test/support/minitest_sqlserver.rb
225
229
  - test/support/paths_sqlserver.rb
226
230
  - test/support/rake_helpers.rb
@@ -231,8 +235,8 @@ licenses:
231
235
  - MIT
232
236
  metadata:
233
237
  bug_tracker_uri: https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/issues
234
- changelog_uri: https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/blob/v7.0.5.1/CHANGELOG.md
235
- source_code_uri: https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/v7.0.5.1
238
+ changelog_uri: https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/blob/v7.1.0.rc1/CHANGELOG.md
239
+ source_code_uri: https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/v7.1.0.rc1
236
240
  post_install_message:
237
241
  rdoc_options: []
238
242
  require_paths:
@@ -244,9 +248,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
244
248
  version: 2.7.0
245
249
  required_rubygems_version: !ruby/object:Gem::Requirement
246
250
  requirements:
247
- - - ">="
251
+ - - ">"
248
252
  - !ruby/object:Gem::Version
249
- version: '0'
253
+ version: 1.3.1
250
254
  requirements: []
251
255
  rubygems_version: 3.4.7
252
256
  signing_key:
@@ -336,6 +340,8 @@ test_files:
336
340
  - test/support/load_schema_sqlserver.rb
337
341
  - test/support/marshal_compatibility_fixtures/SQLServer/rails_6_1_topic.dump
338
342
  - test/support/marshal_compatibility_fixtures/SQLServer/rails_6_1_topic_associations.dump
343
+ - test/support/marshal_compatibility_fixtures/SQLServer/rails_7_1_topic.dump
344
+ - test/support/marshal_compatibility_fixtures/SQLServer/rails_7_1_topic_associations.dump
339
345
  - test/support/minitest_sqlserver.rb
340
346
  - test/support/paths_sqlserver.rb
341
347
  - test/support/rake_helpers.rb