activerecord-sqlserver-adapter 5.2.1 → 7.0.0.0

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 (164) hide show
  1. checksums.yaml +4 -4
  2. data/.editorconfig +9 -0
  3. data/.github/issue_template.md +23 -0
  4. data/.github/workflows/ci.yml +29 -0
  5. data/.gitignore +1 -0
  6. data/.rubocop.yml +29 -0
  7. data/CHANGELOG.md +17 -27
  8. data/{Dockerfile → Dockerfile.ci} +1 -1
  9. data/Gemfile +49 -41
  10. data/Guardfile +9 -8
  11. data/MIT-LICENSE +1 -1
  12. data/README.md +65 -42
  13. data/RUNNING_UNIT_TESTS.md +3 -0
  14. data/Rakefile +14 -16
  15. data/VERSION +1 -1
  16. data/activerecord-sqlserver-adapter.gemspec +25 -14
  17. data/appveyor.yml +22 -17
  18. data/docker-compose.ci.yml +7 -5
  19. data/guides/RELEASING.md +11 -0
  20. data/lib/active_record/connection_adapters/sqlserver/core_ext/active_record.rb +2 -4
  21. data/lib/active_record/connection_adapters/sqlserver/core_ext/attribute_methods.rb +5 -4
  22. data/lib/active_record/connection_adapters/sqlserver/core_ext/calculations.rb +10 -14
  23. data/lib/active_record/connection_adapters/sqlserver/core_ext/explain.rb +12 -5
  24. data/lib/active_record/connection_adapters/sqlserver/core_ext/explain_subscriber.rb +2 -0
  25. data/lib/active_record/connection_adapters/sqlserver/core_ext/finder_methods.rb +10 -7
  26. data/lib/active_record/connection_adapters/sqlserver/core_ext/preloader.rb +30 -0
  27. data/lib/active_record/connection_adapters/sqlserver/database_limits.rb +9 -4
  28. data/lib/active_record/connection_adapters/sqlserver/database_statements.rb +117 -52
  29. data/lib/active_record/connection_adapters/sqlserver/database_tasks.rb +9 -12
  30. data/lib/active_record/connection_adapters/sqlserver/errors.rb +2 -3
  31. data/lib/active_record/connection_adapters/sqlserver/quoting.rb +51 -14
  32. data/lib/active_record/connection_adapters/sqlserver/schema_creation.rb +40 -6
  33. data/lib/active_record/connection_adapters/sqlserver/schema_dumper.rb +18 -10
  34. data/lib/active_record/connection_adapters/sqlserver/schema_statements.rb +235 -167
  35. data/lib/active_record/connection_adapters/sqlserver/showplan/printer_table.rb +4 -2
  36. data/lib/active_record/connection_adapters/sqlserver/showplan/printer_xml.rb +3 -1
  37. data/lib/active_record/connection_adapters/sqlserver/showplan.rb +8 -8
  38. data/lib/active_record/connection_adapters/sqlserver/sql_type_metadata.rb +36 -7
  39. data/lib/active_record/connection_adapters/sqlserver/table_definition.rb +43 -45
  40. data/lib/active_record/connection_adapters/sqlserver/transaction.rb +8 -10
  41. data/lib/active_record/connection_adapters/sqlserver/type/big_integer.rb +3 -3
  42. data/lib/active_record/connection_adapters/sqlserver/type/binary.rb +5 -4
  43. data/lib/active_record/connection_adapters/sqlserver/type/boolean.rb +3 -3
  44. data/lib/active_record/connection_adapters/sqlserver/type/char.rb +7 -4
  45. data/lib/active_record/connection_adapters/sqlserver/type/data.rb +5 -3
  46. data/lib/active_record/connection_adapters/sqlserver/type/date.rb +7 -5
  47. data/lib/active_record/connection_adapters/sqlserver/type/datetime.rb +8 -8
  48. data/lib/active_record/connection_adapters/sqlserver/type/datetime2.rb +2 -2
  49. data/lib/active_record/connection_adapters/sqlserver/type/datetimeoffset.rb +2 -2
  50. data/lib/active_record/connection_adapters/sqlserver/type/decimal.rb +5 -4
  51. data/lib/active_record/connection_adapters/sqlserver/type/decimal_without_scale.rb +22 -0
  52. data/lib/active_record/connection_adapters/sqlserver/type/float.rb +3 -3
  53. data/lib/active_record/connection_adapters/sqlserver/type/integer.rb +3 -3
  54. data/lib/active_record/connection_adapters/sqlserver/type/json.rb +2 -1
  55. data/lib/active_record/connection_adapters/sqlserver/type/money.rb +4 -4
  56. data/lib/active_record/connection_adapters/sqlserver/type/real.rb +3 -3
  57. data/lib/active_record/connection_adapters/sqlserver/type/small_integer.rb +3 -3
  58. data/lib/active_record/connection_adapters/sqlserver/type/small_money.rb +4 -4
  59. data/lib/active_record/connection_adapters/sqlserver/type/smalldatetime.rb +3 -3
  60. data/lib/active_record/connection_adapters/sqlserver/type/string.rb +2 -2
  61. data/lib/active_record/connection_adapters/sqlserver/type/text.rb +3 -3
  62. data/lib/active_record/connection_adapters/sqlserver/type/time.rb +6 -6
  63. data/lib/active_record/connection_adapters/sqlserver/type/time_value_fractional.rb +8 -9
  64. data/lib/active_record/connection_adapters/sqlserver/type/timestamp.rb +3 -3
  65. data/lib/active_record/connection_adapters/sqlserver/type/tiny_integer.rb +3 -3
  66. data/lib/active_record/connection_adapters/sqlserver/type/unicode_char.rb +5 -4
  67. data/lib/active_record/connection_adapters/sqlserver/type/unicode_string.rb +2 -2
  68. data/lib/active_record/connection_adapters/sqlserver/type/unicode_text.rb +3 -3
  69. data/lib/active_record/connection_adapters/sqlserver/type/unicode_varchar.rb +6 -5
  70. data/lib/active_record/connection_adapters/sqlserver/type/unicode_varchar_max.rb +4 -4
  71. data/lib/active_record/connection_adapters/sqlserver/type/uuid.rb +4 -3
  72. data/lib/active_record/connection_adapters/sqlserver/type/varbinary.rb +6 -5
  73. data/lib/active_record/connection_adapters/sqlserver/type/varbinary_max.rb +4 -4
  74. data/lib/active_record/connection_adapters/sqlserver/type/varchar.rb +6 -5
  75. data/lib/active_record/connection_adapters/sqlserver/type/varchar_max.rb +4 -4
  76. data/lib/active_record/connection_adapters/sqlserver/type.rb +38 -35
  77. data/lib/active_record/connection_adapters/sqlserver/utils.rb +26 -12
  78. data/lib/active_record/connection_adapters/sqlserver/version.rb +2 -2
  79. data/lib/active_record/connection_adapters/sqlserver_adapter.rb +271 -180
  80. data/lib/active_record/connection_adapters/sqlserver_column.rb +76 -16
  81. data/lib/active_record/sqlserver_base.rb +11 -9
  82. data/lib/active_record/tasks/sqlserver_database_tasks.rb +38 -39
  83. data/lib/activerecord-sqlserver-adapter.rb +3 -1
  84. data/lib/arel/visitors/sqlserver.rb +177 -56
  85. data/lib/arel_sqlserver.rb +4 -2
  86. data/test/appveyor/dbsetup.ps1 +4 -4
  87. data/test/cases/active_schema_test_sqlserver.rb +55 -0
  88. data/test/cases/adapter_test_sqlserver.rb +258 -173
  89. data/test/cases/change_column_collation_test_sqlserver.rb +33 -0
  90. data/test/cases/change_column_null_test_sqlserver.rb +14 -12
  91. data/test/cases/coerced_tests.rb +1421 -397
  92. data/test/cases/column_test_sqlserver.rb +321 -315
  93. data/test/cases/connection_test_sqlserver.rb +17 -20
  94. data/test/cases/disconnected_test_sqlserver.rb +39 -0
  95. data/test/cases/eager_load_too_many_ids_test_sqlserver.rb +18 -0
  96. data/test/cases/execute_procedure_test_sqlserver.rb +28 -19
  97. data/test/cases/fetch_test_sqlserver.rb +33 -21
  98. data/test/cases/fully_qualified_identifier_test_sqlserver.rb +15 -19
  99. data/test/cases/helper_sqlserver.rb +15 -15
  100. data/test/cases/in_clause_test_sqlserver.rb +63 -0
  101. data/test/cases/index_test_sqlserver.rb +15 -15
  102. data/test/cases/json_test_sqlserver.rb +25 -25
  103. data/test/cases/lateral_test_sqlserver.rb +35 -0
  104. data/test/cases/migration_test_sqlserver.rb +74 -27
  105. data/test/cases/optimizer_hints_test_sqlserver.rb +72 -0
  106. data/test/cases/order_test_sqlserver.rb +59 -53
  107. data/test/cases/pessimistic_locking_test_sqlserver.rb +27 -33
  108. data/test/cases/primary_keys_test_sqlserver.rb +103 -0
  109. data/test/cases/rake_test_sqlserver.rb +70 -45
  110. data/test/cases/schema_dumper_test_sqlserver.rb +124 -109
  111. data/test/cases/schema_test_sqlserver.rb +20 -26
  112. data/test/cases/scratchpad_test_sqlserver.rb +4 -4
  113. data/test/cases/showplan_test_sqlserver.rb +28 -35
  114. data/test/cases/specific_schema_test_sqlserver.rb +68 -65
  115. data/test/cases/transaction_test_sqlserver.rb +18 -20
  116. data/test/cases/trigger_test_sqlserver.rb +14 -13
  117. data/test/cases/utils_test_sqlserver.rb +70 -70
  118. data/test/cases/uuid_test_sqlserver.rb +13 -14
  119. data/test/debug.rb +8 -6
  120. data/test/migrations/create_clients_and_change_column_collation.rb +19 -0
  121. data/test/migrations/create_clients_and_change_column_null.rb +3 -1
  122. data/test/migrations/transaction_table/1_table_will_never_be_created.rb +4 -4
  123. data/test/models/sqlserver/booking.rb +3 -1
  124. data/test/models/sqlserver/composite_pk.rb +9 -0
  125. data/test/models/sqlserver/customers_view.rb +3 -1
  126. data/test/models/sqlserver/datatype.rb +2 -0
  127. data/test/models/sqlserver/datatype_migration.rb +2 -0
  128. data/test/models/sqlserver/dollar_table_name.rb +3 -1
  129. data/test/models/sqlserver/edge_schema.rb +3 -3
  130. data/test/models/sqlserver/fk_has_fk.rb +3 -1
  131. data/test/models/sqlserver/fk_has_pk.rb +3 -1
  132. data/test/models/sqlserver/natural_pk_data.rb +4 -2
  133. data/test/models/sqlserver/natural_pk_int_data.rb +3 -1
  134. data/test/models/sqlserver/no_pk_data.rb +3 -1
  135. data/test/models/sqlserver/object_default.rb +3 -1
  136. data/test/models/sqlserver/quoted_table.rb +4 -2
  137. data/test/models/sqlserver/quoted_view_1.rb +3 -1
  138. data/test/models/sqlserver/quoted_view_2.rb +3 -1
  139. data/test/models/sqlserver/sst_memory.rb +3 -1
  140. data/test/models/sqlserver/sst_string_collation.rb +3 -0
  141. data/test/models/sqlserver/string_default.rb +3 -1
  142. data/test/models/sqlserver/string_defaults_big_view.rb +3 -1
  143. data/test/models/sqlserver/string_defaults_view.rb +3 -1
  144. data/test/models/sqlserver/tinyint_pk.rb +3 -1
  145. data/test/models/sqlserver/trigger.rb +4 -2
  146. data/test/models/sqlserver/trigger_history.rb +3 -1
  147. data/test/models/sqlserver/upper.rb +3 -1
  148. data/test/models/sqlserver/uppered.rb +3 -1
  149. data/test/models/sqlserver/uuid.rb +3 -1
  150. data/test/schema/sqlserver_specific_schema.rb +56 -21
  151. data/test/support/coerceable_test_sqlserver.rb +19 -13
  152. data/test/support/connection_reflection.rb +3 -2
  153. data/test/support/core_ext/query_cache.rb +4 -1
  154. data/test/support/load_schema_sqlserver.rb +5 -5
  155. data/test/support/marshal_compatibility_fixtures/SQLServer/rails_6_1_topic.dump +0 -0
  156. data/test/support/marshal_compatibility_fixtures/SQLServer/rails_6_1_topic_associations.dump +0 -0
  157. data/test/support/minitest_sqlserver.rb +3 -1
  158. data/test/support/paths_sqlserver.rb +11 -11
  159. data/test/support/rake_helpers.rb +15 -10
  160. data/test/support/sql_counter_sqlserver.rb +16 -15
  161. data/test/support/test_in_memory_oltp.rb +9 -7
  162. metadata +47 -13
  163. data/.travis.yml +0 -25
  164. data/lib/active_record/connection_adapters/sqlserver/core_ext/query_methods.rb +0 -26
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module SQLServer
@@ -41,7 +43,7 @@ module ActiveRecord
41
43
  end
