activerecord-sqlserver-adapter 6.1.3.0 → 7.0.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 (31) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +11 -69
  3. data/Gemfile +2 -4
  4. data/MIT-LICENSE +1 -1
  5. data/README.md +7 -7
  6. data/VERSION +1 -1
  7. data/activerecord-sqlserver-adapter.gemspec +2 -2
  8. data/lib/active_record/connection_adapters/sqlserver/core_ext/preloader.rb +7 -15
  9. data/lib/active_record/connection_adapters/sqlserver/database_statements.rb +13 -6
  10. data/lib/active_record/connection_adapters/sqlserver/quoting.rb +2 -4
  11. data/lib/active_record/connection_adapters/sqlserver/schema_creation.rb +9 -11
  12. data/lib/active_record/connection_adapters/sqlserver/schema_statements.rb +15 -1
  13. data/lib/active_record/connection_adapters/sqlserver/type/data.rb +3 -1
  14. data/lib/active_record/connection_adapters/sqlserver/type/date.rb +1 -1
  15. data/lib/active_record/connection_adapters/sqlserver/type/datetime.rb +1 -1
  16. data/lib/active_record/connection_adapters/sqlserver/type/time.rb +1 -1
  17. data/lib/active_record/connection_adapters/sqlserver_adapter.rb +92 -87
  18. data/lib/arel/visitors/sqlserver.rb +2 -0
  19. data/test/cases/coerced_tests.rb +287 -89
  20. data/test/cases/column_test_sqlserver.rb +58 -58
  21. data/test/cases/eager_load_too_many_ids_test_sqlserver.rb +18 -0
  22. data/test/cases/schema_dumper_test_sqlserver.rb +2 -2
  23. data/test/migrations/transaction_table/1_table_will_never_be_created.rb +1 -1
  24. data/test/support/coerceable_test_sqlserver.rb +4 -4
  25. data/test/support/marshal_compatibility_fixtures/SQLServer/rails_6_1_topic.dump +0 -0
  26. data/test/support/marshal_compatibility_fixtures/SQLServer/rails_6_1_topic_associations.dump +0 -0
  27. data/test/support/rake_helpers.rb +3 -1
  28. metadata +19 -19
  29. data/test/cases/active_schema_test_sqlserver.rb +0 -55
  30. data/test/support/marshal_compatibility_fixtures/SQLServer/rails_6_0_topic.dump +0 -0
  31. data/test/support/marshal_compatibility_fixtures/SQLServer/rails_6_0_topic_associations.dump +0 -0
@@ -105,7 +105,7 @@ module ActiveRecord
105
105
  end
106
106
 
107
107
  def config_appname(config)
108
- if self.instance_methods.include?(:configure_application_name)
108
+ if instance_methods.include?(:configure_application_name)
109
109
  ActiveSupport::Deprecation.warn <<~MSG.squish
110
110
  Configuring the application name used by TinyTDS by overriding the
111
111
  `ActiveRecord::ConnectionAdapters::SQLServerAdapter#configure_application_name`
@@ -140,7 +140,7 @@ module ActiveRecord
140
140
  def initialize(connection, logger, _connection_options, config)
141
141
  super(connection, logger, config)
142
142
  @connection_options = config
143
- perform_connection_configuration
143
+ configure_connection
144
144
  end
145
145
 
146
146
  # === Abstract Adapter ========================================== #
@@ -301,6 +301,14 @@ module ActiveRecord
301
301
  do_execute "IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION"
302
302
  end
303
303
 
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
+
304
312
  # === Abstract Adapter (Misc Support) =========================== #
305
313
 
306
314
  def tables_with_referential_integrity
@@ -369,83 +377,93 @@ module ActiveRecord
369
377
  version_year
370
378
  end
371
379
 
