activerecord-sqlserver-adapter 7.1.0.beta1 → 7.1.0.rc2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '009fdf722e06ca141f900257d1980016e76edc153d5af717d5f15ae6792ea4d4'
4
- data.tar.gz: 292f605553c6bfbfc357efc6c9e26fca3be1414921d8a4b810ccd17ce46f4e88
3
+ metadata.gz: ddd1e2bb81c9a6675d4a8f561c585869b0fafb6ecfe3c513e7e69d8bc3646d9f
4
+ data.tar.gz: 0d669eaaa14be843acc19cc887c47a3f8eecfb3552e8477a062df688d9ef1172
5
5
  SHA512:
6
- metadata.gz: a2c2363f6445554a6067f15ca1467130dfe4499513746e2a1d374c2e27635d68f0eb5c1682cc49621c101c31531723f66c5670e1d73d89b798cb6eda90d52f39
7
- data.tar.gz: a788af6fbd28c02f0ab1e9d6283f4a11934f9bb702d93a7428d0d1e37aed4cb9e72f9fba4f4e21c18057b789204a9bfd0cc353b988f1751c8e65689ec8b4b686
6
+ metadata.gz: 879aeb90caaef5bb0218651407ec5a978d4a62d51682e92d55fbda2d3eed2fd37e8348e72aa8c4c92cab856c8eebc2fa4bf1c2166ad13d99c983f1310d3b66ab
7
+ data.tar.gz: 15030862f3ae2044dd780a62f4a8868dc383cd6e9775fcedff214b1429bdbf2881be503e670cf2cbcfcbe92c0583c2a89d53f30ddd988a5425649ff29ef2c971
data/CHANGELOG.md CHANGED
@@ -1,9 +1,51 @@
1
- ## v7.1.0.beta1
1
+ ## v7.1.0.rc2
2
2
 
