activerecord-sqlserver-adapter 6.1.2.1 → 7.2.4

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 (97) hide show
  1. checksums.yaml +4 -4
  2. data/.devcontainer/Dockerfile +30 -0
  3. data/.devcontainer/boot.sh +22 -0
  4. data/.devcontainer/devcontainer.json +38 -0
  5. data/.devcontainer/docker-compose.yml +42 -0
  6. data/.github/workflows/ci.yml +7 -4
  7. data/.gitignore +3 -1
  8. data/CHANGELOG.md +19 -42
  9. data/Dockerfile.ci +3 -3
  10. data/Gemfile +6 -1
  11. data/MIT-LICENSE +1 -1
  12. data/README.md +113 -27
  13. data/RUNNING_UNIT_TESTS.md +27 -14
  14. data/Rakefile +2 -6
  15. data/VERSION +1 -1
  16. data/activerecord-sqlserver-adapter.gemspec +3 -3
  17. data/appveyor.yml +4 -6
  18. data/docker-compose.ci.yml +2 -1
  19. data/lib/active_record/connection_adapters/sqlserver/core_ext/abstract_adapter.rb +20 -0
  20. data/lib/active_record/connection_adapters/sqlserver/core_ext/attribute_methods.rb +6 -4
  21. data/lib/active_record/connection_adapters/sqlserver/core_ext/calculations.rb +5 -23
  22. data/lib/active_record/connection_adapters/sqlserver/core_ext/explain.rb +10 -7
  23. data/lib/active_record/connection_adapters/sqlserver/core_ext/explain_subscriber.rb +2 -0
  24. data/lib/active_record/connection_adapters/sqlserver/core_ext/finder_methods.rb +12 -2
  25. data/lib/active_record/connection_adapters/sqlserver/core_ext/preloader.rb +24 -16
  26. data/lib/active_record/connection_adapters/sqlserver/database_limits.rb +0 -31
  27. data/lib/active_record/connection_adapters/sqlserver/database_statements.rb +143 -155
  28. data/lib/active_record/connection_adapters/sqlserver/database_tasks.rb +5 -5
  29. data/lib/active_record/connection_adapters/sqlserver/quoting.rb +57 -56
  30. data/lib/active_record/connection_adapters/sqlserver/savepoints.rb +26 -0
  31. data/lib/active_record/connection_adapters/sqlserver/schema_creation.rb +14 -12
  32. data/lib/active_record/connection_adapters/sqlserver/schema_dumper.rb +11 -0
  33. data/lib/active_record/connection_adapters/sqlserver/schema_statements.rb +213 -57
  34. data/lib/active_record/connection_adapters/sqlserver/showplan.rb +3 -3
  35. data/lib/active_record/connection_adapters/sqlserver/table_definition.rb +13 -2
  36. data/lib/active_record/connection_adapters/sqlserver/transaction.rb +4 -6
  37. data/lib/active_record/connection_adapters/sqlserver/type/data.rb +19 -1
  38. data/lib/active_record/connection_adapters/sqlserver/type/date.rb +1 -1
  39. data/lib/active_record/connection_adapters/sqlserver/type/datetime.rb +1 -1
  40. data/lib/active_record/connection_adapters/sqlserver/type/time.rb +1 -1
  41. data/lib/active_record/connection_adapters/sqlserver/utils.rb +21 -10
  42. data/lib/active_record/connection_adapters/sqlserver_adapter.rb +187 -187
  43. data/lib/active_record/connection_adapters/sqlserver_column.rb +1 -0
  44. data/lib/active_record/tasks/sqlserver_database_tasks.rb +42 -33
  45. data/lib/arel/visitors/sqlserver.rb +77 -34
  46. data/test/cases/active_schema_test_sqlserver.rb +127 -0
  47. data/test/cases/adapter_test_sqlserver.rb +114 -26
  48. data/test/cases/coerced_tests.rb +1121 -340
  49. data/test/cases/column_test_sqlserver.rb +67 -64
  50. data/test/cases/connection_test_sqlserver.rb +3 -6
  51. data/test/cases/dbconsole.rb +19 -0
  52. data/test/cases/disconnected_test_sqlserver.rb +8 -5
  53. data/test/cases/eager_load_too_many_ids_test_sqlserver.rb +18 -0
  54. data/test/cases/enum_test_sqlserver.rb +49 -0
  55. data/test/cases/execute_procedure_test_sqlserver.rb +9 -5
  56. data/test/cases/fetch_test_sqlserver.rb +19 -0
  57. data/test/cases/helper_sqlserver.rb +11 -5
  58. data/test/cases/index_test_sqlserver.rb +8 -6
  59. data/test/cases/json_test_sqlserver.rb +1 -1
  60. data/test/cases/lateral_test_sqlserver.rb +2 -2
  61. data/test/cases/migration_test_sqlserver.rb +19 -1
  62. data/test/cases/optimizer_hints_test_sqlserver.rb +21 -12
  63. data/test/cases/pessimistic_locking_test_sqlserver.rb +8 -7
  64. data/test/cases/primary_keys_test_sqlserver.rb +2 -2
  65. data/test/cases/rake_test_sqlserver.rb +10 -5
  66. data/test/cases/schema_dumper_test_sqlserver.rb +155 -109
  67. data/test/cases/schema_test_sqlserver.rb +64 -1
  68. data/test/cases/showplan_test_sqlserver.rb +7 -7
  69. data/test/cases/specific_schema_test_sqlserver.rb +17 -13
  70. data/test/cases/transaction_test_sqlserver.rb +13 -8
  71. data/test/cases/trigger_test_sqlserver.rb +20 -0
  72. data/test/cases/utils_test_sqlserver.rb +2 -2
  73. data/test/cases/uuid_test_sqlserver.rb +8 -0
  74. data/test/cases/view_test_sqlserver.rb +58 -0
  75. data/test/config.yml +1 -2
  76. data/test/migrations/transaction_table/1_table_will_never_be_created.rb +1 -1
  77. data/test/models/sqlserver/alien.rb +5 -0
  78. data/test/models/sqlserver/table_with_spaces.rb +5 -0
  79. data/test/models/sqlserver/trigger.rb +8 -0
  80. data/test/schema/sqlserver_specific_schema.rb +54 -6
  81. data/test/support/coerceable_test_sqlserver.rb +4 -4
  82. data/test/support/connection_reflection.rb +3 -9
  83. data/test/support/core_ext/query_cache.rb +7 -1
  84. data/test/support/marshal_compatibility_fixtures/SQLServer/rails_6_1_topic.dump +0 -0
  85. data/test/support/marshal_compatibility_fixtures/SQLServer/rails_6_1_topic_associations.dump +0 -0
  86. data/test/support/marshal_compatibility_fixtures/SQLServer/rails_7_1_topic.dump +0 -0
  87. data/test/support/marshal_compatibility_fixtures/SQLServer/rails_7_1_topic_associations.dump +0 -0
  88. data/test/support/query_assertions.rb +49 -0
  89. data/test/support/rake_helpers.rb +3 -1
  90. data/test/support/table_definition_sqlserver.rb +24 -0
  91. data/test/support/test_in_memory_oltp.rb +2 -2
  92. metadata +41 -17
  93. data/lib/active_record/sqlserver_base.rb +0 -18
  94. data/test/cases/scratchpad_test_sqlserver.rb +0 -8
  95. data/test/support/marshal_compatibility_fixtures/SQLServer/rails_6_0_topic.dump +0 -0
  96. data/test/support/marshal_compatibility_fixtures/SQLServer/rails_6_0_topic_associations.dump +0 -0
  97. data/test/support/sql_counter_sqlserver.rb +0 -29