42
44
 
43
45
  def build_separator
44
- '+' + @widths.map { |w| '-' * (w + (cell_padding * 2)) }.join('+') + '+'
46
+ "+" + @widths.map { |w| "-" * (w + (cell_padding * 2)) }.join("+") + "+"
45
47
  end
46
48
 
47
49
  def build_cells(items)
@@ -54,7 +56,7 @@ module ActiveRecord
54
56
 
55
57
  def cast_item(item)
56
58
  case item
57
- when NilClass then 'NULL'
59
+ when NilClass then "NULL"
58
60
  when Float then item.to_s.to(9)
59
61
  else item.to_s.truncate(max_column_width)
60
62
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module SQLServer
@@ -10,7 +12,7 @@ module ActiveRecord
10
12
  def pp
11
13
  xml = @result.rows.first.first
12
14
  if defined?(Nokogiri)
13
- Nokogiri::XML(xml).to_xml indent: 2, encoding: 'UTF-8'
15
+ Nokogiri::XML(xml).to_xml indent: 2, encoding: "UTF-8"
14
16
  else
15
17
  xml
16
18
  end
@@ -1,19 +1,20 @@
1
- require 'active_record/connection_adapters/sqlserver/showplan/printer_table'
2
- require 'active_record/connection_adapters/sqlserver/showplan/printer_xml'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_record/connection_adapters/sqlserver/showplan/printer_table"
4
+ require "active_record/connection_adapters/sqlserver/showplan/printer_xml"
3
5
 
