tiny_tds 2.1.2 → 3.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/ci.yml +571 -0
  3. data/.gitignore +2 -0
  4. data/CHANGELOG.md +56 -1
  5. data/Gemfile +1 -8
  6. data/ISSUE_TEMPLATE.md +1 -1
  7. data/README.md +89 -89
  8. data/Rakefile +44 -30
  9. data/VERSION +1 -1
  10. data/docker-compose.yml +34 -0
  11. data/ext/tiny_tds/client.c +100 -59
  12. data/ext/tiny_tds/client.h +5 -3
  13. data/ext/tiny_tds/extconf.rb +173 -52
  14. data/ext/tiny_tds/extconsts.rb +4 -11
  15. data/ext/tiny_tds/result.c +52 -45
  16. data/ext/tiny_tds/tiny_tds_ext.c +4 -1
  17. data/lib/tiny_tds/bin.rb +12 -26
  18. data/lib/tiny_tds/client.rb +38 -42
  19. data/lib/tiny_tds/error.rb +0 -2
  20. data/lib/tiny_tds/gem.rb +5 -14
  21. data/lib/tiny_tds/result.rb +0 -2
  22. data/lib/tiny_tds/version.rb +1 -1
  23. data/lib/tiny_tds.rb +28 -47
  24. data/setup_cimgruby_dev.sh +25 -0
  25. data/start_dev.sh +21 -0
  26. data/tasks/native_gem.rake +12 -10
  27. data/tasks/package.rake +1 -3
  28. data/tasks/ports.rake +14 -77
  29. data/tasks/test.rake +3 -5
  30. data/test/bin/install-freetds.sh +2 -4
  31. data/test/bin/install-mssql.ps1 +42 -0
  32. data/test/bin/install-mssqltools.sh +9 -0
  33. data/test/bin/restore-from-native-gem.ps1 +10 -0
  34. data/test/bin/setup_tinytds_db.sh +7 -0
  35. data/test/bin/setup_volume_permissions.sh +10 -0
  36. data/test/client_test.rb +152 -116
  37. data/test/gem_test.rb +39 -118
  38. data/test/result_test.rb +285 -350
  39. data/test/schema_test.rb +369 -395
  40. data/test/sql/db-create.sql +18 -0
  41. data/test/sql/db-login.sql +38 -0
  42. data/test/test_helper.rb +112 -85
  43. data/test/thread_test.rb +22 -31
  44. data/tiny_tds.gemspec +28 -26
  45. metadata +85 -59
  46. data/.travis.yml +0 -24
  47. data/BACKERS.md +0 -32
  48. data/appveyor.yml +0 -51
  49. data/tasks/ports/freetds.rb +0 -37
  50. data/tasks/ports/libiconv.rb +0 -43
  51. data/tasks/ports/openssl.rb +0 -78
  52. data/tasks/ports/recipe.rb +0 -52
  53. data/test/appveyor/dbsetup.ps1 +0 -27
  54. data/test/appveyor/dbsetup.sql +0 -9
  55. data/test/benchmark/query.rb +0 -77
  56. data/test/benchmark/query_odbc.rb +0 -106
  57. data/test/benchmark/query_tinytds.rb +0 -126
  58. data/test/bin/setup.sh +0 -19
  59. data/test/schema/sqlserver_2000.sql +0 -140
  60. data/test/schema/sqlserver_2005.sql +0 -140
  61. data/test/schema/sqlserver_2014.sql +0 -140
  62. data/test/schema/sqlserver_2016.sql +0 -140
  63. data/test/schema/sybase_ase.sql +0 -138
  64. /data/test/schema/{sqlserver_2008.sql → sqlserver_2017.sql} +0 -0
data/test/result_test.rb CHANGED
@@ -1,43 +1,40 @@
1
- # encoding: utf-8
2
- require 'test_helper'
1
+ require "test_helper"
3
2
 
4
3
  class ResultTest < TinyTds::TestCase
5
-
6
- describe 'Basic query and result' do
7
-
4
+ describe "Basic query and result" do
8
5
  before do
9
6
  @@current_schema_loaded ||= load_current_schema
10
7
  @client = new_connection
11
- @query1 = 'SELECT 1 AS [one]'
8
+ @query1 = "SELECT 1 AS [one]"
12
9
  end
13
10
 
14
- it 'has included Enumerable' do
11
+ it "has included Enumerable" do
15
12
  assert TinyTds::Result.ancestors.include?(Enumerable)
16
13
  end
17
14
 
18
- it 'responds to #each' do
15
+ it "responds to #each" do
19
16
  result = @client.execute(@query1)
20
17
  assert result.respond_to?(:each)
21
18
  end
22
19
 
23
- it 'returns all results for #each with no block' do
20
+ it "returns all results for #each with no block" do
24
21
  result = @client.execute(@query1)
25
22
  data = result.each
26
23
  row = data.first
27
24
  assert_instance_of Array, data
28
25
  assert_equal 1, data.size
29
- assert_instance_of Hash, row, 'hash is the default query option'
26
+ assert_instance_of Hash, row, "hash is the default query option"
30
27
  end
31
28
 
32
- it 'returns all results for #each with a block yielding a row at a time' do
29
+ it "returns all results for #each with a block yielding a row at a time" do
33
30
  result = @client.execute(@query1)
34
31
  data = result.each do |row|
35
- assert_instance_of Hash, row, 'hash is the default query option'
32
+ assert_instance_of Hash, row, "hash is the default query option"
36
33
  end
37
34
  assert_instance_of Array, data
38
35
  end
39
36
 
40
- it 'allows successive calls to each returning the same data' do
37
+ it "allows successive calls to each returning the same data" do
41
38
  result = @client.execute(@query1)
42
39
  data = result.each
43
40
  result.each
@@ -45,151 +42,150 @@ class ResultTest < TinyTds::TestCase
45
42
  assert_equal data.first.object_id, result.each.first.object_id
46
43
  end
47
44
 
48
- it 'returns hashes with string keys' do
45
+ it "returns hashes with string keys" do
49
46
  result = @client.execute(@query1)
50
- row = result.each(:as => :hash, :symbolize_keys => false).first
47
+ row = result.each(as: :hash, symbolize_keys: false).first
51
48
  assert_instance_of Hash, row
52
- assert_equal ['one'], row.keys
53
- assert_equal ['one'], result.fields
49
+ assert_equal ["one"], row.keys
50
+ assert_equal ["one"], result.fields
54
51
  end
55
52
 
56
- it 'returns hashes with symbol keys' do
53
+ it "returns hashes with symbol keys" do
57
54
  result = @client.execute(@query1)
58
- row = result.each(:as => :hash, :symbolize_keys => true).first
55
+ row = result.each(as: :hash, symbolize_keys: true).first
59
56
  assert_instance_of Hash, row
60
57
  assert_equal [:one], row.keys
61
58
  assert_equal [:one], result.fields
62
59
  end
63
60
 
64
- it 'returns arrays with string fields' do
61
+ it "returns arrays with string fields" do
65
62
  result = @client.execute(@query1)
