tiny_tds 0.6.2-x64-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.
@@ -0,0 +1,138 @@
1
+
2
+ /*
3
+
4
+ * Binary Data - Our test binary data is a 1 pixel gif. The basic (raw) data is below. Quoting this data
5
+ would involve this (encode) method and be (encoded) with the 0x prefix for raw SQL. In other clients the
6
+ (raw_db) value without the 0x prefix would need to be (packed) again yield the original (raw) value.
7
+
8
+ (raw) - "GIF89a\001\000\001\000\221\000\000\377\377\377\377\377\377\376\001\002\000\000\000!\371\004\004\024\000\377\000,\000\000\000\000\001\000\001\000\000\002\002D\001\000;"
9
+ (encode) - "0x#{raw.unpack("H*")[0]}"
10
+ (encoded) - "0x47494638396101000100910000fffffffffffffe010200000021f904041400ff002c00000000010001000002024401003b"
11
+ (raw_db) - "47494638396101000100910000fffffffffffffe010200000021f904041400ff002c00000000010001000002024401003b"
12
+ (packed) - [raw_db].pack('H*')
13
+
14
+ */
15
+
16
+ CREATE TABLE [datatypes] (
17
+ [id] [int] IDENTITY NOT NULL PRIMARY KEY,
18
+ [bigint] [bigint] NULL,
19
+ [binary_50] [binary](50) NULL,
20
+ [bit] [bit] DEFAULT 0,
21
+ [char_10] [char](10) NULL,
22
+ [date] [date] NULL,
23
+ [datetime] [datetime] NULL,
24
+ -- [datetime2_7] [datetime2](7) NULL,
25
+ -- [datetimeoffset_2] [datetimeoffset](2) NULL,
26
+ -- [datetimeoffset_7] [datetimeoffset](7) NULL,
27
+ [decimal_9_2] [decimal](9, 2) NULL,
28
+ [decimal_16_4] [decimal](16, 4) NULL,
29
+ [float] [float] NULL,
30
+ -- [geography] [geography] NULL,
31
+ -- [geometry] [geometry] NULL,
32
+ -- [hierarchyid] [hierarchyid] NULL,
33
+ [image] [image] NULL,
34
+ [int] [int] NULL,
35
+ [money] [money] NULL,
36
+ [nchar_10] [nchar](10) NULL,
37
+ -- [ntext] [ntext] NULL,
38
+ [numeric_18_0] [numeric](18, 0) NULL,
39
+ [numeric_36_2] [numeric](36, 2) NULL,
40
+ [nvarchar_50] [nvarchar](50) NULL,
41
+ -- [nvarchar_max] [nvarchar](max) NULL,
42
+ [real] [real] NULL,
43
+ [smalldatetime] [smalldatetime] NULL,
44
+ [smallint] [smallint] NULL,
45
+ [smallmoney] [smallmoney] NULL,
46
+ [text] [text] NULL,
47
+ -- [time_2] [time](2) NULL,
48
+ -- [time_7] [time](7) NULL,
49
+ [timestamp] [timestamp] NULL,
50
+ [tinyint] [tinyint] NULL,
51
+ -- [uniqueidentifier] [uniqueidentifier] NULL,
52
+ [varbinary_50] [varbinary](50) NULL,
53
+ -- [varbinary_max] [varbinary](max) NULL,
54
+ [varchar_50] [varchar](50) NULL
55
+ -- [varchar_max] [varchar](max) NULL,
56
+ -- [xml] [xml] NULL
57
+ )
58
+
59
+ SET IDENTITY_INSERT [datatypes] ON
60
+
61
+ INSERT INTO [datatypes] ([id], [bigint]) VALUES ( 11, -9223372036854775807 )
62
+ INSERT INTO [datatypes] ([id], [bigint]) VALUES ( 12, 9223372036854775806 )
63
+ INSERT INTO [datatypes] ([id], [binary_50]) VALUES ( 21, 0x47494638396101000100910000fffffffffffffe010200000021f904041400ff002c00000000010001000002024401003b )
64
+ INSERT INTO [datatypes] ([id], [bit]) VALUES ( 31, 1 )
65
+ INSERT INTO [datatypes] ([id], [bit]) VALUES ( 32, 0 )
66
+ INSERT INTO [datatypes] ([id], [char_10]) VALUES ( 41, '1234567890' )
67
+ INSERT INTO [datatypes] ([id], [char_10]) VALUES ( 42, '12345678' )
68
+ INSERT INTO [datatypes] ([id], [date]) VALUES ( 51, '0001-01-01' )
69
+ INSERT INTO [datatypes] ([id], [date]) VALUES ( 52, '9999-12-31' )
70
+ INSERT INTO [datatypes] ([id], [datetime]) VALUES ( 61, '1753-01-01T00:00:00.000' )
71
+ INSERT INTO [datatypes] ([id], [datetime]) VALUES ( 62, '9999-12-31T23:59:59.997' )
72
+ INSERT INTO [datatypes] ([id], [datetime]) VALUES ( 63, '2010-01-01T12:34:56.123' )
73
+ -- INSERT INTO [datatypes] ([id], [datetime2_7]) VALUES ( 71, '0001-01-01T00:00:00.0000000Z' )
74
+ -- INSERT INTO [datatypes] ([id], [datetime2_7]) VALUES ( 72, '1984-01-24T04:20:00.0000000-08:00' )
75
+ -- INSERT INTO [datatypes] ([id], [datetime2_7]) VALUES ( 73, '9999-12-31T23:59:59.9999999Z' )
76
+ -- INSERT INTO [datatypes] ([id], [datetimeoffset_2]) VALUES ( 81, '1984-01-24T04:20:00.0000000-08:00' ) -- 1984-01-24 04:20:00.00 -08:00
77
+ -- INSERT INTO [datatypes] ([id], [datetimeoffset_2]) VALUES ( 82, '1984-01-24T04:20:00.0000000Z' ) -- 1984-01-24 04:20:00.00 +00:00
78
+ -- INSERT INTO [datatypes] ([id], [datetimeoffset_2]) VALUES ( 83, '9999-12-31T23:59:59.9999999Z' ) -- 9999-12-31 23:59:59.99 +00:00
79
+ -- INSERT INTO [datatypes] ([id], [datetimeoffset_7]) VALUES ( 84, '1984-01-24T04:20:00.0000000-08:00' ) -- 1984-01-24 04:20:00.0000000 -08:00
80
+ -- INSERT INTO [datatypes] ([id], [datetimeoffset_7]) VALUES ( 85, '1984-01-24T04:20:00.0000000Z' ) -- 1984-01-24 04:20:00.0000000 +00:00
81
+ -- INSERT INTO [datatypes] ([id], [datetimeoffset_7]) VALUES ( 86, '9999-12-31T23:59:59.9999999Z' ) -- 9999-12-31 23:59:59.9999999 +00:00
82
+ INSERT INTO [datatypes] ([id], [decimal_9_2]) VALUES ( 91, 12345.01 )
83
+ INSERT INTO [datatypes] ([id], [decimal_9_2]) VALUES ( 92, 1234567.89 )
84
+ INSERT INTO [datatypes] ([id], [decimal_16_4]) VALUES ( 93, 0.0 )
85
+ INSERT INTO [datatypes] ([id], [decimal_16_4]) VALUES ( 94, 123456789012.3456 )
86
+ INSERT INTO [datatypes] ([id], [float]) VALUES ( 101, 123.00000001 )
87
+ INSERT INTO [datatypes] ([id], [float]) VALUES ( 102, 0.0 )
88
+ INSERT INTO [datatypes] ([id], [float]) VALUES ( 103, 123.45 )
89
+ -- INSERT INTO [datatypes] ([id], [geography]) VALUES ( 111, geography::STGeomFromText('LINESTRING(-122.360 47.656, -122.343 47.656)', 4326) ) -- 0xE610000001148716D9CEF7D34740D7A3703D0A975EC08716D9CEF7D34740CBA145B6F3955EC0
90
+ -- INSERT INTO [datatypes] ([id], [geometry]) VALUES ( 121, geometry::STGeomFromText('LINESTRING (100 100, 20 180, 180 180)', 0) ) -- 0x0000000001040300000000000000000059400000000000005940000000000000344000000000008066400000000000806640000000000080664001000000010000000001000000FFFFFFFF0000000002
91
+ -- INSERT INTO [datatypes] ([id], [hierarchyid]) VALUES ( 131, CAST('/1/' AS hierarchyid) ) -- 0x58
92
+ -- INSERT INTO [datatypes] ([id], [hierarchyid]) VALUES ( 132, CAST('/2/' AS hierarchyid) ) -- 0x68
93
+ INSERT INTO [datatypes] ([id], [image]) VALUES ( 141, 0x47494638396101000100910000fffffffffffffe010200000021f904041400ff002c00000000010001000002024401003b )
94
+ INSERT INTO [datatypes] ([id], [int]) VALUES ( 151, -2147483647 )
95
+ INSERT INTO [datatypes] ([id], [int]) VALUES ( 152, 2147483646 )
96
+ INSERT INTO [datatypes] ([id], [money]) VALUES ( 161, 4.20 )
97
+ INSERT INTO [datatypes] ([id], [money]) VALUES ( 162, -922337203685477.5807 )
98
+ INSERT INTO [datatypes] ([id], [money]) VALUES ( 163, 922337203685477.5806 )
99
+ INSERT INTO [datatypes] ([id], [nchar_10]) VALUES ( 171, N'1234567890' )
100
+ INSERT INTO [datatypes] ([id], [nchar_10]) VALUES ( 172, N'123456åå' )
101
+ INSERT INTO [datatypes] ([id], [nchar_10]) VALUES ( 173, N'abc123' )
102
+ -- INSERT INTO [datatypes] ([id], [ntext]) VALUES ( 181, N'test ntext' )
103
+ -- INSERT INTO [datatypes] ([id], [ntext]) VALUES ( 182, N'test ntext' ) -- Removed UTF-8 chars. They make sybase choke in comments.
104
+ INSERT INTO [datatypes] ([id], [numeric_18_0]) VALUES ( 191, 191 )
105
+ INSERT INTO [datatypes] ([id], [numeric_18_0]) VALUES ( 192, 123456789012345678 )
106
+ INSERT INTO [datatypes] ([id], [numeric_36_2]) VALUES ( 193, 12345678901234567890.01 )
107
+ INSERT INTO [datatypes] ([id], [numeric_36_2]) VALUES ( 194, 123.46 )
108
+ INSERT INTO [datatypes] ([id], [nvarchar_50]) VALUES ( 201, N'test nvarchar_50' )
109
+ INSERT INTO [datatypes] ([id], [nvarchar_50]) VALUES ( 202, N'test nvarchar_50 åå' )
110
+ -- INSERT INTO [datatypes] ([id], [nvarchar_max]) VALUES ( 211, N'test nvarchar_max' )
111
+ -- INSERT INTO [datatypes] ([id], [nvarchar_max]) VALUES ( 212, N'test nvarchar_max' ) -- Removed UTF-8 chars. They make sybase choke in comments.
112
+ INSERT INTO [datatypes] ([id], [real]) VALUES ( 221, 123.45 )
113
+ INSERT INTO [datatypes] ([id], [real]) VALUES ( 222, 0.0 )
114
+ INSERT INTO [datatypes] ([id], [real]) VALUES ( 223, 0.00001 )
115
+ INSERT INTO [datatypes] ([id], [smalldatetime]) VALUES ( 231, '1901-01-01T15:45:00.000' ) -- 1901-01-01 15:45:00
116
+ INSERT INTO [datatypes] ([id], [smalldatetime]) VALUES ( 232, '2078-06-05T04:20:00.000' ) -- 2078-06-05 04:20:00
117
+ INSERT INTO [datatypes] ([id], [smallint]) VALUES ( 241, -32767 )
118
+ INSERT INTO [datatypes] ([id], [smallint]) VALUES ( 242, 32766 )
119
+ INSERT INTO [datatypes] ([id], [smallmoney]) VALUES ( 251, 4.20 )
120
+ INSERT INTO [datatypes] ([id], [smallmoney]) VALUES ( 252, -214748.3647 )
121
+ INSERT INTO [datatypes] ([id], [smallmoney]) VALUES ( 253, 214748.3646 )
122
+ INSERT INTO [datatypes] ([id], [text]) VALUES ( 271, 'test text' )
123
+ -- INSERT INTO [datatypes] ([id], [time_2]) VALUES ( 281, '1901-01-01T15:45:00.0100001Z' ) -- 15:45:00.01
124
+ -- INSERT INTO [datatypes] ([id], [time_2]) VALUES ( 282, '1984-01-24T04:20:00.0000001-08:00' ) -- 04:20:00.00
125
+ -- INSERT INTO [datatypes] ([id], [time_7]) VALUES ( 283, '1901-01-01T15:45:00.0100001Z' ) -- 15:45:00.0100001
126
+ -- INSERT INTO [datatypes] ([id], [time_7]) VALUES ( 284, '1984-01-24T04:20:00.0000001-08:00' ) -- 04:20:00.0000001
127
+ INSERT INTO [datatypes] ([id], [tinyint]) VALUES ( 301, 0 )
128
+ INSERT INTO [datatypes] ([id], [tinyint]) VALUES ( 302, 255 )
129
+ -- INSERT INTO [datatypes] ([id], [uniqueidentifier]) VALUES ( 311, NEWID() )
130
+ INSERT INTO [datatypes] ([id], [varbinary_50]) VALUES ( 321, 0x47494638396101000100910000fffffffffffffe010200000021f904041400ff002c00000000010001000002024401003b )
131
+ -- INSERT INTO [datatypes] ([id], [varbinary_max]) VALUES ( 331, 0x47494638396101000100910000fffffffffffffe010200000021f904041400ff002c00000000010001000002024401003b )
132
+ INSERT INTO [datatypes] ([id], [varchar_50]) VALUES ( 341, 'test varchar_50' )
133
+ -- INSERT INTO [datatypes] ([id], [varchar_max]) VALUES ( 351, 'test varchar_max' )
134
+ -- INSERT INTO [datatypes] ([id], [xml]) VALUES ( 361, '<foo><bar>batz</bar></foo>' )
135
+
136
+ SET IDENTITY_INSERT [datatypes] OFF
137
+
138
+
@@ -0,0 +1,305 @@
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
+ binary_value = sqlserver_azure? ? @gif1px : @gif1px+"\000"
23
+ value = find_value(21, :binary_50)
24
+ assert_equal binary_value, value
25
+ assert_binary_encoding(value)
26
+ end
27
+
28
+ it 'casts bit' do
29
+ assert_equal true, find_value(31, :bit)
30
+ assert_equal false, find_value(32, :bit)
31
+ assert_equal nil, find_value(21, :bit)
32
+ end
33
+
34
+ it 'casts char' do
35
+ partial_char = sqlserver_azure? ? '12345678' : '12345678 '
36
+ assert_equal '1234567890', find_value(41, :char_10)
37
+ assert_equal partial_char, find_value(42, :char_10)
38
+ assert_utf8_encoding find_value(42, :char_10)
39
+ end
40
+
41
+ it 'casts datetime' do
42
+ # 1753-01-01T00:00:00.000
43
+ v = find_value 61, :datetime
44
+ assert_instance_of Time, v, 'not in range of Time class'
45
+ assert_equal 1753, v.year
46
+ assert_equal 01, v.month
47
+ assert_equal 01, v.day
48
+ assert_equal 0, v.hour
49
+ assert_equal 0, v.min
50
+ assert_equal 0, v.sec
51
+ assert_equal 0, v.usec
52
+ # 9999-12-31T23:59:59.997
53
+ v = find_value 62, :datetime
54
+ assert_instance_of Time, v, 'not in range of Time class'
55
+ assert_equal 9999, v.year
56
+ assert_equal 12, v.month
57
+ assert_equal 31, v.day
58
+ assert_equal 23, v.hour
59
+ assert_equal 59, v.min
60
+ assert_equal 59, v.sec
61
+ assert_equal 997000, v.usec
62
+ assert_equal utc_offset, find_value(62, :datetime, :timezone => :local).utc_offset
63
+ assert_equal 0, find_value(62, :datetime, :timezone => :utc).utc_offset
64
+ # 2010-01-01T12:34:56.123
65
+ v = find_value 63, :datetime
66
+ assert_instance_of Time, v, 'in range of Time class'
67
+ assert_equal 2010, v.year
68
+ assert_equal 01, v.month
69
+ assert_equal 01, v.day
70
+ assert_equal 12, v.hour
71
+ assert_equal 34, v.min
72
+ assert_equal 56, v.sec
73
+ assert_equal 123000, v.usec
74
+ assert_equal utc_offset, find_value(63, :datetime, :timezone => :local).utc_offset
75
+ assert_equal 0, find_value(63, :datetime, :timezone => :utc).utc_offset
76
+ end
77
+
78
+ it 'casts decimal' do
79
+ assert_instance_of BigDecimal, find_value(91, :decimal_9_2)
80
+ assert_equal BigDecimal.new('12345.01'), find_value(91, :decimal_9_2)
81
+ assert_equal BigDecimal.new('1234567.89'), find_value(92, :decimal_9_2)
82
+ assert_equal BigDecimal.new('0.0'), find_value(93, :decimal_16_4)
83
+ assert_equal BigDecimal.new('123456789012.3456'), find_value(94, :decimal_16_4)
84
+ end
85
+
86
+ it 'casts float' do
87
+ assert_equal 123.00000001, find_value(101,:float)
88
+ assert_equal 0.0, find_value(102,:float)
89
+ assert_equal find_value(102,:float).object_id, find_value(102,:float).object_id, 'use global zero float'
90
+ assert_equal 123.45, find_value(103,:float)
91
+ end
92
+
93
+ it 'casts image' do
94
+ value = find_value(141,:image)
95
+ assert_equal @gif1px, value
96
+ assert_binary_encoding(value)
97
+ end
98
+
99
+ it 'casts int' do
100
+ assert_equal -2147483647, find_value(151, :int)
101
+ assert_equal 2147483646, find_value(152, :int)
102
+ end
103
+
104
+ it 'casts money' do
105
+ assert_instance_of BigDecimal, find_value(161, :money)
106
+ assert_equal BigDecimal.new('4.20'), find_value(161, :money)
107
+ assert_equal BigDecimal.new('922337203685477.5806'), find_value(163 ,:money)
108
+ assert_equal BigDecimal.new('-922337203685477.5807'), find_value(162 ,:money)
109
+ end
110
+
111
+ it 'casts nchar' do
112
+ assert_equal '1234567890', find_value(171, :nchar_10)
113
+ assert_equal '123456åå ', find_value(172, :nchar_10)
114
+ assert_equal 'abc123 ', find_value(173, :nchar_10)
115
+ end
116
+
117
+ it 'casts ntext' do
118
+ assert_equal 'test ntext', find_value(181, :ntext)
119
+ assert_equal 'test ntext åå', find_value(182, :ntext)
120
+ assert_utf8_encoding find_value(182, :ntext)
121
+ # If this test fails, try setting the "text size" in your freetds.conf. See: http://www.freetds.org/faq.html#textdata
122
+ large_value = "x" * 5000
123
+ large_value_id = @client.execute("INSERT INTO [datatypes] ([ntext]) VALUES (N'#{large_value}')").insert
124
+ assert_equal large_value, find_value(large_value_id, :ntext)
125
+ end unless sybase_ase?
126
+
127
+ it 'casts numeric' do
128
+ assert_instance_of BigDecimal, find_value(191, :numeric_18_0)
129
+ assert_equal BigDecimal('191'), find_value(191, :numeric_18_0)
130
+ assert_equal BigDecimal('123456789012345678'), find_value(192, :numeric_18_0)
131
+ assert_equal BigDecimal('12345678901234567890.01'), find_value(193, :numeric_36_2)
132
+ assert_equal BigDecimal('123.46'), find_value(194, :numeric_36_2)
133
+ end
134
+
135
+ it 'casts nvarchar' do
136
+ assert_equal 'test nvarchar_50', find_value(201, :nvarchar_50)
137
+ assert_equal 'test nvarchar_50 åå', find_value(202, :nvarchar_50)
138
+ assert_utf8_encoding find_value(202, :nvarchar_50)
139
+ end
140
+
141
+ it 'casts real' do
142
+ assert_in_delta 123.45, find_value(221, :real), 0.01
143
+ assert_equal 0.0, find_value(222, :real)
144
+ assert_equal find_value(222, :real).object_id, find_value(222, :real).object_id, 'use global zero float'
145
+ assert_in_delta 0.00001, find_value(223, :real), 0.000001
146
+ end
147
+
148
+ it 'casts smalldatetime' do
149
+ # 1901-01-01 15:45:00
150
+ v = find_value 231, :smalldatetime
151
+ assert_instance_of Time, v
152
+ assert_equal 1901, v.year
153
+ assert_equal 01, v.month
154
+ assert_equal 01, v.day
155
+ assert_equal 15, v.hour
156
+ assert_equal 45, v.min
157
+ assert_equal 00, v.sec
158
+ assert_equal Time.local(1901).utc_offset, find_value(231, :smalldatetime, :timezone => :local).utc_offset
159
+ assert_equal 0, find_value(231, :smalldatetime, :timezone => :utc).utc_offset
160
+ # 2078-06-05 04:20:00
161
+ v = find_value 232, :smalldatetime
162
+ assert_instance_of Time, v
163
+ assert_equal 2078, v.year
164
+ assert_equal 06, v.month
165
+ assert_equal 05, v.day
166
+ assert_equal 04, v.hour
167
+ assert_equal 20, v.min
168
+ assert_equal 00, v.sec
169
+ assert_equal Time.local(2078,6).utc_offset, find_value(232, :smalldatetime, :timezone => :local).utc_offset
170
+ assert_equal 0, find_value(232, :smalldatetime, :timezone => :utc).utc_offset
171
+ end
172
+
173
+ it 'casts smallint' do
174
+ assert_equal -32767, find_value(241, :smallint)
175
+ assert_equal 32766, find_value(242, :smallint)
176
+ end
177
+
178
+ it 'casts smallmoney' do
179
+ assert_instance_of BigDecimal, find_value(251, :smallmoney)
180
+ assert_equal BigDecimal.new("4.20"), find_value(251, :smallmoney)
181
+ assert_equal BigDecimal.new("-214748.3647"), find_value(252, :smallmoney)
182
+ assert_equal BigDecimal.new("214748.3646"), find_value(253, :smallmoney)
183
+ end
184
+
185
+ it 'casts text' do
186
+ assert_equal 'test text', find_value(271, :text)
187
+ assert_utf8_encoding find_value(271, :text)
188
+ end
189
+
190
+ it 'casts tinyint' do
191
+ assert_equal 0, find_value(301, :tinyint)
192
+ assert_equal 255, find_value(302, :tinyint)
193
+ end
194
+
195
+ it 'casts uniqueidentifier' do
196
+ assert_match %r|\w{8}-\w{4}-\w{4}-\w{4}-\w{12}|, find_value(311, :uniqueidentifier)
197
+ assert_utf8_encoding find_value(311, :uniqueidentifier)
198
+ end unless sybase_ase?
199
+
200
+ it 'casts varbinary' do
201
+ value = find_value(321, :varbinary_50)
202
+ assert_equal @gif1px, value
203
+ assert_binary_encoding(value)
204
+ end
205
+
206
+ it 'casts varchar' do
207
+ assert_equal 'test varchar_50', find_value(341, :varchar_50)
208
+ assert_utf8_encoding find_value(341, :varchar_50)
209
+ end
210
+
211
+ end
212
+
213
+
214
+ describe 'for 2005 and up' do
215
+
216
+ it 'casts nvarchar(max)' do
217
+ assert_equal 'test nvarchar_max', find_value(211, :nvarchar_max)
218
+ assert_equal 'test nvarchar_max åå', find_value(212, :nvarchar_max)
219
+ assert_utf8_encoding find_value(212, :nvarchar_max)
220
+ end
221
+
222
+ it 'casts varbinary(max)' do
223
+ value = find_value(331, :varbinary_max)
224
+ assert_equal @gif1px, value
225
+ assert_binary_encoding(value)
226
+ end
227
+
228
+ it 'casts varchar(max)' do
229
+ value = find_value(351, :varchar_max)
230
+ assert_equal 'test varchar_max', value
231
+ assert_utf8_encoding(value)
232
+ end
233
+
234
+ it 'casts xml' do
235
+ value = find_value(361, :xml)
236
+ assert_equal '<foo><bar>batz</bar></foo>', value
237
+ assert_utf8_encoding(value)
238
+ end
239
+
240
+ end if sqlserver_2005? || sqlserver_2008? || sqlserver_azure?
241
+
242
+
243
+ describe 'for 2008 and up' do
244
+
245
+ # These data types always come back as SYBTEXT and there is no way I can
246
+ # find out the column's human readable name.
247
+ #
248
+ # * [date]
249
+ # * [datetime2]
250
+ # * [datetimeoffset]
251
+ # * [time]
252
+ #
253
+ # I have tried the following and I only get back either "char" or 0/null.
254
+ #
255
+ # rb_warn("SYBTEXT: dbprtype: %s", dbprtype(coltype));
256
+ # rb_warn("SYBTEXT: dbcolutype: %s", dbcolutype(rwrap->client, col));
257
+ # rb_warn("SYBTEXT: dbcolutype: %ld", dbcolutype(rwrap->client, col));
258
+
259
+ # it 'casts date' do
260
+ # value = find_value 51, :date
261
+ # assert_equal '', value
262
+ # end
263
+ #
264
+ # it 'casts datetime2' do
265
+ # value = find_value 72, :datetime2_7
266
+ # assert_equal '', value
267
+ # end
268
+ #
269
+ # it 'casts datetimeoffset' do
270
+ # value = find_value 81, :datetimeoffset_2
271
+ # assert_equal '', value
272
+ # end
273
+ #
274
+ # it 'casts geography' do
275
+ # value = find_value 111, :geography
276
+ # assert_equal '', value
277
+ # end
278
+ #
279
+ # it 'casts geometry' do
280
+ # value = find_value 121, :geometry
281
+ # assert_equal '', value
282
+ # end
283
+ #
284
+ # it 'casts hierarchyid' do
285
+ # value = find_value 131, :hierarchyid
286
+ # assert_equal '', value
287
+ # end
288
+ #
289
+ # it 'casts time' do
290
+ # value = find_value 283, :time_7
291
+ # assert_equal '', value
292
+ # end
293
+
294
+ end if sqlserver_2008? || sqlserver_azure?
295
+
296
+ end
297
+
298
+
299
+
300
+ end
301
+
302
+
303
+
304
+
305
+
@@ -0,0 +1,195 @@
1
+ # encoding: UTF-8
2
+ require 'bundler' ; Bundler.require :development, :test
3
+ require 'tiny_tds'
4
+ require 'minitest/autorun'
5
+
6
+ class DateTime
7
+ def usec
8
+ (sec_fraction * 1_000_000).to_i
9
+ end
10
+ end
11
+
12
+ TINYTDS_SCHEMAS = ['sqlserver_2000', 'sqlserver_2005', 'sqlserver_2008', 'sqlserver_azure', 'sybase_ase'].freeze
13
+
14
+ module TinyTds
15
+ class TestCase < MiniTest::Spec
16
+
17
+ class << self
18
+
19
+ def current_schema
20
+ ENV['TINYTDS_SCHEMA'] || 'sqlserver_2008'
21
+ end
22
+
23
+ TINYTDS_SCHEMAS.each do |schema|
24
+ define_method "#{schema}?" do
25
+ schema == self.current_schema
26
+ end
27
+ end
28
+
29
+ def sqlserver?
30
+ current_schema =~ /sqlserver/
31
+ end
32
+
33
+ end
34
+
35
+ after do
36
+ @client.close if @client.is_a?(TinyTds::Client)
37
+ end
38
+
39
+ protected
40
+
41
+ TINYTDS_SCHEMAS.each do |schema|
42
+ define_method "#{schema}?" do
43
+ schema == self.class.current_schema
44
+ end
45
+ end
46
+
47
+ def current_schema
48
+ self.class.current_schema
49
+ end
50
+
51
+ def sqlserver?
52
+ self.class.sqlserver?
53
+ end
54
+
55
+ def new_connection(options={})
56
+ client = TinyTds::Client.new(connection_options(options))
57
+ if sybase_ase?
58
+ client.execute("SET ANSINULL ON").do
59
+ elsif !sqlserver_azure?
60
+ client.execute("SET ANSI_DEFAULTS ON").do
61
+ client.execute("SET IMPLICIT_TRANSACTIONS OFF").do
62
+ client.execute("SET CURSOR_CLOSE_ON_COMMIT OFF").do
63
+ end
64
+ client
65
+ end
66
+
67
+ def connection_options(options={})
68
+ username = sqlserver_azure? ? ENV['TINYTDS_UNIT_AZURE_USER'] : ENV['TINYTDS_UNIT_USER'] || 'tinytds'
69
+ password = sqlserver_azure? ? ENV['TINYTDS_UNIT_AZURE_PASS'] : ENV['TINYTDS_UNIT_PASS'] || ''
70
+ { :dataserver => ENV['TINYTDS_UNIT_DATASERVER'],
71
+ :host => ENV['TINYTDS_UNIT_HOST'],
72
+ :port => ENV['TINYTDS_UNIT_PORT'],
73
+ :tds_version => ENV['TINYTDS_UNIT_VERSION'],
74
+ :username => username,
75
+ :password => password,
76
+ :database => 'tinytdstest',
77
+ :appname => 'TinyTds Dev',
78
+ :login_timeout => 5,
79
+ :timeout => 5,
80
+ :azure => sqlserver_azure?
81
+ }.merge(options)
82
+ end
83
+
84
+ def assert_client_works(client)
85
+ client.execute("SELECT 'client_works' as [client_works]").each.must_equal [{'client_works' => 'client_works'}]
86
+ end
87
+
88
+ def assert_new_connections_work
89
+ client = new_connection
90
+ client.execute("SELECT 'new_connections_work' as [new_connections_work]").each
91
+ end
92
+
93
+ def assert_raise_tinytds_error(action)
94
+ error_raised = false
95
+ begin
96
+ action.call
97
+ rescue TinyTds::Error => e
98
+ error_raised = true
99
+ end
100
+ assert error_raised, 'expected a TinyTds::Error but none happened'
101
+ yield e
102
+ end
103
+
104
+ def inspect_tinytds_exception
105
+ begin
106
+ yield
107
+ rescue TinyTds::Error => e
108
+ props = { :source => e.source, :message => e.message, :severity => e.severity,
109
+ :db_error_number => e.db_error_number, :os_error_number => e.os_error_number }
110
+ raise "TinyTds::Error - #{props.inspect}"
111
+ end
112
+ end
113
+
114
+ def assert_binary_encoding(value)
115
+ assert_equal Encoding.find('BINARY'), value.encoding
116
+ end
117
+
118
+ def assert_utf8_encoding(value)
119
+ assert_equal Encoding.find('UTF-8'), value.encoding
120
+ end
121
+
122
+ def rubyRbx?
123
+ RUBY_DESCRIPTION =~ /rubinius/i
124
+ end
125
+
126
+ def load_current_schema
127
+ loader = new_connection
128
+ schema_file = File.expand_path File.join(File.dirname(__FILE__), 'schema', "#{current_schema}.sql")
129
+ schema_sql = File.open(schema_file,"rb:UTF-8") { |f|f.read }
130
+ loader.execute(drop_sql).each
131
+ loader.execute(schema_sql).cancel
132
+ loader.execute(sp_sql).cancel
133
+ loader.close
134
+ true
135
+ end
136
+
137
+ def drop_sql
138
+ sybase_ase? ? drop_sql_sybase : drop_sql_microsoft
139
+ end
140
+
141
+ def drop_sql_sybase
142
+ %|IF EXISTS(
143
+ SELECT 1 FROM sysobjects WHERE type = 'U' AND name = 'datatypes'
144
+ ) DROP TABLE datatypes
145
+ IF EXISTS(
146
+ SELECT 1 FROM sysobjects WHERE type = 'P' AND name = 'tinytds_TestReturnCodes'
147
+ ) DROP PROCEDURE tinytds_TestReturnCodes|
148
+ end
149
+
150
+ def drop_sql_microsoft
151
+ %|IF EXISTS (
152
+ SELECT TABLE_NAME
153
+ FROM INFORMATION_SCHEMA.TABLES
154
+ WHERE TABLE_CATALOG = 'tinytdstest'
155
+ AND TABLE_TYPE = 'BASE TABLE'
156
+ AND TABLE_NAME = 'datatypes'
157
+ ) DROP TABLE [datatypes]
158
+ IF EXISTS (
159
+ SELECT name FROM sysobjects
160
+ WHERE name = 'tinytds_TestReturnCodes' AND type = 'P'
161
+ ) DROP PROCEDURE tinytds_TestReturnCodes|
162
+ end
163
+
164
+ def sp_sql
165
+ %|CREATE PROCEDURE tinytds_TestReturnCodes
166
+ AS
167
+ SELECT 1 as [one]
168
+ RETURN(420) |
169
+ end
170
+
171
+ def find_value(id, column, query_options={})
172
+ query_options[:timezone] ||= :utc
173
+ sql = "SELECT [#{column}] FROM [datatypes] WHERE [id] = #{id}"
174
+ @client.execute(sql).each(query_options).first[column.to_s]
175
+ end
176
+
177
+ def local_offset
178
+ TinyTds::Client.local_offset
179
+ end
180
+
181
+ def utc_offset
182
+ ::Time.local(2010).utc_offset
183
+ end
184
+
185
+ def rollback_transaction(client)
186
+ client.execute("BEGIN TRANSACTION").do
187
+ yield
188
+ ensure
189
+ client.execute("ROLLBACK TRANSACTION").do
190
+ end
191
+
192
+
193
+ end
194
+ end
195
+