vm_tiny_tds 2.1.2

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 (69) hide show
  1. checksums.yaml +7 -0
  2. data/.codeclimate.yml +20 -0
  3. data/.gitattributes +1 -0
  4. data/.gitignore +20 -0
  5. data/.rubocop.yml +31 -0
  6. data/.travis.yml +24 -0
  7. data/BACKERS.md +32 -0
  8. data/CHANGELOG.md +255 -0
  9. data/CODE_OF_CONDUCT.md +31 -0
  10. data/Gemfile +9 -0
  11. data/ISSUE_TEMPLATE.md +38 -0
  12. data/MIT-LICENSE +23 -0
  13. data/README.md +504 -0
  14. data/Rakefile +53 -0
  15. data/VERSION +1 -0
  16. data/appveyor.yml +51 -0
  17. data/bin/defncopy-ttds +3 -0
  18. data/bin/tsql-ttds +3 -0
  19. data/exe/.keep +0 -0
  20. data/ext/tiny_tds/client.c +451 -0
  21. data/ext/tiny_tds/client.h +51 -0
  22. data/ext/tiny_tds/extconf.rb +69 -0
  23. data/ext/tiny_tds/extconsts.rb +15 -0
  24. data/ext/tiny_tds/result.c +619 -0
  25. data/ext/tiny_tds/result.h +32 -0
  26. data/ext/tiny_tds/tiny_tds_ext.c +12 -0
  27. data/ext/tiny_tds/tiny_tds_ext.h +17 -0
  28. data/lib/tiny_tds/bin.rb +104 -0
  29. data/lib/tiny_tds/client.rb +136 -0
  30. data/lib/tiny_tds/error.rb +14 -0
  31. data/lib/tiny_tds/gem.rb +32 -0
  32. data/lib/tiny_tds/result.rb +7 -0
  33. data/lib/tiny_tds/version.rb +3 -0
  34. data/lib/tiny_tds.rb +61 -0
  35. data/patches/freetds/1.00.27/0001-mingw_missing_inet_pton.diff +34 -0
  36. data/patches/freetds/1.00.27/0002-Don-t-use-MSYS2-file-libws2_32.diff +28 -0
  37. data/patches/libiconv/1.14/1-avoid-gets-error.patch +17 -0
  38. data/tasks/native_gem.rake +14 -0
  39. data/tasks/package.rake +8 -0
  40. data/tasks/ports/freetds.rb +37 -0
  41. data/tasks/ports/libiconv.rb +43 -0
  42. data/tasks/ports/openssl.rb +78 -0
  43. data/tasks/ports/recipe.rb +52 -0
  44. data/tasks/ports.rake +87 -0
  45. data/tasks/test.rake +9 -0
  46. data/test/appveyor/dbsetup.ps1 +27 -0
  47. data/test/appveyor/dbsetup.sql +9 -0
  48. data/test/benchmark/query.rb +77 -0
  49. data/test/benchmark/query_odbc.rb +106 -0
  50. data/test/benchmark/query_tinytds.rb +126 -0
  51. data/test/bin/install-freetds.sh +20 -0
  52. data/test/bin/install-openssl.sh +18 -0
  53. data/test/bin/setup.sh +19 -0
  54. data/test/client_test.rb +230 -0
  55. data/test/gem_test.rb +179 -0
  56. data/test/result_test.rb +773 -0
  57. data/test/schema/1px.gif +0 -0
  58. data/test/schema/sqlserver_2000.sql +140 -0
  59. data/test/schema/sqlserver_2005.sql +140 -0
  60. data/test/schema/sqlserver_2008.sql +140 -0
  61. data/test/schema/sqlserver_2014.sql +140 -0
  62. data/test/schema/sqlserver_2016.sql +140 -0
  63. data/test/schema/sqlserver_azure.sql +140 -0
  64. data/test/schema/sybase_ase.sql +138 -0
  65. data/test/schema_test.rb +443 -0
  66. data/test/test_helper.rb +217 -0
  67. data/test/thread_test.rb +98 -0
  68. data/tiny_tds.gemspec +29 -0
  69. metadata +225 -0
