activerecord-jdbcsqlserver-adapter 50.0.0 → 52.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -1
  3. data/.travis.yml +4 -5
  4. data/CHANGELOG.md +22 -101
  5. data/{Dockerfile → Dockerfile.ci} +0 -0
  6. data/Gemfile +1 -3
  7. data/README.md +5 -9
  8. data/VERSION +1 -1
  9. data/activerecord-jdbcsqlserver-adapter.gemspec +2 -2
  10. data/appveyor.yml +1 -1
  11. data/docker-compose.ci.yml +7 -5
  12. data/lib/active_record/connection_adapters/sqlserver/core_ext/active_record.rb +3 -1
  13. data/lib/active_record/connection_adapters/sqlserver/core_ext/attribute_methods.rb +3 -1
  14. data/lib/active_record/connection_adapters/sqlserver/core_ext/calculations.rb +51 -0
  15. data/lib/active_record/connection_adapters/sqlserver/core_ext/explain.rb +18 -20
  16. data/lib/active_record/connection_adapters/sqlserver/core_ext/explain_subscriber.rb +5 -3
  17. data/lib/active_record/connection_adapters/sqlserver/core_ext/finder_methods.rb +43 -0
  18. data/lib/active_record/connection_adapters/sqlserver/core_ext/query_methods.rb +26 -0
  19. data/lib/active_record/connection_adapters/sqlserver/database_limits.rb +13 -2
  20. data/lib/active_record/connection_adapters/sqlserver/database_statements.rb +94 -28
  21. data/lib/active_record/connection_adapters/sqlserver/database_tasks.rb +1 -0
  22. data/lib/active_record/connection_adapters/sqlserver/jdbc_overrides.rb +5 -25
  23. data/lib/active_record/connection_adapters/sqlserver/schema_creation.rb +24 -1
  24. data/lib/active_record/connection_adapters/sqlserver/schema_dumper.rb +23 -2
  25. data/lib/active_record/connection_adapters/sqlserver/schema_statements.rb +110 -74
  26. data/lib/active_record/connection_adapters/sqlserver/table_definition.rb +15 -7
  27. data/lib/active_record/connection_adapters/sqlserver/transaction.rb +3 -4
  28. data/lib/active_record/connection_adapters/sqlserver/type/big_integer.rb +0 -4
  29. data/lib/active_record/connection_adapters/sqlserver/type/data.rb +5 -0
  30. data/lib/active_record/connection_adapters/sqlserver/type/datetime.rb +3 -6
  31. data/lib/active_record/connection_adapters/sqlserver/type/json.rb +1 -1
  32. data/lib/active_record/connection_adapters/sqlserver/type/string.rb +7 -0
  33. data/lib/active_record/connection_adapters/sqlserver/type/time.rb +1 -0
  34. data/lib/active_record/connection_adapters/sqlserver_adapter.rb +47 -24
  35. data/lib/active_record/tasks/sqlserver_database_tasks.rb +5 -3
  36. data/lib/activerecord-jdbcsqlserver-adapter.rb +4 -1
  37. data/lib/arel/visitors/sqlserver.rb +17 -4
  38. data/lib/arel_sqlserver.rb +0 -1
  39. data/lib/jdbc_mssql_driver_loader.rb +22 -0
  40. data/test/bin/install-freetds.sh +18 -0
  41. data/test/bin/setup.sh +19 -0
  42. data/test/cases/adapter_test_sqlserver.rb +43 -39
  43. data/test/cases/change_column_null_test_sqlserver.rb +42 -0
  44. data/test/cases/coerced_tests.rb +419 -39
  45. data/test/cases/column_test_sqlserver.rb +496 -462
  46. data/test/cases/connection_test_sqlserver.rb +2 -2
  47. data/test/cases/fetch_test_sqlserver.rb +5 -5
  48. data/test/cases/helper_sqlserver.rb +12 -1
  49. data/test/cases/json_test_sqlserver.rb +6 -6
  50. data/test/cases/migration_test_sqlserver.rb +13 -3
  51. data/test/cases/order_test_sqlserver.rb +19 -19
  52. data/test/cases/pessimistic_locking_test_sqlserver.rb +37 -20
  53. data/test/cases/rake_test_sqlserver.rb +20 -20
  54. data/test/cases/schema_dumper_test_sqlserver.rb +44 -43
  55. data/test/cases/schema_test_sqlserver.rb +2 -2
  56. data/test/cases/showplan_test_sqlserver.rb +25 -10
  57. data/test/cases/specific_schema_test_sqlserver.rb +11 -17
  58. data/test/cases/transaction_test_sqlserver.rb +9 -9
  59. data/test/cases/trigger_test_sqlserver.rb +31 -0
  60. data/test/cases/utils_test_sqlserver.rb +36 -36
  61. data/test/cases/uuid_test_sqlserver.rb +8 -8
  62. data/test/config.yml +2 -2
  63. data/test/migrations/create_clients_and_change_column_null.rb +23 -0
  64. data/test/models/sqlserver/trigger.rb +7 -0
  65. data/test/models/sqlserver/trigger_history.rb +3 -0
  66. data/test/schema/datatypes/2012.sql +1 -0
  67. data/test/schema/sqlserver_specific_schema.rb +47 -5
  68. data/test/support/core_ext/query_cache.rb +29 -0
  69. data/test/support/sql_counter_sqlserver.rb +1 -1
  70. metadata +32 -15
  71. data/RAILS5-TODO.md +0 -5
  72. data/test/models/sqlserver/dot_table_name.rb +0 -3