@@ -5,14 +5,12 @@ require "active_record/connection_adapters/abstract/transaction"
5
5
  module ActiveRecord
6
6
  module ConnectionAdapters
7
7
  module SQLServerTransaction
8
- private
8
+ delegate :sqlserver?, to: :connection, prefix: true
9
9
 
10
- def sqlserver?
11
- connection.respond_to?(:sqlserver?) && connection.sqlserver?
12
- end
10
+ private
13
11
 
14
12
  def current_isolation_level
15
- return unless sqlserver?
13
+ return unless connection_sqlserver?
16
14
 
17
15
  level = connection.user_options_isolation_level
18
16
  # When READ_COMMITTED_SNAPSHOT is set to ON,
@@ -50,7 +48,7 @@ module ActiveRecord
50
48
  private
51
49
 
52
50
  def reset_starting_isolation_level
53
- if sqlserver? && starting_isolation_level
51
+ if connection_sqlserver? && starting_isolation_level
54
52
  connection.set_transaction_isolation_level(starting_isolation_level)
55
53
  end
56
54
  end
@@ -7,6 +7,8 @@ module ActiveRecord
7
7
  class Data
8
8
  attr_reader :value, :type
9
9
 
10
+ delegate :sub, to: :value
11
+
10
12
  def initialize(value, type)
