activerecord-sqlserver-adapter 6.1.0.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.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +4 -1
- data/CHANGELOG.md +12 -23
- data/Gemfile +1 -0
- data/MIT-LICENSE +1 -1
- data/README.md +31 -16
- data/VERSION +1 -1
- data/activerecord-sqlserver-adapter.gemspec +2 -2
- data/appveyor.yml +4 -6
- data/lib/active_record/connection_adapters/sqlserver/core_ext/attribute_methods.rb +2 -0
- data/lib/active_record/connection_adapters/sqlserver/core_ext/calculations.rb +5 -1
- data/lib/active_record/connection_adapters/sqlserver/core_ext/explain.rb +2 -0
- data/lib/active_record/connection_adapters/sqlserver/core_ext/finder_methods.rb +2 -0
- data/lib/active_record/connection_adapters/sqlserver/core_ext/preloader.rb +7 -13
- data/lib/active_record/connection_adapters/sqlserver/database_statements.rb +15 -6
- data/lib/active_record/connection_adapters/sqlserver/quoting.rb +4 -5
- data/lib/active_record/connection_adapters/sqlserver/schema_statements.rb +28 -9
- data/lib/active_record/connection_adapters/sqlserver/sql_type_metadata.rb +14 -5
- data/lib/active_record/connection_adapters/sqlserver/type/data.rb +3 -1
- data/lib/active_record/connection_adapters/sqlserver/type/date.rb +3 -2
- data/lib/active_record/connection_adapters/sqlserver/type/datetime.rb +1 -1
- data/lib/active_record/connection_adapters/sqlserver/type/time.rb +1 -1
- data/lib/active_record/connection_adapters/sqlserver/utils.rb +16 -1
- data/lib/active_record/connection_adapters/sqlserver_adapter.rb +99 -76
- data/lib/active_record/connection_adapters/sqlserver_column.rb +74 -35
- data/lib/arel/visitors/sqlserver.rb +17 -2
- data/test/cases/adapter_test_sqlserver.rb +10 -2
- data/test/cases/coerced_tests.rb +314 -85
- data/test/cases/column_test_sqlserver.rb +62 -58
- data/test/cases/eager_load_too_many_ids_test_sqlserver.rb +18 -0
- data/test/cases/fetch_test_sqlserver.rb +18 -0
- data/test/cases/rake_test_sqlserver.rb +36 -0
- data/test/cases/schema_dumper_test_sqlserver.rb +2 -2
- data/test/migrations/transaction_table/1_table_will_never_be_created.rb +1 -1
- data/test/models/sqlserver/composite_pk.rb +9 -0
- data/test/schema/sqlserver_specific_schema.rb +18 -0
- data/test/support/coerceable_test_sqlserver.rb +4 -4
- data/test/support/marshal_compatibility_fixtures/SQLServer/rails_6_1_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/SQLServer/rails_6_1_topic_associations.dump +0 -0
- data/test/support/rake_helpers.rb +3 -1
- metadata +18 -15
- data/lib/active_record/connection_adapters/sqlserver/core_ext/query_methods.rb +0 -28
- data/test/support/marshal_compatibility_fixtures/SQLServer/rails_6_0_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/SQLServer/rails_6_0_topic_associations.dump +0 -0
@@ -277,8 +277,8 @@ class ColumnTestSQLServer < ActiveRecord::TestCase
|
|
277
277
|
_(col.sql_type).must_equal "date"
|
278
278
|
_(col.type).must_equal :date
|
279
279
|
_(col.null).must_equal true
|
280
|
-
_(col.default).must_equal connection_dblib_73? ? Date.civil(
|
281
|
-
_(obj.date).must_equal Date.civil(
|
280
|
+
_(col.default).must_equal connection_dblib_73? ? Date.civil(1, 1, 1) : "0001-01-01"
|
281
|
+
_(obj.date).must_equal Date.civil(1, 1, 1)
|
282
282
|
_(col.default_function).must_be_nil
|
283
283
|
type = connection.lookup_cast_type_from_column(col)
|
284
284
|
_(type).must_be_instance_of Type::Date
|
@@ -287,20 +287,22 @@ class ColumnTestSQLServer < ActiveRecord::TestCase
|
|
287
287
|
_(type.scale).must_be_nil
|
288
288
|
# Can cast strings. SQL Server format.
|
289
289
|
obj.date = "04-01-0001"
|
290
|
-
_(obj.date).must_equal Date.civil(
|
290
|
+
_(obj.date).must_equal Date.civil(1, 4, 1)
|
291
291
|
obj.save!
|
292
|
-
_(obj.date).must_equal Date.civil(
|
292
|
+
_(obj.date).must_equal Date.civil(1, 4, 1)
|
293
293
|
obj.reload
|
294
|
-
_(obj.date).must_equal Date.civil(
|
294
|
+
_(obj.date).must_equal Date.civil(1, 4, 1)
|
295
295
|
# Can cast strings. ISO format.
|
296
296
|
obj.date = "0001-04-01"
|
297
|
-
_(obj.date).must_equal Date.civil(
|
297
|
+
_(obj.date).must_equal Date.civil(1, 4, 1)
|
298
298
|
obj.save!
|
299
|
-
_(obj.date).must_equal Date.civil(
|
299
|
+
_(obj.date).must_equal Date.civil(1, 4, 1)
|
300
300
|
obj.reload
|
301
|
-
_(obj.date).must_equal Date.civil(
|
301
|
+
_(obj.date).must_equal Date.civil(1, 4, 1)
|
302
|
+
# Can filter by date range
|
303
|
+
_(obj).must_equal obj.class.where(date: obj.date..Date::Infinity.new).first
|
302
304
|
# Can keep and return assigned date.
|
303
|
-
assert_obj_set_and_save :date, Date.civil(1972,
|
305
|
+
assert_obj_set_and_save :date, Date.civil(1972, 4, 14)
|
304
306
|
# Can accept and cast time objects.
|
305
307
|
obj.date = Time.utc(2010, 4, 14, 12, 34, 56, 3000)
|
306
308
|
_(obj.date).must_equal Date.civil(2010, 4, 14)
|
@@ -313,7 +315,7 @@ class ColumnTestSQLServer < ActiveRecord::TestCase
|
|
313
315
|
_(col.sql_type).must_equal "datetime"
|
314
316
|
_(col.type).must_equal :datetime
|
315
317
|
_(col.null).must_equal true
|
316
|
-
time = Time.utc 1753,
|
318
|
+
time = Time.utc 1753, 1, 1, 0, 0, 0, 123000
|
317
319
|
_(col.default).must_equal time, "Microseconds were <#{col.default.usec}> vs <123000>"
|
318
320
|
_(obj.datetime).must_equal time, "Microseconds were <#{obj.datetime.usec}> vs <123000>"
|
319
321
|
_(col.default_function).must_be_nil
|
@@ -325,7 +327,7 @@ class ColumnTestSQLServer < ActiveRecord::TestCase
|
|
325
327
|
obj.save!
|
326
328
|
_(obj).must_equal obj.class.where(datetime: time).first
|
327
329
|
# Can save to proper accuracy and return again.
|
328
|
-
time = Time.utc 2010,
|
330
|
+
time = Time.utc 2010, 4, 1, 12, 34, 56, 3000
|
329
331
|
obj.datetime = time
|
330
332
|
_(obj.datetime).must_equal time, "Microseconds were <#{obj.datetime.usec}> vs <3000>"
|
331
333
|
obj.save!
|
@@ -333,9 +335,11 @@ class ColumnTestSQLServer < ActiveRecord::TestCase
|
|
333
335
|
obj.reload
|
334
336
|
_(obj.datetime).must_equal time, "Microseconds were <#{obj.datetime.usec}> vs <3000>"
|
335
337
|
_(obj).must_equal obj.class.where(datetime: time).first
|
338
|
+
# Can filter by datetime range
|
339
|
+
_(obj).must_equal obj.class.where(datetime: time..DateTime::Infinity.new).first
|
336
340
|
# Will cast to true DB value on attribute write, save and return again.
|
337
|
-
time = Time.utc 2010,
|
338
|
-
time2 = Time.utc 2010,
|
341
|
+
time = Time.utc 2010, 4, 1, 12, 34, 56, 234567
|
342
|
+
time2 = Time.utc 2010, 4, 1, 12, 34, 56, 233000
|
339
343
|
obj.datetime = time
|
340
344
|
_(obj.datetime).must_equal time2, "Microseconds were <#{obj.datetime.usec}> vs <233000>"
|
341
345
|
obj.save!
|
@@ -423,8 +427,8 @@ class ColumnTestSQLServer < ActiveRecord::TestCase
|
|
423
427
|
_(col.sql_type).must_equal "datetimeoffset(7)"
|
424
428
|
_(col.type).must_equal :datetimeoffset
|
425
429
|
_(col.null).must_equal true
|
426
|
-
_(col.default).must_equal Time.new(1984,
|
427
|
-
_(obj.datetimeoffset_7).must_equal Time.new(1984,
|
430
|
+
_(col.default).must_equal Time.new(1984, 1, 24, 4, 20, 0, -28800).change(nsec: 123456700), "Nanoseconds <#{col.default.nsec}> vs <123456700>"
|
431
|
+
_(obj.datetimeoffset_7).must_equal Time.new(1984, 1, 24, 4, 20, 0, -28800).change(nsec: 123456700), "Nanoseconds were <#{obj.datetimeoffset_7.nsec}> vs <999999900>"
|
428
432
|
_(col.default_function).must_be_nil
|
429
433
|
type = connection.lookup_cast_type_from_column(col)
|
430
434
|
_(type).must_be_instance_of Type::DateTimeOffset
|
@@ -432,12 +436,12 @@ class ColumnTestSQLServer < ActiveRecord::TestCase
|
|
432
436
|
_(type.precision).must_equal 7
|
433
437
|
_(type.scale).must_be_nil
|
434
438
|
# Can save 100 nanosecond precisoins and return again.
|
435
|
-
obj.datetimeoffset_7 = Time.new(2010,
|
436
|
-
_(obj.datetimeoffset_7).must_equal Time.new(2010,
|
439
|
+
obj.datetimeoffset_7 = Time.new(2010, 4, 1, 12, 34, 56, +18000).change(nsec: 123456755)
|
440
|
+
_(obj.datetimeoffset_7).must_equal Time.new(2010, 4, 1, 12, 34, 56, +18000).change(nsec: 123456800), "Nanoseconds were <#{obj.datetimeoffset_7.nsec}> vs <123456800>"
|
437
441
|
obj.save!
|
438
|
-
_(obj.datetimeoffset_7).must_equal Time.new(2010,
|
442
|
+
_(obj.datetimeoffset_7).must_equal Time.new(2010, 4, 1, 12, 34, 56, +18000).change(nsec: 123456800), "Nanoseconds were <#{obj.datetimeoffset_7.nsec}> vs <123456800>"
|
439
443
|
obj.reload
|
440
|
-
_(obj.datetimeoffset_7).must_equal Time.new(2010,
|
444
|
+
_(obj.datetimeoffset_7).must_equal Time.new(2010, 4, 1, 12, 34, 56, +18000).change(nsec: 123456800), "Nanoseconds were <#{obj.datetimeoffset_7.nsec}> vs <123456800>"
|
441
445
|
# Maintains the timezone
|
442
446
|
time = ActiveSupport::TimeZone["America/Los_Angeles"].local 2010, 12, 31, 23, 59, 59, Rational(123456800, 1000)
|
443
447
|
obj.datetimeoffset_7 = time
|
@@ -466,8 +470,8 @@ class ColumnTestSQLServer < ActiveRecord::TestCase
|
|
466
470
|
_(col.sql_type).must_equal "smalldatetime"
|
467
471
|
_(col.type).must_equal :smalldatetime
|
468
472
|
_(col.null).must_equal true
|
469
|
-
_(col.default).must_equal Time.utc(1901,
|
470
|
-
_(obj.smalldatetime).must_equal Time.utc(1901,
|
473
|
+
_(col.default).must_equal Time.utc(1901, 1, 1, 15, 45, 0, 0)
|
474
|
+
_(obj.smalldatetime).must_equal Time.utc(1901, 1, 1, 15, 45, 0, 0)
|
471
475
|
_(col.default_function).must_be_nil
|
472
476
|
type = connection.lookup_cast_type_from_column(col)
|
473
477
|
_(type).must_be_instance_of Type::SmallDateTime
|
@@ -475,12 +479,12 @@ class ColumnTestSQLServer < ActiveRecord::TestCase
|
|
475
479
|
_(type.precision).must_be_nil
|
476
480
|
_(type.scale).must_be_nil
|
477
481
|
# Will remove fractional seconds and return again.
|
478
|
-
obj.smalldatetime = Time.utc(2078,
|
479
|
-
_(obj.smalldatetime).must_equal Time.utc(2078,
|
482
|
+
obj.smalldatetime = Time.utc(2078, 6, 5, 4, 20, 0, 3000)
|
483
|
+
_(obj.smalldatetime).must_equal Time.utc(2078, 6, 5, 4, 20, 0, 0), "Microseconds were <#{obj.smalldatetime.usec}> vs <0>"
|
480
484
|
obj.save!
|
481
|
-
_(obj.smalldatetime).must_equal Time.utc(2078,
|
485
|
+
_(obj.smalldatetime).must_equal Time.utc(2078, 6, 5, 4, 20, 0, 0), "Microseconds were <#{obj.reload.smalldatetime.usec}> vs <0>"
|
482
486
|
obj.reload
|
483
|
-
_(obj.smalldatetime).must_equal Time.utc(2078,
|
487
|
+
_(obj.smalldatetime).must_equal Time.utc(2078, 6, 5, 4, 20, 0, 0), "Microseconds were <#{obj.reload.smalldatetime.usec}> vs <0>"
|
484
488
|
end
|
485
489
|
|
486
490
|
it "time(7)" do
|
@@ -489,7 +493,7 @@ class ColumnTestSQLServer < ActiveRecord::TestCase
|
|
489
493
|
_(col.sql_type).must_equal "time(7)"
|
490
494
|
_(col.type).must_equal :time
|
491
495
|
_(col.null).must_equal true
|
492
|
-
_(col.default).must_equal Time.utc(1900,
|
496
|
+
_(col.default).must_equal Time.utc(1900, 1, 1, 4, 20, 0, Rational(288321500, 1000)), "Nanoseconds were <#{col.default.nsec}> vs <288321500>"
|
493
497
|
_(col.default_function).must_be_nil
|
494
498
|
type = connection.lookup_cast_type_from_column(col)
|
495
499
|
_(type).must_be_instance_of Type::Time
|
@@ -497,22 +501,22 @@ class ColumnTestSQLServer < ActiveRecord::TestCase
|
|
497
501
|
_(type.precision).must_equal 7
|
498
502
|
_(type.scale).must_be_nil
|
499
503
|
# Time's #usec precision (low micro)
|
500
|
-
obj.time_7 = Time.utc(2000,
|
501
|
-
_(obj.time_7).must_equal Time.utc(2000,
|
502
|
-
_(obj.time_7).must_equal Time.utc(2000,
|
504
|
+
obj.time_7 = Time.utc(2000, 1, 1, 15, 45, 0, 300)
|
505
|
+
_(obj.time_7).must_equal Time.utc(2000, 1, 1, 15, 45, 0, 300), "Microseconds were <#{obj.time_7.usec}> vs <0>"
|
506
|
+
_(obj.time_7).must_equal Time.utc(2000, 1, 1, 15, 45, 0, 300), "Nanoseconds were <#{obj.time_7.nsec}> vs <300>"
|
503
507
|
obj.save!; obj.reload
|
504
|
-
_(obj.time_7).must_equal Time.utc(2000,
|
505
|
-
_(obj.time_7).must_equal Time.utc(2000,
|
508
|
+
_(obj.time_7).must_equal Time.utc(2000, 1, 1, 15, 45, 0, 300), "Microseconds were <#{obj.time_7.usec}> vs <0>"
|
509
|
+
_(obj.time_7).must_equal Time.utc(2000, 1, 1, 15, 45, 0, 300), "Nanoseconds were <#{obj.time_7.nsec}> vs <300>"
|
506
510
|
# Time's #usec precision (high micro)
|
507
|
-
obj.time_7 = Time.utc(2000,
|
508
|
-
_(obj.time_7).must_equal Time.utc(2000,
|
511
|
+
obj.time_7 = Time.utc(2000, 1, 1, 15, 45, 0, 234567)
|
512
|
+
_(obj.time_7).must_equal Time.utc(2000, 1, 1, 15, 45, 0, 234567), "Microseconds were <#{obj.time_7.usec}> vs <234567>"
|
509
513
|
obj.save!; obj.reload
|
510
|
-
_(obj.time_7).must_equal Time.utc(2000,
|
514
|
+
_(obj.time_7).must_equal Time.utc(2000, 1, 1, 15, 45, 0, 234567), "Microseconds were <#{obj.time_7.usec}> vs <234567>"
|
511
515
|
# Time's #usec precision (high nano rounded)
|
512
|
-
obj.time_7 = Time.utc(2000,
|
513
|
-
_(obj.time_7).must_equal Time.utc(2000,
|
516
|
+
obj.time_7 = Time.utc(2000, 1, 1, 15, 45, 0, Rational(288321545, 1000))
|
517
|
+
_(obj.time_7).must_equal Time.utc(2000, 1, 1, 15, 45, 0, Rational(288321500, 1000)), "Nanoseconds were <#{obj.time_7.nsec}> vs <288321500>"
|
514
518
|
obj.save!; obj.reload
|
515
|
-
_(obj.time_7).must_equal Time.utc(2000,
|
519
|
+
_(obj.time_7).must_equal Time.utc(2000, 1, 1, 15, 45, 0, Rational(288321500, 1000)), "Nanoseconds were <#{obj.time_7.nsec}> vs <288321500>"
|
516
520
|
end
|
517
521
|
|
518
522
|
it "time(2)" do
|
@@ -529,20 +533,20 @@ class ColumnTestSQLServer < ActiveRecord::TestCase
|
|
529
533
|
_(type.precision).must_equal 2
|
530
534
|
_(type.scale).must_be_nil
|
531
535
|
# Always uses TinyTDS/Windows 2000-01-01 convention too.
|
532
|
-
obj.time_2 = Time.utc(2015,
|
533
|
-
_(obj.time_2).must_equal Time.utc(2000,
|
536
|
+
obj.time_2 = Time.utc(2015, 1, 10, 15, 45, 0, 0)
|
537
|
+
_(obj.time_2).must_equal Time.utc(2000, 1, 1, 15, 45, 0, 0)
|
534
538
|
obj.save!; obj.reload
|
535
|
-
_(obj.time_2).must_equal Time.utc(2000,
|
539
|
+
_(obj.time_2).must_equal Time.utc(2000, 1, 1, 15, 45, 0, 0)
|
536
540
|
# Time's #usec precision (barely in 2 precision equal to 0.03 seconds)
|
537
|
-
obj.time_2 = Time.utc(2000,
|
538
|
-
_(obj.time_2).must_equal Time.utc(2000,
|
541
|
+
obj.time_2 = Time.utc(2000, 1, 1, 15, 45, 0, 30000)
|
542
|
+
_(obj.time_2).must_equal Time.utc(2000, 1, 1, 15, 45, 0, 30000), "Microseconds were <#{obj.time_2.usec}> vs <30000>"
|
539
543
|
obj.save!; obj.reload
|
540
|
-
_(obj.time_2).must_equal Time.utc(2000,
|
544
|
+
_(obj.time_2).must_equal Time.utc(2000, 1, 1, 15, 45, 0, 30000), "Microseconds were <#{obj.time_2.usec}> vs <30000>"
|
541
545
|
# Time's #usec precision (below 2 precision)
|
542
|
-
obj.time_2 = Time.utc(2000,
|
543
|
-
_(obj.time_2).must_equal Time.utc(2000,
|
546
|
+
obj.time_2 = Time.utc(2000, 1, 1, 15, 45, 0, 4000)
|
547
|
+
_(obj.time_2).must_equal Time.utc(2000, 1, 1, 15, 45, 0, 0), "Microseconds were <#{obj.time_2.usec}> vs <0>"
|
544
548
|
obj.save!; obj.reload
|
545
|
-
_(obj.time_2).must_equal Time.utc(2000,
|
549
|
+
_(obj.time_2).must_equal Time.utc(2000, 1, 1, 15, 45, 0, 0), "Microseconds were <#{obj.time_2.usec}> vs <0>"
|
546
550
|
end
|
547
551
|
|
548
552
|
it "time using default precision" do
|
@@ -551,7 +555,7 @@ class ColumnTestSQLServer < ActiveRecord::TestCase
|
|
551
555
|
_(col.sql_type).must_equal "time(7)"
|
552
556
|
_(col.type).must_equal :time
|
553
557
|
_(col.null).must_equal true
|
554
|
-
_(col.default).must_equal Time.utc(1900,
|
558
|
+
_(col.default).must_equal Time.utc(1900, 1, 1, 15, 3, 42, Rational(62197800, 1000)), "Nanoseconds were <#{col.default.nsec}> vs <62197800>"
|
555
559
|
_(col.default_function).must_be_nil
|
556
560
|
type = connection.lookup_cast_type_from_column(col)
|
557
561
|
_(type).must_be_instance_of Type::Time
|
@@ -559,22 +563,22 @@ class ColumnTestSQLServer < ActiveRecord::TestCase
|
|
559
563
|
_(type.precision).must_equal 7
|
560
564
|
_(type.scale).must_be_nil
|
561
565
|
# Time's #usec precision (low micro)
|
562
|
-
obj.time_default = Time.utc(2000,
|
563
|
-
_(obj.time_default).must_equal Time.utc(2000,
|
564
|
-
_(obj.time_default).must_equal Time.utc(2000,
|
566
|
+
obj.time_default = Time.utc(2000, 1, 1, 15, 45, 0, 300)
|
567
|
+
_(obj.time_default).must_equal Time.utc(2000, 1, 1, 15, 45, 0, 300), "Microseconds were <#{obj.time_default.usec}> vs <0>"
|
568
|
+
_(obj.time_default).must_equal Time.utc(2000, 1, 1, 15, 45, 0, 300), "Nanoseconds were <#{obj.time_default.nsec}> vs <300>"
|
565
569
|
obj.save!; obj.reload
|
566
|
-
_(obj.time_default).must_equal Time.utc(2000,
|
567
|
-
_(obj.time_default).must_equal Time.utc(2000,
|
570
|
+
_(obj.time_default).must_equal Time.utc(2000, 1, 1, 15, 45, 0, 300), "Microseconds were <#{obj.time_default.usec}> vs <0>"
|
571
|
+
_(obj.time_default).must_equal Time.utc(2000, 1, 1, 15, 45, 0, 300), "Nanoseconds were <#{obj.time_default.nsec}> vs <300>"
|
568
572
|
# Time's #usec precision (high micro)
|
569
|
-
obj.time_default = Time.utc(2000,
|
570
|
-
_(obj.time_default).must_equal Time.utc(2000,
|
573
|
+
obj.time_default = Time.utc(2000, 1, 1, 15, 45, 0, 234567)
|
574
|
+
_(obj.time_default).must_equal Time.utc(2000, 1, 1, 15, 45, 0, 234567), "Microseconds were <#{obj.time_default.usec}> vs <234567>"
|
571
575
|
obj.save!; obj.reload
|
572
|
-
_(obj.time_default).must_equal Time.utc(2000,
|
576
|
+
_(obj.time_default).must_equal Time.utc(2000, 1, 1, 15, 45, 0, 234567), "Microseconds were <#{obj.time_default.usec}> vs <234567>"
|
573
577
|
# Time's #usec precision (high nano rounded)
|
574
|
-
obj.time_default = Time.utc(2000,
|
575
|
-
_(obj.time_default).must_equal Time.utc(2000,
|
578
|
+
obj.time_default = Time.utc(2000, 1, 1, 15, 45, 0, Rational(288321545, 1000))
|
579
|
+
_(obj.time_default).must_equal Time.utc(2000, 1, 1, 15, 45, 0, Rational(288321500, 1000)), "Nanoseconds were <#{obj.time_default.nsec}> vs <288321500>"
|
576
580
|
obj.save!; obj.reload
|
577
|
-
_(obj.time_default).must_equal Time.utc(2000,
|
581
|
+
_(obj.time_default).must_equal Time.utc(2000, 1, 1, 15, 45, 0, Rational(288321500, 1000)), "Nanoseconds were <#{obj.time_default.nsec}> vs <288321500>"
|
578
582
|
end
|
579
583
|
|
580
584
|
# Character Strings
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require "cases/helper_sqlserver"
|
2
|
+
require "models/citation"
|
3
|
+
require "models/book"
|
4
|
+
|
5
|
+
class EagerLoadingTooManyIdsTest < ActiveRecord::TestCase
|
6
|
+
fixtures :citations
|
7
|
+
|
8
|
+
def test_batch_preloading_too_many_ids
|
9
|
+
in_clause_length = 10_000
|
10
|
+
|
11
|
+
# We Monkey patch Preloader to work with batches of 10_000 records.
|
12
|
+
# Expect: N Books queries + Citation query
|
13
|
+
expected_query_count = (Citation.count / in_clause_length.to_f).ceil + 1
|
14
|
+
assert_queries(expected_query_count) do
|
15
|
+
Citation.preload(:reference_of).to_a.size
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -49,3 +49,21 @@ class FetchTestSqlserver < ActiveRecord::TestCase
|
|
49
49
|
@books = (1..10).map { |i| Book.create! name: "Name-#{i}" }
|
50
50
|
end
|
51
51
|
end
|
52
|
+
|
53
|
+
class DeterministicFetchWithCompositePkTestSQLServer < ActiveRecord::TestCase
|
54
|
+
it "orders by the identity column if table has one" do
|
55
|
+
SSCompositePkWithIdentity.delete_all
|
56
|
+
SSCompositePkWithIdentity.create(pk_col_two: 2)
|
57
|
+
SSCompositePkWithIdentity.create(pk_col_two: 1)
|
58
|
+
|
59
|
+
_(SSCompositePkWithIdentity.take(1).map(&:pk_col_two)).must_equal [2]
|
60
|
+
end
|
61
|
+
|
62
|
+
it "orders by the first column if table has no identity column" do
|
63
|
+
SSCompositePkWithoutIdentity.delete_all
|
64
|
+
SSCompositePkWithoutIdentity.create(pk_col_one: 2, pk_col_two: 2)
|
65
|
+
SSCompositePkWithoutIdentity.create(pk_col_one: 1, pk_col_two: 1)
|
66
|
+
|
67
|
+
_(SSCompositePkWithoutIdentity.take(1).map(&:pk_col_two)).must_equal [1]
|
68
|
+
end
|
69
|
+
end
|
@@ -156,3 +156,39 @@ class SQLServerRakeStructureDumpLoadTest < SQLServerRakeTest
|
|
156
156
|
_(connection.tables).must_include "users"
|
157
157
|
end
|
158
158
|
end
|
159
|
+
|
160
|
+
class SQLServerRakeSchemaCacheDumpLoadTest < SQLServerRakeTest
|
161
|
+
let(:filename) { File.join ARTest::SQLServer.test_root_sqlserver, "schema_cache.yml" }
|
162
|
+
let(:filedata) { File.read(filename) }
|
163
|
+
|
164
|
+
before do
|
165
|
+
quietly { db_tasks.create(configuration) }
|
166
|
+
|
167
|
+
connection.create_table :users, force: true do |t|
|
168
|
+
t.string :name, null: false
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
after do
|
173
|
+
FileUtils.rm_rf(filename)
|
174
|
+
end
|
175
|
+
|
176
|
+
it "dumps schema cache with SQL Server metadata" do
|
177
|
+
quietly { db_tasks.dump_schema_cache connection, filename }
|
178
|
+
|
179
|
+
filedata = File.read(filename)
|
180
|
+
schema_cache = YAML.respond_to?(:unsafe_load) ? YAML.unsafe_load(filedata) : YAML.load(filedata)
|
181
|
+
|
182
|
+
col_id, col_name = connection.schema_cache.columns("users")
|
183
|
+
|
184
|
+
assert col_id.is_identity
|
185
|
+
assert col_id.is_primary
|
186
|
+
assert_equal col_id.ordinal_position, 1
|
187
|
+
assert_equal col_id.table_name, "users"
|
188
|
+
|
189
|
+
assert_not col_name.is_identity
|
190
|
+
assert_not col_name.is_primary
|
191
|
+
assert_equal col_name.ordinal_position, 2
|
192
|
+
assert_equal col_name.table_name, "users"
|
193
|
+
end
|
194
|
+
end
|
@@ -67,7 +67,7 @@ class SchemaDumperTestSQLServer < ActiveRecord::TestCase
|
|
67
67
|
_(columns["float_col"].sql_type).must_equal "float"
|
68
68
|
_(columns["string_col"].sql_type).must_equal "nvarchar(4000)"
|
69
69
|
_(columns["text_col"].sql_type).must_equal "nvarchar(max)"
|
70
|
-
_(columns["datetime_col"].sql_type).must_equal "
|
70
|
+
_(columns["datetime_col"].sql_type).must_equal "datetime2(6)"
|
71
71
|
_(columns["timestamp_col"].sql_type).must_equal "datetime"
|
72
72
|
_(columns["time_col"].sql_type).must_equal "time(7)"
|
73
73
|
_(columns["date_col"].sql_type).must_equal "date"
|
@@ -79,7 +79,7 @@ class SchemaDumperTestSQLServer < ActiveRecord::TestCase
|
|
79
79
|
assert_line :float_col, type: "float", limit: nil, precision: nil, scale: nil, default: nil
|
80
80
|
assert_line :string_col, type: "string", limit: nil, precision: nil, scale: nil, default: nil
|
81
81
|
assert_line :text_col, type: "text", limit: nil, precision: nil, scale: nil, default: nil
|
82
|
-
assert_line :datetime_col, type: "datetime", limit: nil, precision:
|
82
|
+
assert_line :datetime_col, type: "datetime", limit: nil, precision: 6, scale: nil, default: nil
|
83
83
|
assert_line :timestamp_col, type: "datetime", limit: nil, precision: nil, scale: nil, default: nil
|
84
84
|
assert_line :time_col, type: "time", limit: nil, precision: 7, scale: nil, default: nil
|
85
85
|
assert_line :date_col, type: "date", limit: nil, precision: nil, scale: nil, default: nil
|
@@ -294,4 +294,22 @@ ActiveRecord::Schema.define do
|
|
294
294
|
CONSTRAINT PK_UNIQUE_KEY PRIMARY KEY (id)
|
295
295
|
);
|
296
296
|
SQLSERVERUNIQUEKEYS
|
297
|
+
|
298
|
+
execute "IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'sst_composite_without_identity') DROP TABLE sst_composite_without_identity"
|
299
|
+
execute <<-COMPOSITE_WITHOUT_IDENTITY
|
300
|
+
CREATE TABLE sst_composite_without_identity (
|
301
|
+
pk_col_one int NOT NULL,
|
302
|
+
pk_col_two int NOT NULL,
|
303
|
+
CONSTRAINT PK_sst_composite_without_identity PRIMARY KEY (pk_col_one, pk_col_two)
|
304
|
+
);
|
305
|
+
COMPOSITE_WITHOUT_IDENTITY
|
306
|
+
|
307
|
+
execute "IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'sst_composite_with_identity') DROP TABLE sst_composite_with_identity"
|
308
|
+
execute <<-COMPOSITE_WITH_IDENTITY
|
309
|
+
CREATE TABLE sst_composite_with_identity (
|
310
|
+
pk_col_one int IDENTITY NOT NULL,
|
311
|
+
pk_col_two int NOT NULL,
|
312
|
+
CONSTRAINT PK_sst_composite_with_identity PRIMARY KEY (pk_col_one, pk_col_two)
|
313
|
+
);
|
314
|
+
COMPOSITE_WITH_IDENTITY
|
297
315
|
end
|
@@ -13,7 +13,7 @@ module ARTest
|
|
13
13
|
module ClassMethods
|
14
14
|
def coerce_tests!(*methods)
|
15
15
|
methods.each do |method|
|
16
|
-
|
16
|
+
coerced_tests.push(method)
|
17
17
|
coerced_test_warning(method)
|
18
18
|
end
|
19
19
|
end
|
@@ -24,7 +24,7 @@ module ARTest
|
|
24
24
|
|
25
25
|
undef_method(method)
|
26
26
|
end
|
27
|
-
STDOUT.puts "🙉 🙈 🙊 Undefined all tests: #{
|
27
|
+
STDOUT.puts "🙉 🙈 🙊 Undefined all tests: #{name}"
|
28
28
|
end
|
29
29
|
|
30
30
|
private
|
@@ -43,9 +43,9 @@ module ARTest
|
|
43
43
|
end
|
44
44
|
|
45
45
|
if result.blank?
|
46
|
-
STDOUT.puts "🐳 Unfound coerced test: #{
|
46
|
+
STDOUT.puts "🐳 Unfound coerced test: #{name}##{m}"
|
47
47
|
else
|
48
|
-
STDOUT.puts "🐵 Undefined coerced test: #{
|
48
|
+
STDOUT.puts "🐵 Undefined coerced test: #{name}##{m}"
|
49
49
|
end
|
50
50
|
end
|
51
51
|
end
|
Binary file
|
@@ -25,7 +25,9 @@ end
|
|
25
25
|
|
26
26
|
def ar_cases
|
27
27
|
@ar_cases ||= begin
|
28
|
-
Dir.glob("#{ARTest::SQLServer.root_activerecord}/test/cases/**/*_test.rb").reject {
|
28
|
+
Dir.glob("#{ARTest::SQLServer.root_activerecord}/test/cases/**/*_test.rb").reject {
|
29
|
+
|x| x.include?("/adapters/") || x.include?("/encryption/performance")
|
30
|
+
}.sort
|
29
31
|
end
|
30
32
|
end
|
31
33
|
|
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:
|
4
|
+
version: 7.0.0.0.rc1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ken Collins
|
@@ -14,7 +14,7 @@ authors:
|
|
14
14
|
autorequire:
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
|
-
date:
|
17
|
+
date: 2022-01-18 00:00:00.000000000 Z
|
18
18
|
dependencies:
|
19
19
|
- !ruby/object:Gem::Dependency
|
20
20
|
name: activerecord
|
@@ -22,14 +22,14 @@ dependencies:
|
|
22
22
|
requirements:
|
23
23
|
- - "~>"
|
24
24
|
- !ruby/object:Gem::Version
|
25
|
-
version:
|
25
|
+
version: 7.0.0
|
26
26
|
type: :runtime
|
27
27
|
prerelease: false
|
28
28
|
version_requirements: !ruby/object:Gem::Requirement
|
29
29
|
requirements:
|
30
30
|
- - "~>"
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version:
|
32
|
+
version: 7.0.0
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: tiny_tds
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -78,7 +78,6 @@ files:
|
|
78
78
|
- lib/active_record/connection_adapters/sqlserver/core_ext/explain_subscriber.rb
|
79
79
|
- lib/active_record/connection_adapters/sqlserver/core_ext/finder_methods.rb
|
80
80
|
- lib/active_record/connection_adapters/sqlserver/core_ext/preloader.rb
|
81
|
-
- lib/active_record/connection_adapters/sqlserver/core_ext/query_methods.rb
|
82
81
|
- lib/active_record/connection_adapters/sqlserver/database_limits.rb
|
83
82
|
- lib/active_record/connection_adapters/sqlserver/database_statements.rb
|
84
83
|
- lib/active_record/connection_adapters/sqlserver/database_tasks.rb
|
@@ -150,6 +149,7 @@ files:
|
|
150
149
|
- test/cases/column_test_sqlserver.rb
|
151
150
|
- test/cases/connection_test_sqlserver.rb
|
152
151
|
- test/cases/disconnected_test_sqlserver.rb
|
152
|
+
- test/cases/eager_load_too_many_ids_test_sqlserver.rb
|
153
153
|
- test/cases/execute_procedure_test_sqlserver.rb
|
154
154
|
- test/cases/fetch_test_sqlserver.rb
|
155
155
|
- test/cases/fully_qualified_identifier_test_sqlserver.rb
|
@@ -180,6 +180,7 @@ files:
|
|
180
180
|
- test/migrations/create_clients_and_change_column_null.rb
|
181
181
|
- test/migrations/transaction_table/1_table_will_never_be_created.rb
|
182
182
|
- test/models/sqlserver/booking.rb
|
183
|
+
- test/models/sqlserver/composite_pk.rb
|
183
184
|
- test/models/sqlserver/customers_view.rb
|
184
185
|
- test/models/sqlserver/datatype.rb
|
185
186
|
- test/models/sqlserver/datatype_migration.rb
|
@@ -212,8 +213,8 @@ files:
|
|
212
213
|
- test/support/connection_reflection.rb
|
213
214
|
- test/support/core_ext/query_cache.rb
|
214
215
|
- test/support/load_schema_sqlserver.rb
|
215
|
-
- test/support/marshal_compatibility_fixtures/SQLServer/
|
216
|
-
- test/support/marshal_compatibility_fixtures/SQLServer/
|
216
|
+
- test/support/marshal_compatibility_fixtures/SQLServer/rails_6_1_topic.dump
|
217
|
+
- test/support/marshal_compatibility_fixtures/SQLServer/rails_6_1_topic_associations.dump
|
217
218
|
- test/support/minitest_sqlserver.rb
|
218
219
|
- test/support/paths_sqlserver.rb
|
219
220
|
- test/support/rake_helpers.rb
|
@@ -224,8 +225,8 @@ licenses:
|
|
224
225
|
- MIT
|
225
226
|
metadata:
|
226
227
|
bug_tracker_uri: https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/issues
|
227
|
-
changelog_uri: https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/blob/
|
228
|
-
source_code_uri: https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/
|
228
|
+
changelog_uri: https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/blob/v7.0.0.0.rc1/CHANGELOG.md
|
229
|
+
source_code_uri: https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/v7.0.0.0.rc1
|
229
230
|
post_install_message:
|
230
231
|
rdoc_options: []
|
231
232
|
require_paths:
|
@@ -234,14 +235,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
234
235
|
requirements:
|
235
236
|
- - ">="
|
236
237
|
- !ruby/object:Gem::Version
|
237
|
-
version: 2.
|
238
|
+
version: 2.7.0
|
238
239
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
239
240
|
requirements:
|
240
|
-
- - "
|
241
|
+
- - ">"
|
241
242
|
- !ruby/object:Gem::Version
|
242
|
-
version:
|
243
|
+
version: 1.3.1
|
243
244
|
requirements: []
|
244
|
-
rubygems_version: 3.2.
|
245
|
+
rubygems_version: 3.2.22
|
245
246
|
signing_key:
|
246
247
|
specification_version: 4
|
247
248
|
summary: ActiveRecord SQL Server Adapter.
|
@@ -258,6 +259,7 @@ test_files:
|
|
258
259
|
- test/cases/column_test_sqlserver.rb
|
259
260
|
- test/cases/connection_test_sqlserver.rb
|
260
261
|
- test/cases/disconnected_test_sqlserver.rb
|
262
|
+
- test/cases/eager_load_too_many_ids_test_sqlserver.rb
|
261
263
|
- test/cases/execute_procedure_test_sqlserver.rb
|
262
264
|
- test/cases/fetch_test_sqlserver.rb
|
263
265
|
- test/cases/fully_qualified_identifier_test_sqlserver.rb
|
@@ -288,6 +290,7 @@ test_files:
|
|
288
290
|
- test/migrations/create_clients_and_change_column_null.rb
|
289
291
|
- test/migrations/transaction_table/1_table_will_never_be_created.rb
|
290
292
|
- test/models/sqlserver/booking.rb
|
293
|
+
- test/models/sqlserver/composite_pk.rb
|
291
294
|
- test/models/sqlserver/customers_view.rb
|
292
295
|
- test/models/sqlserver/datatype.rb
|
293
296
|
- test/models/sqlserver/datatype_migration.rb
|
@@ -320,8 +323,8 @@ test_files:
|
|
320
323
|
- test/support/connection_reflection.rb
|
321
324
|
- test/support/core_ext/query_cache.rb
|
322
325
|
- test/support/load_schema_sqlserver.rb
|
323
|
-
- test/support/marshal_compatibility_fixtures/SQLServer/
|
324
|
-
- test/support/marshal_compatibility_fixtures/SQLServer/
|
326
|
+
- test/support/marshal_compatibility_fixtures/SQLServer/rails_6_1_topic.dump
|
327
|
+
- test/support/marshal_compatibility_fixtures/SQLServer/rails_6_1_topic_associations.dump
|
325
328
|
- test/support/minitest_sqlserver.rb
|
326
329
|
- test/support/paths_sqlserver.rb
|
327
330
|
- test/support/rake_helpers.rb
|
@@ -1,28 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "active_record/relation"
|
4
|
-
require "active_record/version"
|
5
|
-
|
6
|
-
module ActiveRecord
|
7
|
-
module ConnectionAdapters
|
8
|
-
module SQLServer
|
9
|
-
module CoreExt
|
10
|
-
module QueryMethods
|
11
|
-
private
|
12
|
-
|
13
|
-
# Copy of original from Rails master.
|
14
|
-
# This patch can be removed when adapter supports Rails version greater than 6.0.2.2
|
15
|
-
def table_name_matches?(from)
|
16
|
-
table_name = Regexp.escape(table.name)
|
17
|
-
quoted_table_name = Regexp.escape(connection.quote_table_name(table.name))
|
18
|
-
/(?:\A|(?<!FROM)\s)(?:\b#{table_name}\b|#{quoted_table_name})(?!\.)/i.match?(from.to_s)
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
ActiveSupport.on_load(:active_record) do
|
27
|
-
ActiveRecord::Relation.include(ActiveRecord::ConnectionAdapters::SQLServer::CoreExt::QueryMethods)
|
28
|
-
end
|
Binary file
|