4
6
  module ActiveRecord
5
7
  module ConnectionAdapters
6
8
  module SQLServer
7
9
  module Showplan
8
-
9
- OPTION_ALL = 'SHOWPLAN_ALL'
10
- OPTION_TEXT = 'SHOWPLAN_TEXT'
11
- OPTION_XML = 'SHOWPLAN_XML'
10
+ OPTION_ALL = "SHOWPLAN_ALL"
11
+ OPTION_TEXT = "SHOWPLAN_TEXT"
12
+ OPTION_XML = "SHOWPLAN_XML"
12
13
  OPTIONS = [OPTION_ALL, OPTION_TEXT, OPTION_XML]
13
14
 
14
15
  def explain(arel, binds = [])
15
16
  sql = to_sql(arel)
16
- result = with_showplan_on { sp_executesql(sql, 'EXPLAIN', binds) }
17
+ result = with_showplan_on { sp_executesql(sql, "EXPLAIN", binds) }
17
18
  printer = showplan_printer.new(result)
18
19
  printer.pp
19
20
  end
@@ -59,7 +60,6 @@ module ActiveRecord
59
60
  else PrinterTable
60
61
  end
61
62
  end
62
-
63
63
  end
64
64
  end
65
65
  end
@@ -1,19 +1,48 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module SQLServer
4
- class SqlTypeMetadata < ActiveRecord::ConnectionAdapters::SqlTypeMetadata
6
+ class TypeMetadata < DelegateClass(SqlTypeMetadata)
7
+ undef to_yaml if method_defined?(:to_yaml)
8
+
9
+ include Deduplicable
10
+
11
+ attr_reader :is_identity, :is_primary, :table_name, :ordinal_position
5
12
 