372
- protected
373
-
374
- # === Abstract Adapter (Misc Support) =========================== #
375
-
376
- def initialize_type_map(m = type_map)
377
- m.register_type %r{.*}, SQLServer::Type::UnicodeString.new
378
-
379
- # Exact Numerics
380
- register_class_with_limit m, "bigint(8)", SQLServer::Type::BigInteger
381
- m.alias_type "bigint", "bigint(8)"
382
- register_class_with_limit m, "int(4)", SQLServer::Type::Integer
383
- m.alias_type "integer", "int(4)"
384
- m.alias_type "int", "int(4)"
385
- register_class_with_limit m, "smallint(2)", SQLServer::Type::SmallInteger
386
- m.alias_type "smallint", "smallint(2)"
387
- register_class_with_limit m, "tinyint(1)", SQLServer::Type::TinyInteger
388
- m.alias_type "tinyint", "tinyint(1)"
389
- m.register_type "bit", SQLServer::Type::Boolean.new
390
- m.register_type %r{\Adecimal}i do |sql_type|
391
- scale = extract_scale(sql_type)
392
- precision = extract_precision(sql_type)
393
- if scale == 0
394
- SQLServer::Type::DecimalWithoutScale.new(precision: precision)
395
- else
396
- SQLServer::Type::Decimal.new(precision: precision, scale: scale)
380
+ class << self
381
+ protected
382
+
383
+ def initialize_type_map(m)
384
+ m.register_type %r{.*}, SQLServer::Type::UnicodeString.new
385
+
386
+ # Exact Numerics
387
+ register_class_with_limit m, "bigint(8)", SQLServer::Type::BigInteger
388
+ m.alias_type "bigint", "bigint(8)"
389
+ register_class_with_limit m, "int(4)", SQLServer::Type::Integer
390
+ m.alias_type "integer", "int(4)"
391
+ m.alias_type "int", "int(4)"
392
+ register_class_with_limit m, "smallint(2)", SQLServer::Type::SmallInteger
393
+ m.alias_type "smallint", "smallint(2)"
394
+ register_class_with_limit m, "tinyint(1)", SQLServer::Type::TinyInteger
395
+ m.alias_type "tinyint", "tinyint(1)"
396
+ m.register_type "bit", SQLServer::Type::Boolean.new
397
+ m.register_type %r{\Adecimal}i do |sql_type|
398
+ scale = extract_scale(sql_type)
399
+ precision = extract_precision(sql_type)
400
+ if scale == 0
401
+ SQLServer::Type::DecimalWithoutScale.new(precision: precision)
402
+ else
403
+ SQLServer::Type::Decimal.new(precision: precision, scale: scale)
404
+ end
397
405
  end
398
- end
399
- m.alias_type %r{\Anumeric}i, "decimal"
400
- m.register_type "money", SQLServer::Type::Money.new
401
- m.register_type "smallmoney", SQLServer::Type::SmallMoney.new
402
-
403
- # Approximate Numerics
404
- m.register_type "float", SQLServer::Type::Float.new
405
- m.register_type "real", SQLServer::Type::Real.new
406
-
407
- # Date and Time
408
- m.register_type "date", SQLServer::Type::Date.new
409
- m.register_type %r{\Adatetime} do |sql_type|
410
- precision = extract_precision(sql_type)
411
- if precision
412
- SQLServer::Type::DateTime2.new precision: precision
413
- else
414
- SQLServer::Type::DateTime.new
406
+ m.alias_type %r{\Anumeric}i, "decimal"
407
+ m.register_type "money", SQLServer::Type::Money.new
408
+ m.register_type "smallmoney", SQLServer::Type::SmallMoney.new
409
+
410
+ # Approximate Numerics
411
+ m.register_type "float", SQLServer::Type::Float.new
412
+ m.register_type "real", SQLServer::Type::Real.new
413
+
414
+ # Date and Time
415
+ m.register_type "date", SQLServer::Type::Date.new
416
+ m.register_type %r{\Adatetime} do |sql_type|
417
+ precision = extract_precision(sql_type)
418
+ if precision
419
+ SQLServer::Type::DateTime2.new precision: precision
420
+ else
421
+ SQLServer::Type::DateTime.new
422
+ end
415
423
  end
424
+ m.register_type %r{\Adatetimeoffset}i do |sql_type|
425
+ precision = extract_precision(sql_type)
426
+ SQLServer::Type::DateTimeOffset.new precision: precision
427
+ end
428
+ m.register_type "smalldatetime", SQLServer::Type::SmallDateTime.new
429
+ m.register_type %r{\Atime}i do |sql_type|
430
+ precision = extract_precision(sql_type) || DEFAULT_TIME_PRECISION
431
+ SQLServer::Type::Time.new precision: precision
432
+ end
433
+
434
+ # Character Strings
435
+ register_class_with_limit m, %r{\Achar}i, SQLServer::Type::Char
436
+ register_class_with_limit m, %r{\Avarchar}i, SQLServer::Type::Varchar
437
+ m.register_type "varchar(max)", SQLServer::Type::VarcharMax.new
438
+ m.register_type "text", SQLServer::Type::Text.new
439
+
440
+ # Unicode Character Strings
441
+ register_class_with_limit m, %r{\Anchar}i, SQLServer::Type::UnicodeChar
442
+ register_class_with_limit m, %r{\Anvarchar}i, SQLServer::Type::UnicodeVarchar
443
+ m.alias_type "string", "nvarchar(4000)"
444
+ m.register_type "nvarchar(max)", SQLServer::Type::UnicodeVarcharMax.new
445
+ m.register_type "nvarchar(max)", SQLServer::Type::UnicodeVarcharMax.new
446
+ m.register_type "ntext", SQLServer::Type::UnicodeText.new
447
+
448
+ # Binary Strings
449
+ register_class_with_limit m, %r{\Abinary}i, SQLServer::Type::Binary
450
+ register_class_with_limit m, %r{\Avarbinary}i, SQLServer::Type::Varbinary
451
+ m.register_type "varbinary(max)", SQLServer::Type::VarbinaryMax.new
452
+
453
+ # Other Data Types
454
+ m.register_type "uniqueidentifier", SQLServer::Type::Uuid.new
455
+ m.register_type "timestamp", SQLServer::Type::Timestamp.new
416
456
  end
