activerecord-sqlserver-adapter 5.2.1 → 6.0.0.rc1

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 (146) hide show
  1. checksums.yaml +4 -4
  2. data/.editorconfig +9 -0
  3. data/.github/issue_template.md +23 -0
  4. data/.travis.yml +6 -8
  5. data/CHANGELOG.md +22 -32
  6. data/{Dockerfile → Dockerfile.ci} +1 -1
  7. data/Gemfile +42 -41
  8. data/README.md +9 -30
  9. data/RUNNING_UNIT_TESTS.md +3 -0
  10. data/Rakefile +2 -0
  11. data/VERSION +1 -1
  12. data/activerecord-sqlserver-adapter.gemspec +25 -14
  13. data/appveyor.yml +24 -17
  14. data/docker-compose.ci.yml +7 -5
  15. data/guides/RELEASING.md +11 -0
  16. data/lib/active_record/connection_adapters/sqlserver/core_ext/active_record.rb +2 -0
  17. data/lib/active_record/connection_adapters/sqlserver/core_ext/attribute_methods.rb +2 -0
  18. data/lib/active_record/connection_adapters/sqlserver/core_ext/calculations.rb +2 -0
  19. data/lib/active_record/connection_adapters/sqlserver/core_ext/explain.rb +3 -1
  20. data/lib/active_record/connection_adapters/sqlserver/core_ext/explain_subscriber.rb +2 -0
  21. data/lib/active_record/connection_adapters/sqlserver/core_ext/finder_methods.rb +6 -4
  22. data/lib/active_record/connection_adapters/sqlserver/core_ext/preloader.rb +36 -0
  23. data/lib/active_record/connection_adapters/sqlserver/core_ext/query_methods.rb +4 -1
  24. data/lib/active_record/connection_adapters/sqlserver/database_limits.rb +9 -0
  25. data/lib/active_record/connection_adapters/sqlserver/database_statements.rb +55 -14
  26. data/lib/active_record/connection_adapters/sqlserver/database_tasks.rb +2 -0
  27. data/lib/active_record/connection_adapters/sqlserver/errors.rb +2 -0
  28. data/lib/active_record/connection_adapters/sqlserver/quoting.rb +38 -0
  29. data/lib/active_record/connection_adapters/sqlserver/schema_creation.rb +16 -3
  30. data/lib/active_record/connection_adapters/sqlserver/schema_dumper.rb +2 -0
  31. data/lib/active_record/connection_adapters/sqlserver/schema_statements.rb +93 -70
  32. data/lib/active_record/connection_adapters/sqlserver/showplan.rb +2 -0
  33. data/lib/active_record/connection_adapters/sqlserver/showplan/printer_table.rb +2 -0
  34. data/lib/active_record/connection_adapters/sqlserver/showplan/printer_xml.rb +2 -0
  35. data/lib/active_record/connection_adapters/sqlserver/sql_type_metadata.rb +2 -0
  36. data/lib/active_record/connection_adapters/sqlserver/table_definition.rb +42 -40
  37. data/lib/active_record/connection_adapters/sqlserver/transaction.rb +3 -1
  38. data/lib/active_record/connection_adapters/sqlserver/type.rb +2 -0
  39. data/lib/active_record/connection_adapters/sqlserver/type/big_integer.rb +3 -1
  40. data/lib/active_record/connection_adapters/sqlserver/type/binary.rb +5 -2
  41. data/lib/active_record/connection_adapters/sqlserver/type/boolean.rb +3 -1
  42. data/lib/active_record/connection_adapters/sqlserver/type/char.rb +5 -2
  43. data/lib/active_record/connection_adapters/sqlserver/type/data.rb +2 -0
  44. data/lib/active_record/connection_adapters/sqlserver/type/date.rb +3 -1
  45. data/lib/active_record/connection_adapters/sqlserver/type/datetime.rb +7 -6
  46. data/lib/active_record/connection_adapters/sqlserver/type/datetime2.rb +2 -0
  47. data/lib/active_record/connection_adapters/sqlserver/type/datetimeoffset.rb +2 -0
  48. data/lib/active_record/connection_adapters/sqlserver/type/decimal.rb +5 -2
  49. data/lib/active_record/connection_adapters/sqlserver/type/float.rb +3 -1
  50. data/lib/active_record/connection_adapters/sqlserver/type/integer.rb +3 -1
  51. data/lib/active_record/connection_adapters/sqlserver/type/json.rb +2 -0
  52. data/lib/active_record/connection_adapters/sqlserver/type/money.rb +4 -2
  53. data/lib/active_record/connection_adapters/sqlserver/type/real.rb +3 -1
  54. data/lib/active_record/connection_adapters/sqlserver/type/small_integer.rb +3 -1
  55. data/lib/active_record/connection_adapters/sqlserver/type/small_money.rb +4 -2
  56. data/lib/active_record/connection_adapters/sqlserver/type/smalldatetime.rb +3 -1
  57. data/lib/active_record/connection_adapters/sqlserver/type/string.rb +2 -0
  58. data/lib/active_record/connection_adapters/sqlserver/type/text.rb +3 -1
  59. data/lib/active_record/connection_adapters/sqlserver/type/time.rb +5 -4
  60. data/lib/active_record/connection_adapters/sqlserver/type/time_value_fractional.rb +2 -0
  61. data/lib/active_record/connection_adapters/sqlserver/type/timestamp.rb +3 -1
  62. data/lib/active_record/connection_adapters/sqlserver/type/tiny_integer.rb +3 -1
  63. data/lib/active_record/connection_adapters/sqlserver/type/unicode_char.rb +5 -2
  64. data/lib/active_record/connection_adapters/sqlserver/type/unicode_string.rb +2 -0
  65. data/lib/active_record/connection_adapters/sqlserver/type/unicode_text.rb +3 -1
  66. data/lib/active_record/connection_adapters/sqlserver/type/unicode_varchar.rb +6 -3
  67. data/lib/active_record/connection_adapters/sqlserver/type/unicode_varchar_max.rb +4 -2
  68. data/lib/active_record/connection_adapters/sqlserver/type/uuid.rb +3 -1
  69. data/lib/active_record/connection_adapters/sqlserver/type/varbinary.rb +6 -3
  70. data/lib/active_record/connection_adapters/sqlserver/type/varbinary_max.rb +4 -2
  71. data/lib/active_record/connection_adapters/sqlserver/type/varchar.rb +6 -3
  72. data/lib/active_record/connection_adapters/sqlserver/type/varchar_max.rb +4 -2
  73. data/lib/active_record/connection_adapters/sqlserver/utils.rb +2 -0
  74. data/lib/active_record/connection_adapters/sqlserver/version.rb +2 -0
  75. data/lib/active_record/connection_adapters/sqlserver_adapter.rb +44 -10
  76. data/lib/active_record/connection_adapters/sqlserver_column.rb +9 -3
  77. data/lib/active_record/sqlserver_base.rb +8 -0
  78. data/lib/active_record/tasks/sqlserver_database_tasks.rb +2 -0
  79. data/lib/activerecord-sqlserver-adapter.rb +2 -0
  80. data/lib/arel/visitors/sqlserver.rb +40 -10
  81. data/lib/arel_sqlserver.rb +2 -0
  82. data/test/appveyor/dbsetup.ps1 +4 -4
  83. data/test/cases/adapter_test_sqlserver.rb +65 -1
  84. data/test/cases/change_column_null_test_sqlserver.rb +2 -0
  85. data/test/cases/coerced_tests.rb +644 -187
  86. data/test/cases/column_test_sqlserver.rb +2 -1
  87. data/test/cases/connection_test_sqlserver.rb +2 -0
  88. data/test/cases/execute_procedure_test_sqlserver.rb +2 -0
  89. data/test/cases/fetch_test_sqlserver.rb +2 -0
  90. data/test/cases/fully_qualified_identifier_test_sqlserver.rb +4 -2
  91. data/test/cases/helper_sqlserver.rb +2 -0
  92. data/test/cases/in_clause_test_sqlserver.rb +36 -0
  93. data/test/cases/index_test_sqlserver.rb +2 -0
  94. data/test/cases/json_test_sqlserver.rb +2 -0
  95. data/test/cases/migration_test_sqlserver.rb +4 -2
  96. data/test/cases/order_test_sqlserver.rb +2 -0
  97. data/test/cases/pessimistic_locking_test_sqlserver.rb +2 -0
  98. data/test/cases/rake_test_sqlserver.rb +2 -0
  99. data/test/cases/schema_dumper_test_sqlserver.rb +3 -1
  100. data/test/cases/schema_test_sqlserver.rb +2 -0
  101. data/test/cases/scratchpad_test_sqlserver.rb +2 -0
  102. data/test/cases/showplan_test_sqlserver.rb +4 -2
  103. data/test/cases/specific_schema_test_sqlserver.rb +2 -0
  104. data/test/cases/transaction_test_sqlserver.rb +2 -1
  105. data/test/cases/trigger_test_sqlserver.rb +2 -1
  106. data/test/cases/utils_test_sqlserver.rb +2 -0
  107. data/test/cases/uuid_test_sqlserver.rb +2 -1
  108. data/test/debug.rb +2 -0
  109. data/test/migrations/create_clients_and_change_column_null.rb +2 -0
  110. data/test/migrations/transaction_table/1_table_will_never_be_created.rb +2 -0
  111. data/test/models/sqlserver/booking.rb +2 -0
  112. data/test/models/sqlserver/customers_view.rb +2 -0
  113. data/test/models/sqlserver/datatype.rb +2 -0
  114. data/test/models/sqlserver/datatype_migration.rb +2 -0
  115. data/test/models/sqlserver/dollar_table_name.rb +2 -0
  116. data/test/models/sqlserver/edge_schema.rb +2 -0
  117. data/test/models/sqlserver/fk_has_fk.rb +2 -0
  118. data/test/models/sqlserver/fk_has_pk.rb +2 -0
  119. data/test/models/sqlserver/natural_pk_data.rb +2 -0
  120. data/test/models/sqlserver/natural_pk_int_data.rb +2 -0
  121. data/test/models/sqlserver/no_pk_data.rb +2 -0
  122. data/test/models/sqlserver/object_default.rb +2 -0
  123. data/test/models/sqlserver/quoted_table.rb +2 -0
  124. data/test/models/sqlserver/quoted_view_1.rb +2 -0
  125. data/test/models/sqlserver/quoted_view_2.rb +2 -0
  126. data/test/models/sqlserver/sst_memory.rb +2 -0
  127. data/test/models/sqlserver/string_default.rb +2 -0
  128. data/test/models/sqlserver/string_defaults_big_view.rb +2 -0
  129. data/test/models/sqlserver/string_defaults_view.rb +2 -0
  130. data/test/models/sqlserver/tinyint_pk.rb +2 -0
  131. data/test/models/sqlserver/trigger.rb +2 -0
  132. data/test/models/sqlserver/trigger_history.rb +2 -0
  133. data/test/models/sqlserver/upper.rb +2 -0
  134. data/test/models/sqlserver/uppered.rb +2 -0
  135. data/test/models/sqlserver/uuid.rb +2 -0
  136. data/test/schema/sqlserver_specific_schema.rb +2 -0
  137. data/test/support/coerceable_test_sqlserver.rb +14 -5
  138. data/test/support/connection_reflection.rb +2 -0
  139. data/test/support/core_ext/query_cache.rb +3 -0
  140. data/test/support/load_schema_sqlserver.rb +2 -0
  141. data/test/support/minitest_sqlserver.rb +2 -0
  142. data/test/support/paths_sqlserver.rb +2 -0
  143. data/test/support/rake_helpers.rb +1 -0
  144. data/test/support/sql_counter_sqlserver.rb +3 -0
  145. data/test/support/test_in_memory_oltp.rb +2 -0
  146. metadata +18 -9
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module SQLServer
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module SQLServer
@@ -7,13 +9,13 @@ module ActiveRecord
7
9
  @native_database_types ||= initialize_native_database_types.freeze
