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
@@ -36,7 +36,7 @@ class ConnectionTestSQLServer < ActiveRecord::TestCase
36
36
  describe 'Connection management' do
37
37
 
38
38
  it 'set spid on connect' do
39
- ['Fixnum', 'Integer'].must_include connection.spid.class.name
39
+ _(['Fixnum', 'Integer']).must_include connection.spid.class.name
40
40
  end
41
41
 
42
42
  it 'reset spid on disconnect!' do
@@ -46,7 +46,7 @@ class ConnectionTestSQLServer < ActiveRecord::TestCase
46
46
 
47
47
  it 'reset the connection' do
48
48
  connection.disconnect!
49
- connection.raw_connection.must_be_nil
49
+ _(connection.raw_connection).must_be_nil
50
50
  end unless defined? JRUBY_VERSION
51
51
 
52
52
  it 'be able to disconnect and reconnect at will' do
@@ -36,11 +36,11 @@ class FetchTestSqlserver < ActiveRecord::TestCase
36
36
 
37
37
  it 'gauntlet' do
38
38
  Book.where(name:'Name-10').delete_all
39
- Book.order(:name).limit(1).offset(1).map(&:name).must_equal ['Name-2']
40
- Book.order(:name).limit(2).offset(2).map(&:name).must_equal ['Name-3', 'Name-4']
41
- Book.order(:name).limit(2).offset(7).map(&:name).must_equal ['Name-8', 'Name-9']
42
- Book.order(:name).limit(3).offset(7).map(&:name).must_equal ['Name-8', 'Name-9']
43
- Book.order(:name).limit(3).offset(9).map(&:name).must_equal []
39
+ _(Book.order(:name).limit(1).offset(1).map(&:name)).must_equal ['Name-2']
40
+ _(Book.order(:name).limit(2).offset(2).map(&:name)).must_equal ['Name-3', 'Name-4']
41
+ _(Book.order(:name).limit(2).offset(7).map(&:name)).must_equal ['Name-8', 'Name-9']
42
+ _(Book.order(:name).limit(3).offset(7).map(&:name)).must_equal ['Name-8', 'Name-9']
43
+ _(Book.order(:name).limit(3).offset(9).map(&:name)).must_equal []
44
44
  end
45
45
 
46
46
  end
@@ -2,6 +2,7 @@ require 'support/paths_sqlserver'
2
2
  require 'bundler/setup'
3
3
  Bundler.require :default, :development
4
4
  require 'pry'
5
+ require 'support/core_ext/query_cache'
5
6
  require 'support/minitest_sqlserver'
6
7
  require 'support/test_in_memory_oltp'
7
8
  require 'cases/helper'
@@ -9,7 +10,7 @@ require 'support/load_schema_sqlserver'
9
10
  require 'support/coerceable_test_sqlserver'
10
11
  require 'support/sql_counter_sqlserver'
11
12
  require 'support/connection_reflection'
12
- require 'mocha/mini_test'
13
+ require 'mocha/minitest'
13
14
 
14
15
  module ActiveRecord
15
16
  class TestCase < ActiveSupport::TestCase
@@ -23,9 +24,19 @@ module ActiveRecord
23
24
 
24
25
  let(:logger) { ActiveRecord::Base.logger }
25
26
 
27
+ setup :ensure_clean_rails_env
28
+ setup :remove_backtrace_silencers
26
29
 
27
30
  private
28
31
 
32
+ def ensure_clean_rails_env
33
+ Rails.instance_variable_set(:@_env, nil) if defined?(::Rails)
34
+ end
35
+
36
+ def remove_backtrace_silencers
37
+ Rails.backtrace_cleaner.remove_silencers!
38
+ end
39
+
29
40
  def host_windows?
30
41
  RbConfig::CONFIG['host_os'] =~ /mswin|mingw/
31
42
  end
@@ -12,20 +12,20 @@ class JsonTestSQLServer < ActiveRecord::TestCase
12
12
  end
13
13
 
14
14
  it 'can return and save JSON data' do
15
- SSTestDatatypeMigrationJson.find(@o1.id).json_col.must_equal({ 'a' => 'a', 'b' => 'b', 'c' => 'c' })
15
+ _(SSTestDatatypeMigrationJson.find(@o1.id).json_col).must_equal({ 'a' => 'a', 'b' => 'b', 'c' => 'c' })
16
16
  @o1.json_col = { 'a' => 'a' }
17
- @o1.json_col.must_equal({ 'a' => 'a' })
17
+ _(@o1.json_col).must_equal({ 'a' => 'a' })
18
18
  @o1.save!
19
- @o1.reload.json_col.must_equal({ 'a' => 'a' })
19
+ _(@o1.reload.json_col).must_equal({ 'a' => 'a' })
20
20
  end
