tiny_tds 0.6.2-x64-mingw32 → 0.6.3.rc2-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.
- checksums.yaml +5 -13
- data/.gitignore +0 -1
- data/CHANGELOG +22 -5
- data/CODE_OF_CONDUCT.md +31 -0
- data/Gemfile +0 -1
- data/README.md +29 -31
- data/Rakefile +52 -62
- data/appveyor.yml +48 -0
- data/ext/tiny_tds/client.c +11 -11
- data/ext/tiny_tds/extconf.rb +203 -6
- data/ext/tiny_tds/result.c +3 -35
- data/lib/tiny_tds.rb +25 -6
- data/lib/tiny_tds/client.rb +15 -17
- data/lib/tiny_tds/version.rb +2 -2
- data/test/client_test.rb +23 -23
- data/test/result_test.rb +80 -84
- data/test/schema/sqlserver_2014.sql +138 -0
- data/test/schema_test.rb +58 -59
- data/test/test_helper.rb +55 -46
- data/test/thread_test.rb +4 -4
- metadata +48 -42
- data/compile/rake-compiler-dev-box.patch +0 -31
- data/ext/patch/Makefile.in.diff +0 -29
- data/ext/patch/dblib-30-char-username.diff +0 -11
- data/ext/patch/sspi_w_kerberos.diff +0 -42
- data/tasks/ports.rake +0 -79
@@ -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 [dbo].[datatypes] (
|
17
|
+
[id] [int] NOT NULL IDENTITY(1,1) PRIMARY KEY,
|
18
|
+
[bigint] [bigint] NULL,
|
19
|
+
[binary_50] [binary](50) NULL,
|
20
|
+
[bit] [bit] NULL,
|
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
|
+
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
|
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 åå' )
|
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 åå' )
|
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.000Z' ) -- 1901-01-01 15:45:00
|
116
|
+
INSERT INTO [datatypes] ([id], [smalldatetime]) VALUES ( 232, '2078-06-05T04:20:00.000Z' ) -- 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
|
+
|
data/test/schema_test.rb
CHANGED
@@ -2,42 +2,41 @@
|
|
2
2
|
require 'test_helper'
|
3
3
|
|
4
4
|
class SchemaTest < TinyTds::TestCase
|
5
|
-
|
5
|
+
|
6
6
|
describe 'Casting SQL Server schema' do
|
7
|
-
|
7
|
+
|
8
8
|
before do
|
9
9
|
@@current_schema_loaded ||= load_current_schema
|
10
10
|
@client = new_connection
|
11
11
|
@gif1px = File.read('test/schema/1px.gif',:mode=>"rb:BINARY")
|
12
12
|
end
|
13
|
-
|
13
|
+
|
14
14
|
describe 'for shared types' do
|
15
|
-
|
15
|
+
|
16
16
|
it 'casts bigint' do
|
17
17
|
assert_equal -9223372036854775807, find_value(11, :bigint)
|
18
18
|
assert_equal 9223372036854775806, find_value(12, :bigint)
|
19
19
|
end
|
20
|
-
|
20
|
+
|
21
21
|
it 'casts binary' do
|
22
|
-
binary_value = sqlserver_azure? ? @gif1px : @gif1px+"\000"
|
23
22
|
value = find_value(21, :binary_50)
|
24
|
-
assert_equal
|
23
|
+
assert_equal @gif1px + "\000", value
|
25
24
|
assert_binary_encoding(value)
|
26
25
|
end
|
27
|
-
|
26
|
+
|
28
27
|
it 'casts bit' do
|
29
28
|
assert_equal true, find_value(31, :bit)
|
30
29
|
assert_equal false, find_value(32, :bit)
|
31
30
|
assert_equal nil, find_value(21, :bit)
|
32
31
|
end
|
33
|
-
|
32
|
+
|
34
33
|
it 'casts char' do
|
35
|
-
partial_char =
|
34
|
+
partial_char = '12345678 '
|
36
35
|
assert_equal '1234567890', find_value(41, :char_10)
|
37
36
|
assert_equal partial_char, find_value(42, :char_10)
|
38
37
|
assert_utf8_encoding find_value(42, :char_10)
|
39
38
|
end
|
40
|
-
|
39
|
+
|
41
40
|
it 'casts datetime' do
|
42
41
|
# 1753-01-01T00:00:00.000
|
43
42
|
v = find_value 61, :datetime
|
@@ -74,7 +73,7 @@ class SchemaTest < TinyTds::TestCase
|
|
74
73
|
assert_equal utc_offset, find_value(63, :datetime, :timezone => :local).utc_offset
|
75
74
|
assert_equal 0, find_value(63, :datetime, :timezone => :utc).utc_offset
|
76
75
|
end
|
77
|
-
|
76
|
+
|
78
77
|
it 'casts decimal' do
|
79
78
|
assert_instance_of BigDecimal, find_value(91, :decimal_9_2)
|
80
79
|
assert_equal BigDecimal.new('12345.01'), find_value(91, :decimal_9_2)
|
@@ -82,38 +81,38 @@ class SchemaTest < TinyTds::TestCase
|
|
82
81
|
assert_equal BigDecimal.new('0.0'), find_value(93, :decimal_16_4)
|
83
82
|
assert_equal BigDecimal.new('123456789012.3456'), find_value(94, :decimal_16_4)
|
84
83
|
end
|
85
|
-
|
84
|
+
|
86
85
|
it 'casts float' do
|
87
86
|
assert_equal 123.00000001, find_value(101,:float)
|
88
87
|
assert_equal 0.0, find_value(102,:float)
|
89
88
|
assert_equal find_value(102,:float).object_id, find_value(102,:float).object_id, 'use global zero float'
|
90
89
|
assert_equal 123.45, find_value(103,:float)
|
91
90
|
end
|
92
|
-
|
91
|
+
|
93
92
|
it 'casts image' do
|
94
93
|
value = find_value(141,:image)
|
95
94
|
assert_equal @gif1px, value
|
96
95
|
assert_binary_encoding(value)
|
97
96
|
end
|
98
|
-
|
97
|
+
|
99
98
|
it 'casts int' do
|
100
99
|
assert_equal -2147483647, find_value(151, :int)
|
101
100
|
assert_equal 2147483646, find_value(152, :int)
|
102
101
|
end
|
103
|
-
|
102
|
+
|
104
103
|
it 'casts money' do
|
105
104
|
assert_instance_of BigDecimal, find_value(161, :money)
|
106
105
|
assert_equal BigDecimal.new('4.20'), find_value(161, :money)
|
107
106
|
assert_equal BigDecimal.new('922337203685477.5806'), find_value(163 ,:money)
|
108
107
|
assert_equal BigDecimal.new('-922337203685477.5807'), find_value(162 ,:money)
|
109
108
|
end
|
110
|
-
|
109
|
+
|
111
110
|
it 'casts nchar' do
|
112
111
|
assert_equal '1234567890', find_value(171, :nchar_10)
|
113
112
|
assert_equal '123456åå ', find_value(172, :nchar_10)
|
114
113
|
assert_equal 'abc123 ', find_value(173, :nchar_10)
|
115
114
|
end
|
116
|
-
|
115
|
+
|
117
116
|
it 'casts ntext' do
|
118
117
|
assert_equal 'test ntext', find_value(181, :ntext)
|
119
118
|
assert_equal 'test ntext åå', find_value(182, :ntext)
|
@@ -123,7 +122,7 @@ class SchemaTest < TinyTds::TestCase
|
|
123
122
|
large_value_id = @client.execute("INSERT INTO [datatypes] ([ntext]) VALUES (N'#{large_value}')").insert
|
124
123
|
assert_equal large_value, find_value(large_value_id, :ntext)
|
125
124
|
end unless sybase_ase?
|
126
|
-
|
125
|
+
|
127
126
|
it 'casts numeric' do
|
128
127
|
assert_instance_of BigDecimal, find_value(191, :numeric_18_0)
|
129
128
|
assert_equal BigDecimal('191'), find_value(191, :numeric_18_0)
|
@@ -131,20 +130,20 @@ class SchemaTest < TinyTds::TestCase
|
|
131
130
|
assert_equal BigDecimal('12345678901234567890.01'), find_value(193, :numeric_36_2)
|
132
131
|
assert_equal BigDecimal('123.46'), find_value(194, :numeric_36_2)
|
133
132
|
end
|
134
|
-
|
133
|
+
|
135
134
|
it 'casts nvarchar' do
|
136
135
|
assert_equal 'test nvarchar_50', find_value(201, :nvarchar_50)
|
137
136
|
assert_equal 'test nvarchar_50 åå', find_value(202, :nvarchar_50)
|
138
137
|
assert_utf8_encoding find_value(202, :nvarchar_50)
|
139
138
|
end
|
140
|
-
|
139
|
+
|
141
140
|
it 'casts real' do
|
142
141
|
assert_in_delta 123.45, find_value(221, :real), 0.01
|
143
142
|
assert_equal 0.0, find_value(222, :real)
|
144
143
|
assert_equal find_value(222, :real).object_id, find_value(222, :real).object_id, 'use global zero float'
|
145
144
|
assert_in_delta 0.00001, find_value(223, :real), 0.000001
|
146
145
|
end
|
147
|
-
|
146
|
+
|
148
147
|
it 'casts smalldatetime' do
|
149
148
|
# 1901-01-01 15:45:00
|
150
149
|
v = find_value 231, :smalldatetime
|
@@ -169,134 +168,134 @@ class SchemaTest < TinyTds::TestCase
|
|
169
168
|
assert_equal Time.local(2078,6).utc_offset, find_value(232, :smalldatetime, :timezone => :local).utc_offset
|
170
169
|
assert_equal 0, find_value(232, :smalldatetime, :timezone => :utc).utc_offset
|
171
170
|
end
|
172
|
-
|
171
|
+
|
173
172
|
it 'casts smallint' do
|
174
173
|
assert_equal -32767, find_value(241, :smallint)
|
175
174
|
assert_equal 32766, find_value(242, :smallint)
|
176
175
|
end
|
177
|
-
|
176
|
+
|
178
177
|
it 'casts smallmoney' do
|
179
178
|
assert_instance_of BigDecimal, find_value(251, :smallmoney)
|
180
179
|
assert_equal BigDecimal.new("4.20"), find_value(251, :smallmoney)
|
181
180
|
assert_equal BigDecimal.new("-214748.3647"), find_value(252, :smallmoney)
|
182
181
|
assert_equal BigDecimal.new("214748.3646"), find_value(253, :smallmoney)
|
183
182
|
end
|
184
|
-
|
183
|
+
|
185
184
|
it 'casts text' do
|
186
185
|
assert_equal 'test text', find_value(271, :text)
|
187
186
|
assert_utf8_encoding find_value(271, :text)
|
188
187
|
end
|
189
|
-
|
188
|
+
|
190
189
|
it 'casts tinyint' do
|
191
190
|
assert_equal 0, find_value(301, :tinyint)
|
192
191
|
assert_equal 255, find_value(302, :tinyint)
|
193
192
|
end
|
194
|
-
|
193
|
+
|
195
194
|
it 'casts uniqueidentifier' do
|
196
195
|
assert_match %r|\w{8}-\w{4}-\w{4}-\w{4}-\w{12}|, find_value(311, :uniqueidentifier)
|
197
196
|
assert_utf8_encoding find_value(311, :uniqueidentifier)
|
198
197
|
end unless sybase_ase?
|
199
|
-
|
198
|
+
|
200
199
|
it 'casts varbinary' do
|
201
200
|
value = find_value(321, :varbinary_50)
|
202
201
|
assert_equal @gif1px, value
|
203
202
|
assert_binary_encoding(value)
|
204
203
|
end
|
205
|
-
|
204
|
+
|
206
205
|
it 'casts varchar' do
|
207
206
|
assert_equal 'test varchar_50', find_value(341, :varchar_50)
|
208
207
|
assert_utf8_encoding find_value(341, :varchar_50)
|
209
208
|
end
|
210
|
-
|
209
|
+
|
211
210
|
end
|
212
|
-
|
213
|
-
|
211
|
+
|
212
|
+
|
214
213
|
describe 'for 2005 and up' do
|
215
|
-
|
214
|
+
|
216
215
|
it 'casts nvarchar(max)' do
|
217
216
|
assert_equal 'test nvarchar_max', find_value(211, :nvarchar_max)
|
218
217
|
assert_equal 'test nvarchar_max åå', find_value(212, :nvarchar_max)
|
219
218
|
assert_utf8_encoding find_value(212, :nvarchar_max)
|
220
219
|
end
|
221
|
-
|
220
|
+
|
222
221
|
it 'casts varbinary(max)' do
|
223
222
|
value = find_value(331, :varbinary_max)
|
224
223
|
assert_equal @gif1px, value
|
225
224
|
assert_binary_encoding(value)
|
226
225
|
end
|
227
|
-
|
226
|
+
|
228
227
|
it 'casts varchar(max)' do
|
229
228
|
value = find_value(351, :varchar_max)
|
230
229
|
assert_equal 'test varchar_max', value
|
231
230
|
assert_utf8_encoding(value)
|
232
231
|
end
|
233
|
-
|
232
|
+
|
234
233
|
it 'casts xml' do
|
235
234
|
value = find_value(361, :xml)
|
236
235
|
assert_equal '<foo><bar>batz</bar></foo>', value
|
237
236
|
assert_utf8_encoding(value)
|
238
237
|
end
|
239
|
-
|
240
|
-
end if sqlserver_2005? || sqlserver_2008? || sqlserver_azure?
|
241
|
-
|
242
|
-
|
238
|
+
|
239
|
+
end if sqlserver_2005? || sqlserver_2008? || sqlserver_2014? || sqlserver_azure?
|
240
|
+
|
241
|
+
|
243
242
|
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
|
-
#
|
243
|
+
|
244
|
+
# These data types always come back as SYBTEXT and there is no way I can
|
245
|
+
# find out the column's human readable name.
|
246
|
+
#
|
248
247
|
# * [date]
|
249
248
|
# * [datetime2]
|
250
249
|
# * [datetimeoffset]
|
251
250
|
# * [time]
|
252
|
-
#
|
251
|
+
#
|
253
252
|
# I have tried the following and I only get back either "char" or 0/null.
|
254
|
-
#
|
253
|
+
#
|
255
254
|
# rb_warn("SYBTEXT: dbprtype: %s", dbprtype(coltype));
|
256
255
|
# rb_warn("SYBTEXT: dbcolutype: %s", dbcolutype(rwrap->client, col));
|
257
256
|
# rb_warn("SYBTEXT: dbcolutype: %ld", dbcolutype(rwrap->client, col));
|
258
|
-
|
257
|
+
|
259
258
|
# it 'casts date' do
|
260
259
|
# value = find_value 51, :date
|
261
260
|
# assert_equal '', value
|
262
261
|
# end
|
263
|
-
#
|
262
|
+
#
|
264
263
|
# it 'casts datetime2' do
|
265
264
|
# value = find_value 72, :datetime2_7
|
266
265
|
# assert_equal '', value
|
267
266
|
# end
|
268
|
-
#
|
267
|
+
#
|
269
268
|
# it 'casts datetimeoffset' do
|
270
269
|
# value = find_value 81, :datetimeoffset_2
|
271
270
|
# assert_equal '', value
|
272
271
|
# end
|
273
|
-
#
|
272
|
+
#
|
274
273
|
# it 'casts geography' do
|
275
274
|
# value = find_value 111, :geography
|
276
275
|
# assert_equal '', value
|
277
276
|
# end
|
278
|
-
#
|
277
|
+
#
|
279
278
|
# it 'casts geometry' do
|
280
279
|
# value = find_value 121, :geometry
|
281
280
|
# assert_equal '', value
|
282
281
|
# end
|
283
|
-
#
|
282
|
+
#
|
284
283
|
# it 'casts hierarchyid' do
|
285
284
|
# value = find_value 131, :hierarchyid
|
286
285
|
# assert_equal '', value
|
287
286
|
# end
|
288
|
-
#
|
287
|
+
#
|
289
288
|
# it 'casts time' do
|
290
289
|
# value = find_value 283, :time_7
|
291
290
|
# assert_equal '', value
|
292
291
|
# end
|
293
|
-
|
294
|
-
end if sqlserver_2008? || sqlserver_azure?
|
295
|
-
|
292
|
+
|
293
|
+
end if sqlserver_2008? || sqlserver_2014? || sqlserver_azure?
|
294
|
+
|
296
295
|
end
|
297
|
-
|
298
|
-
|
299
|
-
|
296
|
+
|
297
|
+
|
298
|
+
|
300
299
|
end
|
301
300
|
|
302
301
|
|
data/test/test_helper.rb
CHANGED
@@ -3,93 +3,102 @@ require 'bundler' ; Bundler.require :development, :test
|
|
3
3
|
require 'tiny_tds'
|
4
4
|
require 'minitest/autorun'
|
5
5
|
|
6
|
-
|
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
|
6
|
+
TINYTDS_SCHEMAS = ['sqlserver_2000', 'sqlserver_2005', 'sqlserver_2008', 'sqlserver_2014', 'sqlserver_azure', 'sybase_ase'].freeze
|
13
7
|
|
14
8
|
module TinyTds
|
15
9
|
class TestCase < MiniTest::Spec
|
16
|
-
|
10
|
+
|
17
11
|
class << self
|
18
|
-
|
12
|
+
|
19
13
|
def current_schema
|
20
|
-
ENV['TINYTDS_SCHEMA'] || '
|
14
|
+
ENV['TINYTDS_SCHEMA'] || 'sqlserver_2014'
|
21
15
|
end
|
22
|
-
|
16
|
+
|
23
17
|
TINYTDS_SCHEMAS.each do |schema|
|
24
18
|
define_method "#{schema}?" do
|
25
19
|
schema == self.current_schema
|
26
20
|
end
|
27
21
|
end
|
28
|
-
|
22
|
+
|
29
23
|
def sqlserver?
|
30
24
|
current_schema =~ /sqlserver/
|
31
25
|
end
|
32
|
-
|
26
|
+
|
33
27
|
end
|
34
|
-
|
28
|
+
|
35
29
|
after do
|
36
30
|
@client.close if @client.is_a?(TinyTds::Client)
|
37
31
|
end
|
38
|
-
|
32
|
+
|
39
33
|
protected
|
40
|
-
|
34
|
+
|
41
35
|
TINYTDS_SCHEMAS.each do |schema|
|
42
36
|
define_method "#{schema}?" do
|
43
37
|
schema == self.class.current_schema
|
44
38
|
end
|
45
39
|
end
|
46
|
-
|
40
|
+
|
47
41
|
def current_schema
|
48
42
|
self.class.current_schema
|
49
43
|
end
|
50
|
-
|
44
|
+
|
51
45
|
def sqlserver?
|
52
46
|
self.class.sqlserver?
|
53
47
|
end
|
54
|
-
|
48
|
+
|
55
49
|
def new_connection(options={})
|
56
50
|
client = TinyTds::Client.new(connection_options(options))
|
57
51
|
if sybase_ase?
|
58
52
|
client.execute("SET ANSINULL ON").do
|
59
|
-
|
60
|
-
|
61
|
-
client.execute(
|
62
|
-
client.execute(
|
53
|
+
return client
|
54
|
+
elsif sqlserver_azure?
|
55
|
+
client.execute('SET ANSI_NULLS ON').do
|
56
|
+
client.execute('SET CURSOR_CLOSE_ON_COMMIT OFF').do
|
57
|
+
client.execute('SET ANSI_NULL_DFLT_ON ON').do
|
58
|
+
client.execute('SET IMPLICIT_TRANSACTIONS OFF').do
|
59
|
+
client.execute('SET ANSI_PADDING ON').do
|
60
|
+
client.execute('SET QUOTED_IDENTIFIER ON').do
|
61
|
+
client.execute('SET ANSI_WARNINGS ON').do
|
62
|
+
else
|
63
|
+
client.execute('SET ANSI_DEFAULTS ON').do
|
64
|
+
client.execute('SET CURSOR_CLOSE_ON_COMMIT OFF').do
|
65
|
+
client.execute('SET IMPLICIT_TRANSACTIONS OFF').do
|
63
66
|
end
|
67
|
+
client.execute('SET TEXTSIZE 2147483647').do
|
68
|
+
client.execute('SET CONCAT_NULL_YIELDS_NULL ON').do
|
64
69
|
client
|
65
70
|
end
|
66
|
-
|
71
|
+
|
67
72
|
def connection_options(options={})
|
68
73
|
username = sqlserver_azure? ? ENV['TINYTDS_UNIT_AZURE_USER'] : ENV['TINYTDS_UNIT_USER'] || 'tinytds'
|
69
74
|
password = sqlserver_azure? ? ENV['TINYTDS_UNIT_AZURE_PASS'] : ENV['TINYTDS_UNIT_PASS'] || ''
|
70
|
-
{ :dataserver => ENV['TINYTDS_UNIT_DATASERVER'],
|
75
|
+
{ :dataserver => sqlserver_azure? ? nil : ENV['TINYTDS_UNIT_DATASERVER'],
|
71
76
|
:host => ENV['TINYTDS_UNIT_HOST'],
|
72
77
|
:port => ENV['TINYTDS_UNIT_PORT'],
|
73
78
|
:tds_version => ENV['TINYTDS_UNIT_VERSION'],
|
74
79
|
:username => username,
|
75
80
|
:password => password,
|
76
|
-
:database => 'tinytdstest',
|
81
|
+
:database => ENV['TINYTDS_UNIT_DATABASE'] || 'tinytdstest',
|
77
82
|
:appname => 'TinyTds Dev',
|
78
83
|
:login_timeout => 5,
|
79
|
-
:timeout =>
|
84
|
+
:timeout => connection_timeout,
|
80
85
|
:azure => sqlserver_azure?
|
81
86
|
}.merge(options)
|
82
87
|
end
|
83
|
-
|
88
|
+
|
89
|
+
def connection_timeout
|
90
|
+
sqlserver_azure? ? 15 : 5
|
91
|
+
end
|
92
|
+
|
84
93
|
def assert_client_works(client)
|
85
94
|
client.execute("SELECT 'client_works' as [client_works]").each.must_equal [{'client_works' => 'client_works'}]
|
86
95
|
end
|
87
|
-
|
96
|
+
|
88
97
|
def assert_new_connections_work
|
89
98
|
client = new_connection
|
90
99
|
client.execute("SELECT 'new_connections_work' as [new_connections_work]").each
|
91
100
|
end
|
92
|
-
|
101
|
+
|
93
102
|
def assert_raise_tinytds_error(action)
|
94
103
|
error_raised = false
|
95
104
|
begin
|
@@ -100,29 +109,29 @@ module TinyTds
|
|
100
109
|
assert error_raised, 'expected a TinyTds::Error but none happened'
|
101
110
|
yield e
|
102
111
|
end
|
103
|
-
|
112
|
+
|
104
113
|
def inspect_tinytds_exception
|
105
114
|
begin
|
106
115
|
yield
|
107
116
|
rescue TinyTds::Error => e
|
108
|
-
props = { :source => e.source, :message => e.message, :severity => e.severity,
|
117
|
+
props = { :source => e.source, :message => e.message, :severity => e.severity,
|
109
118
|
:db_error_number => e.db_error_number, :os_error_number => e.os_error_number }
|
110
119
|
raise "TinyTds::Error - #{props.inspect}"
|
111
120
|
end
|
112
121
|
end
|
113
|
-
|
122
|
+
|
114
123
|
def assert_binary_encoding(value)
|
115
124
|
assert_equal Encoding.find('BINARY'), value.encoding
|
116
125
|
end
|
117
|
-
|
126
|
+
|
118
127
|
def assert_utf8_encoding(value)
|
119
128
|
assert_equal Encoding.find('UTF-8'), value.encoding
|
120
129
|
end
|
121
|
-
|
130
|
+
|
122
131
|
def rubyRbx?
|
123
132
|
RUBY_DESCRIPTION =~ /rubinius/i
|
124
133
|
end
|
125
|
-
|
134
|
+
|
126
135
|
def load_current_schema
|
127
136
|
loader = new_connection
|
128
137
|
schema_file = File.expand_path File.join(File.dirname(__FILE__), 'schema', "#{current_schema}.sql")
|
@@ -150,17 +159,17 @@ module TinyTds
|
|
150
159
|
def drop_sql_microsoft
|
151
160
|
%|IF EXISTS (
|
152
161
|
SELECT TABLE_NAME
|
153
|
-
FROM INFORMATION_SCHEMA.TABLES
|
154
|
-
WHERE TABLE_CATALOG = 'tinytdstest'
|
155
|
-
AND TABLE_TYPE = 'BASE TABLE'
|
162
|
+
FROM INFORMATION_SCHEMA.TABLES
|
163
|
+
WHERE TABLE_CATALOG = 'tinytdstest'
|
164
|
+
AND TABLE_TYPE = 'BASE TABLE'
|
156
165
|
AND TABLE_NAME = 'datatypes'
|
157
166
|
) DROP TABLE [datatypes]
|
158
167
|
IF EXISTS (
|
159
|
-
SELECT name FROM sysobjects
|
168
|
+
SELECT name FROM sysobjects
|
160
169
|
WHERE name = 'tinytds_TestReturnCodes' AND type = 'P'
|
161
170
|
) DROP PROCEDURE tinytds_TestReturnCodes|
|
162
171
|
end
|
163
|
-
|
172
|
+
|
164
173
|
def sp_sql
|
165
174
|
%|CREATE PROCEDURE tinytds_TestReturnCodes
|
166
175
|
AS
|
@@ -173,23 +182,23 @@ module TinyTds
|
|
173
182
|
sql = "SELECT [#{column}] FROM [datatypes] WHERE [id] = #{id}"
|
174
183
|
@client.execute(sql).each(query_options).first[column.to_s]
|
175
184
|
end
|
176
|
-
|
185
|
+
|
177
186
|
def local_offset
|
178
187
|
TinyTds::Client.local_offset
|
179
188
|
end
|
180
|
-
|
189
|
+
|
181
190
|
def utc_offset
|
182
191
|
::Time.local(2010).utc_offset
|
183
192
|
end
|
184
|
-
|
193
|
+
|
185
194
|
def rollback_transaction(client)
|
186
195
|
client.execute("BEGIN TRANSACTION").do
|
187
196
|
yield
|
188
197
|
ensure
|
189
198
|
client.execute("ROLLBACK TRANSACTION").do
|
190
199
|
end
|
191
|
-
|
192
|
-
|
200
|
+
|
201
|
+
|
193
202
|
end
|
194
203
|
end
|
195
204
|
|