6
- def initialize(**kwargs)
7
- @sqlserver_options = kwargs.extract!(:sqlserver_options)
8
- super(**kwargs)
13
+ def initialize(type_metadata, is_identity: nil, is_primary: nil, table_name: nil, ordinal_position: nil)
14
+ super(type_metadata)
15
+ @is_identity = is_identity
16
+ @is_primary = is_primary
17
+ @table_name = table_name
18
+ @ordinal_position = ordinal_position
9
19
  end
10
20
 
11
- protected
21
+ def ==(other)
22
+ other.is_a?(TypeMetadata) &&
23
+ __getobj__ == other.__getobj__ &&
24
+ is_identity == other.is_identity &&
25
+ is_primary == other.is_primary &&
26
+ table_name == other.table_name &&
27
+ ordinal_position == other.ordinal_position
28
+ end
29
+ alias eql? ==
12
30
 
13
- def attributes_for_hash
14
- super + [@sqlserver_options]
31
+ def hash
32
+ TypeMetadata.hash ^
33
+ __getobj__.hash ^
34
+ is_identity.hash ^
35
+ is_primary.hash ^
36
+ table_name.hash ^
37
+ ordinal_position.hash
15
38
  end
16
39
 
40
+ private
41
+
42
+ def deduplicated
43
+ __setobj__(__getobj__.deduplicate)
44
+ super
45
+ end
17
46
  end