66
- row = result.each(:as => :array, :symbolize_keys => false).first
63
+ row = result.each(as: :array, symbolize_keys: false).first
67
64
  assert_instance_of Array, row
68
- assert_equal ['one'], result.fields
65
+ assert_equal ["one"], result.fields
69
66
  end
70
67
 
71
- it 'returns arrays with symbol fields' do
68
+ it "returns arrays with symbol fields" do
72
69
  result = @client.execute(@query1)
73
- row = result.each(:as => :array, :symbolize_keys => true).first
70
+ row = result.each(as: :array, symbolize_keys: true).first
74
71
  assert_instance_of Array, row
75
72
  assert_equal [:one], result.fields
76
73
  end
77
74
 
78
- it 'allows sql concat + to work' do
75
+ it "allows sql concat + to work" do
79
76
  rollback_transaction(@client) do
80
77
  @client.execute("DELETE FROM [datatypes]").do
81
78
  @client.execute("INSERT INTO [datatypes] ([char_10], [varchar_50]) VALUES ('1', '2')").do
82
- result = @client.execute("SELECT TOP (1) [char_10] + 'test' + [varchar_50] AS [test] FROM [datatypes]").each.first['test']
83
- result.must_equal "1 test2"
79
+ result = @client.execute("SELECT TOP (1) [char_10] + 'test' + [varchar_50] AS [test] FROM [datatypes]").each.first["test"]
80
+ _(result).must_equal "1 test2"
84
81
  end
85
82
  end
86
83
 
87
- it 'must be able to turn :cache_rows option off' do
84
+ it "must be able to turn :cache_rows option off" do
88
85
  result = @client.execute(@query1)
89
86
  local = []
90
- result.each(:cache_rows => false) do |row|
87
+ result.each(cache_rows: false) do |row|
91
88
  local << row
92
89
  end
93
- assert local.first, 'should have iterated over each row'
94
- assert_equal [], result.each, 'should not have been cached'
95
- assert_equal ['one'], result.fields, 'should still cache field names'
90
+ assert local.first, "should have iterated over each row"
91
+ assert_equal [], result.each, "should not have been cached"
92
+ assert_equal ["one"], result.fields, "should still cache field names"
96
93
  end
97
94
 
98
- it 'must be able to get the first result row only' do
95
+ it "must be able to get the first result row only" do
99
96
  load_current_schema
100
97
  big_query = "SELECT [id] FROM [datatypes]"
101
- one = @client.execute(big_query).each(:first => true)
98
+ one = @client.execute(big_query).each(first: true)
102
99
  many = @client.execute(big_query).each
103
100
  assert many.size > 1
104
101
  assert one.size == 1
105
102
  end
106
103
 
107
- it 'copes with no results when using first option' do
108
- data = @client.execute("SELECT [id] FROM [datatypes] WHERE [id] = -1").each(:first => true)
104
+ it "copes with no results when using first option" do
105
+ data = @client.execute("SELECT [id] FROM [datatypes] WHERE [id] = -1").each(first: true)
109
106
  assert_equal [], data
110
107
  end
111
108
 
112
- it 'must delete, insert and find data' do
109
+ it "must delete, insert and find data" do
113
110
  rollback_transaction(@client) do
114
- text = 'test insert and delete'
111
+ text = "test insert and delete"
115
112
  @client.execute("DELETE FROM [datatypes] WHERE [varchar_50] IS NOT NULL").do
116
113
  @client.execute("INSERT INTO [datatypes] ([varchar_50]) VALUES ('#{text}')").do
117
114
  row = @client.execute("SELECT [varchar_50] FROM [datatypes] WHERE [varchar_50] IS NOT NULL").each.first
118
115
  assert row
119
- assert_equal text, row['varchar_50']
116
+ assert_equal text, row["varchar_50"]
120
117
  end
121
118
  end
122
119
 
123
- it 'must insert and find unicode data' do
120
+ it "must insert and find unicode data" do
124
121
  rollback_transaction(@client) do
125
- text = '😍'
122
+ text = "😍"
126
123
  @client.execute("DELETE FROM [datatypes] WHERE [nvarchar_50] IS NOT NULL").do
127
124
  @client.execute("INSERT INTO [datatypes] ([nvarchar_50]) VALUES (N'#{text}')").do
128
125
  row = @client.execute("SELECT [nvarchar_50] FROM [datatypes] WHERE [nvarchar_50] IS NOT NULL").each.first
129
- assert_equal text, row['nvarchar_50']
126
+ assert_equal text, row["nvarchar_50"]
130
127
  end
131
128
  end
132
129
 
133
- it 'must delete and update with affected rows support and insert with identity support in native sql' do
130
+ it "must delete and update with affected rows support and insert with identity support in native sql" do
134
131
  rollback_transaction(@client) do
135
- text = 'test affected rows sql'
132
+ text = "test affected rows sql"
136
133
  @client.execute("DELETE FROM [datatypes]").do
137
- afrows = @client.execute("SELECT @@ROWCOUNT AS AffectedRows").each.first['AffectedRows']
138
- ['Fixnum', 'Integer'].must_include afrows.class.name
134
+ afrows = @client.execute("SELECT @@ROWCOUNT AS AffectedRows").each.first["AffectedRows"]
135
+ _(["Fixnum", "Integer"]).must_include afrows.class.name
139
136
  @client.execute("INSERT INTO [datatypes] ([varchar_50]) VALUES ('#{text}')").do
140
- pk1 = @client.execute(@client.identity_sql).each.first['Ident']
141
- ['Fixnum', 'Integer'].must_include pk1.class.name, 'we it be able to CAST to bigint'
137
+ pk1 = @client.execute(@client.identity_sql).each.first["Ident"]
138
+ _(["Fixnum", "Integer"]).must_include pk1.class.name, "we it be able to CAST to bigint"
142
139
  @client.execute("UPDATE [datatypes] SET [varchar_50] = NULL WHERE [varchar_50] = '#{text}'").do
143
- afrows = @client.execute("SELECT @@ROWCOUNT AS AffectedRows").each.first['AffectedRows']
140
+ afrows = @client.execute("SELECT @@ROWCOUNT AS AffectedRows").each.first["AffectedRows"]
144
141
  assert_equal 1, afrows
145
142
  end
146
143
  end
147
144
 
148
- it 'has a #do method that cancels result rows and returns affected rows natively' do
145
+ it "has a #do method that cancels result rows and returns affected rows natively" do
149
146
  rollback_transaction(@client) do
150
- text = 'test affected rows native'
151
- count = @client.execute("SELECT COUNT(*) AS [count] FROM [datatypes]").each.first['count']
147
+ text = "test affected rows native"
148
+ count = @client.execute("SELECT COUNT(*) AS [count] FROM [datatypes]").each.first["count"]
152
149
  deleted_rows = @client.execute("DELETE FROM [datatypes]").do
153
- assert_equal count, deleted_rows, 'should have deleted rows equal to count'
150
+ assert_equal count, deleted_rows, "should have deleted rows equal to count"
154
151
  inserted_rows = @client.execute("INSERT INTO [datatypes] ([varchar_50]) VALUES ('#{text}')").do