21
21
 
22
22
  it 'can use ISJSON function' do
23
- SSTestDatatypeMigrationJson.where('ISJSON(json_col) > 0').count.must_equal 4
24
- SSTestDatatypeMigrationJson.where('ISJSON(json_col) IS NULL').count.must_equal 1
23
+ _(SSTestDatatypeMigrationJson.where('ISJSON(json_col) > 0').count).must_equal 4
24
+ _(SSTestDatatypeMigrationJson.where('ISJSON(json_col) IS NULL').count).must_equal 1
25
25
  end
26
26
 
27
27
  it 'can use JSON_VALUE function' do
28
- SSTestDatatypeMigrationJson.where("JSON_VALUE(json_col, '$.b') = 'b'").count.must_equal 2
28
+ _(SSTestDatatypeMigrationJson.where("JSON_VALUE(json_col, '$.b') = 'b'").count).must_equal 2
29
29
  end
30
30
 
31
31
  end
@@ -20,12 +20,12 @@ class MigrationTestSQLServer < ActiveRecord::TestCase
20
20
  it 'not create a tables if error in migrations' do
21
21
  begin
22
22
  migrations_dir = File.join ARTest::SQLServer.migrations_root, 'transaction_table'
23
- quietly { ActiveRecord::Migrator.up(migrations_dir) }
23
+ quietly { ActiveRecord::MigrationContext.new(migrations_dir).up }
24
24
  rescue Exception => e
25
25
  assert_match %r|this and all later migrations canceled|, e.message
26
26
  end
27
- connection.tables.wont_include @trans_test_table1
28
- connection.tables.wont_include @trans_test_table2
27
+ _(connection.tables).wont_include @trans_test_table1
28
+ _(connection.tables).wont_include @trans_test_table2
29
29
  end
30
30
 
31
31
  end
@@ -41,6 +41,8 @@ class MigrationTestSQLServer < ActiveRecord::TestCase
41
41
  lock_version_column = Person.columns_hash['lock_version']
42
42
  assert_equal :string, lock_version_column.type
43
43
  assert lock_version_column.default.nil?
44
+ assert_nothing_raised { connection.change_column 'people', 'lock_version', :integer }
45
+ Person.reset_column_information
44
46
  end
45
47
 
46
48
  it 'not drop the default contraint if just renaming' do
@@ -55,6 +57,14 @@ class MigrationTestSQLServer < ActiveRecord::TestCase
55
57
  assert default_after
56
58
  assert_equal default_before['constraint_keys'], default_after['constraint_keys']
57
59
  end
60
+
61
+ it 'change limit' do
62
+ assert_nothing_raised { connection.change_column :people, :lock_version, :integer, limit: 8 }
63
+ end
64
+
65
+ it 'change null and default' do
66
+ assert_nothing_raised { connection.change_column :people, :first_name, :text, null: true, default: nil }
67
+ end
58
68
 
59
69
  end
60
70
 
@@ -44,13 +44,13 @@ class OrderTestSQLServer < ActiveRecord::TestCase
44
44
  it 'support quoted column' do
45
45
  order = "[title]"
46
46
  post1 = Post.create title: 'AAA Post', body: 'Test cased orders.'
47
- assert_equal post1, Post.order(order).first
47
+ assert_equal post1, Post.order(Arel.sql(order)).first
48
48
  end
49
49
 
50
50
  it 'support quoted table and column' do
51
51
  order = "[posts].[title]"
52
52
  post1 = Post.create title: 'AAA Post', body: 'Test cased orders.'
53
- assert_equal post1, Post.order(order).first
53
+ assert_equal post1, Post.order(Arel.sql(order)).first
54
54
  end
55
55
 
56
56
  it 'support primary: column, secondary: column' do
@@ -73,74 +73,74 @@ class OrderTestSQLServer < ActiveRecord::TestCase
73
73
  order = "(CASE WHEN [title] LIKE N'ZZZ%' THEN title ELSE '' END) DESC, body"
74
74
  post1 = Post.create title: 'ZZZ Post', body: 'Test cased orders.'
75
75
  post2 = Post.create title: 'ZZZ Post', body: 'ZZZ Test cased orders.'
76
- assert_equal post1, Post.order(order).first
77
- assert_equal post2, Post.order(order).second
76
+ assert_equal post1, Post.order(Arel.sql(order)).first
77
+ assert_equal post2, Post.order(Arel.sql(order)).second
78
78
  end
79
79
 
80
80
  it 'support primary: quoted table and column, secondary: case expresion' do
81
81
  order = "[posts].[body] DESC, (CASE WHEN [title] LIKE N'ZZZ%' THEN title ELSE '' END) DESC"
82
82
  post1 = Post.create title: 'ZZZ Post', body: 'ZZZ Test cased orders.'