11
13
  @value, @type = value, type
12
14
  end
@@ -25,9 +27,25 @@ module ActiveRecord
25
27
  end
26
28
 
27
29
  def eql?(other)
28
- self.class == other.class && self.value == other.value
30
+ # Support comparing `Type::Char`, `Type::Varchar` and `VarcharMax` with strings.
31
+ # This happens when we use enum with string columns.
32
+ if other.is_a?(::String)
33
+ return type.is_a?(ActiveRecord::ConnectionAdapters::SQLServer::Type::String) && value == other
34
+ end
35
+
36
+ self.class == other.class && value == other.value
29
37
  end
30
38
  alias :== :eql?
39
+
40
+ def self.from_msgpack_ext(string)
41
+ type, value = string.chomp!("msgpack_ext").split(',')
42
+
43
+ Data.new(value, type.constantize)
44
+ end
45
+
46
+ def to_msgpack_ext
47
+ [type.class.to_s, value].join(',') + "msgpack_ext"
48
+ end
31
49
  end
32
50
  end
33
51
  end
@@ -13,7 +13,7 @@ module ActiveRecord
13
13
  value = super
14
14
  return value unless value.acts_like?(:date)
15
15
 
16
- date = super(value).to_s(:_sqlserver_dateformat)
16
+ date = super(value).to_formatted_s(:_sqlserver_dateformat)
17
17
  Data.new date, self
18
18
  end
19
19
 
@@ -15,7 +15,7 @@ module ActiveRecord
15
15
  value = super
16
16
  return value unless value.acts_like?(:time)
17
17
 
18
- datetime = "#{value.to_s(:_sqlserver_datetime)}.#{quote_fractional(value)}"
18
+ datetime = "#{value.to_formatted_s(:_sqlserver_datetime)}.#{quote_fractional(value)}"
19
19
 
20
20
  Data.new datetime, self
21
21
  end
@@ -11,7 +11,7 @@ module ActiveRecord
11
11
  value = super
12
12
  return value unless value.acts_like?(:time)
13
13
 
14
- time = "#{value.to_s(:_sqlserver_time)}.#{quote_fractional(value)}"
14
+ time = "#{value.to_formatted_s(:_sqlserver_time)}.#{quote_fractional(value)}"
15
15
 
16
16
  Data.new time, self
17
17
  end
@@ -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
- # Inspiried from Rails PostgreSQL::Name adapter object in their own Utils.
13
- #
10
+ # Inspired from Rails PostgreSQL::Name adapter object in their own Utils.
14
11
  class Name
15
- SEPARATOR = "."
16
12
  UNQUOTED_SCANNER = /\]?\./
17
13
  QUOTED_SCANNER = /\A\[.*?\]\./
18
14
  QUOTED_CHECKER = /\A\[/
@@ -42,11 +38,26 @@ 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?
49
- parts.compact.size == 4
45
+ qualified_level == :fully
46
+ end
47
+
48
+ def qualified_level
49
+ case parts.compact.size
50
+ when 4
51
+ :fully
52
+ when 3
53
+ :database
54
+ when 2
55
+ :schema
56
+ when 1
57
+ :table
58
+ else
59
+ :none
60
+ end
50
61
  end
51
62
 
52
63
  def to_s
@@ -54,7 +65,7 @@ module ActiveRecord
54
65
  end
55
66
 
56
67
  def quoted
57
- parts.map { |p| quote(p) if p }.join SEPARATOR
68
+ parts.map { |p| quote(p) if p }.join('.')
58
69
  end
59
70
 
60
71
  def quoted_raw
@@ -117,7 +128,7 @@ module ActiveRecord
117
128
  extend self
118
129
 
119
130
  def quote_string(s)
120
- s.to_s.gsub /\'/, "''"
131
+ s.to_s.gsub(/\'/, "''")
121
132
  end
122
133
 
123
134
  def quote_string_single(s)
@@ -125,7 +136,7 @@ module ActiveRecord
125
136
  end
126
137
 
127
138
  def quote_string_single_national(s)
128
- "#{QUOTED_STRING_PREFIX}'#{quote_string(s)}'"
139
+ "N'#{quote_string(s)}'"
129
140
  end
130
141
 
131
142
  def quoted_raw(name)