155
- assert_equal 1, inserted_rows, 'should have inserted row for one above'
152
+ assert_equal 1, inserted_rows, "should have inserted row for one above"
156
153
  updated_rows = @client.execute("UPDATE [datatypes] SET [varchar_50] = NULL WHERE [varchar_50] = '#{text}'").do
157
- assert_equal 1, updated_rows, 'should have updated row for one above' unless sqlserver_2000? # Will report -1
154
+ assert_equal 1, updated_rows, "should have updated row for one above"
158
155
  end
159
156
  end
160
157
 
161
- it 'allows native affected rows using #do to work under transaction' do
158
+ it "allows native affected rows using #do to work under transaction" do
162
159
  rollback_transaction(@client) do
163
- text = 'test affected rows native in transaction'
160
+ text = "test affected rows native in transaction"
164
161
  @client.execute("BEGIN TRANSACTION").do
165
162
  @client.execute("DELETE FROM [datatypes]").do
166
163
  inserted_rows = @client.execute("INSERT INTO [datatypes] ([varchar_50]) VALUES ('#{text}')").do
167
- assert_equal 1, inserted_rows, 'should have inserted row for one above'
164
+ assert_equal 1, inserted_rows, "should have inserted row for one above"
168
165
  updated_rows = @client.execute("UPDATE [datatypes] SET [varchar_50] = NULL WHERE [varchar_50] = '#{text}'").do
169
- assert_equal 1, updated_rows, 'should have updated row for one above' unless sqlserver_2000? # Will report -1
166
+ assert_equal 1, updated_rows, "should have updated row for one above"
170
167
  end
171
168
  end
172
169
 
173
- it 'has an #insert method that cancels result rows and returns IDENTITY natively' do
170
+ it "has an #insert method that cancels result rows and returns IDENTITY natively" do
174
171
  rollback_transaction(@client) do
175
- text = 'test scope identity rows native'
172
+ text = "test scope identity rows native"
176
173
  @client.execute("DELETE FROM [datatypes] WHERE [varchar_50] = '#{text}'").do
177
174
  @client.execute("INSERT INTO [datatypes] ([varchar_50]) VALUES ('#{text}')").do
178
- sql_identity = @client.execute(@client.identity_sql).each.first['Ident']
175
+ sql_identity = @client.execute(@client.identity_sql).each.first["Ident"]
179
176
  native_identity = @client.execute("INSERT INTO [datatypes] ([varchar_50]) VALUES ('#{text}')").insert
180
- assert_equal sql_identity+1, native_identity
177
+ assert_equal sql_identity + 1, native_identity
181
178
  end
182
179
  end
183
180
 
184
- it 'returns bigint for #insert when needed' do
181
+ it "returns bigint for #insert when needed" do
185
182
  return if sqlserver_azure? # We can not alter clustered index like this test does.
186
- return if sybase_ase? # On Sybase, sp_helpindex cannot be used inside a transaction since it does a
187
- # 'CREATE TABLE' command is not allowed within a multi-statement transaction
188
- # and and sp_helpindex creates a temporary table #spindtab.
183
+ # 'CREATE TABLE' command is not allowed within a multi-statement transaction
184
+ # and and sp_helpindex creates a temporary table #spindtab.
189
185
  rollback_transaction(@client) do
190
186
  seed = 9223372036854775805
191
187
  @client.execute("DELETE FROM [datatypes]").do
192
- id_constraint_name = @client.execute("EXEC sp_helpindex [datatypes]").detect{ |row| row['index_keys'] == 'id' }['index_name']
188
+ id_constraint_name = @client.execute("EXEC sp_helpindex [datatypes]").detect { |row| row["index_keys"] == "id" }["index_name"]
193
189
  @client.execute("ALTER TABLE [datatypes] DROP CONSTRAINT [#{id_constraint_name}]").do
194
190
  @client.execute("ALTER TABLE [datatypes] DROP COLUMN [id]").do
195
191
  @client.execute("ALTER TABLE [datatypes] ADD [id] [bigint] NOT NULL IDENTITY(1,1) PRIMARY KEY").do
@@ -199,151 +195,154 @@ class ResultTest < TinyTds::TestCase
199
195
  end
200
196
  end
201
197
 
202
- it 'must be able to begin/commit transactions with raw sql' do
198
+ it "must be able to begin/commit transactions with raw sql" do
203
199
  rollback_transaction(@client) do
204
200
  @client.execute("BEGIN TRANSACTION").do
205
201
  @client.execute("DELETE FROM [datatypes]").do
206
202
  @client.execute("COMMIT TRANSACTION").do
207
- count = @client.execute("SELECT COUNT(*) AS [count] FROM [datatypes]").each.first['count']
203
+ count = @client.execute("SELECT COUNT(*) AS [count] FROM [datatypes]").each.first["count"]
208
204
  assert_equal 0, count
209
205
  end
210
206
  end
211
207
 
212
- it 'must be able to begin/rollback transactions with raw sql' do
208
+ it "must be able to begin/rollback transactions with raw sql" do
213
209
  load_current_schema
214
210
  @client.execute("BEGIN TRANSACTION").do
215
211
  @client.execute("DELETE FROM [datatypes]").do
216
212
  @client.execute("ROLLBACK TRANSACTION").do
217
- count = @client.execute("SELECT COUNT(*) AS [count] FROM [datatypes]").each.first['count']
218
- 0.wont_equal count
213
+ count = @client.execute("SELECT COUNT(*) AS [count] FROM [datatypes]").each.first["count"]
214
+ _(count).wont_equal 0
219
215
  end
220
216
 
221
- it 'has a #fields accessor with logic default and valid outcome' do
217
+ it "has a #fields accessor with logic default and valid outcome" do
222
218
  result = @client.execute(@query1)
223
- result.fields.must_equal ['one']
219
+ _(result.fields).must_equal ["one"]
224
220
  result.each
225
- result.fields.must_equal ['one']
221
+ _(result.fields).must_equal ["one"]
226
222
  end
227
223
 
228
- it 'always returns an array for fields for all sql' do
224
+ it "always returns an array for fields for all sql" do
229
225
  result = @client.execute("USE [tinytdstest]")
230
- result.fields.must_equal []
226
+ _(result.fields).must_equal []
231
227
  result.do
232
- result.fields.must_equal []
228
+ _(result.fields).must_equal []
233
229
  end
234
230
 
235
- it 'returns fields even when no results are found' do
231
+ it "returns fields even when no results are found" do
236
232
  no_results_query = "SELECT [id], [varchar_50] FROM [datatypes] WHERE [varchar_50] = 'NOTFOUND'"
237
233
  # Fields before each.
238
234
  result = @client.execute(no_results_query)
239
- result.fields.must_equal ['id','varchar_50']
235
+ _(result.fields).must_equal ["id", "varchar_50"]
240
236
  result.each
241
- result.fields.must_equal ['id','varchar_50']
237
+ _(result.fields).must_equal ["id", "varchar_50"]
242
238
  # Each then fields
243
239
  result = @client.execute(no_results_query)
244
240
  result.each
245
- result.fields.must_equal ['id','varchar_50']
241
+ _(result.fields).must_equal ["id", "varchar_50"]
246
242
  end
247
243
 