83
83
  post2 = Post.create title: 'ZZY Post', body: 'ZZZ Test cased orders.'
84
- assert_equal post1, Post.order(order).first
85
- assert_equal post2, Post.order(order).second
84
+ assert_equal post1, Post.order(Arel.sql(order)).first
85
+ assert_equal post2, Post.order(Arel.sql(order)).second
86
86
  end
87
87
 
88
88
  it 'support inline function' do
89
89
  order = "LEN(title)"
90
90
  post1 = Post.create title: 'A', body: 'AAA Test cased orders.'
91
- assert_equal post1, Post.order(order).first
91
+ assert_equal post1, Post.order(Arel.sql(order)).first
92
92
  end
93
93
 
94
94
  it 'support inline function with parameters' do
95
95
  order = "SUBSTRING(title, 1, 3)"
96
96
  post1 = Post.create title: 'AAA Post', body: 'Test cased orders.'
97
- assert_equal post1, Post.order(order).first
97
+ assert_equal post1, Post.order(Arel.sql(order)).first
98
98
  end
99
99
 
100
100
  it 'support inline function with parameters DESC' do
101
101
  order = "SUBSTRING(title, 1, 3) DESC"
102
102
  post1 = Post.create title: 'ZZZ Post', body: 'Test cased orders.'
103
- assert_equal post1, Post.order(order).first
103
+ assert_equal post1, Post.order(Arel.sql(order)).first
104
104
  end
105
105
 
106
106
  it 'support primary: inline function, secondary: column' do
107
107
  order = "LEN(title), body"
108
108
  post1 = Post.create title: 'A', body: 'AAA Test cased orders.'
109
109
  post2 = Post.create title: 'A', body: 'Test cased orders.'
110
- assert_equal post1, Post.order(order).first
111
- assert_equal post2, Post.order(order).second
110
+ assert_equal post1, Post.order(Arel.sql(order)).first
111
+ assert_equal post2, Post.order(Arel.sql(order)).second
112
112
  end
113
113
 
114
114
  it 'support primary: inline function, secondary: column with direction' do
115
115
  order = "LEN(title) ASC, body DESC"
116
116
  post1 = Post.create title: 'A', body: 'ZZZ Test cased orders.'
117
117
  post2 = Post.create title: 'A', body: 'Test cased orders.'
118
- assert_equal post1, Post.order(order).first
119
- assert_equal post2, Post.order(order).second
118
+ assert_equal post1, Post.order(Arel.sql(order)).first
119
+ assert_equal post2, Post.order(Arel.sql(order)).second
120
120
  end
121
121
 
122
122
  it 'support primary: column, secondary: inline function' do
123
123
  order = "body DESC, LEN(title)"
124
124
  post1 = Post.create title: 'Post', body: 'ZZZ Test cased orders.'
125
125
  post2 = Post.create title: 'Longer Post', body: 'ZZZ Test cased orders.'
126
- assert_equal post1, Post.order(order).first
127
- assert_equal post2, Post.order(order).second
126
+ assert_equal post1, Post.order(Arel.sql(order)).first
127
+ assert_equal post2, Post.order(Arel.sql(order)).second
128
128
  end
129
129
 
130
130
  it 'support primary: case expression, secondary: inline function' do
131
131
  order = "CASE WHEN [title] LIKE N'ZZZ%' THEN title ELSE '' END DESC, LEN(body) ASC"
132
132
  post1 = Post.create title: 'ZZZ Post', body: 'Z'
133
133
  post2 = Post.create title: 'ZZZ Post', body: 'Test cased orders.'
134
- assert_equal post1, Post.order(order).first
135
- assert_equal post2, Post.order(order).second
134
+ assert_equal post1, Post.order(Arel.sql(order)).first
135
+ assert_equal post2, Post.order(Arel.sql(order)).second
136
136
  end
137
137
 
138
138
  it 'support primary: inline function, secondary: case expression' do
139
139
  order = "LEN(body), CASE WHEN [title] LIKE N'ZZZ%' THEN title ELSE '' END DESC"
140
140
  post1 = Post.create title: 'ZZZ Post', body: 'Z'
141
141
  post2 = Post.create title: 'Post', body: 'Z'
142
- assert_equal post1, Post.order(order).first
143
- assert_equal post2, Post.order(order).second
142
+ assert_equal post1, Post.order(Arel.sql(order)).first
143
+ assert_equal post2, Post.order(Arel.sql(order)).second
144
144
  end
145
145
 
146
146
 
@@ -13,7 +13,7 @@ class PessimisticLockingTestSQLServer < ActiveRecord::TestCase
13
13
 
14
14
  it 'uses with updlock by default' do
15
15
  assert_sql %r|SELECT \[people\]\.\* FROM \[people\] WITH\(UPDLOCK\)| do