@@ -5,7 +5,7 @@ class SchemaTestSQLServer < ActiveRecord::TestCase
5
5
  describe 'When table is dbo schema' do
6
6
 
7
7
  it 'find primary key for tables with odd schema' do
8
- connection.primary_key('sst_natural_pk_data').must_equal 'legacy_id'
8
+ _(connection.primary_key('sst_natural_pk_data')).must_equal 'legacy_id'
9
9
  end
10
10
 
11
11
  end
@@ -18,7 +18,7 @@ class SchemaTestSQLServer < ActiveRecord::TestCase
18
18
  end
19
19
 
20
20
  it 'find primary key for tables with odd schema' do
21
- connection.primary_key('test.sst_schema_natural_id').must_equal 'legacy_id'
21
+ _(connection.primary_key('test.sst_schema_natural_id')).must_equal 'legacy_id'
22
22
  end
23
23
 
24
24
  it "have only one identity column" do
@@ -5,25 +5,40 @@ class ShowplanTestSQLServer < ActiveRecord::TestCase
5
5
 
6
6
  fixtures :cars
7
7
 
8
+ # For some reason the default max width truncates values that we are looking for in jruby
9
+ ActiveRecord::ConnectionAdapters::SQLServer::Showplan::PrinterTable.max_column_width = 500 if defined? JRUBY_VERSION
10
+
8
11
  describe 'Unprepare previously prepared SQL' do
9
12
 
10
13
  it 'from simple statement' do
11
14
  plan = Car.where(id: 1).explain
12
- plan.must_include "SELECT [cars].* FROM [cars] WHERE [cars].[id] = 1"
13
- plan.must_include "Clustered Index Seek", 'make sure we do not showplan the sp_executesql'
15
+ _(plan).must_include "SELECT [cars].* FROM [cars] WHERE [cars].[id] = 1"
16
+ _(plan).must_include "Clustered Index Seek", 'make sure we do not showplan the sp_executesql'
14
17
  end
15
18
 
16
19
  it 'from multiline statement' do
17
20
  plan = Car.where("\n id = 1 \n").explain
18
- plan.must_include "SELECT [cars].* FROM [cars] WHERE (\n id = 1 \n)"
19
- plan.must_include "Clustered Index Seek", 'make sure we do not showplan the sp_executesql'
21
+ _(plan).must_include "SELECT [cars].* FROM [cars] WHERE (\n id = 1 \n)"
22
+ _(plan).must_include "Clustered Index Seek", 'make sure we do not showplan the sp_executesql'
20
23
  end
21
24
 
22
25
  it 'from prepared statement' do
23
26
  plan = Car.where(name: ',').limit(1).explain
24
- plan.must_include " SELECT [cars].* FROM [cars] WHERE [cars].[name]"
25
- plan.must_include "TOP EXPRESSION", 'make sure we do not showplan the sp_executesql'
26
- plan.must_include "Clustered Index Scan", 'make sure we do not showplan the sp_executesql'
27
+ _(plan).must_include " SELECT [cars].* FROM [cars] WHERE [cars].[name]"
28
+ _(plan).must_include "TOP EXPRESSION", 'make sure we do not showplan the sp_executesql'
29
+ _(plan).must_include "Clustered Index Scan", 'make sure we do not showplan the sp_executesql'
30
+ end
31
+
32
+ it 'from array condition using index' do
33
+ plan = Car.where(id: [1, 2]).explain
34
+ _(plan).must_include " SELECT [cars].* FROM [cars] WHERE [cars].[id] IN (1, 2)"
35
+ _(plan).must_include "Clustered Index Seek", 'make sure we do not showplan the sp_executesql'
36
+ end
37
+
38
+ it 'from array condition' do
39
+ plan = Car.where(name: ['honda', 'zyke']).explain
40
+ _(plan).must_include " SELECT [cars].* FROM [cars] WHERE [cars].[name] IN (N'honda', N'zyke')"
41
+ _(plan).must_include "Clustered Index Scan", 'make sure we do not showplan the sp_executesql'
27
42
  end
28
43
 
29
44
  end
@@ -33,8 +48,8 @@ class ShowplanTestSQLServer < ActiveRecord::TestCase
33
48
  it 'use simple table printer' do
34
49
  with_showplan_option('SHOWPLAN_TEXT') do
35
50
  plan = Car.where(id: 1).explain
36
- plan.must_include "SELECT [cars].* FROM [cars] WHERE [cars].[id]"
37
- plan.must_include "Clustered Index Seek", 'make sure we do not showplan the sp_executesql'
51
+ _(plan).must_include "SELECT [cars].* FROM [cars] WHERE [cars].[id]"
52
+ _(plan).must_include "Clustered Index Seek", 'make sure we do not showplan the sp_executesql'
38
53
  end
39
54
  end
40
55
 
@@ -45,7 +60,7 @@ class ShowplanTestSQLServer < ActiveRecord::TestCase
45
60
  it 'show formatted xml' do
46
61
  with_showplan_option('SHOWPLAN_XML') do
47
62
  plan = Car.where(id: 1).explain
48
- plan.must_include 'ShowPlanXML'
63
+ _(plan).must_include 'ShowPlanXML'
49
64
  end
50
65
  end
51
66
 
@@ -9,16 +9,10 @@ class SpecificSchemaTestSQLServer < ActiveRecord::TestCase
9
9
  SSTestDollarTableName.limit(20).offset(1)
10
10
  end
11
11
 
12
- it 'handle dot table names' do
13
- SSTestDotTableName.create! name: 'test'
14
- SSTestDotTableName.limit(20).offset(1)
15
- SSTestDotTableName.where(name: 'test').first.must_be :present?
16
- end
17
-
18
12
  it 'models can use tinyint pk tables' do
19
13
  obj = SSTestTinyintPk.create! name: '1'
20
- ['Fixnum', 'Integer'].must_include obj.id.class.name
21
- SSTestTinyintPk.find(obj.id).must_equal obj
14
+ _(['Fixnum', 'Integer']).must_include obj.id.class.name
15
+ _(SSTestTinyintPk.find(obj.id)).must_equal obj
22
16
  end
23
17
 
24
18
  it 'be able to complex count tables with no primary key' do
@@ -64,17 +58,17 @@ class SpecificSchemaTestSQLServer < ActiveRecord::TestCase
64
58
 
65
59
  it 'default objects work' do
66
60
  obj = SSTestObjectDefault.create! name: 'MetaSkills'
67
- obj.date.must_be_nil 'since this is set on insert'
68
- obj.reload.date.must_be_instance_of Date
61
+ _(obj.date).must_be_nil 'since this is set on insert'
62
+ _(obj.reload.date).must_be_instance_of Date
69
63
  end
70
64
 
71
65
  it 'allows datetime2 as timestamps' do
72
- SSTestBooking.columns_hash['created_at'].sql_type.must_equal 'datetime2(7)'
73
- SSTestBooking.columns_hash['updated_at'].sql_type.must_equal 'datetime2(7)'
66
+ _(SSTestBooking.columns_hash['created_at'].sql_type).must_equal 'datetime2(7)'
67
+ _(SSTestBooking.columns_hash['updated_at'].sql_type).must_equal 'datetime2(7)'
74
68
  obj1 = SSTestBooking.new name: 'test1'
75
69
  obj1.save!
76
- obj1.created_at.must_be_instance_of Time
77
- obj1.updated_at.must_be_instance_of Time
70
+ _(obj1.created_at).must_be_instance_of Time
71
+ _(obj1.updated_at).must_be_instance_of Time
78
72
  end
79
73
 
80
74
  # Natural primary keys.
@@ -134,10 +128,10 @@ class SpecificSchemaTestSQLServer < ActiveRecord::TestCase
134
128
  o = SSTestDatatypeMigration.create!
135
129
  o.varchar_col = "O'Reilly"
136
130
  o.save!
137
- o.reload.varchar_col.must_equal "O'Reilly"
131
+ _(o.reload.varchar_col).must_equal "O'Reilly"
138
132
  o.varchar_col = nil
139
133
  o.save!
140
- o.reload.varchar_col.must_be_nil
134
+ _(o.reload.varchar_col).must_be_nil
141
135
  end
142
136
 
143
137
  # With column names that have spaces
@@ -166,7 +160,7 @@ class SpecificSchemaTestSQLServer < ActiveRecord::TestCase
166
160
  it 'returns a new id via connection newid_function' do
167
161
  acceptable_uuid = ActiveRecord::ConnectionAdapters::SQLServer::Type::Uuid::ACCEPTABLE_UUID
168
162
  db_uuid = ActiveRecord::Base.connection.newid_function
169
- db_uuid.must_match(acceptable_uuid)
163
+ _(db_uuid).must_match(acceptable_uuid)
170
164
  end
171
165
 
172
166
  # with similar table definition in two schemas
@@ -34,22 +34,22 @@ class TransactionTestSQLServer < ActiveRecord::TestCase
34
34
  it 'can use an isolation level and reverts back to starting isolation level' do
35
35
  in_level = nil
36
36
  begin_level = connection.user_options_isolation_level
37
- begin_level.must_match %r{read committed}i
37
+ _(begin_level).must_match %r{read committed}i
38
38
  Ship.transaction(isolation: :serializable) do
39
39
  Ship.create! name: 'Black Pearl'
40
40
  in_level = connection.user_options_isolation_level
41
41
  end
42
42
  after_level = connection.user_options_isolation_level
43
- in_level.must_match %r{serializable}i
44
- after_level.must_match %r{read committed}i
43
+ _(in_level).must_match %r{serializable}i
44
+ _(after_level).must_match %r{read committed}i
45
45
  end
46
46
 
47
47
  it 'can use an isolation level and reverts back to starting isolation level under exceptions' do
48
- connection.user_options_isolation_level.must_match %r{read committed}i
49
- lambda {
48
+ _(connection.user_options_isolation_level).must_match %r{read committed}i
49
+ _(lambda {
50
50
  Ship.transaction(isolation: :serializable) { Ship.create! }
51
- }.must_raise(ActiveRecord::RecordInvalid)
52
- connection.user_options_isolation_level.must_match %r{read committed}i
51
+ }).must_raise(ActiveRecord::RecordInvalid)
52
+ _(connection.user_options_isolation_level).must_match %r{read committed}i
53
53
  end
54
54
 
55
55
  describe 'when READ_COMMITTED_SNAPSHOT is set' do
@@ -64,7 +64,7 @@ class TransactionTestSQLServer < ActiveRecord::TestCase
64
64
  end
65
65
 
66
66
  it 'should use READ COMMITTED as an isolation level' do
67
- connection.user_options_isolation_level.must_match "read committed snapshot"
67
+ _(connection.user_options_isolation_level).must_match "read committed snapshot"
68
68
 
69
69
  Ship.transaction(isolation: :serializable) do
70
70
  Ship.create! name: 'Black Pearl'
@@ -73,7 +73,7 @@ class TransactionTestSQLServer < ActiveRecord::TestCase
73
73
  # We're actually testing that the isolation level was correctly reset to
74
74
  # "READ COMMITTED", and that no exception was raised (it's reported back
75
75
  # by SQL Server as "read committed snapshot").
76
- connection.user_options_isolation_level.must_match "read committed snapshot"
76
+ _(connection.user_options_isolation_level).must_match "read committed snapshot"
77
77
  end
78
78
  end
79
79
 
@@ -0,0 +1,31 @@
1
+ # encoding: UTF-8
2
+ require 'cases/helper_sqlserver'
3
+
4
+ class SQLServerTriggerTest < ActiveRecord::TestCase
5
+ after { exclude_output_inserted_table_names.clear }
6
+
7
+ let(:exclude_output_inserted_table_names) do
8
+ ActiveRecord::ConnectionAdapters::SQLServerAdapter.exclude_output_inserted_table_names
9
+ end
10
+
11
+ it 'can insert into a table with output inserted - with a true setting for table name' do
12
+ exclude_output_inserted_table_names['sst_table_with_trigger'] = true
13
+ assert SSTestTriggerHistory.all.empty?
14
+ obj = SSTestTrigger.create! event_name: 'test trigger'
15
+ _(['Fixnum', 'Integer']).must_include obj.id.class.name
16
+ _(obj.event_name).must_equal 'test trigger'
17
+ _(obj.id).must_be :present?
18
+ _(obj.id.to_s).must_equal SSTestTriggerHistory.first.id_source
19
+ end
20
+
21
+ it 'can insert into a table with output inserted - with a uniqueidentifier value' do
22
+ skip 'OUTPUT.inserted not supported at this point' if defined? JRUBY_VERSION
23
+ exclude_output_inserted_table_names['sst_table_with_uuid_trigger'] = 'uniqueidentifier'
24
+ assert SSTestTriggerHistory.all.empty?
25
+ obj = SSTestTriggerUuid.create! event_name: 'test uuid trigger'
26
+ _(obj.id.class.name).must_equal 'String'
27
+ _(obj.event_name).must_equal 'test uuid trigger'
28
+ _(obj.id).must_be :present?
29
+ _(obj.id.to_s).must_equal SSTestTriggerHistory.first.id_source
30
+ end
31
+ end
@@ -3,15 +3,15 @@ require 'cases/helper_sqlserver'
3
3
  class UtilsTestSQLServer < ActiveRecord::TestCase
4
4
 
5
5
  it '.quote_string' do
6
- SQLServer::Utils.quote_string("I'll store this in C:\\Users").must_equal "I''ll store this in C:\\Users"
6
+ _(SQLServer::Utils.quote_string("I'll store this in C:\\Users")).must_equal "I''ll store this in C:\\Users"
7
7
  end
8
8
 
9
9
  it '.unquote_string' do
10
- SQLServer::Utils.unquote_string("I''ll store this in C:\\Users").must_equal "I'll store this in C:\\Users"
10
+ _(SQLServer::Utils.unquote_string("I''ll store this in C:\\Users")).must_equal "I'll store this in C:\\Users"
11
11
  end
12
12
 
13
13
  it '.quoted_raw' do
14
- SQLServer::Utils.quoted_raw("some.Name").must_equal "[some.Name]"
14
+ _(SQLServer::Utils.quoted_raw("some.Name")).must_equal "[some.Name]"
15
15
  end
16
16
 
17
17
  describe '.extract_identifiers constructor and thus SQLServer::Utils::Name value object' do
@@ -47,8 +47,8 @@ class UtilsTestSQLServer < ActiveRecord::TestCase
47
47
  it 'extracts and returns #object identifier unquoted by default or quoted as needed' do
48
48
  valid_names.each do |n|
49
49
  name = extract_identifiers(n)
50
- name.object.must_equal 'object', "With #{n.inspect} for #object"
51
- name.object_quoted.must_equal '[object]', "With #{n.inspect} for #object_quoted"
50
+ _(name.object).must_equal 'object', "With #{n.inspect} for #object"
51
+ _(name.object_quoted).must_equal '[object]', "With #{n.inspect} for #object_quoted"
52
52
  end
53
53
  end
54
54
 
@@ -58,64 +58,64 @@ class UtilsTestSQLServer < ActiveRecord::TestCase
58
58
  present, blank = send(:"#{part}_names")
59
59
  present.each do |n|
60
60
  name = extract_identifiers(n)
61
- name.send(:"#{part}").must_equal "#{part}", "With #{n.inspect} for ##{part} method"
62
- name.send(:"#{part}_quoted").must_equal "[#{part}]", "With #{n.inspect} for ##{part}_quoted method"
61
+ _(name.send(:"#{part}")).must_equal "#{part}", "With #{n.inspect} for ##{part} method"
62
+ _(name.send(:"#{part}_quoted")).must_equal "[#{part}]", "With #{n.inspect} for ##{part}_quoted method"
63
63
  end
64
64
  blank.each do |n|
65
65
  name = extract_identifiers(n)
66
- name.send(:"#{part}").must_be_nil "With #{n.inspect} for ##{part} method"
67
- name.send(:"#{part}_quoted").must_be_nil "With #{n.inspect} for ##{part}_quoted method"
66
+ _(name.send(:"#{part}")).must_be_nil "With #{n.inspect} for ##{part} method"
67
+ _(name.send(:"#{part}_quoted")).must_be_nil "With #{n.inspect} for ##{part}_quoted method"
68
68
  end
69
69
  end
70
70
 
71
71
  end
72
72
 
73
73
  it 'does not blow up on nil or blank string name' do
74
- extract_identifiers(nil).object.must_be_nil
75
- extract_identifiers(' ').object.must_be_nil
74
+ _(extract_identifiers(nil).object).must_be_nil
75
+ _(extract_identifiers(' ').object).must_be_nil
76
76
  end
77
77
 
78
78
  it 'has a #quoted that returns a fully quoted name with all identifiers as orginially passed in' do
79
- extract_identifiers('object').quoted.must_equal '[object]'
80
- extract_identifiers('server.database..object').quoted.must_equal '[server].[database]..[object]'
81
- extract_identifiers('[server]...[object]').quoted.must_equal '[server]...[object]'
79
+ _(extract_identifiers('object').quoted).must_equal '[object]'
80
+ _(extract_identifiers('server.database..object').quoted).must_equal '[server].[database]..[object]'
81
+ _(extract_identifiers('[server]...[object]').quoted).must_equal '[server]...[object]'
82
82
  end
83
83
 
84
84
  it 'can take a symbol argument' do
85
- extract_identifiers(:object).object.must_equal 'object'
85
+ _(extract_identifiers(:object).object).must_equal 'object'
86
86
  end
87
87
 
88
88
  it 'allows identifiers with periods to work' do
89
- extract_identifiers('[obj.name]').quoted.must_equal '[obj.name]'
90
- extract_identifiers('[obj.name].[foo]').quoted.must_equal '[obj.name].[foo]'
89
+ _(extract_identifiers('[obj.name]').quoted).must_equal '[obj.name]'
90
+ _(extract_identifiers('[obj.name].[foo]').quoted).must_equal '[obj.name].[foo]'
91
91
  end
92
92
 
93
93
  it 'should indicate if a name is fully qualitified' do
94
- extract_identifiers('object').fully_qualified?.must_equal false
95
- extract_identifiers('schema.object').fully_qualified?.must_equal false
96
- extract_identifiers('database.schema.object').fully_qualified?.must_equal false
97
- extract_identifiers('database.object').fully_qualified?.must_equal false
98
- extract_identifiers('server...object').fully_qualified?.must_equal false
99
- extract_identifiers('server.database..object').fully_qualified?.must_equal false
100
- extract_identifiers('server.database.schema.object').fully_qualified?.must_equal true
101
- extract_identifiers('server.database.schema.').fully_qualified?.must_equal true
102
- extract_identifiers('[obj.name]').fully_qualified?.must_equal false
103
- extract_identifiers('[schema].[obj.name]').fully_qualified?.must_equal false
104
- extract_identifiers('[database].[schema].[obj.name]').fully_qualified?.must_equal false
105
- extract_identifiers('[database].[obj.name]').fully_qualified?.must_equal false
106
- extract_identifiers('[server.name]...[obj.name]').fully_qualified?.must_equal false
107
- extract_identifiers('[server.name].[database]..[obj.name]').fully_qualified?.must_equal false
108
- extract_identifiers('[server.name].[database].[schema].[obj.name]').fully_qualified?.must_equal true
109
- extract_identifiers('[server.name].[database].[schema].').fully_qualified?.must_equal true
94
+ _(extract_identifiers('object').fully_qualified?).must_equal false
95
+ _(extract_identifiers('schema.object').fully_qualified?).must_equal false
96
+ _(extract_identifiers('database.schema.object').fully_qualified?).must_equal false
97
+ _(extract_identifiers('database.object').fully_qualified?).must_equal false
98
+ _(extract_identifiers('server...object').fully_qualified?).must_equal false
99
+ _(extract_identifiers('server.database..object').fully_qualified?).must_equal false
100
+ _(extract_identifiers('server.database.schema.object').fully_qualified?).must_equal true
101
+ _(extract_identifiers('server.database.schema.').fully_qualified?).must_equal true
102
+ _(extract_identifiers('[obj.name]').fully_qualified?).must_equal false
103
+ _(extract_identifiers('[schema].[obj.name]').fully_qualified?).must_equal false
104
+ _(extract_identifiers('[database].[schema].[obj.name]').fully_qualified?).must_equal false
105
+ _(extract_identifiers('[database].[obj.name]').fully_qualified?).must_equal false
106
+ _(extract_identifiers('[server.name]...[obj.name]').fully_qualified?).must_equal false
107
+ _(extract_identifiers('[server.name].[database]..[obj.name]').fully_qualified?).must_equal false
108
+ _(extract_identifiers('[server.name].[database].[schema].[obj.name]').fully_qualified?).must_equal true
109
+ _(extract_identifiers('[server.name].[database].[schema].').fully_qualified?).must_equal true
110
110
  end
111
111
 
112
112
  it 'can return fully qualified quoted table name' do
113
113
  name = extract_identifiers('[my.server].db.schema.')
114
- name.fully_qualified_database_quoted.must_equal '[my.server].[db]'
114
+ _(name.fully_qualified_database_quoted).must_equal '[my.server].[db]'
115
115
  name = extract_identifiers('[server.name].[database].[schema].[object]')
116
- name.fully_qualified_database_quoted.must_equal '[server.name].[database]'
116
+ _(name.fully_qualified_database_quoted).must_equal '[server.name].[database]'
117
117
  name = extract_identifiers('server.database.schema.object')
118
- name.fully_qualified_database_quoted.must_equal '[server].[database]'
118
+ _(name.fully_qualified_database_quoted).must_equal '[server].[database]'
119
119
  end
120
120
 
121
121
  end
@@ -6,26 +6,26 @@ class SQLServerUuidTest < ActiveRecord::TestCase
6
6
  let(:acceptable_uuid) { ActiveRecord::ConnectionAdapters::SQLServer::Type::Uuid::ACCEPTABLE_UUID }
7
7
 
8
8
  it 'has a uuid primary key' do
9
- SSTestUuid.columns_hash['id'].type.must_equal :uuid
9
+ _(SSTestUuid.columns_hash['id'].type).must_equal :uuid
10
10
  assert SSTestUuid.primary_key
11
11
  end
12
12
 
13
13
  it 'can create with a new pk' do
14
14
  skip 'We do not support uuid autogenerated primary keys at this time' if defined? JRUBY_VERSION
15
15
  obj = SSTestUuid.create!
16
- obj.id.must_be :present?
17
- obj.id.must_match acceptable_uuid
16
+ _(obj.id).must_be :present?
17
+ _(obj.id).must_match acceptable_uuid
18
18
  end
19
19
 
20
20
  it 'can create other uuid column on reload' do
21
21
  skip 'We do not support uuid autogenerated primary keys at this time' if defined? JRUBY_VERSION
22
22
  obj = SSTestUuid.create!
23
23
  obj.reload
24
- obj.other_uuid.must_match acceptable_uuid
24
+ _(obj.other_uuid).must_match acceptable_uuid
25
25
  end
26
26
 
27
27
  it 'can find uuid pk via connection' do
28
- connection.primary_key(SSTestUuid.table_name).must_equal 'id'
28
+ _(connection.primary_key(SSTestUuid.table_name)).must_equal 'id'
29
29
  end
30
30
 
31
31
  it 'changing column default' do
@@ -33,17 +33,17 @@ class SQLServerUuidTest < ActiveRecord::TestCase
33
33
  connection.add_column table_name, :thingy, :uuid, null: false, default: "NEWSEQUENTIALID()"
34
34
  SSTestUuid.reset_column_information
35
35
  column = SSTestUuid.columns_hash['thingy']
36
- column.default_function.must_equal "newsequentialid()"
36
+ _(column.default_function).must_equal "newsequentialid()"
37
37
  # Now to a different function.
38
38
  connection.change_column table_name, :thingy, :uuid, null: false, default: "NEWID()"
39
39
  SSTestUuid.reset_column_information
40
40
  column = SSTestUuid.columns_hash['thingy']
41
- column.default_function.must_equal "newid()"
41
+ _(column.default_function).must_equal "newid()"
42
42
  end
43
43
 
44
44
  it 'can insert even when use_output_inserted to false ' do
45
45
  obj = with_use_output_inserted_disabled { SSTestUuid.create!(name: "😢") }
46
- obj.id.must_be :nil?
46
+ _(obj.id).must_be :nil?
47
47
  end
48
48
 
49
49
  end
@@ -19,7 +19,7 @@ connections:
19
19
  dataserver: <%= ENV['ACTIVERECORD_UNITTEST_DATASERVER'] %>
20
20
  tds_version: <%= ENV['ACTIVERECORD_UNITTEST_TDSVERSION'] %>
21
21
  azure: <%= !ENV['ACTIVERECORD_UNITTEST_AZURE'].nil? %>
22
- timeout: <%= ENV['ACTIVERECORD_UNITTEST_AZURE'].present? ? 20 : nil %>
22
+ timeout: <%= ENV['ACTIVERECORD_UNITTEST_AZURE'].present? ? 20 : 10 %>
23
23
  arunit2:
24
24
  <<: *default_connection_info
25
25
  database: activerecord_unittest2
@@ -27,7 +27,7 @@ connections:
27
27
  dataserver: <%= ENV['ACTIVERECORD_UNITTEST_DATASERVER'] %>
28
28
  tds_version: <%= ENV['ACTIVERECORD_UNITTEST_TDSVERSION'] %>
29
29
  azure: <%= !ENV['ACTIVERECORD_UNITTEST_AZURE'].nil? %>
30
- timeout: <%= ENV['ACTIVERECORD_UNITTEST_AZURE'].present? ? 20 : nil %>
30
+ timeout: <%= ENV['ACTIVERECORD_UNITTEST_AZURE'].present? ? 20 : 10 %>
31
31
 
32
32
  jdbc:
33
33
  arunit:
@@ -0,0 +1,23 @@
1
+ class CreateClientsAndChangeColumnNull < ActiveRecord::Migration[5.2]
2
+ def up
3
+ create_table :clients do |t|
4
+ t.string :name
5
+ t.string :code
6
+ t.decimal :value
7
+
8
+ t.timestamps
9
+ end
10
+
11
+ change_column :clients, :name, :string, limit: 15
12
+ change_column :clients, :code, :string, default: 'n/a'
13
+ change_column :clients, :value, :decimal, precision: 32, scale: 8
14
+
15
+ change_column_null :clients, :name, false
16
+ change_column_null :clients, :code, false
17
+ change_column_null :clients, :value, false
18
+ end
19
+
20
+ def down
21
+ drop_table :clients
22
+ end
23
+ end