248
- it 'allows the result to be canceled before reading' do
244
+ it "allows the result to be canceled before reading" do
249
245
  result = @client.execute(@query1)
250
246
  result.cancel
251
247
  @client.execute(@query1).each
252
248
  end
253
249
 
254
- it 'works in tandem with the client when needing to find out if client has sql sent and result is canceled or not' do
250
+ it "works in tandem with the client when needing to find out if client has sql sent and result is canceled or not" do
255
251
  # Default state.
256
252
  @client = TinyTds::Client.new(connection_options)
257
- @client.sqlsent?.must_equal false
258
- @client.canceled?.must_equal false
253
+ _(@client.sqlsent?).must_equal false
254
+ _(@client.canceled?).must_equal false
259
255
  # With active result before and after cancel.
260
256
  result = @client.execute(@query1)
261
- @client.sqlsent?.must_equal true
262
- @client.canceled?.must_equal false
257
+ _(@client.sqlsent?).must_equal true
258
+ _(@client.canceled?).must_equal false
263
259
  result.cancel
264
- @client.sqlsent?.must_equal false
265
- @client.canceled?.must_equal true
266
- assert result.cancel, 'must be safe to call again'
260
+ _(@client.sqlsent?).must_equal false
261
+ _(@client.canceled?).must_equal true
262
+ assert result.cancel, "must be safe to call again"
267
263
  # With each and no block.
268
264
  @client.execute(@query1).each
269
- @client.sqlsent?.must_equal false
270
- @client.canceled?.must_equal false
265
+ _(@client.sqlsent?).must_equal false
266
+ _(@client.canceled?).must_equal false
271
267
  # With each and block.
272
268
  @client.execute(@query1).each do |row|
273
- @client.sqlsent?.must_equal true, 'when iterating over each row in a block'
274
- @client.canceled?.must_equal false
269
+ _(@client.sqlsent?).must_equal true, "when iterating over each row in a block"
270
+ _(@client.canceled?).must_equal false
275
271
  end
276
- @client.sqlsent?.must_equal false
277
- @client.canceled?.must_equal false
272
+ _(@client.sqlsent?).must_equal false
273
+ _(@client.canceled?).must_equal false
278
274
  # With each and block canceled half way thru.
279
- count = @client.execute("SELECT COUNT([id]) AS [count] FROM [datatypes]").each[0]['count']
280
- assert count > 10, 'since we want to cancel early for test'
275
+ count = @client.execute("SELECT COUNT([id]) AS [count] FROM [datatypes]").each[0]["count"]
276
+ assert count > 10, "since we want to cancel early for test"
281
277
  result = @client.execute("SELECT [id] FROM [datatypes]")
282
278
  index = 0
283
279
  result.each do |row|
284
280
  break if index > 10
285
281
  index += 1
286
282
  end
287
- @client.sqlsent?.must_equal true
288
- @client.canceled?.must_equal false
283
+ _(@client.sqlsent?).must_equal true
284
+ _(@client.canceled?).must_equal false
289
285
  result.cancel
290
- @client.sqlsent?.must_equal false
291
- @client.canceled?.must_equal true
286
+ _(@client.sqlsent?).must_equal false
287
+ _(@client.canceled?).must_equal true
292
288
  # With do method.
293
289
  @client.execute(@query1).do
294
- @client.sqlsent?.must_equal false
295
- @client.canceled?.must_equal true
290
+ _(@client.sqlsent?).must_equal false
291
+ _(@client.canceled?).must_equal true
296
292
  # With insert method.
297
293
  rollback_transaction(@client) do
298
294
  @client.execute("INSERT INTO [datatypes] ([varchar_50]) VALUES ('test')").insert
299
- @client.sqlsent?.must_equal false
300
- @client.canceled?.must_equal true
295
+ _(@client.sqlsent?).must_equal false
296
+ _(@client.canceled?).must_equal true
301
297
  end
302
298
  # With first
303
- @client.execute("SELECT [id] FROM [datatypes]").each(:first => true)
304
- @client.sqlsent?.must_equal false
305
- @client.canceled?.must_equal true
299
+ @client.execute("SELECT [id] FROM [datatypes]").each(first: true)
300
+ _(@client.sqlsent?).must_equal false
301
+ _(@client.canceled?).must_equal true
306
302
  end
307
303
 
308
- it 'use same string object for hash keys' do
304
+ it "use same string object for hash keys" do
309
305
  data = @client.execute("SELECT [id], [bigint] FROM [datatypes]").each
310
- assert_equal data.first.keys.map{ |r| r.object_id }, data.last.keys.map{ |r| r.object_id }
306
+ assert_equal data.first.keys.map { |r| r.object_id }, data.last.keys.map { |r| r.object_id }
311
307
  end
312
308
 
313
- it 'has properly encoded column names with symbol keys' do
309
+ it "has properly encoded column names with symbol keys" do
314
310
  col_name = "öäüß"
315
- @client.execute("DROP TABLE [test_encoding]").do rescue nil
311
+ begin
312
+ @client.execute("DROP TABLE [test_encoding]").do
313
+ rescue
314
+ nil
315
+ end
316
316
  @client.execute("CREATE TABLE [dbo].[test_encoding] ( [id] int NOT NULL IDENTITY(1,1) PRIMARY KEY, [#{col_name}] [nvarchar](10) NOT NULL )").do
317
317
  @client.execute("INSERT INTO [test_encoding] ([#{col_name}]) VALUES (N'#{col_name}')").do
318
318
  result = @client.execute("SELECT [#{col_name}] FROM [test_encoding]")
319
- row = result.each(:as => :hash, :symbolize_keys => true).first
319
+ row = result.each(as: :hash, symbolize_keys: true).first
320
320
  assert_instance_of Symbol, result.fields.first
321
321
  assert_equal col_name.to_sym, result.fields.first
322
322
  assert_instance_of Symbol, row.keys.first
323
323
  assert_equal col_name.to_sym, row.keys.first
324
324
  end
325
325
 
326
- it 'allows #return_code to work with stored procedures and reset per sql batch' do
326
+ it "allows #return_code to work with stored procedures and reset per sql batch" do
327
327
  assert_nil @client.return_code
328
328
  result = @client.execute("EXEC tinytds_TestReturnCodes")
329
- assert_equal [{"one"=>1}], result.each
329
+ assert_equal [{"one" => 1}], result.each
330
330
  assert_equal 420, @client.return_code
331
331
  assert_equal 420, result.return_code
332
- result = @client.execute('SELECT 1 as [one]')
332
+ result = @client.execute("SELECT 1 as [one]")
333
333
  result.each
334
334
  assert_nil @client.return_code
335
335
  assert_nil result.return_code
336
336
  end
337
337
 
338
- it 'with LOGINPROPERTY function' do
339
- v = @client.execute("SELECT LOGINPROPERTY('sa', 'IsLocked') as v").first['v']
340
- v.must_equal 0
338
+ it "with LOGINPROPERTY function" do
339
+ v = @client.execute("SELECT LOGINPROPERTY('sa', 'IsLocked') as v").first["v"]
340
+ _(v).must_equal 0
341
341
  end
342
342
 