18
47
  end
19
48
  end
@@ -1,101 +1,99 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module SQLServer
4
-
5
6
  module ColumnMethods
6
-
7
7
  def primary_key(name, type = :primary_key, **options)
8
8
  if [:integer, :bigint].include?(type)
9
9
  options[:is_identity] = true unless options.key?(:default)
10
10
  elsif type == :uuid
11
- options[:default] = options.fetch(:default, 'NEWID()')
12
- options[:primary_key] = true
11
+ options[:default] = options.fetch(:default, "NEWID()")
13
12
  end
14
13
  super
15
14
  end
16
15
 
17
- def primary_key_nonclustered(*args, **options)
18
- args.each { |name| column(name, :primary_key_nonclustered, options) }
16
+ def primary_key_nonclustered(*names, **options)
17
+ names.each { |name| column(name, :primary_key_nonclustered, **options) }
19
18
  end
20
19
 
21
- def real(*args, **options)
22
- args.each { |name| column(name, :real, options) }
20
+ def real(*names, **options)
21
+ names.each { |name| column(name, :real, **options) }
23
22
  end
24
23
 
25
- def money(*args, **options)
26
- args.each { |name| column(name, :money, options) }
24
+ def money(*names, **options)
25
+ names.each { |name| column(name, :money, **options) }
27
26
  end
28
27
 
29
- def smalldatetime(*args, **options)
30
- args.each { |name| column(name, :smalldatetime, options) }
28
+ def smalldatetime(*names, **options)
29
+ names.each { |name| column(name, :smalldatetime, **options) }
31
30
  end
32
31
 
33
- def datetime(*args, **options)
34
- args.each do |name|
32
+ def datetime(*names, **options)
33
+ names.each do |name|
35
34
  if options[:precision]
36
- datetime2(name, options)
35
+ datetime2(name, **options)
37
36
  else
38
- column(name, :datetime, options)
37
+ column(name, :datetime, **options)
39
38
  end
40
39
  end
41
40
  end
42
41
 
43
- def datetime2(*args, **options)
44
- args.each { |name| column(name, :datetime2, options) }
42
+ def datetime2(*names, **options)
43
+ names.each { |name| column(name, :datetime2, **options) }
45
44
  end
46
45
 
47
- def datetimeoffset(*args, **options)
48
- args.each { |name| column(name, :datetimeoffset, options) }
46
+ def datetimeoffset(*names, **options)
47
+ names.each { |name| column(name, :datetimeoffset, **options) }
49
48
  end
50
49
 
51
- def smallmoney(*args, **options)
52
- args.each { |name| column(name, :smallmoney, options) }
50
+ def smallmoney(*names, **options)
51
+ names.each { |name| column(name, :smallmoney, **options) }
53
52
  end
54
53
 
55
- def char(*args, **options)
56
- args.each { |name| column(name, :char, options) }
54
+ def char(*names, **options)
55
+ names.each { |name| column(name, :char, **options) }
57
56
  end
