activerecord-sqlserver-adapter 7.0.0.0 → 7.0.1.0

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: da2be1cf7b3b5d8c8ad40cb1c79e037d5054cdf522e8e98b53fd22185af10a24
4
- data.tar.gz: 9d1da7dc2e59761988098939f3254979df4862f26a7edcb617d7a35ff720155d
3
+ metadata.gz: 9b2be5773d5cd15b49d3e11adcb9f464730316716e28823ed517b21f4bcff205
4
+ data.tar.gz: 69588165e5c5fb13f262c3aab89a43fb33da26c0c4688fc4d26bbc1e754c1341
5
5
  SHA512:
6
- metadata.gz: 51b6f8a1d55f2e27dd0301ee9b65a2922c7120b20db3831a774c33acd3b736035f6a6238c26a3491c817ebe808ccd8719eabfd957766a2064c8368ad2c6cd2ee
7
- data.tar.gz: dc7b43ee4d532e44f1106064d3757ea3dd636ecc0bc5cec64d58a5c4de3e4b6bf5ce4017ad9bf6ee8c5a4503627b345e2b83811b71318765f5c4072c5e327456
6
+ metadata.gz: e3dcbc98ce8064c3e44ccab64c197ef9aeb3ce2e34c0f1829eabf5d16157a984d4f2f151b2ea69586ce1247b55363c6a210ca14c3cd8952151e52ce9ee7dff09
7
+ data.tar.gz: 8ac25a4fc712a546b395e30c38936a98350b97826f8868ad2d8e4d378efe0065730619248da93991ba08dbb283303c9ccbeb7e5a5d0492fc5252b97395eb66cb
data/CHANGELOG.md CHANGED
@@ -1,3 +1,18 @@
1
+ ## v7.0.1.0
2
+
3
+ [Full changelog](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/compare/v7.0.0.0...v7.0.1.0)
4
+
5
+ #### Fixed
6
+
7
+ - [#1029](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1029) Handle views defined in other databases.
8
+ - [#1033](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1033) Support proc default values in ruby 3.2.
9
+ - [#1020](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1020) Support using adapter as a stand-alone gem.
10
+ - [#1039](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1039) Fix hook method that allows custom connection configuration.
11
+
12
+ #### Changed
13
+
14
+ - [#1021](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1021) Freeze the SQL sent to instrumentation.
15
+
1
16
  ## v7.0.0.0
2
17
 
3
18
  [Full changelog](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/compare/v7.0.0.0.rc1...v7.0.0.0)
data/Gemfile CHANGED
@@ -11,6 +11,7 @@ gem "pg", ">= 0.18.0"
11
11
  gem "sqlite3", "~> 1.4"
12
12
  gem "tzinfo-data", platforms: [:mingw, :mswin, :x64_mingw, :jruby]
13
13
  gem "benchmark-ips"
14
+ gem "minitest", ">= 5.15.0", "< 5.16"
14
15
 
15
16
  if ENV["RAILS_SOURCE"]
16
17
  gemspec path: ENV["RAILS_SOURCE"]
data/README.md CHANGED
@@ -12,8 +12,8 @@ The SQL Server adapter for ActiveRecord using SQL Server 2012 or higher.
12
12
  Interested in older versions? We follow a rational versioning policy that tracks Rails. That means that our 7.x version of the adapter is only for the latest 7.x version of Rails. If you need the adapter for SQL Server 2008 or 2005, you are still in the right spot. Just install the latest 3.2.x to 4.1.x version of the adapter that matches your Rails version. We also have stable branches for each major/minor release of ActiveRecord.
13
13
 
14
14
  | Adapter Version | Rails Version | Support |
15
- | --------------- | ------------- | ------------------------------------------------------------------------------------------- |
16
- | `7.0.0.0` | `7.0.x` | [active](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/main) |
15
+ |-----------------| ------------- | ------------------------------------------------------------------------------------------- |
16
+ | `7.0.1.0` | `7.0.x` | [active](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/main) |
17
17
  | `6.1.2.1` | `6.1.x` | [active](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/6-1-stable) |
18
18
  | `6.0.2` | `6.0.x` | [active](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/6-0-stable) |
19
19
  | `5.2.1` | `5.2.x` | [ended](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/5-2-stable) |
@@ -25,7 +25,7 @@ For older versions, please check their stable branches.
25
25
 
26
26
  #### Native Data Type Support
27
27
 
28
- We support every data type supported by FreeTDS. All simplified Rails types in migrations will coorespond to a matching SQL Server national (unicode) data type. Always check the `initialize_native_database_types` [(here)](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/blob/master/lib/active_record/connection_adapters/sqlserver/schema_statements.rb) for an updated list.
28
+ We support every data type supported by FreeTDS. All simplified Rails types in migrations will correspond to a matching SQL Server national (unicode) data type. Always check the `initialize_native_database_types` [(here)](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/blob/master/lib/active_record/connection_adapters/sqlserver/schema_statements.rb) for an updated list.
29
29
 
30
30
  The following types (`date`, `datetime2`, `datetimeoffset`, `time`) all require TDS version `7.3` with TinyTDS. We recommend using FreeTDS 1.0 or higher which default to using `TDSVER` to `7.3`. The adapter also sets TinyTDS's `tds_version` to this as well if non is specified.
31
31
 
@@ -85,7 +85,7 @@ end
85
85
 
86
86
  #### Configure Connection
87
87
 
88
- We currently conform to an unpublished and non-standard AbstractAdapter interface to configure connections made to the database. To do so, just override the `configure_connection` method in an initializer like so. In this case below we are setting the `TEXTSIZE` to 64 megabytes.
88
+ We currently conform to an unpublished and non-standard AbstractAdapter interface to configure connections made to the database. To do so, just implement the `configure_connection` method in an initializer like so. In this case below we are setting the `TEXTSIZE` to 64 megabytes.
89
89
 
90
90
  ```ruby
91
91
  module ActiveRecord
data/VERSION CHANGED
@@ -1 +1 @@
1
- 7.0.0.0
1
+ 7.0.1.0
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "active_support/core_ext/kernel/reporting"
4
+
3
5
  ActiveSupport.on_load(:active_record) do
4
6
  silence_warnings do
5
7
  # Already defined in Rails
@@ -360,7 +360,7 @@ module ActiveRecord
360
360
  sql = "EXEC sp_executesql #{quote(sql)}"
361
361
  sql += ", #{types}, #{params}" unless params.empty?
362
362
  end
363
- sql
363
+ sql.freeze
364
364
  end
365
365
 
366
366
  def raw_connection_do(sql)
@@ -39,7 +39,7 @@ module ActiveRecord
39
39
 
40
40
  def quote_default_expression(value, column)
41
41
  cast_type = lookup_cast_type(column.sql_type)
42
- if cast_type.type == :uuid && value =~ /\(\)/
42
+ if cast_type.type == :uuid && value.is_a?(String) && value.include?('()')
43
43
  value
44
44
  else
45
45
  super
@@ -580,7 +580,8 @@ module ActiveRecord
580
580
  @view_information ||= {}
581
581
  @view_information[table_name] ||= begin
582
582
  identifier = SQLServer::Utils.extract_identifiers(table_name)
583
- view_info = select_one "SELECT * FROM INFORMATION_SCHEMA.VIEWS WITH (NOLOCK) WHERE TABLE_NAME = #{quote(identifier.object)}", "SCHEMA"
583
+ information_query_table = identifier.database.present? ? "[#{identifier.database}].[INFORMATION_SCHEMA].[VIEWS]" : "[INFORMATION_SCHEMA].[VIEWS]"
584
+ view_info = select_one "SELECT * FROM #{information_query_table} WITH (NOLOCK) WHERE TABLE_NAME = #{quote(identifier.object)}", "SCHEMA"
584
585
  if view_info
585
586
  view_info = view_info.with_indifferent_access
586
587
  if view_info[:VIEW_DEFINITION].blank? || view_info[:VIEW_DEFINITION].length == 4000
@@ -59,6 +59,23 @@ module ActiveRecord
59
59
  self.exclude_output_inserted_table_names = Concurrent::Map.new { false }
60
60
 
61
61
  class << self
62
+ def dbconsole(config, options = {})
63
+ sqlserver_config = config.configuration_hash
64
+ args = []
65
+
66
+ args += ["-d", "#{config.database}"] if config.database
67
+ args += ["-U", "#{sqlserver_config[:username]}"] if sqlserver_config[:username]
68
+ args += ["-P", "#{sqlserver_config[:password]}"] if sqlserver_config[:password]
69
+
70
+ if sqlserver_config[:host]
71
+ host_arg = +"tcp:#{sqlserver_config[:host]}"
72
+ host_arg << ",#{sqlserver_config[:port]}" if sqlserver_config[:port]
73
+ args += ["-S", host_arg]
74
+ end
75
+
76
+ find_cmd_and_exec("sqlcmd", *args)
77
+ end
78
+
62
79
  def new_client(config)
63
80
  case config[:mode]
64
81
  when :dblib
@@ -140,7 +157,7 @@ module ActiveRecord
140
157
  def initialize(connection, logger, _connection_options, config)
141
158
  super(connection, logger, config)
142
159
  @connection_options = config
143
- configure_connection
160
+ perform_connection_configuration
144
161
  end
145
162
 
146
163
  # === Abstract Adapter ========================================== #
@@ -301,14 +318,6 @@ module ActiveRecord
301
318
  do_execute "IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION"
302
319
  end
303
320
 
304
- def configure_connection
305
- @spid = _raw_select("SELECT @@SPID", fetch: :rows).first.first
306
- @version_year = version_year
307
-
308
- initialize_dateformatter
309
- use_database
310
- end
311
-
312
321
  # === Abstract Adapter (Misc Support) =========================== #
313
322
 
314
323
  def tables_with_referential_integrity
@@ -540,7 +549,20 @@ module ActiveRecord
540
549
 
541
550
  def connect
542
551
  @connection = self.class.new_client(@connection_options)
543
- configure_connection
552
+ perform_connection_configuration
553
+ end
554
+
555
+ def perform_connection_configuration
556
+ configure_connection_defaults
557
+ configure_connection if self.respond_to?(:configure_connection)
558
+ end
559
+
560
+ def configure_connection_defaults
561
+ @spid = _raw_select("SELECT @@SPID", fetch: :rows).first.first
562
+ @version_year = version_year
563
+
564
+ initialize_dateformatter
565
+ use_database
544
566
  end
545
567
  end
546
568
  end
@@ -2,13 +2,17 @@
2
2
 
3
3
  module ActiveRecord
4
4
  module ConnectionHandling
5
+ def sqlserver_adapter_class
6
+ ConnectionAdapters::SQLServerAdapter
7
+ end
8
+
5
9
  def sqlserver_connection(config) #:nodoc:
6
10
  config = config.symbolize_keys
7
11
  config.reverse_merge!(mode: :dblib)
8
12
  config[:mode] = config[:mode].to_s.downcase.underscore.to_sym
9
13
 
10
- ConnectionAdapters::SQLServerAdapter.new(
11
- ConnectionAdapters::SQLServerAdapter.new_client(config),
14
+ sqlserver_adapter_class.new(
15
+ sqlserver_adapter_class.new_client(config),
12
16
  logger,
13
17
  nil,
14
18
  config
@@ -373,11 +373,28 @@ class AdapterTestSQLServer < ActiveRecord::TestCase
373
373
  assert_match(/CREATE VIEW sst_customers_view/, view_info["VIEW_DEFINITION"])
374
374
  end
375
375
 
376
+ it "allows connection#view_information to work with qualified object names" do
377
+ view_info = connection.send(:view_information, "[activerecord_unittest].[dbo].[sst_customers_view]")
378
+ assert_equal("sst_customers_view", view_info["TABLE_NAME"])
379
+ assert_match(/CREATE VIEW sst_customers_view/, view_info["VIEW_DEFINITION"])
380
+ end
381
+
382
+ it "allows connection#view_information to work across databases when using qualified object names" do
383
+ # College is defined in activerecord_unittest2 database.
384
+ view_info = College.connection.send(:view_information, "[activerecord_unittest].[dbo].[sst_customers_view]")
385
+ assert_equal("sst_customers_view", view_info["TABLE_NAME"])
386
+ assert_match(/CREATE VIEW sst_customers_view/, view_info["VIEW_DEFINITION"])
387
+ end
388
+
376
389
  it "allow the connection#view_table_name method to return true table_name for the view" do
377
390
  assert_equal "customers", connection.send(:view_table_name, "sst_customers_view")
378
391
  assert_equal "topics", connection.send(:view_table_name, "topics"), "No view here, the same table name should come back."
379
392
  end
380
393
 
394
+ it "allow the connection#view_table_name method to return true table_name for the view for other connections" do
395
+ assert_equal "customers", College.connection.send(:view_table_name, "[activerecord_unittest].[dbo].[sst_customers_view]")
396
+ assert_equal "topics", College.connection.send(:view_table_name, "topics"), "No view here, the same table name should come back."
397
+ end
381
398
  # With same column names
382
399
 
383
400
  it "have matching column objects" do
@@ -1395,7 +1395,7 @@ class SchemaDumperTest < ActiveRecord::TestCase
1395
1395
  assert_match %r{t.decimal\s+"atoms_in_universe",\s+precision: 38}, output
1396
1396
  end
1397
1397
 
1398
- # This is a poorly written test and really does not catch the bottom'ness it is meant too. Ours throw it off.
1398
+ # This is a poorly written test and really does not catch the bottom'ness it is meant to. Ours throw it off.
1399
1399
  coerce_tests! :test_foreign_keys_are_dumped_at_the_bottom_to_circumvent_dependency_issues
1400
1400
 
1401
1401
  # Fall through false positive with no filter.
@@ -1416,6 +1416,35 @@ end
1416
1416
  class SchemaDumperDefaultsTest < ActiveRecord::TestCase
1417
1417
  # These date formats do not match ours. We got these covered in our dumper tests.
1418
1418
  coerce_tests! :test_schema_dump_defaults_with_universally_supported_types
1419
+
1420
+ # SQL Server uses different method to generate a UUID than Rails test uses. Reimplemented the
1421
+ # test in 'SchemaDumperDefaultsCoerceTest'.
1422
+ coerce_tests! :test_schema_dump_with_text_column
1423
+ end
1424
+
1425
+ class SchemaDumperDefaultsCoerceTest < ActiveRecord::TestCase
1426
+ include SchemaDumpingHelper
1427
+
1428
+ setup do
1429
+ @connection = ActiveRecord::Base.connection
1430
+ @connection.create_table :dump_defaults, force: true do |t|
1431
+ t.string :string_with_default, default: "Hello!"
1432
+ t.date :date_with_default, default: "2014-06-05"
1433
+ t.datetime :datetime_with_default, default: "2014-06-05 07:17:04"
1434
+ t.time :time_with_default, default: "07:17:04"
1435
+ t.decimal :decimal_with_default, default: "1234567890.0123456789", precision: 20, scale: 10
1436
+
1437
+ t.text :text_with_default, default: "John' Doe"
1438
+ t.text :uuid, default: -> { "newid()" }
1439
+ end
1440
+ end
1441
+
1442
+ def test_schema_dump_with_text_column_coerced
1443
+ output = dump_table_schema("dump_defaults")
1444
+
1445
+ assert_match %r{t\.text\s+"text_with_default",.*?default: "John' Doe"}, output
1446
+ assert_match %r{t\.text\s+"uuid",.*?default: -> \{ "newid\(\)" \}}, output
1447
+ end
1419
1448
  end
1420
1449
 
1421
1450
  class TestAdapterWithInvalidConnection < ActiveRecord::TestCase
@@ -2057,6 +2086,17 @@ class FieldOrderedValuesTest < ActiveRecord::TestCase
2057
2086
  Book.connection.add_index(:books, [:author_id, :name], unique: true)
2058
2087
  end
2059
2088
 
2089
+ # Need to remove index as SQL Server considers NULLs on a unique-index to be equal unlike PostgreSQL/MySQL/SQLite.
2090
+ coerce_tests! :test_in_order_of_with_string_column
2091
+ def test_in_order_of_with_string_column_coerced
2092
+ Book.connection.remove_index(:books, column: [:author_id, :name])
2093
+
2094
+ original_test_in_order_of_with_string_column
2095
+ ensure
2096
+ Book.where(author_id: nil, name: nil).delete_all
2097
+ Book.connection.add_index(:books, [:author_id, :name], unique: true)
2098
+ end
2099
+
2060
2100
  # Need to remove index as SQL Server considers NULLs on a unique-index to be equal unlike PostgreSQL/MySQL/SQLite.
2061
2101
  coerce_tests! :test_in_order_of_with_enums_keys
2062
2102
  def test_in_order_of_with_enums_keys_coerced
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ class DbConsole < ActiveRecord::TestCase
4
+ subject { ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter }
5
+
6
+ it "uses sqlplus to connect to database" do
7
+ subject.expects(:find_cmd_and_exec).with("sqlcmd", "-d", "db", "-U", "user", "-P", "secret", "-S", "tcp:localhost,1433")
8
+
9
+ config = make_db_config(adapter: "sqlserver", database: "db", username: "user", password: "secret", host: "localhost", port: 1433)
10
+
11
+ subject.dbconsole(config)
12
+ end
13
+
14
+ private
15
+
16
+ def make_db_config(config)
17
+ ActiveRecord::DatabaseConfigurations::HashConfig.new("test", "primary", config)
18
+ end
19
+ end
@@ -43,4 +43,12 @@ class SQLServerUuidTest < ActiveRecord::TestCase
43
43
  obj = with_use_output_inserted_disabled { SSTestUuid.create!(name: "😢") }
44
44
  _(obj.id).must_be :nil?
45
45
  end
46
+
47
+ it "can add column with proc as default" do
48
+ table_name = SSTestUuid.table_name
49
+ connection.add_column table_name, :thingy, :uuid, null: false, default: -> { "NEWSEQUENTIALID()" }
50
+ SSTestUuid.reset_column_information
51
+ column = SSTestUuid.columns_hash["thingy"]
52
+ _(column.default_function).must_equal "newsequentialid()"
53
+ end
46
54
  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.0.0
4
+ version: 7.0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ken Collins
@@ -11,10 +11,10 @@ authors:
11
11
  - Shawn Balestracci
12
12
  - Joe Rafaniello
13
13
  - Tom Ward
14
- autorequire:
14
+ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
- date: 2022-02-22 00:00:00.000000000 Z
17
+ date: 2023-03-15 00:00:00.000000000 Z
18
18
  dependencies:
19
19
  - !ruby/object:Gem::Dependency
20
20
  name: activerecord
@@ -149,6 +149,7 @@ files:
149
149
  - test/cases/coerced_tests.rb
150
150
  - test/cases/column_test_sqlserver.rb
151
151
  - test/cases/connection_test_sqlserver.rb
152
+ - test/cases/dbconsole.rb
152
153
  - test/cases/disconnected_test_sqlserver.rb
153
154
  - test/cases/eager_load_too_many_ids_test_sqlserver.rb
154
155
  - test/cases/execute_procedure_test_sqlserver.rb
@@ -226,9 +227,9 @@ licenses:
226
227
  - MIT
227
228
  metadata:
228
229
  bug_tracker_uri: https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/issues
229
- changelog_uri: https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/blob/v7.0.0.0/CHANGELOG.md
230
- source_code_uri: https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/v7.0.0.0
231
- post_install_message:
230
+ changelog_uri: https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/blob/v7.0.1.0/CHANGELOG.md
231
+ source_code_uri: https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/v7.0.1.0
232
+ post_install_message:
232
233
  rdoc_options: []
233
234
  require_paths:
234
235
  - lib
@@ -243,8 +244,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
243
244
  - !ruby/object:Gem::Version
244
245
  version: '0'
245
246
  requirements: []
246
- rubygems_version: 3.2.22
247
- signing_key:
247
+ rubygems_version: 3.2.33
248
+ signing_key:
248
249
  specification_version: 4
249
250
  summary: ActiveRecord SQL Server Adapter.
250
251
  test_files:
@@ -260,6 +261,7 @@ test_files:
260
261
  - test/cases/coerced_tests.rb
261
262
  - test/cases/column_test_sqlserver.rb
262
263
  - test/cases/connection_test_sqlserver.rb
264
+ - test/cases/dbconsole.rb
263
265
  - test/cases/disconnected_test_sqlserver.rb
264
266
  - test/cases/eager_load_too_many_ids_test_sqlserver.rb
265
267
  - test/cases/execute_procedure_test_sqlserver.rb