343
- describe 'with multiple result sets' do
344
-
343
+ describe "with multiple result sets" do
345
344
  before do
346
- @empty_select = "SELECT 1 AS [rs1] WHERE 1 = 0"
345
+ @empty_select = "SELECT 1 AS [rs1] WHERE 1 = 0"
347
346
  @double_select = "SELECT 1 AS [rs1]
348
347
  SELECT 2 AS [rs2]"
349
348
  @triple_select_1st_empty = "SELECT 1 AS [rs1] WHERE 1 = 0
@@ -357,50 +356,41 @@ class ResultTest < TinyTds::TestCase
357
356
  SELECT 3 AS [rs3] WHERE 1 = 0"
358
357
  end
359
358
 
360
- it 'handles a command buffer with double selects' do
359
+ it "handles a command buffer with double selects" do
361
360
  result = @client.execute(@double_select)
362
361
  result_sets = result.each
363
362
  assert_equal 2, result_sets.size
364
- assert_equal [{'rs1' => 1}], result_sets.first
365
- assert_equal [{'rs2' => 2}], result_sets.last
366
- assert_equal [['rs1'], ['rs2']], result.fields
367
- assert_equal result.each.object_id, result.each.object_id, 'same cached rows'
363
+ assert_equal [{"rs1" => 1}], result_sets.first
364
+ assert_equal [{"rs2" => 2}], result_sets.last
365
+ assert_equal [["rs1"], ["rs2"]], result.fields
366
+ assert_equal result.each.object_id, result.each.object_id, "same cached rows"
368
367
  # As array
369
368
  result = @client.execute(@double_select)
370
- result_sets = result.each(:as => :array)
369
+ result_sets = result.each(as: :array)
371
370
  assert_equal 2, result_sets.size
372
371
  assert_equal [[1]], result_sets.first
373
372
  assert_equal [[2]], result_sets.last
374
- assert_equal [['rs1'], ['rs2']], result.fields
375
- assert_equal result.each.object_id, result.each.object_id, 'same cached rows'
373
+ assert_equal [["rs1"], ["rs2"]], result.fields
374
+ assert_equal result.each.object_id, result.each.object_id, "same cached rows"
376
375
  end
377
376
 
378
- it 'yields each row for each result set' do
377
+ it "yields each row for each result set" do
379
378
  data = []
380
379
  result_sets = @client.execute(@double_select).each { |row| data << row }
381
380
  assert_equal data.first, result_sets.first[0]
382
381
  assert_equal data.last, result_sets.last[0]
383
382
  end
384
383
 
385
- it 'works from a stored procedure' do
386
- if sqlserver?
387
- results1, results2 = @client.execute("EXEC sp_helpconstraint '[datatypes]'").each
388
- assert_equal [{"Object Name"=>"[datatypes]"}], results1
389
- constraint_info = results2.first
390
- assert constraint_info.key?("constraint_keys")
391
- assert constraint_info.key?("constraint_type")
392
- assert constraint_info.key?("constraint_name")
393
- elsif sybase_ase?
394
- results1, results2 = @client.execute("EXEC sp_helpconstraint 'datatypes'").each
395
- assert results1['name'] =~ /^datatypes_bit/
396
- assert results1['defintion'] == 'DEFAULT 0'
397
- assert results2['name'] =~ /^datatypes_id/
398
- assert results2['defintion'] =~ /^PRIMARY KEY/
399
- end
384
+ it "works from a stored procedure" do
385
+ results1, results2 = @client.execute("EXEC sp_helpconstraint '[datatypes]'").each
386
+ assert_equal [{"Object Name" => "[datatypes]"}], results1
387
+ constraint_info = results2.first
388
+ assert constraint_info.key?("constraint_keys")
389
+ assert constraint_info.key?("constraint_type")
390
+ assert constraint_info.key?("constraint_name")
400
391
  end
401
392
 
402
- describe 'using :empty_sets TRUE' do
403
-
393
+ describe "using :empty_sets TRUE" do
404
394
  before do
405
395
  close_client
406
396
  @old_query_option_value = TinyTds::Client.default_query_options[:empty_sets]
@@ -412,76 +402,74 @@ class ResultTest < TinyTds::TestCase
412
402
  TinyTds::Client.default_query_options[:empty_sets] = @old_query_option_value
413
403
  end
414
404
 
415
- it 'handles a basic empty result set' do
405
+ it "handles a basic empty result set" do
416
406
  result = @client.execute(@empty_select)
417
407
  assert_equal [], result.each
418
- assert_equal ['rs1'], result.fields
408
+ assert_equal ["rs1"], result.fields
419
409
  end
420
410
 
421
- it 'includes empty result sets by default - using 1st empty buffer' do
411
+ it "includes empty result sets by default - using 1st empty buffer" do
422
412
  result = @client.execute(@triple_select_1st_empty)
423
413
  result_sets = result.each
424
414
  assert_equal 3, result_sets.size
425
415
  assert_equal [], result_sets[0]
426
- assert_equal [{'rs2' => 2}], result_sets[1]
427
- assert_equal [{'rs3' => 3}], result_sets[2]
428
- assert_equal [['rs1'], ['rs2'], ['rs3']], result.fields
429
- assert_equal result.each.object_id, result.each.object_id, 'same cached rows'
416
+ assert_equal [{"rs2" => 2}], result_sets[1]
417
+ assert_equal [{"rs3" => 3}], result_sets[2]
418
+ assert_equal [["rs1"], ["rs2"], ["rs3"]], result.fields
419
+ assert_equal result.each.object_id, result.each.object_id, "same cached rows"
430
420
  # As array
431
421
  result = @client.execute(@triple_select_1st_empty)
432
- result_sets = result.each(:as => :array)
422
+ result_sets = result.each(as: :array)
433
423
  assert_equal 3, result_sets.size
434
424
  assert_equal [], result_sets[0]
435
425
  assert_equal [[2]], result_sets[1]
436
426
  assert_equal [[3]], result_sets[2]
437
- assert_equal [['rs1'], ['rs2'], ['rs3']], result.fields
438
- assert_equal result.each.object_id, result.each.object_id, 'same cached rows'
427
+ assert_equal [["rs1"], ["rs2"], ["rs3"]], result.fields
428
+ assert_equal result.each.object_id, result.each.object_id, "same cached rows"
439
429
  end
440
430
 
441
- it 'includes empty result sets by default - using 2nd empty buffer' do
431
+ it "includes empty result sets by default - using 2nd empty buffer" do
442
432
  result = @client.execute(@triple_select_2nd_empty)
443
433
  result_sets = result.each
444
434
  assert_equal 3, result_sets.size
445
- assert_equal [{'rs1' => 1}], result_sets[0]
435
+ assert_equal [{"rs1" => 1}], result_sets[0]
446
436
  assert_equal [], result_sets[1]
447
- assert_equal [{'rs3' => 3}], result_sets[2]
448
- assert_equal [['rs1'], ['rs2'], ['rs3']], result.fields
449
- assert_equal result.each.object_id, result.each.object_id, 'same cached rows'
437
+ assert_equal [{"rs3" => 3}], result_sets[2]
438
+ assert_equal [["rs1"], ["rs2"], ["rs3"]], result.fields
439
+ assert_equal result.each.object_id, result.each.object_id, "same cached rows"
450
440
  # As array
