oledb32: Implement CanConvert.
[wine.git] / dlls / oledb32 / tests / convert.c
blob9c64a541ccd6ffea6eefdc0d82cfe7bd9e631de9
1 /* OLE DB Conversion library tests
3 * Copyright 2009 Huw Davies
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #include <stdarg.h>
22 #define COBJMACROS
23 #define NONAMELESSUNION
24 #define NONAMELESSSTRUCT
26 #include "windef.h"
27 #include "winbase.h"
28 #include "ole2.h"
29 #include "msdadc.h"
31 #include "oledberr.h"
33 #include "initguid.h"
34 #include "msdaguid.h"
36 #include "wine/test.h"
38 static void test_dcinfo(void)
40 IDCInfo *info;
41 HRESULT hr;
42 DCINFOTYPE types[2];
43 DCINFO *inf;
45 hr = CoCreateInstance(&CLSID_OLEDB_CONVERSIONLIBRARY, NULL, CLSCTX_INPROC_SERVER, &IID_IDCInfo, (void**)&info);
46 if(FAILED(hr))
48 win_skip("Unable to load oledb conversion library\n");
49 return;
52 types[0] = DCINFOTYPE_VERSION;
53 hr = IDCInfo_GetInfo(info, 1, types, &inf);
54 ok(hr == S_OK, "got %08x\n", hr);
56 ok(inf->eInfoType == DCINFOTYPE_VERSION, "got %08x\n", inf->eInfoType);
57 ok(V_VT(&inf->vData) == VT_UI4, "got %08x\n", V_VT(&inf->vData));
58 ok(V_UI4(&inf->vData) == 0x110, "got %08x\n", V_UI4(&inf->vData));
60 V_UI4(&inf->vData) = 0x200;
61 hr = IDCInfo_SetInfo(info, 1, inf);
62 ok(hr == S_OK, "got %08x\n", hr);
63 CoTaskMemFree(inf);
65 hr = IDCInfo_GetInfo(info, 1, types, &inf);
66 ok(hr == S_OK, "got %08x\n", hr);
67 ok(inf->eInfoType == DCINFOTYPE_VERSION, "got %08x\n", inf->eInfoType);
68 ok(V_VT(&inf->vData) == VT_UI4, "got %08x\n", V_VT(&inf->vData));
69 ok(V_UI4(&inf->vData) == 0x200, "got %08x\n", V_UI4(&inf->vData));
71 V_UI4(&inf->vData) = 0x100;
72 hr = IDCInfo_SetInfo(info, 1, inf);
73 ok(hr == S_OK, "got %08x\n", hr);
74 CoTaskMemFree(inf);
76 hr = IDCInfo_GetInfo(info, 1, types, &inf);
77 ok(hr == S_OK, "got %08x\n", hr);
78 ok(inf->eInfoType == DCINFOTYPE_VERSION, "got %08x\n", inf->eInfoType);
79 ok(V_VT(&inf->vData) == VT_UI4, "got %08x\n", V_VT(&inf->vData));
80 ok(V_UI4(&inf->vData) == 0x100, "got %08x\n", V_UI4(&inf->vData));
82 V_UI4(&inf->vData) = 0x500;
83 hr = IDCInfo_SetInfo(info, 1, inf);
84 ok(hr == S_OK, "got %08x\n", hr);
85 CoTaskMemFree(inf);
87 hr = IDCInfo_GetInfo(info, 1, types, &inf);
88 ok(hr == S_OK, "got %08x\n", hr);
89 ok(inf->eInfoType == DCINFOTYPE_VERSION, "got %08x\n", inf->eInfoType);
90 ok(V_VT(&inf->vData) == VT_UI4, "got %08x\n", V_VT(&inf->vData));
91 ok(V_UI4(&inf->vData) == 0x500, "got %08x\n", V_UI4(&inf->vData));
93 V_UI4(&inf->vData) = 0xffff;
94 hr = IDCInfo_SetInfo(info, 1, inf);
95 ok(hr == S_OK, "got %08x\n", hr);
96 CoTaskMemFree(inf);
98 hr = IDCInfo_GetInfo(info, 1, types, &inf);
99 ok(hr == S_OK, "got %08x\n", hr);
100 ok(inf->eInfoType == DCINFOTYPE_VERSION, "got %08x\n", inf->eInfoType);
101 ok(V_VT(&inf->vData) == VT_UI4, "got %08x\n", V_VT(&inf->vData));
102 ok(V_UI4(&inf->vData) == 0xffff, "got %08x\n", V_UI4(&inf->vData));
104 V_UI4(&inf->vData) = 0x12345678;
105 hr = IDCInfo_SetInfo(info, 1, inf);
106 ok(hr == S_OK, "got %08x\n", hr);
107 CoTaskMemFree(inf);
109 hr = IDCInfo_GetInfo(info, 1, types, &inf);
110 ok(hr == S_OK, "got %08x\n", hr);
111 ok(inf->eInfoType == DCINFOTYPE_VERSION, "got %08x\n", inf->eInfoType);
112 ok(V_VT(&inf->vData) == VT_UI4, "got %08x\n", V_VT(&inf->vData));
113 ok(V_UI4(&inf->vData) == 0x12345678, "got %08x\n", V_UI4(&inf->vData));
115 /* Try setting a version variant of something other than VT_UI4 */
116 V_VT(&inf->vData) = VT_I4;
117 V_I4(&inf->vData) = 0x200;
118 hr = IDCInfo_SetInfo(info, 1, inf);
119 ok(hr == DB_S_ERRORSOCCURRED, "got %08x\n", hr);
120 CoTaskMemFree(inf);
122 hr = IDCInfo_GetInfo(info, 1, types, &inf);
123 ok(hr == S_OK, "got %08x\n", hr);
124 ok(inf->eInfoType == DCINFOTYPE_VERSION, "got %08x\n", inf->eInfoType);
125 ok(V_VT(&inf->vData) == VT_UI4, "got %08x\n", V_VT(&inf->vData));
126 ok(V_UI4(&inf->vData) == 0x12345678, "got %08x\n", V_UI4(&inf->vData));
127 CoTaskMemFree(inf);
129 /* More than one type */
130 types[1] = 2;
131 hr = IDCInfo_GetInfo(info, 2, types, &inf);
132 ok(hr == S_OK, "got %08x\n", hr);
133 ok(inf[0].eInfoType == DCINFOTYPE_VERSION, "got %08x\n", inf[0].eInfoType);
134 ok(V_VT(&inf[0].vData) == VT_UI4, "got %08x\n", V_VT(&inf[0].vData));
135 ok(V_UI4(&inf[0].vData) == 0x12345678, "got %08x\n", V_UI4(&inf[0].vData));
136 ok(inf[1].eInfoType == 2, "got %08x\n", inf[1].eInfoType);
137 ok(V_VT(&inf[1].vData) == VT_EMPTY, "got %08x\n", V_VT(&inf[1].vData));
139 hr = IDCInfo_SetInfo(info, 2, inf);
140 ok(hr == S_OK, "got %08x\n", hr);
141 CoTaskMemFree(inf);
144 IDCInfo_Release(info);
147 struct can_convert
149 DBTYPE type;
150 DWORD can_convert_to;
151 } simple_convert[] =
153 {DBTYPE_EMPTY, 0x23bfd9ff},
154 {DBTYPE_NULL, 0x00001002},
155 {DBTYPE_I2, 0x3b9fd9ff},
156 {DBTYPE_I4, 0x3bdfd9ff},
158 {DBTYPE_R4, 0x3b9fd9ff},
159 {DBTYPE_R8, 0x3b9fd9ff},
160 {DBTYPE_CY, 0x039fd97f},
161 {DBTYPE_DATE, 0x399f99bf},
163 {DBTYPE_BSTR, 0x3bffd9ff},
164 {DBTYPE_IDISPATCH, 0x3bffffff},
165 {DBTYPE_ERROR, 0x01001500},
166 {DBTYPE_BOOL, 0x039fd9ff},
168 {DBTYPE_VARIANT, 0x3bffffff},
169 {DBTYPE_IUNKNOWN, 0x00003203},
170 {DBTYPE_DECIMAL, 0x3b9fd97f},
171 {DBTYPE_I1, 0x3b9fd9ff},
173 {DBTYPE_UI1, 0x3b9fd9ff},
174 {DBTYPE_UI2, 0x3b9fd9ff},
175 {DBTYPE_UI4, 0x3bdfd9ff},
176 {DBTYPE_I8, 0x03dfd97f},
178 {DBTYPE_UI8, 0x03dfd97f},
179 {DBTYPE_GUID, 0x01e01103},
180 {DBTYPE_BYTES, 0x01fc110b},
181 {DBTYPE_STR, 0x3bffd9ff},
183 {DBTYPE_WSTR, 0x3bffd9ff},
184 {DBTYPE_NUMERIC, 0x039fd97f},
185 {DBTYPE_UDT, 0x00000000},
186 {DBTYPE_DBDATE, 0x39801183},
188 {DBTYPE_DBTIME, 0x39801183},
189 {DBTYPE_DBTIMESTAMP, 0x39801183}
193 static inline BOOL array_type(DBTYPE type)
195 return (type >= DBTYPE_I2 && type <= DBTYPE_UI4);
198 static void test_canconvert(void)
200 IDataConvert *convert;
201 HRESULT hr;
202 int src_idx, dst_idx;
204 hr = CoCreateInstance(&CLSID_OLEDB_CONVERSIONLIBRARY, NULL, CLSCTX_INPROC_SERVER, &IID_IDataConvert, (void**)&convert);
205 if(FAILED(hr))
207 win_skip("Unable to load oledb conversion library\n");
208 return;
211 /* Some older versions of the library don't support several conversions, we'll skip
212 if we have such a library */
213 hr = IDataConvert_CanConvert(convert, DBTYPE_EMPTY, DBTYPE_DBTIMESTAMP);
214 if(hr == S_FALSE)
216 win_skip("Doesn't handle DBTYPE_EMPTY -> DBTYPE_DBTIMESTAMP conversion so skipping\n");
217 IDataConvert_Release(convert);
218 return;
221 /* Some older versions of the library don't support several conversions, we'll skip
222 if we have such a library */
223 hr = IDataConvert_CanConvert(convert, DBTYPE_EMPTY, DBTYPE_DBTIMESTAMP);
224 if(hr == S_FALSE)
226 win_skip("Doesn't handle DBTYPE_EMPTY -> DBTYPE_DBTIMESTAMP conversion so skipping\n");
227 IDataConvert_Release(convert);
228 return;
231 for(src_idx = 0; src_idx < sizeof(simple_convert) / sizeof(simple_convert[0]); src_idx++)
232 for(dst_idx = 0; dst_idx < sizeof(simple_convert) / sizeof(simple_convert[0]); dst_idx++)
234 BOOL expect, simple_expect;
235 simple_expect = (simple_convert[src_idx].can_convert_to >> dst_idx) & 1;
237 hr = IDataConvert_CanConvert(convert, simple_convert[src_idx].type, simple_convert[dst_idx].type);
238 expect = simple_expect;
239 ok((hr == S_OK && expect == TRUE) ||
240 (hr == S_FALSE && expect == FALSE),
241 "%04x -> %04x: got %08x expect conversion to be %spossible\n", simple_convert[src_idx].type,
242 simple_convert[dst_idx].type, hr, expect ? "" : "not ");
244 /* src DBTYPE_BYREF */
245 hr = IDataConvert_CanConvert(convert, simple_convert[src_idx].type | DBTYPE_BYREF, simple_convert[dst_idx].type);
246 expect = simple_expect;
247 ok((hr == S_OK && expect == TRUE) ||
248 (hr == S_FALSE && expect == FALSE),
249 "%04x -> %04x: got %08x expect conversion to be %spossible\n", simple_convert[src_idx].type | DBTYPE_BYREF,
250 simple_convert[dst_idx].type, hr, expect ? "" : "not ");
252 /* dst DBTYPE_BYREF */
253 hr = IDataConvert_CanConvert(convert, simple_convert[src_idx].type, simple_convert[dst_idx].type | DBTYPE_BYREF);
254 expect = FALSE;
255 if(simple_expect &&
256 (simple_convert[dst_idx].type == DBTYPE_BYTES ||
257 simple_convert[dst_idx].type == DBTYPE_STR ||
258 simple_convert[dst_idx].type == DBTYPE_WSTR))
259 expect = TRUE;
260 ok((hr == S_OK && expect == TRUE) ||
261 (hr == S_FALSE && expect == FALSE),
262 "%04x -> %04x: got %08x expect conversion to be %spossible\n", simple_convert[src_idx].type,
263 simple_convert[dst_idx].type | DBTYPE_BYREF, hr, expect ? "" : "not ");
265 /* src & dst DBTYPE_BYREF */
266 hr = IDataConvert_CanConvert(convert, simple_convert[src_idx].type | DBTYPE_BYREF, simple_convert[dst_idx].type | DBTYPE_BYREF);
267 expect = FALSE;
268 if(simple_expect &&
269 (simple_convert[dst_idx].type == DBTYPE_BYTES ||
270 simple_convert[dst_idx].type == DBTYPE_STR ||
271 simple_convert[dst_idx].type == DBTYPE_WSTR))
272 expect = TRUE;
273 ok((hr == S_OK && expect == TRUE) ||
274 (hr == S_FALSE && expect == FALSE),
275 "%04x -> %04x: got %08x expect conversion to be %spossible\n", simple_convert[src_idx].type | DBTYPE_BYREF,
276 simple_convert[dst_idx].type | DBTYPE_BYREF, hr, expect ? "" : "not ");
278 /* src DBTYPE_ARRAY */
279 hr = IDataConvert_CanConvert(convert, simple_convert[src_idx].type | DBTYPE_ARRAY, simple_convert[dst_idx].type);
280 expect = FALSE;
281 if(array_type(simple_convert[src_idx].type) && simple_convert[dst_idx].type == DBTYPE_VARIANT)
282 expect = TRUE;
283 ok((hr == S_OK && expect == TRUE) ||
284 (hr == S_FALSE && expect == FALSE),
285 "%04x -> %04x: got %08x expect conversion to be %spossible\n", simple_convert[src_idx].type | DBTYPE_ARRAY,
286 simple_convert[dst_idx].type, hr, expect ? "" : "not ");
288 /* dst DBTYPE_ARRAY */
289 hr = IDataConvert_CanConvert(convert, simple_convert[src_idx].type, simple_convert[dst_idx].type | DBTYPE_ARRAY);
290 expect = FALSE;
291 if(array_type(simple_convert[dst_idx].type) &&
292 (simple_convert[src_idx].type == DBTYPE_IDISPATCH ||
293 simple_convert[src_idx].type == DBTYPE_VARIANT))
294 expect = TRUE;
295 ok((hr == S_OK && expect == TRUE) ||
296 (hr == S_FALSE && expect == FALSE),
297 "%04x -> %04x: got %08x expect conversion to be %spossible\n", simple_convert[src_idx].type,
298 simple_convert[dst_idx].type | DBTYPE_ARRAY, hr, expect ? "" : "not ");
300 /* src & dst DBTYPE_ARRAY */
301 hr = IDataConvert_CanConvert(convert, simple_convert[src_idx].type | DBTYPE_ARRAY, simple_convert[dst_idx].type | DBTYPE_ARRAY);
302 expect = FALSE;
303 if(array_type(simple_convert[src_idx].type) &&
304 simple_convert[src_idx].type == simple_convert[dst_idx].type)
305 expect = TRUE;
306 ok((hr == S_OK && expect == TRUE) ||
307 (hr == S_FALSE && expect == FALSE),
308 "%04x -> %04x: got %08x expect conversion to be %spossible\n", simple_convert[src_idx].type | DBTYPE_ARRAY,
309 simple_convert[dst_idx].type | DBTYPE_ARRAY, hr, expect ? "" : "not ");
311 /* src DBTYPE_VECTOR */
312 hr = IDataConvert_CanConvert(convert, simple_convert[src_idx].type | DBTYPE_VECTOR, simple_convert[dst_idx].type);
313 expect = FALSE;
314 ok((hr == S_OK && expect == TRUE) ||
315 (hr == S_FALSE && expect == FALSE),
316 "%04x -> %04x: got %08x expect conversion to be %spossible\n", simple_convert[src_idx].type | DBTYPE_VECTOR,
317 simple_convert[dst_idx].type, hr, expect ? "" : "not ");
319 /* dst DBTYPE_VECTOR */
320 hr = IDataConvert_CanConvert(convert, simple_convert[src_idx].type, simple_convert[dst_idx].type | DBTYPE_VECTOR);
321 expect = FALSE;
322 ok((hr == S_OK && expect == TRUE) ||
323 (hr == S_FALSE && expect == FALSE),
324 "%04x -> %04x: got %08x expect conversion to be %spossible\n", simple_convert[src_idx].type,
325 simple_convert[dst_idx].type | DBTYPE_VECTOR, hr, expect ? "" : "not ");
327 /* src & dst DBTYPE_VECTOR */
328 hr = IDataConvert_CanConvert(convert, simple_convert[src_idx].type | DBTYPE_VECTOR, simple_convert[dst_idx].type | DBTYPE_VECTOR);
329 expect = FALSE;
330 ok((hr == S_OK && expect == TRUE) ||
331 (hr == S_FALSE && expect == FALSE),
332 "%04x -> %04x: got %08x expect conversion to be %spossible\n", simple_convert[src_idx].type | DBTYPE_VECTOR,
333 simple_convert[dst_idx].type | DBTYPE_VECTOR, hr, expect ? "" : "not ");
338 IDataConvert_Release(convert);
341 START_TEST(convert)
343 OleInitialize(NULL);
344 test_dcinfo();
345 test_canconvert();
346 OleUninitialize();