16
- Person.lock(true).to_a.must_equal Person.all.to_a
16
+ _(Person.lock(true).to_a).must_equal Person.all.to_a
17
17
  end
18
18
  end
19
19
 
@@ -22,7 +22,7 @@ class PessimisticLockingTestSQLServer < ActiveRecord::TestCase
22
22
  it 'lock with simple find' do
23
23
  assert_nothing_raised do
24
24
  Person.transaction do
25
- Person.lock(true).find(1).must_equal Person.find(1)
25
+ _(Person.lock(true).find(1)).must_equal Person.find(1)
26
26
  end
27
27
  end
28
28
  end
@@ -31,7 +31,7 @@ class PessimisticLockingTestSQLServer < ActiveRecord::TestCase
31
31
  assert_nothing_raised do
32
32
  Person.transaction do
33
33
  Person.lock(true).scoping do
34
- Person.find(1).must_equal Person.find(1)
34
+ _(Person.find(1)).must_equal Person.find(1)
35
35
  end
36
36
  end
37
37
  end
@@ -41,18 +41,7 @@ class PessimisticLockingTestSQLServer < ActiveRecord::TestCase
41
41
  assert_nothing_raised do
42
42
  Person.transaction do
43
43
  person = Person.lock(true).includes(:readers).find(1)
44
- person.must_equal Person.find(1)
45
- end
46
- end
47
- end
48
-
49
- it 'reload with lock when #lock! called' do
50
- assert_nothing_raised do
51
- Person.transaction do
52
- person = Person.find 1
53
- old, person.first_name = person.first_name, 'fooman'
54
- person.lock!
55
- assert_equal old, person.first_name
44
+ _(person).must_equal Person.find(1)
56
45
  end
57
46
  end
58
47
  end
@@ -63,6 +52,34 @@ class PessimisticLockingTestSQLServer < ActiveRecord::TestCase
63
52
  end
64
53
  end
65
54
 
55
+ describe 'joining tables' do
56
+
57
+ it 'joined tables use updlock by default' do
58
+ assert_sql %r|SELECT \[people\]\.\* FROM \[people\] WITH\(UPDLOCK\) INNER JOIN \[readers\] WITH\(UPDLOCK\)\s+ON \[readers\]\.\[person_id\] = \[people\]\.\[id\]| do
59
+ Person.lock(true).joins(:readers).load
60
+ end
61
+ end
62
+
63
+ it 'joined tables can use custom lock directive' do
64
+ assert_sql %r|SELECT \[people\]\.\* FROM \[people\] WITH\(NOLOCK\) INNER JOIN \[readers\] WITH\(NOLOCK\)\s+ON \[readers\]\.\[person_id\] = \[people\]\.\[id\]| do
65
+ Person.lock('WITH(NOLOCK)').joins(:readers).load
66
+ end
67
+ end
68
+
69
+ it 'left joined tables use updlock by default' do
70
+ assert_sql %r|SELECT \[people\]\.\* FROM \[people\] WITH\(UPDLOCK\) LEFT OUTER JOIN \[readers\] WITH\(UPDLOCK\)\s+ON \[readers\]\.\[person_id\] = \[people\]\.\[id\]| do
71
+ Person.lock(true).left_joins(:readers).load
72
+ end
73
+ end
74
+
75
+ it 'left joined tables can use custom lock directive' do
76
+ assert_sql %r|SELECT \[people\]\.\* FROM \[people\] WITH\(NOLOCK\) LEFT OUTER JOIN \[readers\] WITH\(NOLOCK\)\s+ON \[readers\]\.\[person_id\] = \[people\]\.\[id\]| do
77
+ Person.lock('WITH(NOLOCK)').left_joins(:readers).load
78
+ end
79
+ end
80
+
81
+ end
82
+
66
83
  end
67
84
 
68
85
  describe 'For paginated finds' do
@@ -81,11 +98,11 @@ class PessimisticLockingTestSQLServer < ActiveRecord::TestCase
81
98
  loader_sql = /SELECT.*FROM \[people\] WITH\(UPDLOCK\).*WHERE \[people\]\.\[id\] IN/
82
99
  assert_sql(eager_ids_sql, loader_sql) do
83
100
  people = Person.lock(true).limit(5).offset(10).includes(:readers).references(:readers).to_a
84
- people[0].first_name.must_equal 'Thing_10'
85
- people[1].first_name.must_equal 'Thing_11'
86
- people[2].first_name.must_equal 'Thing_12'
87
- people[3].first_name.must_equal 'Thing_13'
88
- people[4].first_name.must_equal 'Thing_14'
101
+ _(people[0].first_name).must_equal 'Thing_10'
102
+ _(people[1].first_name).must_equal 'Thing_11'
103
+ _(people[2].first_name).must_equal 'Thing_12'
104
+ _(people[3].first_name).must_equal 'Thing_13'
105
+ _(people[4].first_name).must_equal 'Thing_14'
89
106
  end