58
57
 
59
- def varchar(*args, **options)
60
- args.each { |name| column(name, :varchar, options) }
58
+ def varchar(*names, **options)
59
+ names.each { |name| column(name, :varchar, **options) }
61
60
  end
62
61
 
63
- def varchar_max(*args, **options)
64
- args.each { |name| column(name, :varchar_max, options) }
62
+ def varchar_max(*names, **options)
63
+ names.each { |name| column(name, :varchar_max, **options) }
65
64
  end
66
65
 
67
- def text_basic(*args, **options)
68
- args.each { |name| column(name, :text_basic, options) }
66
+ def text_basic(*names, **options)
67
+ names.each { |name| column(name, :text_basic, **options) }
69
68
  end
70
69
 
71
- def nchar(*args, **options)
72
- args.each { |name| column(name, :nchar, options) }
70
+ def nchar(*names, **options)
71
+ names.each { |name| column(name, :nchar, **options) }
73
72
  end
74
73
 
75
- def ntext(*args, **options)
76
- args.each { |name| column(name, :ntext, options) }
74
+ def ntext(*names, **options)
75
+ names.each { |name| column(name, :ntext, **options) }
77
76
  end
78
77
 
79
- def binary_basic(*args, **options)
80
- args.each { |name| column(name, :binary_basic, options) }
78
+ def binary_basic(*names, **options)
79
+ names.each { |name| column(name, :binary_basic, **options) }
81
80
  end
82
81
 
83
- def varbinary(*args, **options)
84
- args.each { |name| column(name, :varbinary, options) }
82
+ def varbinary(*names, **options)
83
+ names.each { |name| column(name, :varbinary, **options) }
85
84
  end
86
85
 
87
- def uuid(*args, **options)
88
- args.each { |name| column(name, :uniqueidentifier, options) }
86
+ def uuid(*names, **options)
87
+ names.each { |name| column(name, :uniqueidentifier, **options) }
89
88
  end
90
89
 
91
- def ss_timestamp(*args, **options)
92
- args.each { |name| column(name, :ss_timestamp, options) }
90
+ def ss_timestamp(*names, **options)
91
+ names.each { |name| column(name, :ss_timestamp, **options) }
93
92
  end
94
93
 
95
- def json(*args, **options)
96
- args.each { |name| column(name, :text, options) }
94
+ def json(*names, **options)
95
+ names.each { |name| column(name, :text, **options) }
97
96
  end
98
-
99
97
  end
100
98
 
101
99
  class TableDefinition < ActiveRecord::ConnectionAdapters::TableDefinition
@@ -1,10 +1,10 @@
1
- require 'active_record/connection_adapters/abstract/transaction'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_record/connection_adapters/abstract/transaction"
2
4
 
3
5
  module ActiveRecord
4
6
  module ConnectionAdapters
5
-
6
7
  module SQLServerTransaction
7
-
8
8
  private
9
9
 
10
10
  def sqlserver?
@@ -13,28 +13,27 @@ module ActiveRecord
13
13
 
14
14
  def current_isolation_level
15
15
  return unless sqlserver?
16
+
16
17
  level = connection.user_options_isolation_level
17
18
  # When READ_COMMITTED_SNAPSHOT is set to ON,
18
19
  # user_options_isolation_level will be equal to 'read committed
19
20
  # snapshot' which is not a valid isolation level
20
- if level.blank? || level == 'read committed snapshot'
21
- 'READ COMMITTED'
21
+ if level.blank? || level == "read committed snapshot"
22
+ "READ COMMITTED"
22
23
  else
23
24
  level.upcase
24
25
  end
25
26
  end
26
-
27
27
  end
28
28
 
29
29
  Transaction.send :prepend, SQLServerTransaction
30
30
 
31
31
  module SQLServerRealTransaction
32
-
33
32
  attr_reader :starting_isolation_level
34
33
 
35
- def initialize(connection, options, *args)
34
+ def initialize(connection, isolation: nil, joinable: true, run_commit_callbacks: false)
36
35
  @connection = connection
37
- @starting_isolation_level = current_isolation_level if options[:isolation]
36
+ @starting_isolation_level = current_isolation_level if isolation
38
37
  super