451
441
  result = @client.execute(@triple_select_2nd_empty)
452
- result_sets = result.each(:as => :array)
442
+ result_sets = result.each(as: :array)
453
443
  assert_equal 3, result_sets.size
454
444
  assert_equal [[1]], result_sets[0]
455
445
  assert_equal [], result_sets[1]
456
446
  assert_equal [[3]], result_sets[2]
457
- assert_equal [['rs1'], ['rs2'], ['rs3']], result.fields
458
- assert_equal result.each.object_id, result.each.object_id, 'same cached rows'
447
+ assert_equal [["rs1"], ["rs2"], ["rs3"]], result.fields
448
+ assert_equal result.each.object_id, result.each.object_id, "same cached rows"
459
449
  end
460
450
 
461
- it 'includes empty result sets by default - using 3rd empty buffer' do
451
+ it "includes empty result sets by default - using 3rd empty buffer" do
462
452
  result = @client.execute(@triple_select_3rd_empty)
463
453
  result_sets = result.each
464
454
  assert_equal 3, result_sets.size
465
- assert_equal [{'rs1' => 1}], result_sets[0]
466
- assert_equal [{'rs2' => 2}], result_sets[1]
455
+ assert_equal [{"rs1" => 1}], result_sets[0]
456
+ assert_equal [{"rs2" => 2}], result_sets[1]
467
457
  assert_equal [], result_sets[2]
468
- assert_equal [['rs1'], ['rs2'], ['rs3']], result.fields
469
- assert_equal result.each.object_id, result.each.object_id, 'same cached rows'
458
+ assert_equal [["rs1"], ["rs2"], ["rs3"]], result.fields
459
+ assert_equal result.each.object_id, result.each.object_id, "same cached rows"
470
460
  # As array
471
461
  result = @client.execute(@triple_select_3rd_empty)
472
- result_sets = result.each(:as => :array)
462
+ result_sets = result.each(as: :array)
473
463
  assert_equal 3, result_sets.size
474
464
  assert_equal [[1]], result_sets[0]
475
465
  assert_equal [[2]], result_sets[1]
476
466
  assert_equal [], result_sets[2]
477
- assert_equal [['rs1'], ['rs2'], ['rs3']], result.fields
478
- assert_equal result.each.object_id, result.each.object_id, 'same cached rows'
467
+ assert_equal [["rs1"], ["rs2"], ["rs3"]], result.fields
468
+ assert_equal result.each.object_id, result.each.object_id, "same cached rows"
479
469
  end
480
-
481
470
  end
482
471
 
483
- describe 'using :empty_sets FALSE' do
484
-
472
+ describe "using :empty_sets FALSE" do
485
473
  before do
486
474
  close_client
487
475
  @old_query_option_value = TinyTds::Client.default_query_options[:empty_sets]
@@ -493,271 +481,220 @@ class ResultTest < TinyTds::TestCase
493
481
  TinyTds::Client.default_query_options[:empty_sets] = @old_query_option_value
494
482
  end
495
483
 
496
- it 'handles a basic empty result set' do
484
+ it "handles a basic empty result set" do
497
485
  result = @client.execute(@empty_select)
498
486
  assert_equal [], result.each
499
- assert_equal ['rs1'], result.fields
487
+ assert_equal ["rs1"], result.fields
500
488
  end
501
489
 
502
- it 'must not include empty result sets by default - using 1st empty buffer' do
490
+ it "must not include empty result sets by default - using 1st empty buffer" do
503
491
  result = @client.execute(@triple_select_1st_empty)
504
492
  result_sets = result.each
505
493
  assert_equal 2, result_sets.size
506
- assert_equal [{'rs2' => 2}], result_sets[0]
507
- assert_equal [{'rs3' => 3}], result_sets[1]
508
- assert_equal [['rs2'], ['rs3']], result.fields
509
- assert_equal result.each.object_id, result.each.object_id, 'same cached rows'
494
+ assert_equal [{"rs2" => 2}], result_sets[0]
495
+ assert_equal [{"rs3" => 3}], result_sets[1]
496
+ assert_equal [["rs2"], ["rs3"]], result.fields
497
+ assert_equal result.each.object_id, result.each.object_id, "same cached rows"
510
498
  # As array
511
499
  result = @client.execute(@triple_select_1st_empty)
512
- result_sets = result.each(:as => :array)
500
+ result_sets = result.each(as: :array)
513
501
  assert_equal 2, result_sets.size
514
502
  assert_equal [[2]], result_sets[0]
515
503
  assert_equal [[3]], result_sets[1]
516
- assert_equal [['rs2'], ['rs3']], result.fields
517
- assert_equal result.each.object_id, result.each.object_id, 'same cached rows'
504
+ assert_equal [["rs2"], ["rs3"]], result.fields
505
+ assert_equal result.each.object_id, result.each.object_id, "same cached rows"
518
506
  end
519
507
 
520
- it 'must not include empty result sets by default - using 2nd empty buffer' do
508
+ it "must not include empty result sets by default - using 2nd empty buffer" do
521
509
  result = @client.execute(@triple_select_2nd_empty)
522
510
  result_sets = result.each
523
511
  assert_equal 2, result_sets.size
524
- assert_equal [{'rs1' => 1}], result_sets[0]
525
- assert_equal [{'rs3' => 3}], result_sets[1]
526
- assert_equal [['rs1'], ['rs3']], result.fields
527
- assert_equal result.each.object_id, result.each.object_id, 'same cached rows'
512
+ assert_equal [{"rs1" => 1}], result_sets[0]
513
+ assert_equal [{"rs3" => 3}], result_sets[1]
514
+ assert_equal [["rs1"], ["rs3"]], result.fields
515
+ assert_equal result.each.object_id, result.each.object_id, "same cached rows"
528
516
  # As array
529
517
  result = @client.execute(@triple_select_2nd_empty)
530
- result_sets = result.each(:as => :array)
518
+ result_sets = result.each(as: :array)
531
519
  assert_equal 2, result_sets.size
532
520
  assert_equal [[1]], result_sets[0]
533
521
  assert_equal [[3]], result_sets[1]
534
- assert_equal [['rs1'], ['rs3']], result.fields
535
- assert_equal result.each.object_id, result.each.object_id, 'same cached rows'
522
+ assert_equal [["rs1"], ["rs3"]], result.fields
523
+ assert_equal result.each.object_id, result.each.object_id, "same cached rows"
536
524
  end
537
525
 
538
- it 'must not include empty result sets by default - using 3rd empty buffer' do
526
+ it "must not include empty result sets by default - using 3rd empty buffer" do
539
527
  result = @client.execute(@triple_select_3rd_empty)
540
528
  result_sets = result.each
541
529
  assert_equal 2, result_sets.size
