tiny_tds 2.1.3.pre-x86-mingw32 → 2.1.5-x86-mingw32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.codeclimate.yml +0 -0
- data/.gitattributes +0 -0
- data/.gitignore +0 -0
- data/.rubocop.yml +0 -0
- data/.travis.yml +1 -1
- data/CHANGELOG.md +12 -1
- data/CODE_OF_CONDUCT.md +0 -0
- data/Gemfile +0 -0
- data/ISSUE_TEMPLATE.md +0 -0
- data/MIT-LICENSE +0 -0
- data/README.md +13 -7
- data/Rakefile +0 -0
- data/VERSION +1 -1
- data/appveyor.yml +15 -1
- data/docker-compose.yml +22 -0
- data/ext/tiny_tds/client.c +90 -44
- data/ext/tiny_tds/client.h +5 -3
- data/ext/tiny_tds/extconf.rb +0 -0
- data/ext/tiny_tds/extconsts.rb +1 -1
- data/ext/tiny_tds/result.c +24 -10
- data/ext/tiny_tds/result.h +0 -0
- data/ext/tiny_tds/tiny_tds_ext.c +0 -0
- data/ext/tiny_tds/tiny_tds_ext.h +0 -0
- data/lib/tiny_tds.rb +0 -0
- data/lib/tiny_tds/bin.rb +0 -0
- data/lib/tiny_tds/client.rb +0 -0
- data/lib/tiny_tds/error.rb +0 -0
- data/lib/tiny_tds/gem.rb +0 -0
- data/lib/tiny_tds/result.rb +0 -0
- data/lib/tiny_tds/version.rb +0 -0
- data/patches/freetds/1.00.27/0001-mingw_missing_inet_pton.diff +0 -0
- data/patches/freetds/1.00.27/0002-Don-t-use-MSYS2-file-libws2_32.diff +0 -0
- data/patches/libiconv/1.14/1-avoid-gets-error.patch +0 -0
- data/tasks/native_gem.rake +0 -0
- data/tasks/package.rake +0 -0
- data/tasks/ports.rake +0 -0
- data/tasks/ports/freetds.rb +0 -0
- data/tasks/ports/libiconv.rb +0 -0
- data/tasks/ports/openssl.rb +0 -0
- data/tasks/ports/recipe.rb +0 -0
- data/tasks/test.rake +0 -0
- data/test/appveyor/dbsetup.ps1 +0 -0
- data/test/appveyor/dbsetup.sql +0 -0
- data/test/benchmark/query.rb +0 -0
- data/test/benchmark/query_odbc.rb +0 -0
- data/test/benchmark/query_tinytds.rb +0 -0
- data/test/client_test.rb +99 -54
- data/test/gem_test.rb +15 -15
- data/test/result_test.rb +83 -42
- data/test/schema/sqlserver_2000.sql +0 -0
- data/test/schema/sqlserver_2005.sql +0 -0
- data/test/schema/sqlserver_2008.sql +0 -0
- data/test/schema/sqlserver_2014.sql +0 -0
- data/test/schema/sqlserver_2016.sql +0 -0
- data/test/schema/sqlserver_azure.sql +0 -0
- data/test/schema/sybase_ase.sql +0 -0
- data/test/schema_test.rb +12 -12
- data/test/test_helper.rb +58 -4
- data/test/thread_test.rb +1 -1
- data/tiny_tds.gemspec +1 -0
- metadata +27 -4
data/ext/tiny_tds/result.h
CHANGED
File without changes
|
data/ext/tiny_tds/tiny_tds_ext.c
CHANGED
File without changes
|
data/ext/tiny_tds/tiny_tds_ext.h
CHANGED
File without changes
|
data/lib/tiny_tds.rb
CHANGED
File without changes
|
data/lib/tiny_tds/bin.rb
CHANGED
File without changes
|
data/lib/tiny_tds/client.rb
CHANGED
File without changes
|
data/lib/tiny_tds/error.rb
CHANGED
File without changes
|
data/lib/tiny_tds/gem.rb
CHANGED
File without changes
|
data/lib/tiny_tds/result.rb
CHANGED
File without changes
|
data/lib/tiny_tds/version.rb
CHANGED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
data/tasks/native_gem.rake
CHANGED
File without changes
|
data/tasks/package.rake
CHANGED
File without changes
|
data/tasks/ports.rake
CHANGED
File without changes
|
data/tasks/ports/freetds.rb
CHANGED
File without changes
|
data/tasks/ports/libiconv.rb
CHANGED
File without changes
|
data/tasks/ports/openssl.rb
CHANGED
File without changes
|
data/tasks/ports/recipe.rb
CHANGED
File without changes
|
data/tasks/test.rake
CHANGED
File without changes
|
data/test/appveyor/dbsetup.ps1
CHANGED
File without changes
|
data/test/appveyor/dbsetup.sql
CHANGED
File without changes
|
data/test/benchmark/query.rb
CHANGED
File without changes
|
File without changes
|
File without changes
|
data/test/client_test.rb
CHANGED
@@ -2,9 +2,7 @@
|
|
2
2
|
require 'test_helper'
|
3
3
|
|
4
4
|
class ClientTest < TinyTds::TestCase
|
5
|
-
|
6
|
-
describe 'With valid credentials' do
|
7
|
-
|
5
|
+
describe 'with valid credentials' do
|
8
6
|
before do
|
9
7
|
@client = new_connection
|
10
8
|
end
|
@@ -67,10 +65,12 @@ class ClientTest < TinyTds::TestCase
|
|
67
65
|
client.close if client
|
68
66
|
end
|
69
67
|
end unless sqlserver_azure?
|
70
|
-
|
71
68
|
end
|
72
69
|
|
73
70
|
describe 'With in-valid options' do
|
71
|
+
before(:all) do
|
72
|
+
init_toxiproxy
|
73
|
+
end
|
74
74
|
|
75
75
|
it 'raises an argument error when no :host given and :dataserver is blank' do
|
76
76
|
assert_raises(ArgumentError) { new_connection :dataserver => nil, :host => nil }
|
@@ -132,30 +132,64 @@ class ClientTest < TinyTds::TestCase
|
|
132
132
|
end
|
133
133
|
end
|
134
134
|
|
135
|
-
it '
|
136
|
-
skip
|
135
|
+
it 'raises TinyTds exception with tcp socket network failure' do
|
136
|
+
skip if ENV['CI'] && ENV['APPVEYOR_BUILD_FOLDER'] # only CI using docker
|
137
137
|
begin
|
138
|
-
client = new_connection :
|
138
|
+
client = new_connection timeout: 2, port: 1234
|
139
139
|
assert_client_works(client)
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
140
|
+
action = lambda { client.execute("waitfor delay '00:00:05'").do }
|
141
|
+
|
142
|
+
# Use toxiproxy to close the TCP socket after 1 second.
|
143
|
+
# We want TinyTds to execute the statement, hit the timeout configured above, and then not be able to use the network to cancel
|
144
|
+
# the network connection needs to close after the sql batch is sent and before the timeout above is hit
|
145
|
+
Toxiproxy[:sqlserver_test].toxic(:slow_close, delay: 1000).apply do
|
146
|
+
assert_raise_tinytds_error(action) do |e|
|
147
|
+
assert_equal 20003, e.db_error_number
|
148
|
+
assert_equal 6, e.severity
|
149
|
+
assert_match %r{timed out}i, e.message, 'ignore if non-english test run'
|
150
|
+
end
|
151
|
+
end
|
152
|
+
ensure
|
153
|
+
assert_new_connections_work
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
it 'raises TinyTds exception with dead connection network failure' do
|
158
|
+
skip if ENV['CI'] && ENV['APPVEYOR_BUILD_FOLDER'] # only CI using docker
|
159
|
+
begin
|
160
|
+
client = new_connection timeout: 2, port: 1234
|
161
|
+
assert_client_works(client)
|
162
|
+
action = lambda { client.execute("waitfor delay '00:00:05'").do }
|
163
|
+
|
164
|
+
# Use toxiproxy to close the network connection after 1 second.
|
165
|
+
# We want TinyTds to execute the statement, hit the timeout configured above, and then not be able to use the network to cancel
|
166
|
+
# the network connection needs to close after the sql batch is sent and before the timeout above is hit
|
167
|
+
Toxiproxy[:sqlserver_test].toxic(:timeout, timeout: 1000).apply do
|
168
|
+
assert_raise_tinytds_error(action) do |e|
|
169
|
+
assert_equal 20047, e.db_error_number
|
170
|
+
assert_includes [1,9], e.severity
|
171
|
+
assert_match %r{dead or not enabled}i, e.message, 'ignore if non-english test run'
|
172
|
+
end
|
173
|
+
end
|
174
|
+
ensure
|
175
|
+
assert_new_connections_work
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
it 'raises TinyTds exception with login timeout' do
|
180
|
+
skip if ENV['CI'] && ENV['APPVEYOR_BUILD_FOLDER'] # only CI using docker
|
181
|
+
begin
|
182
|
+
action = lambda do
|
183
|
+
Toxiproxy[:sqlserver_test].toxic(:timeout, timeout: 0).apply do
|
184
|
+
new_connection login_timeout: 1, port: 1234
|
185
|
+
end
|
186
|
+
end
|
144
187
|
assert_raise_tinytds_error(action) do |e|
|
145
188
|
assert_equal 20003, e.db_error_number
|
146
189
|
assert_equal 6, e.severity
|
147
190
|
assert_match %r{timed out}i, e.message, 'ignore if non-english test run'
|
148
191
|
end
|
149
192
|
ensure
|
150
|
-
STDOUT.puts "Reconnect network!"
|
151
|
-
sleep 10
|
152
|
-
action = lambda { client.execute('SELECT 1 as [one]').each }
|
153
|
-
assert_raise_tinytds_error(action) do |e|
|
154
|
-
assert_equal 20047, e.db_error_number
|
155
|
-
assert_equal 1, e.severity
|
156
|
-
assert_match %r{dead or not enabled}i, e.message, 'ignore if non-english test run'
|
157
|
-
end
|
158
|
-
close_client(client)
|
159
193
|
assert_new_connections_work
|
160
194
|
end
|
161
195
|
end
|
@@ -174,57 +208,68 @@ class ClientTest < TinyTds::TestCase
|
|
174
208
|
|
175
209
|
end
|
176
210
|
|
177
|
-
describe '
|
178
|
-
|
211
|
+
describe '#parse_username' do
|
179
212
|
let(:client) { @client = new_connection }
|
180
213
|
|
181
|
-
it '
|
182
|
-
|
183
|
-
|
214
|
+
it 'returns username if azure is not true' do
|
215
|
+
_(
|
216
|
+
client.send(:parse_username, username: 'user@abc123.database.windows.net')
|
217
|
+
).must_equal 'user@abc123.database.windows.net'
|
184
218
|
end
|
185
219
|
|
186
|
-
it '
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
220
|
+
it 'returns short username if azure is true' do
|
221
|
+
_(
|
222
|
+
client.send(
|
223
|
+
:parse_username,
|
224
|
+
username: 'user@abc123.database.windows.net',
|
225
|
+
host: 'abc123.database.windows.net',
|
226
|
+
azure: true
|
227
|
+
)
|
191
228
|
).must_equal 'user@abc123'
|
192
229
|
end
|
193
230
|
|
194
|
-
it '
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
231
|
+
it 'returns full username if azure is false' do
|
232
|
+
_(
|
233
|
+
client.send(
|
234
|
+
:parse_username,
|
235
|
+
username: 'user@abc123.database.windows.net',
|
236
|
+
host: 'abc123.database.windows.net',
|
237
|
+
azure: false
|
238
|
+
)
|
199
239
|
).must_equal 'user@abc123.database.windows.net'
|
200
240
|
end
|
201
241
|
|
202
|
-
it '
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
242
|
+
it 'returns short username if passed and azure is true' do
|
243
|
+
_(
|
244
|
+
client.send(
|
245
|
+
:parse_username,
|
246
|
+
username: 'user@abc123',
|
247
|
+
host: 'abc123.database.windows.net',
|
248
|
+
azure: true
|
249
|
+
)
|
207
250
|
).must_equal 'user@abc123'
|
208
251
|
end
|
209
252
|
|
210
|
-
it '
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
253
|
+
it 'returns username with servername if passed and azure is true' do
|
254
|
+
_(
|
255
|
+
client.send(
|
256
|
+
:parse_username,
|
257
|
+
username: 'user',
|
258
|
+
host: 'abc123.database.windows.net',
|
259
|
+
azure: true
|
260
|
+
)
|
215
261
|
).must_equal 'user@abc123'
|
216
262
|
end
|
217
263
|
|
218
|
-
it '
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
264
|
+
it 'returns username with servername if passed and azure is false' do
|
265
|
+
_(
|
266
|
+
client.send(
|
267
|
+
:parse_username,
|
268
|
+
username: 'user',
|
269
|
+
host: 'abc123.database.windows.net',
|
270
|
+
azure: false
|
271
|
+
)
|
223
272
|
).must_equal 'user'
|
224
273
|
end
|
225
|
-
|
226
274
|
end
|
227
|
-
|
228
|
-
|
229
275
|
end
|
230
|
-
|
data/test/gem_test.rb
CHANGED
@@ -21,13 +21,13 @@ class GemTest < MiniTest::Spec
|
|
21
21
|
let(:root_path) { TinyTds::Gem.root_path }
|
22
22
|
|
23
23
|
it 'should be the root path' do
|
24
|
-
root_path.must_equal gem_root
|
24
|
+
_(root_path).must_equal gem_root
|
25
25
|
end
|
26
26
|
|
27
27
|
it 'should be the root path no matter the cwd' do
|
28
28
|
Dir.chdir '/'
|
29
29
|
|
30
|
-
root_path.must_equal gem_root
|
30
|
+
_(root_path).must_equal gem_root
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
@@ -35,19 +35,19 @@ class GemTest < MiniTest::Spec
|
|
35
35
|
let(:ports_root_path) { TinyTds::Gem.ports_root_path }
|
36
36
|
|
37
37
|
it 'should be the ports path' do
|
38
|
-
ports_root_path.must_equal File.join(gem_root,'ports')
|
38
|
+
_(ports_root_path).must_equal File.join(gem_root,'ports')
|
39
39
|
end
|
40
40
|
|
41
41
|
it 'should be the ports path no matter the cwd' do
|
42
42
|
Dir.chdir '/'
|
43
43
|
|
44
|
-
ports_root_path.must_equal File.join(gem_root,'ports')
|
44
|
+
_(ports_root_path).must_equal File.join(gem_root,'ports')
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
48
48
|
describe '#ports_bin_paths' do
|
49
49
|
let(:ports_bin_paths) { TinyTds::Gem.ports_bin_paths }
|
50
|
-
|
50
|
+
|
51
51
|
describe 'when the ports directories exist' do
|
52
52
|
let(:fake_bin_paths) do
|
53
53
|
ports_host_root = File.join(gem_root, 'ports', 'fake-host-with-dirs')
|
@@ -74,12 +74,12 @@ class GemTest < MiniTest::Spec
|
|
74
74
|
end
|
75
75
|
|
76
76
|
it 'should return all the bin directories' do
|
77
|
-
ports_bin_paths.sort.must_equal fake_bin_paths.sort
|
77
|
+
_(ports_bin_paths.sort).must_equal fake_bin_paths.sort
|
78
78
|
end
|
79
79
|
|
80
80
|
it 'should return all the bin directories regardless of cwd' do
|
81
81
|
Dir.chdir '/'
|
82
|
-
ports_bin_paths.sort.must_equal fake_bin_paths.sort
|
82
|
+
_(ports_bin_paths.sort).must_equal fake_bin_paths.sort
|
83
83
|
end
|
84
84
|
end
|
85
85
|
|
@@ -89,19 +89,19 @@ class GemTest < MiniTest::Spec
|
|
89
89
|
end
|
90
90
|
|
91
91
|
it 'should return no directories' do
|
92
|
-
ports_bin_paths.must_be_empty
|
92
|
+
_(ports_bin_paths).must_be_empty
|
93
93
|
end
|
94
94
|
|
95
95
|
it 'should return no directories regardless of cwd' do
|
96
96
|
Dir.chdir '/'
|
97
|
-
ports_bin_paths.must_be_empty
|
97
|
+
_(ports_bin_paths).must_be_empty
|
98
98
|
end
|
99
99
|
end
|
100
100
|
end
|
101
101
|
|
102
102
|
describe '#ports_lib_paths' do
|
103
103
|
let(:ports_lib_paths) { TinyTds::Gem.ports_lib_paths }
|
104
|
-
|
104
|
+
|
105
105
|
describe 'when the ports directories exist' do
|
106
106
|
let(:fake_lib_paths) do
|
107
107
|
ports_host_root = File.join(gem_root, 'ports', 'fake-host-with-dirs')
|
@@ -128,12 +128,12 @@ class GemTest < MiniTest::Spec
|
|
128
128
|
end
|
129
129
|
|
130
130
|
it 'should return all the lib directories' do
|
131
|
-
ports_lib_paths.sort.must_equal fake_lib_paths.sort
|
131
|
+
_(ports_lib_paths.sort).must_equal fake_lib_paths.sort
|
132
132
|
end
|
133
133
|
|
134
134
|
it 'should return all the lib directories regardless of cwd' do
|
135
135
|
Dir.chdir '/'
|
136
|
-
ports_lib_paths.sort.must_equal fake_lib_paths.sort
|
136
|
+
_(ports_lib_paths.sort).must_equal fake_lib_paths.sort
|
137
137
|
end
|
138
138
|
end
|
139
139
|
|
@@ -144,12 +144,12 @@ class GemTest < MiniTest::Spec
|
|
144
144
|
|
145
145
|
|
146
146
|
it 'should return no directories' do
|
147
|
-
ports_lib_paths.must_be_empty
|
147
|
+
_(ports_lib_paths).must_be_empty
|
148
148
|
end
|
149
149
|
|
150
150
|
it 'should return no directories regardless of cwd' do
|
151
151
|
Dir.chdir '/'
|
152
|
-
ports_lib_paths.must_be_empty
|
152
|
+
_(ports_lib_paths).must_be_empty
|
153
153
|
end
|
154
154
|
end
|
155
155
|
end
|
@@ -169,7 +169,7 @@ class GemTest < MiniTest::Spec
|
|
169
169
|
end
|
170
170
|
|
171
171
|
it "should return a #{expected} ports host" do
|
172
|
-
TinyTds::Gem.ports_host.must_equal expected
|
172
|
+
_(TinyTds::Gem.ports_host).must_equal expected
|
173
173
|
end
|
174
174
|
end
|
175
175
|
end
|
data/test/result_test.rb
CHANGED
@@ -80,7 +80,7 @@ class ResultTest < TinyTds::TestCase
|
|
80
80
|
@client.execute("DELETE FROM [datatypes]").do
|
81
81
|
@client.execute("INSERT INTO [datatypes] ([char_10], [varchar_50]) VALUES ('1', '2')").do
|
82
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"
|
83
|
+
_(result).must_equal "1 test2"
|
84
84
|
end
|
85
85
|
end
|
86
86
|
|
@@ -135,10 +135,10 @@ class ResultTest < TinyTds::TestCase
|
|
135
135
|
text = 'test affected rows sql'
|
136
136
|
@client.execute("DELETE FROM [datatypes]").do
|
137
137
|
afrows = @client.execute("SELECT @@ROWCOUNT AS AffectedRows").each.first['AffectedRows']
|
138
|
-
['Fixnum', 'Integer'].must_include afrows.class.name
|
138
|
+
_(['Fixnum', 'Integer']).must_include afrows.class.name
|
139
139
|
@client.execute("INSERT INTO [datatypes] ([varchar_50]) VALUES ('#{text}')").do
|
140
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'
|
141
|
+
_(['Fixnum', 'Integer']).must_include pk1.class.name, 'we it be able to CAST to bigint'
|
142
142
|
@client.execute("UPDATE [datatypes] SET [varchar_50] = NULL WHERE [varchar_50] = '#{text}'").do
|
143
143
|
afrows = @client.execute("SELECT @@ROWCOUNT AS AffectedRows").each.first['AffectedRows']
|
144
144
|
assert_equal 1, afrows
|
@@ -215,34 +215,34 @@ class ResultTest < TinyTds::TestCase
|
|
215
215
|
@client.execute("DELETE FROM [datatypes]").do
|
216
216
|
@client.execute("ROLLBACK TRANSACTION").do
|
217
217
|
count = @client.execute("SELECT COUNT(*) AS [count] FROM [datatypes]").each.first['count']
|
218
|
-
|
218
|
+
_(count).wont_equal 0
|
219
219
|
end
|
220
220
|
|
221
221
|
it 'has a #fields accessor with logic default and valid outcome' do
|
222
222
|
result = @client.execute(@query1)
|
223
|
-
result.fields.must_equal ['one']
|
223
|
+
_(result.fields).must_equal ['one']
|
224
224
|
result.each
|
225
|
-
result.fields.must_equal ['one']
|
225
|
+
_(result.fields).must_equal ['one']
|
226
226
|
end
|
227
227
|
|
228
228
|
it 'always returns an array for fields for all sql' do
|
229
229
|
result = @client.execute("USE [tinytdstest]")
|
230
|
-
result.fields.must_equal []
|
230
|
+
_(result.fields).must_equal []
|
231
231
|
result.do
|
232
|
-
result.fields.must_equal []
|
232
|
+
_(result.fields).must_equal []
|
233
233
|
end
|
234
234
|
|
235
235
|
it 'returns fields even when no results are found' do
|
236
236
|
no_results_query = "SELECT [id], [varchar_50] FROM [datatypes] WHERE [varchar_50] = 'NOTFOUND'"
|
237
237
|
# Fields before each.
|
238
238
|
result = @client.execute(no_results_query)
|
239
|
-
result.fields.must_equal ['id','varchar_50']
|
239
|
+
_(result.fields).must_equal ['id','varchar_50']
|
240
240
|
result.each
|
241
|
-
result.fields.must_equal ['id','varchar_50']
|
241
|
+
_(result.fields).must_equal ['id','varchar_50']
|
242
242
|
# Each then fields
|
243
243
|
result = @client.execute(no_results_query)
|
244
244
|
result.each
|
245
|
-
result.fields.must_equal ['id','varchar_50']
|
245
|
+
_(result.fields).must_equal ['id','varchar_50']
|
246
246
|
end
|
247
247
|
|
248
248
|
it 'allows the result to be canceled before reading' do
|
@@ -254,27 +254,27 @@ class ResultTest < TinyTds::TestCase
|
|
254
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
|
255
255
|
# Default state.
|
256
256
|
@client = TinyTds::Client.new(connection_options)
|
257
|
-
@client.sqlsent
|
258
|
-
@client.canceled
|
257
|
+
_(@client.sqlsent?).must_equal false
|
258
|
+
_(@client.canceled?).must_equal false
|
259
259
|
# With active result before and after cancel.
|
260
260
|
result = @client.execute(@query1)
|
261
|
-
@client.sqlsent
|
262
|
-
@client.canceled
|
261
|
+
_(@client.sqlsent?).must_equal true
|
262
|
+
_(@client.canceled?).must_equal false
|
263
263
|
result.cancel
|
264
|
-
@client.sqlsent
|
265
|
-
@client.canceled
|
264
|
+
_(@client.sqlsent?).must_equal false
|
265
|
+
_(@client.canceled?).must_equal true
|
266
266
|
assert result.cancel, 'must be safe to call again'
|
267
267
|
# With each and no block.
|
268
268
|
@client.execute(@query1).each
|
269
|
-
@client.sqlsent
|
270
|
-
@client.canceled
|
269
|
+
_(@client.sqlsent?).must_equal false
|
270
|
+
_(@client.canceled?).must_equal false
|
271
271
|
# With each and block.
|
272
272
|
@client.execute(@query1).each do |row|
|
273
|
-
@client.sqlsent
|
274
|
-
@client.canceled
|
273
|
+
_(@client.sqlsent?).must_equal true, 'when iterating over each row in a block'
|
274
|
+
_(@client.canceled?).must_equal false
|
275
275
|
end
|
276
|
-
@client.sqlsent
|
277
|
-
@client.canceled
|
276
|
+
_(@client.sqlsent?).must_equal false
|
277
|
+
_(@client.canceled?).must_equal false
|
278
278
|
# With each and block canceled half way thru.
|
279
279
|
count = @client.execute("SELECT COUNT([id]) AS [count] FROM [datatypes]").each[0]['count']
|
280
280
|
assert count > 10, 'since we want to cancel early for test'
|
@@ -284,25 +284,25 @@ class ResultTest < TinyTds::TestCase
|
|
284
284
|
break if index > 10
|
285
285
|
index += 1
|
286
286
|
end
|
287
|
-
@client.sqlsent
|
288
|
-
@client.canceled
|
287
|
+
_(@client.sqlsent?).must_equal true
|
288
|
+
_(@client.canceled?).must_equal false
|
289
289
|
result.cancel
|
290
|
-
@client.sqlsent
|
291
|
-
@client.canceled
|
290
|
+
_(@client.sqlsent?).must_equal false
|
291
|
+
_(@client.canceled?).must_equal true
|
292
292
|
# With do method.
|
293
293
|
@client.execute(@query1).do
|
294
|
-
@client.sqlsent
|
295
|
-
@client.canceled
|
294
|
+
_(@client.sqlsent?).must_equal false
|
295
|
+
_(@client.canceled?).must_equal true
|
296
296
|
# With insert method.
|
297
297
|
rollback_transaction(@client) do
|
298
298
|
@client.execute("INSERT INTO [datatypes] ([varchar_50]) VALUES ('test')").insert
|
299
|
-
@client.sqlsent
|
300
|
-
@client.canceled
|
299
|
+
_(@client.sqlsent?).must_equal false
|
300
|
+
_(@client.canceled?).must_equal true
|
301
301
|
end
|
302
302
|
# With first
|
303
303
|
@client.execute("SELECT [id] FROM [datatypes]").each(:first => true)
|
304
|
-
@client.sqlsent
|
305
|
-
@client.canceled
|
304
|
+
_(@client.sqlsent?).must_equal false
|
305
|
+
_(@client.canceled?).must_equal true
|
306
306
|
end
|
307
307
|
|
308
308
|
it 'use same string object for hash keys' do
|
@@ -337,7 +337,7 @@ class ResultTest < TinyTds::TestCase
|
|
337
337
|
|
338
338
|
it 'with LOGINPROPERTY function' do
|
339
339
|
v = @client.execute("SELECT LOGINPROPERTY('sa', 'IsLocked') as v").first['v']
|
340
|
-
v.must_equal 0
|
340
|
+
_(v).must_equal 0
|
341
341
|
end
|
342
342
|
|
343
343
|
describe 'with multiple result sets' do
|
@@ -652,6 +652,48 @@ class ResultTest < TinyTds::TestCase
|
|
652
652
|
assert_equal 1, messages.length, 'there should be one message after one print statement'
|
653
653
|
assert_equal msg, m.message, 'message text'
|
654
654
|
end
|
655
|
+
|
656
|
+
it 'must raise an error preceded by a `print` message' do
|
657
|
+
messages.clear
|
658
|
+
action = lambda { @client.execute("EXEC tinytds_TestPrintWithError").do }
|
659
|
+
assert_raise_tinytds_error(action) do |e|
|
660
|
+
assert_equal 'hello', messages.first.message, 'message text'
|
661
|
+
|
662
|
+
assert_equal "Error following print", e.message
|
663
|
+
assert_equal 16, e.severity
|
664
|
+
assert_equal 50000, e.db_error_number
|
665
|
+
end
|
666
|
+
end
|
667
|
+
|
668
|
+
it 'calls the provided message handler for each of a series of `print` messages' do
|
669
|
+
messages.clear
|
670
|
+
@client.execute("EXEC tinytds_TestSeveralPrints").do
|
671
|
+
assert_equal ['hello 1', 'hello 2', 'hello 3'], messages.map { |e| e.message }, 'message list'
|
672
|
+
end
|
673
|
+
|
674
|
+
it 'should flush info messages before raising error in cases of timeout' do
|
675
|
+
@client = new_connection timeout: 1, message_handler: Proc.new { |m| messages << m }
|
676
|
+
action = lambda { @client.execute("print 'hello'; waitfor delay '00:00:02'").do }
|
677
|
+
messages.clear
|
678
|
+
assert_raise_tinytds_error(action) do |e|
|
679
|
+
assert_match %r{timed out}i, e.message, 'ignore if non-english test run'
|
680
|
+
assert_equal 6, e.severity
|
681
|
+
assert_equal 20003, e.db_error_number
|
682
|
+
assert_equal 'hello', messages.first&.message, 'message text'
|
683
|
+
end
|
684
|
+
end
|
685
|
+
|
686
|
+
it 'should print info messages before raising error in cases of timeout' do
|
687
|
+
@client = new_connection timeout: 1, message_handler: Proc.new { |m| messages << m }
|
688
|
+
action = lambda { @client.execute("raiserror('hello', 1, 1) with nowait; waitfor delay '00:00:02'").do }
|
689
|
+
messages.clear
|
690
|
+
assert_raise_tinytds_error(action) do |e|
|
691
|
+
assert_match %r{timed out}i, e.message, 'ignore if non-english test run'
|
692
|
+
assert_equal 6, e.severity
|
693
|
+
assert_equal 20003, e.db_error_number
|
694
|
+
assert_equal 'hello', messages.first&.message, 'message text'
|
695
|
+
end
|
696
|
+
end
|
655
697
|
end
|
656
698
|
|
657
699
|
it 'must not raise an error when severity is 10 or less' do
|
@@ -684,7 +726,7 @@ class ResultTest < TinyTds::TestCase
|
|
684
726
|
end
|
685
727
|
|
686
728
|
it 'throws an error when you execute another query with other results pending' do
|
687
|
-
|
729
|
+
@client.execute(@query1)
|
688
730
|
action = lambda { @client.execute(@query1) }
|
689
731
|
assert_raise_tinytds_error(action) do |e|
|
690
732
|
assert_match %r|with results pending|i, e.message
|
@@ -717,22 +759,22 @@ class ResultTest < TinyTds::TestCase
|
|
717
759
|
it 'must not error at all from reading non-convertable charcters and just use ? marks' do
|
718
760
|
close_client
|
719
761
|
@client = new_connection :encoding => 'ASCII'
|
720
|
-
@client.charset.must_equal 'ASCII'
|
721
|
-
find_value(202, :nvarchar_50).must_equal 'test nvarchar_50 ??'
|
762
|
+
_(@client.charset).must_equal 'ASCII'
|
763
|
+
_(find_value(202, :nvarchar_50)).must_equal 'test nvarchar_50 ??'
|
722
764
|
end
|
723
765
|
|
724
766
|
it 'must error gracefully from writing non-convertable characters' do
|
725
767
|
close_client
|
726
768
|
@client = new_connection :encoding => 'ASCII'
|
727
|
-
@client.charset.must_equal 'ASCII'
|
769
|
+
_(@client.charset).must_equal 'ASCII'
|
728
770
|
rollback_transaction(@client) do
|
729
771
|
text = 'Test ✓'
|
730
772
|
@client.execute("DELETE FROM [datatypes] WHERE [nvarchar_50] IS NOT NULL").do
|
731
773
|
action = lambda { @client.execute("INSERT INTO [datatypes] ([nvarchar_50]) VALUES ('#{text}')").do }
|
732
774
|
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
|
775
|
+
_(e.message).must_match %r{Unclosed quotation mark}i
|
776
|
+
_(e.severity).must_equal 15
|
777
|
+
_(e.db_error_number).must_equal 105
|
736
778
|
end
|
737
779
|
assert_followup_query
|
738
780
|
end
|
@@ -770,4 +812,3 @@ class ResultTest < TinyTds::TestCase
|
|
770
812
|
end
|
771
813
|
|
772
814
|
end
|
773
|
-
|