90
107
  end
91
108
 
@@ -43,23 +43,23 @@ class SQLServerRakeCreateTest < SQLServerRakeTest
43
43
 
44
44
  it 'establishes connection to database after create ' do
45
45
  quietly { db_tasks.create configuration }
46
- connection.current_database.must_equal(new_database)
46
+ _(connection.current_database).must_equal(new_database)
47
47
  end
48
48
 
49
49
  it 'creates database with default collation' do
50
50
  quietly { db_tasks.create configuration }
51
- connection.collation.must_equal 'SQL_Latin1_General_CP1_CI_AS'
51
+ _(connection.collation).must_equal 'SQL_Latin1_General_CP1_CI_AS'
52
52
  end
53
53
 
54
54
  it 'creates database with given collation' do
55
55
  quietly { db_tasks.create configuration.merge('collation' => 'Latin1_General_CI_AS') }
56
- connection.collation.must_equal 'Latin1_General_CI_AS'
56
+ _(connection.collation).must_equal 'Latin1_General_CI_AS'
57
57
  end
58
58
 
59
59
  it 'prints error message when database exists' do
60
60
  quietly { db_tasks.create configuration }
61
61
  message = capture(:stderr) { db_tasks.create configuration }
62
- message.must_match %r{activerecord_unittest_tasks.*already exists}
62
+ _(message).must_match %r{activerecord_unittest_tasks.*already exists}
63
63
  end
64
64
 
65
65
  end
@@ -73,12 +73,12 @@ class SQLServerRakeDropTest < SQLServerRakeTest
73
73
  db_tasks.create configuration
74
74
  db_tasks.drop configuration
75
75
  end
76
- connection.current_database.must_equal 'master'
76
+ _(connection.current_database).must_equal 'master'
77
77
  end
78
78
 
79
79
  it 'prints error message when database does not exist' do
80
80
  message = capture(:stderr) { db_tasks.drop configuration.merge('database' => 'doesnotexist') }
81
- message.must_match %r{'doesnotexist' does not exist}
81
+ _(message).must_match %r{'doesnotexist' does not exist}
82
82
  end
83
83
 
84
84
  end
@@ -94,11 +94,11 @@ class SQLServerRakePurgeTest < SQLServerRakeTest
94
94
  end
95
95
 
96
96
  it 'clears active connections, drops database, and recreates with established connection' do
97
- connection.current_database.must_equal(new_database)
98
- connection.tables.must_include 'users'
97
+ _(connection.current_database).must_equal(new_database)
98
+ _(connection.tables).must_include 'users'
99
99
  quietly { db_tasks.purge(configuration) }
100
- connection.current_database.must_equal(new_database)
101
- connection.tables.wont_include 'users'
100
+ _(connection.current_database).must_equal(new_database)
101
+ _(connection.tables).wont_include 'users'
102
102
  end
103
103
 
104
104
  end
@@ -110,7 +110,7 @@ class SQLServerRakeCharsetTest < SQLServerRakeTest
110
110
  end
111
111
 
112
112
  it 'retrieves charset' do
113
- db_tasks.charset(configuration).must_equal 'iso_1'
113
+ _(db_tasks.charset(configuration)).must_equal 'iso_1'
114
114
  end
115
115
 
116
116
  end
@@ -122,7 +122,7 @@ class SQLServerRakeCollationTest < SQLServerRakeTest
122
122
  end
123
123
 
124
124
  it 'retrieves collation' do
125
- db_tasks.collation(configuration).must_equal 'SQL_Latin1_General_CP1_CI_AS'
125
+ _(db_tasks.collation(configuration)).must_equal 'SQL_Latin1_General_CP1_CI_AS'
126
126
  end
127
127
 
128
128
  end
@@ -149,21 +149,21 @@ class SQLServerRakeStructureDumpLoadTest < SQLServerRakeTest
149
149
  it 'dumps structure and accounts for defncopy oddities' do
150
150
  skip 'debug defncopy on windows later' if host_windows?
151
151
  quietly { db_tasks.structure_dump configuration, filename }
152
- filedata.wont_match %r{\AUSE.*\z}
153
- filedata.wont_match %r{\AGO.*\z}
154
- filedata.must_match %r{email\s+nvarchar\(4000\)}
155
- filedata.must_match %r{background1\s+nvarchar\(max\)}
156
- filedata.must_match %r{background2\s+text\s+}
152
+ _(filedata).wont_match %r{\AUSE.*\z}
153
+ _(filedata).wont_match %r{\AGO.*\z}
154
+ _(filedata).must_match %r{email\s+nvarchar\(4000\)}
155
+ _(filedata).must_match %r{background1\s+nvarchar\(max\)}
156
+ _(filedata).must_match %r{background2\s+text\s+}
157
157
  end