542
- assert_equal [{'rs1' => 1}], result_sets[0]
543
- assert_equal [{'rs2' => 2}], result_sets[1]
544
- assert_equal [['rs1'], ['rs2']], result.fields
545
- assert_equal result.each.object_id, result.each.object_id, 'same cached rows'
530
+ assert_equal [{"rs1" => 1}], result_sets[0]
531
+ assert_equal [{"rs2" => 2}], result_sets[1]
532
+ assert_equal [["rs1"], ["rs2"]], result.fields
533
+ assert_equal result.each.object_id, result.each.object_id, "same cached rows"
546
534
  # As array
547
535
  result = @client.execute(@triple_select_3rd_empty)
548
- result_sets = result.each(:as => :array)
536
+ result_sets = result.each(as: :array)
549
537
  assert_equal 2, result_sets.size
550
538
  assert_equal [[1]], result_sets[0]
551
539
  assert_equal [[2]], result_sets[1]
552
- assert_equal [['rs1'], ['rs2']], result.fields
553
- assert_equal result.each.object_id, result.each.object_id, 'same cached rows'
540
+ assert_equal [["rs1"], ["rs2"]], result.fields
541
+ assert_equal result.each.object_id, result.each.object_id, "same cached rows"
554
542
  end
555
-
556
543
  end
557
-
558
544
  end
559
545
 
560
- describe 'Complex query with multiple results sets but no actual results' do
546
+ unless sqlserver_azure?
547
+ describe "Complex query with multiple results sets but no actual results" do
548
+ let(:backup_file) { 'C:\\Users\\Public\\tinytdstest.bak' }
561
549
 
562
- let(:backup_file) { 'C:\\Users\\Public\\tinytdstest.bak' }
550
+ after { File.delete(backup_file) if File.exist?(backup_file) }
563
551
 
564
- after { File.delete(backup_file) if File.exist?(backup_file) }
565
-
566
- it 'must not cancel the query until complete' do
567
- @client.execute("BACKUP DATABASE tinytdstest TO DISK = '#{backup_file}'").do
552
+ it "must not cancel the query until complete" do
553
+ @client.execute("BACKUP DATABASE tinytdstest TO DISK = '#{backup_file}'").do
554
+ end
568
555
  end
556
+ end
569
557
 
570
- end unless sqlserver_azure?
571
-
572
- describe 'when casting to native ruby values' do
573
-
574
- it 'returns fixnum for 1' do
575
- value = @client.execute('SELECT 1 AS [fixnum]').each.first['fixnum']
558
+ describe "when casting to native ruby values" do
559
+ it "returns fixnum for 1" do
560
+ value = @client.execute("SELECT 1 AS [fixnum]").each.first["fixnum"]
576
561
  assert_equal 1, value
577
562
  end
578
563
 
579
- it 'returns nil for NULL' do
580
- value = @client.execute('SELECT NULL AS [null]').each.first['null']
564
+ it "returns nil for NULL" do
565
+ value = @client.execute("SELECT NULL AS [null]").each.first["null"]
581
566
  assert_nil value
582
567
  end
583
-
584
568
  end
585
569
 
586
- describe 'with data type' do
587
-
588
- describe 'char max' do
589
-
570
+ describe "with data type" do
571
+ describe "char max" do
590
572
  before do
591
- @big_text = 'x' * 2_000_000
592
- @old_textsize = @client.execute("SELECT @@TEXTSIZE AS [textsize]").each.first['textsize'].inspect
593
- @client.execute("SET TEXTSIZE #{(@big_text.length*2)+1}").do
573
+ @big_text = "x" * 2_000_000
574
+ @old_textsize = @client.execute("SELECT @@TEXTSIZE AS [textsize]").each.first["textsize"].inspect
575
+ @client.execute("SET TEXTSIZE #{(@big_text.length * 2) + 1}").do
594
576
  end
595
577
 
596
- it 'must insert and select large varchar_max' do
578
+ it "must insert and select large varchar_max" do
597
579
  insert_and_select_datatype :varchar_max
598
580
  end
599
581
 
600
- it 'must insert and select large nvarchar_max' do
582
+ it "must insert and select large nvarchar_max" do
601
583
  insert_and_select_datatype :nvarchar_max
602
584
  end
603
-
604
- end unless sqlserver_2000? || sybase_ase?
605
-
585
+ end
606
586
  end
607
587
 
608
- describe 'when shit happens' do
609
-
610
- it 'copes with nil or empty buffer' do
588
+ describe "when shit happens" do
589
+ it "copes with nil or empty buffer" do
611
590
  assert_raises(TypeError) { @client.execute(nil) }
612
- assert_equal [], @client.execute('').each
591
+ assert_equal [], @client.execute("").each
613
592
  end
614
593
 
615
- if sqlserver?
594
+ describe "using :message_handler option" do
595
+ let(:messages) { [] }
616
596
 
617
- describe 'using :message_handler option' do
618
- let(:messages) { Array.new }
619
-
620
- before do
621
- close_client
622
- @client = new_connection message_handler: Proc.new { |m| messages << m }
623
- end
624
-
625
- after do
626
- messages.clear
627
- end
597
+ before do
598
+ close_client
599
+ @client = new_connection message_handler: proc { |m| messages << m }
600
+ end
628
601
 
629
- it 'has a message handler that responds to call' do
630
- assert @client.message_handler.respond_to?(:call)
631
- end
602
+ after do
603
+ messages.clear
604
+ end
632
605
 
633
- it 'calls the provided message handler when severity is 10 or less' do
634
- (1..10).to_a.each do |severity|
635
- messages.clear
636
- msg = "Test #{severity} severity"
637
- state = rand(1..255)
638
- @client.execute("RAISERROR(N'#{msg}', #{severity}, #{state})").do
639
- m = messages.first
640
- assert_equal 1, messages.length, 'there should be one message after one raiserror'
641
- assert_equal msg, m.message, 'message text'
642
- assert_equal severity, m.severity, 'message severity' unless severity == 10 && m.severity.to_i == 0
643
- assert_equal state, m.os_error_number, 'message state'
644
- end
645
- end
606
+ it "has a message handler that responds to call" do
607
+ assert @client.message_handler.respond_to?(:call)
608
+ end
646
609
 
647
- it 'calls the provided message handler for `print` messages' do
610
+ it "calls the provided message handler when severity is 10 or less" do
611
+ (1..10).to_a.each do |severity|
648
612
  messages.clear
649
- msg = 'hello'
650
- @client.execute("PRINT '#{msg}'").do
613
+ msg = "Test #{severity} severity"
614
+ state = rand(1..255)
615
+ @client.execute("RAISERROR(N'#{msg}', #{severity}, #{state})").do
651
616
  m = messages.first
652
- assert_equal 1, messages.length, 'there should be one message after one print statement'
653
- assert_equal msg, m.message, 'message text'
617
+ assert_equal 1, messages.length, "there should be one message after one raiserror"
618
+ assert_equal msg, m.message, "message text"
619
+ assert_equal severity, m.severity, "message severity" unless severity == 10 && m.severity.to_i == 0
620
+ assert_equal state, m.os_error_number, "message state"
654
621
  end
655
622
  end
656
623
 