3
- #### Changed
3
+ #### Added
4
+
5
+ - [#1136](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1136) Prevent marking broken connections as verified
6
+ - [#1138](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1138) Cache quoted names
4
7
 
5
- #### Fixed
8
+ ## v7.1.0.rc1
6
9
 
7
10
  #### Added
8
11
 
12
+ * Rails 7.1 Support
13
+
14
+ The adapter supports new Rails 7.1 features such as composite primary keys. See the
15
+ [Rails 7.1 release notes](https://guides.rubyonrails.org/7_1_release_notes.html) for more information.
16
+
17
+ #### Changed
18
+
19
+ * Configure Connection
20
+
21
+ If you require additional connection configuration you now need to call `super` within the `configure_connection`
22
+ method so that the default configuration is also applied.
23
+
24
+ v7.1.x adapter:
25
+ ```ruby
26
+ module ActiveRecord
27
+ module ConnectionAdapters
28
+ class SQLServerAdapter < AbstractAdapter
29
+ def configure_connection
30
+ super
31
+ raw_connection_do "SET TEXTSIZE #{64.megabytes}"
32
+ end
33
+ end
34
+ end
35
+ end
36
+ ```
37
+
38
+ v7.0.x adapter:
39
+ ```ruby
40
+ module ActiveRecord
41
+ module ConnectionAdapters
42
+ class SQLServerAdapter < AbstractAdapter
43
+ def configure_connection
44
+ raw_connection_do "SET TEXTSIZE #{64.megabytes}"
45
+ end
46
+ end
47
+ end
48
+ end
49
+ ```
50
+
9
51
  Please check [7-0-stable](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/blob/7-0-stable/CHANGELOG.md) for previous changes.
data/README.md CHANGED
@@ -13,10 +13,10 @@ Interested in older versions? We follow a rational versioning policy that tracks
13
13
 
14
14
  | Adapter Version | Rails Version | Support | Branch |
15
15
  |-----------------|---------------|----------------|-------------------------------------------------------------------------------------------------|
16
- | `v7.1.0.beta1` | `7.1.0` | In development | [main](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/main) |
17
- | `7.0.4.0` | `7.0.x` | Active | [7-0-stable](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/7-0-stable) |
18
- | `6.1.2.1` | `6.1.x` | Active | [6-1-stable](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/6-1-stable) |
19
- | `6.0.3` | `6.0.x` | Active | [6-0-stable](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/6-0-stable) |
16
+ | `7.1.0.rc2` | `7.1.x` | In development | [main](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/main) |
17
+ | `7.0.5.1` | `7.0.x` | Active | [7-0-stable](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/7-0-stable) |
18
+ | `6.1.3.0` | `6.1.x` | Active | [6-1-stable](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/6-1-stable) |
19
+ | `6.0.3` | `6.0.x` | Ended | [6-0-stable](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/6-0-stable) |
20
20
  | `5.2.1` | `5.2.x` | Ended | [5-2-stable](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/5-2-stable) |
21
21
  | `5.1.6` | `5.1.x` | Ended | [5-1-stable](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/5-1-stable) |
22
22
  | `4.2.18` | `4.2.x` | Ended | [4-2-stable](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/4-2-stable) |
@@ -13,12 +13,12 @@ Default testing uses DBLIB with TinyTDS.
13
13
 
14
14
  * Setup two databases in SQL Server, [activerecord_unittest] and [activerecord_unittest2]
15
15
  * Create a [rails] user with an empty password and give it a [db_owner] role to both DBs. Some tests require a server role of [sysadmin] too. More details below with DDL SQL examples.
16
- * $ bundle install
17
- * $ bundle exec rake test ACTIVERECORD_UNITTEST_HOST='my.db.net'
16
+ * `bundle install`
17
+ * `bundle exec rake test ACTIVERECORD_UNITTEST_HOST='my.db.net'`
18
18
 
19
19
  Focusing tests. Use the `ONLY_` env vars to run either ours or the ActiveRecord cases. Use the `TEST_FILES` env variants to focus on specific test(s), use commas for multiple cases. Note, you have to use different env vars to focus only on ours or a core ActiveRecord case. There may be failures when focusing on an ActiveRecord case since our coereced test files is not loaded in this scenerio.
20
20
 
21
- ```
21
+ ```console
22
22
  $ bundle exec rake test ONLY_SQLSERVER=1
23
23
  $ bundle exec rake test ONLY_ACTIVERECORD=1
24
24
 
@@ -49,13 +49,13 @@ GO
49
49
 
50
50
  The tests of this adapter depend on the existence of the Rails which are automatically cloned for you with bundler. However you can clone Rails from git://github.com/rails/rails.git and set the `RAILS_SOURCE` environment variable so bundler will use another local path instead.
51
51
 
52
- ```
52
+ ```console
53
53
  $ git clone git://github.com/rails-sqlserver/activerecord-sqlserver-adapter.git
54
54
  ```
55
55
 
56
56
  Suggest just letting bundler do all the work and assuming there is a git tag for the Rails version, you can set `RAILS_VERSION` before bundling.
57
57
 
58
- ```
58
+ ```console
59
59
  $ export RAILS_VERSION='4.2.0'
60
60
  $ bundle install
61
61
  ```
@@ -65,20 +65,20 @@ $ bundle install
65
65
 
66
66
  Please consult the `test/config.yml` file which is used to parse the configuration options for the DB connections when running tests. This file has overrides for any connection mode that you can set using simple environment variables. Assuming you are using FreeTDS 0.91 and above
67
67
 
68
- ```
68
+ ```console
69
69
  $ export ACTIVERECORD_UNITTEST_HOST='my.db.net' # Defaults to localhost
70
70
  $ export ACTIVERECORD_UNITTEST_PORT='1533' # Defaults to 1433
71
71
  ```
72
72
 
73
73
  If you have FreeTDS installed and/or want to use a named dataserver in your freetds.conf file
74
74
 
75
- ```
75
+ ```console
76
76
  $ export ACTIVERECORD_UNITTEST_DATASERVER='mydbname'
77
77
  ```
78
78
 
79
79
  These can be passed down to rake too.
80
80
 
81
- ```
81
+ ```console
82
82
  $ bundle exec rake test ACTIVERECORD_UNITTEST_HOST='my.db.net'
83
83
  ```
84
84
 
@@ -87,16 +87,30 @@ $ bundle exec rake test ACTIVERECORD_UNITTEST_HOST='my.db.net'
87
87
 
88
88
  Now with that out of the way you can run "bundle install" to hook everything up. Our tests use bundler to setup the load paths correctly. The default mode is DBLIB using TinyTDS. It is important to use bundle exec so we can wire up the ActiveRecord test libs correctly.
89
89
 
90
- ```
90
+ ```console
91
91
  $ bundle exec rake test
92
92
  ```
93
93
 
94
94
 
95
95
  ## Testing Options
96
96
 
97
-
98
97
  By default, Bundler will download the Rails git repo and use the git tag that matches the dependency version in our gemspec. If you want to test another version of Rails, you can either temporarily change the :tag for Rails in the Gemfile. Likewise, you can clone the Rails repo your self to another directory and use the `RAILS_SOURCE` environment variable.
99
98
 
99
+ ```console
100
+ $ RAILS_SOURCE='/vagrant/rails' bundle exec rake test
101
+ ```
102
+
103
+ If you want to use a specific seed for the tests use the `TESTOPTS` env variable like:
104
+
105
+ ```console
106
+ $ bundle exec rake test TESTOPTS="--seed=45250"
107
+ ```
108
+
109
+ And to make the tests fail-fast use:
110
+
111
+ ```console
112
+ $ bundle exec rake test TESTOPTS="-f"
113
+ ```
100
114
 
101
115
  ## Troubleshooting
102
116
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 7.1.0.beta1
1
+ 7.1.0.rc2
@@ -23,6 +23,7 @@ module ActiveRecord
23
23
  else
24
24
  internal_raw_execute(sql, conn, perform_do: true)
25
25
  end
26
+ verified!
26
27
  end
27
28
  end
28
29
 
@@ -43,28 +44,27 @@ module ActiveRecord
43
44
 
44
45
  log(sql, name, binds, async: async) do
45
46
  with_raw_connection do |conn|
46
- begin
47
- options = { ar_result: true }
48
-
49
- # TODO: Look into refactoring this.
50
- if id_insert_table_name = query_requires_identity_insert?(sql)
51
- with_identity_insert_enabled(id_insert_table_name, conn) do
52
- handle = internal_raw_execute(sql, conn)
53
- result = handle_to_names_and_values(handle, options)
54
- end
55
- else
56
- handle = internal_raw_execute(sql, conn)
57
- result = handle_to_names_and_values(handle, options)
47
+ if id_insert_table_name = query_requires_identity_insert?(sql)
48
+ with_identity_insert_enabled(id_insert_table_name, conn) do
49
+ result = internal_exec_sql_query(sql, conn)
58
50
  end
59
- ensure
60
- finish_statement_handle(handle)
51
+ else
52
+ result = internal_exec_sql_query(sql, conn)
61
53
  end
54
+ verified!
62
55
  end
63
56
  end
64
57
 
65
58
  result
66
59
  end
67
60
 
61
+ def internal_exec_sql_query(sql, conn)
62
+ handle = internal_raw_execute(sql, conn)
63
+ handle_to_names_and_values(handle, ar_result: true)
64
+ ensure
65
+ finish_statement_handle(handle)
66
+ end
67
+
68
68
  def exec_delete(sql, name, binds)
69
69
  sql = sql.dup << "; SELECT @@ROWCOUNT AS AffectedRows"
70
70
  super(sql, name, binds).rows.first.first
@@ -177,6 +177,7 @@ module ActiveRecord
177
177
  log(sql, "Execute Procedure") do
178
178
  with_raw_connection do |conn|
179
179
  result = internal_raw_execute(sql, conn)
180
+ verified!
180
181
  options = { as: :hash, cache_rows: true, timezone: ActiveRecord.default_timezone || :utc }
181
182
 
182
183
  result.each(options) do |row|
@@ -400,10 +401,9 @@ module ActiveRecord
400
401
 
401
402
  # === SQLServer Specific (Selecting) ============================ #
402
403
 
403
- def _raw_select(sql, conn, options = {})
404
+ def _raw_select(sql, conn)
404
405
  handle = internal_raw_execute(sql, conn)
405
-
406
- handle_to_names_and_values(handle, options)
406
+ handle_to_names_and_values(handle, fetch: :rows)
407
407
  ensure
408
408
  finish_statement_handle(handle)
409
409
  end
@@ -4,18 +4,18 @@ module ActiveRecord
4
4
  module ConnectionAdapters
5
5
  module SQLServer
6
6
  module Quoting
7
- QUOTED_TRUE = "1".freeze
8
- QUOTED_FALSE = "0".freeze
9
- QUOTED_STRING_PREFIX = "N".freeze
7
+ QUOTED_COLUMN_NAMES = Concurrent::Map.new # :nodoc:
8
+ QUOTED_TABLE_NAMES = Concurrent::Map.new # :nodoc:
10
9
 
11
10
  def fetch_type_metadata(sql_type, sqlserver_options = {})
12
11
  cast_type = lookup_cast_type(sql_type)
12
+
13
13
  simple_type = SqlTypeMetadata.new(
14
- sql_type: sql_type,
15
- type: cast_type.type,
16
- limit: cast_type.limit,
14
+ sql_type: sql_type,
15
+ type: cast_type.type,
16
+ limit: cast_type.limit,
17
17
  precision: cast_type.precision,
18
- scale: cast_type.scale
18
+ scale: cast_type.scale
19
19
  )
20
20
 
21
21
  SQLServer::TypeMetadata.new(simple_type, **sqlserver_options)
@@ -34,7 +34,11 @@ module ActiveRecord
34
34
  end
35
35
 
36
36
  def quote_column_name(name)
37
- SQLServer::Utils.extract_identifiers(name).quoted
37
+ QUOTED_COLUMN_NAMES[name] ||= SQLServer::Utils.extract_identifiers(name).quoted
38
+ end
39
+
40
+ def quote_table_name(name)
41
+ QUOTED_TABLE_NAMES[name] ||= SQLServer::Utils.extract_identifiers(name).quoted
38
42
  end
39
43
 
40
44
  def quote_default_expression(value, column)
@@ -47,7 +51,7 @@ module ActiveRecord
47
51
  end
48
52
 
49
53
  def quoted_true
50
- QUOTED_TRUE
54
+ '1'
51
55
  end
52
56
 
53
57
  def unquoted_true
@@ -55,7 +59,7 @@ module ActiveRecord
55
59
  end
56
60
 
57
61
  def quoted_false
58
- QUOTED_FALSE
62
+ '0'
59
63
  end
60
64
 
61
65
  def unquoted_false
@@ -117,7 +121,7 @@ module ActiveRecord
117
121
  when ActiveRecord::Type::SQLServer::Data
118
122
  value.quoted
119
123
  when String, ActiveSupport::Multibyte::Chars
120
- "#{QUOTED_STRING_PREFIX}#{super}"
124
+ "N#{super}"
121
125
  else
122
126
  super
123
127
  end
@@ -640,17 +640,19 @@ module ActiveRecord
640
640
  identifier = SQLServer::Utils.extract_identifiers(table_name)
641
641
  information_query_table = identifier.database.present? ? "[#{identifier.database}].[INFORMATION_SCHEMA].[VIEWS]" : "[INFORMATION_SCHEMA].[VIEWS]"
642
642
  view_info = select_one "SELECT * FROM #{information_query_table} WITH (NOLOCK) WHERE TABLE_NAME = #{quote(identifier.object)}", "SCHEMA"
643
+
643
644
  if view_info
644
645
  view_info = view_info.with_indifferent_access
645
646
  if view_info[:VIEW_DEFINITION].blank? || view_info[:VIEW_DEFINITION].length == 4000
646
647
  view_info[:VIEW_DEFINITION] = begin
647
- select_values("EXEC sp_helptext #{identifier.object_quoted}", "SCHEMA").join
648
+ select_values("EXEC sp_helptext #{identifier.object_quoted}", "SCHEMA").join
648
649
  rescue
649
650
  warn "No view definition found, possible permissions problem.\nPlease run GRANT VIEW DEFINITION TO your_user;"
650
651
  nil
651
- end
652
+ end
652
653
  end
653
654
  end
655
+
654
656
  view_info
655
657
  end
656
658
  end
@@ -659,7 +661,8 @@ module ActiveRecord
659
661
  view_definition = view_information(table_name)[:VIEW_DEFINITION]
660
662
  return column_name unless view_definition
661
663
 
662
- match_data = view_definition.match(/CREATE\s+VIEW.*AS\s+SELECT.*\W([\w-]*)\s+AS\s+#{column_name}/im)
664
+ # Remove "CREATE VIEW ... AS SELECT ..." and then match the column name.
665
+ match_data = view_definition.sub(/CREATE\s+VIEW.*AS\s+SELECT\s/, '').match(/([\w-]*)\s+AS\s+#{column_name}\W/im)
663
666
  match_data ? match_data[1] : column_name
664
667
  end
665
668
 
@@ -6,13 +6,9 @@ module ActiveRecord
6
6
  module ConnectionAdapters
7
7
  module SQLServer
8
8
  module Utils
9
- QUOTED_STRING_PREFIX = "N"
10
-
11
9
  # Value object to return identifiers from SQL Server names http://bit.ly/1CZ3EiL
12
10
  # Inspired from Rails PostgreSQL::Name adapter object in their own Utils.
13
- #
14
11
  class Name
15
- SEPARATOR = "."
16
12
  UNQUOTED_SCANNER = /\]?\./
17
13
  QUOTED_SCANNER = /\A\[.*?\]\./
18
14
  QUOTED_CHECKER = /\A\[/
@@ -42,7 +38,7 @@ module ActiveRecord
42
38
  end
43
39
 
44
40
  def fully_qualified_database_quoted
45
- [server_quoted, database_quoted].compact.join(SEPARATOR)
41
+ [server_quoted, database_quoted].compact.join('.')
46
42
  end
47
43
 
48
44
  def fully_qualified?
@@ -69,7 +65,7 @@ module ActiveRecord
69
65
  end
70
66
 
71
67
  def quoted
72
- parts.map { |p| quote(p) if p }.join SEPARATOR
68
+ parts.map { |p| quote(p) if p }.join('.')
73
69
  end
74
70
 
75
71
  def quoted_raw
@@ -132,7 +128,7 @@ module ActiveRecord
132
128
  extend self
133
129
 
134
130
  def quote_string(s)
135
- s.to_s.gsub /\'/, "''"
131
+ s.to_s.gsub(/\'/, "''")
136
132
  end
137
133
 
138
134
  def quote_string_single(s)
@@ -140,7 +136,7 @@ module ActiveRecord
140
136
  end
141
137
 
142
138
  def quote_string_single_national(s)
143
- "#{QUOTED_STRING_PREFIX}'#{quote_string(s)}'"
139
+ "N'#{quote_string(s)}'"
144
140
  end
145
141
 
146
142
  def quoted_raw(name)
@@ -501,7 +501,7 @@ module ActiveRecord
501
501
  end
502
502
 
503
503
  def sqlserver_version
504
- @sqlserver_version ||= _raw_select("SELECT @@version", @raw_connection, fetch: :rows).first.first.to_s
504
+ @sqlserver_version ||= _raw_select("SELECT @@version", @raw_connection).first.first.to_s
505
505
  end
506
506
 
507
507
  private
@@ -526,7 +526,7 @@ module ActiveRecord
526
526
  @raw_connection.execute("SET TEXTSIZE 2147483647").do
527
527
  @raw_connection.execute("SET CONCAT_NULL_YIELDS_NULL ON").do
528
528
 
529
- @spid = _raw_select("SELECT @@SPID", @raw_connection, fetch: :rows).first.first
529
+ @spid = _raw_select("SELECT @@SPID", @raw_connection).first.first
530
530
 
531
531
  initialize_dateformatter
532
532
  use_database
@@ -53,7 +53,7 @@ module ActiveRecord
53
53
  end
54
54
 
55
55
  def clear_active_connections!
56
- ActiveRecord::Base.connection_handler.clear_active_connections!
56
+ ActiveRecord::Base.connection_handler.clear_active_connections!(:all)
57
57
  end
58
58
 
59
59
  def structure_dump(filename, extra_flags)
@@ -64,6 +64,38 @@ module Arel
64
64
  super
65
65
  end
66
66
 
67
+ def visit_Arel_Nodes_HomogeneousIn(o, collector)
68
+ collector.preparable = false
69
+
70
+ visit o.left, collector
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
+ # Monkey-patch start.
81
+ column_name = o.attribute.name
82
+ column_type = o.attribute.relation.type_for_attribute(column_name)
83
+ column_type = column_type.cast_type if column_type.is_a?(ActiveRecord::Encryption::EncryptedAttributeType) # Use cast_type on encrypted attributes. Don't encrypt them again
84
+
85
+ if values.empty?
86
+ collector << @connection.quote(nil)
87
+ elsif @connection.prepared_statements && !column_type.serialized?
88
+ # Add query attribute bindings rather than just values.
89
+ attrs = values.map { |value| ActiveRecord::Relation::QueryAttribute.new(column_name, value, column_type) }
90
+ collector.add_binds(attrs, &bind_block)
91
+ else
92
+ collector.add_binds(values, o.proc_for_binds, &bind_block)
93
+ end
94
+ # Monkey-patch end.
95
+
96
+ collector << ")"
97
+ end
98
+
67
99
  def visit_Arel_Nodes_SelectStatement(o, collector)
68
100
  @select_statement = o
69
101
  distinct_One_As_One_Is_So_Not_Fetch o
@@ -923,34 +923,6 @@ class DefaultScopingTest < ActiveRecord::TestCase
923
923
  coerce_tests! :test_order_in_default_scope_should_not_prevail
924
924
  end
925
925
 
926
- require "models/post"
927
- require "models/subscriber"
928
- class EachTest < ActiveRecord::TestCase
929
- # Quoting in tests does not cope with bracket quoting.
930
- # TODO: Remove coerced test when https://github.com/rails/rails/pull/49269 merged.
931
- coerce_tests! :test_in_batches_no_subqueries_for_whole_tables_batching
932
- def test_in_batches_no_subqueries_for_whole_tables_batching_coerced
933
- c = Post.connection
934
- quoted_posts_id = Regexp.escape(c.quote_table_name("posts.id"))
935
- assert_sql(/DELETE FROM #{Regexp.escape(c.quote_table_name("posts"))} WHERE #{quoted_posts_id} > .+ AND #{quoted_posts_id} <=/i) do
936
- Post.in_batches(of: 2).delete_all
937
- end
938
- end
939
-
940
- # Quoting in tests does not cope with bracket quoting.
941
- # TODO: Remove coerced test when https://github.com/rails/rails/pull/49269 merged.
942
- coerce_tests! :test_in_batches_should_quote_batch_order
943
- def test_in_batches_should_quote_batch_order_coerced
944
- c = Post.connection
945
- assert_sql(/ORDER BY #{Regexp.escape(c.quote_table_name('posts'))}\.#{Regexp.escape(c.quote_column_name('id'))}/) do
946
- Post.in_batches(of: 1) do |relation|
947
- assert_kind_of ActiveRecord::Relation, relation
948
- assert_kind_of Post, relation.first
949
- end
950
- end
951
- end
952
- end
953
-
954
926
  class EagerAssociationTest < ActiveRecord::TestCase
955
927
  # Use LEN() instead of LENGTH() function.
956
928
  coerce_tests! :test_count_with_include
@@ -2293,16 +2265,6 @@ class LogSubscriberTest < ActiveRecord::TestCase
2293
2265
  end
2294
2266
  end
2295
2267
 
2296
- # TODO: Method `reset_column_information` does not exist. Comment out the test for the time being.
2297
- # class ActiveRecordSchemaTest < ActiveRecord::TestCase
2298
- # # Workaround for randomly failing test.
2299
- # coerce_tests! :test_has_primary_key
2300
- # def test_has_primary_key_coerced
2301
- # @schema_migration.reset_column_information
2302
- # original_test_has_primary_key
2303
- # end
2304
- # end
2305
-
2306
2268
  class ReloadModelsTest < ActiveRecord::TestCase
2307
2269
  # Skip test on Windows. The number of arguments passed to `IO.popen` in
2308
2270
  # `activesupport/lib/active_support/testing/isolation.rb` exceeds what Windows can handle.
@@ -2533,37 +2495,6 @@ class InsertAllTest < ActiveRecord::TestCase
2533
2495
  end
2534
2496
  end
2535
2497
 
2536
- class HasOneThroughDisableJoinsAssociationsTest < ActiveRecord::TestCase
2537
- # TODO: Remove coerce after Rails 7.1.0 (see https://github.com/rails/rails/pull/44051)
2538
- coerce_tests! :test_disable_joins_through_with_enum_type
2539
- def test_disable_joins_through_with_enum_type_coerced
2540
- joins = capture_sql { @member.club }
2541
- no_joins = capture_sql { @member.club_without_joins }
2542
-
2543
- assert_equal 1, joins.size
2544
- assert_equal 2, no_joins.size
2545
-
2546
- assert_match(/INNER JOIN/, joins.first)
2547
- no_joins.each do |nj|
2548
- assert_no_match(/INNER JOIN/, nj)
2549
- end
2550
-
2551
- assert_match(/\[memberships\]\.\[type\]/, no_joins.first)
2552
- end
2553
- end
2554
-
2555
- class ActiveRecord::Encryption::EncryptableRecordTest < ActiveRecord::EncryptionTestCase
2556
- # TODO: Remove coerce after Rails 7.1.0 (see https://github.com/rails/rails/pull/44052)
2557
- # Same as original but SQL Server string is varchar(4000), not varchar(255) as other adapters. Produce invalid strings with 4001 characters
2558
- coerce_tests! %r{validate column sizes}
2559
- test "validate column sizes coerced" do
2560
- assert EncryptedAuthor.new(name: "jorge").valid?
2561
- assert_not EncryptedAuthor.new(name: "a" * 4001).valid?
2562
- author = EncryptedAuthor.create(name: "a" * 4001)
2563
- assert_not author.valid?
2564
- end
2565
- end
2566
-
2567
2498
  module ActiveRecord
2568
2499
  class Migration
2569
2500
  class InvalidOptionsTest < ActiveRecord::TestCase
@@ -2654,8 +2585,3 @@ module ActiveRecord
2654
2585
  end
2655
2586
  end
2656
2587
  end
2657
-
2658
- # TODO: Need to uncoerce the 'SerializedAttributeTest' tests before releasing adapter for Rails 7.1
2659
- class SerializedAttributeTest < ActiveRecord::TestCase
2660
- coerce_all_tests!
2661
- end
@@ -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
 
@@ -9,18 +9,20 @@ class ViewTestSQLServer < ActiveRecord::TestCase
9
9
  before do
10
10
  connection.drop_table :view_casing_table rescue nil
11
11
  connection.create_table :view_casing_table, force: true do |t|
12
- t.boolean :Default_Falsey, null: false, default: false
13
- t.boolean :Default_Truthy, null: false, default: true
14
- t.string :default_string, null: false, default: "abc"
12
+ t.boolean :Default_Falsey, null: false, default: false
13
+ t.boolean :Default_Truthy, null: false, default: true
14
+ t.string :default_string_null, null: true, default: nil
15
+ t.string :default_string, null: false, default: "abc"
15
16
  end
16
17
 
17
18
  connection.execute("DROP VIEW IF EXISTS view_casing_table_view;")
18
19
  connection.execute <<-SQL
19
20
  CREATE VIEW view_casing_table_view AS
20
21
  SELECT id AS id,
21
- default_falsey AS falsey,
22
- default_truthy AS truthy,
23
- default_string AS s
22
+ default_falsey AS falsey,
23
+ default_truthy AS truthy,
24
+ default_string_null AS s_null,
25
+ default_string AS s
24
26
  FROM view_casing_table
25
27
  SQL
26
28
  end
@@ -34,12 +36,14 @@ class ViewTestSQLServer < ActiveRecord::TestCase
34
36
  assert_equal false, obj.falsey
35
37
  assert_equal true, obj.truthy
36
38
  assert_equal "abc", obj.s
39
+ assert_nil obj.s_null
37
40
  assert_equal 0, klass.count
38
41
 
39
42
  obj.save!
40
43
  assert_equal false, obj.falsey
41
44
  assert_equal true, obj.truthy
42
45
  assert_equal "abc", obj.s
46
+ assert_nil obj.s_null
43
47
  assert_equal 1, klass.count
44
48
  end
45
49
  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.1.0.beta1
4
+ version: 7.1.0.rc2
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-06 00:00:00.000000000 Z
18
+ date: 2023-11-14 00:00:00.000000000 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: activerecord
@@ -235,8 +235,8 @@ licenses:
235
235
  - MIT
236
236
  metadata:
237
237
  bug_tracker_uri: https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/issues
238
- changelog_uri: https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/blob/v7.1.0.beta1/CHANGELOG.md
239
- source_code_uri: https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/v7.1.0.beta1
238
+ changelog_uri: https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/blob/v7.1.0.rc2/CHANGELOG.md
239
+ source_code_uri: https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/v7.1.0.rc2
240
240
  post_install_message:
241
241
  rdoc_options: []
242
242
  require_paths: