activerecord-jdbcsqlserver-adapter 51.1.0 → 52.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -1
- data/CHANGELOG.md +22 -39
- data/{Dockerfile → Dockerfile.ci} +0 -0
- data/Gemfile +1 -3
- data/README.md +5 -8
- data/VERSION +1 -1
- data/activerecord-jdbcsqlserver-adapter.gemspec +2 -3
- data/docker-compose.ci.yml +7 -5
- data/lib/active_record/connection_adapters/sqlserver/core_ext/calculations.rb +25 -29
- data/lib/active_record/connection_adapters/sqlserver/core_ext/explain.rb +14 -18
- data/lib/active_record/connection_adapters/sqlserver/core_ext/finder_methods.rb +43 -0
- data/lib/active_record/connection_adapters/sqlserver/core_ext/query_methods.rb +26 -0
- data/lib/active_record/connection_adapters/sqlserver/database_limits.rb +13 -2
- data/lib/active_record/connection_adapters/sqlserver/database_statements.rb +53 -10
- data/lib/active_record/connection_adapters/sqlserver/database_tasks.rb +1 -0
- data/lib/active_record/connection_adapters/sqlserver/jdbc_overrides.rb +5 -13
- data/lib/active_record/connection_adapters/sqlserver/schema_creation.rb +2 -1
- data/lib/active_record/connection_adapters/sqlserver/schema_dumper.rb +2 -2
- data/lib/active_record/connection_adapters/sqlserver/schema_statements.rb +43 -27
- data/lib/active_record/connection_adapters/sqlserver/transaction.rb +3 -4
- data/lib/active_record/connection_adapters/sqlserver/type/json.rb +1 -1
- data/lib/active_record/connection_adapters/sqlserver/type/string.rb +7 -0
- data/lib/active_record/connection_adapters/sqlserver/type/time.rb +1 -0
- data/lib/active_record/connection_adapters/sqlserver_adapter.rb +20 -14
- data/lib/active_record/tasks/sqlserver_database_tasks.rb +3 -1
- data/lib/activerecord-jdbcsqlserver-adapter.rb +3 -0
- data/lib/arel/visitors/sqlserver.rb +1 -1
- data/lib/arel_sqlserver.rb +0 -1
- data/test/bin/install-freetds.sh +18 -0
- data/test/cases/adapter_test_sqlserver.rb +29 -21
- data/test/cases/change_column_null_test_sqlserver.rb +42 -0
- data/test/cases/coerced_tests.rb +304 -30
- data/test/cases/column_test_sqlserver.rb +496 -462
- data/test/cases/connection_test_sqlserver.rb +2 -2
- data/test/cases/fetch_test_sqlserver.rb +5 -5
- data/test/cases/helper_sqlserver.rb +6 -0
- data/test/cases/json_test_sqlserver.rb +6 -6
- data/test/cases/migration_test_sqlserver.rb +13 -3
- data/test/cases/order_test_sqlserver.rb +19 -19
- data/test/cases/pessimistic_locking_test_sqlserver.rb +9 -9
- data/test/cases/rake_test_sqlserver.rb +20 -20
- data/test/cases/schema_dumper_test_sqlserver.rb +34 -33
- data/test/cases/schema_test_sqlserver.rb +2 -2
- data/test/cases/showplan_test_sqlserver.rb +25 -10
- data/test/cases/specific_schema_test_sqlserver.rb +11 -11
- data/test/cases/transaction_test_sqlserver.rb +9 -9
- data/test/cases/trigger_test_sqlserver.rb +8 -8
- data/test/cases/utils_test_sqlserver.rb +36 -36
- data/test/cases/uuid_test_sqlserver.rb +8 -8
- data/test/migrations/create_clients_and_change_column_null.rb +23 -0
- data/test/schema/datatypes/2012.sql +1 -0
- data/test/schema/sqlserver_specific_schema.rb +9 -1
- data/test/support/core_ext/query_cache.rb +29 -0
- metadata +19 -10
- data/BACKERS.md +0 -32
@@ -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
|
|
@@ -11,8 +11,8 @@ class SpecificSchemaTestSQLServer < ActiveRecord::TestCase
|
|
11
11
|
|
12
12
|
it 'models can use tinyint pk tables' do
|
13
13
|
obj = SSTestTinyintPk.create! name: '1'
|
14
|
-
['Fixnum', 'Integer'].must_include obj.id.class.name
|
15
|
-
SSTestTinyintPk.find(obj.id).must_equal obj
|
14
|
+
_(['Fixnum', 'Integer']).must_include obj.id.class.name
|
15
|
+
_(SSTestTinyintPk.find(obj.id)).must_equal obj
|
16
16
|
end
|
17
17
|
|
18
18
|
it 'be able to complex count tables with no primary key' do
|
@@ -58,17 +58,17 @@ class SpecificSchemaTestSQLServer < ActiveRecord::TestCase
|
|
58
58
|
|
59
59
|
it 'default objects work' do
|
60
60
|
obj = SSTestObjectDefault.create! name: 'MetaSkills'
|
61
|
-
obj.date.must_be_nil 'since this is set on insert'
|
62
|
-
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
|
63
63
|
end
|
64
64
|
|
65
65
|
it 'allows datetime2 as timestamps' do
|
66
|
-
SSTestBooking.columns_hash['created_at'].sql_type.must_equal 'datetime2(7)'
|
67
|
-
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)'
|
68
68
|
obj1 = SSTestBooking.new name: 'test1'
|
69
69
|
obj1.save!
|
70
|
-
obj1.created_at.must_be_instance_of Time
|
71
|
-
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
|
72
72
|
end
|
73
73
|
|
74
74
|
# Natural primary keys.
|
@@ -128,10 +128,10 @@ class SpecificSchemaTestSQLServer < ActiveRecord::TestCase
|
|
128
128
|
o = SSTestDatatypeMigration.create!
|
129
129
|
o.varchar_col = "O'Reilly"
|
130
130
|
o.save!
|
131
|
-
o.reload.varchar_col.must_equal "O'Reilly"
|
131
|
+
_(o.reload.varchar_col).must_equal "O'Reilly"
|
132
132
|
o.varchar_col = nil
|
133
133
|
o.save!
|
134
|
-
o.reload.varchar_col.must_be_nil
|
134
|
+
_(o.reload.varchar_col).must_be_nil
|
135
135
|
end
|
136
136
|
|
137
137
|
# With column names that have spaces
|
@@ -160,7 +160,7 @@ class SpecificSchemaTestSQLServer < ActiveRecord::TestCase
|
|
160
160
|
it 'returns a new id via connection newid_function' do
|
161
161
|
acceptable_uuid = ActiveRecord::ConnectionAdapters::SQLServer::Type::Uuid::ACCEPTABLE_UUID
|
162
162
|
db_uuid = ActiveRecord::Base.connection.newid_function
|
163
|
-
db_uuid.must_match(acceptable_uuid)
|
163
|
+
_(db_uuid).must_match(acceptable_uuid)
|
164
164
|
end
|
165
165
|
|
166
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
|
|
@@ -12,10 +12,10 @@ class SQLServerTriggerTest < ActiveRecord::TestCase
|
|
12
12
|
exclude_output_inserted_table_names['sst_table_with_trigger'] = true
|
13
13
|
assert SSTestTriggerHistory.all.empty?
|
14
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
|
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
19
|
end
|
20
20
|
|
21
21
|
it 'can insert into a table with output inserted - with a uniqueidentifier value' do
|
@@ -23,9 +23,9 @@ class SQLServerTriggerTest < ActiveRecord::TestCase
|
|
23
23
|
exclude_output_inserted_table_names['sst_table_with_uuid_trigger'] = 'uniqueidentifier'
|
24
24
|
assert SSTestTriggerHistory.all.empty?
|
25
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
|
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
30
|
end
|
31
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
|
95
|
-
extract_identifiers('schema.object').fully_qualified
|
96
|
-
extract_identifiers('database.schema.object').fully_qualified
|
97
|
-
extract_identifiers('database.object').fully_qualified
|
98
|
-
extract_identifiers('server...object').fully_qualified
|
99
|
-
extract_identifiers('server.database..object').fully_qualified
|
100
|
-
extract_identifiers('server.database.schema.object').fully_qualified
|
101
|
-
extract_identifiers('server.database.schema.').fully_qualified
|
102
|
-
extract_identifiers('[obj.name]').fully_qualified
|
103
|
-
extract_identifiers('[schema].[obj.name]').fully_qualified
|
104
|
-
extract_identifiers('[database].[schema].[obj.name]').fully_qualified
|
105
|
-
extract_identifiers('[database].[obj.name]').fully_qualified
|
106
|
-
extract_identifiers('[server.name]...[obj.name]').fully_qualified
|
107
|
-
extract_identifiers('[server.name].[database]..[obj.name]').fully_qualified
|
108
|
-
extract_identifiers('[server.name].[database].[schema].[obj.name]').fully_qualified
|
109
|
-
extract_identifiers('[server.name].[database].[schema].').fully_qualified
|
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
|
@@ -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
|
@@ -35,6 +35,7 @@ CREATE TABLE [sst_datatypes] (
|
|
35
35
|
[smalldatetime] [smalldatetime] NULL DEFAULT '1901-01-01T15:45:00.000Z',
|
36
36
|
[time_7] [time](7) NULL DEFAULT '04:20:00.2883215',
|
37
37
|
[time_2] [time](2) NULL,
|
38
|
+
[time_default] [time] NULL DEFAULT '15:03:42.0621978',
|
38
39
|
-- Character Strings
|
39
40
|
[char_10] [char](10) NULL DEFAULT '1234567890',
|
40
41
|
[varchar_50] [varchar](50) NULL DEFAULT 'test varchar_50',
|
@@ -144,12 +144,20 @@ ActiveRecord::Schema.define do
|
|
144
144
|
|
145
145
|
# Constraints
|
146
146
|
|
147
|
-
create_table(:sst_has_fks, force: true)
|
147
|
+
create_table(:sst_has_fks, force: true) do |t|
|
148
|
+
t.column(:fk_id, :bigint, null: false)
|
149
|
+
t.column(:fk_id2, :bigint)
|
150
|
+
end
|
151
|
+
|
148
152
|
create_table(:sst_has_pks, force: true) { }
|
149
153
|
execute <<-ADDFKSQL
|
150
154
|
ALTER TABLE sst_has_fks
|
151
155
|
ADD CONSTRAINT FK__sst_has_fks_id
|
152
156
|
FOREIGN KEY ([fk_id])
|
157
|
+
REFERENCES [sst_has_pks] ([id]),
|
158
|
+
|
159
|
+
CONSTRAINT FK__sst_has_fks_id2
|
160
|
+
FOREIGN KEY ([fk_id2])
|
153
161
|
REFERENCES [sst_has_pks] ([id])
|
154
162
|
ADDFKSQL
|
155
163
|
|