158
158
 
159
159
  it 'can load dumped structure' do
160
160
  skip 'debug defncopy on windows later' if host_windows?
161
161
  quietly { db_tasks.structure_dump configuration, filename }
162
- filedata.must_match %r{CREATE TABLE dbo\.users}
162
+ _(filedata).must_match %r{CREATE TABLE dbo\.users}
163
163
  db_tasks.purge(configuration)
164
- connection.tables.wont_include 'users'
164
+ _(connection.tables).wont_include 'users'
165
165
  db_tasks.load_schema configuration, :sql, filename
166
- connection.tables.must_include 'users'
166
+ _(connection.tables).must_include 'users'
167
167
  end
168
168
 
169
169
  end
@@ -34,21 +34,22 @@ class SchemaDumperTestSQLServer < ActiveRecord::TestCase
34
34
  if connection_dblib_73?
35
35
  assert_line :time_7, type: 'time', limit: nil, precision: 7, scale: nil, default: "04:20:00.2883215"
36
36
  assert_line :time_2, type: 'time', limit: nil, precision: 2, scale: nil, default: nil
37
+ assert_line :time_default, type: 'time', limit: nil, precision: 7, scale: nil, default: "15:03:42.0621978"
37
38
  end
38
39
  # Character Strings
39
40
  assert_line :char_10, type: 'char', limit: 10, precision: nil, scale: nil, default: "1234567890", collation: nil
40
41
  assert_line :varchar_50, type: 'varchar', limit: 50, precision: nil, scale: nil, default: "test varchar_50", collation: nil
41
- assert_line :varchar_max, type: 'varchar_max', limit: 2147483647, precision: nil, scale: nil, default: "test varchar_max", collation: nil
42
- assert_line :text, type: 'text_basic', limit: 2147483647, precision: nil, scale: nil, default: "test text", collation: nil
42
+ assert_line :varchar_max, type: 'varchar_max', limit: nil, precision: nil, scale: nil, default: "test varchar_max", collation: nil
43
+ assert_line :text, type: 'text_basic', limit: nil, precision: nil, scale: nil, default: "test text", collation: nil
43
44
  # Unicode Character Strings
44
45
  assert_line :nchar_10, type: 'nchar', limit: 10, precision: nil, scale: nil, default: "12345678åå", collation: nil
45
46
  assert_line :nvarchar_50, type: 'string', limit: 50, precision: nil, scale: nil, default: "test nvarchar_50 åå", collation: nil
46
- assert_line :nvarchar_max, type: 'text', limit: 2147483647, precision: nil, scale: nil, default: "test nvarchar_max åå", collation: nil
47
- assert_line :ntext, type: 'ntext', limit: 2147483647, precision: nil, scale: nil, default: "test ntext åå", collation: nil
47
+ assert_line :nvarchar_max, type: 'text', limit: nil, precision: nil, scale: nil, default: "test nvarchar_max åå", collation: nil
48
+ assert_line :ntext, type: 'ntext', limit: nil, precision: nil, scale: nil, default: "test ntext åå", collation: nil
48
49
  # Binary Strings
49
50
  assert_line :binary_49, type: 'binary_basic', limit: 49, precision: nil, scale: nil, default: nil
50
51
  assert_line :varbinary_49, type: 'varbinary', limit: 49, precision: nil, scale: nil, default: nil
51
- assert_line :varbinary_max, type: 'binary', limit: 2147483647, precision: nil, scale: nil, default: nil
52
+ assert_line :varbinary_max, type: 'binary', limit: nil, precision: nil, scale: nil, default: nil
52
53
  # Other Data Types
53
54
  assert_line :uniqueidentifier, type: 'uuid', limit: nil, precision: nil, scale: nil, default: -> { "newid()" }
54
55
  assert_line :timestamp, type: 'ss_timestamp', limit: nil, precision: nil, scale: nil, default: nil
@@ -58,47 +59,47 @@ class SchemaDumperTestSQLServer < ActiveRecord::TestCase
58
59
  columns = SSTestDatatypeMigration.columns_hash
59
60
  generate_schema_for_table 'sst_datatypes_migration'
60
61
  # Simple Rails conventions