657
- it 'must not raise an error when severity is 10 or less' do
658
- (1..10).to_a.each do |severity|
659
- @client.execute("RAISERROR(N'Test #{severity} severity', #{severity}, 1)").do
660
- end
624
+ it "calls the provided message handler for `print` messages" do
625
+ messages.clear
626
+ msg = "hello"
627
+ @client.execute("PRINT '#{msg}'").do
628
+ m = messages.first
629
+ assert_equal 1, messages.length, "there should be one message after one print statement"
630
+ assert_equal msg, m.message, "message text"
661
631
  end
662
632
 
663
- it 'raises an error when severity is greater than 10' do
664
- action = lambda { @client.execute("RAISERROR(N'Test 11 severity', 11, 1)").do }
633
+ it "must raise an error preceded by a `print` message" do
634
+ messages.clear
635
+ action = lambda { @client.execute("EXEC tinytds_TestPrintWithError").do }
665
636
  assert_raise_tinytds_error(action) do |e|
666
- assert_equal "Test 11 severity", e.message
667
- assert_equal 11, e.severity
637
+ assert_equal "hello", messages.first.message, "message text"
638
+
639
+ assert_equal "Error following print", e.message
640
+ assert_equal 16, e.severity
668
641
  assert_equal 50000, e.db_error_number
669
642
  end
670
643
  end
671
644
 
672
- else
645
+ it "calls the provided message handler for each of a series of `print` messages" do
646
+ messages.clear
647
+ @client.execute("EXEC tinytds_TestSeveralPrints").do
648
+ assert_equal ["hello 1", "hello 2", "hello 3"], messages.map { |e| e.message }, "message list"
649
+ end
673
650
 
674
- it 'raises an error' do
675
- action = lambda { @client.execute("RAISERROR 50000 N'Hello World'").do }
651
+ it "should flush info messages before raising error in cases of timeout" do
652
+ @client = new_connection timeout: 1, message_handler: proc { |m| messages << m }
653
+ action = lambda { @client.execute("print 'hello'; waitfor delay '00:00:02'").do }
654
+ messages.clear
676
655
  assert_raise_tinytds_error(action) do |e|
677
- assert_equal "Hello World", e.message
678
- assert_equal 16, e.severity # predefined on ASE
679
- assert_equal 50000, e.db_error_number
656
+ assert_match %r{timed out}i, e.message, "ignore if non-english test run"
657
+ assert_equal 6, e.severity
658
+ assert_equal 20003, e.db_error_number
659
+ assert_equal "hello", messages.first&.message, "message text"
680
660
  end
681
- assert_followup_query
682
661
  end
683
662
 
684
- end
685
-
686
- it 'throws an error when you execute another query with other results pending' do
687
- result1 = @client.execute(@query1)
688
- action = lambda { @client.execute(@query1) }
689
- assert_raise_tinytds_error(action) do |e|
690
- assert_match %r|with results pending|i, e.message
691
- assert_equal 7, e.severity
692
- assert_equal 20019, e.db_error_number
663
+ it "should print info messages before raising error in cases of timeout" do
664
+ @client = new_connection timeout: 1, message_handler: proc { |m| messages << m }
665
+ action = lambda { @client.execute("raiserror('hello', 1, 1) with nowait; waitfor delay '00:00:02'").do }
666
+ messages.clear
667
+ assert_raise_tinytds_error(action) do |e|
668
+ assert_match %r{timed out}i, e.message, "ignore if non-english test run"
669
+ assert_equal 6, e.severity
670
+ assert_equal 20003, e.db_error_number
671
+ assert_equal "hello", messages.first&.message, "message text"
672
+ end
693
673
  end
694
674
  end
695
675
 
696
- it 'must error gracefully with bad table name' do
697
- action = lambda { @client.execute('SELECT * FROM [foobar]').each }
698
- assert_raise_tinytds_error(action) do |e|
699
- pattern = sybase_ase? ? /foobar not found/ : %r|invalid object name.*foobar|i
700
- assert_match pattern, e.message
701
- assert_equal 16, e.severity
702
- assert_equal 208, e.db_error_number
676
+ it "must not raise an error when severity is 10 or less" do
677
+ (1..10).to_a.each do |severity|
678
+ @client.execute("RAISERROR(N'Test #{severity} severity', #{severity}, 1)").do
703
679
  end
704
- assert_followup_query
705
680
  end
706
681
 
707
- it 'must error gracefully with incorrect syntax' do
708
- action = lambda { @client.execute('this will not work').each }
682
+ it "raises an error when severity is greater than 10" do
683
+ action = lambda { @client.execute("RAISERROR(N'Test 11 severity', 11, 1)").do }
709
684
  assert_raise_tinytds_error(action) do |e|
710
- assert_match %r|incorrect syntax|i, e.message
711
- assert_equal 15, e.severity
712
- assert_equal 156, e.db_error_number
685
+ assert_equal "Test 11 severity", e.message
686
+ assert_equal 11, e.severity
687
+ assert_equal 50000, e.db_error_number
713
688
  end
714
- assert_followup_query
715
689
  end
716
-
717
- it 'must not error at all from reading non-convertable charcters and just use ? marks' do
718
- close_client
719
- @client = new_connection :encoding => 'ASCII'
720
- @client.charset.must_equal 'ASCII'
721
- find_value(202, :nvarchar_50).must_equal 'test nvarchar_50 ??'
722
- end
723
-
724
- it 'must error gracefully from writing non-convertable characters' do
725
- close_client
726
- @client = new_connection :encoding => 'ASCII'
727
- @client.charset.must_equal 'ASCII'
728
- rollback_transaction(@client) do
729
- text = 'Test ✓'
730
- @client.execute("DELETE FROM [datatypes] WHERE [nvarchar_50] IS NOT NULL").do
731
- action = lambda { @client.execute("INSERT INTO [datatypes] ([nvarchar_50]) VALUES ('#{text}')").do }
732
- assert_raise_tinytds_error(action) do |e|
733
- e.message.must_match %r{Unclosed quotation mark}i
734
- e.severity.must_equal 15
735
- e.db_error_number.must_equal 105
736
- end
737
- assert_followup_query
738
- end
739
- end
740
-
741
- it 'errors gracefully with incorrect syntax in sp_executesql' do
742
- action = lambda { @client.execute("EXEC sp_executesql N'this will not work'").each }
743
- assert_raise_tinytds_error(action) do |e|
744
- assert_match %r|incorrect syntax|i, e.message
745
- assert_equal 15, e.severity
746
- assert_equal 156, e.db_error_number
747
- end
748
- assert_followup_query
749
- end unless sybase_ase?
750
-
751
690
  end
752
-
753
691
  end
754
692
 
755
-
756
693
  protected
757
694
 
758
695
  def assert_followup_query
759
696
  result = @client.execute(@query1)
760
- assert_equal 1, result.each.first['one']
697
+ assert_equal 1, result.each.first["one"]
761
698
  end
762
699
 
763
700
  def insert_and_select_datatype(datatype)
@@ -768,6 +705,4 @@ class ResultTest < TinyTds::TestCase
768
705
  flunk "Large #{datatype} data with a length of #{@big_text.length} did not match found text with length of #{found_text.length}" unless @big_text == found_text
769
706
  end
770
707
  end
771
-
772
708
  end
773
-