8
10
  end
9
11
 
10
- def create_table(table_name, comment: nil, **options)
12
+ def create_table(table_name, **options)
11
13
  res = super
12
14
  clear_cache!
13
15
  res
14
16
  end
15
17
 
16
- def drop_table(table_name, options = {})
18
+ def drop_table(table_name, **options)
17
19
  # Mimic CASCADE option as best we can.
18
20
  if options[:force] == :cascade
19
21
  execute_procedure(:sp_fkeys, pktable_name: table_name).each do |fkdata|
@@ -66,14 +68,13 @@ module ActiveRecord
66
68
  def columns(table_name)
67
69
  return [] if table_name.blank?
68
70
  column_definitions(table_name).map do |ci|
69
- sqlserver_options = ci.slice :ordinal_position, :is_primary, :is_identity
71
+ sqlserver_options = ci.slice :ordinal_position, :is_primary, :is_identity, :table_name
70
72
  sql_type_metadata = fetch_type_metadata ci[:type], sqlserver_options
71
73
  new_column(
72
74
  ci[:name],
73
75
  ci[:default_value],
74
76
  sql_type_metadata,
75
77
  ci[:null],
76
- ci[:table_name],
77
78
  ci[:default_function],
78
79
  ci[:collation],
79
80
  nil,
@@ -82,16 +83,16 @@ module ActiveRecord
82
83
  end
83
84
  end
84
85
 
85
- def new_column(name, default, sql_type_metadata, null, table_name, default_function = nil, collation = nil, comment = nil, sqlserver_options = {})
86
+ def new_column(name, default, sql_type_metadata, null, default_function = nil, collation = nil, comment = nil, sqlserver_options = {})
86
87
  SQLServerColumn.new(
87
88
  name,
88
89
  default,
89
90
  sql_type_metadata,
90
- null, table_name,
91
+ null,
91
92
  default_function,
92
- collation,
93
- comment,
94
- sqlserver_options
93
+ collation: collation,
94
+ comment: comment,
95
+ **sqlserver_options
95
96
  )
96
97
  end
97
98
 
@@ -153,8 +154,9 @@ module ActiveRecord
153
154
  remove_indexes(table_name, column_name)
154
155
  end
155
156
  sql_commands << "UPDATE #{quote_table_name(table_name)} SET #{quote_column_name(column_name)}=#{quote_default_expression(options[:default], column_object)} WHERE #{quote_column_name(column_name)} IS NULL" if !options[:null].nil? && options[:null] == false && !options[:default].nil?
156
- sql_commands << "ALTER TABLE #{quote_table_name(table_name)} ALTER COLUMN #{quote_column_name(column_name)} #{type_to_sql(type, limit: options[:limit], precision: options[:precision], scale: options[:scale])}"
157
- sql_commands.last << ' NOT NULL' if !options[:null].nil? && options[:null] == false
157
+ alter_command = "ALTER TABLE #{quote_table_name(table_name)} ALTER COLUMN #{quote_column_name(column_name)} #{type_to_sql(type, limit: options[:limit], precision: options[:precision], scale: options[:scale])}"
158
+ alter_command += ' NOT NULL' if !options[:null].nil? && options[:null] == false
159
+ sql_commands << alter_command
158
160
  if without_constraints
159
161
  default = quote_default_expression(default, column_object || column_for(table_name, column_name))
160
162
  sql_commands << "ALTER TABLE #{quote_table_name(table_name)} ADD CONSTRAINT #{default_constraint_name(table_name, column_name)} DEFAULT #{default} FOR #{quote_column_name(column_name)}"
@@ -237,7 +239,7 @@ module ActiveRecord
237
239
  if (0..7) === precision
238
240
  column_type_sql << "(#{precision})"
239
241
  else
240
- raise(ActiveRecordError, "The dattime2 type has precision of #{precision}. The allowed range of precision is from 0 to 7")
242
+ raise(ActiveRecordError, "The datetime2 type has precision of #{precision}. The allowed range of precision is from 0 to 7")
241
243
  end
242
244
  end
243
245
  column_type_sql
@@ -268,7 +270,7 @@ module ActiveRecord
268
270
  do_execute("UPDATE #{table_id} SET #{column_id}=#{quote(default)} WHERE #{column_id} IS NULL")
269
271
  end
270
272
  sql = "ALTER TABLE #{table_id} ALTER COLUMN #{column_id} #{type_to_sql column.type, limit: column.limit, precision: column.precision, scale: column.scale}"
271
- sql << ' NOT NULL' if !allow_null.nil? && allow_null == false
273
+ sql += ' NOT NULL' if !allow_null.nil? && allow_null == false
272
274
  do_execute sql
273
275
  end
274
276
 
@@ -282,12 +284,12 @@ module ActiveRecord
282
284
  scope = quoted_scope name, type: type
283
285
  table_name = lowercase_schema_reflection_sql 'TABLE_NAME'
284
286
  sql = "SELECT #{table_name}"
285
- sql << ' FROM INFORMATION_SCHEMA.TABLES WITH (NOLOCK)'
286
- sql << ' WHERE TABLE_CATALOG = DB_NAME()'
287
- sql << " AND TABLE_SCHEMA = #{quote(scope[:schema])}"
288
- sql << " AND TABLE_NAME = #{quote(scope[:name])}" if scope[:name]
289
- sql << " AND TABLE_TYPE = #{quote(scope[:type])}" if scope[:type]
290
- sql << " ORDER BY #{table_name}"
287
+ sql += ' FROM INFORMATION_SCHEMA.TABLES WITH (NOLOCK)'
288
+ sql += ' WHERE TABLE_CATALOG = DB_NAME()'
289
+ sql += " AND TABLE_SCHEMA = #{quote(scope[:schema])}"
290
+ sql += " AND TABLE_NAME = #{quote(scope[:name])}" if scope[:name]
291
+ sql += " AND TABLE_TYPE = #{quote(scope[:type])}" if scope[:type]
292
+ sql += " ORDER BY #{table_name}"
291
293
  sql
292
294
  end
293
295
 
@@ -343,55 +345,9 @@ module ActiveRecord
343
345
  database = identifier.fully_qualified_database_quoted
344
346
  view_exists = view_exists?(table_name)
345
347
  view_tblnm = view_table_name(table_name) if view_exists
346
- sql = %{
347
- SELECT DISTINCT
348
- #{lowercase_schema_reflection_sql('columns.TABLE_NAME')} AS table_name,
349
- #{lowercase_schema_reflection_sql('columns.COLUMN_NAME')} AS name,
350
- columns.DATA_TYPE AS type,
351
- columns.COLUMN_DEFAULT AS default_value,
352
- columns.NUMERIC_SCALE AS numeric_scale,
353
- columns.NUMERIC_PRECISION AS numeric_precision,
354
- columns.DATETIME_PRECISION AS datetime_precision,
355
- columns.COLLATION_NAME AS [collation],
356
- columns.ordinal_position,
357
- CASE
358
- WHEN columns.DATA_TYPE IN ('nchar','nvarchar','char','varchar') THEN columns.CHARACTER_MAXIMUM_LENGTH
359
- ELSE COL_LENGTH('#{database}.'+columns.TABLE_SCHEMA+'.'+columns.TABLE_NAME, columns.COLUMN_NAME)
360
- END AS [length],
361
- CASE
362
- WHEN columns.IS_NULLABLE = 'YES' THEN 1
363
- ELSE NULL
364
- END AS [is_nullable],
365
- CASE
366
- WHEN KCU.COLUMN_NAME IS NOT NULL AND TC.CONSTRAINT_TYPE = N'PRIMARY KEY' THEN 1
367
- ELSE NULL
368
- END AS [is_primary],
369
- c.is_identity AS [is_identity]
370
- FROM #{database}.INFORMATION_SCHEMA.COLUMNS columns
371
- LEFT OUTER JOIN #{database}.INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS TC
372
- ON TC.TABLE_NAME = columns.TABLE_NAME
373
- AND TC.TABLE_SCHEMA = columns.TABLE_SCHEMA
374
- AND TC.CONSTRAINT_TYPE = N'PRIMARY KEY'
375
- LEFT OUTER JOIN #{database}.INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KCU
376
- ON KCU.COLUMN_NAME = columns.COLUMN_NAME
377
- AND KCU.CONSTRAINT_NAME = TC.CONSTRAINT_NAME
378
- AND KCU.CONSTRAINT_CATALOG = TC.CONSTRAINT_CATALOG
379
- AND KCU.CONSTRAINT_SCHEMA = TC.CONSTRAINT_SCHEMA
380
- INNER JOIN #{database}.sys.schemas AS s
381
- ON s.name = columns.TABLE_SCHEMA
382
- AND s.schema_id = s.schema_id
383
- INNER JOIN #{database}.sys.objects AS o
384
- ON s.schema_id = o.schema_id
385
- AND o.is_ms_shipped = 0
386
- AND o.type IN ('U', 'V')
387
- AND o.name = columns.TABLE_NAME
388
- INNER JOIN #{database}.sys.columns AS c
389
- ON o.object_id = c.object_id
390
- AND c.name = columns.COLUMN_NAME
391
- WHERE columns.TABLE_NAME = #{prepared_statements ? '@0' : quote(identifier.object)}
392
- AND columns.TABLE_SCHEMA = #{identifier.schema.blank? ? 'schema_name()' : (prepared_statements ? '@1' : quote(identifier.schema))}
393
- ORDER BY columns.ordinal_position
394
- }.gsub(/[ \t\r\n]+/, ' ').strip
348
+
349
+ sql = column_definitions_sql(database, identifier)
350
+
395
351
  binds = []
396
352
  nv128 = SQLServer::Type::UnicodeVarchar.new limit: 128
397
353
  binds << Relation::QueryAttribute.new('TABLE_NAME', identifier.object, nv128)
@@ -458,6 +414,73 @@ module ActiveRecord
458
414
  end
459
415
  end
460
416
 
417
+ def column_definitions_sql(database, identifier)
418
+ object_name = prepared_statements ? '@0' : quote(identifier.object)
419
+ schema_name = if identifier.schema.blank?
420
+ 'schema_name()'
421
+ else
422
+ prepared_statements ? '@1' : quote(identifier.schema)
423
+ end
424
+
425
+ %{
426
+ SELECT
427
+ #{lowercase_schema_reflection_sql('o.name')} AS [table_name],
428
+ #{lowercase_schema_reflection_sql('c.name')} AS [name],
429
+ t.name AS [type],
430
+ d.definition AS [default_value],
431
+ CASE
432
+ WHEN t.name IN ('decimal', 'bigint', 'int', 'money', 'numeric', 'smallint', 'smallmoney', 'tinyint')
433
+ THEN c.scale
434
+ END AS [numeric_scale],
435
+ CASE
436
+ WHEN t.name IN ('decimal', 'bigint', 'int', 'money', 'numeric', 'smallint', 'smallmoney', 'tinyint', 'real', 'float')
437
+ THEN c.precision
438
+ END AS [numeric_precision],
439
+ CASE
440
+ WHEN t.name IN ('date', 'datetime', 'datetime2', 'datetimeoffset', 'smalldatetime', 'time')
441
+ THEN c.scale
442
+ END AS [datetime_precision],
443
+ c.collation_name AS [collation],
444
+ ROW_NUMBER() OVER (ORDER BY c.column_id) AS [ordinal_position],
445
+ CASE
446
+ WHEN t.name IN ('nchar', 'nvarchar') AND c.max_length > 0
447
+ THEN c.max_length / 2
448
+ ELSE c.max_length
449
+ END AS [length],
450
+ CASE c.is_nullable
451
+ WHEN 1
452
+ THEN 1
453
+ END AS [is_nullable],
454
+ CASE
455
+ WHEN ic.object_id IS NOT NULL
456
+ THEN 1
457
+ END AS [is_primary],
458
+ c.is_identity AS [is_identity]
459
+ FROM #{database}.sys.columns c
460
+ INNER JOIN #{database}.sys.objects o
461
+ ON c.object_id = o.object_id
462
+ INNER JOIN #{database}.sys.schemas s
463
+ ON o.schema_id = s.schema_id
464
+ INNER JOIN #{database}.sys.types t
465
+ ON c.system_type_id = t.system_type_id
466
+ AND c.user_type_id = t.user_type_id
467
+ LEFT OUTER JOIN #{database}.sys.default_constraints d
468
+ ON c.object_id = d.parent_object_id
469
+ AND c.default_object_id = d.object_id
470
+ LEFT OUTER JOIN #{database}.sys.key_constraints k
471
+ ON c.object_id = k.parent_object_id
472
+ LEFT OUTER JOIN #{database}.sys.index_columns ic
473
+ ON k.parent_object_id = ic.object_id
474
+ AND k.unique_index_id = ic.index_id
475
+ AND c.column_id = ic.column_id
476
+ WHERE
477
+ o.name = #{object_name}
478
+ AND s.name = #{schema_name}
479
+ ORDER BY
480
+ c.column_id
481
+ }.gsub(/[ \t\r\n]+/, ' ').strip
482
+ end
483
+
461
484
  def remove_check_constraints(table_name, column_name)
462
485
  constraints = select_values "SELECT CONSTRAINT_NAME FROM INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE where TABLE_NAME = '#{quote_string(table_name)}' and COLUMN_NAME = '#{quote_string(column_name)}'", 'SCHEMA'
463
486
  constraints.each do |constraint|
@@ -535,8 +558,8 @@ module ActiveRecord
535
558
  match_data ? match_data[1] : column_name
536
559
  end
537
560
 
538
- def create_table_definition(*args)
539
- SQLServer::TableDefinition.new(*args)
561
+ def create_table_definition(*args, **options)
562
+ SQLServer::TableDefinition.new(self, *args, **options)
540
563
  end
541
564
 
542
565
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'active_record/connection_adapters/sqlserver/showplan/printer_table'
2
4
  require 'active_record/connection_adapters/sqlserver/showplan/printer_xml'
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module SQLServer
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module SQLServer
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module SQLServer
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module SQLServer
@@ -14,86 +16,86 @@ module ActiveRecord
14
16
  super
15
17
  end
16
18
 
17
- def primary_key_nonclustered(*args, **options)
18
- args.each { |name| column(name, :primary_key_nonclustered, options) }
19
+ def primary_key_nonclustered(*names, **options)
20
+ names.each { |name| column(name, :primary_key_nonclustered, **options) }
19
21
  end
20
22
 
21
- def real(*args, **options)
22
- args.each { |name| column(name, :real, options) }
23
+ def real(*names, **options)
24
+ names.each { |name| column(name, :real, **options) }
23
25
  end
24
26
 
25
- def money(*args, **options)
26
- args.each { |name| column(name, :money, options) }
27
+ def money(*names, **options)
28
+ names.each { |name| column(name, :money, **options) }
27
29
  end
28
30
 
29
- def smalldatetime(*args, **options)
30
- args.each { |name| column(name, :smalldatetime, options) }
31
+ def smalldatetime(*names, **options)
32
+ names.each { |name| column(name, :smalldatetime, **options) }
31
33
  end
32
34
 
33
- def datetime(*args, **options)
34
- args.each do |name|
35
+ def datetime(*names, **options)
36
+ names.each do |name|
35
37
  if options[:precision]
36
- datetime2(name, options)
38
+ datetime2(name, **options)
37
39
  else
38
- column(name, :datetime, options)
40
+ column(name, :datetime, **options)
39
41
  end
40
42
  end
41
43
  end
42
44
 
43
- def datetime2(*args, **options)
44
- args.each { |name| column(name, :datetime2, options) }
45
+ def datetime2(*names, **options)
46
+ names.each { |name| column(name, :datetime2, **options) }
45
47
  end
46
48
 
47
- def datetimeoffset(*args, **options)
48
- args.each { |name| column(name, :datetimeoffset, options) }
49
+ def datetimeoffset(*names, **options)
50
+ names.each { |name| column(name, :datetimeoffset, **options) }
49
51
  end
50
52
 
51
- def smallmoney(*args, **options)
52
- args.each { |name| column(name, :smallmoney, options) }
53
+ def smallmoney(*names, **options)
54
+ names.each { |name| column(name, :smallmoney, **options) }
53
55
  end
54
56
 
55
- def char(*args, **options)
56
- args.each { |name| column(name, :char, options) }
57
+ def char(*names, **options)
58
+ names.each { |name| column(name, :char, **options) }
57
59
  end
58
60
 
59
- def varchar(*args, **options)
60
- args.each { |name| column(name, :varchar, options) }
61
+ def varchar(*names, **options)
62
+ names.each { |name| column(name, :varchar, **options) }
61
63
  end
62
64
 
63
- def varchar_max(*args, **options)
64
- args.each { |name| column(name, :varchar_max, options) }
65
+ def varchar_max(*names, **options)
66
+ names.each { |name| column(name, :varchar_max, **options) }
65
67
  end
66
68
 
67
- def text_basic(*args, **options)
68
- args.each { |name| column(name, :text_basic, options) }
69
+ def text_basic(*names, **options)
70
+ names.each { |name| column(name, :text_basic, **options) }
69
71
  end
70
72
 
71
- def nchar(*args, **options)
72
- args.each { |name| column(name, :nchar, options) }
73
+ def nchar(*names, **options)
74
+ names.each { |name| column(name, :nchar, **options) }
73
75
  end
74
76
 
75
- def ntext(*args, **options)
76
- args.each { |name| column(name, :ntext, options) }
77
+ def ntext(*names, **options)
78
+ names.each { |name| column(name, :ntext, **options) }
77
79
  end
78
80
 
79
- def binary_basic(*args, **options)
80
- args.each { |name| column(name, :binary_basic, options) }
81
+ def binary_basic(*names, **options)
82
+ names.each { |name| column(name, :binary_basic, **options) }
81
83
  end
82
84
 
83
- def varbinary(*args, **options)
84
- args.each { |name| column(name, :varbinary, options) }
85
+ def varbinary(*names, **options)
86
+ names.each { |name| column(name, :varbinary, **options) }
85
87
  end
86
88
 
87
- def uuid(*args, **options)
88
- args.each { |name| column(name, :uniqueidentifier, options) }
89
+ def uuid(*names, **options)
90
+ names.each { |name| column(name, :uniqueidentifier, **options) }
89
91
  end
90
92
 
91
- def ss_timestamp(*args, **options)
92
- args.each { |name| column(name, :ss_timestamp, options) }
93
+ def ss_timestamp(*names, **options)
94
+ names.each { |name| column(name, :ss_timestamp, **options) }
93
95
  end
94
96
 
95
- def json(*args, **options)
96
- args.each { |name| column(name, :text, options) }
97
+ def json(*names, **options)
98
+ names.each { |name| column(name, :text, **options) }
97
99
  end
98
100
 
99
101
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'active_record/connection_adapters/abstract/transaction'
2
4
 
3
5
  module ActiveRecord
@@ -32,7 +34,7 @@ module ActiveRecord
32
34
 
33
35
  attr_reader :starting_isolation_level
34
36
 
35
- def initialize(connection, options, *args)
37
+ def initialize(connection, options, **args)
36
38
  @connection = connection
37
39
  @starting_isolation_level = current_isolation_level if options[:isolation]
38
40
  super
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'active_record/type'
2
4
  # Behaviors
3
5
  require 'active_record/connection_adapters/sqlserver/type/data'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module SQLServer
@@ -5,7 +7,7 @@ module ActiveRecord
5
7
  class BigInteger < Integer
6
8
 
7
9
  def sqlserver_type
8
- 'bigint'.freeze
10
+ "bigint"
9
11
  end
10
12
 
11
13
  end