61
- columns['integer_col'].sql_type.must_equal 'int(4)'
62
- columns['bigint_col'].sql_type.must_equal 'bigint(8)'
63
- columns['boolean_col'].sql_type.must_equal 'bit'
64
- columns['decimal_col'].sql_type.must_equal 'decimal(18,0)'
65
- columns['float_col'].sql_type.must_equal 'float'
66
- columns['string_col'].sql_type.must_equal 'nvarchar(4000)'
67
- columns['text_col'].sql_type.must_equal 'nvarchar(max)'
68
- columns['datetime_col'].sql_type.must_equal 'datetime'
69
- columns['timestamp_col'].sql_type.must_equal 'datetime'
70
- columns['time_col'].sql_type.must_equal 'time(7)'
71
- columns['date_col'].sql_type.must_equal 'date'
72
- columns['binary_col'].sql_type.must_equal 'varbinary(max)'
62
+ _(columns['integer_col'].sql_type).must_equal 'int(4)'
63
+ _(columns['bigint_col'].sql_type).must_equal 'bigint(8)'
64
+ _(columns['boolean_col'].sql_type).must_equal 'bit'
65
+ _(columns['decimal_col'].sql_type).must_equal 'decimal(18,0)'
66
+ _(columns['float_col'].sql_type).must_equal 'float'
67
+ _(columns['string_col'].sql_type).must_equal 'nvarchar(4000)'
68
+ _(columns['text_col'].sql_type).must_equal 'nvarchar(max)'
69
+ _(columns['datetime_col'].sql_type).must_equal 'datetime'
70
+ _(columns['timestamp_col'].sql_type).must_equal 'datetime'
71
+ _(columns['time_col'].sql_type).must_equal 'time(7)'
72
+ _(columns['date_col'].sql_type).must_equal 'date'
73
+ _(columns['binary_col'].sql_type).must_equal 'varbinary(max)'
73
74
  assert_line :integer_col, type: 'integer', limit: nil, precision: nil, scale: nil, default: nil
74
75
  assert_line :bigint_col, type: 'bigint', limit: nil, precision: nil, scale: nil, default: nil
75
76
  assert_line :boolean_col, type: 'boolean', limit: nil, precision: nil, scale: nil, default: nil
76
77
  assert_line :decimal_col, type: 'decimal', limit: nil, precision: 18, scale: 0, default: nil
77
78
  assert_line :float_col, type: 'float', limit: nil, precision: nil, scale: nil, default: nil
78
79
  assert_line :string_col, type: 'string', limit: nil, precision: nil, scale: nil, default: nil
79
- assert_line :text_col, type: 'text', limit: 2147483647, precision: nil, scale: nil, default: nil
80
+ assert_line :text_col, type: 'text', limit: nil, precision: nil, scale: nil, default: nil
80
81
  assert_line :datetime_col, type: 'datetime', limit: nil, precision: nil, scale: nil, default: nil
81
82
  assert_line :timestamp_col, type: 'datetime', limit: nil, precision: nil, scale: nil, default: nil
82
83
  assert_line :time_col, type: 'time', limit: nil, precision: 7, scale: nil, default: nil
83
84
  assert_line :date_col, type: 'date', limit: nil, precision: nil, scale: nil, default: nil
84
- assert_line :binary_col, type: 'binary', limit: 2147483647, precision: nil, scale: nil, default: nil
85
+ assert_line :binary_col, type: 'binary', limit: nil, precision: nil, scale: nil, default: nil
85
86
  # Our type methods.
86
- columns['real_col'].sql_type.must_equal 'real'
87
- columns['money_col'].sql_type.must_equal 'money'
88
- columns['smalldatetime_col'].sql_type.must_equal 'smalldatetime'
89
- columns['datetime2_col'].sql_type.must_equal 'datetime2(7)'
90
- columns['datetimeoffset'].sql_type.must_equal 'datetimeoffset(7)'
91
- columns['smallmoney_col'].sql_type.must_equal 'smallmoney'
92
- columns['char_col'].sql_type.must_equal 'char(1)'
93
- columns['varchar_col'].sql_type.must_equal 'varchar(8000)'
94
- columns['text_basic_col'].sql_type.must_equal 'text'
95
- columns['nchar_col'].sql_type.must_equal 'nchar(1)'
96
- columns['ntext_col'].sql_type.must_equal 'ntext'
97
- columns['binary_basic_col'].sql_type.must_equal 'binary(1)'
98
- columns['varbinary_col'].sql_type.must_equal 'varbinary(8000)'
99
- columns['uuid_col'].sql_type.must_equal 'uniqueidentifier'
100
- columns['sstimestamp_col'].sql_type.must_equal 'timestamp'
101
- columns['json_col'].sql_type.must_equal 'nvarchar(max)'
87
+ _(columns['real_col'].sql_type).must_equal 'real'
88
+ _(columns['money_col'].sql_type).must_equal 'money'
89
+ _(columns['smalldatetime_col'].sql_type).must_equal 'smalldatetime'
90
+ _(columns['datetime2_col'].sql_type).must_equal 'datetime2(7)'
91
+ _(columns['datetimeoffset'].sql_type).must_equal 'datetimeoffset(7)'
92
+ _(columns['smallmoney_col'].sql_type).must_equal 'smallmoney'
93
+ _(columns['char_col'].sql_type).must_equal 'char(1)'
94
+ _(columns['varchar_col'].sql_type).must_equal 'varchar(8000)'
95
+ _(columns['text_basic_col'].sql_type).must_equal 'text'
96
+ _(columns['nchar_col'].sql_type).must_equal 'nchar(1)'
97
+ _(columns['ntext_col'].sql_type).must_equal 'ntext'
98
+ _(columns['binary_basic_col'].sql_type).must_equal 'binary(1)'
99
+ _(columns['varbinary_col'].sql_type).must_equal 'varbinary(8000)'
100
+ _(columns['uuid_col'].sql_type).must_equal 'uniqueidentifier'
101
+ _(columns['sstimestamp_col'].sql_type).must_equal 'timestamp'
102
+ _(columns['json_col'].sql_type).must_equal 'nvarchar(max)'
102
103
  assert_line :real_col, type: 'real', limit: nil, precision: nil, scale: nil, default: nil