39
38
  end
40
39
 
@@ -55,7 +54,6 @@ module ActiveRecord
55
54
  connection.set_transaction_isolation_level(starting_isolation_level)
56
55
  end
57
56
  end
58
-
59
57
  end
60
58
 
61
59
  RealTransaction.send :prepend, SQLServerRealTransaction
@@ -1,13 +1,13 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module SQLServer
4
6
  module Type
5
7
  class BigInteger < Integer
6
-
7
8
  def sqlserver_type
8
- 'bigint'.freeze
9
+ "bigint"
9
10
  end
10
-
11
11
  end
12
12
  end
13
13
  end
@@ -1,19 +1,20 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module SQLServer
4
6
  module Type
5
7
  class Binary < ActiveRecord::Type::Binary
6
-
7
8
  def type
8
9
  :binary_basic
9
10
  end
10
11
 
11
12
  def sqlserver_type
12
- 'binary'.tap do |type|
13
- type << "(#{limit})" if limit
13
+ "binary".yield_self do |type|
14
+ type += "(#{limit})" if limit
15
+ type
14
16
  end
15
17
  end
16
-
17
18
  end
18
19
  end
19
20
  end
@@ -1,13 +1,13 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module SQLServer
4
6
  module Type
5
7
  class Boolean < ActiveRecord::Type::Boolean
6
-
7
8
  def sqlserver_type
8
- 'bit'.freeze
9
+ "bit"
9
10
  end
10
-
11
11
  end
12
12
  end
13
13
  end
@@ -1,9 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module SQLServer
4
6
  module Type
5
7
  class Char < String
6
-
7
8
  def type
8
9
  :char
9
10
  end
@@ -11,20 +12,22 @@ module ActiveRecord
11
12
  def serialize(value)
12
13
  return if value.nil?
13
14
  return value if value.is_a?(Data)
15
+
14
16
  Data.new super, self
15
17
  end
16
18
 
17
19
  def sqlserver_type
18
- 'char'.tap do |type|
19
- type << "(#{limit})" if limit
20
+ "char".yield_self do |type|
21
+ type += "(#{limit})" if limit
22
+ type
20
23
  end
21
24
  end
22
25
 
23
26
  def quoted(value)
24
27
  return value.quoted_id if value.respond_to?(:quoted_id)
28
+
25
29
  Utils.quote_string_single(value)
26
30
  end
27
-
28
31
  end
29
32
  end
30
33
  end
@@ -1,11 +1,14 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module SQLServer
4
6
  module Type
5
7
  class Data
6
-
7
8
  attr_reader :value, :type
8
9
 
10
+ delegate :sub, to: :value
11
+
9
12
  def initialize(value, type)
10
13
  @value, @type = value, type
11
14
  end
@@ -24,10 +27,9 @@ module ActiveRecord
24
27
  end
25
28
 
26
29
  def eql?(other)
27
- self.class == other.class && self.value == other.value
30
+ self.class == other.class && value == other.value
28
31
  end
29
32
  alias :== :eql?
30
-
31
33
  end
32
34
  end
33
35
  end
@@ -1,16 +1,19 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module SQLServer
4
6
  module Type
5
7
  class Date < ActiveRecord::Type::Date
6
-
7
8
  def sqlserver_type
8
- 'date'.freeze
9
+ "date"
9
10
  end
10
11
 
11
12
  def serialize(value)
12
- return unless value.present?
13
- date = super(value).to_s(:_sqlserver_dateformat)
13
+ value = super
14
+ return value unless value.acts_like?(:date)
15
+
16
+ date = super(value).to_formatted_s(:_sqlserver_dateformat)
14
17
  Data.new date, self
15
18
  end
16
19
 
@@ -37,7 +40,6 @@ module ActiveRecord
37
40
  def fast_string_to_date_format
38
41
  ::Date::DATE_FORMATS[:_sqlserver_dateformat]
39
42
  end
40
-
41
43
  end
42
44
  end
43
45
  end
@@ -1,22 +1,22 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module SQLServer
4
6
  module Type
5
7
  class DateTime < ActiveRecord::Type::DateTime
6
-
7
8
  include TimeValueFractional
8
9
 
9
10
  def sqlserver_type