@@ -0,0 +1,443 @@
1
+ # encoding: utf-8
2
+ require 'test_helper'
3
+
4
+ class SchemaTest < TinyTds::TestCase
5
+
6
+ describe 'Casting SQL Server schema' do
7
+
8
+ before do
9
+ @@current_schema_loaded ||= load_current_schema
10
+ @client = new_connection
11
+ @gif1px = File.read('test/schema/1px.gif',:mode=>"rb:BINARY")
12
+ end
13
+
14
+ describe 'for shared types' do
15
+
16
+ it 'casts bigint' do
17
+ assert_equal -9223372036854775807, find_value(11, :bigint)
18
+ assert_equal 9223372036854775806, find_value(12, :bigint)
19
+ end
20
+
21
+ it 'casts binary' do
22
+ value = find_value(21, :binary_50)
23
+ assert_equal @gif1px + "\000", value
24
+ assert_binary_encoding(value)
25
+ end
26
+
27
+ it 'casts bit' do
28
+ assert_equal true, find_value(31, :bit)
29
+ assert_equal false, find_value(32, :bit)
30
+ assert_nil find_value(21, :bit)
31
+ end
32
+
33
+ it 'casts char' do
34
+ partial_char = '12345678 '
35
+ assert_equal '1234567890', find_value(41, :char_10)
36
+ assert_equal partial_char, find_value(42, :char_10)
37
+ assert_utf8_encoding find_value(42, :char_10)
38
+ end
39
+
40
+ it 'casts datetime' do
41
+ # 1753-01-01T00:00:00.000
42
+ v = find_value 61, :datetime
43
+ assert_instance_of Time, v, 'not in range of Time class'
44
+ assert_equal 1753, v.year
45
+ assert_equal 01, v.month
46
+ assert_equal 01, v.day
47
+ assert_equal 0, v.hour
48
+ assert_equal 0, v.min
49
+ assert_equal 0, v.sec
50
+ assert_equal 0, v.usec
51
+ # 9999-12-31T23:59:59.997
52
+ v = find_value 62, :datetime
53
+ assert_instance_of Time, v, 'not in range of Time class'
54
+ assert_equal 9999, v.year
55
+ assert_equal 12, v.month
56
+ assert_equal 31, v.day
57
+ assert_equal 23, v.hour
58
+ assert_equal 59, v.min
59
+ assert_equal 59, v.sec
60
+ assert_equal 997000, v.usec
61
+ assert_equal utc_offset, find_value(62, :datetime, :timezone => :local).utc_offset
62
+ assert_equal 0, find_value(62, :datetime, :timezone => :utc).utc_offset
63
+ # 2010-01-01T12:34:56.123
64
+ v = find_value 63, :datetime
65
+ assert_instance_of Time, v, 'in range of Time class'
66
+ assert_equal 2010, v.year
67
+ assert_equal 01, v.month
68
+ assert_equal 01, v.day
69
+ assert_equal 12, v.hour
70
+ assert_equal 34, v.min
71
+ assert_equal 56, v.sec
72
+ assert_equal 123000, v.usec
73
+ assert_equal utc_offset, find_value(63, :datetime, :timezone => :local).utc_offset
74
+ assert_equal 0, find_value(63, :datetime, :timezone => :utc).utc_offset
75
+ end
76
+
77
+ it 'casts decimal' do
78
+ assert_instance_of BigDecimal, find_value(91, :decimal_9_2)
79
+ assert_equal BigDecimal('12345.01'), find_value(91, :decimal_9_2)
80
+ assert_equal BigDecimal('1234567.89'), find_value(92, :decimal_9_2)
81
+ assert_equal BigDecimal('0.0'), find_value(93, :decimal_16_4)
82
+ assert_equal BigDecimal('123456789012.3456'), find_value(94, :decimal_16_4)
83
+ end
84
+
85
+ it 'casts float' do
86
+ assert_equal 123.00000001, find_value(101,:float)
87
+ assert_equal 0.0, find_value(102,:float)
88
+ assert_equal find_value(102,:float).object_id, find_value(102,:float).object_id, 'use global zero float'
89
+ assert_equal 123.45, find_value(103,:float)
90
+ end
91
+
92
+ it 'casts image' do
93
+ value = find_value(141,:image)
94
+ assert_equal @gif1px, value
95
+ assert_binary_encoding(value)
96
+ end
97
+
98
+ it 'casts int' do
99
+ assert_equal -2147483647, find_value(151, :int)
100
+ assert_equal 2147483646, find_value(152, :int)
101
+ end
102
+
103
+ it 'casts money' do
104
+ assert_instance_of BigDecimal, find_value(161, :money)
105
+ assert_equal BigDecimal('4.20'), find_value(161, :money)
106
+ assert_equal BigDecimal('922337203685477.5806'), find_value(163 ,:money)
107
+ assert_equal BigDecimal('-922337203685477.5807'), find_value(162 ,:money)
108
+ end
109
+
110
+ it 'casts nchar' do
111
+ assert_equal '1234567890', find_value(171, :nchar_10)
112
+ assert_equal '123456åå ', find_value(172, :nchar_10)
113
+ assert_equal 'abc123 ', find_value(173, :nchar_10)
114
+ end
115
+
116
+ it 'casts ntext' do
117
+ assert_equal 'test ntext', find_value(181, :ntext)
118
+ assert_equal 'test ntext åå', find_value(182, :ntext)
119
+ assert_utf8_encoding find_value(182, :ntext)
120
+ # If this test fails, try setting the "text size" in your freetds.conf. See: http://www.freetds.org/faq.html#textdata
121
+ large_value = "x" * 5000
122
+ large_value_id = @client.execute("INSERT INTO [datatypes] ([ntext]) VALUES (N'#{large_value}')").insert
123
+ assert_equal large_value, find_value(large_value_id, :ntext)
124
+ end unless sybase_ase?
125
+
126
+ it 'casts numeric' do
127
+ assert_instance_of BigDecimal, find_value(191, :numeric_18_0)
128
+ assert_equal BigDecimal('191'), find_value(191, :numeric_18_0)
129
+ assert_equal BigDecimal('123456789012345678'), find_value(192, :numeric_18_0)
130
+ assert_equal BigDecimal('12345678901234567890.01'), find_value(193, :numeric_36_2)
131
+ assert_equal BigDecimal('123.46'), find_value(194, :numeric_36_2)
132
+ end
133
+
134
+ it 'casts nvarchar' do
135
+ assert_equal 'test nvarchar_50', find_value(201, :nvarchar_50)
136
+ assert_equal 'test nvarchar_50 åå', find_value(202, :nvarchar_50)
137
+ assert_utf8_encoding find_value(202, :nvarchar_50)
138
+ end
139
+
140
+ it 'casts real' do
141
+ assert_in_delta 123.45, find_value(221, :real), 0.01
142
+ assert_equal 0.0, find_value(222, :real)
143
+ assert_equal find_value(222, :real).object_id, find_value(222, :real).object_id, 'use global zero float'
144
+ assert_in_delta 0.00001, find_value(223, :real), 0.000001
145
+ end
146
+
147
+ it 'casts smalldatetime' do
148
+ # 1901-01-01 15:45:00
149
+ v = find_value 231, :smalldatetime
150
+ assert_instance_of Time, v
151
+ assert_equal 1901, v.year
152
+ assert_equal 01, v.month
153
+ assert_equal 01, v.day
154
+ assert_equal 15, v.hour
155
+ assert_equal 45, v.min
156
+ assert_equal 00, v.sec
157
+ assert_equal Time.local(1901).utc_offset, find_value(231, :smalldatetime, :timezone => :local).utc_offset
158
+ assert_equal 0, find_value(231, :smalldatetime, :timezone => :utc).utc_offset
159
+ # 2078-06-05 04:20:00
160
+ v = find_value 232, :smalldatetime
161
+ assert_instance_of Time, v
162
+ assert_equal 2078, v.year
163
+ assert_equal 06, v.month
164
+ assert_equal 05, v.day
165
+ assert_equal 04, v.hour
166
+ assert_equal 20, v.min
167
+ assert_equal 00, v.sec
168
+ assert_equal Time.local(2078,6).utc_offset, find_value(232, :smalldatetime, :timezone => :local).utc_offset
169
+ assert_equal 0, find_value(232, :smalldatetime, :timezone => :utc).utc_offset
170
+ end
171
+
172
+ it 'casts smallint' do
173
+ assert_equal -32767, find_value(241, :smallint)
174
+ assert_equal 32766, find_value(242, :smallint)
175
+ end
176
+
177
+ it 'casts smallmoney' do
178
+ assert_instance_of BigDecimal, find_value(251, :smallmoney)
179
+ assert_equal BigDecimal("4.20"), find_value(251, :smallmoney)
180
+ assert_equal BigDecimal("-214748.3647"), find_value(252, :smallmoney)
181
+ assert_equal BigDecimal("214748.3646"), find_value(253, :smallmoney)
182
+ end
183
+
184
+ it 'casts text' do
185
+ assert_equal 'test text', find_value(271, :text)
186
+ assert_utf8_encoding find_value(271, :text)
187
+ end
188
+
189
+ it 'casts tinyint' do
190
+ assert_equal 0, find_value(301, :tinyint)
191
+ assert_equal 255, find_value(302, :tinyint)
192
+ end
193
+
194
+ it 'casts uniqueidentifier' do
195
+ assert_match %r|\w{8}-\w{4}-\w{4}-\w{4}-\w{12}|, find_value(311, :uniqueidentifier)
196
+ assert_utf8_encoding find_value(311, :uniqueidentifier)
197
+ end unless sybase_ase?
198
+
199
+ it 'casts varbinary' do
200
+ value = find_value(321, :varbinary_50)
201
+ assert_equal @gif1px, value
202
+ assert_binary_encoding(value)
203
+ end
204
+
205
+ it 'casts varchar' do
206
+ assert_equal 'test varchar_50', find_value(341, :varchar_50)
207
+ assert_utf8_encoding find_value(341, :varchar_50)
208
+ end
209
+
210
+ end
211
+
212
+
213
+ describe 'for 2005 and up' do
214
+
215
+ it 'casts nvarchar(max)' do
216
+ assert_equal 'test nvarchar_max', find_value(211, :nvarchar_max)
217
+ assert_equal 'test nvarchar_max åå', find_value(212, :nvarchar_max)
218
+ assert_utf8_encoding find_value(212, :nvarchar_max)
219
+ end
220
+
221
+ it 'casts varbinary(max)' do
222
+ value = find_value(331, :varbinary_max)
223
+ assert_equal @gif1px, value
224
+ assert_binary_encoding(value)
225
+ end
226
+
227
+ it 'casts varchar(max)' do
228
+ value = find_value(351, :varchar_max)
229
+ assert_equal 'test varchar_max', value
230
+ assert_utf8_encoding(value)
231
+ end
232
+
233
+ it 'casts xml' do
234
+ value = find_value(361, :xml)
235
+ assert_equal '<foo><bar>batz</bar></foo>', value
236
+ assert_utf8_encoding(value)
237
+ end
238
+
239
+ end if sqlserver_2005? || sqlserver_2008? || sqlserver_2014? || sqlserver_azure?
240
+
241
+
242
+ describe 'for 2008 and up' do
243
+
244
+ it 'casts date' do
245
+ # 0001-01-01
246
+ v = find_value 51, :date
247
+ if @client.tds_73?
248
+ assert_instance_of Date, v
249
+ assert_equal 1, v.year, 'Year'
250
+ assert_equal 1, v.month, 'Month'
251
+ assert_equal 1, v.day, 'Day'
252
+ else
253
+ assert_equal '0001-01-01', v
254
+ end
255
+ # 9999-12-31
256
+ v = find_value 52, :date
257
+ if @client.tds_73?
258
+ assert_instance_of Date, v
259
+ assert_equal 9999, v.year, 'Year'
260
+ assert_equal 12, v.month, 'Month'
261
+ assert_equal 31, v.day, 'Day'
262
+ else
263
+ assert_equal '9999-12-31', v
264
+ end
265
+ end
266
+
267
+ it 'casts time' do
268
+ # 15:45:00.709714966
269
+ v = find_value 281, :time_2
270
+ if @client.tds_73?
271
+ assert_instance_of Time, v
272
+ assert_equal 1900, v.year, 'Year'
273
+ assert_equal 1, v.month, 'Month'
274
+ assert_equal 1, v.day, 'Day'
275
+ assert_equal 15, v.hour, 'Hour'
276
+ assert_equal 45, v.min, 'Minute'
277
+ assert_equal 0, v.sec, 'Second'
278
+ assert_equal 710000, v.usec, 'Microseconds'
279
+ assert_equal 710000000, v.nsec, 'Nanoseconds'
280
+ else
281
+ assert_equal '15:45:00.71', v
282
+ end
283
+ # 04:20:00.288321545
284
+ v = find_value 282, :time_2
285
+ if @client.tds_73?
286
+ assert_instance_of Time, v
287
+ assert_equal 1900, v.year, 'Year'
288
+ assert_equal 1, v.month, 'Month'
289
+ assert_equal 1, v.day, 'Day'
290
+ assert_equal 4, v.hour, 'Hour'
291
+ assert_equal 20, v.min, 'Minute'
292
+ assert_equal 0, v.sec, 'Second'
293
+ assert_equal 290000, v.usec, 'Microseconds'
294
+ assert_equal 290000000, v.nsec, 'Nanoseconds'
295
+ else
296
+ assert_equal '04:20:00.29', v
297
+ end
298
+ # 15:45:00.709714966
299
+ v = find_value 283, :time_7
300
+ if @client.tds_73?
301
+ assert_instance_of Time, v
302
+ assert_equal 1900, v.year, 'Year'
303
+ assert_equal 1, v.month, 'Month'
304
+ assert_equal 1, v.day, 'Day'
305
+ assert_equal 15, v.hour, 'Hour'
306
+ assert_equal 45, v.min, 'Minute'
307
+ assert_equal 0, v.sec, 'Second'
308
+ assert_equal 709715, v.usec, 'Microseconds'
309
+ assert_equal 709715000, v.nsec, 'Nanoseconds'
310
+ else
311
+ assert_equal '15:45:00.7097150', v
312
+ end
313
+ # 04:20:00.288321545
314
+ v = find_value 284, :time_7
315
+ if @client.tds_73?
316
+ assert_instance_of Time, v
317
+ assert_equal 1900, v.year, 'Year'
318
+ assert_equal 1, v.month, 'Month'
319
+ assert_equal 1, v.day, 'Day'
320
+ assert_equal 4, v.hour, 'Hour'
321
+ assert_equal 20, v.min, 'Minute'
322
+ assert_equal 0, v.sec, 'Second'
323
+ assert_equal 288321, v.usec, 'Microseconds'
324
+ assert_equal 288321500, v.nsec, 'Nanoseconds'
325
+ else
326
+ assert_equal '04:20:00.2883215', v
327
+ end
328
+ end
329
+
330
+ it 'casts datetime2' do
331
+ # 0001-01-01 00:00:00.0000000
332
+ v = find_value 71, :datetime2_7
333
+ if @client.tds_73?
334
+ assert_instance_of Time, v
335
+ assert_equal 1, v.year, 'Year'
336
+ assert_equal 1, v.month, 'Month'
337
+ assert_equal 1, v.day, 'Day'
338
+ assert_equal 0, v.hour, 'Hour'
339
+ assert_equal 0, v.min, 'Minute'
340
+ assert_equal 0, v.sec, 'Second'
341
+ assert_equal 0, v.usec, 'Microseconds'
342
+ assert_equal 0, v.nsec, 'Nanoseconds'
343
+ else
344
+ assert_equal '0001-01-01 00:00:00.0000000', v
345
+ end
346
+ # 1984-01-24 04:20:00.0000000
347
+ v = find_value 72, :datetime2_7
348
+ if @client.tds_73?
349
+ assert_instance_of Time, v
350
+ assert_equal 1984, v.year, 'Year'
351
+ assert_equal 1, v.month, 'Month'
352
+ assert_equal 24, v.day, 'Day'
353
+ assert_equal 4, v.hour, 'Hour'
354
+ assert_equal 20, v.min, 'Minute'
355
+ assert_equal 0, v.sec, 'Second'
356
+ assert_equal 0, v.usec, 'Microseconds'
357
+ assert_equal 0, v.nsec, 'Nanoseconds'
358
+ else
359
+ assert_equal '1984-01-24 04:20:00.0000000', v
360
+ end
361
+ # 9999-12-31 23:59:59.9999999
362
+ v = find_value 73, :datetime2_7
363
+ if @client.tds_73?
364
+ assert_instance_of Time, v
365
+ assert_equal 9999, v.year, 'Year'
366
+ assert_equal 12, v.month, 'Month'
367
+ assert_equal 31, v.day, 'Day'
368
+ assert_equal 23, v.hour, 'Hour'
369
+ assert_equal 59, v.min, 'Minute'
370
+ assert_equal 59, v.sec, 'Second'
371
+ assert_equal 999999, v.usec, 'Microseconds'
372
+ assert_equal 999999900, v.nsec, 'Nanoseconds'
373
+ else
374
+ assert_equal '9999-12-31 23:59:59.9999999', v
375
+ end
376
+ # 9999-12-31 23:59:59.123456789
377
+ v = find_value 74, :datetime2_2
378
+ if @client.tds_73?
379
+ assert_instance_of Time, v
380
+ assert_equal 9999, v.year, 'Year'
381
+ assert_equal 12, v.month, 'Month'
382
+ assert_equal 31, v.day, 'Day'
383
+ assert_equal 23, v.hour, 'Hour'
384
+ assert_equal 59, v.min, 'Minute'
385
+ assert_equal 59, v.sec, 'Second'
386
+ assert_equal 120000, v.usec, 'Microseconds'
387
+ assert_equal 120000000, v.nsec, 'Nanoseconds'
388
+ else
389
+ assert_equal '9999-12-31 23:59:59.12', v
390
+ end
391
+ end
392
+
393
+ it 'casts datetimeoffset' do
394
+ # 1984-01-24T04:20:00.1234567-08:00
395
+ v = find_value 84, :datetimeoffset_7
396
+ if @client.tds_73?
397
+ assertions = lambda {
398
+ assert_instance_of Time, v
399
+ assert_equal 1984, v.year, 'Year'
400
+ assert_equal 1, v.month, 'Month'
401
+ assert_equal 24, v.day, 'Day'
402
+ assert_equal 4, v.hour, 'Hour'
403
+ assert_equal 20, v.min, 'Minute'
404
+ assert_equal 59, v.sec, 'Second'
405
+ assert_equal 123456, v.usec, 'Microseconds'
406
+ assert_equal 123456700, v.nsec, 'Nanoseconds'
407
+ assert_equal -28800, v.utc_offset, 'Offset'
408
+ }
409
+ assertions.call
410
+ v = find_value 84, :datetimeoffset_7, timezone: :local
411
+ assertions.call # Ignores timezone query option.
412
+ else
413
+ assert_equal '1984-01-24 04:20:59.1234567 -08:00', v
414
+ end
415
+ end
416
+
417
+ # it 'casts geography' do
418
+ # value = find_value 111, :geography
419
+ # assert_equal '', value
420
+ # end
421
+ #
422
+ # it 'casts geometry' do
423
+ # value = find_value 121, :geometry
424
+ # assert_equal '', value
425
+ # end
426
+ #
427
+ # it 'casts hierarchyid' do
428
+ # value = find_value 131, :hierarchyid
429
+ # assert_equal '', value
430
+ # end
431
+
432
+ end if sqlserver_2008? || sqlserver_2014? || sqlserver_azure?
433
+
434
+ end
435
+
436
+
437
+
438
+ end
439
+
440
+
441
+
442
+
443
+
@@ -0,0 +1,217 @@
1
+ # encoding: UTF-8
2
+ require 'bundler' ; Bundler.require :development, :test
3
+ require 'tiny_tds'
4
+ require 'minitest/autorun'
5
+
6
+ TINYTDS_SCHEMAS = ['sqlserver_2000', 'sqlserver_2005', 'sqlserver_2008', 'sqlserver_2014', 'sqlserver_azure', 'sybase_ase'].freeze
7
+
8
+ module TinyTds
9
+ class TestCase < MiniTest::Spec
10
+
11
+ class << self
12
+
13
+ def current_schema
14
+ ENV['TINYTDS_SCHEMA'] || 'sqlserver_2014'
15
+ end
16
+
17
+ TINYTDS_SCHEMAS.each do |schema|
18
+ define_method "#{schema}?" do
19
+ schema == self.current_schema
20
+ end
21
+ end
22
+
23
+ def sqlserver?
24
+ current_schema =~ /sqlserver/
25
+ end
26
+
27
+ end
28
+
29
+ after { close_client }
30
+
31
+ protected
32
+
33
+ TINYTDS_SCHEMAS.each do |schema|
34
+ define_method "#{schema}?" do
35
+ schema == self.class.current_schema
36
+ end
37
+ end
38
+
39
+ def current_schema
40
+ self.class.current_schema
41
+ end
42
+
43
+ def sqlserver?
44
+ self.class.sqlserver?
45
+ end
46
+
47
+ def close_client(client=@client)
48
+ client.close if defined?(client) && client.is_a?(TinyTds::Client)
49
+ end
50
+
51
+ def new_connection(options={})
52
+ client = TinyTds::Client.new(connection_options(options))
53
+ if sybase_ase?
54
+ client.execute("SET ANSINULL ON").do
55
+ return client
56
+ elsif sqlserver_azure?
57
+ client.execute('SET ANSI_NULLS ON').do
58
+ client.execute('SET CURSOR_CLOSE_ON_COMMIT OFF').do
59
+ client.execute('SET ANSI_NULL_DFLT_ON ON').do
60
+ client.execute('SET IMPLICIT_TRANSACTIONS OFF').do
61
+ client.execute('SET ANSI_PADDING ON').do
62
+ client.execute('SET QUOTED_IDENTIFIER ON').do
63
+ client.execute('SET ANSI_WARNINGS ON').do
64
+ else
65
+ client.execute('SET ANSI_DEFAULTS ON').do
66
+ client.execute('SET CURSOR_CLOSE_ON_COMMIT OFF').do
67
+ client.execute('SET IMPLICIT_TRANSACTIONS OFF').do
68
+ end
69
+ client.execute('SET TEXTSIZE 2147483647').do
70
+ client.execute('SET CONCAT_NULL_YIELDS_NULL ON').do
71
+ client
72
+ end
73
+
74
+ def connection_options(options={})
75
+ username = (sqlserver_azure? ? ENV['TINYTDS_UNIT_AZURE_USER'] : ENV['TINYTDS_UNIT_USER']) || 'tinytds'
76
+ password = (sqlserver_azure? ? ENV['TINYTDS_UNIT_AZURE_PASS'] : ENV['TINYTDS_UNIT_PASS']) || ''
77
+ { :dataserver => sqlserver_azure? ? nil : ENV['TINYTDS_UNIT_DATASERVER'],
78
+ :host => ENV['TINYTDS_UNIT_HOST'] || 'localhost',
79
+ :port => ENV['TINYTDS_UNIT_PORT'] || '1433',
80
+ :tds_version => ENV['TINYTDS_UNIT_VERSION'],
81
+ :username => username,
82
+ :password => password,
83
+ :database => ENV['TINYTDS_UNIT_DATABASE'] || 'tinytdstest',
84
+ :appname => 'TinyTds Dev',
85
+ :login_timeout => 5,
86
+ :timeout => connection_timeout,
87
+ :azure => sqlserver_azure?
88
+ }.merge(options)
89
+ end
90
+
91
+ def connection_timeout
92
+ sqlserver_azure? ? 20 : 8
93
+ end
94
+
95
+ def assert_client_works(client)
96
+ client.execute("SELECT 'client_works' as [client_works]").each.must_equal [{'client_works' => 'client_works'}]
97
+ end
98
+
99
+ def assert_new_connections_work
100
+ client = new_connection
101
+ client.execute("SELECT 'new_connections_work' as [new_connections_work]").each
102
+ client.close
103
+ end
104
+
105
+ def assert_raise_tinytds_error(action)
106
+ result = nil
107
+ error_raised = false
108
+ begin
109
+ result = action.call
110
+ rescue TinyTds::Error => e
111
+ error_raised = true
112
+ end
113
+ assert error_raised, 'expected a TinyTds::Error but none happened'
114
+ yield e
115
+ ensure
116
+ close_client(result)
117
+ end
118
+
119
+ def inspect_tinytds_exception
120
+ begin
121
+ yield
122
+ rescue TinyTds::Error => e
123
+ props = { :source => e.source, :message => e.message, :severity => e.severity,
124
+ :db_error_number => e.db_error_number, :os_error_number => e.os_error_number }
125
+ raise "TinyTds::Error - #{props.inspect}"
126
+ end
127
+ end
128
+
129
+ def assert_binary_encoding(value)
130
+ assert_equal Encoding.find('BINARY'), value.encoding
131
+ end
132
+
133
+ def assert_utf8_encoding(value)
134
+ assert_equal Encoding.find('UTF-8'), value.encoding
135
+ end
136
+
137
+ def rubyRbx?
138
+ RUBY_DESCRIPTION =~ /rubinius/i
139
+ end
140
+
141
+ def ruby_windows?
142
+ RbConfig::CONFIG['host_os'] =~ /ming/
143
+ end
144
+
145
+ def ruby_darwin?
146
+ RbConfig::CONFIG['host_os'] =~ /darwin/
147
+ end
148
+
149
+ def load_current_schema
150
+ loader = new_connection
151
+ schema_file = File.expand_path File.join(File.dirname(__FILE__), 'schema', "#{current_schema}.sql")
152
+ schema_sql = File.open(schema_file,"rb:UTF-8") { |f|f.read }
153
+ loader.execute(drop_sql).do
154
+ loader.execute(schema_sql).do
155
+ loader.execute(sp_sql).do
156
+ loader.close
157
+ true
158
+ end
159
+
160
+ def drop_sql
161
+ sybase_ase? ? drop_sql_sybase : drop_sql_microsoft
162
+ end
163
+
164
+ def drop_sql_sybase
165
+ %|IF EXISTS(
166
+ SELECT 1 FROM sysobjects WHERE type = 'U' AND name = 'datatypes'
167
+ ) DROP TABLE datatypes
168
+ IF EXISTS(
169
+ SELECT 1 FROM sysobjects WHERE type = 'P' AND name = 'tinytds_TestReturnCodes'
170
+ ) DROP PROCEDURE tinytds_TestReturnCodes|
171
+ end
172
+
173
+ def drop_sql_microsoft
174
+ %|IF EXISTS (
175
+ SELECT TABLE_NAME
176
+ FROM INFORMATION_SCHEMA.TABLES
177
+ WHERE TABLE_CATALOG = 'tinytdstest'
178
+ AND TABLE_TYPE = 'BASE TABLE'
179
+ AND TABLE_NAME = 'datatypes'
180
+ ) DROP TABLE [datatypes]
181
+ IF EXISTS (
182
+ SELECT name FROM sysobjects
183
+ WHERE name = 'tinytds_TestReturnCodes' AND type = 'P'
184
+ ) DROP PROCEDURE tinytds_TestReturnCodes|
185
+ end
186
+
187
+ def sp_sql
188
+ %|CREATE PROCEDURE tinytds_TestReturnCodes
189
+ AS
190
+ SELECT 1 as [one]
191
+ RETURN(420) |
192
+ end
193
+
194
+ def find_value(id, column, query_options={})
195
+ query_options[:timezone] ||= :utc
196
+ sql = "SELECT [#{column}] FROM [datatypes] WHERE [id] = #{id}"
197
+ @client.execute(sql).each(query_options).first[column.to_s]
198
+ end
199
+
200
+ def local_offset
201
+ TinyTds::Client.local_offset
202
+ end
203
+
204
+ def utc_offset
205
+ ::Time.local(2010).utc_offset
206
+ end
207
+
208
+ def rollback_transaction(client)
209
+ client.execute("BEGIN TRANSACTION").do
210
+ yield
211
+ ensure
212
+ client.execute("ROLLBACK TRANSACTION").do
213
+ end
214
+
215
+ end
216
+ end
217
+