103
104
  assert_line :money_col, type: 'money', limit: nil, precision: 19, scale: 4, default: nil
104
105
  assert_line :smalldatetime_col, type: 'smalldatetime', limit: nil, precision: nil, scale: nil, default: nil
@@ -107,14 +108,14 @@ class SchemaDumperTestSQLServer < ActiveRecord::TestCase
107
108
  assert_line :smallmoney_col, type: 'smallmoney', limit: nil, precision: 10, scale: 4, default: nil
108
109
  assert_line :char_col, type: 'char', limit: 1, precision: nil, scale: nil, default: nil
109
110
  assert_line :varchar_col, type: 'varchar', limit: nil, precision: nil, scale: nil, default: nil
110
- assert_line :text_basic_col, type: 'text_basic', limit: 2147483647, precision: nil, scale: nil, default: nil
111
+ assert_line :text_basic_col, type: 'text_basic', limit: nil, precision: nil, scale: nil, default: nil
111
112
  assert_line :nchar_col, type: 'nchar', limit: 1, precision: nil, scale: nil, default: nil
112
- assert_line :ntext_col, type: 'ntext', limit: 2147483647, precision: nil, scale: nil, default: nil
113
+ assert_line :ntext_col, type: 'ntext', limit: nil, precision: nil, scale: nil, default: nil
113
114
  assert_line :binary_basic_col, type: 'binary_basic', limit: 1, precision: nil, scale: nil, default: nil
114
115
  assert_line :varbinary_col, type: 'varbinary', limit: nil, precision: nil, scale: nil, default: nil
115
116
  assert_line :uuid_col, type: 'uuid', limit: nil, precision: nil, scale: nil, default: nil
116
117
  assert_line :sstimestamp_col, type: 'ss_timestamp', limit: nil, precision: nil, scale: nil, default: nil
117
- assert_line :json_col, type: 'text', limit: 2147483647, precision: nil, scale: nil, default: nil
118
+ assert_line :json_col, type: 'text', limit: nil, precision: nil, scale: nil, default: nil
118
119
  end
119
120
 
120
121
  # Special Cases
@@ -129,7 +130,7 @@ class SchemaDumperTestSQLServer < ActiveRecord::TestCase
129
130
 
130
131
  it 'no id with model driven primary key' do
131
132
  output = generate_schema_for_table 'sst_no_pk_data'
132
- output.must_match %r{create_table "sst_no_pk_data".*id:\sfalse.*do}
133
+ _(output).must_match %r{create_table "sst_no_pk_data".*id:\sfalse.*do}
133
134
  assert_line :name, type: 'string', limit: nil, default: nil, collation: nil
134
135
  end
135
136
 
@@ -165,15 +166,15 @@ class SchemaDumperTestSQLServer < ActiveRecord::TestCase
165
166
  expected = options[key]
166
167
  message = "#{key.to_s.titleize} of #{expected.inspect} not found in:\n#{line}"
167
168
  if expected.nil?
168
- actual.must_be_nil message
169
+ _(actual).must_be_nil message
169
170
  elsif expected.is_a?(Array)
170
171
  actual.must_include expected, message
171
172
  elsif expected.is_a?(Float)
172
- actual.must_be_close_to expected, 0.001
173
+ _(actual).must_be_close_to expected, 0.001
173
174
  elsif expected.is_a?(Proc)
174
- actual.call.must_equal(expected.call)
175
+ _(actual.call).must_equal(expected.call)
175
176
  else
176
- actual.must_equal expected, message
177
+ _(actual).must_equal expected, message
177
178
  end
178
179
  end
179
180
  end