10
- 'datetime'.freeze
11
+ "datetime"
11
12
  end
12
13
 
13
14
  def serialize(value)
14
15
  value = super
15
16
  return value unless value.acts_like?(:time)
16
- datetime = value.to_s(:_sqlserver_datetime).tap do |v|
17
- fraction = quote_fractional(value)
18
- v << ".#{fraction}"
19
- end
17
+
18
+ datetime = "#{value.to_formatted_s(:_sqlserver_datetime)}.#{quote_fractional(value)}"
19
+
20
20
  Data.new datetime, self
21
21
  end
22
22
 
@@ -35,7 +35,7 @@ module ActiveRecord
35
35
  private
36
36
 
37
37
  def fast_string_to_time(string)
38
- time = ActiveSupport::TimeZone['UTC'].strptime(string, fast_string_to_time_format)
38
+ time = ActiveSupport::TimeZone["UTC"].strptime(string, fast_string_to_time_format)
39
39
  new_time(time.year, time.month, time.day, time.hour,
40
40
  time.min, time.sec, Rational(time.nsec, 1_000))
41
41
  rescue ArgumentError
@@ -43,7 +43,7 @@ module ActiveRecord
43
43
  end
44
44
 
45
45
  def fast_string_to_time_format
46
- "#{::Time::DATE_FORMATS[:_sqlserver_datetime]}.%N".freeze
46
+ "#{::Time::DATE_FORMATS[:_sqlserver_datetime]}.%N"
47
47
  end
48
48
  end
49
49
  end
@@ -1,15 +1,15 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module SQLServer
4
6
  module Type
5
7
  class DateTime2 < DateTime
6
-
7
8
  include TimeValueFractional2
8
9
 
9
10
  def sqlserver_type
10
11
  "datetime2(#{precision.to_i})"
11
12
  end
12
-
13
13
  end
14
14
  end
15
15
  end
@@ -1,9 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module SQLServer
4
6
  module Type
5
7
  class DateTimeOffset < DateTime2
6
-
7
8
  def type
8
9
  :datetimeoffset
9
10
  end
@@ -15,7 +16,6 @@ module ActiveRecord
15
16
  def quoted(value)
16
17
  Utils.quote_string_single(value)
17
18
  end
18
-
19
19
  end
20
20
  end
21
21
  end
@@ -1,19 +1,20 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module SQLServer
4
6
  module Type
5
7
  class Decimal < ActiveRecord::Type::Decimal
6
-
7
8
  def sqlserver_type
8
- 'decimal'.tap do |type|
9
- type << "(#{precision.to_i},#{scale.to_i})" if precision || scale
9
+ "decimal".yield_self do |type|
10
+ type += "(#{precision.to_i},#{scale.to_i})" if precision || scale
11
+ type
10
12
  end
11
13
  end
12
14
 
13
15
  def type_cast_for_schema(value)
14
16
  value.is_a?(BigDecimal) ? value.to_s : value.inspect
15
17
  end
16
-
17
18
  end
18
19
  end
19
20
  end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module ConnectionAdapters
5
+ module SQLServer
6
+ module Type
7
+ class DecimalWithoutScale < ActiveRecord::Type::DecimalWithoutScale
8
+ def sqlserver_type
9
+ "decimal".yield_self do |type|
10
+ type += "(#{precision.to_i},0)" if precision
11
+ type
12
+ end
13
+ end
14
+
15
+ def type_cast_for_schema(value)
16
+ value.is_a?(BigDecimal) ? value.to_s : value.inspect
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -1,17 +1,17 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module SQLServer
4
6
  module Type
5
7
  class Float < ActiveRecord::Type::Float
6
-
7
8
  def type
8
9
  :float
9
10
  end
10
11
 
11
12
  def sqlserver_type
12
- 'float'.freeze
13
+ "float"
13
14
  end
14
-
15
15
  end
16
16
  end
17
17
  end
@@ -1,13 +1,13 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module SQLServer
4
6
  module Type
5
7
  class Integer < ActiveRecord::Type::Integer
6
-
7
8
  def sqlserver_type
8
- 'int'.freeze
9
+ "int"
9
10
  end
10
-
11
11
  end
12
12
  end
13
13
  end