417
- m.register_type %r{\Adatetimeoffset}i do |sql_type|
418
- precision = extract_precision(sql_type)
419
- SQLServer::Type::DateTimeOffset.new precision: precision
420
- end
421
- m.register_type "smalldatetime", SQLServer::Type::SmallDateTime.new
422
- m.register_type %r{\Atime}i do |sql_type|
423
- precision = extract_precision(sql_type) || DEFAULT_TIME_PRECISION
424
- SQLServer::Type::Time.new precision: precision
425
- end
457
+ end
426
458
 
427
- # Character Strings
428
- register_class_with_limit m, %r{\Achar}i, SQLServer::Type::Char
429
- register_class_with_limit m, %r{\Avarchar}i, SQLServer::Type::Varchar
430
- m.register_type "varchar(max)", SQLServer::Type::VarcharMax.new
431
- m.register_type "text", SQLServer::Type::Text.new
459
+ TYPE_MAP = Type::TypeMap.new.tap { |m| initialize_type_map(m) }
432
460
 
433
- # Unicode Character Strings
434
- register_class_with_limit m, %r{\Anchar}i, SQLServer::Type::UnicodeChar
435
- register_class_with_limit m, %r{\Anvarchar}i, SQLServer::Type::UnicodeVarchar
436
- m.alias_type "string", "nvarchar(4000)"
437
- m.register_type "nvarchar(max)", SQLServer::Type::UnicodeVarcharMax.new
438
- m.register_type "nvarchar(max)", SQLServer::Type::UnicodeVarcharMax.new
439
- m.register_type "ntext", SQLServer::Type::UnicodeText.new
461
+ protected
440
462
 
441
- # Binary Strings
442
- register_class_with_limit m, %r{\Abinary}i, SQLServer::Type::Binary
443
- register_class_with_limit m, %r{\Avarbinary}i, SQLServer::Type::Varbinary
444
- m.register_type "varbinary(max)", SQLServer::Type::VarbinaryMax.new
463
+ # === Abstract Adapter (Misc Support) =========================== #
445
464
 
446
- # Other Data Types
447
- m.register_type "uniqueidentifier", SQLServer::Type::Uuid.new
448
- m.register_type "timestamp", SQLServer::Type::Timestamp.new
465
+ def type_map
466
+ TYPE_MAP
449
467
  end
450
468
 
451
469
  def translate_exception(e, message:, sql:, binds:)
@@ -459,7 +477,7 @@ module ActiveRecord
459
477
  when /has been chosen as the deadlock victim/i
460
478
  DeadlockVictim.new(message, sql: sql, binds: binds)
461
479
  when /database .* does not exist/i
462
- NoDatabaseError.new(message, sql: sql, binds: binds)
480
+ NoDatabaseError.new(message)
463
481
  when /data would be truncated/
464
482
  ValueTooLong.new(message, sql: sql, binds: binds)
465
483
  when /connection timed out/
@@ -522,20 +540,7 @@ module ActiveRecord
522
540
 
523
541
  def connect
524
542
  @connection = self.class.new_client(@connection_options)
525
- perform_connection_configuration
526
- end
527
-
528
- def perform_connection_configuration
529
- configure_connection_defaults
530
- configure_connection if self.respond_to?(:configure_connection)
531
- end
532
-
533
- def configure_connection_defaults
534
- @spid = _raw_select("SELECT @@SPID", fetch: :rows).first.first
535
- @version_year = version_year
536
-
537
- initialize_dateformatter
538
- use_database
543
+ configure_connection
539
544
  end
540
545
  end
541
546
  end
@@ -83,6 +83,8 @@ module Arel
83
83
  # Monkey-patch start. Add query attribute bindings rather than just values.
84
84
  column_name = o.column_name
85
85
  column_type = o.attribute.relation.type_for_attribute(o.column_name)
86
+ # Use cast_type on encrypted attributes. Don't encrypt them again
87
+ column_type = column_type.cast_type if column_type.is_a?(ActiveRecord::Encryption::EncryptedAttributeType)
86
88
  attrs = values.map { |value| ActiveRecord::Relation::QueryAttribute.new(column_name, value, column_type) }
87
89
 
88
90
  collector.add_binds(attrs, &bind_block)