ReactOS 0.4.15-dev-7942-gd23573b
db.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2005 Mike McCormack for CodeWeavers
3 *
4 * A test program for MSI database files.
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21#define COBJMACROS
22
23#include <stdio.h>
24
25#include <windows.h>
26#include <objidl.h>
27#include <msi.h>
28#include <msidefs.h>
29#include <msiquery.h>
30
31#include "wine/test.h"
32
33static const char *msifile = "winetest-db.msi";
34static const char *msifile2 = "winetst2-db.msi";
35static const char *mstfile = "winetst-db.mst";
36static const WCHAR msifileW[] = L"winetest-db.msi";
37static const WCHAR msifile2W[] = L"winetst2-db.msi";
38
39static void WINAPIV check_record_(int line, MSIHANDLE rec, UINT count, ...)
40{
42 UINT i;
43
44 ok_(__FILE__, line)(count == MsiRecordGetFieldCount(rec),
45 "expected %u fields, got %u\n", count, MsiRecordGetFieldCount(rec));
46
48
49 for (i = 1; i <= count; ++i)
50 {
51 const char *expect = va_arg(args, const char *);
52 char buffer[200] = "x";
53 DWORD sz = sizeof(buffer);
54 UINT r = MsiRecordGetStringA(rec, i, buffer, &sz);
55 ok_(__FILE__, line)(r == ERROR_SUCCESS, "field %u: got unexpected error %u\n", i, r);
56 ok_(__FILE__, line)(!strcmp(buffer, expect),
57 "field %u: expected \"%s\", got \"%s\"\n", i, expect, buffer);
58 }
59
60 va_end(args);
61}
62#define check_record(rec, ...) check_record_(__LINE__, rec, __VA_ARGS__)
63
64static void test_msidatabase(void)
65{
66 MSIHANDLE hdb = 0, hdb2 = 0;
68 DWORD len;
69 UINT res;
70
72
74 ok( res == ERROR_OPEN_FAILED, "expected failure\n");
75
76 res = MsiOpenDatabaseW( msifileW, (LPWSTR)0xff, &hdb );
77 ok( res == ERROR_INVALID_PARAMETER, "expected failure\n");
78
79 res = MsiCloseHandle( hdb );
80 ok( res == ERROR_SUCCESS , "Failed to close database\n" );
81
82 /* create an empty database */
84 ok( res == ERROR_SUCCESS , "Failed to create database\n" );
85
86 res = MsiDatabaseCommit( hdb );
87 ok( res == ERROR_SUCCESS , "Failed to commit database\n" );
88
89 ok( GetFileAttributesA( msifile ) != INVALID_FILE_ATTRIBUTES, "database should exist\n");
90
91 res = MsiCloseHandle( hdb );
92 ok( res == ERROR_SUCCESS , "Failed to close database\n" );
94 ok( res == ERROR_SUCCESS , "Failed to open database\n" );
95
96 ok( GetFileAttributesA( msifile2 ) != INVALID_FILE_ATTRIBUTES, "database should exist\n");
97
98 res = MsiDatabaseCommit( hdb2 );
99 ok( res == ERROR_SUCCESS , "Failed to commit database\n" );
100
101 res = MsiCloseHandle( hdb2 );
102 ok( res == ERROR_SUCCESS , "Failed to close database\n" );
103
105 ok( res == ERROR_SUCCESS , "Failed to open database\n" );
106
107 res = MsiCloseHandle( hdb2 );
108 ok( res == ERROR_SUCCESS , "Failed to close database\n" );
109
110 ok( GetFileAttributesA( msifile2 ) == INVALID_FILE_ATTRIBUTES, "uncommitted database should not exist\n");
111
113 ok( res == ERROR_SUCCESS , "Failed to close database\n" );
114
115 res = MsiDatabaseCommit( hdb2 );
116 ok( res == ERROR_SUCCESS , "Failed to commit database\n" );
117
118 res = MsiCloseHandle( hdb2 );
119 ok( res == ERROR_SUCCESS , "Failed to close database\n" );
120
121 ok( GetFileAttributesA( msifile2 ) != INVALID_FILE_ATTRIBUTES, "committed database should exist\n");
122
124 ok( res == ERROR_SUCCESS , "Failed to open database\n" );
125
126 res = MsiDatabaseCommit( hdb );
127 ok( res == ERROR_SUCCESS , "Failed to commit database\n" );
128
129 res = MsiCloseHandle( hdb );
130 ok( res == ERROR_SUCCESS , "Failed to close database\n" );
131
133 ok( res == ERROR_SUCCESS , "Failed to open database\n" );
134
135 res = MsiCloseHandle( hdb );
136 ok( res == ERROR_SUCCESS , "Failed to close database\n" );
137
139 ok( res == ERROR_SUCCESS , "Failed to open database\n" );
140
141 res = MsiCloseHandle( hdb );
142 ok( res == ERROR_SUCCESS , "Failed to close database\n" );
143 ok( GetFileAttributesA( msifile ) != INVALID_FILE_ATTRIBUTES, "database should exist\n");
144
145 /* MSIDBOPEN_CREATE deletes the database if MsiCommitDatabase isn't called */
147 ok( res == ERROR_SUCCESS , "Failed to open database\n" );
148
149 ok( GetFileAttributesA( msifile ) != INVALID_FILE_ATTRIBUTES, "database should exist\n");
150
151 res = MsiCloseHandle( hdb );
152 ok( res == ERROR_SUCCESS , "Failed to close database\n" );
153
154 ok( GetFileAttributesA( msifile ) == INVALID_FILE_ATTRIBUTES, "database should exist\n");
155
157 ok( res == ERROR_SUCCESS , "Failed to open database\n" );
158
159 res = MsiDatabaseCommit( hdb );
160 ok( res == ERROR_SUCCESS , "Failed to commit database\n" );
161
162 ok( GetFileAttributesA( msifile ) != INVALID_FILE_ATTRIBUTES, "database should exist\n");
163
164 res = MsiCloseHandle( hdb );
165 ok( res == ERROR_SUCCESS , "Failed to close database\n" );
166
168 ok ( res, "Got zero res.\n" );
169 lstrcatW( path, L"\\");
171 len = lstrlenW(path);
172 path[len - 4] = 0;
173
175 ok( res != ERROR_SUCCESS , "Got unexpected res %u.\n", res );
176
178 path[lstrlenW(path) - 4] = 0;
179
181 ok( res != ERROR_SUCCESS , "Got unexpected res %u.\n", res );
182
184 ok( res == TRUE, "Failed to delete database\n" );
185
187 ok( res == TRUE, "Failed to delete database\n" );
188}
189
190static UINT do_query(MSIHANDLE hdb, const char *query, MSIHANDLE *phrec)
191{
192 MSIHANDLE hview = 0;
193 UINT r, ret;
194
195 if (phrec)
196 *phrec = 0;
197
198 /* open a select query */
199 r = MsiDatabaseOpenViewA(hdb, query, &hview);
200 if (r != ERROR_SUCCESS)
201 return r;
202 r = MsiViewExecute(hview, 0);
203 if (r != ERROR_SUCCESS)
204 return r;
205 ret = MsiViewFetch(hview, phrec);
206 r = MsiViewClose(hview);
207 if (r != ERROR_SUCCESS)
208 return r;
209 r = MsiCloseHandle(hview);
210 if (r != ERROR_SUCCESS)
211 return r;
212 return ret;
213}
214
215static UINT run_query( MSIHANDLE hdb, MSIHANDLE hrec, const char *query )
216{
217 MSIHANDLE hview = 0;
218 UINT r;
219
220 r = MsiDatabaseOpenViewA(hdb, query, &hview);
221 if( r != ERROR_SUCCESS )
222 return r;
223
224 r = MsiViewExecute(hview, hrec);
225 if( r == ERROR_SUCCESS )
226 r = MsiViewClose(hview);
227 MsiCloseHandle(hview);
228 return r;
229}
230
231static UINT run_queryW( MSIHANDLE hdb, MSIHANDLE hrec, const WCHAR *query )
232{
233 MSIHANDLE hview = 0;
234 UINT r;
235
236 r = MsiDatabaseOpenViewW(hdb, query, &hview);
237 if( r != ERROR_SUCCESS )
238 return r;
239
240 r = MsiViewExecute(hview, hrec);
241 if( r == ERROR_SUCCESS )
242 r = MsiViewClose(hview);
243 MsiCloseHandle(hview);
244 return r;
245}
246
248{
249 UINT r = run_query( hdb, 0,
250 "CREATE TABLE `Component` ( "
251 "`Component` CHAR(72) NOT NULL, "
252 "`ComponentId` CHAR(38), "
253 "`Directory_` CHAR(72) NOT NULL, "
254 "`Attributes` SHORT NOT NULL, "
255 "`Condition` CHAR(255), "
256 "`KeyPath` CHAR(72) "
257 "PRIMARY KEY `Component`)" );
258 ok(r == ERROR_SUCCESS, "Failed to create Component table: %u\n", r);
259 return r;
260}
261
263{
264 UINT r = run_query( hdb, 0,
265 "CREATE TABLE `CustomAction` ( "
266 "`Action` CHAR(72) NOT NULL, "
267 "`Type` SHORT NOT NULL, "
268 "`Source` CHAR(72), "
269 "`Target` CHAR(255) "
270 "PRIMARY KEY `Action`)" );
271 ok(r == ERROR_SUCCESS, "Failed to create CustomAction table: %u\n", r);
272 return r;
273}
274
276{
277 UINT r = run_query( hdb, 0,
278 "CREATE TABLE `Directory` ( "
279 "`Directory` CHAR(255) NOT NULL, "
280 "`Directory_Parent` CHAR(255), "
281 "`DefaultDir` CHAR(255) NOT NULL "
282 "PRIMARY KEY `Directory`)" );
283 ok(r == ERROR_SUCCESS, "Failed to create Directory table: %u\n", r);
284 return r;
285}
286
288{
289 UINT r = run_query( hdb, 0,
290 "CREATE TABLE `FeatureComponents` ( "
291 "`Feature_` CHAR(38) NOT NULL, "
292 "`Component_` CHAR(72) NOT NULL "
293 "PRIMARY KEY `Feature_`, `Component_` )" );
294 ok(r == ERROR_SUCCESS, "Failed to create FeatureComponents table: %u\n", r);
295 return r;
296}
297
299{
300 UINT r = run_query( hdb, 0,
301 "CREATE TABLE `StdDlls` ( "
302 "`File` CHAR(255) NOT NULL, "
303 "`Binary_` CHAR(72) NOT NULL "
304 "PRIMARY KEY `File` )" );
305 ok(r == ERROR_SUCCESS, "Failed to create StdDlls table: %u\n", r);
306 return r;
307}
308
310{
311 UINT r = run_query( hdb, 0,
312 "CREATE TABLE `Binary` ( "
313 "`Name` CHAR(72) NOT NULL, "
314 "`Data` CHAR(72) NOT NULL "
315 "PRIMARY KEY `Name` )" );
316 ok(r == ERROR_SUCCESS, "Failed to create Binary table: %u\n", r);
317 return r;
318}
319
320static inline UINT add_entry(const char *file, int line, const char *type, MSIHANDLE hdb, const char *values, const char *insert)
321{
322 char *query;
323 UINT sz, r;
324
325 sz = strlen(values) + strlen(insert) + 1;
326 query = malloc(sz);
328 r = run_query(hdb, 0, query);
329 free(query);
330 ok_(file, line)(r == ERROR_SUCCESS, "failed to insert into %s table: %u\n", type, r);
331 return r;
332}
333
334#define add_component_entry(hdb, values) add_entry(__FILE__, __LINE__, "Component", hdb, values, \
335 "INSERT INTO `Component` " \
336 "(`Component`, `ComponentId`, `Directory_`, " \
337 "`Attributes`, `Condition`, `KeyPath`) VALUES( %s )")
338
339#define add_custom_action_entry(hdb, values) add_entry(__FILE__, __LINE__, "CustomAction", hdb, values, \
340 "INSERT INTO `CustomAction` " \
341 "(`Action`, `Type`, `Source`, `Target`) VALUES( %s )")
342
343#define add_feature_components_entry(hdb, values) add_entry(__FILE__, __LINE__, "FeatureComponents", hdb, values, \
344 "INSERT INTO `FeatureComponents` " \
345 "(`Feature_`, `Component_`) VALUES( %s )")
346
347#define add_std_dlls_entry(hdb, values) add_entry(__FILE__, __LINE__, "StdDlls", hdb, values, \
348 "INSERT INTO `StdDlls` (`File`, `Binary_`) VALUES( %s )")
349
350#define add_binary_entry(hdb, values) add_entry(__FILE__, __LINE__, "Binary", hdb, values, \
351 "INSERT INTO `Binary` (`Name`, `Data`) VALUES( %s )")
352
353static void test_msiinsert(void)
354{
355 MSIHANDLE hdb = 0, hview = 0, hview2 = 0, hrec = 0;
356 UINT r;
357 const char *query;
358 char buf[80];
359 DWORD sz;
360
362
363 /* just MsiOpenDatabase should not create a file */
365 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n");
366
367 /* create a table */
368 query = "CREATE TABLE `phone` ( "
369 "`id` INT, `name` CHAR(32), `number` CHAR(32) "
370 "PRIMARY KEY `id`)";
371 r = MsiDatabaseOpenViewA(hdb, query, &hview);
372 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
373 r = MsiViewExecute(hview, 0);
374 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
375 r = MsiViewClose(hview);
376 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
377 r = MsiCloseHandle(hview);
378 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
379
380 query = "SELECT * FROM phone WHERE number = '8675309'";
381 r = MsiDatabaseOpenViewA(hdb, query, &hview2);
382 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
383 r = MsiViewExecute(hview2, 0);
384 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
385 r = MsiViewFetch(hview2, &hrec);
386 ok(r == ERROR_NO_MORE_ITEMS, "MsiViewFetch produced items\n");
387
388 /* insert a value into it */
389 query = "INSERT INTO `phone` ( `id`, `name`, `number` )"
390 "VALUES('1', 'Abe', '8675309')";
391 r = MsiDatabaseOpenViewA(hdb, query, &hview);
392 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
393 r = MsiViewExecute(hview, 0);
394 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
395 r = MsiViewClose(hview);
396 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
397 r = MsiCloseHandle(hview);
398 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
399
400 r = MsiViewFetch(hview2, &hrec);
401 ok(r == ERROR_NO_MORE_ITEMS, "MsiViewFetch produced items\n");
402 r = MsiViewExecute(hview2, 0);
403 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
404 r = MsiViewFetch(hview2, &hrec);
405 ok(r == ERROR_SUCCESS, "MsiViewFetch failed: %u\n", r);
406
407 r = MsiCloseHandle(hrec);
408 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
409 r = MsiViewClose(hview2);
410 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
411 r = MsiCloseHandle(hview2);
412 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
413
414 query = "SELECT * FROM `phone` WHERE `id` = 1";
415 r = do_query(hdb, query, &hrec);
416 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
417
418 /* check the record contains what we put in it */
420 ok(r == 3, "record count wrong\n");
421
422 r = MsiRecordIsNull(hrec, 0);
423 ok(r == FALSE, "field 0 not null\n");
424
425 r = MsiRecordGetInteger(hrec, 1);
426 ok(r == 1, "field 1 contents wrong\n");
427 sz = sizeof buf;
428 r = MsiRecordGetStringA(hrec, 2, buf, &sz);
429 ok(r == ERROR_SUCCESS, "field 2 content fetch failed\n");
430 ok(!strcmp(buf,"Abe"), "field 2 content incorrect\n");
431 sz = sizeof buf;
432 r = MsiRecordGetStringA(hrec, 3, buf, &sz);
433 ok(r == ERROR_SUCCESS, "field 3 content fetch failed\n");
434 ok(!strcmp(buf,"8675309"), "field 3 content incorrect\n");
435
436 r = MsiCloseHandle(hrec);
437 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
438
439 /* open a select query */
440 hrec = 100;
441 query = "SELECT * FROM `phone` WHERE `id` >= 10";
442 r = do_query(hdb, query, &hrec);
443 ok(r == ERROR_NO_MORE_ITEMS, "MsiViewFetch failed\n");
444 ok(hrec == 0, "hrec should be null\n");
445
446 r = MsiCloseHandle(hrec);
447 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
448
449 query = "SELECT * FROM `phone` WHERE `id` < 0";
450 r = do_query(hdb, query, &hrec);
451 ok(r == ERROR_NO_MORE_ITEMS, "MsiViewFetch failed\n");
452
453 query = "SELECT * FROM `phone` WHERE `id` <= 0";
454 r = do_query(hdb, query, &hrec);
455 ok(r == ERROR_NO_MORE_ITEMS, "MsiViewFetch failed\n");
456
457 query = "SELECT * FROM `phone` WHERE `id` <> 1";
458 r = do_query(hdb, query, &hrec);
459 ok(r == ERROR_NO_MORE_ITEMS, "MsiViewFetch failed\n");
460
461 query = "SELECT * FROM `phone` WHERE `id` > 10";
462 r = do_query(hdb, query, &hrec);
463 ok(r == ERROR_NO_MORE_ITEMS, "MsiViewFetch failed\n");
464
465 /* now try a few bad INSERT xqueries */
466 query = "INSERT INTO `phone` ( `id`, `name`, `number` )"
467 "VALUES(?, ?)";
468 r = MsiDatabaseOpenViewA(hdb, query, &hview);
469 ok(r == ERROR_BAD_QUERY_SYNTAX, "MsiDatabaseOpenView failed\n");
470
471 /* construct a record to insert */
472 hrec = MsiCreateRecord(4);
473 r = MsiRecordSetInteger(hrec, 1, 2);
474 ok(r == ERROR_SUCCESS, "MsiRecordSetInteger failed\n");
475 r = MsiRecordSetStringA(hrec, 2, "Adam");
476 ok(r == ERROR_SUCCESS, "MsiRecordSetString failed\n");
477 r = MsiRecordSetStringA(hrec, 3, "96905305");
478 ok(r == ERROR_SUCCESS, "MsiRecordSetString failed\n");
479
480 /* insert another value, using a record and wildcards */
481 query = "INSERT INTO `phone` ( `id`, `name`, `number` )"
482 "VALUES(?, ?, ?)";
483 r = MsiDatabaseOpenViewA(hdb, query, &hview);
484 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
485
486 if (r == ERROR_SUCCESS)
487 {
488 r = MsiViewExecute(hview, hrec);
489 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
490 r = MsiViewClose(hview);
491 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
492 r = MsiCloseHandle(hview);
493 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
494 }
495 r = MsiCloseHandle(hrec);
496 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
497
498 r = MsiViewFetch(0, NULL);
499 ok(r == ERROR_INVALID_PARAMETER, "MsiViewFetch failed\n");
500
501 r = MsiDatabaseCommit(hdb);
502 ok(r == ERROR_SUCCESS, "MsiDatabaseCommit failed\n");
503
504 r = MsiCloseHandle(hdb);
505 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
506
508 ok(r == TRUE, "file didn't exist after commit\n");
509}
510
511static void test_msidecomposedesc(void)
512{
513 UINT (WINAPI *pMsiDecomposeDescriptorA)(LPCSTR, LPCSTR, LPSTR, LPSTR, DWORD *);
515 const char *desc;
516 UINT r;
517 DWORD len;
519
520 hmod = GetModuleHandleA("msi.dll");
521 pMsiDecomposeDescriptorA = (void*)GetProcAddress(hmod, "MsiDecomposeDescriptorA");
522 if (!pMsiDecomposeDescriptorA)
523 return;
524
525 /* test a valid feature descriptor */
526 desc = "']gAVn-}f(ZXfeAR6.jiFollowTheWhiteRabbit>3w2x^IGfe?CxI5heAvk.";
527 len = 0;
528 prod[0] = feature[0] = comp[0] = 0;
529 r = pMsiDecomposeDescriptorA(desc, prod, feature, comp, &len);
530 ok(r == ERROR_SUCCESS, "returned an error\n");
531 ok(len == strlen(desc), "length was wrong\n");
532 ok(strcmp(prod,"{90110409-6000-11D3-8CFE-0150048383C9}")==0, "product wrong\n");
533 ok(strcmp(feature,"FollowTheWhiteRabbit")==0, "feature wrong\n");
534 ok(strcmp(comp,"{A7CD68DB-EF74-49C8-FBB2-A7C463B2AC24}")==0,"component wrong\n");
535
536 /* test an invalid feature descriptor with too many characters */
537 desc = "']gAVn-}f(ZXfeAR6.ji"
538 "ThisWillFailIfTheresMoreThanAGuidsChars>"
539 "3w2x^IGfe?CxI5heAvk.";
540 len = 0;
541 r = pMsiDecomposeDescriptorA(desc, prod, feature, comp, &len);
542 ok(r == ERROR_INVALID_PARAMETER, "returned wrong error\n");
543
544 /* test a feature descriptor with < instead of > */
545 desc = "']gAVn-}f(ZXfeAR6.jiFollowTheWhiteRabbit<3w2x^IGfe?CxI5heAvk.";
546 len = 0;
547 prod[0] = feature[0] = 0;
548 comp[0] = 0x55;
549 r = pMsiDecomposeDescriptorA(desc, prod, feature, comp, &len);
550 ok(r == ERROR_SUCCESS, "returned an error\n");
551 ok(len == 41, "got %lu\n", len);
552 ok(!strcmp(prod,"{90110409-6000-11D3-8CFE-0150048383C9}"), "got '%s'\n", prod);
553 ok(!strcmp(feature,"FollowTheWhiteRabbit"), "got '%s'\n", feature);
554 ok(!comp[0], "got '%s'\n", comp);
555
556 len = 0;
557 prod[0] = feature[0] = 0;
558 comp[0] = 0x55;
559 r = pMsiDecomposeDescriptorA("yh1BVN)8A$!!!!!MKKSkAlwaysInstalledIntl_1033<", prod, feature, comp, &len);
560 ok(r == ERROR_SUCCESS, "got %u\n", r);
561 ok(len == 45, "got %lu\n", len);
562 ok(!strcmp(prod, "{90150000-006E-0409-0000-0000000FF1CE}"), "got '%s'\n", prod);
563 ok(!strcmp(feature, "AlwaysInstalledIntl_1033"), "got '%s'\n", feature);
564 ok(!comp[0], "got '%s'\n", comp);
565
566 /*
567 * Test a valid feature descriptor with the
568 * maximum number of characters and some trailing characters.
569 */
570 desc = "']gAVn-}f(ZXfeAR6.ji"
571 "ThisWillWorkIfTheresLTEThanAGuidsChars>"
572 "3w2x^IGfe?CxI5heAvk."
573 "extra";
574 len = 0;
575 r = pMsiDecomposeDescriptorA(desc, prod, feature, comp, &len);
576 ok(r == ERROR_SUCCESS, "returned wrong error\n");
577 ok(len == (strlen(desc) - strlen("extra")), "length wrong\n");
578
579 len = 0;
580 r = pMsiDecomposeDescriptorA(desc, prod, feature, NULL, &len);
581 ok(r == ERROR_SUCCESS, "returned wrong error\n");
582 ok(len == (strlen(desc) - strlen("extra")), "length wrong\n");
583
584 len = 0;
585 r = pMsiDecomposeDescriptorA(desc, prod, NULL, NULL, &len);
586 ok(r == ERROR_SUCCESS, "returned wrong error\n");
587 ok(len == (strlen(desc) - strlen("extra")), "length wrong\n");
588
589 len = 0;
590 r = pMsiDecomposeDescriptorA(desc, NULL, NULL, NULL, &len);
591 ok(r == ERROR_SUCCESS, "returned wrong error\n");
592 ok(len == (strlen(desc) - strlen("extra")), "length wrong\n");
593
594 len = 0;
595 r = pMsiDecomposeDescriptorA(NULL, NULL, NULL, NULL, &len);
596 ok(r == ERROR_INVALID_PARAMETER, "returned wrong error\n");
597 ok(len == 0, "length wrong\n");
598
599 r = pMsiDecomposeDescriptorA(desc, NULL, NULL, NULL, NULL);
600 ok(r == ERROR_SUCCESS, "returned wrong error\n");
601}
602
603static UINT try_query_param( MSIHANDLE hdb, LPCSTR szQuery, MSIHANDLE hrec )
604{
605 MSIHANDLE htab = 0;
606 UINT res;
607
608 res = MsiDatabaseOpenViewA( hdb, szQuery, &htab );
609 if(res == ERROR_SUCCESS )
610 {
611 UINT r;
612
613 r = MsiViewExecute( htab, hrec );
614 if(r != ERROR_SUCCESS )
615 res = r;
616
617 r = MsiViewClose( htab );
618 if(r != ERROR_SUCCESS )
619 res = r;
620
621 r = MsiCloseHandle( htab );
622 if(r != ERROR_SUCCESS )
623 res = r;
624 }
625 return res;
626}
627
628static UINT try_query( MSIHANDLE hdb, LPCSTR szQuery )
629{
630 return try_query_param( hdb, szQuery, 0 );
631}
632
633static UINT try_insert_query( MSIHANDLE hdb, LPCSTR szQuery )
634{
635 MSIHANDLE hrec = 0;
636 UINT r;
637
638 hrec = MsiCreateRecord( 1 );
639 MsiRecordSetStringA( hrec, 1, "Hello");
640
641 r = try_query_param( hdb, szQuery, hrec );
642
643 MsiCloseHandle( hrec );
644 return r;
645}
646
647static void test_msibadqueries(void)
648{
649 MSIHANDLE hdb = 0;
650 UINT r;
651
653
654 /* just MsiOpenDatabase should not create a file */
656 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n");
657
658 r = MsiDatabaseCommit( hdb );
659 ok(r == ERROR_SUCCESS , "Failed to commit database\n");
660
661 r = MsiCloseHandle( hdb );
662 ok(r == ERROR_SUCCESS , "Failed to close database\n");
663
664 /* open it readonly */
666 ok(r == ERROR_SUCCESS , "Failed to open database r/o\n");
667
668 /* add a table to it */
669 r = try_query( hdb, "select * from _Tables");
670 ok(r == ERROR_SUCCESS , "query 1 failed\n");
671
672 r = MsiCloseHandle( hdb );
673 ok(r == ERROR_SUCCESS , "Failed to close database r/o\n");
674
675 /* open it read/write */
677 ok(r == ERROR_SUCCESS , "Failed to open database r/w\n");
678
679 /* a bunch of test queries that fail with the native MSI */
680
681 r = try_query( hdb, "CREATE TABLE");
682 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2a return code\n");
683
684 r = try_query( hdb, "CREATE TABLE `a`");
685 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2b return code\n");
686
687 r = try_query( hdb, "CREATE TABLE `a` ()");
688 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2c return code\n");
689
690 r = try_query( hdb, "CREATE TABLE `a` (`b`)");
691 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2d return code\n");
692
693 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(72) )");
694 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2e return code\n");
695
696 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(72) NOT NULL)");
697 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2f return code\n");
698
699 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(72) NOT NULL PRIMARY)");
700 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2g return code\n");
701
702 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(72) NOT NULL PRIMARY KEY)");
703 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2h return code\n");
704
705 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(72) NOT NULL PRIMARY KEY)");
706 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2i return code\n");
707
708 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(72) NOT NULL PRIMARY KEY 'b')");
709 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2j return code\n");
710
711 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(72) NOT NULL PRIMARY KEY `b')");
712 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2k return code\n");
713
714 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(72) NOT NULL PRIMARY KEY `b')");
715 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2l return code\n");
716
717 r = try_query( hdb, "CREATE TABLE `a` (`b` CHA(72) NOT NULL PRIMARY KEY `b`)");
718 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2m return code\n");
719
720 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(-1) NOT NULL PRIMARY KEY `b`)");
721 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2n return code\n");
722
723 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(720) NOT NULL PRIMARY KEY `b`)");
724 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2o return code\n");
725
726 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(72) NOT NULL KEY `b`)");
727 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2p return code\n");
728
729 r = try_query( hdb, "CREATE TABLE `a` (`` CHAR(72) NOT NULL PRIMARY KEY `b`)");
730 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2p return code\n");
731
732 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(72) NOT NULL PRIMARY KEY `b`)");
733 ok(r == ERROR_SUCCESS , "valid query 2z failed\n");
734
735 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(72) NOT NULL PRIMARY KEY `b`)");
736 ok(r == ERROR_BAD_QUERY_SYNTAX , "created same table again\n");
737
738 r = try_query( hdb, "CREATE TABLE `aa` (`b` CHAR(72) NOT NULL, `c` "
739 "CHAR(72), `d` CHAR(255) NOT NULL LOCALIZABLE PRIMARY KEY `b`)");
740 ok(r == ERROR_SUCCESS , "query 4 failed\n");
741
742 r = MsiDatabaseCommit( hdb );
743 ok(r == ERROR_SUCCESS , "Failed to commit database after write\n");
744
745 r = try_query( hdb, "CREATE TABLE `blah` (`foo` CHAR(72) NOT NULL "
746 "PRIMARY KEY `foo`)");
747 ok(r == ERROR_SUCCESS , "query 4 failed\n");
748
749 r = try_insert_query( hdb, "insert into a ( `b` ) VALUES ( ? )");
750 ok(r == ERROR_SUCCESS , "failed to insert record in db\n");
751
752 r = MsiDatabaseCommit( hdb );
753 ok(r == ERROR_SUCCESS , "Failed to commit database after write\n");
754
755 r = try_query( hdb, "CREATE TABLE `boo` (`foo` CHAR(72) NOT NULL "
756 "PRIMARY KEY `ba`)");
757 ok(r != ERROR_SUCCESS , "query 5 succeeded\n");
758
759 r = try_query( hdb,"CREATE TABLE `bee` (`foo` CHAR(72) NOT NULL )");
760 ok(r != ERROR_SUCCESS , "query 6 succeeded\n");
761
762 r = try_query( hdb, "CREATE TABLE `temp` (`t` CHAR(72) NOT NULL "
763 "PRIMARY KEY `t`)");
764 ok(r == ERROR_SUCCESS , "query 7 failed\n");
765
766 r = try_query( hdb, "CREATE TABLE `c` (`b` CHAR NOT NULL PRIMARY KEY `b`)");
767 ok(r == ERROR_SUCCESS , "query 8 failed\n");
768
769 r = try_query( hdb, "select * from c");
770 ok(r == ERROR_SUCCESS , "query failed\n");
771
772 r = try_query( hdb, "select * from c where b = 'x");
773 ok(r == ERROR_BAD_QUERY_SYNTAX, "query failed\n");
774
775 r = try_query( hdb, "select * from c where b = 'x'");
776 ok(r == ERROR_SUCCESS, "query failed\n");
777
778 r = try_query( hdb, "select * from 'c'");
779 ok(r == ERROR_BAD_QUERY_SYNTAX, "query failed\n");
780
781 r = try_query( hdb, "select * from ''");
782 ok(r == ERROR_BAD_QUERY_SYNTAX, "query failed\n");
783
784 r = try_query( hdb, "select * from c where b = x");
785 ok(r == ERROR_BAD_QUERY_SYNTAX, "query failed\n");
786
787 r = try_query( hdb, "select * from c where b = \"x\"");
788 ok(r == ERROR_BAD_QUERY_SYNTAX, "query failed\n");
789
790 r = try_query( hdb, "select * from c where b = 'x'");
791 ok(r == ERROR_SUCCESS, "query failed\n");
792
793 r = try_query( hdb, "select * from c where b = '\"x'");
794 ok(r == ERROR_SUCCESS, "query failed\n");
795
796 if (0) /* FIXME: this query causes trouble with other tests */
797 {
798 r = try_query( hdb, "select * from c where b = '\\\'x'");
799 ok(r == ERROR_BAD_QUERY_SYNTAX, "query failed\n");
800 }
801
802 r = try_query( hdb, "select * from 'c'");
803 ok(r == ERROR_BAD_QUERY_SYNTAX, "query failed\n");
804
805 r = try_query( hdb, "select `c`.`b` from `c` order by `c`.`order`");
806 ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %u\n", r );
807
808 r = try_query( hdb, "select `c`.b` from `c`");
809 ok( r == ERROR_SUCCESS, "query failed: %u\n", r );
810
811 r = try_query( hdb, "select `c`.`b from `c`");
812 ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %u\n", r );
813
814 r = try_query( hdb, "select `c`.b from `c`");
815 ok( r == ERROR_SUCCESS, "query failed: %u\n", r );
816
817 r = try_query( hdb, "select `c.`b` from `c`");
818 ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %u\n", r );
819
820 r = try_query( hdb, "select c`.`b` from `c`");
821 ok( r == ERROR_SUCCESS, "query failed: %u\n", r );
822
823 r = try_query( hdb, "select c.`b` from `c`");
824 ok( r == ERROR_SUCCESS, "query failed: %u\n", r );
825
826 r = try_query( hdb, "select `c`.`b` from c`");
827 ok( r == ERROR_SUCCESS, "query failed: %u\n", r );
828
829 r = try_query( hdb, "select `c`.`b` from `c");
830 ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %u\n", r );
831
832 r = try_query( hdb, "select `c`.`b` from c");
833 ok( r == ERROR_SUCCESS, "query failed: %u\n", r );
834
835 r = try_query( hdb, "CREATE TABLE `\5a` (`b` CHAR NOT NULL PRIMARY KEY `b`)" );
836 ok( r == ERROR_SUCCESS , "query failed: %u\n", r );
837
838 r = try_query( hdb, "SELECT * FROM \5a" );
839 ok( r == ERROR_SUCCESS , "query failed: %u\n", r );
840
841 r = try_query( hdb, "CREATE TABLE `a\5` (`b` CHAR NOT NULL PRIMARY KEY `b`)" );
842 ok( r == ERROR_SUCCESS , "query failed: %u\n", r );
843
844 r = try_query( hdb, "SELECT * FROM a\5" );
845 ok( r == ERROR_SUCCESS , "query failed: %u\n", r );
846
847 r = try_query( hdb, "CREATE TABLE `-a` (`b` CHAR NOT NULL PRIMARY KEY `b`)" );
848 ok( r == ERROR_SUCCESS , "query failed: %u\n", r );
849
850 r = try_query( hdb, "SELECT * FROM -a" );
851 todo_wine ok( r == ERROR_SUCCESS , "query failed: %u\n", r );
852
853 r = try_query( hdb, "CREATE TABLE `a-` (`b` CHAR NOT NULL PRIMARY KEY `b`)" );
854 ok( r == ERROR_SUCCESS , "query failed: %u\n", r );
855
856 r = try_query( hdb, "SELECT * FROM a-" );
857 ok( r == ERROR_SUCCESS , "query failed: %u\n", r );
858
859 r = MsiCloseHandle( hdb );
860 ok(r == ERROR_SUCCESS , "Failed to close database transact\n");
861
862 r = DeleteFileA( msifile );
863 ok(r == TRUE, "file didn't exist after commit\n");
864}
865
866static void test_viewmodify(void)
867{
868 MSIHANDLE hdb = 0, hview = 0, hrec = 0;
869 UINT r;
871 const char *query;
872 char buffer[0x100];
873 DWORD sz;
874
876
877 /* just MsiOpenDatabase should not create a file */
879 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n");
880
881 query = "CREATE TABLE `phone` ( "
882 "`id` INT, `name` CHAR(32), `number` CHAR(32) "
883 "PRIMARY KEY `id`)";
884 r = run_query( hdb, 0, query );
885 ok(r == ERROR_SUCCESS, "query failed\n");
886
887 query = "CREATE TABLE `_Validation` ( "
888 "`Table` CHAR(32) NOT NULL, `Column` CHAR(32) NOT NULL, "
889 "`Nullable` CHAR(4) NOT NULL, `MinValue` INT, `MaxValue` INT, "
890 "`KeyTable` CHAR(255), `KeyColumn` SHORT, `Category` CHAR(32), "
891 "`Set` CHAR(255), `Description` CHAR(255) PRIMARY KEY `Table`, `Column`)";
892 r = run_query( hdb, 0, query );
893 ok(r == ERROR_SUCCESS, "query failed\n");
894
895 query = "INSERT INTO `_Validation` ( `Table`, `Column`, `Nullable` ) "
896 "VALUES('phone', 'id', 'N')";
897 r = run_query( hdb, 0, query );
898 ok(r == ERROR_SUCCESS, "query failed\n");
899
900 query = "SELECT * FROM `phone`";
901 r = MsiDatabaseOpenViewA(hdb, query, &hview);
902 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
903
904 /* check what the error function reports without doing anything */
905 sz = sizeof(buffer);
906 strcpy(buffer, "x");
907 err = MsiViewGetErrorA( hview, buffer, &sz );
908 ok(err == MSIDBERROR_NOERROR, "got %d\n", err);
909 ok(!buffer[0], "got \"%s\"\n", buffer);
910 ok(sz == 0, "got size %lu\n", sz);
911
912 r = MsiViewExecute(hview, 0);
913 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
914
915 /* try some invalid records */
916 r = MsiViewModify(hview, MSIMODIFY_INSERT, 0 );
917 ok(r == ERROR_INVALID_HANDLE, "MsiViewModify failed\n");
918 r = MsiViewModify(hview, -1, 0 );
919 ok(r == ERROR_INVALID_HANDLE, "MsiViewModify failed\n");
920
921 /* try an small record */
922 hrec = MsiCreateRecord(1);
923 r = MsiViewModify(hview, -1, hrec );
924 ok(r == ERROR_INVALID_DATA, "MsiViewModify failed\n");
925
926 sz = sizeof(buffer);
927 strcpy(buffer, "x");
928 err = MsiViewGetErrorA( hview, buffer, &sz );
929 ok(err == MSIDBERROR_NOERROR, "got %d\n", err);
930 ok(!buffer[0], "got \"%s\"\n", buffer);
931 ok(sz == 0, "got size %lu\n", sz);
932
933 r = MsiCloseHandle(hrec);
934 ok(r == ERROR_SUCCESS, "failed to close record\n");
935
936 /* insert a valid record */
937 hrec = MsiCreateRecord(3);
938
939 r = MsiRecordSetInteger(hrec, 1, 1);
940 ok(r == ERROR_SUCCESS, "failed to set integer\n");
941 r = MsiRecordSetStringA(hrec, 2, "bob");
942 ok(r == ERROR_SUCCESS, "failed to set string\n");
943 r = MsiRecordSetStringA(hrec, 3, "7654321");
944 ok(r == ERROR_SUCCESS, "failed to set string\n");
945
946 r = MsiViewExecute(hview, 0);
947 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
949 ok(r == ERROR_SUCCESS, "MsiViewModify failed\n");
950
951 /* validate it */
952 r = MsiViewExecute(hview, 0);
953 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
954
955 r = MsiViewModify(hview, MSIMODIFY_VALIDATE_NEW, hrec );
956 ok(r == ERROR_INVALID_DATA, "MsiViewModify failed %u\n", r);
957
958 sz = sizeof(buffer);
959 strcpy(buffer, "x");
960 err = MsiViewGetErrorA( hview, buffer, &sz );
961 ok(err == MSIDBERROR_DUPLICATEKEY, "got %d\n", err);
962 ok(!strcmp(buffer, "id"), "got \"%s\"\n", buffer);
963 ok(sz == 2, "got size %lu\n", sz);
964
965 /* insert the same thing again */
966 r = MsiViewExecute(hview, 0);
967 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
968
969 /* should fail ... */
971 ok(r == ERROR_FUNCTION_FAILED, "MsiViewModify failed\n");
972
973 /* try to merge the same record */
974 r = MsiViewExecute(hview, 0);
975 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
976 r = MsiViewModify(hview, MSIMODIFY_MERGE, hrec );
977 ok(r == ERROR_SUCCESS, "MsiViewModify failed\n");
978
979 r = MsiCloseHandle(hrec);
980 ok(r == ERROR_SUCCESS, "failed to close record\n");
981
982 /* try merging a new record */
983 hrec = MsiCreateRecord(3);
984
985 r = MsiRecordSetInteger(hrec, 1, 10);
986 ok(r == ERROR_SUCCESS, "failed to set integer\n");
987 r = MsiRecordSetStringA(hrec, 2, "pepe");
988 ok(r == ERROR_SUCCESS, "failed to set string\n");
989 r = MsiRecordSetStringA(hrec, 3, "7654321");
990 ok(r == ERROR_SUCCESS, "failed to set string\n");
991
992 r = MsiViewModify(hview, MSIMODIFY_MERGE, hrec );
993 ok(r == ERROR_SUCCESS, "MsiViewModify failed\n");
994 r = MsiViewExecute(hview, 0);
995 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
996
997 r = MsiCloseHandle(hrec);
998 ok(r == ERROR_SUCCESS, "failed to close record\n");
999
1000 r = MsiViewClose(hview);
1001 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
1002 r = MsiCloseHandle(hview);
1003 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
1004
1005 query = "SELECT * FROM `phone`";
1006 r = MsiDatabaseOpenViewA(hdb, query, &hview);
1007 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
1008
1009 r = MsiViewExecute(hview, 0);
1010 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
1011
1012 r = MsiViewFetch(hview, &hrec);
1013 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
1014 check_record(hrec, 3, "1", "bob", "7654321");
1015
1016 /* update the view, non-primary key */
1017 r = MsiRecordSetStringA(hrec, 3, "3141592");
1018 ok(r == ERROR_SUCCESS, "MsiRecordSetString failed\n");
1019
1020 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec);
1021 ok(r == ERROR_SUCCESS, "MsiViewModify failed\n");
1022
1023 /* do it again */
1024 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec);
1025 ok(r == ERROR_SUCCESS, "MsiViewModify failed: %d\n", r);
1026
1027 /* update the view, primary key */
1028 r = MsiRecordSetInteger(hrec, 1, 5);
1029 ok(r == ERROR_SUCCESS, "MsiRecordSetInteger failed\n");
1030
1031 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec);
1032 ok(r == ERROR_FUNCTION_FAILED, "MsiViewModify failed\n");
1033
1034 r = MsiCloseHandle(hrec);
1035 ok(r == ERROR_SUCCESS, "failed to close record\n");
1036
1037 r = MsiViewClose(hview);
1038 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
1039 r = MsiCloseHandle(hview);
1040 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
1041
1042 query = "SELECT * FROM `phone`";
1043 r = MsiDatabaseOpenViewA(hdb, query, &hview);
1044 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
1045
1046 r = MsiViewExecute(hview, 0);
1047 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
1048
1049 r = MsiViewFetch(hview, &hrec);
1050 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
1051 check_record(hrec, 3, "1", "bob", "3141592");
1052 r = MsiCloseHandle(hrec);
1053 ok(r == ERROR_SUCCESS, "failed to close record\n");
1054
1055 /* use a record that doesn't come from a view fetch */
1056 hrec = MsiCreateRecord(3);
1057 ok(hrec != 0, "MsiCreateRecord failed\n");
1058
1059 r = MsiRecordSetInteger(hrec, 1, 3);
1060 ok(r == ERROR_SUCCESS, "failed to set integer\n");
1061 r = MsiRecordSetStringA(hrec, 2, "jane");
1062 ok(r == ERROR_SUCCESS, "failed to set string\n");
1063 r = MsiRecordSetStringA(hrec, 3, "112358");
1064 ok(r == ERROR_SUCCESS, "failed to set string\n");
1065
1066 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec);
1067 ok(r == ERROR_FUNCTION_FAILED, "Expected ERROR_FUNCTION_FAILED, got %d\n", r);
1068
1069 r = MsiCloseHandle(hrec);
1070 ok(r == ERROR_SUCCESS, "failed to close record\n");
1071
1072 /* use a record that doesn't come from a view fetch, primary key matches */
1073 hrec = MsiCreateRecord(3);
1074 ok(hrec != 0, "MsiCreateRecord failed\n");
1075
1076 r = MsiRecordSetInteger(hrec, 1, 1);
1077 ok(r == ERROR_SUCCESS, "failed to set integer\n");
1078 r = MsiRecordSetStringA(hrec, 2, "jane");
1079 ok(r == ERROR_SUCCESS, "failed to set string\n");
1080 r = MsiRecordSetStringA(hrec, 3, "112358");
1081 ok(r == ERROR_SUCCESS, "failed to set string\n");
1082
1083 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec);
1084 ok(r == ERROR_FUNCTION_FAILED, "MsiViewModify failed\n");
1085
1086 r = MsiCloseHandle(hrec);
1087 ok(r == ERROR_SUCCESS, "failed to close record\n");
1088
1089 hrec = MsiCreateRecord(3);
1090
1091 r = MsiRecordSetInteger(hrec, 1, 2);
1092 ok(r == ERROR_SUCCESS, "failed to set integer\n");
1093 r = MsiRecordSetStringA(hrec, 2, "nick");
1094 ok(r == ERROR_SUCCESS, "failed to set string\n");
1095 r = MsiRecordSetStringA(hrec, 3, "141421");
1096 ok(r == ERROR_SUCCESS, "failed to set string\n");
1097
1098 r = MsiViewExecute(hview, 0);
1099 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
1101 ok(r == ERROR_SUCCESS, "MsiViewModify failed\n");
1102
1103 r = MsiCloseHandle(hrec);
1104 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
1105 r = MsiViewClose(hview);
1106 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
1107 r = MsiCloseHandle(hview);
1108 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
1109
1110 query = "SELECT * FROM `phone` WHERE `id` = 1";
1111 r = MsiDatabaseOpenViewA(hdb, query, &hview);
1112 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
1113 r = MsiViewExecute(hview, 0);
1114 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
1115 r = MsiViewFetch(hview, &hrec);
1116 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
1117
1118 /* change the id to match the second row */
1119 r = MsiRecordSetInteger(hrec, 1, 2);
1120 ok(r == ERROR_SUCCESS, "failed to set integer\n");
1121 r = MsiRecordSetStringA(hrec, 2, "jerry");
1122 ok(r == ERROR_SUCCESS, "failed to set string\n");
1123
1124 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec);
1125 ok(r == ERROR_FUNCTION_FAILED, "MsiViewModify failed\n");
1126
1127 r = MsiCloseHandle(hrec);
1128 ok(r == ERROR_SUCCESS, "failed to close record\n");
1129 r = MsiViewClose(hview);
1130 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
1131 r = MsiCloseHandle(hview);
1132 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
1133
1134 /* broader search */
1135 query = "SELECT * FROM `phone` ORDER BY `id`";
1136 r = MsiDatabaseOpenViewA(hdb, query, &hview);
1137 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
1138 r = MsiViewExecute(hview, 0);
1139 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
1140 r = MsiViewFetch(hview, &hrec);
1141 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
1142
1143 /* change the id to match the second row */
1144 r = MsiRecordSetInteger(hrec, 1, 2);
1145 ok(r == ERROR_SUCCESS, "failed to set integer\n");
1146 r = MsiRecordSetStringA(hrec, 2, "jerry");
1147 ok(r == ERROR_SUCCESS, "failed to set string\n");
1148
1149 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec);
1150 ok(r == ERROR_FUNCTION_FAILED, "MsiViewModify failed\n");
1151
1152 r = MsiCloseHandle(hrec);
1153 ok(r == ERROR_SUCCESS, "failed to close record\n");
1154 r = MsiViewClose(hview);
1155 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
1156 r = MsiCloseHandle(hview);
1157 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
1158
1159 r = MsiCloseHandle( hdb );
1160 ok(r == ERROR_SUCCESS, "MsiOpenDatabase close failed\n");
1161}
1162
1164{
1165 MSIHANDLE hdb = 0;
1166 UINT res;
1167
1169
1170 /* create an empty database */
1172 ok( res == ERROR_SUCCESS , "Failed to create database\n" );
1173 if( res != ERROR_SUCCESS )
1174 return hdb;
1175
1176 res = MsiDatabaseCommit( hdb );
1177 ok( res == ERROR_SUCCESS , "Failed to commit database\n" );
1178
1179 return hdb;
1180}
1181
1182static void test_getcolinfo(void)
1183{
1184 MSIHANDLE hdb, hview = 0, rec = 0;
1185 UINT r;
1186
1187 /* create an empty db */
1188 hdb = create_db();
1189 ok( hdb, "failed to create db\n");
1190
1191 /* tables should be present */
1192 r = MsiDatabaseOpenViewA(hdb, "select Name from _Tables", &hview);
1193 ok( r == ERROR_SUCCESS, "failed to open query\n");
1194
1195 r = MsiViewExecute(hview, 0);
1196 ok( r == ERROR_SUCCESS, "failed to execute query\n");
1197
1198 /* check that NAMES works */
1199 rec = 0;
1200 r = MsiViewGetColumnInfo( hview, MSICOLINFO_NAMES, &rec );
1201 ok( r == ERROR_SUCCESS, "failed to get names\n");
1202 check_record(rec, 1, "Name");
1203 r = MsiCloseHandle( rec );
1204 ok( r == ERROR_SUCCESS, "failed to close record handle\n");
1205
1206 /* check that TYPES works */
1207 rec = 0;
1208 r = MsiViewGetColumnInfo( hview, MSICOLINFO_TYPES, &rec );
1209 ok( r == ERROR_SUCCESS, "failed to get names\n");
1210 check_record(rec, 1, "s64");
1211 r = MsiCloseHandle( rec );
1212 ok( r == ERROR_SUCCESS, "failed to close record handle\n");
1213
1214 /* check that invalid values fail */
1215 rec = 0;
1216 r = MsiViewGetColumnInfo( hview, 100, &rec );
1217 ok( r == ERROR_INVALID_PARAMETER, "wrong error code\n");
1218 ok( rec == 0, "returned a record\n");
1219
1221 ok( r == ERROR_INVALID_PARAMETER, "wrong error code\n");
1222
1224 ok( r == ERROR_INVALID_HANDLE, "wrong error code\n");
1225
1226 r = MsiViewClose(hview);
1227 ok( r == ERROR_SUCCESS, "failed to close view\n");
1228 r = MsiCloseHandle(hview);
1229 ok( r == ERROR_SUCCESS, "failed to close view handle\n");
1230 r = MsiCloseHandle(hdb);
1231 ok( r == ERROR_SUCCESS, "failed to close database\n");
1232}
1233
1235{
1236 MSIHANDLE hview = 0, rec = 0;
1237 UINT r;
1238
1239 r = MsiDatabaseOpenViewA(hdb, query, &hview);
1240 if( r != ERROR_SUCCESS )
1241 return r;
1242
1243 r = MsiViewExecute(hview, 0);
1244 if( r == ERROR_SUCCESS )
1245 {
1246 MsiViewGetColumnInfo( hview, type, &rec );
1247 }
1248 MsiViewClose(hview);
1249 MsiCloseHandle(hview);
1250 return rec;
1251}
1252
1254{
1255 MSIHANDLE hview = 0, rec = 0;
1256 UINT r, type = 0;
1257 char query[0x100];
1258
1259 sprintf(query, "select * from `_Columns` where `Table` = '%s'", table );
1260
1261 r = MsiDatabaseOpenViewA(hdb, query, &hview);
1262 if( r != ERROR_SUCCESS )
1263 return r;
1264
1265 r = MsiViewExecute(hview, 0);
1266 if( r == ERROR_SUCCESS )
1267 {
1268 while (1)
1269 {
1270 r = MsiViewFetch( hview, &rec );
1271 if( r != ERROR_SUCCESS)
1272 break;
1273 r = MsiRecordGetInteger( rec, 2 );
1274 if (r == field)
1275 type = MsiRecordGetInteger( rec, 4 );
1276 MsiCloseHandle( rec );
1277 }
1278 }
1279 MsiViewClose(hview);
1280 MsiCloseHandle(hview);
1281 return type;
1282}
1283
1284static void test_viewgetcolumninfo(void)
1285{
1286 MSIHANDLE hdb = 0, rec;
1287 UINT r;
1288
1289 hdb = create_db();
1290 ok( hdb, "failed to create db\n");
1291
1292 r = run_query( hdb, 0,
1293 "CREATE TABLE `Properties` "
1294 "( `Property` CHAR(255), "
1295 " `Value` CHAR(1), "
1296 " `Intvalue` INT, "
1297 " `Integervalue` INTEGER, "
1298 " `Shortvalue` SHORT, "
1299 " `Longvalue` LONG, "
1300 " `Longcharvalue` LONGCHAR, "
1301 " `Charvalue` CHAR, "
1302 " `Localizablevalue` CHAR LOCALIZABLE "
1303 " PRIMARY KEY `Property`)" );
1304 ok( r == ERROR_SUCCESS , "Failed to create table\n" );
1305
1306 /* check the column types */
1307 rec = get_column_info( hdb, "select * from `Properties`", MSICOLINFO_TYPES );
1308 ok( rec, "failed to get column info record\n" );
1309 check_record(rec, 9, "S255", "S1", "I2", "I2", "I2", "I4", "S0", "S0", "L0");
1310 MsiCloseHandle( rec );
1311
1312 /* check the type in _Columns */
1313 ok( 0x3dff == get_columns_table_type(hdb, "Properties", 1 ), "_columns table wrong\n");
1314 ok( 0x1d01 == get_columns_table_type(hdb, "Properties", 2 ), "_columns table wrong\n");
1315 ok( 0x1502 == get_columns_table_type(hdb, "Properties", 3 ), "_columns table wrong\n");
1316 ok( 0x1502 == get_columns_table_type(hdb, "Properties", 4 ), "_columns table wrong\n");
1317 ok( 0x1502 == get_columns_table_type(hdb, "Properties", 5 ), "_columns table wrong\n");
1318 ok( 0x1104 == get_columns_table_type(hdb, "Properties", 6 ), "_columns table wrong\n");
1319 ok( 0x1d00 == get_columns_table_type(hdb, "Properties", 7 ), "_columns table wrong\n");
1320 ok( 0x1d00 == get_columns_table_type(hdb, "Properties", 8 ), "_columns table wrong\n");
1321 ok( 0x1f00 == get_columns_table_type(hdb, "Properties", 9 ), "_columns table wrong\n");
1322
1323 /* now try the names */
1324 rec = get_column_info( hdb, "select * from `Properties`", MSICOLINFO_NAMES );
1325 ok( rec, "failed to get column info record\n" );
1326 check_record(rec, 9, "Property", "Value", "Intvalue", "Integervalue", "Shortvalue",
1327 "Longvalue", "Longcharvalue", "Charvalue", "Localizablevalue");
1328 MsiCloseHandle( rec );
1329
1330 r = run_query( hdb, 0,
1331 "CREATE TABLE `Binary` "
1332 "( `Name` CHAR(255), `Data` OBJECT PRIMARY KEY `Name`)" );
1333 ok( r == ERROR_SUCCESS , "Failed to create table\n" );
1334
1335 /* check the column types */
1336 rec = get_column_info( hdb, "select * from `Binary`", MSICOLINFO_TYPES );
1337 ok( rec, "failed to get column info record\n" );
1338 check_record(rec, 2, "S255", "V0");
1339 MsiCloseHandle( rec );
1340
1341 /* check the type in _Columns */
1342 ok( 0x3dff == get_columns_table_type(hdb, "Binary", 1 ), "_columns table wrong\n");
1343 ok( 0x1900 == get_columns_table_type(hdb, "Binary", 2 ), "_columns table wrong\n");
1344
1345 /* now try the names */
1346 rec = get_column_info( hdb, "select * from `Binary`", MSICOLINFO_NAMES );
1347 ok( rec, "failed to get column info record\n" );
1348 check_record(rec, 2, "Name", "Data");
1349 MsiCloseHandle( rec );
1350
1351 r = run_query( hdb, 0,
1352 "CREATE TABLE `UIText` "
1353 "( `Key` CHAR(72) NOT NULL, `Text` CHAR(255) LOCALIZABLE PRIMARY KEY `Key`)" );
1354 ok( r == ERROR_SUCCESS , "Failed to create table\n" );
1355
1356 ok( 0x2d48 == get_columns_table_type(hdb, "UIText", 1 ), "_columns table wrong\n");
1357 ok( 0x1fff == get_columns_table_type(hdb, "UIText", 2 ), "_columns table wrong\n");
1358
1359 rec = get_column_info( hdb, "select * from `UIText`", MSICOLINFO_NAMES );
1360 ok( rec, "failed to get column info record\n" );
1361 check_record(rec, 2, "Key", "Text");
1362 MsiCloseHandle( rec );
1363
1364 rec = get_column_info( hdb, "select * from `UIText`", MSICOLINFO_TYPES );
1365 ok( rec, "failed to get column info record\n" );
1366 check_record(rec, 2, "s72", "L255");
1367 MsiCloseHandle( rec );
1368
1369 MsiCloseHandle( hdb );
1370}
1371
1372static void test_msiexport(void)
1373{
1374 MSIHANDLE hdb = 0, hview = 0;
1375 UINT r;
1376 const char *query;
1377 char path[MAX_PATH];
1378 const char file[] = "phone.txt";
1379 HANDLE handle;
1380 char buffer[0x100];
1381 DWORD length;
1382 const char expected[] =
1383 "id\tname\tnumber\r\n"
1384 "I2\tS32\tS32\r\n"
1385 "phone\tid\r\n"
1386 "1\tAbe\t8675309\r\n";
1387
1389
1390 /* just MsiOpenDatabase should not create a file */
1392 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n");
1393
1394 /* create a table */
1395 query = "CREATE TABLE `phone` ( "
1396 "`id` INT, `name` CHAR(32), `number` CHAR(32) "
1397 "PRIMARY KEY `id`)";
1398 r = MsiDatabaseOpenViewA(hdb, query, &hview);
1399 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
1400 r = MsiViewExecute(hview, 0);
1401 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
1402 r = MsiViewClose(hview);
1403 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
1404 r = MsiCloseHandle(hview);
1405 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
1406
1407 /* insert a value into it */
1408 query = "INSERT INTO `phone` ( `id`, `name`, `number` )"
1409 "VALUES('1', 'Abe', '8675309')";
1410 r = MsiDatabaseOpenViewA(hdb, query, &hview);
1411 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
1412 r = MsiViewExecute(hview, 0);
1413 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
1414 r = MsiViewClose(hview);
1415 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
1416 r = MsiCloseHandle(hview);
1417 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
1418
1420
1421 r = MsiDatabaseExportA(hdb, "phone", path, file);
1422 ok(r == ERROR_SUCCESS, "MsiDatabaseExport failed\n");
1423
1424 MsiCloseHandle(hdb);
1425
1426 lstrcatA(path, "\\");
1427 lstrcatA(path, file);
1428
1429 /* check the data that was written */
1430 length = 0;
1431 memset(buffer, 0, sizeof buffer);
1434 {
1435 ReadFile(handle, buffer, sizeof buffer, &length, NULL);
1438 }
1439 else
1440 ok(0, "failed to open file %s\n", path);
1441
1442 ok( length == strlen(expected), "length of data wrong\n");
1443 ok( !lstrcmpA(buffer, expected), "data doesn't match\n");
1445}
1446
1447static void test_longstrings(void)
1448{
1449 const char insert_query[] =
1450 "INSERT INTO `strings` ( `id`, `val` ) VALUES('1', 'Z')";
1451 char *str;
1452 MSIHANDLE hdb = 0, hview = 0, hrec = 0;
1453 DWORD len;
1454 UINT r;
1455 const DWORD STRING_LENGTH = 0x10005;
1456
1458 /* just MsiOpenDatabase should not create a file */
1460 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n");
1461
1462 /* create a table */
1463 r = try_query( hdb,
1464 "CREATE TABLE `strings` ( `id` INT, `val` CHAR(0) PRIMARY KEY `id`)");
1465 ok(r == ERROR_SUCCESS, "query failed\n");
1466
1467 /* try to insert a very long string */
1468 str = malloc(STRING_LENGTH + sizeof insert_query);
1469 len = strchr(insert_query, 'Z') - insert_query;
1470 strcpy(str, insert_query);
1471 memset(str+len, 'Z', STRING_LENGTH);
1472 strcpy(str+len+STRING_LENGTH, insert_query+len+1);
1473 r = try_query( hdb, str );
1474 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
1475 free(str);
1476
1477 r = MsiDatabaseCommit(hdb);
1478 ok(r == ERROR_SUCCESS, "MsiDatabaseCommit failed\n");
1479 MsiCloseHandle(hdb);
1480
1482 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n");
1483
1484 r = MsiDatabaseOpenViewA(hdb, "select * from `strings` where `id` = 1", &hview);
1485 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
1486
1487 r = MsiViewExecute(hview, 0);
1488 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
1489
1490 r = MsiViewFetch(hview, &hrec);
1491 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
1492
1493 MsiViewClose(hview);
1494 MsiCloseHandle(hview);
1495
1496 r = MsiRecordGetStringA(hrec, 2, NULL, &len);
1497 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
1498 ok(len == STRING_LENGTH, "string length wrong\n");
1499
1500 MsiCloseHandle(hrec);
1501 MsiCloseHandle(hdb);
1503}
1504
1506{
1507 HANDLE file;
1508 DWORD written;
1509
1512 return;
1513
1514 WriteFile(file, data, strlen(data), &written, NULL);
1515 WriteFile(file, "\n", strlen("\n"), &written, NULL);
1516
1517 if (size)
1518 {
1521 }
1522
1524}
1525
1526#define create_file(name) create_file_data(name, name, 0)
1527
1528static void test_streamtable(void)
1529{
1530 MSIHANDLE hdb = 0, rec, view, hsi;
1531 char file[MAX_PATH];
1532 char buf[MAX_PATH];
1533 DWORD size;
1534 UINT r;
1535
1536 hdb = create_db();
1537 ok( hdb, "failed to create db\n");
1538
1539 r = run_query( hdb, 0,
1540 "CREATE TABLE `Properties` "
1541 "( `Property` CHAR(255), `Value` CHAR(1) PRIMARY KEY `Property`)" );
1542 ok( r == ERROR_SUCCESS , "Failed to create table\n" );
1543
1544 r = run_query( hdb, 0,
1545 "INSERT INTO `Properties` "
1546 "( `Value`, `Property` ) VALUES ( 'Prop', 'value' )" );
1547 ok( r == ERROR_SUCCESS, "Failed to add to table\n" );
1548
1549 r = MsiDatabaseCommit( hdb );
1550 ok( r == ERROR_SUCCESS , "Failed to commit database\n" );
1551
1552 MsiCloseHandle( hdb );
1553
1555 ok( r == ERROR_SUCCESS , "Failed to open database\n" );
1556
1557 /* check the column types */
1558 rec = get_column_info( hdb, "select * from `_Streams`", MSICOLINFO_TYPES );
1559 ok( rec, "failed to get column info record\n" );
1560 check_record(rec, 2, "s62", "V0");
1561 MsiCloseHandle( rec );
1562
1563 /* now try the names */
1564 rec = get_column_info( hdb, "select * from `_Streams`", MSICOLINFO_NAMES );
1565 ok( rec, "failed to get column info record\n" );
1566 check_record(rec, 2, "Name", "Data");
1567 MsiCloseHandle( rec );
1568
1569 r = MsiDatabaseOpenViewA( hdb,
1570 "SELECT * FROM `_Streams` WHERE `Name` = '\5SummaryInformation'", &view );
1571 ok( r == ERROR_SUCCESS, "Failed to open database view: %u\n", r );
1572
1573 r = MsiViewExecute( view, 0 );
1574 ok( r == ERROR_SUCCESS, "Failed to execute view: %u\n", r );
1575
1576 r = MsiViewFetch( view, &rec );
1577 ok( r == ERROR_NO_MORE_ITEMS, "Unexpected result: %u\n", r );
1578
1579 MsiCloseHandle( rec );
1580 MsiViewClose( view );
1582
1583 /* create a summary information stream */
1584 r = MsiGetSummaryInformationA( hdb, NULL, 1, &hsi );
1585 ok( r == ERROR_SUCCESS, "Failed to get summary information handle: %u\n", r );
1586
1588 ok( r == ERROR_SUCCESS, "Failed to set property: %u\n", r );
1589
1590 r = MsiSummaryInfoPersist( hsi );
1591 ok( r == ERROR_SUCCESS, "Failed to save summary information: %u\n", r );
1592
1593 MsiCloseHandle( hsi );
1594
1595 r = MsiDatabaseOpenViewA( hdb,
1596 "SELECT * FROM `_Streams` WHERE `Name` = '\5SummaryInformation'", &view );
1597 ok( r == ERROR_SUCCESS, "Failed to open database view: %u\n", r );
1598
1599 r = MsiViewExecute( view, 0 );
1600 ok( r == ERROR_SUCCESS, "Failed to execute view: %u\n", r );
1601
1602 r = MsiViewFetch( view, &rec );
1603 ok( r == ERROR_SUCCESS, "Unexpected result: %u\n", r );
1604
1605 MsiCloseHandle( rec );
1606 MsiViewClose( view );
1608
1609 /* insert a file into the _Streams table */
1610 create_file( "test.txt" );
1611
1612 rec = MsiCreateRecord( 2 );
1613 MsiRecordSetStringA( rec, 1, "data" );
1614
1615 r = MsiRecordSetStreamA( rec, 2, "test.txt" );
1616 ok( r == ERROR_SUCCESS, "Failed to add stream data to the record: %d\n", r);
1617
1618 DeleteFileA("test.txt");
1619
1620 r = MsiDatabaseOpenViewA( hdb,
1621 "INSERT INTO `_Streams` ( `Name`, `Data` ) VALUES ( ?, ? )", &view );
1622 ok( r == ERROR_SUCCESS, "Failed to open database view: %d\n", r);
1623
1624 r = MsiViewExecute( view, rec );
1625 ok( r == ERROR_SUCCESS, "Failed to execute view: %d\n", r);
1626
1627 MsiCloseHandle( rec );
1628 MsiViewClose( view );
1630
1631 /* insert another one */
1632 create_file( "test1.txt" );
1633
1634 rec = MsiCreateRecord( 2 );
1635 MsiRecordSetStringA( rec, 1, "data1" );
1636
1637 r = MsiRecordSetStreamA( rec, 2, "test1.txt" );
1638 ok( r == ERROR_SUCCESS, "Failed to add stream data to the record: %d\n", r);
1639
1640 DeleteFileA("test1.txt");
1641
1642 r = MsiDatabaseOpenViewA( hdb,
1643 "INSERT INTO `_Streams` ( `Name`, `Data` ) VALUES ( ?, ? )", &view );
1644 ok( r == ERROR_SUCCESS, "Failed to open database view: %d\n", r);
1645
1646 r = MsiViewExecute( view, rec );
1647 ok( r == ERROR_SUCCESS, "Failed to execute view: %d\n", r);
1648
1649 MsiCloseHandle( rec );
1650 MsiViewClose( view );
1652
1653 /* try again */
1654 create_file( "test1.txt" );
1655
1656 rec = MsiCreateRecord( 2 );
1657 MsiRecordSetStringA( rec, 1, "data1" );
1658
1659 r = MsiRecordSetStreamA( rec, 2, "test1.txt" );
1660 ok( r == ERROR_SUCCESS, "Failed to add stream data to the record: %d\n", r );
1661
1662 DeleteFileA( "test1.txt" );
1663
1664 r = MsiDatabaseOpenViewA( hdb,
1665 "INSERT INTO `_Streams` ( `Name`, `Data` ) VALUES ( ?, ? )", &view );
1666 ok( r == ERROR_SUCCESS, "Failed to open database view: %d\n", r );
1667
1668 r = MsiViewExecute( view, rec );
1669 ok( r == ERROR_FUNCTION_FAILED, "got %u\n", r );
1670
1671 MsiCloseHandle( rec );
1672 MsiViewClose( view );
1674
1675 r = MsiDatabaseOpenViewA( hdb,
1676 "SELECT `Name`, `Data` FROM `_Streams` WHERE `Name` = 'data'", &view );
1677 ok( r == ERROR_SUCCESS, "Failed to open database view: %d\n", r);
1678
1679 r = MsiViewExecute( view, 0 );
1680 ok( r == ERROR_SUCCESS, "Failed to execute view: %d\n", r);
1681
1682 r = MsiViewFetch( view, &rec );
1683 ok( r == ERROR_SUCCESS, "Failed to fetch record: %d\n", r);
1684
1685 size = MAX_PATH;
1686 r = MsiRecordGetStringA( rec, 1, file, &size );
1687 ok( r == ERROR_SUCCESS, "Failed to get string: %d\n", r);
1688 ok( !lstrcmpA(file, "data"), "Expected 'data', got %s\n", file);
1689
1690 size = MAX_PATH;
1691 memset(buf, 0, MAX_PATH);
1692 r = MsiRecordReadStream( rec, 2, buf, &size );
1693 ok( r == ERROR_SUCCESS, "Failed to get stream: %d\n", r);
1694 ok( !lstrcmpA(buf, "test.txt\n"), "Expected 'test.txt\\n', got %s\n", buf);
1695
1696 MsiCloseHandle( rec );
1697 MsiViewClose( view );
1699
1700 r = MsiDatabaseOpenViewA( hdb,
1701 "SELECT `Name`, `Data` FROM `_Streams` WHERE `Name` = 'data1'", &view );
1702 ok( r == ERROR_SUCCESS, "Failed to open database view: %d\n", r);
1703
1704 r = MsiViewExecute( view, 0 );
1705 ok( r == ERROR_SUCCESS, "Failed to execute view: %d\n", r);
1706
1707 r = MsiViewFetch( view, &rec );
1708 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1709
1710 size = MAX_PATH;
1711 r = MsiRecordGetStringA( rec, 1, file, &size );
1712 ok( r == ERROR_SUCCESS, "Failed to get string: %d\n", r);
1713 ok( !lstrcmpA(file, "data1"), "Expected 'data1', got %s\n", file);
1714
1715 size = MAX_PATH;
1716 memset(buf, 0, MAX_PATH);
1717 r = MsiRecordReadStream( rec, 2, buf, &size );
1718 ok( r == ERROR_SUCCESS, "Failed to get stream: %d\n", r);
1719 ok( !lstrcmpA(buf, "test1.txt\n"), "Expected 'test1.txt\\n', got %s\n", buf);
1720
1721 MsiCloseHandle( rec );
1722 MsiViewClose( view );
1724
1725 /* perform an update */
1726 create_file( "test2.txt" );
1727 rec = MsiCreateRecord( 1 );
1728
1729 r = MsiRecordSetStreamA( rec, 1, "test2.txt" );
1730 ok( r == ERROR_SUCCESS, "Failed to add stream data to the record: %d\n", r);
1731
1732 DeleteFileA("test2.txt");
1733
1734 r = MsiDatabaseOpenViewA( hdb,
1735 "UPDATE `_Streams` SET `Data` = ? WHERE `Name` = 'data1'", &view );
1736 ok( r == ERROR_SUCCESS, "Failed to open database view: %d\n", r);
1737
1738 r = MsiViewExecute( view, rec );
1739 ok( r == ERROR_SUCCESS, "Failed to execute view: %d\n", r);
1740
1741 MsiCloseHandle( rec );
1742 MsiViewClose( view );
1744
1745 r = MsiDatabaseOpenViewA( hdb,
1746 "SELECT `Name`, `Data` FROM `_Streams` WHERE `Name` = 'data1'", &view );
1747 ok( r == ERROR_SUCCESS, "Failed to open database view: %d\n", r);
1748
1749 r = MsiViewExecute( view, 0 );
1750 ok( r == ERROR_SUCCESS, "Failed to execute view: %d\n", r);
1751
1752 r = MsiViewFetch( view, &rec );
1753 ok( r == ERROR_SUCCESS, "Failed to fetch record: %d\n", r);
1754
1755 size = MAX_PATH;
1756 r = MsiRecordGetStringA( rec, 1, file, &size );
1757 ok( r == ERROR_SUCCESS, "Failed to get string: %d\n", r);
1758 ok( !lstrcmpA(file, "data1"), "Expected 'data1', got %s\n", file);
1759
1760 size = MAX_PATH;
1761 memset(buf, 0, MAX_PATH);
1762 r = MsiRecordReadStream( rec, 2, buf, &size );
1763 ok( r == ERROR_SUCCESS, "Failed to get stream: %d\n", r);
1764 ok( !lstrcmpA(buf, "test2.txt\n"), "Expected 'test2.txt\\n', got %s\n", buf);
1765
1766 MsiCloseHandle( rec );
1767 MsiViewClose( view );
1769 MsiCloseHandle( hdb );
1771
1772 /* insert a file into the _Streams table */
1774 ok(r == ERROR_SUCCESS, "Failed to create database\n");
1775 ok( hdb, "failed to create db\n");
1776 create_file( "test.txt" );
1777 rec = MsiCreateRecord( 2 );
1778 MsiRecordSetStringA( rec, 1, "data" );
1779 r = MsiRecordSetStreamA( rec, 2, "test.txt" );
1780 ok( r == ERROR_SUCCESS, "Failed to add stream data to the record: %d\n", r);
1781 DeleteFileA("test.txt");
1782 r = MsiDatabaseOpenViewA( hdb,
1783 "INSERT INTO `_Streams` ( `Name`, `Data` ) VALUES ( ?, ? )", &view );
1784 ok( r == ERROR_SUCCESS, "Failed to open database view: %d\n", r);
1785 r = MsiViewExecute( view, rec );
1786 ok( r == ERROR_SUCCESS, "Failed to execute view: %d\n", r);
1787 MsiCloseHandle( rec );
1788 MsiViewClose( view );
1790 r = MsiDatabaseCommit( hdb );
1791 ok( r == ERROR_SUCCESS , "Failed to commit database\n" );
1792
1793 /* open a handle to the "data" stream */
1794 r = MsiDatabaseOpenViewA( hdb,
1795 "SELECT `Name`, `Data` FROM `_Streams` WHERE `Name` = 'data'", &view );
1796 ok( r == ERROR_SUCCESS, "Failed to open database view: %d\n", r);
1797 r = MsiViewExecute( view, 0 );
1798 ok( r == ERROR_SUCCESS, "Failed to execute view: %d\n", r);
1799 r = MsiViewFetch( view, &rec );
1800 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1801 MsiViewClose( view );
1803 /* read the stream while it still exists (normal case) */
1804 size = MAX_PATH;
1805 r = MsiRecordGetStringA( rec, 1, file, &size );
1806 ok( r == ERROR_SUCCESS, "Failed to get string: %d\n", r);
1807 ok( !lstrcmpA(file, "data"), "Expected 'data', got %s\n", file);
1808 size = MAX_PATH;
1809 memset(buf, 0, MAX_PATH);
1810 r = MsiRecordReadStream( rec, 2, buf, &size );
1811 ok( r == ERROR_SUCCESS, "Failed to get stream: %d\n", r);
1812 ok( !lstrcmpA(buf, "test.txt\n"), "Expected 'test.txt\\n', got '%s' (%lu)\n", buf, size);
1813 MsiCloseHandle( rec );
1814
1815 /* open a handle to the "data" stream (and keep it open during removal) */
1816 r = MsiDatabaseOpenViewA( hdb,
1817 "SELECT `Name`, `Data` FROM `_Streams` WHERE `Name` = 'data'", &view );
1818 ok( r == ERROR_SUCCESS, "Failed to open database view: %d\n", r);
1819 r = MsiViewExecute( view, 0 );
1820 ok( r == ERROR_SUCCESS, "Failed to execute view: %d\n", r);
1821 r = MsiViewFetch( view, &rec );
1822 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1823 MsiViewClose( view );
1825
1826 /* remove the stream */
1827 r = MsiDatabaseOpenViewA( hdb,
1828 "DELETE FROM `_Streams` WHERE `Name` = 'data'", &view );
1829 ok( r == ERROR_SUCCESS, "Failed to open database view: %d\n", r);
1830 r = MsiViewExecute( view, 0 );
1831 ok( r == ERROR_SUCCESS, "Failed to execute view: %d\n", r);
1832 MsiViewClose( view );
1834
1835 /* attempt to read the stream that no longer exists (abnormal case) */
1836 size = MAX_PATH;
1837 r = MsiRecordGetStringA( rec, 1, file, &size );
1838 ok( r == ERROR_SUCCESS, "Failed to get string: %d\n", r);
1839 ok( !lstrcmpA(file, "data"), "Expected 'data', got %s\n", file);
1840 size = MAX_PATH;
1841 memset(buf, 0, MAX_PATH);
1842 r = MsiRecordReadStream( rec, 2, buf, &size );
1843 ok( r == ERROR_SUCCESS, "Failed to get stream: %d\n", r);
1844 todo_wine ok( size == 0, "Expected empty buffer, got %lu bytes\n", size);
1845 MsiCloseHandle( rec );
1846
1847 MsiCloseHandle( hdb );
1849}
1850
1851static void test_binary(void)
1852{
1853 MSIHANDLE hdb = 0, rec;
1854 char file[MAX_PATH];
1855 char buf[MAX_PATH];
1856 DWORD size;
1857 LPCSTR query;
1858 UINT r;
1859
1860 /* insert a file into the Binary table */
1862 ok( r == ERROR_SUCCESS , "Failed to open database\n" );
1863
1864 query = "CREATE TABLE `Binary` ( `Name` CHAR(72) NOT NULL, `ID` INT NOT NULL, `Data` OBJECT PRIMARY KEY `Name`, `ID`)";
1865 r = run_query( hdb, 0, query );
1866 ok( r == ERROR_SUCCESS, "Cannot create Binary table: %d\n", r );
1867
1868 create_file( "test.txt" );
1869 rec = MsiCreateRecord( 1 );
1870 r = MsiRecordSetStreamA( rec, 1, "test.txt" );
1871 ok( r == ERROR_SUCCESS, "Failed to add stream data to the record: %d\n", r);
1872 DeleteFileA( "test.txt" );
1873
1874 /* try a name that exceeds maximum OLE stream name length */
1875 query = "INSERT INTO `Binary` ( `Name`, `ID`, `Data` ) VALUES ( 'encryption.dll.CB4E6205_F99A_4C51_ADD4_184506EFAB87', 10000, ? )";
1876 r = run_query( hdb, rec, query );
1877 ok( r == ERROR_SUCCESS, "Insert into Binary table failed: %d\n", r );
1878
1879 r = MsiCloseHandle( rec );
1880 ok( r == ERROR_SUCCESS , "Failed to close record handle\n" );
1881
1882 r = MsiDatabaseCommit( hdb );
1883 ok( r == ERROR_FUNCTION_FAILED , "got %u\n", r );
1884
1885 r = MsiCloseHandle( hdb );
1886 ok( r == ERROR_SUCCESS , "Failed to close database\n" );
1887
1889 ok( r == ERROR_SUCCESS , "Failed to open database\n" );
1890
1891 query = "CREATE TABLE `Binary` ( `Name` CHAR(72) NOT NULL, `ID` INT NOT NULL, `Data` OBJECT PRIMARY KEY `Name`, `ID`)";
1892 r = run_query( hdb, 0, query );
1893 ok( r == ERROR_SUCCESS, "Cannot create Binary table: %d\n", r );
1894
1895 create_file( "test.txt" );
1896 rec = MsiCreateRecord( 1 );
1897 r = MsiRecordSetStreamA( rec, 1, "test.txt" );
1898 ok( r == ERROR_SUCCESS, "Failed to add stream data to the record: %d\n", r );
1899 DeleteFileA( "test.txt" );
1900
1901 query = "INSERT INTO `Binary` ( `Name`, `ID`, `Data` ) VALUES ( 'filename1', 1, ? )";
1902 r = run_query( hdb, rec, query );
1903 ok( r == ERROR_SUCCESS, "Insert into Binary table failed: %d\n", r );
1904
1905 query = "INSERT INTO `Binary` ( `Name`, `ID`, `Data` ) VALUES ( 'filename1', 1, ? )";
1906 r = run_query( hdb, rec, query );
1907 ok( r == ERROR_FUNCTION_FAILED, "got %u\n", r );
1908
1909 r = MsiCloseHandle( rec );
1910 ok( r == ERROR_SUCCESS , "Failed to close record handle\n" );
1911
1912 r = MsiDatabaseCommit( hdb );
1913 ok( r == ERROR_SUCCESS , "Failed to commit database\n" );
1914
1915 r = MsiCloseHandle( hdb );
1916 ok( r == ERROR_SUCCESS , "Failed to close database\n" );
1917
1918 /* read file from the Stream table */
1920 ok( r == ERROR_SUCCESS , "Failed to open database\n" );
1921
1922 query = "SELECT * FROM `_Streams`";
1923 r = do_query( hdb, query, &rec );
1924 ok( r == ERROR_SUCCESS, "SELECT query failed: %d\n", r );
1925
1926 size = MAX_PATH;
1927 r = MsiRecordGetStringA( rec, 1, file, &size );
1928 ok( r == ERROR_SUCCESS, "Failed to get string: %d\n", r );
1929 ok( !lstrcmpA(file, "Binary.filename1.1"), "Expected 'Binary.filename1.1', got %s\n", file );
1930
1931 size = MAX_PATH;
1932 memset( buf, 0, MAX_PATH );
1933 r = MsiRecordReadStream( rec, 2, buf, &size );
1934 ok( r == ERROR_SUCCESS, "Failed to get stream: %d\n", r );
1935 ok( !lstrcmpA(buf, "test.txt\n"), "Expected 'test.txt\\n', got %s\n", buf );
1936
1937 r = MsiCloseHandle( rec );
1938 ok( r == ERROR_SUCCESS , "Failed to close record handle\n" );
1939
1940 /* read file from the Binary table */
1941 query = "SELECT * FROM `Binary`";
1942 r = do_query( hdb, query, &rec );
1943 ok( r == ERROR_SUCCESS, "SELECT query failed: %d\n", r );
1944
1945 size = MAX_PATH;
1946 r = MsiRecordGetStringA( rec, 1, file, &size );
1947 ok( r == ERROR_SUCCESS, "Failed to get string: %d\n", r );
1948 ok( !lstrcmpA(file, "filename1"), "Expected 'filename1', got %s\n", file );
1949
1950 size = MAX_PATH;
1951 memset( buf, 0, MAX_PATH );
1952 r = MsiRecordReadStream( rec, 3, buf, &size );
1953 ok( r == ERROR_SUCCESS, "Failed to get stream: %d\n", r );
1954 ok( !lstrcmpA(buf, "test.txt\n"), "Expected 'test.txt\\n', got %s\n", buf );
1955
1956 r = MsiCloseHandle( rec );
1957 ok( r == ERROR_SUCCESS , "Failed to close record handle\n" );
1958
1959 r = MsiCloseHandle( hdb );
1960 ok( r == ERROR_SUCCESS , "Failed to close database\n" );
1961
1963}
1964
1966{
1967 MSIHANDLE hdb = 0, rec, view;
1968 LPCSTR query;
1969 UINT r;
1970
1971 hdb = create_db();
1972 ok( hdb, "failed to create db\n");
1973
1974 r = run_query(hdb, 0,
1975 "CREATE TABLE `IESTable` ("
1976 "`Action` CHAR(64), "
1977 "`Condition` CHAR(64), "
1978 "`Sequence` LONG PRIMARY KEY `Sequence`)");
1979 ok( r == S_OK, "Cannot create IESTable table: %d\n", r);
1980
1981 r = run_query(hdb, 0,
1982 "CREATE TABLE `CATable` ("
1983 "`Action` CHAR(64), "
1984 "`Type` LONG PRIMARY KEY `Type`)");
1985 ok( r == S_OK, "Cannot create CATable table: %d\n", r);
1986
1987 r = run_query(hdb, 0, "INSERT INTO `IESTable` "
1988 "( `Action`, `Condition`, `Sequence`) "
1989 "VALUES ( 'clean', 'cond4', 4)");
1990 ok( r == S_OK, "cannot add entry to IESTable table:%d\n", r );
1991
1992 r = run_query(hdb, 0, "INSERT INTO `IESTable` "
1993 "( `Action`, `Condition`, `Sequence`) "
1994 "VALUES ( 'depends', 'cond1', 1)");
1995 ok( r == S_OK, "cannot add entry to IESTable table:%d\n", r );
1996
1997 r = run_query(hdb, 0, "INSERT INTO `IESTable` "
1998 "( `Action`, `Condition`, `Sequence`) "
1999 "VALUES ( 'build', 'cond2', 2)");
2000 ok( r == S_OK, "cannot add entry to IESTable table:%d\n", r );
2001
2002 r = run_query(hdb, 0, "INSERT INTO `IESTable` "
2003 "( `Action`, `Condition`, `Sequence`) "
2004 "VALUES ( 'build2', 'cond6', 6)");
2005 ok( r == S_OK, "cannot add entry to IESTable table:%d\n", r );
2006
2007 r = run_query(hdb, 0, "INSERT INTO `IESTable` "
2008 "( `Action`, `Condition`, `Sequence`) "
2009 "VALUES ( 'build', 'cond3', 3)");
2010 ok(r == S_OK, "cannot add entry to IESTable table:%d\n", r );
2011
2012 r = run_query(hdb, 0, "INSERT INTO `CATable` "
2013 "( `Action`, `Type` ) "
2014 "VALUES ( 'build', 32)");
2015 ok(r == S_OK, "cannot add entry to CATable table:%d\n", r );
2016
2017 r = run_query(hdb, 0, "INSERT INTO `CATable` "
2018 "( `Action`, `Type` ) "
2019 "VALUES ( 'depends', 64)");
2020 ok(r == S_OK, "cannot add entry to CATable table:%d\n", r );
2021
2022 r = run_query(hdb, 0, "INSERT INTO `CATable` "
2023 "( `Action`, `Type` ) "
2024 "VALUES ( 'clean', 63)");
2025 ok(r == S_OK, "cannot add entry to CATable table:%d\n", r );
2026
2027 r = run_query(hdb, 0, "INSERT INTO `CATable` "
2028 "( `Action`, `Type` ) "
2029 "VALUES ( 'build2', 34)");
2030 ok(r == S_OK, "cannot add entry to CATable table:%d\n", r );
2031 query = "Select IESTable.Condition from CATable, IESTable where "
2032 "CATable.Action = IESTable.Action and CATable.Type = 32";
2033 r = MsiDatabaseOpenViewA(hdb, query, &view);
2034 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r );
2035
2036 r = MsiViewExecute(view, 0);
2037 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r );
2038
2039 r = MsiViewFetch(view, &rec);
2040 ok( r == ERROR_SUCCESS, "failed to fetch view: %d\n", r );
2041 check_record(rec, 1, "cond2");
2042 MsiCloseHandle( rec );
2043
2044 r = MsiViewFetch(view, &rec);
2045 ok( r == ERROR_SUCCESS, "failed to fetch view: %d\n", r );
2046 check_record(rec, 1, "cond3");
2047 MsiCloseHandle( rec );
2048
2051
2052 MsiCloseHandle( hdb );
2054}
2055
2056
2057static void test_where(void)
2058{
2059 MSIHANDLE hdb = 0, rec, view;
2060 LPCSTR query;
2061 UINT r;
2062
2063 hdb = create_db();
2064 ok( hdb, "failed to create db\n");
2065
2066 r = run_query( hdb, 0,
2067 "CREATE TABLE `Media` ("
2068 "`DiskId` SHORT NOT NULL, "
2069 "`LastSequence` LONG, "
2070 "`DiskPrompt` CHAR(64) LOCALIZABLE, "
2071 "`Cabinet` CHAR(255), "
2072 "`VolumeLabel` CHAR(32), "
2073 "`Source` CHAR(72) "
2074 "PRIMARY KEY `DiskId`)" );
2075 ok( r == S_OK, "cannot create Media table: %d\n", r );
2076
2077 r = run_query( hdb, 0, "INSERT INTO `Media` "
2078 "( `DiskId`, `LastSequence`, `DiskPrompt`, `Cabinet`, `VolumeLabel`, `Source` ) "
2079 "VALUES ( 1, 0, '', 'zero.cab', '', '' )" );
2080 ok( r == S_OK, "cannot add file to the Media table: %d\n", r );
2081
2082 r = run_query( hdb, 0, "INSERT INTO `Media` "
2083 "( `DiskId`, `LastSequence`, `DiskPrompt`, `Cabinet`, `VolumeLabel`, `Source` ) "
2084 "VALUES ( 2, 1, '', 'one.cab', '', '' )" );
2085 ok( r == S_OK, "cannot add file to the Media table: %d\n", r );
2086
2087 r = run_query( hdb, 0, "INSERT INTO `Media` "
2088 "( `DiskId`, `LastSequence`, `DiskPrompt`, `Cabinet`, `VolumeLabel`, `Source` ) "
2089 "VALUES ( 3, 2, '', 'two.cab', '', '' )" );
2090 ok( r == S_OK, "cannot add file to the Media table: %d\n", r );
2091
2092 query = "SELECT * FROM `Media`";
2093 r = do_query(hdb, query, &rec);
2094 ok(r == ERROR_SUCCESS, "MsiViewFetch failed: %d\n", r);
2095 check_record(rec, 6, "1", "0", "", "zero.cab", "", "");
2096 MsiCloseHandle( rec );
2097
2098 query = "SELECT * FROM `Media` WHERE `LastSequence` >= 1";
2099 r = do_query(hdb, query, &rec);
2100 ok(r == ERROR_SUCCESS, "MsiViewFetch failed: %d\n", r);
2101 check_record(rec, 6, "2", "1", "", "one.cab", "", "");
2102 MsiCloseHandle( rec );
2103
2104 query = "SELECT `DiskId` FROM `Media` WHERE `LastSequence` >= 1 AND DiskId >= 0";
2105 r = MsiDatabaseOpenViewA(hdb, query, &view);
2106 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r );
2107
2108 r = MsiViewExecute(view, 0);
2109 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r );
2110
2111 r = MsiViewFetch(view, &rec);
2112 ok( r == ERROR_SUCCESS, "failed to fetch view: %d\n", r );
2113 check_record(rec, 1, "2");
2114 MsiCloseHandle( rec );
2115
2116 r = MsiViewFetch(view, &rec);
2117 ok( r == ERROR_SUCCESS, "failed to fetch view: %d\n", r );
2118 check_record(rec, 1, "3");
2119 MsiCloseHandle( rec );
2120
2121 r = MsiViewFetch(view, &rec);
2122 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r );
2123
2126
2127 MsiCloseHandle( rec );
2128
2129 rec = 0;
2130 query = "SELECT * FROM `Media` WHERE `DiskPrompt` IS NULL";
2131 r = do_query(hdb, query, &rec);
2132 ok( r == ERROR_SUCCESS, "query failed: %d\n", r );
2133 MsiCloseHandle( rec );
2134
2135 rec = 0;
2136 query = "SELECT * FROM `Media` WHERE `DiskPrompt` < 'Cabinet'";
2137 r = do_query(hdb, query, &rec);
2138 ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %d\n", r );
2139 MsiCloseHandle( rec );
2140
2141 rec = 0;
2142 query = "SELECT * FROM `Media` WHERE `DiskPrompt` > 'Cabinet'";
2143 r = do_query(hdb, query, &rec);
2144 ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %d\n", r );
2145 MsiCloseHandle( rec );
2146
2147 rec = 0;
2148 query = "SELECT * FROM `Media` WHERE `DiskPrompt` <> 'Cabinet'";
2149 r = do_query(hdb, query, &rec);
2150 ok( r == ERROR_SUCCESS, "query failed: %d\n", r );
2151 MsiCloseHandle( rec );
2152
2153 rec = 0;
2154 query = "SELECT * FROM `Media` WHERE `DiskPrompt` = 'Cabinet'";
2155 r = do_query(hdb, query, &rec);
2156 ok( r == ERROR_NO_MORE_ITEMS, "query failed: %d\n", r );
2157 MsiCloseHandle( rec );
2158
2159 rec = MsiCreateRecord(1);
2160 MsiRecordSetStringA(rec, 1, "");
2161
2162 query = "SELECT * FROM `Media` WHERE `DiskPrompt` = ?";
2163 r = MsiDatabaseOpenViewA(hdb, query, &view);
2164 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2165 r = MsiViewExecute(view, rec);
2166 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2167
2168 MsiCloseHandle(rec);
2169
2170 r = MsiViewFetch(view, &rec);
2171 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2172
2173 MsiCloseHandle(rec);
2176
2177 MsiCloseHandle( hdb );
2179}
2180
2182
2183static const CHAR test_data[] = "FirstPrimaryColumn\tSecondPrimaryColumn\tShortInt\tShortIntNullable\tLongInt\tLongIntNullable\tString\tLocalizableString\tLocalizableStringNullable\n"
2184 "s255\ti2\ti2\tI2\ti4\tI4\tS255\tS0\ts0\n"
2185 "TestTable\tFirstPrimaryColumn\n"
2186 "stringage\t5\t2\t\t2147483640\t-2147483640\tanother string\tlocalizable\tduh\n";
2187
2188static const CHAR two_primary[] = "PrimaryOne\tPrimaryTwo\n"
2189 "s255\ts255\n"
2190 "TwoPrimary\tPrimaryOne\tPrimaryTwo\n"
2191 "papaya\tleaf\n"
2192 "papaya\tflower\n";
2193
2194static const CHAR endlines1[] = "A\tB\tC\tD\tE\tF\r\n"
2195 "s72\ts72\ts72\ts72\ts72\ts72\n"
2196 "Table\tA\r\n"
2197 "a\tb\tc\td\te\tf\n"
2198 "g\th\ti\t\rj\tk\tl\r\n";
2199
2200static const CHAR endlines2[] = "A\tB\tC\tD\tE\tF\r"
2201 "s72\ts72\ts72\ts72\ts72\ts72\n"
2202 "Table2\tA\r\n"
2203 "a\tb\tc\td\te\tf\n"
2204 "g\th\ti\tj\tk\tl\r\n";
2205
2206static const CHAR suminfo[] = "PropertyId\tValue\n"
2207 "i2\tl255\n"
2208 "_SummaryInformation\tPropertyId\n"
2209 "1\t1252\n"
2210 "2\tInstaller Database\n"
2211 "3\tInstaller description\n"
2212 "4\tWineHQ\n"
2213 "5\tInstaller\n"
2214 "6\tInstaller comments\n"
2215 "7\tIntel;1033,2057\n"
2216 "9\t{12345678-1234-1234-1234-123456789012}\n"
2217 "12\t2009/04/12 15:46:11\n"
2218 "13\t2009/04/12 15:46:11\n"
2219 "14\t200\n"
2220 "15\t2\n"
2221 "18\tVim\n"
2222 "19\t2\n";
2223
2224static void write_file(const CHAR *filename, const char *data, int data_size)
2225{
2226 DWORD size;
2227
2230 WriteFile(hf, data, data_size, &size, NULL);
2231 CloseHandle(hf);
2232}
2233
2235{
2236 UINT r;
2237
2238 write_file("temp_file", table_data, (lstrlenA(table_data) - 1) * sizeof(char));
2239 r = MsiDatabaseImportA(hdb, CURR_DIR, "temp_file");
2240 DeleteFileA("temp_file");
2241
2242 return r;
2243}
2244
2245static void test_suminfo_import(void)
2246{
2247 MSIHANDLE hdb, hsi, view = 0;
2248 LPCSTR query;
2249 UINT r, count, type;
2250 DWORD size;
2251 char str_value[50];
2252 INT int_value;
2253 FILETIME ft_value;
2254
2256
2258 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2259
2260 r = add_table_to_db(hdb, suminfo);
2261 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2262
2263 /* _SummaryInformation is not imported as a regular table... */
2264
2265 query = "SELECT * FROM `_SummaryInformation`";
2266 r = MsiDatabaseOpenViewA(hdb, query, &view);
2267 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %u\n", r);
2269
2270 /* ...its data is added to the special summary information stream */
2271
2272 r = MsiGetSummaryInformationA(hdb, NULL, 0, &hsi);
2273 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2274
2276 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2277 ok(count == 14, "Expected 14, got %u\n", count);
2278
2279 r = MsiSummaryInfoGetPropertyA(hsi, PID_CODEPAGE, &type, &int_value, NULL, NULL, NULL);
2280 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2281 ok(type == VT_I2, "Expected VT_I2, got %u\n", type);
2282 ok(int_value == 1252, "Expected 1252, got %d\n", int_value);
2283
2284 size = sizeof(str_value);
2285 r = MsiSummaryInfoGetPropertyA(hsi, PID_TITLE, &type, NULL, NULL, str_value, &size);
2286 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2287 ok(type == VT_LPSTR, "Expected VT_LPSTR, got %u\n", type);
2288 ok(size == 18, "Expected 18, got %lu\n", size);
2289 ok(!strcmp(str_value, "Installer Database"),
2290 "Expected \"Installer Database\", got %s\n", str_value);
2291
2292 size = sizeof(str_value);
2293 r = MsiSummaryInfoGetPropertyA(hsi, PID_SUBJECT, &type, NULL, NULL, str_value, &size);
2294 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2295 ok(type == VT_LPSTR, "Expected VT_LPSTR, got %u\n", type);
2296 ok(!strcmp(str_value, "Installer description"),
2297 "Expected \"Installer description\", got %s\n", str_value);
2298
2299 size = sizeof(str_value);
2300 r = MsiSummaryInfoGetPropertyA(hsi, PID_AUTHOR, &type, NULL, NULL, str_value, &size);
2301 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2302 ok(type == VT_LPSTR, "Expected VT_LPSTR, got %u\n", type);
2303 ok(!strcmp(str_value, "WineHQ"),
2304 "Expected \"WineHQ\", got %s\n", str_value);
2305
2306 size = sizeof(str_value);
2307 r = MsiSummaryInfoGetPropertyA(hsi, PID_KEYWORDS, &type, NULL, NULL, str_value, &size);
2308 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2309 ok(type == VT_LPSTR, "Expected VT_LPSTR, got %u\n", type);
2310 ok(!strcmp(str_value, "Installer"),
2311 "Expected \"Installer\", got %s\n", str_value);
2312
2313 size = sizeof(str_value);
2314 r = MsiSummaryInfoGetPropertyA(hsi, PID_COMMENTS, &type, NULL, NULL, str_value, &size);
2315 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2316 ok(type == VT_LPSTR, "Expected VT_LPSTR, got %u\n", type);
2317 ok(!strcmp(str_value, "Installer comments"),
2318 "Expected \"Installer comments\", got %s\n", str_value);
2319
2320 size = sizeof(str_value);
2321 r = MsiSummaryInfoGetPropertyA(hsi, PID_TEMPLATE, &type, NULL, NULL, str_value, &size);
2322 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2323 ok(type == VT_LPSTR, "Expected VT_LPSTR, got %u\n", type);
2324 ok(!strcmp(str_value, "Intel;1033,2057"),
2325 "Expected \"Intel;1033,2057\", got %s\n", str_value);
2326
2327 size = sizeof(str_value);
2328 r = MsiSummaryInfoGetPropertyA(hsi, PID_REVNUMBER, &type, NULL, NULL, str_value, &size);
2329 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2330 ok(type == VT_LPSTR, "Expected VT_LPSTR, got %u\n", type);
2331 ok(!strcmp(str_value, "{12345678-1234-1234-1234-123456789012}"),
2332 "Expected \"{12345678-1234-1234-1234-123456789012}\", got %s\n", str_value);
2333
2335 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2336 ok(type == VT_FILETIME, "Expected VT_FILETIME, got %u\n", type);
2337
2339 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2340 ok(type == VT_FILETIME, "Expected VT_FILETIME, got %u\n", type);
2341
2342 r = MsiSummaryInfoGetPropertyA(hsi, PID_PAGECOUNT, &type, &int_value, NULL, NULL, NULL);
2343 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2344 ok(type == VT_I4, "Expected VT_I4, got %u\n", type);
2345 ok(int_value == 200, "Expected 200, got %d\n", int_value);
2346
2347 r = MsiSummaryInfoGetPropertyA(hsi, PID_WORDCOUNT, &type, &int_value, NULL, NULL, NULL);
2348 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2349 ok(type == VT_I4, "Expected VT_I4, got %u\n", type);
2350 ok(int_value == 2, "Expected 2, got %d\n", int_value);
2351
2352 r = MsiSummaryInfoGetPropertyA(hsi, PID_SECURITY, &type, &int_value, NULL, NULL, NULL);
2353 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2354 ok(type == VT_I4, "Expected VT_I4, got %u\n", type);
2355 ok(int_value == 2, "Expected 2, got %d\n", int_value);
2356
2357 size = sizeof(str_value);
2358 r = MsiSummaryInfoGetPropertyA(hsi, PID_APPNAME, &type, NULL, NULL, str_value, &size);
2359 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2360 ok(type == VT_LPSTR, "Expected VT_LPSTR, got %u\n", type);
2361 ok(!strcmp(str_value, "Vim"), "Expected \"Vim\", got %s\n", str_value);
2362
2363 MsiCloseHandle(hsi);
2364 MsiCloseHandle(hdb);
2366}
2367
2368static void test_msiimport(void)
2369{
2370 MSIHANDLE hdb, view, rec;
2371 LPCSTR query;
2372 UINT r;
2373
2375
2377 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2378
2380 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2381
2382 r = MsiDatabaseImportA(hdb, CURR_DIR, "nonexistent");
2383 ok(r == ERROR_FUNCTION_FAILED, "Expected ERROR_FUNCTION_FAILED, got %d\n", r);
2384
2385 r = add_table_to_db(hdb, test_data);
2386 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2387
2389 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2390
2391 r = add_table_to_db(hdb, endlines1);
2392 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2393
2394 r = add_table_to_db(hdb, endlines2);
2395 ok(r == ERROR_FUNCTION_FAILED, "Expected ERROR_FUNCTION_FAILED, got %d\n", r);
2396
2397 query = "SELECT * FROM `TestTable`";
2398 r = MsiDatabaseOpenViewA(hdb, query, &view);
2399 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2400
2402 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2403 check_record(rec, 9, "FirstPrimaryColumn", "SecondPrimaryColumn", "ShortInt",
2404 "ShortIntNullable", "LongInt", "LongIntNullable", "String",
2405 "LocalizableString", "LocalizableStringNullable");
2406 MsiCloseHandle(rec);
2407
2409 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2410 check_record(rec, 9, "s255", "i2", "i2", "I2", "i4", "I4", "S255", "S0", "s0");
2411 MsiCloseHandle(rec);
2412
2413 query = "SELECT * FROM `TestTable`";
2414 r = do_query(hdb, query, &rec);
2415 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2416 check_record(rec, 9, "stringage", "5", "2", "", "2147483640", "-2147483640",
2417 "another string", "localizable", "duh");
2418 MsiCloseHandle(rec);
2419
2422
2423 query = "SELECT * FROM `TwoPrimary`";
2424 r = MsiDatabaseOpenViewA(hdb, query, &view);
2425 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2426
2428 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2429 check_record(rec, 2, "PrimaryOne", "PrimaryTwo");
2430 MsiCloseHandle(rec);
2431
2433 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2434 check_record(rec, 2, "s255", "s255");
2435 MsiCloseHandle(rec);
2436
2437 r = MsiViewExecute(view, 0);
2438 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2439
2440 r = MsiViewFetch(view, &rec);
2441 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2442 check_record(rec, 2, "papaya", "leaf");
2443 MsiCloseHandle(rec);
2444
2445 r = MsiViewFetch(view, &rec);
2446 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2447 check_record(rec, 2, "papaya", "flower");
2448 MsiCloseHandle(rec);
2449
2450 r = MsiViewFetch(view, &rec);
2452 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
2453
2454 r = MsiViewClose(view);
2455 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2456
2458
2459 query = "SELECT * FROM `Table`";
2460 r = MsiDatabaseOpenViewA(hdb, query, &view);
2461 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2462
2464 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2465 check_record(rec, 6, "A", "B", "C", "D", "E", "F");
2466 MsiCloseHandle(rec);
2467
2469 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2470 check_record(rec, 6, "s72", "s72", "s72", "s72", "s72", "s72");
2471 MsiCloseHandle(rec);
2472
2475
2476 query = "SELECT * FROM `Table`";
2477 r = MsiDatabaseOpenViewA(hdb, query, &view);
2478 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2479
2480 r = MsiViewExecute(view, 0);
2481 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2482
2483 r = MsiViewFetch(view, &rec);
2484 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2485 check_record(rec, 6, "a", "b", "c", "d", "e", "f");
2486 MsiCloseHandle(rec);
2487
2488 r = MsiViewFetch(view, &rec);
2489 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2490 check_record(rec, 6, "g", "h", "i", "j", "k", "l");
2491 MsiCloseHandle(rec);
2492
2493 r = MsiViewFetch(view, &rec);
2495 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
2496
2499 MsiCloseHandle(hdb);
2501}
2502
2503static const CHAR bin_import_dat[] = "Name\tData\r\n"
2504 "s72\tV0\r\n"
2505 "Binary\tName\r\n"
2506 "filename1\tfilename1.ibd\r\n";
2507
2508static void test_binary_import(void)
2509{
2510 MSIHANDLE hdb = 0, rec;
2511 char file[MAX_PATH];
2512 char buf[MAX_PATH];
2513 char path[MAX_PATH];
2514 DWORD size;
2515 LPCSTR query;
2516 UINT r;
2517
2518 /* create files to import */
2519 write_file("bin_import.idt", bin_import_dat,
2520 (sizeof(bin_import_dat) - 1) * sizeof(char));
2521 CreateDirectoryA("bin_import", NULL);
2522 create_file_data("bin_import/filename1.ibd", "just some words", 15);
2523
2524 /* import files into database */
2526 ok( r == ERROR_SUCCESS , "Failed to open database\n");
2527
2529 r = MsiDatabaseImportA(hdb, path, "bin_import.idt");
2530 ok(r == ERROR_SUCCESS , "Failed to import Binary table\n");
2531
2532 /* read file from the Binary table */
2533 query = "SELECT * FROM `Binary`";
2534 r = do_query(hdb, query, &rec);
2535 ok(r == ERROR_SUCCESS, "SELECT query failed: %d\n", r);
2536
2537 size = MAX_PATH;
2538 r = MsiRecordGetStringA(rec, 1, file, &size);
2539 ok(r == ERROR_SUCCESS, "Failed to get string: %d\n", r);
2540 ok(!lstrcmpA(file, "filename1"), "Expected 'filename1', got %s\n", file);
2541
2542 size = MAX_PATH;
2543 memset(buf, 0, MAX_PATH);
2544 r = MsiRecordReadStream(rec, 2, buf, &size);
2545 ok(r == ERROR_SUCCESS, "Failed to get stream: %d\n", r);
2546 ok(!lstrcmpA(buf, "just some words"), "Expected 'just some words', got %s\n", buf);
2547
2548 r = MsiCloseHandle(rec);
2549 ok(r == ERROR_SUCCESS , "Failed to close record handle\n");
2550
2551 r = MsiCloseHandle(hdb);
2552 ok(r == ERROR_SUCCESS , "Failed to close database\n");
2553
2554 DeleteFileA("bin_import/filename1.ibd");
2555 RemoveDirectoryA("bin_import");
2556 DeleteFileA("bin_import.idt");
2557}
2558
2559static void test_markers(void)
2560{
2561 MSIHANDLE hdb, rec;
2562 LPCSTR query;
2563 UINT r;
2564
2565 hdb = create_db();
2566 ok( hdb, "failed to create db\n");
2567
2568 rec = MsiCreateRecord(3);
2569 MsiRecordSetStringA(rec, 1, "Table");
2570 MsiRecordSetStringA(rec, 2, "Apples");
2571 MsiRecordSetStringA(rec, 3, "Oranges");
2572
2573 /* try a legit create */
2574 query = "CREATE TABLE `Table` ( `One` SHORT NOT NULL, `Two` CHAR(255) PRIMARY KEY `One`)";
2575 r = run_query(hdb, 0, query);
2576 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2577 MsiCloseHandle(rec);
2578
2579 /* try table name as marker */
2580 rec = MsiCreateRecord(1);
2581 MsiRecordSetStringA(rec, 1, "Fable");
2582 query = "CREATE TABLE `?` ( `One` SHORT NOT NULL, `Two` CHAR(255) PRIMARY KEY `One`)";
2583 r = run_query(hdb, rec, query);
2584 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2585
2586 /* verify that we just created a table called '?', not 'Fable' */
2587 r = try_query(hdb, "SELECT * from `Fable`");
2588 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
2589
2590 r = try_query(hdb, "SELECT * from `?`");
2591 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2592
2593 /* try table name as marker without backticks */
2594 MsiRecordSetStringA(rec, 1, "Mable");
2595 query = "CREATE TABLE ? ( `One` SHORT NOT NULL, `Two` CHAR(255) PRIMARY KEY `One`)";
2596 r = run_query(hdb, rec, query);
2597 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
2598
2599 /* try one column name as marker */
2600 MsiRecordSetStringA(rec, 1, "One");
2601 query = "CREATE TABLE `Mable` ( `?` SHORT NOT NULL, `Two` CHAR(255) PRIMARY KEY `One`)";
2602 r = run_query(hdb, rec, query);
2603 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
2604 MsiCloseHandle(rec);
2605
2606 /* try column names as markers */
2607 rec = MsiCreateRecord(2);
2608 MsiRecordSetStringA(rec, 1, "One");
2609 MsiRecordSetStringA(rec, 2, "Two");
2610 query = "CREATE TABLE `Mable` ( `?` SHORT NOT NULL, `?` CHAR(255) PRIMARY KEY `One`)";
2611 r = run_query(hdb, rec, query);
2612 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
2613 MsiCloseHandle(rec);
2614
2615 /* try names with backticks */
2616 rec = MsiCreateRecord(3);
2617 MsiRecordSetStringA(rec, 1, "One");
2618 MsiRecordSetStringA(rec, 2, "Two");
2619 MsiRecordSetStringA(rec, 3, "One");
2620 query = "CREATE TABLE `Mable` ( `?` SHORT NOT NULL, `?` CHAR(255) PRIMARY KEY `?`)";
2621 r = run_query(hdb, rec, query);
2622 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
2623
2624 /* try names with backticks, minus definitions */
2625 query = "CREATE TABLE `Mable` ( `?`, `?` PRIMARY KEY `?`)";
2626 r = run_query(hdb, rec, query);
2627 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
2628
2629 /* try names without backticks */
2630 query = "CREATE TABLE `Mable` ( ? SHORT NOT NULL, ? CHAR(255) PRIMARY KEY ?)";
2631 r = run_query(hdb, rec, query);
2632 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
2633 MsiCloseHandle(rec);
2634
2635 /* try one long marker */
2636 rec = MsiCreateRecord(1);
2637 MsiRecordSetStringA(rec, 1, "`One` SHORT NOT NULL, `Two` CHAR(255) PRIMARY KEY `One`");
2638 query = "CREATE TABLE `Mable` ( ? )";
2639 r = run_query(hdb, rec, query);
2640 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
2641 MsiCloseHandle(rec);
2642
2643 /* try all names as markers */
2644 rec = MsiCreateRecord(4);
2645 MsiRecordSetStringA(rec, 1, "Mable");
2646 MsiRecordSetStringA(rec, 2, "One");
2647 MsiRecordSetStringA(rec, 3, "Two");
2648 MsiRecordSetStringA(rec, 4, "One");
2649 query = "CREATE TABLE `?` ( `?` SHORT NOT NULL, `?` CHAR(255) PRIMARY KEY `?`)";
2650 r = run_query(hdb, rec, query);
2651 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
2652 MsiCloseHandle(rec);
2653
2654 /* try a legit insert */
2655 query = "INSERT INTO `Table` ( `One`, `Two` ) VALUES ( 5, 'hello' )";
2656 r = run_query(hdb, 0, query);
2657 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2658
2659 r = try_query(hdb, "SELECT * from `Table`");
2660 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2661
2662 /* try values as markers */
2663 rec = MsiCreateRecord(2);
2664 MsiRecordSetInteger(rec, 1, 4);
2665 MsiRecordSetStringA(rec, 2, "hi");
2666 query = "INSERT INTO `Table` ( `One`, `Two` ) VALUES ( ?, '?' )";
2667 r = run_query(hdb, rec, query);
2668 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2669 MsiCloseHandle(rec);
2670
2671 /* try column names and values as markers */
2672 rec = MsiCreateRecord(4);
2673 MsiRecordSetStringA(rec, 1, "One");
2674 MsiRecordSetStringA(rec, 2, "Two");
2675 MsiRecordSetInteger(rec, 3, 5);
2676 MsiRecordSetStringA(rec, 4, "hi");
2677 query = "INSERT INTO `Table` ( `?`, `?` ) VALUES ( ?, '?' )";
2678 r = run_query(hdb, rec, query);
2679 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
2680 MsiCloseHandle(rec);
2681
2682 /* try column names as markers */
2683 rec = MsiCreateRecord(2);
2684 MsiRecordSetStringA(rec, 1, "One");
2685 MsiRecordSetStringA(rec, 2, "Two");
2686 query = "INSERT INTO `Table` ( `?`, `?` ) VALUES ( 3, 'yellow' )";
2687 r = run_query(hdb, rec, query);
2688 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
2689 MsiCloseHandle(rec);
2690
2691 /* try table name as a marker */
2692 rec = MsiCreateRecord(1);
2693 MsiRecordSetStringA(rec, 1, "Table");
2694 query = "INSERT INTO `?` ( `One`, `Two` ) VALUES ( 2, 'green' )";
2695 r = run_query(hdb, rec, query);
2696 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2697 MsiCloseHandle(rec);
2698
2699 /* try table name and values as markers */
2700 rec = MsiCreateRecord(3);
2701 MsiRecordSetStringA(rec, 1, "Table");
2702 MsiRecordSetInteger(rec, 2, 10);
2703 MsiRecordSetStringA(rec, 3, "haha");
2704 query = "INSERT INTO `?` ( `One`, `Two` ) VALUES ( ?, '?' )";
2705 r = run_query(hdb, rec, query);
2706 ok(r == ERROR_FUNCTION_FAILED, "Expected ERROR_FUNCTION_FAILED, got %d\n", r);
2707 MsiCloseHandle(rec);
2708
2709 /* try all markers */
2710 rec = MsiCreateRecord(5);
2711 MsiRecordSetStringA(rec, 1, "Table");
2712 MsiRecordSetStringA(rec, 1, "One");
2713 MsiRecordSetStringA(rec, 1, "Two");
2714 MsiRecordSetInteger(rec, 2, 10);
2715 MsiRecordSetStringA(rec, 3, "haha");
2716 query = "INSERT INTO `?` ( `?`, `?` ) VALUES ( ?, '?' )";
2717 r = run_query(hdb, rec, query);
2718 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
2719 MsiCloseHandle(rec);
2720
2721 /* insert an integer as a string */
2722 rec = MsiCreateRecord(2);
2723 MsiRecordSetStringA(rec, 1, "11");
2724 MsiRecordSetStringA(rec, 2, "hi");
2725 query = "INSERT INTO `Table` ( `One`, `Two` ) VALUES ( ?, '?' )";
2726 r = run_query(hdb, rec, query);
2727 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2728 MsiCloseHandle(rec);
2729
2730 /* leave off the '' for the string */
2731 rec = MsiCreateRecord(2);
2732 MsiRecordSetInteger(rec, 1, 12);
2733 MsiRecordSetStringA(rec, 2, "hi");
2734 query = "INSERT INTO `Table` ( `One`, `Two` ) VALUES ( ?, ? )";
2735 r = run_query(hdb, rec, query);
2736 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2737 MsiCloseHandle(rec);
2738
2739 MsiCloseHandle(hdb);
2741}
2742
2743#define MY_NVIEWS 4000 /* Largest installer I've seen uses < 2000 */
2744static void test_handle_limit(void)
2745{
2746 int i;
2747 MSIHANDLE hdb;
2748 MSIHANDLE hviews[MY_NVIEWS];
2749 UINT r;
2750
2751 /* create an empty db */
2752 hdb = create_db();
2753 ok( hdb, "failed to create db\n");
2754
2755 memset(hviews, 0, sizeof(hviews));
2756
2757 for (i=0; i<MY_NVIEWS; i++) {
2758 static char szQueryBuf[256] = "SELECT * from `_Tables`";
2759 hviews[i] = 0xdeadbeeb;
2760 r = MsiDatabaseOpenViewA(hdb, szQueryBuf, &hviews[i]);
2761 if( r != ERROR_SUCCESS || hviews[i] == 0xdeadbeeb ||
2762 hviews[i] == 0 || (i && (hviews[i] == hviews[i-1])))
2763 break;
2764 }
2765
2766 ok( i == MY_NVIEWS, "problem opening views\n");
2767
2768 for (i=0; i<MY_NVIEWS; i++) {
2769 if (hviews[i] != 0 && hviews[i] != 0xdeadbeeb) {
2770 MsiViewClose(hviews[i]);
2771 r = MsiCloseHandle(hviews[i]);
2772 if (r != ERROR_SUCCESS)
2773 break;
2774 }
2775 }
2776
2777 ok( i == MY_NVIEWS, "problem closing views\n");
2778
2779 r = MsiCloseHandle(hdb);
2780 ok( r == ERROR_SUCCESS, "failed to close database\n");
2781}
2782
2783static void generate_transform(void)
2784{
2785 MSIHANDLE hdb1, hdb2, hrec;
2786 LPCSTR query;
2787 UINT r;
2788
2789 /* start with two identical databases */
2791
2793 ok( r == ERROR_SUCCESS , "Failed to create database\n" );
2794
2795 r = MsiDatabaseCommit( hdb1 );
2796 ok( r == ERROR_SUCCESS , "Failed to commit database\n" );
2797
2799 ok( r == ERROR_SUCCESS , "Failed to create database\n" );
2800
2801 /* the transform between two identical database should be empty */
2802 r = MsiDatabaseGenerateTransformA(hdb1, hdb2, NULL, 0, 0);
2803 todo_wine {
2804 ok( r == ERROR_NO_DATA, "return code %d, should be ERROR_NO_DATA\n", r );
2805 }
2806
2807 query = "CREATE TABLE `AAR` ( `BAR` SHORT NOT NULL, `CAR` CHAR(255) PRIMARY KEY `CAR`)";
2808 r = run_query(hdb1, 0, query);
2809 ok(r == ERROR_SUCCESS, "failed to add table\n");
2810
2811 query = "INSERT INTO `AAR` ( `BAR`, `CAR` ) VALUES ( 1, 'vw' )";
2812 r = run_query(hdb1, 0, query);
2813 ok(r == ERROR_SUCCESS, "failed to add row 1\n");
2814
2815 query = "INSERT INTO `AAR` ( `BAR`, `CAR` ) VALUES ( 2, 'bmw' )";
2816 r = run_query(hdb1, 0, query);
2817 ok(r == ERROR_SUCCESS, "failed to add row 2\n");
2818
2819 query = "UPDATE `MOO` SET `OOO` = 'c' WHERE `NOO` = 1";
2820 r = run_query(hdb1, 0, query);
2821 ok(r == ERROR_SUCCESS, "failed to modify row\n");
2822
2823 query = "DELETE FROM `MOO` WHERE `NOO` = 3";
2824 r = run_query(hdb1, 0, query);
2825 ok(r == ERROR_SUCCESS, "failed to delete row\n");
2826
2827 hrec = MsiCreateRecord(2);
2828 r = MsiRecordSetInteger(hrec, 1, 1);
2829 ok(r == ERROR_SUCCESS, "failed to set integer\n");
2830
2831 write_file("testdata.bin", "naengmyon", 9);
2832 r = MsiRecordSetStreamA(hrec, 2, "testdata.bin");
2833 ok(r == ERROR_SUCCESS, "failed to set stream\n");
2834
2835 query = "INSERT INTO `BINARY` ( `ID`, `BLOB` ) VALUES ( ?, ? )";
2836 r = run_query(hdb1, hrec, query);
2837 ok(r == ERROR_SUCCESS, "failed to add row with blob\n");
2838
2839 MsiCloseHandle(hrec);
2840
2841 query = "ALTER TABLE `MOO` ADD `COW` INTEGER";
2842 r = run_query(hdb1, 0, query);
2843 ok(r == ERROR_SUCCESS, "failed to add column\n");
2844
2845 query = "ALTER TABLE `MOO` ADD `PIG` INTEGER";
2846 r = run_query(hdb1, 0, query);
2847 ok(r == ERROR_SUCCESS, "failed to add column\n");
2848
2849 query = "UPDATE `MOO` SET `PIG` = 5 WHERE `NOO` = 1";
2850 r = run_query(hdb1, 0, query);
2851 ok(r == ERROR_SUCCESS, "failed to modify row\n");
2852
2853 query = "CREATE TABLE `Property` ( `Property` CHAR(72) NOT NULL, "
2854 "`Value` CHAR(0) PRIMARY KEY `Property`)";
2855 r = run_query(hdb1, 0, query);
2856 ok(r == ERROR_SUCCESS, "failed to add property table\n");
2857
2858 query = "INSERT INTO `Property` ( `Property`, `Value` ) VALUES ( 'prop', 'val' )";
2859 r = run_query(hdb1, 0, query);
2860 ok(r == ERROR_SUCCESS, "failed to add property\n");
2861
2862 /* database needs to be committed */
2863 MsiDatabaseCommit(hdb1);
2864
2865 r = MsiDatabaseGenerateTransformA(hdb1, hdb2, mstfile, 0, 0);
2866 ok( r == ERROR_SUCCESS, "return code %d, should be ERROR_SUCCESS\n", r );
2867
2868 MsiCloseHandle( hdb1 );
2869 MsiCloseHandle( hdb2 );
2870
2871 DeleteFileA("testdata.bin");
2872}
2873
2874/* data for generating a transform */
2875
2876/* tables transform names - encoded as they would be in an msi database file */
2877static const WCHAR name1[] = { 0x4840, 0x3a8a, 0x481b, 0 }; /* AAR */
2878static const WCHAR name2[] = { 0x4840, 0x3b3f, 0x43f2, 0x4438, 0x45b1, 0 }; /* _Columns */
2879static const WCHAR name3[] = { 0x4840, 0x3f7f, 0x4164, 0x422f, 0x4836, 0 }; /* _Tables */
2880static const WCHAR name4[] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3b6a, 0x45e4, 0x4824, 0 }; /* _StringData */
2881static const WCHAR name5[] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3e6a, 0x44b2, 0x482f, 0 }; /* _StringPool */
2882static const WCHAR name6[] = { 0x4840, 0x3e16, 0x4818, 0}; /* MOO */
2883static const WCHAR name7[] = { 0x4840, 0x3c8b, 0x3a97, 0x409b, 0 }; /* BINARY */
2884static const WCHAR name8[] = { 0x3c8b, 0x3a97, 0x409b, 0x387e, 0 }; /* BINARY.1 */
2885static const WCHAR name9[] = { 0x4840, 0x4559, 0x44f2, 0x4568, 0x4737, 0 }; /* Property */
2886
2887/* data in each table */
2888static const WCHAR data1[] = { /* AAR */
2889 0x0201, 0x0008, 0x8001, /* 0x0201 = add row (1), two shorts */
2890 0x0201, 0x0009, 0x8002,
2891};
2892static const WCHAR data2[] = { /* _Columns */
2893 0x0401, 0x0001, 0x8003, 0x0002, 0x9502,
2894 0x0401, 0x0001, 0x8004, 0x0003, 0x9502,
2895 0x0401, 0x0005, 0x0000, 0x0006, 0xbdff, /* 0x0401 = add row (1), 4 shorts */
2896 0x0401, 0x0005, 0x0000, 0x0007, 0x8502,
2897 0x0401, 0x000a, 0x0000, 0x000a, 0xad48,
2898 0x0401, 0x000a, 0x0000, 0x000b, 0x9d00,
2899};
2900static const WCHAR data3[] = { /* _Tables */
2901 0x0101, 0x0005, /* 0x0101 = add row (1), 1 short */
2902 0x0101, 0x000a,
2903};
2904static const char data4[] = /* _StringData */
2905 "MOOCOWPIGcAARCARBARvwbmwPropertyValuepropval"; /* all the strings squashed together */
2906static const WCHAR data5[] = { /* _StringPool */
2907/* len, refs */
2908 0, 0, /* string 0 '' */
2909 3, 2, /* string 1 'MOO' */
2910 3, 1, /* string 2 'COW' */
2911 3, 1, /* string 3 'PIG' */
2912 1, 1, /* string 4 'c' */
2913 3, 3, /* string 5 'AAR' */
2914 3, 1, /* string 6 'CAR' */
2915 3, 1, /* string 7 'BAR' */
2916 2, 1, /* string 8 'vw' */
2917 3, 1, /* string 9 'bmw' */
2918 8, 4, /* string 10 'Property' */
2919 5, 1, /* string 11 'Value' */
2920 4, 1, /* string 12 'prop' */
2921 3, 1, /* string 13 'val' */
2922};
2923/* update row, 0x0002 is a bitmask of present column data, keys are excluded */
2924static const WCHAR data6[] = { /* MOO */
2925 0x000a, 0x8001, 0x0004, 0x8005, /* update row */
2926 0x0000, 0x8003, /* delete row */
2927};
2928
2929static const WCHAR data7[] = { /* BINARY */
2930 0x0201, 0x8001, 0x0001,
2931};
2932
2933static const char data8[] = /* stream data for the BINARY table */
2934 "naengmyon";
2935
2936static const WCHAR data9[] = { /* Property */
2937 0x0201, 0x000c, 0x000d,
2938};
2939
2940static const struct {
2942 const void *data;
2945{
2946 { name1, data1, sizeof data1 },
2947 { name2, data2, sizeof data2 },
2948 { name3, data3, sizeof data3 },
2949 { name4, data4, sizeof data4 - 1 },
2950 { name5, data5, sizeof data5 },
2951 { name6, data6, sizeof data6 },
2952 { name7, data7, sizeof data7 },
2953 { name8, data8, sizeof data8 - 1 },
2954 { name9, data9, sizeof data9 },
2956
2958{
2959 IStorage *stg = NULL;
2960 IStream *stm;
2961 WCHAR name[0x20];
2962 HRESULT r;
2963 DWORD i, count;
2965
2966 const CLSID CLSID_MsiTransform = { 0xc1082,0,0,{0xc0,0,0,0,0,0,0,0x46}};
2967
2968 MultiByteToWideChar(CP_ACP, 0, mstfile, -1, name, 0x20);
2969
2970 r = StgCreateDocfile(name, mode, 0, &stg);
2971 ok(r == S_OK, "failed to create storage\n");
2972 if (!stg)
2973 return;
2974
2975 r = IStorage_SetClass( stg, &CLSID_MsiTransform );
2976 ok(r == S_OK, "failed to set storage type\n");
2977
2978 for (i=0; i<ARRAY_SIZE(table_transform_data); i++)
2979 {
2980 r = IStorage_CreateStream( stg, table_transform_data[i].name,
2981 STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm );
2982 if (FAILED(r))
2983 {
2984 ok(0, "failed to create stream %#lx\n", r);
2985 continue;
2986 }
2987
2988 r = IStream_Write( stm, table_transform_data[i].data,
2991 ok(0, "failed to write stream\n");
2992 IStream_Release(stm);
2993 }
2994
2995 IStorage_Release(stg);
2996}
2997
2999{
3000 UINT res;
3002
3003 /* build summary info */
3005 ok( res == ERROR_SUCCESS , "Failed to open summaryinfo\n" );
3006
3008 "Installation Database");
3009 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
3010
3012 "Installation Database");
3013 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
3014
3016 "Wine Hackers");
3017 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
3018
3020 ";1033,2057");
3021 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
3022
3024 "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}");
3025 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
3026
3028 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
3029
3031 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
3032
3034 ok( res == ERROR_SUCCESS , "Failed to make summary info persist\n" );
3035
3037 ok( res == ERROR_SUCCESS , "Failed to close suminfo\n" );
3038
3039 return res;
3040}
3041
3043{
3044 MSIHANDLE hdb = 0;
3045 UINT res;
3046
3048
3049 /* create an empty database */
3051 ok( res == ERROR_SUCCESS , "Failed to create database\n" );
3052 if( res != ERROR_SUCCESS )
3053 return hdb;
3054
3055 res = MsiDatabaseCommit( hdb );
3056 ok( res == ERROR_SUCCESS , "Failed to commit database\n" );
3057
3058 res = set_summary_info(hdb);
3059 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
3060
3062
3063 return hdb;
3064}
3065
3067{
3068 UINT res;
3069 CHAR szPackage[12];
3070 MSIHANDLE hPackage;
3071
3072 sprintf(szPackage, "#%lu", hdb);
3073 res = MsiOpenPackageA(szPackage, &hPackage);
3074 if (res != ERROR_SUCCESS)
3075 return res;
3076
3077 res = MsiCloseHandle(hdb);
3078 if (res != ERROR_SUCCESS)
3079 {
3080 MsiCloseHandle(hPackage);
3081 return res;
3082 }
3083
3084 *handle = hPackage;
3085 return ERROR_SUCCESS;
3086}
3087
3088static void test_try_transform(void)
3089{
3090 static const struct {
3091 const char *table;
3092 const char *column;
3093 const char *row;
3094 const char *data;
3095 const char *current;
3096 } transform_view[] = {
3097 { "MOO", "OOO", "1", "c", "a" },
3098 { "MOO", "COW", "", "5378", "3" },
3099 { "MOO", "PIG", "", "5378", "4" },
3100 { "MOO", "PIG", "1", "5", "" },
3101 { "MOO", "DELETE", "3", "", "" },
3102 { "BINARY", "BLOB", "1", "BINARY.1", "" },
3103 { "BINARY", "INSERT", "1", "", "" },
3104 { "AAR", "CREATE", "", "", "" },
3105 { "AAR", "CAR", "", "15871", "1" },
3106 { "AAR", "BAR", "", "1282", "2" },
3107 { "AAR", "BAR", "vw", "1", "" },
3108 { "AAR", "BAR", "bmw", "2", "" },
3109 { "AAR", "INSERT", "vw", "", "" },
3110 { "AAR", "INSERT", "bmw", "", "" },
3111 { "Property", "CREATE", "", "", "" },
3112 { "Property", "Property", "", "11592", "1" },
3113 { "Property", "Value", "", "7424", "2" },
3114 { "Property", "Value", "prop", "val", "" },
3115 { "Property", "INSERT", "prop", "", "" }
3116 };
3117
3118 MSIHANDLE hdb, hview, hrec, hpkg = 0;
3119 LPCSTR query;
3120 UINT r;
3121 DWORD sz;
3122 char buffer[MAX_PATH];
3123 int i, matched;
3124
3127
3128 /* create the database */
3130 ok(hdb, "Failed to create package db\n");
3131
3132 query = "CREATE TABLE `MOO` ( `NOO` SHORT NOT NULL, `OOO` CHAR(255) PRIMARY KEY `NOO`)";
3133 r = run_query(hdb, 0, query);
3134 ok(r == ERROR_SUCCESS, "failed to add table\n");
3135
3136 query = "INSERT INTO `MOO` ( `NOO`, `OOO` ) VALUES ( 1, 'a' )";
3137 r = run_query(hdb, 0, query);
3138 ok(r == ERROR_SUCCESS, "failed to add row\n");
3139
3140 query = "INSERT INTO `MOO` ( `NOO`, `OOO` ) VALUES ( 2, 'b' )";
3141 r = run_query(hdb, 0, query);
3142 ok(r == ERROR_SUCCESS, "failed to add row\n");
3143
3144 query = "INSERT INTO `MOO` ( `NOO`, `OOO` ) VALUES ( 3, 'c' )";
3145 r = run_query(hdb, 0, query);
3146 ok(r == ERROR_SUCCESS, "failed to add row\n");
3147
3148 query = "CREATE TABLE `BINARY` ( `ID` SHORT NOT NULL, `BLOB` OBJECT PRIMARY KEY `ID`)";
3149 r = run_query(hdb, 0, query);
3150 ok(r == ERROR_SUCCESS, "failed to add table\n");
3151
3152 hrec = MsiCreateRecord(2);
3153 r = MsiRecordSetInteger(hrec, 1, 2);
3154 ok(r == ERROR_SUCCESS, "failed to set integer\n");
3155
3156 write_file("testdata.bin", "lamyon", 6);
3157 r = MsiRecordSetStreamA(hrec, 2, "testdata.bin");
3158 ok(r == ERROR_SUCCESS, "failed to set stream\n");
3159
3160 query = "INSERT INTO `BINARY` ( `ID`, `BLOB` ) VALUES ( ?, ? )";
3161 r = run_query(hdb, hrec, query);
3162 ok(r == ERROR_SUCCESS, "failed to add row with blob\n");
3163
3164 MsiCloseHandle(hrec);
3165
3166 r = MsiDatabaseCommit( hdb );
3167 ok( r == ERROR_SUCCESS , "Failed to commit database\n" );
3168
3169 MsiCloseHandle( hdb );
3170 DeleteFileA("testdata.bin");
3171
3172 /*
3173 * Both these generate an equivalent transform,
3174 * but the first doesn't work in Wine yet
3175 * because MsiDatabaseGenerateTransform is unimplemented.
3176 */
3177 if (0)
3179 else
3181
3183 ok( r == ERROR_SUCCESS , "Failed to create database\n" );
3184
3186 ok(r == ERROR_SUCCESS, "return code %d, should be ERROR_SUCCESS\n", r);
3187
3188 query = "select * from `_TransformView`";
3189 r = MsiDatabaseOpenViewA(hdb, query, &hview);
3190 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
3191 r = MsiViewExecute(hview, 0);
3192 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
3193
3194 r = MsiViewGetColumnInfo(hview, MSICOLINFO_NAMES, &hrec);
3195 ok(r == ERROR_SUCCESS, "error\n");
3196 check_record(hrec, 5, "Table", "Column", "Row", "Data", "Current");
3197 MsiCloseHandle(hrec);
3198
3199 r = MsiViewGetColumnInfo(hview, MSICOLINFO_TYPES, &hrec);
3200 ok(r == ERROR_SUCCESS, "error\n");
3201 check_record(hrec, 5, "g0", "g0", "G0", "G0", "G0");
3202 MsiCloseHandle(hrec);
3203
3204 matched = 0;
3205 while (MsiViewFetch(hview, &hrec) == ERROR_SUCCESS)
3206 {
3207 char data[5][256];
3208
3209 for (i = 1; i <= 5; i++) {
3210 sz = ARRAY_SIZE(data[0]);
3211 r = MsiRecordGetStringA(hrec, i, data[i-1], &sz);
3212 ok(r == ERROR_SUCCESS, "%d) MsiRecordGetStringA failed %d\n", i, r);
3213 }
3214
3215 for (i = 0; i < ARRAY_SIZE(transform_view); i++)
3216 {
3217 if (strcmp(data[0], transform_view[i].table) ||
3220 continue;
3221
3222 matched++;
3223 ok(!strcmp(data[3], transform_view[i].data), "%d) data[3] = %s\n", i, data[3]);
3224 ok(!strcmp(data[4], transform_view[i].current), "%d) data[4] = %s\n", i, data[4]);
3225 break;
3226 }
3227 ok(i != ARRAY_SIZE(transform_view), "invalid row: %s, %s, %s\n",
3229 MsiCloseHandle(hrec);
3230 }
3231 ok(matched == ARRAY_SIZE(transform_view), "matched = %d\n", matched);
3232
3233 r = MsiViewClose(hview);
3234 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
3235 r = MsiCloseHandle(hview);
3236 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
3237
3238 query = "ALTER TABLE `_TransformView` FREE";
3239 r = run_query( hdb, 0, query );
3240 ok( r == ERROR_SUCCESS, "cannot free _TransformView table: %d\n", r );
3241 r = run_query( hdb, 0, query );
3242 ok( r == ERROR_BAD_QUERY_SYNTAX, "_TransformView table still exist: %d\n", r );
3243
3245 ok( r == ERROR_SUCCESS, "return code %d, should be ERROR_SUCCESS\n", r );
3246
3247 r = MsiDatabaseCommit( hdb );
3248 ok( r == ERROR_SUCCESS , "Failed to commit database\n" );
3249
3250 /* check new values */
3251 hrec = 0;
3252 query = "select `BAR`,`CAR` from `AAR` where `BAR` = 1 AND `CAR` = 'vw'";
3253 r = do_query(hdb, query, &hrec);
3254 ok(r == ERROR_SUCCESS, "select query failed\n");
3255 MsiCloseHandle(hrec);
3256
3257 query = "select `BAR`,`CAR` from `AAR` where `BAR` = 2 AND `CAR` = 'bmw'";
3258 hrec = 0;
3259 r = do_query(hdb, query, &hrec);
3260 ok(r == ERROR_SUCCESS, "select query failed\n");
3261 MsiCloseHandle(hrec);
3262
3263 /* check updated values */
3264 hrec = 0;
3265 query = "select `NOO`,`OOO` from `MOO` where `NOO` = 1 AND `OOO` = 'c'";
3266 r = do_query(hdb, query, &hrec);
3267 ok(r == ERROR_SUCCESS, "select query failed\n");
3268 MsiCloseHandle(hrec);
3269
3270 /* check unchanged value */
3271 hrec = 0;
3272 query = "select `NOO`,`OOO` from `MOO` where `NOO` = 2 AND `OOO` = 'b'";
3273 r = do_query(hdb, query, &hrec);
3274 ok(r == ERROR_SUCCESS, "select query failed\n");
3275 MsiCloseHandle(hrec);
3276
3277 /* check deleted value */
3278 hrec = 0;
3279 query = "select * from `MOO` where `NOO` = 3";
3280 r = do_query(hdb, query, &hrec);
3281 ok(r == ERROR_NO_MORE_ITEMS, "select query failed\n");
3282 if (hrec) MsiCloseHandle(hrec);
3283
3284 /* check added stream */
3285 hrec = 0;
3286 query = "select `BLOB` from `BINARY` where `ID` = 1";
3287 r = do_query(hdb, query, &hrec);
3288 ok(r == ERROR_SUCCESS, "select query failed\n");
3289
3290 /* check the contents of the stream */
3291 sz = sizeof buffer;
3292 r = MsiRecordReadStream( hrec, 1, buffer, &sz );
3293 ok(r == ERROR_SUCCESS, "read stream failed\n");
3294 ok(!memcmp(buffer, "naengmyon", 9), "stream data was wrong\n");
3295 ok(sz == 9, "stream data was wrong size\n");
3296 if (hrec) MsiCloseHandle(hrec);
3297
3298 /* check the validity of the table with a deleted row */
3299 hrec = 0;
3300 query = "select * from `MOO`";
3301 r = MsiDatabaseOpenViewA(hdb, query, &hview);
3302 ok(r == ERROR_SUCCESS, "open view failed\n");
3303
3304 r = MsiViewExecute(hview, 0);
3305 ok(r == ERROR_SUCCESS, "view execute failed\n");
3306
3307 r = MsiViewFetch(hview, &hrec);
3308 ok(r == ERROR_SUCCESS, "view fetch failed\n");
3309 check_record(hrec, 4, "1", "c", "", "5");
3310 MsiCloseHandle(hrec);
3311
3312 r = MsiViewFetch(hview, &hrec);
3313 ok(r == ERROR_SUCCESS, "view fetch failed\n");
3314 check_record(hrec, 4, "2", "b", "", "");
3315 MsiCloseHandle(hrec);
3316
3317 r = MsiViewFetch(hview, &hrec);
3318 ok(r == ERROR_NO_MORE_ITEMS, "view fetch succeeded\n");
3319
3320 MsiCloseHandle(hrec);
3321 MsiViewClose(hview);
3322 MsiCloseHandle(hview);
3323
3324 /* check that the property was added */
3325 r = package_from_db(hdb, &hpkg);
3327 {
3328 skip("Not enough rights to perform tests\n");
3329 goto error;
3330 }
3331 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3332
3333 sz = MAX_PATH;
3334 r = MsiGetPropertyA(hpkg, "prop", buffer, &sz);
3335 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3336 ok(!lstrcmpA(buffer, "val"), "Expected val, got %s\n", buffer);
3337
3338 MsiCloseHandle(hpkg);
3339
3340error:
3341 MsiCloseHandle(hdb);
3344}
3345
3346static const char *join_res_first[][2] =
3347{
3348 { "alveolar", "procerus" },
3349 { "septum", "procerus" },
3350 { "septum", "nasalis" },
3351 { "ramus", "nasalis" },
3352 { "malar", "mentalis" },
3353};
3354
3355static const char *join_res_second[][2] =
3356{
3357 { "nasal", "septum" },
3358 { "mandible", "ramus" },
3359};
3360
3361static const char *join_res_third[][2] =
3362{
3363 { "msvcp.dll", "abcdefgh" },
3364 { "msvcr.dll", "ijklmnop" },
3365};
3366
3367static const char *join_res_fourth[][2] =
3368{
3369 { "msvcp.dll.01234", "single.dll.31415" },
3370};
3371
3372static const char *join_res_fifth[][2] =
3373{
3374 { "malar", "procerus" },
3375};
3376
3377static const char *join_res_sixth[][2] =
3378{
3379 { "malar", "procerus" },
3380 { "malar", "procerus" },
3381 { "malar", "nasalis" },
3382 { "malar", "nasalis" },
3383 { "malar", "nasalis" },
3384 { "malar", "mentalis" },
3385};
3386
3387static const char *join_res_seventh[][2] =
3388{
3389 { "malar", "nasalis" },
3390 { "malar", "nasalis" },
3391 { "malar", "nasalis" },
3392};
3393
3394static const char *join_res_eighth[][4] =
3395{
3396 { "msvcp.dll", "msvcp.dll.01234", "msvcp.dll.01234", "abcdefgh" },
3397 { "msvcr.dll", "msvcr.dll.56789", "msvcp.dll.01234", "abcdefgh" },
3398 { "msvcp.dll", "msvcp.dll.01234", "msvcr.dll.56789", "ijklmnop" },
3399 { "msvcr.dll", "msvcr.dll.56789", "msvcr.dll.56789", "ijklmnop" },
3400 { "msvcp.dll", "msvcp.dll.01234", "single.dll.31415", "msvcp.dll" },
3401 { "msvcr.dll", "msvcr.dll.56789", "single.dll.31415", "msvcp.dll" },
3402};
3403
3404static const char *join_res_ninth[][6] =
3405{
3406 { "1", "2", "3", "4", "7", "8" },
3407 { "1", "2", "5", "6", "7", "8" },
3408 { "1", "2", "3", "4", "9", "10" },
3409 { "1", "2", "5", "6", "9", "10" },
3410 { "1", "2", "3", "4", "11", "12" },
3411 { "1", "2", "5", "6", "11", "12" },
3412};
3413
3414static void test_join(void)
3415{
3416 MSIHANDLE hdb, hview, hrec;
3417 LPCSTR query;
3418 UINT r;
3419 DWORD i;
3420
3421 hdb = create_db();
3422 ok( hdb, "failed to create db\n");
3423
3425 add_component_entry( hdb, "'zygomatic', 'malar', 'INSTALLDIR', 0, '', ''" );
3426 add_component_entry( hdb, "'maxilla', 'alveolar', 'INSTALLDIR', 0, '', ''" );
3427 add_component_entry( hdb, "'nasal', 'septum', 'INSTALLDIR', 0, '', ''" );
3428 add_component_entry( hdb, "'mandible', 'ramus', 'INSTALLDIR', 0, '', ''" );
3429
3431 add_feature_components_entry( hdb, "'procerus', 'maxilla'" );
3432 add_feature_components_entry( hdb, "'procerus', 'nasal'" );
3433 add_feature_components_entry( hdb, "'nasalis', 'nasal'" );
3434 add_feature_components_entry( hdb, "'nasalis', 'mandible'" );
3435 add_feature_components_entry( hdb, "'nasalis', 'notacomponent'" );
3436 add_feature_components_entry( hdb, "'mentalis', 'zygomatic'" );
3437
3438 create_std_dlls_table( hdb );
3439 add_std_dlls_entry( hdb, "'msvcp.dll', 'msvcp.dll.01234'" );
3440 add_std_dlls_entry( hdb, "'msvcr.dll', 'msvcr.dll.56789'" );
3441
3442 create_binary_table( hdb );
3443 add_binary_entry( hdb, "'msvcp.dll.01234', 'abcdefgh'" );
3444 add_binary_entry( hdb, "'msvcr.dll.56789', 'ijklmnop'" );
3445 add_binary_entry( hdb, "'single.dll.31415', 'msvcp.dll'" );
3446
3447 query = "CREATE TABLE `One` (`A` SHORT, `B` SHORT PRIMARY KEY `A`)";
3448 r = run_query( hdb, 0, query);
3449 ok(r == ERROR_SUCCESS, "cannot create table: %d\n", r );
3450
3451 query = "CREATE TABLE `Two` (`C` SHORT, `D` SHORT PRIMARY KEY `C`)";
3452 r = run_query( hdb, 0, query);
3453 ok(r == ERROR_SUCCESS, "cannot create table: %d\n", r );
3454
3455 query = "CREATE TABLE `Three` (`E` SHORT, `F` SHORT PRIMARY KEY `E`)";
3456 r = run_query( hdb, 0, query);
3457 ok(r == ERROR_SUCCESS, "cannot create table: %d\n", r );
3458
3459 query = "INSERT INTO `One` (`A`, `B`) VALUES (1, 2)";
3460 r = run_query( hdb, 0, query);
3461 ok(r == ERROR_SUCCESS, "cannot insert into table: %d\n", r );
3462
3463 query = "INSERT INTO `Two` (`C`, `D`) VALUES (3, 4)";
3464 r = run_query( hdb, 0, query);
3465 ok(r == ERROR_SUCCESS, "cannot insert into table: %d\n", r );
3466
3467 query = "INSERT INTO `Two` (`C`, `D`) VALUES (5, 6)";
3468 r = run_query( hdb, 0, query);
3469 ok(r == ERROR_SUCCESS, "cannot insert into table: %d\n", r );
3470
3471 query = "INSERT INTO `Three` (`E`, `F`) VALUES (7, 8)";
3472 r = run_query( hdb, 0, query);
3473 ok(r == ERROR_SUCCESS, "cannot insert into table: %d\n", r );
3474
3475 query = "INSERT INTO `Three` (`E`, `F`) VALUES (9, 10)";
3476 r = run_query( hdb, 0, query);
3477 ok(r == ERROR_SUCCESS, "cannot insert into table: %d\n", r );
3478
3479 query = "INSERT INTO `Three` (`E`, `F`) VALUES (11, 12)";
3480 r = run_query( hdb, 0, query);
3481 ok(r == ERROR_SUCCESS, "cannot insert into table: %d\n", r );
3482
3483 query = "CREATE TABLE `Four` (`G` SHORT, `H` SHORT PRIMARY KEY `G`)";
3484 r = run_query( hdb, 0, query);
3485 ok(r == ERROR_SUCCESS, "cannot create table: %d\n", r );
3486
3487 query = "CREATE TABLE `Five` (`I` SHORT, `J` SHORT PRIMARY KEY `I`)";
3488 r = run_query( hdb, 0, query);
3489 ok(r == ERROR_SUCCESS, "cannot create table: %d\n", r );
3490
3491 query = "INSERT INTO `Five` (`I`, `J`) VALUES (13, 14)";
3492 r = run_query( hdb, 0, query);
3493 ok(r == ERROR_SUCCESS, "cannot insert into table: %d\n", r );
3494
3495 query = "INSERT INTO `Five` (`I`, `J`) VALUES (15, 16)";
3496 r = run_query( hdb, 0, query);
3497 ok(r == ERROR_SUCCESS, "cannot insert into table: %d\n", r );
3498
3499 query = "SELECT `Component`.`ComponentId`, `FeatureComponents`.`Feature_` "
3500 "FROM `Component`, `FeatureComponents` "
3501 "WHERE `Component`.`Component` = `FeatureComponents`.`Component_` "
3502 "ORDER BY `Feature_`";
3503 r = MsiDatabaseOpenViewA(hdb, query, &hview);
3504 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r );
3505
3506 r = MsiViewExecute(hview, 0);
3507 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r );
3508
3509 i = 0;
3510 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS)
3511 {
3512 check_record(hrec, 2, join_res_first[i][0], join_res_first[i][1]);
3513 i++;
3514 MsiCloseHandle(hrec);
3515 }
3516 ok( i == 5, "Expected 5 rows, got %lu\n", i );
3517 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r );
3518
3519 MsiViewClose(hview);
3520 MsiCloseHandle(hview);
3521
3522 /* try a join without a WHERE condition */
3523 query = "SELECT `Component`.`ComponentId`, `FeatureComponents`.`Feature_` "
3524 "FROM `Component`, `FeatureComponents` ";
3525 r = MsiDatabaseOpenViewA(hdb, query, &hview);
3526 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r );
3527
3528 r = MsiViewExecute(hview, 0);
3529 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r );
3530
3531 i = 0;
3532 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS)
3533 {
3534 i++;
3535 MsiCloseHandle(hrec);
3536 }
3537 ok( i == 24, "Expected 24 rows, got %lu\n", i );
3538
3539 MsiViewClose(hview);
3540 MsiCloseHandle(hview);
3541
3542 query = "SELECT DISTINCT Component, ComponentId FROM FeatureComponents, Component "
3543 "WHERE FeatureComponents.Component_=Component.Component "
3544 "AND (Feature_='nasalis') ORDER BY Feature_";
3545 r = MsiDatabaseOpenViewA(hdb, query, &hview);
3546 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r );
3547
3548 r = MsiViewExecute(hview, 0);
3549 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r );
3550
3551 i = 0;
3552 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS)
3553 {
3554 check_record(hrec, 2, join_res_second[i][0], join_res_second[i][1]);
3555 i++;
3556 MsiCloseHandle(hrec);
3557 }
3558
3559 ok( i == 2, "Expected 2 rows, got %lu\n", i );
3560 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r );
3561
3562 MsiViewClose(hview);
3563 MsiCloseHandle(hview);
3564
3565 query = "SELECT `StdDlls`.`File`, `Binary`.`Data` "
3566 "FROM `StdDlls`, `Binary` "
3567 "WHERE `StdDlls`.`Binary_` = `Binary`.`Name` "
3568 "ORDER BY `File`";
3569 r = MsiDatabaseOpenViewA(hdb, query, &hview);
3570 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r );
3571
3572 r = MsiViewExecute(hview, 0);
3573 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r );
3574
3575 i = 0;
3576 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS)
3577 {
3578 check_record(hrec, 2, join_res_third[i][0], join_res_third[i][1]);
3579 i++;
3580 MsiCloseHandle(hrec);
3581 }
3582 ok( i == 2, "Expected 2 rows, got %lu\n", i );
3583 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r );
3584
3585 MsiViewClose(hview);
3586 MsiCloseHandle(hview);
3587
3588 query = "SELECT `StdDlls`.`Binary_`, `Binary`.`Name` "
3589 "FROM `StdDlls`, `Binary` "
3590 "WHERE `StdDlls`.`File` = `Binary`.`Data` "
3591 "ORDER BY `Name`";
3592 r = MsiDatabaseOpenViewA(hdb, query, &hview);
3593 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r );
3594
3595 r = MsiViewExecute(hview, 0);
3596 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r );
3597
3598 i = 0;
3599 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS)
3600 {
3601 check_record(hrec, 2, join_res_fourth[i][0], join_res_fourth[i][1]);
3602 i++;
3603 MsiCloseHandle(hrec);
3604 }
3605 ok( i == 1, "Expected 1 rows, got %lu\n", i );
3606 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r );
3607
3608 MsiViewClose(hview);
3609 MsiCloseHandle(hview);
3610
3611 query = "SELECT `Component`.`ComponentId`, `FeatureComponents`.`Feature_` "
3612 "FROM `Component`, `FeatureComponents` "
3613 "WHERE `Component`.`Component` = 'zygomatic' "
3614 "AND `FeatureComponents`.`Component_` = 'maxilla' "
3615 "ORDER BY `Feature_`";
3616 r = MsiDatabaseOpenViewA(hdb, query, &hview);
3617 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r );
3618
3619 r = MsiViewExecute(hview, 0);
3620 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r );
3621
3622 i = 0;
3623 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS)
3624 {
3625 check_record(hrec, 2, join_res_fifth[i][0], join_res_fifth[i][1]);
3626 i++;
3627 MsiCloseHandle(hrec);
3628 }
3629 ok( i == 1, "Expected 1 rows, got %lu\n", i );
3630 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r );
3631
3632 MsiViewClose(hview);
3633 MsiCloseHandle(hview);
3634
3635 query = "SELECT `Component`.`ComponentId`, `FeatureComponents`.`Feature_` "
3636 "FROM `Component`, `FeatureComponents` "
3637 "WHERE `Component` = 'zygomatic' "
3638 "ORDER BY `Feature_`";
3639 r = MsiDatabaseOpenViewA(hdb, query, &hview);
3640 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r );
3641
3642 r = MsiViewExecute(hview, 0);
3643 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r );
3644
3645 i = 0;
3646 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS)
3647 {
3648 check_record(hrec, 2, join_res_sixth[i][0], join_res_sixth[i][1]);
3649 i++;
3650 MsiCloseHandle(hrec);
3651 }
3652 ok( i == 6, "Expected 6 rows, got %lu\n", i );
3653 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r );
3654
3655 MsiViewClose(hview);
3656 MsiCloseHandle(hview);
3657
3658 query = "SELECT `Component`.`ComponentId`, `FeatureComponents`.`Feature_` "
3659 "FROM `Component`, `FeatureComponents` "
3660 "WHERE `Component` = 'zygomatic' "
3661 "AND `Feature_` = 'nasalis' "
3662 "ORDER BY `Feature_`";
3663 r = MsiDatabaseOpenViewA(hdb, query, &hview);
3664 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r );
3665
3666 r = MsiViewExecute(hview, 0);
3667 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r );
3668
3669 i = 0;
3670 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS)
3671 {
3673 i++;
3674 MsiCloseHandle(hrec);
3675 }
3676 ok( i == 3, "Expected 3 rows, got %lu\n", i );
3677 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r );
3678
3679 MsiViewClose(hview);
3680 MsiCloseHandle(hview);
3681
3682 query = "SELECT `StdDlls`.`File`, `Binary`.`Data` "
3683 "FROM `StdDlls`, `Binary` ";
3684 r = MsiDatabaseOpenViewA(hdb, query, &hview);
3685 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r );
3686
3687 r = MsiViewExecute(hview, 0);
3688 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r );
3689
3690 i = 0;
3691 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS)
3692 {
3693 check_record(hrec, 2, join_res_eighth[i][0], join_res_eighth[i][3]);
3694 i++;
3695 MsiCloseHandle(hrec);
3696 }
3697 ok( i == 6, "Expected 6 rows, got %lu\n", i );
3698 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r );
3699
3700 MsiViewClose(hview);
3701 MsiCloseHandle(hview);
3702
3703 query = "SELECT * FROM `StdDlls`, `Binary` ";
3704 r = MsiDatabaseOpenViewA(hdb, query, &hview);
3705 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r );
3706
3707 r = MsiViewExecute(hview, 0);
3708 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r );
3709
3710 i = 0;
3711 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS)
3712 {
3715 i++;
3716 MsiCloseHandle(hrec);
3717 }
3718 ok( i == 6, "Expected 6 rows, got %lu\n", i );
3719 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r );
3720
3721 MsiViewClose(hview);
3722 MsiCloseHandle(hview);
3723
3724 query = "SELECT * FROM `One`, `Two`, `Three` ";
3725 r = MsiDatabaseOpenViewA(hdb, query, &hview);
3726 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r );
3727
3728 r = MsiViewExecute(hview, 0);
3729 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r );
3730
3731 i = 0;
3732 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS)
3733 {
3734 check_record(hrec, 6, join_res_ninth[i][0], join_res_ninth[i][1],
3736 join_res_ninth[i][4], join_res_ninth[i][5]);
3737 i++;
3738 MsiCloseHandle(hrec);
3739 }
3740 ok( i == 6, "Expected 6 rows, got %lu\n", i );
3741 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r );
3742
3743 MsiViewClose(hview);
3744 MsiCloseHandle(hview);
3745
3746 query = "SELECT * FROM `Four`, `Five`";
3747 r = MsiDatabaseOpenViewA(hdb, query, &hview);
3748 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r );
3749
3750 r = MsiViewExecute(hview, 0);
3751 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r );
3752
3753 r = MsiViewFetch(hview, &hrec);
3754 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
3755
3756 MsiViewClose(hview);
3757 MsiCloseHandle(hview);
3758
3759 query = "SELECT * FROM `Nonexistent`, `One`";
3760 r = MsiDatabaseOpenViewA(hdb, query, &hview);
3762 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r );
3763
3764 /* try updating a row in a join table */
3765 query = "SELECT `Component`.`ComponentId`, `FeatureComponents`.`Feature_` "
3766 "FROM `Component`, `FeatureComponents` "
3767 "WHERE `Component`.`Component` = `FeatureComponents`.`Component_` "
3768 "ORDER BY `Feature_`";
3769 r = MsiDatabaseOpenViewA(hdb, query, &hview);
3770 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r );
3771
3772 r = MsiViewExecute(hview, 0);
3773 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r );
3774
3775 r = MsiViewFetch(hview, &hrec);
3776 ok( r == ERROR_SUCCESS, "failed to fetch view: %d\n", r );
3777 check_record(hrec, 2, "alveolar", "procerus");
3778
3779 r = MsiRecordSetStringA( hrec, 1, "fascia" );
3780 ok( r == ERROR_SUCCESS, "failed to set string: %d\n", r );
3781 r = MsiRecordSetStringA( hrec, 2, "pterygoid" );
3782 ok( r == ERROR_SUCCESS, "failed to set string: %d\n", r );
3783
3784 r = MsiViewModify(hview, MSIMODIFY_REFRESH, hrec);
3785 ok( r == ERROR_SUCCESS, "failed to refresh row: %d\n", r );
3786 check_record(hrec, 2, "alveolar", "procerus");
3787
3788 r = MsiRecordSetStringA( hrec, 1, "epicranius" );
3789 ok( r == ERROR_SUCCESS, "failed to set string: %d\n", r );
3790
3791 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec);
3792 ok( r == ERROR_SUCCESS, "failed to update row: %d\n", r );
3793
3794 /* primary key cannot be updated */
3795 r = MsiRecordSetStringA( hrec, 2, "epicranius" );
3796 ok( r == ERROR_SUCCESS, "failed to set string: %d\n", r );
3797
3798 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec);
3799 ok( r == ERROR_FUNCTION_FAILED, "failed to update row: %d\n", r );
3800
3801 /* all other operations are invalid for joins */
3802 r = MsiViewModify(hview, MSIMODIFY_SEEK, hrec);
3803 ok( r == ERROR_FUNCTION_FAILED, "unexpected result: %d\n", r );
3804
3805 r = MsiViewModify(hview, MSIMODIFY_ASSIGN, hrec);
3806 ok( r == ERROR_FUNCTION_FAILED, "unexpected result: %d\n", r );
3807
3808 r = MsiViewModify(hview, MSIMODIFY_REPLACE, hrec);
3809 ok( r == ERROR_FUNCTION_FAILED, "unexpected result: %d\n", r );
3810
3811 r = MsiViewModify(hview, MSIMODIFY_MERGE, hrec);
3812 ok( r == ERROR_FUNCTION_FAILED, "unexpected result: %d\n", r );
3813
3814 r = MsiViewModify(hview, MSIMODIFY_DELETE, hrec);
3815 ok( r == ERROR_FUNCTION_FAILED, "unexpected result: %d\n", r );
3816
3817 r = MsiViewModify(hview, MSIMODIFY_VALIDATE, hrec);
3818 ok( r == ERROR_FUNCTION_FAILED, "unexpected result: %d\n", r );
3819
3821 ok( r == ERROR_FUNCTION_FAILED, "unexpected result: %d\n", r );
3822
3823 MsiRecordSetStringA(hrec, 2, "epicranius");
3824 r = MsiViewModify(hview, MSIMODIFY_INSERT, hrec);
3825 ok( r == ERROR_FUNCTION_FAILED, "unexpected result: %d\n", r );
3826
3828 ok( r == ERROR_FUNCTION_FAILED, "unexpected result: %d\n", r );
3829
3830 r = MsiViewModify(hview, MSIMODIFY_VALIDATE_NEW, hrec);
3831 ok( r == ERROR_FUNCTION_FAILED, "unexpected result: %d\n", r );
3832
3834 ok( r == ERROR_FUNCTION_FAILED, "unexpected result: %d\n", r );
3835
3836 MsiCloseHandle(hrec);
3837 MsiViewClose(hview);
3838 MsiCloseHandle(hview);
3839
3840 r = MsiDatabaseOpenViewA(hdb, query, &hview);
3841 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
3842
3843 r = MsiViewExecute(hview, 0);
3844 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
3845
3846 r = MsiViewFetch(hview, &hrec);
3847 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
3848 check_record(hrec, 2, "epicranius", "procerus");
3849 MsiCloseHandle(hrec);
3850
3851 MsiViewClose(hview);
3852 MsiCloseHandle(hview);
3853
3854 MsiCloseHandle(hdb);
3856}
3857
3858static void test_temporary_table(void)
3859{
3860 MSICONDITION cond;
3861 MSIHANDLE hdb = 0, view = 0, rec;
3862 const char *query;
3863 UINT r;
3864
3866 ok( cond == MSICONDITION_ERROR, "wrong return condition\n");
3867
3868 hdb = create_db();
3869 ok( hdb, "failed to create db\n");
3870
3872 ok( cond == MSICONDITION_ERROR, "wrong return condition\n");
3873
3874 cond = MsiDatabaseIsTablePersistentA(hdb, "_Tables");
3875 ok( cond == MSICONDITION_NONE, "wrong return condition\n");
3876
3877 cond = MsiDatabaseIsTablePersistentA(hdb, "_Columns");
3878 ok( cond == MSICONDITION_NONE, "wrong return condition\n");
3879
3880 cond = MsiDatabaseIsTablePersistentA(hdb, "_Storages");
3881 ok( cond == MSICONDITION_NONE, "wrong return condition\n");
3882
3883 cond = MsiDatabaseIsTablePersistentA(hdb, "_Streams");
3884 ok( cond == MSICONDITION_NONE, "wrong return condition\n");
3885
3886 query = "CREATE TABLE `P` ( `B` SHORT NOT NULL, `C` CHAR(255) PRIMARY KEY `C`)";
3887 r = run_query(hdb, 0, query);
3888 ok(r == ERROR_SUCCESS, "failed to add table\n");
3889
3890 cond = MsiDatabaseIsTablePersistentA(hdb, "P");
3891 ok( cond == MSICONDITION_TRUE, "wrong return condition\n");
3892
3893 query = "CREATE TABLE `P2` ( `B` SHORT NOT NULL, `C` CHAR(255) PRIMARY KEY `C`) HOLD";
3894 r = run_query(hdb, 0, query);
3895 ok(r == ERROR_SUCCESS, "failed to add table\n");
3896
3897 cond = MsiDatabaseIsTablePersistentA(hdb, "P2");
3898 ok( cond == MSICONDITION_TRUE, "wrong return condition\n");
3899
3900 query = "CREATE TABLE `T` ( `B` SHORT NOT NULL TEMPORARY, `C` CHAR(255) TEMPORARY PRIMARY KEY `C`) HOLD";
3901 r = run_query(hdb, 0, query);
3902 ok(r == ERROR_SUCCESS, "failed to add table\n");
3903
3904 cond = MsiDatabaseIsTablePersistentA(hdb, "T");
3905 ok( cond == MSICONDITION_FALSE, "wrong return condition\n");
3906
3907 query = "CREATE TABLE `T2` ( `B` SHORT NOT NULL TEMPORARY, `C` CHAR(255) TEMPORARY PRIMARY KEY `C`)";
3908 r = run_query(hdb, 0, query);
3909 ok(r == ERROR_SUCCESS, "failed to add table\n");
3910
3911 query = "SELECT * FROM `T2`";
3912 r = MsiDatabaseOpenViewA(hdb, query, &view);
3914 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
3915
3916 cond = MsiDatabaseIsTablePersistentA(hdb, "T2");
3917 ok( cond == MSICONDITION_NONE, "wrong return condition\n");
3918
3919 query = "CREATE TABLE `T3` ( `B` SHORT NOT NULL TEMPORARY, `C` CHAR(255) PRIMARY KEY `C`)";
3920 r = run_query(hdb, 0, query);
3921 ok(r == ERROR_SUCCESS, "failed to add table\n");
3922
3923 cond = MsiDatabaseIsTablePersistentA(hdb, "T3");
3924 ok( cond == MSICONDITION_TRUE, "wrong return condition\n");
3925
3926 query = "CREATE TABLE `T4` ( `B` SHORT NOT NULL, `C` CHAR(255) TEMPORARY PRIMARY KEY `C`)";
3927 r = run_query(hdb, 0, query);
3928 ok(r == ERROR_FUNCTION_FAILED, "failed to add table\n");
3929
3930 cond = MsiDatabaseIsTablePersistentA(hdb, "T4");
3931 ok( cond == MSICONDITION_NONE, "wrong return condition\n");
3932
3933 query = "CREATE TABLE `T5` ( `B` SHORT NOT NULL TEMP, `C` CHAR(255) TEMP PRIMARY KEY `C`) HOLD";
3934 r = run_query(hdb, 0, query);
3935 ok(r == ERROR_BAD_QUERY_SYNTAX, "failed to add table\n");
3936
3937 query = "select * from `T`";
3938 r = MsiDatabaseOpenViewA(hdb, query, &view);
3939 ok(r == ERROR_SUCCESS, "failed to query table\n");
3941 ok(r == ERROR_SUCCESS, "failed to get column info\n");
3942 check_record(rec, 2, "G255", "j2");
3943 MsiCloseHandle( rec );
3944
3945 MsiViewClose( view );
3947
3948 /* query the table data */
3949 rec = 0;
3950 r = do_query(hdb, "select * from `_Tables` where `Name` = 'T'", &rec);
3951 ok( r == ERROR_SUCCESS, "temporary table exists in _Tables\n");
3952 MsiCloseHandle( rec );
3953
3954 /* query the column data */
3955 rec = 0;
3956 r = do_query(hdb, "select * from `_Columns` where `Table` = 'T' AND `Name` = 'B'", &rec);
3957 ok( r == ERROR_NO_MORE_ITEMS, "temporary table exists in _Columns\n");
3958 if (rec) MsiCloseHandle( rec );
3959
3960 r = do_query(hdb, "select * from `_Columns` where `Table` = 'T' AND `Name` = 'C'", &rec);
3961 ok( r == ERROR_NO_MORE_ITEMS, "temporary table exists in _Columns\n");
3962 if (rec) MsiCloseHandle( rec );
3963
3964 MsiCloseHandle( hdb );
3966}
3967
3968static void test_alter(void)
3969{
3970 MSICONDITION cond;
3971 MSIHANDLE hdb = 0, rec;
3972 const char *query;
3973 UINT r;
3974
3975 hdb = create_db();
3976 ok( hdb, "failed to create db\n");
3977
3978 query = "CREATE TABLE `T` ( `B` SHORT NOT NULL TEMPORARY, `C` CHAR(255) TEMPORARY PRIMARY KEY `C`)";
3979 r = run_query(hdb, 0, query);
3980 ok(r == ERROR_SUCCESS, "failed to add table\n");
3981
3982 query = "SELECT * FROM `T`";
3983 r = run_query(hdb, 0, query);
3984 ok(r == ERROR_BAD_QUERY_SYNTAX, "expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
3985
3986 query = "CREATE TABLE `T` ( `B` SHORT NOT NULL TEMPORARY, `C` CHAR(255) TEMPORARY PRIMARY KEY `C`) HOLD";
3987 r = run_query(hdb, 0, query);
3988 ok(r == ERROR_SUCCESS, "failed to add table\n");
3989
3990 query = "SELECT * FROM `T`";
3991 r = run_query(hdb, 0, query);
3992 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", r);
3993
3994 cond = MsiDatabaseIsTablePersistentA(hdb, "T");
3995 ok( cond == MSICONDITION_FALSE, "wrong return condition\n");
3996
3997 query = "ALTER TABLE `T` HOLD";
3998 r = run_query(hdb, 0, query);
3999 ok(r == ERROR_SUCCESS, "failed to hold table %d\n", r);
4000
4001 query = "ALTER TABLE `T` FREE";
4002 r = run_query(hdb, 0, query);
4003 ok(r == ERROR_SUCCESS, "failed to free table\n");
4004
4005 query = "ALTER TABLE `T` FREE";
4006 r = run_query(hdb, 0, query);
4007 ok(r == ERROR_SUCCESS, "failed to free table\n");
4008
4009 query = "ALTER TABLE `T` FREE";
4010 r = run_query(hdb, 0, query);
4011 ok(r == ERROR_BAD_QUERY_SYNTAX, "failed to free table\n");
4012
4013 query = "ALTER TABLE `T` HOLD";
4014 r = run_query(hdb, 0, query);
4015 ok(r == ERROR_BAD_QUERY_SYNTAX, "failed to hold table %d\n", r);
4016
4017 /* table T is removed */
4018 query = "SELECT * FROM `T`";
4019 r = run_query(hdb, 0, query);
4020 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
4021
4022 /* create the table again */
4023 query = "CREATE TABLE `U` ( `A` INTEGER, `B` INTEGER PRIMARY KEY `B`)";
4024 r = run_query(hdb, 0, query);
4025 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4026
4027 /* up the ref count */
4028 query = "ALTER TABLE `U` HOLD";
4029 r = run_query(hdb, 0, query);
4030 ok(r == ERROR_SUCCESS, "failed to free table\n");
4031
4032 /* add column, no data type */
4033 query = "ALTER TABLE `U` ADD `C`";
4034 r = run_query(hdb, 0, query);
4035 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
4036
4037 query = "ALTER TABLE `U` ADD `C` INTEGER";
4038 r = run_query(hdb, 0, query);
4039 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4040
4041 query = "SELECT * FROM `_Columns` WHERE `Table` = 'U' AND `Name` = 'C'";
4042 r = do_query(hdb, query, &rec);
4043 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4044
4045 /* add column C again */
4046 query = "ALTER TABLE `U` ADD `C` INTEGER";
4047 r = run_query(hdb, 0, query);
4048 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
4049
4050 query = "ALTER TABLE `U` ADD `D` INTEGER TEMPORARY";
4051 r = run_query(hdb, 0, query);
4052 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4053
4054 query = "INSERT INTO `U` ( `A`, `B`, `C`, `D` ) VALUES ( 1, 2, 3, 4 )";
4055 r = run_query(hdb, 0, query);
4056 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4057
4058 query = "ALTER TABLE `U` ADD `D` INTEGER TEMPORARY HOLD";
4059 r = run_query(hdb, 0, query);
4060 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
4061
4062 query = "SELECT * FROM `_Columns` WHERE `Table` = 'U' AND `Name` = 'D'";
4063 r = do_query(hdb, query, &rec);
4064 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
4065
4066 query = "INSERT INTO `U` ( `A`, `B`, `C`, `D` ) VALUES ( 5, 6, 7, 8 )";
4067 r = run_query(hdb, 0, query);
4068 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4069
4070 query = "SELECT * FROM `U` WHERE `D` = 8";
4071 r = run_query(hdb, 0, query);
4072 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4073
4074 query = "ALTER TABLE `U` ADD `D` INTEGER TEMPORARY FREE";
4075 r = run_query(hdb, 0, query);
4076 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
4077
4078 query = "ALTER COLUMN `D` FREE";
4079 r = run_query(hdb, 0, query);
4080 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
4081
4082 /* drop the ref count */
4083 query = "ALTER TABLE `U` FREE";
4084 r = run_query(hdb, 0, query);
4085 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4086
4087 /* table is not empty */
4088 query = "SELECT * FROM `U`";
4089 r = run_query(hdb, 0, query);
4090 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4091
4092 /* column D is removed */
4093 query = "SELECT * FROM `U` WHERE `D` = 8";
4094 r = run_query(hdb, 0, query);
4095 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
4096
4097 query = "INSERT INTO `U` ( `A`, `B`, `C`, `D` ) VALUES ( 9, 10, 11, 12 )";
4098 r = run_query(hdb, 0, query);
4099 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
4100
4101 /* add the column again */
4102 query = "ALTER TABLE `U` ADD `E` INTEGER TEMPORARY HOLD";
4103 r = run_query(hdb, 0, query);
4104 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4105
4106 /* up the ref count */
4107 query = "ALTER TABLE `U` HOLD";
4108 r = run_query(hdb, 0, query);
4109 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4110
4111 query = "INSERT INTO `U` ( `A`, `B`, `C`, `E` ) VALUES ( 13, 14, 15, 16 )";
4112 r = run_query(hdb, 0, query);
4113 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4114
4115 query = "SELECT * FROM `U` WHERE `E` = 16";
4116 r = run_query(hdb, 0, query);
4117 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4118
4119 /* drop the ref count */
4120 query = "ALTER TABLE `U` FREE";
4121 r = run_query(hdb, 0, query);
4122 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4123
4124 query = "INSERT INTO `U` ( `A`, `B`, `C`, `E` ) VALUES ( 17, 18, 19, 20 )";
4125 r = run_query(hdb, 0, query);
4126 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4127
4128 query = "SELECT * FROM `U` WHERE `E` = 20";
4129 r = run_query(hdb, 0, query);
4130 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4131
4132 /* drop the ref count */
4133 query = "ALTER TABLE `U` FREE";
4134 r = run_query(hdb, 0, query);
4135 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4136
4137 /* table still exists */
4138 query = "SELECT * FROM `U`";
4139 r = run_query(hdb, 0, query);
4140 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4141
4142 /* col E is removed */
4143 query = "SELECT * FROM `U` WHERE `E` = 20";
4144 r = run_query(hdb, 0, query);
4145 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
4146
4147 query = "INSERT INTO `U` ( `A`, `B`, `C`, `E` ) VALUES ( 20, 21, 22, 23 )";
4148 r = run_query(hdb, 0, query);
4149 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
4150
4151 /* drop the ref count once more */
4152 query = "ALTER TABLE `U` FREE";
4153 r = run_query(hdb, 0, query);
4154 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4155
4156 /* table still exists */
4157 query = "SELECT * FROM `U`";
4158 r = run_query(hdb, 0, query);
4159 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4160
4161 MsiCloseHandle( hdb );
4163}
4164
4165static void test_integers(void)
4166{
4167 MSIHANDLE hdb = 0, view = 0, rec = 0;
4168 DWORD i;
4169 const char *query;
4170 UINT r;
4171
4172 /* just MsiOpenDatabase should not create a file */
4174 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n");
4175
4176 /* create a table */
4177 query = "CREATE TABLE `integers` ( "
4178 "`one` SHORT, `two` INT, `three` INTEGER, `four` LONG, "
4179 "`five` SHORT NOT NULL, `six` INT NOT NULL, "
4180 "`seven` INTEGER NOT NULL, `eight` LONG NOT NULL "
4181 "PRIMARY KEY `one`)";
4182 r = MsiDatabaseOpenViewA(hdb, query, &view);
4183 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
4184 r = MsiViewExecute(view, 0);
4185 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
4186 r = MsiViewClose(view);
4187 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
4189 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
4190
4191 query = "SELECT * FROM `integers`";
4192 r = MsiDatabaseOpenViewA(hdb, query, &view);
4193 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4194
4196 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4197 check_record(rec, 8, "one", "two", "three", "four", "five", "six", "seven", "eight");
4198 MsiCloseHandle(rec);
4199
4201 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4202 check_record(rec, 8, "I2", "I2", "I2", "I4", "i2", "i2", "i2", "i4");
4203 MsiCloseHandle(rec);
4204
4207
4208 /* insert values into it, NULL where NOT NULL is specified */
4209 query = "INSERT INTO `integers` ( `one`, `two`, `three`, `four`, `five`, `six`, `seven`, `eight` )"
4210 "VALUES('', '', '', '', '', '', '', '')";
4211 r = MsiDatabaseOpenViewA(hdb, query, &view);
4212 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4213 r = MsiViewExecute(view, 0);
4214 ok(r == ERROR_FUNCTION_FAILED, "Expected ERROR_FUNCTION_FAILED, got %d\n", r);
4215
4218
4219 query = "SELECT * FROM `integers`";
4220 r = do_query(hdb, query, &rec);
4221 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
4222
4224 ok(r == -1, "record count wrong: %d\n", r);
4225
4226 MsiCloseHandle(rec);
4227
4228 /* insert legitimate values into it */
4229 query = "INSERT INTO `integers` ( `one`, `two`, `three`, `four`, `five`, `six`, `seven`, `eight` )"
4230 "VALUES('', '2', '', '4', '5', '6', '7', '8')";
4231 r = MsiDatabaseOpenViewA(hdb, query, &view);
4232 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4233 r = MsiViewExecute(view, 0);
4234 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4235
4236 query = "SELECT * FROM `integers`";
4237 r = do_query(hdb, query, &rec);
4238 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4239
4241 ok(r == 8, "record count wrong: %d\n", r);
4242
4243 i = MsiRecordGetInteger(rec, 1);
4244 ok(i == MSI_NULL_INTEGER, "Expected MSI_NULL_INTEGER, got %lu\n", i);
4245 i = MsiRecordGetInteger(rec, 3);
4246 ok(i == MSI_NULL_INTEGER, "Expected MSI_NULL_INTEGER, got %lu\n", i);
4247 i = MsiRecordGetInteger(rec, 2);
4248 ok(i == 2, "Expected 2, got %lu\n", i);
4249 i = MsiRecordGetInteger(rec, 4);
4250 ok(i == 4, "Expected 4, got %lu\n", i);
4251 i = MsiRecordGetInteger(rec, 5);
4252 ok(i == 5, "Expected 5, got %lu\n", i);
4253 i = MsiRecordGetInteger(rec, 6);
4254 ok(i == 6, "Expected 6, got %lu\n", i);
4255 i = MsiRecordGetInteger(rec, 7);
4256 ok(i == 7, "Expected 7, got %lu\n", i);
4257 i = MsiRecordGetInteger(rec, 8);
4258 ok(i == 8, "Expected 8, got %lu\n", i);
4259
4260 MsiCloseHandle(rec);
4263
4264 r = MsiDatabaseCommit(hdb);
4265 ok(r == ERROR_SUCCESS, "MsiDatabaseCommit failed\n");
4266
4267 r = MsiCloseHandle(hdb);
4268 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
4269
4271 ok(r == TRUE, "file didn't exist after commit\n");
4272}
4273
4274static void test_update(void)
4275{
4276 MSIHANDLE hdb = 0, view = 0, rec = 0;
4277 const char *query;
4278 UINT r;
4279
4280 /* just MsiOpenDatabase should not create a file */
4282 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n");
4283
4284 /* create the Control table */
4285 query = "CREATE TABLE `Control` ( "
4286 "`Dialog_` CHAR(72) NOT NULL, `Control` CHAR(50) NOT NULL, `Type` SHORT NOT NULL, "
4287 "`X` SHORT NOT NULL, `Y` SHORT NOT NULL, `Width` SHORT NOT NULL, `Height` SHORT NOT NULL,"
4288 "`Attributes` LONG, `Property` CHAR(50), `Text` CHAR(0) LOCALIZABLE, "
4289 "`Control_Next` CHAR(50), `Help` CHAR(50) LOCALIZABLE PRIMARY KEY `Dialog_`, `Control`)";
4290 r = MsiDatabaseOpenViewA(hdb, query, &view);
4291 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
4292 r = MsiViewExecute(view, 0);
4293 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
4294 r = MsiViewClose(view);
4295 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
4297 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
4298
4299 /* add a control */
4300 query = "INSERT INTO `Control` ( "
4301 "`Dialog_`, `Control`, `Type`, `X`, `Y`, `Width`, `Height`, "
4302 "`Property`, `Text`, `Control_Next`, `Help` )"
4303 "VALUES('ErrorDialog', 'ErrorText', '1', '5', '5', '5', '5', '', '', '', '')";
4304 r = MsiDatabaseOpenViewA(hdb, query, &view);
4305 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4306 r = MsiViewExecute(view, 0);
4307 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4308 r = MsiViewClose(view);
4309 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
4311 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
4312
4313 /* add a second control */
4314 query = "INSERT INTO `Control` ( "
4315 "`Dialog_`, `Control`, `Type`, `X`, `Y`, `Width`, `Height`, "
4316 "`Property`, `Text`, `Control_Next`, `Help` )"
4317 "VALUES('ErrorDialog', 'Button', '1', '5', '5', '5', '5', '', '', '', '')";
4318 r = MsiDatabaseOpenViewA(hdb, query, &view);
4319 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4320 r = MsiViewExecute(view, 0);
4321 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4322 r = MsiViewClose(view);
4323 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
4325 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
4326
4327 /* add a third control */
4328 query = "INSERT INTO `Control` ( "
4329 "`Dialog_`, `Control`, `Type`, `X`, `Y`, `Width`, `Height`, "
4330 "`Property`, `Text`, `Control_Next`, `Help` )"
4331 "VALUES('AnotherDialog', 'ErrorText', '1', '5', '5', '5', '5', '', '', '', '')";
4332 r = MsiDatabaseOpenViewA(hdb, query, &view);
4333 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4334 r = MsiViewExecute(view, 0);
4335 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4336 r = MsiViewClose(view);
4337 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
4339 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
4340
4341 /* bad table */
4342 query = "UPDATE `NotATable` SET `Text` = 'this is text' WHERE `Dialog_` = 'ErrorDialog'";
4343 r = MsiDatabaseOpenViewA(hdb, query, &view);
4344 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
4345
4346 /* bad set column */
4347 query = "UPDATE `Control` SET `NotAColumn` = 'this is text' WHERE `Dialog_` = 'ErrorDialog'";
4348 r = MsiDatabaseOpenViewA(hdb, query, &view);
4349 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
4350
4351 /* bad where condition */
4352 query = "UPDATE `Control` SET `Text` = 'this is text' WHERE `NotAColumn` = 'ErrorDialog'";
4353 r = MsiDatabaseOpenViewA(hdb, query, &view);
4354 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
4355
4356 /* just the dialog_ specified */
4357 query = "UPDATE `Control` SET `Text` = 'this is text' WHERE `Dialog_` = 'ErrorDialog'";
4358 r = MsiDatabaseOpenViewA(hdb, query, &view);
4359 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4360 r = MsiViewExecute(view, 0);
4361 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4362 r = MsiViewClose(view);
4363 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
4365 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
4366
4367 /* check the modified text */
4368 query = "SELECT `Text` FROM `Control` WHERE `Control` = 'ErrorText'";
4369 r = MsiDatabaseOpenViewA(hdb, query, &view);
4370 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4371 r = MsiViewExecute(view, 0);
4372 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4373
4374 r = MsiViewFetch(view, &rec);
4375 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4376 check_record(rec, 1, "this is text");
4377 MsiCloseHandle(rec);
4378
4379 r = MsiViewFetch(view, &rec);
4380 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4381 check_record(rec, 1, "");
4382 MsiCloseHandle(rec);
4383
4384 r = MsiViewFetch(view, &rec);
4385 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
4386
4387 r = MsiViewClose(view);
4388 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
4390 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
4391
4392 /* dialog_ and control specified */
4393 query = "UPDATE `Control` SET `Text` = 'this is text' WHERE `Dialog_` = 'ErrorDialog' AND `Control` = 'ErrorText'";
4394 r = MsiDatabaseOpenViewA(hdb, query, &view);
4395 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4396 r = MsiViewExecute(view, 0);
4397 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4398 r = MsiViewClose(view);
4399 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
4401 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
4402
4403 /* check the modified text */
4404 query = "SELECT `Text` FROM `Control` WHERE `Control` = 'ErrorText'";
4405 r = MsiDatabaseOpenViewA(hdb, query, &view);
4406 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4407 r = MsiViewExecute(view, 0);
4408 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4409
4410 r = MsiViewFetch(view, &rec);
4411 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4412 check_record(rec, 1, "this is text");
4413 MsiCloseHandle(rec);
4414
4415 r = MsiViewFetch(view, &rec);
4416 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4417 check_record(rec, 1, "");
4418 MsiCloseHandle(rec);
4419
4420 r = MsiViewFetch(view, &rec);
4421 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
4422
4423 r = MsiViewClose(view);
4424 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
4426 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
4427
4428 /* no where condition */
4429 query = "UPDATE `Control` SET `Text` = 'this is text'";
4430 r = MsiDatabaseOpenViewA(hdb, query, &view);
4431 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4432 r = MsiViewExecute(view, 0);
4433 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4434 r = MsiViewClose(view);
4435 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
4437 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
4438
4439 /* check the modified text */
4440 query = "SELECT `Text` FROM `Control`";
4441 r = MsiDatabaseOpenViewA(hdb, query, &view);
4442 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4443 r = MsiViewExecute(view, 0);
4444 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4445
4446 r = MsiViewFetch(view, &rec);
4447 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4448 check_record(rec, 1, "this is text");
4449 MsiCloseHandle(rec);
4450
4451 r = MsiViewFetch(view, &rec);
4452 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4453 check_record(rec, 1, "this is text");
4454 MsiCloseHandle(rec);
4455
4456 r = MsiViewFetch(view, &rec);
4457 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4458 check_record(rec, 1, "this is text");
4459 MsiCloseHandle(rec);
4460
4461 r = MsiViewFetch(view, &rec);
4462 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
4463
4464 r = MsiViewClose(view);
4465 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
4467 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
4468
4469 query = "CREATE TABLE `Apple` ( `Banana` CHAR(72) NOT NULL, "
4470 "`Orange` CHAR(72), `Pear` INT PRIMARY KEY `Banana`)";
4471 r = run_query(hdb, 0, query);
4472 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4473
4474 query = "INSERT INTO `Apple` ( `Banana`, `Orange`, `Pear` )"
4475 "VALUES('one', 'two', 3)";
4476 r = run_query(hdb, 0, query);
4477 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4478
4479 query = "INSERT INTO `Apple` ( `Banana`, `Orange`, `Pear` )"
4480 "VALUES('three', 'four', 5)";
4481 r = run_query(hdb, 0, query);
4482 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4483
4484 query = "INSERT INTO `Apple` ( `Banana`, `Orange`, `Pear` )"
4485 "VALUES('six', 'two', 7)";
4486 r = run_query(hdb, 0, query);
4487 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4488
4489 rec = MsiCreateRecord(2);
4490 MsiRecordSetInteger(rec, 1, 8);
4491 MsiRecordSetStringA(rec, 2, "two");
4492
4493 query = "UPDATE `Apple` SET `Pear` = ? WHERE `Orange` = ?";
4494 r = run_query(hdb, rec, query);
4495 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4496
4497 MsiCloseHandle(rec);
4498
4499 query = "SELECT `Pear` FROM `Apple` ORDER BY `Orange`";
4500 r = MsiDatabaseOpenViewA(hdb, query, &view);
4501 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4502 r = MsiViewExecute(view, 0);
4503 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4504
4505 r = MsiViewFetch(view, &rec);
4506 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4507
4508 r = MsiRecordGetInteger(rec, 1);
4509 ok(r == 8, "Expected 8, got %d\n", r);
4510
4511 MsiCloseHandle(rec);
4512
4513 r = MsiViewFetch(view, &rec);
4514 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4515
4516 r = MsiRecordGetInteger(rec, 1);
4517 ok(r == 8, "Expected 8, got %d\n", r);
4518
4519 MsiCloseHandle(rec);
4520
4521 r = MsiViewFetch(view, &rec);
4522 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4523
4524 r = MsiRecordGetInteger(rec, 1);
4525 ok(r == 5, "Expected 5, got %d\n", r);
4526
4527 MsiCloseHandle(rec);
4528
4529 r = MsiViewFetch(view, &rec);
4530 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
4531
4534
4535 r = MsiDatabaseCommit(hdb);
4536 ok(r == ERROR_SUCCESS, "MsiDatabaseCommit failed\n");
4537 r = MsiCloseHandle(hdb);
4538 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
4539
4541}
4542
4543static void test_special_tables(void)
4544{
4545 const char *query;
4546 MSIHANDLE hdb = 0;
4547 UINT r;
4548
4550 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n");
4551
4552 query = "CREATE TABLE `_Properties` ( "
4553 "`foo` INT NOT NULL, `bar` INT LOCALIZABLE PRIMARY KEY `foo`)";
4554 r = run_query(hdb, 0, query);
4555 ok(r == ERROR_SUCCESS, "failed to create table\n");
4556
4557 query = "CREATE TABLE `_Storages` ( "
4558 "`foo` INT NOT NULL, `bar` INT LOCALIZABLE PRIMARY KEY `foo`)";
4559 r = run_query(hdb, 0, query);
4560 ok(r == ERROR_BAD_QUERY_SYNTAX, "created _Streams table\n");
4561
4562 query = "CREATE TABLE `_Streams` ( "
4563 "`foo` INT NOT NULL, `bar` INT LOCALIZABLE PRIMARY KEY `foo`)";
4564 r = run_query(hdb, 0, query);
4565 ok(r == ERROR_BAD_QUERY_SYNTAX, "created _Streams table\n");
4566
4567 query = "CREATE TABLE `_Tables` ( "
4568 "`foo` INT NOT NULL, `bar` INT LOCALIZABLE PRIMARY KEY `foo`)";
4569 r = run_query(hdb, 0, query);
4570 ok(r == ERROR_BAD_QUERY_SYNTAX, "created _Tables table\n");
4571
4572 query = "CREATE TABLE `_Columns` ( "
4573 "`foo` INT NOT NULL, `bar` INT LOCALIZABLE PRIMARY KEY `foo`)";
4574 r = run_query(hdb, 0, query);
4575 ok(r == ERROR_BAD_QUERY_SYNTAX, "created _Columns table\n");
4576
4577 r = MsiCloseHandle(hdb);
4578 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
4579}
4580
4581static void test_tables_order(void)
4582{
4583 const char *query;
4584 MSIHANDLE hdb = 0, hview = 0, hrec = 0;
4585 UINT r;
4586
4588 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n");
4589
4590 query = "CREATE TABLE `foo` ( "
4591 "`baz` INT NOT NULL PRIMARY KEY `baz`)";
4592 r = run_query(hdb, 0, query);
4593 ok(r == ERROR_SUCCESS, "failed to create table\n");
4594
4595 query = "CREATE TABLE `bar` ( "
4596 "`foo` INT NOT NULL PRIMARY KEY `foo`)";
4597 r = run_query(hdb, 0, query);
4598 ok(r == ERROR_SUCCESS, "failed to create table\n");
4599
4600 query = "CREATE TABLE `baz` ( "
4601 "`bar` INT NOT NULL, "
4602 "`baz` INT NOT NULL, "
4603 "`foo` INT NOT NULL PRIMARY KEY `bar`)";
4604 r = run_query(hdb, 0, query);
4605 ok(r == ERROR_SUCCESS, "failed to create table\n");
4606
4607 /* The names of the tables in the _Tables table must
4608 be in the same order as these names are created in
4609 the strings table. */
4610 query = "SELECT `Name` FROM `_Tables`";
4611 r = MsiDatabaseOpenViewA(hdb, query, &hview);
4612 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
4613 r = MsiViewExecute(hview, 0);
4614 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
4615
4616 r = MsiViewFetch(hview, &hrec);
4617 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
4618 check_record(hrec, 1, "foo");
4619 r = MsiCloseHandle(hrec);
4620 ok(r == ERROR_SUCCESS, "failed to close record\n");
4621
4622 r = MsiViewFetch(hview, &hrec);
4623 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
4624 check_record(hrec, 1, "baz");
4625 r = MsiCloseHandle(hrec);
4626 ok(r == ERROR_SUCCESS, "failed to close record\n");
4627
4628 r = MsiViewFetch(hview, &hrec);
4629 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
4630 check_record(hrec, 1, "bar");
4631 r = MsiCloseHandle(hrec);
4632 ok(r == ERROR_SUCCESS, "failed to close record\n");
4633
4634 r = MsiViewClose(hview);
4635 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
4636 r = MsiCloseHandle(hview);
4637 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
4638
4639 /* The names of the tables in the _Columns table must
4640 be in the same order as these names are created in
4641 the strings table. */
4642 query = "SELECT `Table`, `Number`, `Name` FROM `_Columns`";
4643 r = MsiDatabaseOpenViewA(hdb, query, &hview);
4644 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
4645 r = MsiViewExecute(hview, 0);
4646 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
4647
4648 r = MsiViewFetch(hview, &hrec);
4649 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
4650 check_record(hrec, 3, "foo", "1", "baz");
4651 r = MsiCloseHandle(hrec);
4652 ok(r == ERROR_SUCCESS, "failed to close record\n");
4653
4654 r = MsiViewFetch(hview, &hrec);
4655 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
4656 check_record(hrec, 3, "baz", "1", "bar");
4657 r = MsiCloseHandle(hrec);
4658 ok(r == ERROR_SUCCESS, "failed to close record\n");
4659
4660 r = MsiViewFetch(hview, &hrec);
4661 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
4662 check_record(hrec, 3, "baz", "2", "baz");
4663 r = MsiCloseHandle(hrec);
4664 ok(r == ERROR_SUCCESS, "failed to close record\n");
4665
4666 r = MsiViewFetch(hview, &hrec);
4667 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
4668 check_record(hrec, 3, "baz", "3", "foo");
4669 r = MsiCloseHandle(hrec);
4670 ok(r == ERROR_SUCCESS, "failed to close record\n");
4671
4672 r = MsiViewFetch(hview, &hrec);
4673 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
4674 check_record(hrec, 3, "bar", "1", "foo");
4675 r = MsiCloseHandle(hrec);
4676 ok(r == ERROR_SUCCESS, "failed to close record\n");
4677
4678 r = MsiViewClose(hview);
4679 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
4680 r = MsiCloseHandle(hview);
4681 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
4682
4683 r = MsiCloseHandle(hdb);
4684 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
4685
4687}
4688
4689static void test_rows_order(void)
4690{
4691 const char *query;
4692 MSIHANDLE hdb = 0, hview = 0, hrec = 0;
4693 UINT r;
4694
4696 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n");
4697
4698 query = "CREATE TABLE `foo` ( "
4699 "`bar` LONGCHAR NOT NULL PRIMARY KEY `bar`)";
4700 r = run_query(hdb, 0, query);
4701 ok(r == ERROR_SUCCESS, "failed to create table\n");
4702
4703 r = run_query(hdb, 0, "INSERT INTO `foo` "
4704 "( `bar` ) VALUES ( 'A' )");
4705 ok(r == ERROR_SUCCESS, "cannot add value to table\n");
4706
4707 r = run_query(hdb, 0, "INSERT INTO `foo` "
4708 "( `bar` ) VALUES ( 'B' )");
4709 ok(r == ERROR_SUCCESS, "cannot add value to table\n");
4710
4711 r = run_query(hdb, 0, "INSERT INTO `foo` "
4712 "( `bar` ) VALUES ( 'C' )");
4713 ok(r == ERROR_SUCCESS, "cannot add value to table\n");
4714
4715 r = run_query(hdb, 0, "INSERT INTO `foo` "
4716 "( `bar` ) VALUES ( 'D' )");
4717 ok(r == ERROR_SUCCESS, "cannot add value to table\n");
4718
4719 r = run_query(hdb, 0, "INSERT INTO `foo` "
4720 "( `bar` ) VALUES ( 'E' )");
4721 ok(r == ERROR_SUCCESS, "cannot add value to table\n");
4722
4723 r = run_query(hdb, 0, "INSERT INTO `foo` "
4724 "( `bar` ) VALUES ( 'F' )");
4725 ok(r == ERROR_SUCCESS, "cannot add value to table\n");
4726
4727 query = "CREATE TABLE `bar` ( "
4728 "`foo` LONGCHAR NOT NULL, "
4729 "`baz` LONGCHAR NOT NULL "
4730 "PRIMARY KEY `foo` )";
4731 r = run_query(hdb, 0, query);
4732 ok(r == ERROR_SUCCESS, "failed to create table\n");
4733
4734 r = run_query(hdb, 0, "INSERT INTO `bar` "
4735 "( `foo`, `baz` ) VALUES ( 'C', 'E' )");
4736 ok(r == ERROR_SUCCESS, "cannot add value to table\n");
4737
4738 r = run_query(hdb, 0, "INSERT INTO `bar` "
4739 "( `foo`, `baz` ) VALUES ( 'F', 'A' )");
4740 ok(r == ERROR_SUCCESS, "cannot add value to table\n");
4741
4742 r = run_query(hdb, 0, "INSERT INTO `bar` "
4743 "( `foo`, `baz` ) VALUES ( 'A', 'B' )");
4744 ok(r == ERROR_SUCCESS, "cannot add value to table\n");
4745
4746 r = run_query(hdb, 0, "INSERT INTO `bar` "
4747 "( `foo`, `baz` ) VALUES ( 'D', 'E' )");
4748 ok(r == ERROR_SUCCESS, "cannot add value to table\n");
4749
4750 /* The rows of the table must be ordered by the column values of
4751 each row. For strings, the column value is the string id
4752 in the string table. */
4753
4754 query = "SELECT * FROM `bar`";
4755 r = MsiDatabaseOpenViewA(hdb, query, &hview);
4756 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
4757 r = MsiViewExecute(hview, 0);
4758 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
4759
4760 r = MsiViewFetch(hview, &hrec);
4761 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
4762 check_record(hrec, 2, "A", "B");
4763 r = MsiCloseHandle(hrec);
4764 ok(r == ERROR_SUCCESS, "failed to close record\n");
4765
4766 r = MsiViewFetch(hview, &hrec);
4767 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
4768 check_record(hrec, 2, "C", "E");
4769 r = MsiCloseHandle(hrec);
4770 ok(r == ERROR_SUCCESS, "failed to close record\n");
4771
4772 r = MsiViewFetch(hview, &hrec);
4773 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
4774 check_record(hrec, 2, "D", "E");
4775 r = MsiCloseHandle(hrec);
4776 ok(r == ERROR_SUCCESS, "failed to close record\n");
4777
4778 r = MsiViewFetch(hview, &hrec);
4779 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
4780 check_record(hrec, 2, "F", "A");
4781 r = MsiCloseHandle(hrec);
4782 ok(r == ERROR_SUCCESS, "failed to close record\n");
4783
4784 r = MsiViewClose(hview);
4785 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
4786 r = MsiCloseHandle(hview);
4787 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
4788
4789 r = MsiCloseHandle(hdb);
4790 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
4791
4793}
4794
4795static void test_collation(void)
4796{
4797 const char *query;
4798 MSIHANDLE hdb = 0, hview = 0, hrec = 0;
4799 UINT r;
4800 char buffer[100];
4801 WCHAR bufferW[100];
4802 DWORD sz;
4803
4805 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n");
4806
4807 query = "CREATE TABLE `bar` ( "
4808 "`foo` LONGCHAR NOT NULL, "
4809 "`baz` LONGCHAR NOT NULL "
4810 "PRIMARY KEY `foo` )";
4811 r = run_query(hdb, 0, query);
4812 ok(r == ERROR_SUCCESS, "failed to create table\n");
4813
4814 r = run_query(hdb, 0, query);
4815 ok(r == ERROR_BAD_QUERY_SYNTAX, "wrong error %u\n", r);
4816
4817 r = run_query(hdb, 0, "INSERT INTO `bar` "
4818 "( `foo`, `baz` ) VALUES ( '\2', 'A' )");
4819 ok(r == ERROR_SUCCESS, "cannot add value to table %u\n", r);
4820
4821 r = run_query(hdb, 0, "INSERT INTO `bar` "
4822 "( `foo`, `baz` ) VALUES ( '\1', 'B' )");
4823 ok(r == ERROR_SUCCESS, "cannot add value to table %u\n", r);
4824
4825 r = run_queryW(hdb, 0, L"INSERT INTO `bar` (`foo`,`baz`) VALUES ('a\x30a','C')");
4826 ok(r == ERROR_SUCCESS, "cannot add value to table %u\n", r);
4827
4828 r = run_queryW(hdb, 0, L"INSERT INTO `bar` (`foo`,`baz`) VALUES ('\xe5','D')");
4829 ok(r == ERROR_SUCCESS, "cannot add value to table %u\n", r);
4830
4831 r = run_queryW(hdb, 0, L"CREATE TABLE `baz` ( `a\x30a` LONGCHAR NOT NULL, `\xe5` LONGCHAR NOT NULL PRIMARY KEY `a\x30a`)");
4832 ok(r == ERROR_SUCCESS, "cannot create table %u\n", r);
4833
4834 r = run_queryW(hdb, 0, L"CREATE TABLE `a\x30a` ( `foo` LONGCHAR NOT NULL PRIMARY KEY `foo`)");
4835 ok(r == ERROR_SUCCESS, "cannot create table %u\n", r);
4836
4837 r = run_queryW(hdb, 0, L"CREATE TABLE `\xe5` ( `foo` LONGCHAR NOT NULL PRIMARY KEY `foo`)");
4838 ok(r == ERROR_SUCCESS, "cannot create table %u\n", r);
4839
4840 query = "SELECT * FROM `bar`";
4841 r = MsiDatabaseOpenViewA(hdb, query, &hview);
4842 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
4843 r = MsiViewExecute(hview, 0);
4844 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
4845
4846 r = MsiViewFetch(hview, &hrec);
4847 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
4848 sz = sizeof(buffer);
4849 r = MsiRecordGetStringA(hrec, 1, buffer, &sz);
4850 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4851 ok(!lstrcmpA(buffer, "\2"), "Expected \\2, got '%s'\n", buffer);
4852 sz = sizeof(buffer);
4853 r = MsiRecordGetStringA(hrec, 2, buffer, &sz);
4854 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4855 ok(!lstrcmpA(buffer, "A"), "Expected A, got '%s'\n", buffer);
4856 MsiCloseHandle(hrec);
4857
4858 r = MsiViewFetch(hview, &hrec);
4859 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
4860 sz = sizeof(buffer);
4861 r = MsiRecordGetStringA(hrec, 1, buffer, &sz);
4862 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4863 ok(!lstrcmpA(buffer, "\1"), "Expected \\1, got '%s'\n", buffer);
4864 sz = sizeof(buffer);
4865 r = MsiRecordGetStringA(hrec, 2, buffer, &sz);
4866 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4867 ok(!lstrcmpA(buffer, "B"), "Expected B, got '%s'\n", buffer);
4868 MsiCloseHandle(hrec);
4869
4870 r = MsiViewFetch(hview, &hrec);
4871 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
4872 sz = ARRAY_SIZE(bufferW);
4873 r = MsiRecordGetStringW(hrec, 1, bufferW, &sz);
4874 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4875 ok(!memcmp(bufferW, L"a\x30a", sizeof(L"a\x30a")),
4876 "Expected %s, got %s\n", wine_dbgstr_w(L"a\x30a"), wine_dbgstr_w(bufferW));
4877 sz = ARRAY_SIZE(bufferW);
4878 r = MsiRecordGetStringW(hrec, 2, bufferW, &sz);
4879 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4880 ok(!lstrcmpW(bufferW, L"C"), "Expected C, got %s\n", wine_dbgstr_w(bufferW));
4881 MsiCloseHandle(hrec);
4882
4883 r = MsiViewFetch(hview, &hrec);
4884 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
4885 sz = ARRAY_SIZE(bufferW);
4886 r = MsiRecordGetStringW(hrec, 1, bufferW, &sz);
4887 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4888 ok(!memcmp(bufferW, L"\xe5", sizeof(L"\xe5")),
4889 "Expected %s, got %s\n", wine_dbgstr_w(L"\xe5"), wine_dbgstr_w(bufferW));
4890 sz = ARRAY_SIZE(bufferW);
4891 r = MsiRecordGetStringW(hrec, 2, bufferW, &sz);
4892 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4893 ok(!lstrcmpW(bufferW, L"D"), "Expected D, got %s\n", wine_dbgstr_w(bufferW));
4894 MsiCloseHandle(hrec);
4895
4896 r = MsiViewClose(hview);
4897 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
4898 r = MsiCloseHandle(hview);
4899 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
4900
4901 r = MsiDatabaseOpenViewW(hdb, L"SELECT * FROM `bar` WHERE `foo` ='\xe5'", &hview);
4902 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
4903 r = MsiViewExecute(hview, 0);
4904 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
4905
4906 r = MsiViewFetch(hview, &hrec);
4907 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
4908 sz = ARRAY_SIZE(bufferW);
4909 r = MsiRecordGetStringW(hrec, 1, bufferW, &sz);
4910 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4911 ok(!memcmp(bufferW, L"\xe5", sizeof(L"\xe5")),
4912 "Expected %s, got %s\n", wine_dbgstr_w(L"\xe5"), wine_dbgstr_w(bufferW));
4913 sz = ARRAY_SIZE(bufferW);
4914 r = MsiRecordGetStringW(hrec, 2, bufferW, &sz);
4915 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4916 ok(!lstrcmpW(bufferW, L"D"), "Expected D, got %s\n", wine_dbgstr_w(bufferW));
4917 MsiCloseHandle(hrec);
4918
4919 r = MsiViewFetch(hview, &hrec);
4920 ok(r == ERROR_NO_MORE_ITEMS, "MsiViewFetch failed\n");
4921
4922 r = MsiViewClose(hview);
4923 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
4924 r = MsiCloseHandle(hview);
4925 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
4926
4927 r = MsiCloseHandle(hdb);
4928 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
4929
4931}
4932
4933static void test_select_markers(void)
4934{
4935 MSIHANDLE hdb = 0, rec, view, res;
4936 LPCSTR query;
4937 UINT r;
4938
4939 hdb = create_db();
4940 ok( hdb, "failed to create db\n");
4941
4942 r = run_query(hdb, 0,
4943 "CREATE TABLE `Table` (`One` CHAR(72), `Two` CHAR(72), `Three` SHORT PRIMARY KEY `One`, `Two`, `Three`)");
4944 ok(r == S_OK, "cannot create table: %d\n", r);
4945
4946 r = run_query(hdb, 0, "INSERT INTO `Table` "
4947 "( `One`, `Two`, `Three` ) VALUES ( 'apple', 'one', 1 )");
4948 ok(r == S_OK, "cannot add file to the Media table: %d\n", r);
4949
4950 r = run_query(hdb, 0, "INSERT INTO `Table` "
4951 "( `One`, `Two`, `Three` ) VALUES ( 'apple', 'two', 1 )");
4952 ok(r == S_OK, "cannot add file to the Media table: %d\n", r);
4953
4954 r = run_query(hdb, 0, "INSERT INTO `Table` "
4955 "( `One`, `Two`, `Three` ) VALUES ( 'apple', 'two', 2 )");
4956 ok(r == S_OK, "cannot add file to the Media table: %d\n", r);
4957
4958 r = run_query(hdb, 0, "INSERT INTO `Table` "
4959 "( `One`, `Two`, `Three` ) VALUES ( 'banana', 'three', 3 )");
4960 ok(r == S_OK, "cannot add file to the Media table: %d\n", r);
4961
4962 rec = MsiCreateRecord(2);
4963 MsiRecordSetStringA(rec, 1, "apple");
4964 MsiRecordSetStringA(rec, 2, "two");
4965
4966 query = "SELECT * FROM `Table` WHERE `One`=? AND `Two`=? ORDER BY `Three`";
4967 r = MsiDatabaseOpenViewA(hdb, query, &view);
4968 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4969
4970 r = MsiViewExecute(view, rec);
4971 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4972
4973 r = MsiViewFetch(view, &res);
4974 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4975 check_record(res, 3, "apple", "two", "1");
4977
4978 r = MsiViewFetch(view, &res);
4979 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4980 check_record(res, 3, "apple", "two", "2");
4982
4983 r = MsiViewFetch(view, &res);
4984 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
4985
4986 MsiCloseHandle(rec);
4989
4990 rec = MsiCreateRecord(2);
4991 MsiRecordSetStringA(rec, 1, "one");
4992 MsiRecordSetInteger(rec, 2, 1);
4993
4994 query = "SELECT * FROM `Table` WHERE `Two`<>? AND `Three`>? ORDER BY `Three`";
4995 r = MsiDatabaseOpenViewA(hdb, query, &view);
4996 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4997 r = MsiViewExecute(view, rec);
4998 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4999
5000 r = MsiViewFetch(view, &res);
5001 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5002 check_record(res, 3, "apple", "two", "2");
5004
5005 r = MsiViewFetch(view, &res);
5006 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5007 check_record(res, 3, "banana", "three", "3");
5009
5010 r = MsiViewFetch(view, &res);
5011 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
5012
5013 MsiCloseHandle(rec);
5016 MsiCloseHandle(hdb);
5018}
5019
5020static void test_viewmodify_update(void)
5021{
5022 MSIHANDLE hdb = 0, hview = 0, hrec = 0;
5023 UINT i, test_max, offset, count;
5024 const char *query;
5025 UINT r;
5026
5028
5030 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n");
5031
5032 query = "CREATE TABLE `table` (`A` INT, `B` INT PRIMARY KEY `A`)";
5033 r = run_query( hdb, 0, query );
5034 ok(r == ERROR_SUCCESS, "query failed\n");
5035
5036 query = "INSERT INTO `table` (`A`, `B`) VALUES (1, 2)";
5037 r = run_query( hdb, 0, query );
5038 ok(r == ERROR_SUCCESS, "query failed\n");
5039
5040 query = "INSERT INTO `table` (`A`, `B`) VALUES (3, 4)";
5041 r = run_query( hdb, 0, query );
5042 ok(r == ERROR_SUCCESS, "query failed\n");
5043
5044 query = "INSERT INTO `table` (`A`, `B`) VALUES (5, 6)";
5045 r = run_query( hdb, 0, query );
5046 ok(r == ERROR_SUCCESS, "query failed\n");
5047
5048 query = "SELECT `B` FROM `table`";
5049 r = MsiDatabaseOpenViewA(hdb, query, &hview);
5050 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
5051 r = MsiViewExecute(hview, 0);
5052 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
5053 r = MsiViewFetch(hview, &hrec);
5054 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
5055
5056 r = MsiRecordSetInteger(hrec, 1, 0);
5057 ok(r == ERROR_SUCCESS, "failed to set integer\n");
5058
5059 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec);
5060 ok(r == ERROR_SUCCESS, "MsiViewModify failed: %d\n", r);
5061
5062 r = MsiCloseHandle(hrec);
5063 ok(r == ERROR_SUCCESS, "failed to close record\n");
5064
5065 r = MsiViewClose(hview);
5066 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
5067 r = MsiCloseHandle(hview);
5068 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
5069
5070 query = "SELECT * FROM `table`";
5071 r = MsiDatabaseOpenViewA(hdb, query, &hview);
5072 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
5073 r = MsiViewExecute(hview, 0);
5074 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
5075 r = MsiViewFetch(hview, &hrec);
5076 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
5077
5078 r = MsiRecordGetInteger(hrec, 1);
5079 ok(r == 1, "Expected 1, got %d\n", r);
5080 r = MsiRecordGetInteger(hrec, 2);
5081 ok(r == 0, "Expected 0, got %d\n", r);
5082
5083 r = MsiCloseHandle(hrec);
5084 ok(r == ERROR_SUCCESS, "failed to close record\n");
5085
5086 r = MsiViewFetch(hview, &hrec);
5087 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
5088
5089 r = MsiRecordGetInteger(hrec, 1);
5090 ok(r == 3, "Expected 3, got %d\n", r);
5091 r = MsiRecordGetInteger(hrec, 2);
5092 ok(r == 4, "Expected 4, got %d\n", r);
5093
5094 r = MsiCloseHandle(hrec);
5095 ok(r == ERROR_SUCCESS, "failed to close record\n");
5096
5097 r = MsiViewFetch(hview, &hrec);
5098 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
5099
5100 r = MsiRecordGetInteger(hrec, 1);
5101 ok(r == 5, "Expected 5, got %d\n", r);
5102 r = MsiRecordGetInteger(hrec, 2);
5103 ok(r == 6, "Expected 6, got %d\n", r);
5104
5105 r = MsiCloseHandle(hrec);
5106 ok(r == ERROR_SUCCESS, "failed to close record\n");
5107
5108 r = MsiViewFetch(hview, &hrec);
5109 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
5110
5111 r = MsiViewClose(hview);
5112 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
5113 r = MsiCloseHandle(hview);
5114 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
5115
5116 /* loop through all elements */
5117 query = "SELECT `B` FROM `table`";
5118 r = MsiDatabaseOpenViewA(hdb, query, &hview);
5119 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
5120 r = MsiViewExecute(hview, 0);
5121 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
5122
5123 while (TRUE)
5124 {
5125 r = MsiViewFetch(hview, &hrec);
5126 if (r != ERROR_SUCCESS)
5127 break;
5128
5129 r = MsiRecordSetInteger(hrec, 1, 0);
5130 ok(r == ERROR_SUCCESS, "failed to set integer\n");
5131
5132 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec);
5133 ok(r == ERROR_SUCCESS, "MsiViewModify failed: %d\n", r);
5134
5135 r = MsiCloseHandle(hrec);
5136 ok(r == ERROR_SUCCESS, "failed to close record\n");
5137 }
5138
5139 r = MsiViewClose(hview);
5140 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
5141 r = MsiCloseHandle(hview);
5142 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
5143
5144 query = "SELECT * FROM `table`";
5145 r = MsiDatabaseOpenViewA(hdb, query, &hview);
5146 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
5147 r = MsiViewExecute(hview, 0);
5148 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
5149 r = MsiViewFetch(hview, &hrec);
5150 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
5151
5152 r = MsiRecordGetInteger(hrec, 1);
5153 ok(r == 1, "Expected 1, got %d\n", r);
5154 r = MsiRecordGetInteger(hrec, 2);
5155 ok(r == 0, "Expected 0, got %d\n", r);
5156
5157 r = MsiCloseHandle(hrec);
5158 ok(r == ERROR_SUCCESS, "failed to close record\n");
5159
5160 r = MsiViewFetch(hview, &hrec);
5161 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
5162
5163 r = MsiRecordGetInteger(hrec, 1);
5164 ok(r == 3, "Expected 3, got %d\n", r);
5165 r = MsiRecordGetInteger(hrec, 2);
5166 ok(r == 0, "Expected 0, got %d\n", r);
5167
5168 r = MsiCloseHandle(hrec);
5169 ok(r == ERROR_SUCCESS, "failed to close record\n");
5170
5171 r = MsiViewFetch(hview, &hrec);
5172 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
5173
5174 r = MsiRecordGetInteger(hrec, 1);
5175 ok(r == 5, "Expected 5, got %d\n", r);
5176 r = MsiRecordGetInteger(hrec, 2);
5177 ok(r == 0, "Expected 0, got %d\n", r);
5178
5179 r = MsiCloseHandle(hrec);
5180 ok(r == ERROR_SUCCESS, "failed to close record\n");
5181
5182 r = MsiViewFetch(hview, &hrec);
5183 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
5184
5185 r = MsiViewClose(hview);
5186 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
5187 r = MsiCloseHandle(hview);
5188 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
5189
5190 query = "CREATE TABLE `table2` (`A` INT, `B` INT PRIMARY KEY `A`)";
5191 r = run_query( hdb, 0, query );
5192 ok(r == ERROR_SUCCESS, "query failed\n");
5193
5194 query = "INSERT INTO `table2` (`A`, `B`) VALUES (?, ?)";
5195 r = MsiDatabaseOpenViewA( hdb, query, &hview );
5196 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
5197
5198 test_max = 100;
5199 offset = 1234;
5200 for(i = 0; i < test_max; i++)
5201 {
5202
5203 hrec = MsiCreateRecord( 2 );
5204 MsiRecordSetInteger( hrec, 1, test_max - i );
5205 MsiRecordSetInteger( hrec, 2, i );
5206
5207 r = MsiViewExecute( hview, hrec );
5208 ok(r == ERROR_SUCCESS, "Got %d\n", r);
5209
5210 r = MsiCloseHandle( hrec );
5211 ok(r == ERROR_SUCCESS, "Got %d\n", r);
5212 }
5213
5214 r = MsiViewClose( hview );
5215 ok(r == ERROR_SUCCESS, "Got %d\n", r);
5216 r = MsiCloseHandle( hview );
5217 ok(r == ERROR_SUCCESS, "Got %d\n", r);
5218
5219 /* Update. */
5220 query = "SELECT * FROM `table2` ORDER BY `B`";
5221 r = MsiDatabaseOpenViewA( hdb, query, &hview);
5222 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
5223 r = MsiViewExecute( hview, 0 );
5224 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
5225
5226 count = 0;
5227 while (MsiViewFetch( hview, &hrec ) == ERROR_SUCCESS)
5228 {
5229 UINT b = MsiRecordGetInteger( hrec, 2 );
5230
5231 r = MsiRecordSetInteger( hrec, 2, b + offset);
5232 ok(r == ERROR_SUCCESS, "Got %d\n", r);
5233
5234 r = MsiViewModify( hview, MSIMODIFY_UPDATE, hrec );
5235 ok(r == ERROR_SUCCESS, "Got %d\n", r);
5236
5237 r = MsiCloseHandle(hrec);
5238 ok(r == ERROR_SUCCESS, "failed to close record\n");
5239 count++;
5240 }
5241 ok(count == test_max, "Got count %d\n", count);
5242
5243 r = MsiViewClose(hview);
5244 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
5245 r = MsiCloseHandle(hview);
5246 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
5247
5248 /* Recheck. */
5249 query = "SELECT * FROM `table2` ORDER BY `B`";
5250 r = MsiDatabaseOpenViewA( hdb, query, &hview);
5251 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
5252 r = MsiViewExecute( hview, 0 );
5253 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
5254
5255 count = 0;
5256 while (MsiViewFetch( hview, &hrec ) == ERROR_SUCCESS)
5257 {
5258 UINT a = MsiRecordGetInteger( hrec, 1 );
5259 UINT b = MsiRecordGetInteger( hrec, 2 );
5260 ok( ( test_max - a + offset) == b, "Got (%d, %d), expected (%d, %d)\n",
5261 a, b, test_max - a + offset, b);
5262
5263 r = MsiCloseHandle(hrec);
5264 ok(r == ERROR_SUCCESS, "failed to close record\n");
5265 count++;
5266 }
5267 ok(count == test_max, "Got count %d\n", count);
5268
5269 r = MsiViewClose(hview);
5270 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
5271 r = MsiCloseHandle(hview);
5272 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
5273
5274 r = MsiCloseHandle( hdb );
5275 ok(r == ERROR_SUCCESS, "MsiOpenDatabase close failed\n");
5276}
5277
5278static void test_viewmodify_assign(void)
5279{
5280 MSIHANDLE hdb = 0, hview = 0, hrec = 0;
5281 const char *query;
5282 UINT r;
5283
5284 /* setup database */
5286
5288 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n");
5289
5290 query = "CREATE TABLE `table` (`A` INT, `B` INT PRIMARY KEY `A`)";
5291 r = run_query( hdb, 0, query );
5292 ok(r == ERROR_SUCCESS, "query failed\n");
5293
5294 /* assign to view, new primary key */
5295 query = "SELECT * FROM `table`";
5296 r = MsiDatabaseOpenViewA(hdb, query, &hview);
5297 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
5298 r = MsiViewExecute(hview, 0);
5299 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
5300
5301 hrec = MsiCreateRecord(2);
5302 ok(hrec != 0, "MsiCreateRecord failed\n");
5303
5304 r = MsiRecordSetInteger(hrec, 1, 1);
5305 ok(r == ERROR_SUCCESS, "failed to set integer\n");
5306 r = MsiRecordSetInteger(hrec, 2, 2);
5307 ok(r == ERROR_SUCCESS, "failed to set integer\n");
5308
5309 r = MsiViewModify(hview, MSIMODIFY_ASSIGN, hrec);
5310 ok(r == ERROR_SUCCESS, "MsiViewModify failed: %d\n", r);
5311
5312 r = MsiCloseHandle(hrec);
5313 ok(r == ERROR_SUCCESS, "failed to close record\n");
5314
5315 r = MsiViewClose(hview);
5316 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
5317 r = MsiCloseHandle(hview);
5318 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
5319
5320 query = "SELECT * FROM `table`";
5321 r = MsiDatabaseOpenViewA(hdb, query, &hview);
5322 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
5323 r = MsiViewExecute(hview, 0);
5324 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
5325 r = MsiViewFetch(hview, &hrec);
5326 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
5327 check_record(hrec, 2, "1", "2");
5328 r = MsiCloseHandle(hrec);
5329 ok(r == ERROR_SUCCESS, "failed to close record\n");
5330
5331 r = MsiViewFetch(hview, &hrec);
5332 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
5333
5334 r = MsiViewClose(hview);
5335 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
5336 r = MsiCloseHandle(hview);
5337 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
5338
5339 /* assign to view, primary key matches */
5340 query = "SELECT * FROM `table`";
5341 r = MsiDatabaseOpenViewA(hdb, query, &hview);
5342 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
5343 r = MsiViewExecute(hview, 0);
5344 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
5345
5346 hrec = MsiCreateRecord(2);
5347 ok(hrec != 0, "MsiCreateRecord failed\n");
5348
5349 r = MsiRecordSetInteger(hrec, 1, 1);
5350 ok(r == ERROR_SUCCESS, "failed to set integer\n");
5351 r = MsiRecordSetInteger(hrec, 2, 4);
5352 ok(r == ERROR_SUCCESS, "failed to set integer\n");
5353
5354 r = MsiViewModify(hview, MSIMODIFY_ASSIGN, hrec);
5355 ok(r == ERROR_SUCCESS, "MsiViewModify failed: %d\n", r);
5356
5357 r = MsiCloseHandle(hrec);
5358 ok(r == ERROR_SUCCESS, "failed to close record\n");
5359
5360 r = MsiViewClose(hview);
5361 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
5362 r = MsiCloseHandle(hview);
5363 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
5364
5365 query = "SELECT * FROM `table`";
5366 r = MsiDatabaseOpenViewA(hdb, query, &hview);
5367 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
5368 r = MsiViewExecute(hview, 0);
5369 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
5370 r = MsiViewFetch(hview, &hrec);
5371 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
5372 check_record(hrec, 2, "1", "4");
5373 r = MsiCloseHandle(hrec);
5374 ok(r == ERROR_SUCCESS, "failed to close record\n");
5375
5376 r = MsiViewFetch(hview, &hrec);
5377 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
5378
5379 r = MsiViewClose(hview);
5380 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
5381 r = MsiCloseHandle(hview);
5382 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
5383
5384 r = run_query(hdb, 0, "CREATE TABLE `table2` (`A` INT, `B` INT, `C` INT, `D` INT PRIMARY KEY `A`,`B`)");
5385 ok(!r, "got %u\n", r);
5386
5387 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `table2`", &hview);
5388 ok(!r, "got %u\n", r);
5389 r = MsiViewExecute(hview, 0);
5390 ok(!r, "got %u\n", r);
5391
5392 hrec = MsiCreateRecord(4);
5393 MsiRecordSetInteger(hrec, 1, 1);
5394 MsiRecordSetInteger(hrec, 2, 2);
5395 MsiRecordSetInteger(hrec, 3, 3);
5396 MsiRecordSetInteger(hrec, 4, 4);
5397 r = MsiViewModify(hview, MSIMODIFY_ASSIGN, hrec);
5398 ok(!r, "got %u\n", r);
5399 MsiCloseHandle(hrec);
5400
5401 MsiCloseHandle(hview);
5402
5403 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `table2`", &hview);
5404 ok(!r, "got %u\n", r);
5405 r = MsiViewExecute(hview, 0);
5406 ok(!r, "got %u\n", r);
5407
5408 r = MsiViewFetch(hview, &hrec);
5409 ok(!r, "got %u\n", r);
5410 check_record(hrec, 4, "1", "2", "3", "4");
5411 MsiCloseHandle(hrec);
5412
5413 r = MsiViewFetch(hview, &hrec);
5414 ok(r == ERROR_NO_MORE_ITEMS, "got %u\n", r);
5415 MsiCloseHandle(hview);
5416
5417 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `table2`", &hview);
5418 ok(!r, "got %u\n", r);
5419 r = MsiViewExecute(hview, 0);
5420 ok(!r, "got %u\n", r);
5421
5422 hrec = MsiCreateRecord(4);
5423 MsiRecordSetInteger(hrec, 1, 1);
5424 MsiRecordSetInteger(hrec, 2, 4);
5425 MsiRecordSetInteger(hrec, 3, 3);
5426 MsiRecordSetInteger(hrec, 4, 3);
5427 r = MsiViewModify(hview, MSIMODIFY_ASSIGN, hrec);
5428 ok(!r, "got %u\n", r);
5429 MsiCloseHandle(hrec);
5430
5431 MsiCloseHandle(hview);
5432
5433 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `table2`", &hview);
5434 ok(!r, "got %u\n", r);
5435 r = MsiViewExecute(hview, 0);
5436 ok(!r, "got %u\n", r);
5437
5438 r = MsiViewFetch(hview, &hrec);
5439 ok(!r, "got %u\n", r);
5440 check_record(hrec, 4, "1", "2", "3", "4");
5441 MsiCloseHandle(hrec);
5442
5443 r = MsiViewFetch(hview, &hrec);
5444 ok(!r, "got %u\n", r);
5445 check_record(hrec, 4, "1", "4", "3", "3");
5446 MsiCloseHandle(hrec);
5447
5448 r = MsiViewFetch(hview, &hrec);
5449 ok(r == ERROR_NO_MORE_ITEMS, "got %u\n", r);
5450 MsiCloseHandle(hview);
5451
5452 r = MsiDatabaseOpenViewA(hdb, "SELECT `B`, `C` FROM `table2`", &hview);
5453 ok(!r, "got %u\n", r);
5454 r = MsiViewExecute(hview, 0);
5455 ok(!r, "got %u\n", r);
5456
5457 hrec = MsiCreateRecord(2);
5458 MsiRecordSetInteger(hrec, 1, 2);
5459 MsiRecordSetInteger(hrec, 2, 4);
5460 r = MsiViewModify(hview, MSIMODIFY_ASSIGN, hrec);
5461 ok(!r, "got %u\n", r);
5462 MsiRecordSetInteger(hrec, 1, 3);
5463 r = MsiViewModify(hview, MSIMODIFY_ASSIGN, hrec);
5464 ok(!r, "got %u\n", r);
5465 MsiCloseHandle(hrec);
5466
5467 MsiCloseHandle(hview);
5468
5469 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `table2` ORDER BY `A`", &hview);
5470 ok(!r, "got %u\n", r);
5471 r = MsiViewExecute(hview, 0);
5472 ok(!r, "got %u\n", r);
5473
5474 r = MsiViewFetch(hview, &hrec);
5475 ok(!r, "got %u\n", r);
5476 check_record(hrec, 4, "", "2", "4", "");
5477 MsiCloseHandle(hrec);
5478
5479 r = MsiViewFetch(hview, &hrec);
5480 ok(!r, "got %u\n", r);
5481 check_record(hrec, 4, "", "3", "4", "");
5482 MsiCloseHandle(hrec);
5483
5484 r = MsiViewFetch(hview, &hrec);
5485 ok(!r, "got %u\n", r);
5486 check_record(hrec, 4, "1", "2", "3", "4");
5487 MsiCloseHandle(hrec);
5488
5489 r = MsiViewFetch(hview, &hrec);
5490 ok(!r, "got %u\n", r);
5491 check_record(hrec, 4, "1", "4", "3", "3");
5492 MsiCloseHandle(hrec);
5493
5494 r = MsiViewFetch(hview, &hrec);
5495 ok(r == ERROR_NO_MORE_ITEMS, "got %u\n", r);
5496 MsiCloseHandle(hview);
5497
5498 r = MsiDatabaseOpenViewA(hdb, "SELECT `A`, `B`, `C` FROM `table2`", &hview);
5499 ok(!r, "got %u\n", r);
5500 r = MsiViewExecute(hview, 0);
5501 ok(!r, "got %u\n", r);
5502
5503 hrec = MsiCreateRecord(3);
5504 MsiRecordSetInteger(hrec, 1, 1);
5505 MsiRecordSetInteger(hrec, 2, 2);
5506 MsiRecordSetInteger(hrec, 3, 5);
5507 r = MsiViewModify(hview, MSIMODIFY_ASSIGN, hrec);
5508 ok(!r, "got %u\n", r);
5509 MsiCloseHandle(hrec);
5510
5511 MsiCloseHandle(hview);
5512
5513 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `table2` ORDER BY `A`", &hview);
5514 ok(!r, "got %u\n", r);
5515 r = MsiViewExecute(hview, 0);
5516 ok(!r, "got %u\n", r);
5517
5518 r = MsiViewFetch(hview, &hrec);
5519 ok(!r, "got %u\n", r);
5520 check_record(hrec, 4, "", "2", "4", "");
5521 MsiCloseHandle(hrec);
5522
5523 r = MsiViewFetch(hview, &hrec);
5524 ok(!r, "got %u\n", r);
5525 check_record(hrec, 4, "", "3", "4", "");
5526 MsiCloseHandle(hrec);
5527
5528 r = MsiViewFetch(hview, &hrec);
5529 ok(!r, "got %u\n", r);
5530 check_record(hrec, 4, "1", "2", "5", "");
5531 MsiCloseHandle(hrec);
5532
5533 r = MsiViewFetch(hview, &hrec);
5534 ok(!r, "got %u\n", r);
5535 check_record(hrec, 4, "1", "4", "3", "3");
5536 MsiCloseHandle(hrec);
5537
5538 r = MsiViewFetch(hview, &hrec);
5539 ok(r == ERROR_NO_MORE_ITEMS, "got %u\n", r);
5540 MsiCloseHandle(hview);
5541
5542 /* close database */
5543 r = MsiCloseHandle( hdb );
5544 ok(r == ERROR_SUCCESS, "MsiOpenDatabase close failed\n");
5545}
5546
5547static const WCHAR data10[] = { /* MOO */
5548 0x8001, 0x000b,
5549};
5550static const WCHAR data11[] = { /* AAR */
5551 0x8002, 0x8005,
5552 0x000c, 0x000f,
5553};
5554static const char data12[] = /* _StringData */
5555 "MOOABAARCDonetwofourfive";
5556static const WCHAR data13[] = { /* _StringPool */
5557/* len, refs */
5558 0, 0, /* string 0 '' */
5559 0, 0, /* string 1 '' */
5560 0, 0, /* string 2 '' */
5561 0, 0, /* string 3 '' */
5562 0, 0, /* string 4 '' */
5563 3, 3, /* string 5 'MOO' */
5564 1, 1, /* string 6 'A' */
5565 1, 1, /* string 7 'B' */
5566 3, 3, /* string 8 'AAR' */
5567 1, 1, /* string 9 'C' */
5568 1, 1, /* string a 'D' */
5569 3, 1, /* string b 'one' */
5570 3, 1, /* string c 'two' */
5571 0, 0, /* string d '' */
5572 4, 1, /* string e 'four' */
5573 4, 1, /* string f 'five' */
5574};
5575
5576static void test_stringtable(void)
5577{
5578 MSIHANDLE hdb = 0, hview = 0, hrec = 0;
5579 IStorage *stg = NULL;
5580 IStream *stm;
5581 WCHAR name[0x20];
5582 HRESULT hr;
5583 const char *query;
5584 char buffer[MAX_PATH];
5586 DWORD read;
5587 UINT r;
5588
5590 static const WCHAR stringdata[] = {0x4840, 0x3f3f, 0x4577, 0x446c, 0x3b6a, 0x45e4, 0x4824, 0}; /* _StringData */
5591 static const WCHAR stringpool[] = {0x4840, 0x3f3f, 0x4577, 0x446c, 0x3e6a, 0x44b2, 0x482f, 0}; /* _StringPool */
5592 static const WCHAR moo[] = {0x4840, 0x3e16, 0x4818, 0}; /* MOO */
5593 static const WCHAR aar[] = {0x4840, 0x3a8a, 0x481b, 0}; /* AAR */
5594
5596
5598 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5599
5600 query = "CREATE TABLE `MOO` (`A` INT, `B` CHAR(72) PRIMARY KEY `A`)";
5601 r = run_query(hdb, 0, query);
5602 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5603
5604 query = "CREATE TABLE `AAR` (`C` INT, `D` CHAR(72) PRIMARY KEY `C`)";
5605 r = run_query(hdb, 0, query);
5606 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5607
5608 /* insert persistent row */
5609 query = "INSERT INTO `MOO` (`A`, `B`) VALUES (1, 'one')";
5610 r = run_query(hdb, 0, query);
5611 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5612
5613 /* insert persistent row */
5614 query = "INSERT INTO `AAR` (`C`, `D`) VALUES (2, 'two')";
5615 r = run_query(hdb, 0, query);
5616 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5617
5618 /* open a view */
5619 query = "SELECT * FROM `MOO`";
5620 r = MsiDatabaseOpenViewA(hdb, query, &hview);
5621 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5622 r = MsiViewExecute(hview, 0);
5623 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5624
5625 hrec = MsiCreateRecord(2);
5626
5627 r = MsiRecordSetInteger(hrec, 1, 3);
5628 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5629 r = MsiRecordSetStringA(hrec, 2, "three");
5630 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5631
5632 /* insert a nonpersistent row */
5634 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5635
5636 r = MsiCloseHandle(hrec);
5637 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5638 r = MsiViewClose(hview);
5639 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5640 r = MsiCloseHandle(hview);
5641 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5642
5643 /* insert persistent row */
5644 query = "INSERT INTO `MOO` (`A`, `B`) VALUES (4, 'four')";
5645 r = run_query(hdb, 0, query);
5646 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5647
5648 /* insert persistent row */
5649 query = "INSERT INTO `AAR` (`C`, `D`) VALUES (5, 'five')";
5650 r = run_query(hdb, 0, query);
5651 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5652
5653 r = MsiDatabaseCommit(hdb);
5654 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5655
5656 r = MsiCloseHandle(hdb);
5657 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5658
5660 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5661
5662 query = "SELECT * FROM `MOO`";
5663 r = MsiDatabaseOpenViewA(hdb, query, &hview);
5664 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5665
5666 r = MsiViewExecute(hview, 0);
5667 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5668
5669 r = MsiViewFetch(hview, &hrec);
5670 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5671 check_record(hrec, 2, "1", "one");
5672 r = MsiCloseHandle(hrec);
5673 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5674
5675 r = MsiViewFetch(hview, &hrec);
5676 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
5677
5678 r = MsiViewClose(hview);
5679 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5680 r = MsiCloseHandle(hview);
5681 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5682 r = MsiCloseHandle(hrec);
5683 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5684
5685 query = "SELECT * FROM `AAR`";
5686 r = MsiDatabaseOpenViewA(hdb, query, &hview);
5687 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5688
5689 r = MsiViewExecute(hview, 0);
5690 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5691
5692 r = MsiViewFetch(hview, &hrec);
5693 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5694 check_record(hrec, 2, "2", "two");
5695 r = MsiCloseHandle(hrec);
5696 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5697
5698 r = MsiViewFetch(hview, &hrec);
5699 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5700 check_record(hrec, 2, "5", "five");
5701 r = MsiCloseHandle(hrec);
5702 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5703
5704 r = MsiViewFetch(hview, &hrec);
5705 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
5706
5707 r = MsiViewClose(hview);
5708 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5709 r = MsiCloseHandle(hview);
5710 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5711 r = MsiCloseHandle(hrec);
5712 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5713 r = MsiCloseHandle(hdb);
5714 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5715
5716 MultiByteToWideChar(CP_ACP, 0, msifile, -1, name, 0x20);
5717 hr = StgOpenStorage(name, NULL, mode, NULL, 0, &stg);
5718 ok(hr == S_OK, "Expected S_OK, got %#lx\n", hr);
5719 ok(stg != NULL, "Expected non-NULL storage\n");
5720
5721 hr = IStorage_OpenStream(stg, moo, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stm);
5722 ok(hr == S_OK, "Expected S_OK, got %#lx\n", hr);
5723 ok(stm != NULL, "Expected non-NULL stream\n");
5724
5725 hr = IStream_Read(stm, data, MAX_PATH, &read);
5726 ok(hr == S_OK, "Expected S_OK, got %#lx\n", hr);
5727 ok(read == 4, "Expected 4, got %lu\n", read);
5728 todo_wine ok(!memcmp(data, data10, read), "Unexpected data\n");
5729
5730 hr = IStream_Release(stm);
5731 ok(hr == S_OK, "Expected S_OK, got %#lx\n", hr);
5732
5733 hr = IStorage_OpenStream(stg, aar, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stm);
5734 ok(hr == S_OK, "Expected S_OK, got %#lx\n", hr);
5735 ok(stm != NULL, "Expected non-NULL stream\n");
5736
5737 hr = IStream_Read(stm, data, MAX_PATH, &read);
5738 ok(hr == S_OK, "Expected S_OK, got %#lx\n", hr);
5739 ok(read == 8, "Expected 8, got %lu\n", read);
5740 todo_wine
5741 {
5742 ok(!memcmp(data, data11, read), "Unexpected data\n");
5743 }
5744
5745 hr = IStream_Release(stm);
5746 ok(hr == S_OK, "Expected S_OK, got %#lx\n", hr);
5747
5748 hr = IStorage_OpenStream(stg, stringdata, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stm);
5749 ok(hr == S_OK, "Expected S_OK, got %#lx\n", hr);
5750 ok(stm != NULL, "Expected non-NULL stream\n");
5751
5752 hr = IStream_Read(stm, buffer, MAX_PATH, &read);
5753 ok(hr == S_OK, "Expected S_OK, got %#lx\n", hr);
5754 ok(read == 24, "Expected 24, got %lu\n", read);
5755 ok(!memcmp(buffer, data12, read), "Unexpected data\n");
5756
5757 hr = IStream_Release(stm);
5758 ok(hr == S_OK, "Expected S_OK, got %#lx\n", hr);
5759
5760 hr = IStorage_OpenStream(stg, stringpool, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stm);
5761 ok(hr == S_OK, "Expected S_OK, got %#lx\n", hr);
5762 ok(stm != NULL, "Expected non-NULL stream\n");
5763
5764 hr = IStream_Read(stm, data, MAX_PATH, &read);
5765 ok(hr == S_OK, "Expected S_OK, got %#lx\n", hr);
5766 todo_wine
5767 {
5768 ok(read == 64, "Expected 64, got %lu\n", read);
5769 ok(!memcmp(data, data13, read), "Unexpected data\n");
5770 }
5771
5772 hr = IStream_Release(stm);
5773 ok(hr == S_OK, "Expected S_OK, got %#lx\n", hr);
5774
5775 hr = IStorage_Release(stg);
5776 ok(hr == S_OK, "Expected S_OK, got %#lx\n", hr);
5777
5779}
5780
5781static void test_viewmodify_delete(void)
5782{
5783 MSIHANDLE hdb = 0, hview = 0, hrec = 0;
5784 UINT r;
5785 const char *query;
5786
5788
5789 /* just MsiOpenDatabase should not create a file */
5791 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5792
5793 query = "CREATE TABLE `phone` ( "
5794 "`id` INT, `name` CHAR(32), `number` CHAR(32) "
5795 "PRIMARY KEY `id`)";
5796 r = run_query(hdb, 0, query);
5797 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5798
5799 query = "INSERT INTO `phone` ( `id`, `name`, `number` )"
5800 "VALUES('1', 'Alan', '5030581')";
5801 r = run_query(hdb, 0, query);
5802 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5803
5804 query = "INSERT INTO `phone` ( `id`, `name`, `number` )"
5805 "VALUES('2', 'Barry', '928440')";
5806 r = run_query(hdb, 0, query);
5807 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5808
5809 query = "INSERT INTO `phone` ( `id`, `name`, `number` )"
5810 "VALUES('3', 'Cindy', '2937550')";
5811 r = run_query(hdb, 0, query);
5812 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5813
5814 query = "SELECT * FROM `phone` WHERE `id` <= 2";
5815 r = MsiDatabaseOpenViewA(hdb, query, &hview);
5816 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5817 r = MsiViewExecute(hview, 0);
5818 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5819 r = MsiViewFetch(hview, &hrec);
5820 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5821
5822 /* delete 1 */
5823 r = MsiViewModify(hview, MSIMODIFY_DELETE, hrec);
5824 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5825
5826 r = MsiCloseHandle(hrec);
5827 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5828 r = MsiViewFetch(hview, &hrec);
5829 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5830
5831 /* delete 2 */
5832 MsiRecordSetInteger(hrec, 1, 4);
5833 r = MsiViewModify(hview, MSIMODIFY_DELETE, hrec);
5834 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5835
5836 r = MsiCloseHandle(hrec);
5837 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5838 r = MsiViewClose(hview);
5839 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5840 r = MsiCloseHandle(hview);
5841 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5842
5843 query = "SELECT * FROM `phone`";
5844 r = MsiDatabaseOpenViewA(hdb, query, &hview);
5845 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5846 r = MsiViewExecute(hview, 0);
5847 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5848 r = MsiViewFetch(hview, &hrec);
5849 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5850 check_record(hrec, 3, "3", "Cindy", "2937550");
5851 r = MsiCloseHandle(hrec);
5852 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5853
5854 r = MsiViewFetch(hview, &hrec);
5855 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
5856
5857 r = MsiViewClose(hview);
5858 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5859 r = MsiCloseHandle(hview);
5860 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5861 r = MsiCloseHandle(hdb);
5862 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5863}
5864
5865static const WCHAR _Tables[] = {0x4840, 0x3f7f, 0x4164, 0x422f, 0x4836, 0};
5866static const WCHAR _StringData[] = {0x4840, 0x3f3f, 0x4577, 0x446c, 0x3b6a, 0x45e4, 0x4824, 0};
5867static const WCHAR _StringPool[] = {0x4840, 0x3f3f, 0x4577, 0x446c, 0x3e6a, 0x44b2, 0x482f, 0};
5868
5869static const WCHAR data14[] = { /* _StringPool */
5870/* len, refs */
5871 0, 0, /* string 0 '' */
5872};
5873
5874static const struct {
5875 LPCWSTR name;
5876 const void *data;
5877 DWORD size;
5879{
5880 {_Tables, NULL, 0},
5881 {_StringData, NULL, 0},
5882 {_StringPool, data14, sizeof data14},
5884
5886{
5887 IEnumSTATSTG *stgenum = NULL;
5888 IStream *stm;
5889 HRESULT hr;
5890 STATSTG stat;
5891 ULONG n, count;
5894 DWORD sz;
5895
5896 memset(check, 'a', MAX_PATH);
5897
5898 hr = IStorage_EnumElements(stg, 0, NULL, 0, &stgenum);
5899 ok(hr == S_OK, "Expected S_OK, got %#lx\n", hr);
5900
5901 n = 0;
5902 while(TRUE)
5903 {
5904 count = 0;
5905 hr = IEnumSTATSTG_Next(stgenum, 1, &stat, &count);
5906 if(FAILED(hr) || !count)
5907 break;
5908
5909 ok(!lstrcmpW(stat.pwcsName, database_table_data[n].name),
5910 "Expected table %lu name to match\n", n);
5911
5912 stm = NULL;
5913 hr = IStorage_OpenStream(stg, stat.pwcsName, NULL,
5914 STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stm);
5915 ok(hr == S_OK, "Expected S_OK, got %#lx\n", hr);
5916 ok(stm != NULL, "Expected non-NULL stream\n");
5917
5918 CoTaskMemFree(stat.pwcsName);
5919
5920 sz = MAX_PATH;
5921 memset(data, 'a', MAX_PATH);
5922 hr = IStream_Read(stm, data, sz, &count);
5923 ok(hr == S_OK, "Expected S_OK, got %#lx\n", hr);
5924
5926 "Expected %lu, got %lu\n", database_table_data[n].size, count);
5927
5929 ok(!memcmp(data, check, MAX_PATH), "data should not be changed\n");
5930 else
5932 "Expected table %lu data to match\n", n);
5933
5934 IStream_Release(stm);
5935 n++;
5936 }
5937
5938 ok(n == 3, "Expected 3, got %lu\n", n);
5939
5940 IEnumSTATSTG_Release(stgenum);
5941}
5942
5943static void test_defaultdatabase(void)
5944{
5945 UINT r;
5946 HRESULT hr;
5947 MSIHANDLE hdb;
5948 IStorage *stg = NULL;
5949
5951
5953 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5954
5955 r = MsiDatabaseCommit(hdb);
5956 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5957
5958 MsiCloseHandle(hdb);
5959
5961 ok(hr == S_OK, "Expected S_OK, got %#lx\n", hr);
5962 ok(stg != NULL, "Expected non-NULL stg\n");
5963
5964 enum_stream_names(stg);
5965
5966 IStorage_Release(stg);
5968}
5969
5970static void test_order(void)
5971{
5972 MSIHANDLE hdb, hview, hrec;
5973 LPCSTR query;
5974 int val;
5975 UINT r;
5976
5977 hdb = create_db();
5978 ok(hdb, "failed to create db\n");
5979
5980 query = "CREATE TABLE `Empty` ( `A` SHORT NOT NULL PRIMARY KEY `A`)";
5981 r = run_query(hdb, 0, query);
5982 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5983
5984 query = "CREATE TABLE `Mesa` ( `A` SHORT NOT NULL, `B` SHORT, `C` SHORT PRIMARY KEY `A`)";
5985 r = run_query(hdb, 0, query);
5986 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5987
5988 query = "INSERT INTO `Mesa` ( `A`, `B`, `C` ) VALUES ( 1, 2, 9 )";
5989 r = run_query(hdb, 0, query);
5990 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5991
5992 query = "INSERT INTO `Mesa` ( `A`, `B`, `C` ) VALUES ( 3, 4, 7 )";
5993 r = run_query(hdb, 0, query);
5994 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5995
5996 query = "INSERT INTO `Mesa` ( `A`, `B`, `C` ) VALUES ( 5, 6, 8 )";
5997 r = run_query(hdb, 0, query);
5998 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5999
6000 query = "CREATE TABLE `Sideboard` ( `D` SHORT NOT NULL, `E` SHORT, `F` SHORT PRIMARY KEY `D`)";
6001 r = run_query(hdb, 0, query);
6002 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6003
6004 query = "INSERT INTO `Sideboard` ( `D`, `E`, `F` ) VALUES ( 10, 11, 18 )";
6005 r = run_query(hdb, 0, query);
6006 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6007
6008 query = "INSERT INTO `Sideboard` ( `D`, `E`, `F` ) VALUES ( 12, 13, 16 )";
6009 r = run_query(hdb, 0, query);
6010 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6011
6012 query = "INSERT INTO `Sideboard` ( `D`, `E`, `F` ) VALUES ( 14, 15, 17 )";
6013 r = run_query(hdb, 0, query);
6014 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6015
6016 query = "SELECT `A`, `B` FROM `Mesa` ORDER BY `C`";
6017 r = MsiDatabaseOpenViewA(hdb, query, &hview);
6018 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6019 r = MsiViewExecute(hview, 0);
6020 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6021
6022 r = MsiViewFetch(hview, &hrec);
6023 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6024
6025 val = MsiRecordGetInteger(hrec, 1);
6026 ok(val == 3, "Expected 3, got %d\n", val);
6027
6028 val = MsiRecordGetInteger(hrec, 2);
6029 ok(val == 4, "Expected 3, got %d\n", val);
6030
6031 MsiCloseHandle(hrec);
6032
6033 r = MsiViewFetch(hview, &hrec);
6034 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6035
6036 val = MsiRecordGetInteger(hrec, 1);
6037 ok(val == 5, "Expected 5, got %d\n", val);
6038
6039 val = MsiRecordGetInteger(hrec, 2);
6040 ok(val == 6, "Expected 6, got %d\n", val);
6041
6042 MsiCloseHandle(hrec);
6043
6044 r = MsiViewFetch(hview, &hrec);
6045 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6046
6047 val = MsiRecordGetInteger(hrec, 1);
6048 ok(val == 1, "Expected 1, got %d\n", val);
6049
6050 val = MsiRecordGetInteger(hrec, 2);
6051 ok(val == 2, "Expected 2, got %d\n", val);
6052
6053 MsiCloseHandle(hrec);
6054
6055 r = MsiViewFetch(hview, &hrec);
6056 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
6057
6058 MsiViewClose(hview);
6059 MsiCloseHandle(hview);
6060
6061 query = "SELECT `A`, `D` FROM `Mesa`, `Sideboard` ORDER BY `F`";
6062 r = MsiDatabaseOpenViewA(hdb, query, &hview);
6063 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6064 r = MsiViewExecute(hview, 0);
6065 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6066
6067 r = MsiViewFetch(hview, &hrec);
6068 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6069
6070 val = MsiRecordGetInteger(hrec, 1);
6071 ok(val == 1, "Expected 1, got %d\n", val);
6072
6073 val = MsiRecordGetInteger(hrec, 2);
6074 ok(val == 12, "Expected 12, got %d\n", val);
6075
6076 MsiCloseHandle(hrec);
6077
6078 r = MsiViewFetch(hview, &hrec);
6079 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6080
6081 val = MsiRecordGetInteger(hrec, 1);
6082 ok(val == 3, "Expected 3, got %d\n", val);
6083
6084 val = MsiRecordGetInteger(hrec, 2);
6085 ok(val == 12, "Expected 12, got %d\n", val);
6086
6087 MsiCloseHandle(hrec);
6088
6089 r = MsiViewFetch(hview, &hrec);
6090 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6091
6092 val = MsiRecordGetInteger(hrec, 1);
6093 ok(val == 5, "Expected 5, got %d\n", val);
6094
6095 val = MsiRecordGetInteger(hrec, 2);
6096 ok(val == 12, "Expected 12, got %d\n", val);
6097
6098 MsiCloseHandle(hrec);
6099
6100 r = MsiViewFetch(hview, &hrec);
6101 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6102
6103 val = MsiRecordGetInteger(hrec, 1);
6104 ok(val == 1, "Expected 1, got %d\n", val);
6105
6106 val = MsiRecordGetInteger(hrec, 2);
6107 ok(val == 14, "Expected 14, got %d\n", val);
6108
6109 MsiCloseHandle(hrec);
6110
6111 r = MsiViewFetch(hview, &hrec);
6112 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6113
6114 val = MsiRecordGetInteger(hrec, 1);
6115 ok(val == 3, "Expected 3, got %d\n", val);
6116
6117 val = MsiRecordGetInteger(hrec, 2);
6118 ok(val == 14, "Expected 14, got %d\n", val);
6119
6120 MsiCloseHandle(hrec);
6121
6122 r = MsiViewFetch(hview, &hrec);
6123 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6124
6125 val = MsiRecordGetInteger(hrec, 1);
6126 ok(val == 5, "Expected 5, got %d\n", val);
6127
6128 val = MsiRecordGetInteger(hrec, 2);
6129 ok(val == 14, "Expected 14, got %d\n", val);
6130
6131 MsiCloseHandle(hrec);
6132
6133 r = MsiViewFetch(hview, &hrec);
6134 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6135
6136 val = MsiRecordGetInteger(hrec, 1);
6137 ok(val == 1, "Expected 1, got %d\n", val);
6138
6139 val = MsiRecordGetInteger(hrec, 2);
6140 ok(val == 10, "Expected 10, got %d\n", val);
6141
6142 MsiCloseHandle(hrec);
6143
6144 r = MsiViewFetch(hview, &hrec);
6145 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6146
6147 val = MsiRecordGetInteger(hrec, 1);
6148 ok(val == 3, "Expected 3, got %d\n", val);
6149
6150 val = MsiRecordGetInteger(hrec, 2);
6151 ok(val == 10, "Expected 10, got %d\n", val);
6152
6153 MsiCloseHandle(hrec);
6154
6155 r = MsiViewFetch(hview, &hrec);
6156 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6157
6158 val = MsiRecordGetInteger(hrec, 1);
6159 ok(val == 5, "Expected 5, got %d\n", val);
6160
6161 val = MsiRecordGetInteger(hrec, 2);
6162 ok(val == 10, "Expected 10, got %d\n", val);
6163
6164 MsiCloseHandle(hrec);
6165
6166 r = MsiViewFetch(hview, &hrec);
6167 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
6168
6169 MsiViewClose(hview);
6170 MsiCloseHandle(hview);
6171
6172 query = "SELECT * FROM `Empty` ORDER BY `A`";
6173 r = MsiDatabaseOpenViewA(hdb, query, &hview);
6174 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6175 r = MsiViewExecute(hview, 0);
6176 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6177
6178 r = MsiViewFetch(hview, &hrec);
6179 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
6180
6181 MsiViewClose(hview);
6182 MsiCloseHandle(hview);
6183
6184 query = "CREATE TABLE `Buffet` ( `One` CHAR(72), `Two` SHORT PRIMARY KEY `One`)";
6185 r = run_query(hdb, 0, query);
6186 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6187
6188 query = "INSERT INTO `Buffet` ( `One`, `Two` ) VALUES ( 'uno', 2)";
6189 r = run_query(hdb, 0, query);
6190 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6191
6192 query = "INSERT INTO `Buffet` ( `One`, `Two` ) VALUES ( 'dos', 3)";
6193 r = run_query(hdb, 0, query);
6194 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6195
6196 query = "INSERT INTO `Buffet` ( `One`, `Two` ) VALUES ( 'tres', 1)";
6197 r = run_query(hdb, 0, query);
6198 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6199
6200 query = "SELECT * FROM `Buffet` WHERE `One` = 'dos' ORDER BY `Two`";
6201 r = MsiDatabaseOpenViewA(hdb, query, &hview);
6202 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6203 r = MsiViewExecute(hview, 0);
6204 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6205
6206 r = MsiViewFetch(hview, &hrec);
6207 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6208 check_record(hrec, 2, "dos", "3");
6209 MsiCloseHandle(hrec);
6210
6211 r = MsiViewFetch(hview, &hrec);
6212 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
6213
6214 MsiViewClose(hview);
6215 MsiCloseHandle(hview);
6216 MsiCloseHandle(hdb);
6217}
6218
6220{
6221 MSIHANDLE hdb, hview, hrec;
6222 const char *query;
6223 UINT r;
6224
6226
6228 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6229
6230 query = "CREATE TABLE `Table` ( `A` SHORT PRIMARY KEY `A` )";
6231 r = run_query(hdb, 0, query);
6232 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6233
6234 query = "SELECT * FROM `Table`";
6235 r = MsiDatabaseOpenViewA(hdb, query, &hview);
6236 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6237 r = MsiViewExecute(hview, 0);
6238 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6239
6240 hrec = MsiCreateRecord(1);
6241 MsiRecordSetInteger(hrec, 1, 1);
6242
6243 r = MsiViewModify(hview, MSIMODIFY_INSERT, hrec);
6244 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6245
6246 MsiCloseHandle(hrec);
6247
6248 hrec = MsiCreateRecord(1);
6249 MsiRecordSetInteger(hrec, 1, 2);
6250
6252 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6253
6254 MsiCloseHandle(hrec);
6255
6256 hrec = MsiCreateRecord(1);
6257 MsiRecordSetInteger(hrec, 1, 3);
6258
6259 r = MsiViewModify(hview, MSIMODIFY_INSERT, hrec);
6260 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6261
6262 MsiCloseHandle(hrec);
6263
6264 hrec = MsiCreateRecord(1);
6265 MsiRecordSetInteger(hrec, 1, 4);
6266
6268 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6269
6270 MsiCloseHandle(hrec);
6271 MsiViewClose(hview);
6272 MsiCloseHandle(hview);
6273
6274 query = "SELECT * FROM `Table` WHERE `A` = 2";
6275 r = MsiDatabaseOpenViewA(hdb, query, &hview);
6276 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6277 r = MsiViewExecute(hview, 0);
6278 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6279 r = MsiViewFetch(hview, &hrec);
6280 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6281
6282 r = MsiViewModify(hview, MSIMODIFY_DELETE, hrec);
6283 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6284
6285 MsiCloseHandle(hrec);
6286 MsiViewClose(hview);
6287 MsiCloseHandle(hview);
6288
6289 query = "SELECT * FROM `Table` WHERE `A` = 3";
6290 r = MsiDatabaseOpenViewA(hdb, query, &hview);
6291 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6292 r = MsiViewExecute(hview, 0);
6293 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6294 r = MsiViewFetch(hview, &hrec);
6295 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6296
6297 r = MsiViewModify(hview, MSIMODIFY_DELETE, hrec);
6298 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6299
6300 MsiCloseHandle(hrec);
6301 MsiViewClose(hview);
6302 MsiCloseHandle(hview);
6303
6304 query = "SELECT * FROM `Table` ORDER BY `A`";
6305 r = MsiDatabaseOpenViewA(hdb, query, &hview);
6306 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6307 r = MsiViewExecute(hview, 0);
6308 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6309
6310 r = MsiViewFetch(hview, &hrec);
6311 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6312
6313 r = MsiRecordGetInteger(hrec, 1);
6314 ok(r == 1, "Expected 1, got %d\n", r);
6315
6316 MsiCloseHandle(hrec);
6317
6318 r = MsiViewFetch(hview, &hrec);
6319 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6320
6321 r = MsiRecordGetInteger(hrec, 1);
6322 ok(r == 4, "Expected 4, got %d\n", r);
6323
6324 MsiCloseHandle(hrec);
6325
6326 r = MsiViewFetch(hview, &hrec);
6327 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
6328
6329 MsiViewClose(hview);
6330 MsiCloseHandle(hview);
6331 MsiCloseHandle(hdb);
6333}
6334
6335static void test_deleterow(void)
6336{
6337 MSIHANDLE hdb, hview, hrec;
6338 const char *query;
6339 UINT r;
6340
6342
6344 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6345
6346 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )";
6347 r = run_query(hdb, 0, query);
6348 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6349
6350 query = "INSERT INTO `Table` (`A`) VALUES ('one')";
6351 r = run_query(hdb, 0, query);
6352 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6353
6354 query = "INSERT INTO `Table` (`A`) VALUES ('two')";
6355 r = run_query(hdb, 0, query);
6356 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6357
6358 query = "DELETE FROM `Table` WHERE `A` = 'one'";
6359 r = run_query(hdb, 0, query);
6360 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6361
6362 r = MsiDatabaseCommit(hdb);
6363 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6364
6365 MsiCloseHandle(hdb);
6366
6368 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6369
6370 query = "SELECT * FROM `Table`";
6371 r = MsiDatabaseOpenViewA(hdb, query, &hview);
6372 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6373 r = MsiViewExecute(hview, 0);
6374 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6375
6376 r = MsiViewFetch(hview, &hrec);
6377 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6378 check_record(hrec, 1, "two");
6379 MsiCloseHandle(hrec);
6380
6381 r = MsiViewFetch(hview, &hrec);
6382 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
6383
6384 MsiViewClose(hview);
6385 MsiCloseHandle(hview);
6386 MsiCloseHandle(hdb);
6388}
6389
6390static const CHAR import_dat[] = "A\n"
6391 "s72\n"
6392 "Table\tA\n"
6393 "This is a new 'string' ok\n";
6394
6395static void test_quotes(void)
6396{
6397 MSIHANDLE hdb, hview, hrec;
6398 const char *query;
6399 UINT r;
6400
6402
6404 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6405
6406 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )";
6407 r = run_query(hdb, 0, query);
6408 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6409
6410 query = "INSERT INTO `Table` ( `A` ) VALUES ( 'This is a 'string' ok' )";
6411 r = run_query(hdb, 0, query);
6413 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6414
6415 query = "INSERT INTO `Table` ( `A` ) VALUES ( \"This is a 'string' ok\" )";
6416 r = run_query(hdb, 0, query);
6418 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6419
6420 query = "INSERT INTO `Table` ( `A` ) VALUES ( \"test\" )";
6421 r = run_query(hdb, 0, query);
6423 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6424
6425 query = "INSERT INTO `Table` ( `A` ) VALUES ( 'This is a ''string'' ok' )";
6426 r = run_query(hdb, 0, query);
6427 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6428
6429 query = "INSERT INTO `Table` ( `A` ) VALUES ( 'This is a '''string''' ok' )";
6430 r = run_query(hdb, 0, query);
6431 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6432
6433 query = "INSERT INTO `Table` ( `A` ) VALUES ( 'This is a \'string\' ok' )";
6434 r = run_query(hdb, 0, query);
6435 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6436
6437 query = "INSERT INTO `Table` ( `A` ) VALUES ( 'This is a \"string\" ok' )";
6438 r = run_query(hdb, 0, query);
6439 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6440
6441 query = "SELECT * FROM `Table`";
6442 r = MsiDatabaseOpenViewA(hdb, query, &hview);
6443 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6444
6445 r = MsiViewExecute(hview, 0);
6446 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6447
6448 r = MsiViewFetch(hview, &hrec);
6449 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6450 check_record(hrec, 1, "This is a \"string\" ok");
6451 MsiCloseHandle(hrec);
6452
6453 r = MsiViewFetch(hview, &hrec);
6454 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
6455
6456 MsiViewClose(hview);
6457 MsiCloseHandle(hview);
6458
6459 write_file("import.idt", import_dat, (sizeof(import_dat) - 1) * sizeof(char));
6460
6461 r = MsiDatabaseImportA(hdb, CURR_DIR, "import.idt");
6462 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6463
6464 DeleteFileA("import.idt");
6465
6466 query = "SELECT * FROM `Table`";
6467 r = MsiDatabaseOpenViewA(hdb, query, &hview);
6468 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6469
6470 r = MsiViewExecute(hview, 0);
6471 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6472
6473 r = MsiViewFetch(hview, &hrec);
6474 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6475 check_record(hrec, 1, "This is a new 'string' ok");
6476 MsiCloseHandle(hrec);
6477
6478 r = MsiViewFetch(hview, &hrec);
6479 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
6480
6481 MsiViewClose(hview);
6482 MsiCloseHandle(hview);
6483 MsiCloseHandle(hdb);
6485}
6486
6487static void test_carriagereturn(void)
6488{
6489 MSIHANDLE hdb, hview, hrec;
6490 const char *query;
6491 UINT r;
6492
6494
6496 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6497
6498 query = "CREATE TABLE `Table`\r ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )";
6499 r = run_query(hdb, 0, query);
6501 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6502
6503 query = "CREATE TABLE `Table` \r( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )";
6504 r = run_query(hdb, 0, query);
6506 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6507
6508 query = "CREATE\r TABLE `Table` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )";
6509 r = run_query(hdb, 0, query);
6511 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6512
6513 query = "CREATE TABLE\r `Table` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )";
6514 r = run_query(hdb, 0, query);
6516 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6517
6518 query = "CREATE TABLE `Table` (\r `A` CHAR(72) NOT NULL PRIMARY KEY `A` )";
6519 r = run_query(hdb, 0, query);
6521 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6522
6523 query = "CREATE TABLE `Table` ( `A`\r CHAR(72) NOT NULL PRIMARY KEY `A` )";
6524 r = run_query(hdb, 0, query);
6526 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6527
6528 query = "CREATE TABLE `Table` ( `A` CHAR(72)\r NOT NULL PRIMARY KEY `A` )";
6529 r = run_query(hdb, 0, query);
6531 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6532
6533 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT\r NULL PRIMARY KEY `A` )";
6534 r = run_query(hdb, 0, query);
6536 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6537
6538 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT \rNULL PRIMARY KEY `A` )";
6539 r = run_query(hdb, 0, query);
6541 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6542
6543 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL\r PRIMARY KEY `A` )";
6544 r = run_query(hdb, 0, query);
6546 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6547
6548 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL \rPRIMARY KEY `A` )";
6549 r = run_query(hdb, 0, query);
6551 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6552
6553 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL PRIMARY\r KEY `A` )";
6554 r = run_query(hdb, 0, query);
6556 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6557
6558 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL PRIMARY \rKEY `A` )";
6559 r = run_query(hdb, 0, query);
6561 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6562
6563 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL PRIMARY KEY\r `A` )";
6564 r = run_query(hdb, 0, query);
6566 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6567
6568 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A`\r )";
6569 r = run_query(hdb, 0, query);
6571 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6572
6573 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )\r";
6574 r = run_query(hdb, 0, query);
6576 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6577
6578 query = "CREATE TABLE `\rOne` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )";
6579 r = run_query(hdb, 0, query);
6580 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6581
6582 query = "CREATE TABLE `Tw\ro` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )";
6583 r = run_query(hdb, 0, query);
6584 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6585
6586 query = "CREATE TABLE `Three\r` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )";
6587 r = run_query(hdb, 0, query);
6588 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6589
6590 query = "CREATE TABLE `Four` ( `A\r` CHAR(72) NOT NULL PRIMARY KEY `A` )";
6591 r = run_query(hdb, 0, query);
6593 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6594
6595 query = "CREATE TABLE `Four` ( `\rA` CHAR(72) NOT NULL PRIMARY KEY `A` )";
6596 r = run_query(hdb, 0, query);
6598 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6599
6600 query = "CREATE TABLE `Four` ( `A` CHAR(72\r) NOT NULL PRIMARY KEY `A` )";
6601 r = run_query(hdb, 0, query);
6603 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6604
6605 query = "CREATE TABLE `Four` ( `A` CHAR(\r72) NOT NULL PRIMARY KEY `A` )";
6606 r = run_query(hdb, 0, query);
6608 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6609
6610 query = "CREATE TABLE `Four` ( `A` CHAR(72) NOT NULL PRIMARY KEY `\rA` )";
6611 r = run_query(hdb, 0, query);
6613 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6614
6615 query = "CREATE TABLE `Four` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A\r` )";
6616 r = run_query(hdb, 0, query);
6618 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6619
6620 query = "CREATE TABLE `Four` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A\r` )";
6621 r = run_query(hdb, 0, query);
6623 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6624
6625 query = "SELECT `Name` FROM `_Tables`";
6626 r = MsiDatabaseOpenViewA(hdb, query, &hview);
6627 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6628 r = MsiViewExecute(hview, 0);
6629 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6630
6631 r = MsiViewFetch(hview, &hrec);
6632 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6633 check_record(hrec, 1, "\rOne");
6634 MsiCloseHandle(hrec);
6635
6636 r = MsiViewFetch(hview, &hrec);
6637 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6638 check_record(hrec, 1, "Tw\ro");
6639 MsiCloseHandle(hrec);
6640
6641 r = MsiViewFetch(hview, &hrec);
6642 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6643 check_record(hrec, 1, "Three\r");
6644 MsiCloseHandle(hrec);
6645
6646 r = MsiViewFetch(hview, &hrec);
6647 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
6648
6649 MsiViewClose(hview);
6650 MsiCloseHandle(hview);
6651
6652 MsiCloseHandle(hdb);
6654}
6655
6656static void test_noquotes(void)
6657{
6658 MSIHANDLE hdb, hview, hrec;
6659 const char *query;
6660 UINT r;
6661
6663
6665 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6666
6667 query = "CREATE TABLE Table ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )";
6668 r = run_query(hdb, 0, query);
6669 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6670
6671 query = "CREATE TABLE `Table` ( A CHAR(72) NOT NULL PRIMARY KEY `A` )";
6672 r = run_query(hdb, 0, query);
6673 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6674
6675 query = "CREATE TABLE `Table2` ( `A` CHAR(72) NOT NULL PRIMARY KEY A )";
6676 r = run_query(hdb, 0, query);
6677 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6678
6679 query = "CREATE TABLE `Table3` ( A CHAR(72) NOT NULL PRIMARY KEY A )";
6680 r = run_query(hdb, 0, query);
6681 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6682
6683 query = "SELECT `Name` FROM `_Tables`";
6684 r = MsiDatabaseOpenViewA(hdb, query, &hview);
6685 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6686 r = MsiViewExecute(hview, 0);
6687 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6688
6689 r = MsiViewFetch(hview, &hrec);
6690 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6691 check_record(hrec, 1, "Table");
6692 MsiCloseHandle(hrec);
6693
6694 r = MsiViewFetch(hview, &hrec);
6695 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6696 check_record(hrec, 1, "Table2");
6697 MsiCloseHandle(hrec);
6698
6699 r = MsiViewFetch(hview, &hrec);
6700 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6701 check_record(hrec, 1, "Table3");
6702 MsiCloseHandle(hrec);
6703
6704 r = MsiViewFetch(hview, &hrec);
6705 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
6706
6707 MsiViewClose(hview);
6708 MsiCloseHandle(hview);
6709
6710 query = "SELECT `Table`, `Number`, `Name` FROM `_Columns`";
6711 r = MsiDatabaseOpenViewA(hdb, query, &hview);
6712 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6713 r = MsiViewExecute(hview, 0);
6714 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6715
6716 r = MsiViewFetch(hview, &hrec);
6717 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6718 check_record(hrec, 3, "Table", "1", "A");
6719 MsiCloseHandle(hrec);
6720
6721 r = MsiViewFetch(hview, &hrec);
6722 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6723 check_record(hrec, 3, "Table2", "1", "A");
6724 MsiCloseHandle(hrec);
6725
6726 r = MsiViewFetch(hview, &hrec);
6727 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6728 check_record(hrec, 3, "Table3", "1", "A");
6729 MsiCloseHandle(hrec);
6730
6731 r = MsiViewFetch(hview, &hrec);
6732 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
6733
6734 MsiViewClose(hview);
6735 MsiCloseHandle(hview);
6736
6737 query = "INSERT INTO Table ( `A` ) VALUES ( 'hi' )";
6738 r = run_query(hdb, 0, query);
6739 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6740
6741 query = "INSERT INTO `Table` ( A ) VALUES ( 'hi' )";
6742 r = run_query(hdb, 0, query);
6743 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6744
6745 query = "INSERT INTO `Table` ( `A` ) VALUES ( hi )";
6746 r = run_query(hdb, 0, query);
6747 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6748
6749 query = "SELECT * FROM Table WHERE `A` = 'hi'";
6750 r = run_query(hdb, 0, query);
6751 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6752
6753 query = "SELECT * FROM `Table` WHERE `A` = hi";
6754 r = run_query(hdb, 0, query);
6755 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6756
6757 query = "SELECT * FROM Table";
6758 r = run_query(hdb, 0, query);
6759 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6760
6761 query = "SELECT * FROM Table2";
6762 r = MsiDatabaseOpenViewA(hdb, query, &hview);
6763 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6764 r = MsiViewExecute(hview, 0);
6765 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6766
6767 r = MsiViewFetch(hview, &hrec);
6768 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
6769
6770 MsiViewClose(hview);
6771 MsiCloseHandle(hview);
6772
6773 query = "SELECT * FROM `Table` WHERE A = 'hi'";
6774 r = MsiDatabaseOpenViewA(hdb, query, &hview);
6775 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6776 r = MsiViewExecute(hview, 0);
6777 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6778
6779 r = MsiViewFetch(hview, &hrec);
6780 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6781 check_record(hrec, 1, "hi");
6782 MsiCloseHandle(hrec);
6783
6784 r = MsiViewFetch(hview, &hrec);
6785 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
6786
6787 MsiViewClose(hview);
6788 MsiCloseHandle(hview);
6789 MsiCloseHandle(hdb);
6791}
6792
6794{
6795 HANDLE file;
6796 DWORD read;
6797
6802}
6803
6804static void test_forcecodepage(void)
6805{
6806 MSIHANDLE hdb;
6807 const char *query;
6808 char buffer[MAX_PATH];
6809 UINT r;
6810
6813
6815 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6816
6817 query = "SELECT * FROM `_ForceCodepage`";
6818 r = run_query(hdb, 0, query);
6819 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6820
6821 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )";
6822 r = run_query(hdb, 0, query);
6823 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6824
6825 query = "SELECT * FROM `_ForceCodepage`";
6826 r = run_query(hdb, 0, query);
6827 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6828
6829 r = MsiDatabaseCommit(hdb);
6830 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6831
6832 query = "SELECT * FROM `_ForceCodepage`";
6833 r = run_query(hdb, 0, query);
6834 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6835
6836 MsiCloseHandle(hdb);
6837
6839 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6840
6841 query = "SELECT * FROM `_ForceCodepage`";
6842 r = run_query(hdb, 0, query);
6843 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6844
6845 r = MsiDatabaseExportA(hdb, "_ForceCodepage", CURR_DIR, "forcecodepage.idt");
6846 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6847
6848 read_file_data("forcecodepage.idt", buffer);
6849 ok(!lstrcmpA(buffer, "\r\n\r\n0\t_ForceCodepage\r\n"),
6850 "Expected \"\r\n\r\n0\t_ForceCodepage\r\n\", got \"%s\"\n", buffer);
6851
6852 create_file_data("forcecodepage.idt", "\r\n\r\n850\t_ForceCodepage\r\n", 0);
6853
6854 r = MsiDatabaseImportA(hdb, CURR_DIR, "forcecodepage.idt");
6855 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6856
6857 r = MsiDatabaseExportA(hdb, "_ForceCodepage", CURR_DIR, "forcecodepage.idt");
6858 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6859
6860 read_file_data("forcecodepage.idt", buffer);
6861 ok(!lstrcmpA(buffer, "\r\n\r\n850\t_ForceCodepage\r\n"),
6862 "Expected \"\r\n\r\n850\t_ForceCodepage\r\n\", got \"%s\"\n", buffer);
6863
6864 create_file_data("forcecodepage.idt", "\r\n\r\n9999\t_ForceCodepage\r\n", 0);
6865
6866 r = MsiDatabaseImportA(hdb, CURR_DIR, "forcecodepage.idt");
6867 ok(r == ERROR_FUNCTION_FAILED, "Expected ERROR_FUNCTION_FAILED, got %d\n", r);
6868
6869 MsiCloseHandle(hdb);
6871 DeleteFileA("forcecodepage.idt");
6872}
6873
6875{
6876 MSIHANDLE hdb, hview, hrec;
6877 const char *query;
6878 UINT r;
6879
6881
6883 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6884
6885 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL, `B` INT PRIMARY KEY `A` )";
6886 r = run_query(hdb, 0, query);
6887 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6888
6889 query = "INSERT INTO `Table` ( `A`, `B` ) VALUES ( 'hi', 1 )";
6890 r = run_query(hdb, 0, query);
6891 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6892
6893 query = "SELECT * FROM `Table`";
6894 r = MsiDatabaseOpenViewA(hdb, query, &hview);
6895 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6896 r = MsiViewExecute(hview, 0);
6897 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6898
6899 r = MsiViewFetch(hview, &hrec);
6900 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6901 check_record(hrec, 2, "hi", "1");
6902
6903 MsiRecordSetInteger(hrec, 2, 5);
6904 r = MsiViewModify(hview, MSIMODIFY_REFRESH, hrec);
6905 ok(!r, "got %u\n", r);
6906 check_record(hrec, 2, "hi", "1");
6907
6908 MsiRecordSetStringA(hrec, 1, "foo");
6909 r = MsiViewModify(hview, MSIMODIFY_REFRESH, hrec);
6910 ok(!r, "got %u\n", r);
6911 check_record(hrec, 2, "hi", "1");
6912
6913 query = "UPDATE `Table` SET `B` = 2 WHERE `A` = 'hi'";
6914 r = run_query(hdb, 0, query);
6915 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6916
6917 r = MsiViewModify(hview, MSIMODIFY_REFRESH, hrec);
6918 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6919 check_record(hrec, 2, "hi", "2");
6920
6921 r = run_query(hdb, 0, "UPDATE `Table` SET `B` = NULL WHERE `A` = 'hi'");
6922 ok(!r, "got %u\n", r);
6923
6924 r = MsiViewModify(hview, MSIMODIFY_REFRESH, hrec);
6925 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6926 check_record(hrec, 2, "hi", "");
6927
6928 MsiCloseHandle(hrec);
6929
6930 MsiViewClose(hview);
6931 MsiCloseHandle(hview);
6932
6933 query = "INSERT INTO `Table` ( `A`, `B` ) VALUES ( 'hello', 3 )";
6934 r = run_query(hdb, 0, query);
6935 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6936
6937 query = "SELECT * FROM `Table` WHERE `B` = 3";
6938 r = MsiDatabaseOpenViewA(hdb, query, &hview);
6939 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6940 r = MsiViewExecute(hview, 0);
6941 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6942
6943 r = MsiViewFetch(hview, &hrec);
6944 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6945
6946 query = "UPDATE `Table` SET `B` = 2 WHERE `A` = 'hello'";
6947 r = run_query(hdb, 0, query);
6948 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6949
6950 query = "INSERT INTO `Table` ( `A`, `B` ) VALUES ( 'hithere', 3 )";
6951 r = run_query(hdb, 0, query);
6952 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6953
6954 r = MsiViewModify(hview, MSIMODIFY_REFRESH, hrec);
6955 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6956 check_record(hrec, 2, "hello", "2");
6957 MsiCloseHandle(hrec);
6958
6959 MsiViewClose(hview);
6960 MsiCloseHandle(hview);
6961
6962 r = MsiDatabaseOpenViewA(hdb, "SELECT `B` FROM `Table` WHERE `A` = 'hello'", &hview);
6963 ok(!r, "got %u\n", r);
6964 r = MsiViewExecute(hview, 0);
6965 ok(!r, "got %u\n", r);
6966
6967 r = MsiViewFetch(hview, &hrec);
6968 ok(!r, "got %u\n", r);
6969 check_record(hrec, 1, "2");
6970
6971 MsiRecordSetInteger(hrec, 1, 8);
6972 r = MsiViewModify(hview, MSIMODIFY_REFRESH, hrec);
6973 ok(!r, "got %u\n", r);
6974 check_record(hrec, 1, "2");
6975
6976 MsiCloseHandle(hrec);
6977 MsiCloseHandle(hview);
6978
6979 MsiCloseHandle(hdb);
6981}
6982
6983static void test_where_viewmodify(void)
6984{
6985 MSIHANDLE hdb, hview, hrec;
6986 const char *query;
6987 UINT r;
6988
6990
6992 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6993
6994 query = "CREATE TABLE `Table` ( `A` INT, `B` INT PRIMARY KEY `A` )";
6995 r = run_query(hdb, 0, query);
6996 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6997
6998 query = "INSERT INTO `Table` ( `A`, `B` ) VALUES ( 1, 2 )";
6999 r = run_query(hdb, 0, query);
7000 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7001
7002 query = "INSERT INTO `Table` ( `A`, `B` ) VALUES ( 3, 4 )";
7003 r = run_query(hdb, 0, query);
7004 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7005
7006 query = "INSERT INTO `Table` ( `A`, `B` ) VALUES ( 5, 6 )";
7007 r = run_query(hdb, 0, query);
7008 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7009
7010 /* `B` = 3 doesn't match, but the view shouldn't be executed */
7011 query = "SELECT * FROM `Table` WHERE `B` = 3";
7012 r = MsiDatabaseOpenViewA(hdb, query, &hview);
7013 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7014
7015 hrec = MsiCreateRecord(2);
7016 MsiRecordSetInteger(hrec, 1, 7);
7017 MsiRecordSetInteger(hrec, 2, 8);
7018
7020 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7021
7022 MsiCloseHandle(hrec);
7023 MsiViewClose(hview);
7024 MsiCloseHandle(hview);
7025
7026 query = "SELECT * FROM `Table` WHERE `A` = 7";
7027 r = MsiDatabaseOpenViewA(hdb, query, &hview);
7028 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7029 r = MsiViewExecute(hview, 0);
7030 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7031
7032 r = MsiViewFetch(hview, &hrec);
7033 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7034
7035 r = MsiRecordGetInteger(hrec, 1);
7036 ok(r == 7, "Expected 7, got %d\n", r);
7037
7038 r = MsiRecordGetInteger(hrec, 2);
7039 ok(r == 8, "Expected 8, got %d\n", r);
7040
7041 MsiRecordSetInteger(hrec, 2, 9);
7042
7043 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec);
7044 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7045
7046 MsiCloseHandle(hrec);
7047 MsiViewClose(hview);
7048 MsiCloseHandle(hview);
7049
7050 query = "SELECT * FROM `Table` WHERE `A` = 7";
7051 r = MsiDatabaseOpenViewA(hdb, query, &hview);
7052 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7053 r = MsiViewExecute(hview, 0);
7054 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7055
7056 r = MsiViewFetch(hview, &hrec);
7057 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7058
7059 r = MsiRecordGetInteger(hrec, 1);
7060 ok(r == 7, "Expected 7, got %d\n", r);
7061
7062 r = MsiRecordGetInteger(hrec, 2);
7063 ok(r == 9, "Expected 9, got %d\n", r);
7064
7065 query = "UPDATE `Table` SET `B` = 10 WHERE `A` = 7";
7066 r = run_query(hdb, 0, query);
7067 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7068
7069 r = MsiViewModify(hview, MSIMODIFY_REFRESH, hrec);
7070 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7071
7072 r = MsiRecordGetInteger(hrec, 1);
7073 ok(r == 7, "Expected 7, got %d\n", r);
7074
7075 r = MsiRecordGetInteger(hrec, 2);
7076 ok(r == 10, "Expected 10, got %d\n", r);
7077
7078 MsiCloseHandle(hrec);
7079 MsiViewClose(hview);
7080 MsiCloseHandle(hview);
7081 MsiCloseHandle(hdb);
7082}
7083
7085{
7087 IStorage *stg;
7088 IStream *stm;
7089 HRESULT hr;
7090 DWORD count;
7091 BOOL res = FALSE;
7092
7096 if (FAILED(hr))
7097 return FALSE;
7098
7099 hr = IStorage_CreateStream(stg, nameW, STGM_WRITE | STGM_SHARE_EXCLUSIVE,
7100 0, 0, &stm);
7101 if (FAILED(hr))
7102 goto done;
7103
7104 hr = IStream_Write(stm, "stgdata", 8, &count);
7105 if (SUCCEEDED(hr))
7106 res = TRUE;
7107
7108done:
7109 IStream_Release(stm);
7110 IStorage_Release(stg);
7111
7112 return res;
7113}
7114
7115static void test_storages_table(void)
7116{
7117 MSIHANDLE hdb, hview, hrec;
7118 IStorage *stg, *inner;
7119 IStream *stm;
7120 char file[MAX_PATH];
7121 char buf[MAX_PATH];
7123 LPCSTR query;
7124 HRESULT hr;
7125 DWORD size;
7126 UINT r;
7127
7128 hdb = create_db();
7129 ok(hdb, "failed to create db\n");
7130
7131 r = MsiDatabaseCommit(hdb);
7132 ok(r == ERROR_SUCCESS , "Failed to commit database\n");
7133
7134 MsiCloseHandle(hdb);
7135
7137 ok(r == ERROR_SUCCESS , "Failed to open database\n");
7138
7139 /* check the column types */
7140 hrec = get_column_info(hdb, "SELECT * FROM `_Storages`", MSICOLINFO_TYPES);
7141 ok(hrec, "failed to get column info hrecord\n");
7142 check_record(hrec, 2, "s62", "V0");
7143 MsiCloseHandle(hrec);
7144
7145 /* now try the names */
7146 hrec = get_column_info(hdb, "SELECT * FROM `_Storages`", MSICOLINFO_NAMES);
7147 ok(hrec, "failed to get column info hrecord\n");
7148 check_record(hrec, 2, "Name", "Data");
7149 MsiCloseHandle(hrec);
7150
7151 create_storage("storage.bin");
7152
7153 hrec = MsiCreateRecord(2);
7154 MsiRecordSetStringA(hrec, 1, "stgname");
7155
7156 r = MsiRecordSetStreamA(hrec, 2, "storage.bin");
7157 ok(r == ERROR_SUCCESS, "Failed to add stream data to the hrecord: %d\n", r);
7158
7159 DeleteFileA("storage.bin");
7160
7161 query = "INSERT INTO `_Storages` (`Name`, `Data`) VALUES (?, ?)";
7162 r = MsiDatabaseOpenViewA(hdb, query, &hview);
7163 ok(r == ERROR_SUCCESS, "Failed to open database hview: %d\n", r);
7164
7165 r = MsiViewExecute(hview, hrec);
7166 ok(r == ERROR_SUCCESS, "Failed to execute hview: %d\n", r);
7167
7168 MsiCloseHandle(hrec);
7169 MsiViewClose(hview);
7170 MsiCloseHandle(hview);
7171
7172 query = "SELECT `Name`, `Data` FROM `_Storages`";
7173 r = MsiDatabaseOpenViewA(hdb, query, &hview);
7174 ok(r == ERROR_SUCCESS, "Failed to open database hview: %d\n", r);
7175
7176 r = MsiViewExecute(hview, 0);
7177 ok(r == ERROR_SUCCESS, "Failed to execute hview: %d\n", r);
7178
7179 r = MsiViewFetch(hview, &hrec);
7180 ok(r == ERROR_SUCCESS, "Failed to fetch hrecord: %d\n", r);
7181
7182 size = MAX_PATH;
7183 r = MsiRecordGetStringA(hrec, 1, file, &size);
7184 ok(r == ERROR_SUCCESS, "Failed to get string: %d\n", r);
7185 ok(!lstrcmpA(file, "stgname"), "Expected \"stgname\", got \"%s\"\n", file);
7186
7187 size = MAX_PATH;
7188 lstrcpyA(buf, "apple");
7189 r = MsiRecordReadStream(hrec, 2, buf, &size);
7190 ok(r == ERROR_INVALID_DATA, "Expected ERROR_INVALID_DATA, got %d\n", r);
7191 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7192 ok(size == 0, "Expected 0, got %lu\n", size);
7193
7194 MsiCloseHandle(hrec);
7195
7196 r = MsiViewFetch(hview, &hrec);
7197 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7198
7199 MsiViewClose(hview);
7200 MsiCloseHandle(hview);
7201
7202 MsiDatabaseCommit(hdb);
7203 MsiCloseHandle(hdb);
7204
7207 STGM_SHARE_DENY_WRITE, NULL, 0, &stg);
7208 ok(hr == S_OK, "Expected S_OK, got %#lx\n", hr);
7209 ok(stg != NULL, "Expected non-NULL storage\n");
7210
7211 MultiByteToWideChar(CP_ACP, 0, "stgname", -1, name, MAX_PATH);
7212 hr = IStorage_OpenStorage(stg, name, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE,
7213 NULL, 0, &inner);
7214 ok(hr == S_OK, "Expected S_OK, got %#lx\n", hr);
7215 ok(inner != NULL, "Expected non-NULL storage\n");
7216
7217 MultiByteToWideChar(CP_ACP, 0, "storage.bin", -1, name, MAX_PATH);
7218 hr = IStorage_OpenStream(inner, name, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stm);
7219 ok(hr == S_OK, "Expected S_OK, got %#lx\n", hr);
7220 ok(stm != NULL, "Expected non-NULL stream\n");
7221
7222 hr = IStream_Read(stm, buf, MAX_PATH, &size);
7223 ok(hr == S_OK, "Expected S_OK, got %#lx\n", hr);
7224 ok(size == 8, "Expected 8, got %lu\n", size);
7225 ok(!lstrcmpA(buf, "stgdata"), "Expected \"stgdata\", got \"%s\"\n", buf);
7226
7227 IStream_Release(stm);
7228 IStorage_Release(inner);
7229
7230 IStorage_Release(stg);
7232}
7233
7234static void test_dbtopackage(void)
7235{
7236 MSIHANDLE hdb, hpkg;
7237 CHAR package[12], buf[MAX_PATH];
7238 DWORD size;
7239 UINT r;
7240
7241 /* create an empty database, transact mode */
7243 ok(r == ERROR_SUCCESS, "Failed to create database\n");
7244
7245 set_summary_info(hdb);
7246
7248
7250 add_custom_action_entry(hdb, "'SetProp', 51, 'MYPROP', 'grape'");
7251
7252 sprintf(package, "#%lu", hdb);
7253 r = MsiOpenPackageA(package, &hpkg);
7255 {
7256 skip("Not enough rights to perform tests\n");
7257 goto error;
7258 }
7259 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7260
7261 /* property is not set yet */
7262 size = MAX_PATH;
7263 lstrcpyA(buf, "kiwi");
7264 r = MsiGetPropertyA(hpkg, "MYPROP", buf, &size);
7265 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7266 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
7267 ok(size == 0, "Expected 0, got %lu\n", size);
7268
7269 /* run the custom action to set the property */
7270 r = MsiDoActionA(hpkg, "SetProp");
7271 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7272
7273 /* property is now set */
7274 size = MAX_PATH;
7275 lstrcpyA(buf, "kiwi");
7276 r = MsiGetPropertyA(hpkg, "MYPROP", buf, &size);
7277 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7278 ok(!lstrcmpA(buf, "grape"), "Expected \"grape\", got \"%s\"\n", buf);
7279 ok(size == 5, "Expected 5, got %lu\n", size);
7280
7281 MsiCloseHandle(hpkg);
7282
7283 /* reset the package */
7284 r = MsiOpenPackageA(package, &hpkg);
7285 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7286
7287 /* property is not set anymore */
7288 size = MAX_PATH;
7289 lstrcpyA(buf, "kiwi");
7290 r = MsiGetPropertyA(hpkg, "MYPROP", buf, &size);
7291 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7292 todo_wine
7293 {
7294 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
7295 ok(size == 0, "Expected 0, got %lu\n", size);
7296 }
7297
7298 MsiCloseHandle(hdb);
7299 MsiCloseHandle(hpkg);
7300
7301 /* create an empty database, direct mode */
7303 ok(r == ERROR_SUCCESS, "Failed to create database\n");
7304
7305 set_summary_info(hdb);
7306
7308
7310 add_custom_action_entry(hdb, "'SetProp', 51, 'MYPROP', 'grape'");
7311
7312 sprintf(package, "#%lu", hdb);
7313 r = MsiOpenPackageA(package, &hpkg);
7314 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7315
7316 /* property is not set yet */
7317 size = MAX_PATH;
7318 lstrcpyA(buf, "kiwi");
7319 r = MsiGetPropertyA(hpkg, "MYPROP", buf, &size);
7320 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7321 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
7322 ok(size == 0, "Expected 0, got %lu\n", size);
7323
7324 /* run the custom action to set the property */
7325 r = MsiDoActionA(hpkg, "SetProp");
7326 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7327
7328 /* property is now set */
7329 size = MAX_PATH;
7330 lstrcpyA(buf, "kiwi");
7331 r = MsiGetPropertyA(hpkg, "MYPROP", buf, &size);
7332 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7333 ok(!lstrcmpA(buf, "grape"), "Expected \"grape\", got \"%s\"\n", buf);
7334 ok(size == 5, "Expected 5, got %lu\n", size);
7335
7336 MsiCloseHandle(hpkg);
7337
7338 /* reset the package */
7339 r = MsiOpenPackageA(package, &hpkg);
7340 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7341
7342 /* property is not set anymore */
7343 size = MAX_PATH;
7344 lstrcpyA(buf, "kiwi");
7345 r = MsiGetPropertyA(hpkg, "MYPROP", buf, &size);
7346 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7347 todo_wine
7348 {
7349 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
7350 ok(size == 0, "Expected 0, got %lu\n", size);
7351 }
7352
7353 MsiCloseHandle(hpkg);
7354
7355error:
7356 MsiCloseHandle(hdb);
7358}
7359
7360static void test_droptable(void)
7361{
7362 MSIHANDLE hdb, hview, hrec;
7363 LPCSTR query;
7364 UINT r;
7365
7367 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7368
7369 query = "CREATE TABLE `One` ( `A` INT PRIMARY KEY `A` )";
7370 r = run_query(hdb, 0, query);
7371 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7372
7373 query = "SELECT * FROM `One`";
7374 r = do_query(hdb, query, &hrec);
7375 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7376
7377 query = "SELECT `Name` FROM `_Tables` WHERE `Name` = 'One'";
7378 r = MsiDatabaseOpenViewA(hdb, query, &hview);
7379 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7380 r = MsiViewExecute(hview, 0);
7381 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7382
7383 r = MsiViewFetch(hview, &hrec);
7384 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7385 check_record(hrec, 1, "One");
7386 MsiCloseHandle(hrec);
7387
7388 MsiViewClose(hview);
7389 MsiCloseHandle(hview);
7390
7391 query = "SELECT `Table`, `Number`, `Name` FROM `_Columns` WHERE `Table` = 'One'";
7392 r = MsiDatabaseOpenViewA(hdb, query, &hview);
7393 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7394 r = MsiViewExecute(hview, 0);
7395 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7396
7397 r = MsiViewFetch(hview, &hrec);
7398 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7399 check_record(hrec, 3, "One", "1", "A");
7400 MsiCloseHandle(hrec);
7401
7402 r = MsiViewFetch(hview, &hrec);
7404 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7405
7406 MsiViewClose(hview);
7407 MsiCloseHandle(hview);
7408
7409 query = "DROP `One`";
7410 r = run_query(hdb, 0, query);
7412 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7413
7414 query = "DROP TABLE";
7415 r = run_query(hdb, 0, query);
7417 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7418
7419 query = "DROP TABLE `One`";
7420 hview = 0;
7421 r = MsiDatabaseOpenViewA(hdb, query, &hview);
7422 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7423 r = MsiViewExecute(hview, 0);
7424 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7425
7426 r = MsiViewFetch(hview, &hrec);
7428 "Expected ERROR_FUNCTION_FAILED, got %d\n", r);
7429
7430 MsiViewClose(hview);
7431 MsiCloseHandle(hview);
7432
7433 query = "SELECT * FROM `IDontExist`";
7434 r = do_query(hdb, query, &hrec);
7436 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7437
7438 query = "SELECT * FROM `One`";
7439 r = do_query(hdb, query, &hrec);
7441 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7442
7443 query = "CREATE TABLE `One` ( `A` INT PRIMARY KEY `A` )";
7444 r = run_query(hdb, 0, query);
7445 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7446
7447 query = "DROP TABLE One";
7448 r = run_query(hdb, 0, query);
7449 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7450
7451 query = "SELECT * FROM `One`";
7452 r = do_query(hdb, query, &hrec);
7454 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7455
7456 query = "SELECT * FROM `_Tables` WHERE `Name` = 'One'";
7457 r = do_query(hdb, query, &hrec);
7458 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7459
7460 query = "SELECT * FROM `_Columns` WHERE `Table` = 'One'";
7461 r = do_query(hdb, query, &hrec);
7462 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7463
7464 query = "CREATE TABLE `One` ( `B` INT, `C` INT PRIMARY KEY `B` )";
7465 r = run_query(hdb, 0, query);
7466 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7467
7468 query = "SELECT * FROM `One`";
7469 r = do_query(hdb, query, &hrec);
7470 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7471
7472 query = "SELECT `Name` FROM `_Tables` WHERE `Name` = 'One'";
7473 r = MsiDatabaseOpenViewA(hdb, query, &hview);
7474 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7475 r = MsiViewExecute(hview, 0);
7476 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7477
7478 r = MsiViewFetch(hview, &hrec);
7479 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7480 check_record(hrec, 1, "One");
7481 MsiCloseHandle(hrec);
7482
7483 MsiViewClose(hview);
7484 MsiCloseHandle(hview);
7485
7486 query = "SELECT `Table`, `Number`, `Name` FROM `_Columns` WHERE `Table` = 'One'";
7487 r = MsiDatabaseOpenViewA(hdb, query, &hview);
7488 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7489 r = MsiViewExecute(hview, 0);
7490 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7491
7492 r = MsiViewFetch(hview, &hrec);
7493 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7494 check_record(hrec, 3, "One", "1", "B");
7495 MsiCloseHandle(hrec);
7496
7497 r = MsiViewFetch(hview, &hrec);
7498 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7499 check_record(hrec, 3, "One", "2", "C");
7500 MsiCloseHandle(hrec);
7501
7502 r = MsiViewFetch(hview, &hrec);
7504 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7505
7506 MsiViewClose(hview);
7507 MsiCloseHandle(hview);
7508
7509 query = "DROP TABLE One";
7510 r = run_query(hdb, 0, query);
7511 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7512
7513 query = "SELECT * FROM `One`";
7514 r = do_query(hdb, query, &hrec);
7516 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7517
7518 query = "SELECT * FROM `_Tables` WHERE `Name` = 'One'";
7519 r = do_query(hdb, query, &hrec);
7520 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7521
7522 query = "SELECT * FROM `_Columns` WHERE `Table` = 'One'";
7523 r = do_query(hdb, query, &hrec);
7524 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7525
7526 MsiCloseHandle(hdb);
7528}
7529
7530static void test_dbmerge(void)
7531{
7532 MSIHANDLE hdb, href, hview, hrec;
7533 CHAR buf[MAX_PATH];
7534 LPCSTR query;
7535 DWORD size;
7536 UINT r;
7537
7539 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7540
7541 r = MsiOpenDatabaseW(L"refdb.msi", MSIDBOPEN_CREATE, &href);
7542 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7543
7544 /* hDatabase is invalid */
7545 r = MsiDatabaseMergeA(0, href, "MergeErrors");
7547 "Expected ERROR_INVALID_HANDLE, got %d\n", r);
7548
7549 /* hDatabaseMerge is invalid */
7550 r = MsiDatabaseMergeA(hdb, 0, "MergeErrors");
7552 "Expected ERROR_INVALID_HANDLE, got %d\n", r);
7553
7554 /* szTableName is NULL */
7555 r = MsiDatabaseMergeA(hdb, href, NULL);
7556 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7557
7558 /* szTableName is empty */
7559 r = MsiDatabaseMergeA(hdb, href, "");
7560 ok(r == ERROR_INVALID_TABLE, "Expected ERROR_INVALID_TABLE, got %d\n", r);
7561
7562 /* both DBs empty, szTableName is valid */
7563 r = MsiDatabaseMergeA(hdb, href, "MergeErrors");
7564 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7565
7566 query = "CREATE TABLE `One` ( `A` INT PRIMARY KEY `A` )";
7567 r = run_query(hdb, 0, query);
7568 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7569
7570 query = "CREATE TABLE `One` ( `A` CHAR(72) PRIMARY KEY `A` )";
7571 r = run_query(href, 0, query);
7572 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7573
7574 /* column types don't match */
7575 r = MsiDatabaseMergeA(hdb, href, "MergeErrors");
7577 "Expected ERROR_DATATYPE_MISMATCH, got %d\n", r);
7578
7579 /* nothing in MergeErrors */
7580 query = "SELECT * FROM `MergeErrors`";
7581 r = do_query(hdb, query, &hrec);
7583 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7584
7585 query = "DROP TABLE `One`";
7586 r = run_query(hdb, 0, query);
7587 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7588
7589 query = "DROP TABLE `One`";
7590 r = run_query(href, 0, query);
7591 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7592
7593 query = "CREATE TABLE `One` ( "
7594 "`A` CHAR(72), "
7595 "`B` CHAR(56), "
7596 "`C` CHAR(64) LOCALIZABLE, "
7597 "`D` LONGCHAR, "
7598 "`E` CHAR(72) NOT NULL, "
7599 "`F` CHAR(56) NOT NULL, "
7600 "`G` CHAR(64) NOT NULL LOCALIZABLE, "
7601 "`H` LONGCHAR NOT NULL "
7602 "PRIMARY KEY `A` )";
7603 r = run_query(hdb, 0, query);
7604 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7605
7606 query = "CREATE TABLE `One` ( "
7607 "`A` CHAR(64), "
7608 "`B` CHAR(64), "
7609 "`C` CHAR(64), "
7610 "`D` CHAR(64), "
7611 "`E` CHAR(64) NOT NULL, "
7612 "`F` CHAR(64) NOT NULL, "
7613 "`G` CHAR(64) NOT NULL, "
7614 "`H` CHAR(64) NOT NULL "
7615 "PRIMARY KEY `A` )";
7616 r = run_query(href, 0, query);
7617 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7618
7619 /* column string types don't match exactly */
7620 r = MsiDatabaseMergeA(hdb, href, "MergeErrors");
7621 ok(r == ERROR_SUCCESS,
7622 "Expected ERROR_SUCCESS, got %d\n", r);
7623
7624 /* nothing in MergeErrors */
7625 query = "SELECT * FROM `MergeErrors`";
7626 r = do_query(hdb, query, &hrec);
7628 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7629
7630 query = "DROP TABLE `One`";
7631 r = run_query(hdb, 0, query);
7632 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7633
7634 query = "DROP TABLE `One`";
7635 r = run_query(href, 0, query);
7636 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7637
7638 query = "CREATE TABLE `One` ( `A` INT, `B` INT PRIMARY KEY `A` )";
7639 r = run_query(hdb, 0, query);
7640 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7641
7642 query = "CREATE TABLE `One` ( `A` INT, `C` INT PRIMARY KEY `A` )";
7643 r = run_query(href, 0, query);
7644 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7645
7646 /* column names don't match */
7647 r = MsiDatabaseMergeA(hdb, href, "MergeErrors");
7649 "Expected ERROR_DATATYPE_MISMATCH, got %d\n", r);
7650
7651 /* nothing in MergeErrors */
7652 query = "SELECT * FROM `MergeErrors`";
7653 r = do_query(hdb, query, &hrec);
7655 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7656
7657 query = "DROP TABLE `One`";
7658 r = run_query(hdb, 0, query);
7659 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7660
7661 query = "DROP TABLE `One`";
7662 r = run_query(href, 0, query);
7663 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7664
7665 query = "CREATE TABLE `One` ( `A` INT, `B` INT PRIMARY KEY `A` )";
7666 r = run_query(hdb, 0, query);
7667 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7668
7669 query = "CREATE TABLE `One` ( `A` INT, `B` INT PRIMARY KEY `B` )";
7670 r = run_query(href, 0, query);
7671 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7672
7673 /* primary keys don't match */
7674 r = MsiDatabaseMergeA(hdb, href, "MergeErrors");
7676 "Expected ERROR_DATATYPE_MISMATCH, got %d\n", r);
7677
7678 /* nothing in MergeErrors */
7679 query = "SELECT * FROM `MergeErrors`";
7680 r = do_query(hdb, query, &hrec);
7682 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7683
7684 query = "DROP TABLE `One`";
7685 r = run_query(hdb, 0, query);
7686 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7687
7688 query = "DROP TABLE `One`";
7689 r = run_query(href, 0, query);
7690 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7691
7692 query = "CREATE TABLE `One` ( `A` INT, `B` INT PRIMARY KEY `A` )";
7693 r = run_query(hdb, 0, query);
7694 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7695
7696 query = "CREATE TABLE `One` ( `A` INT, `B` INT PRIMARY KEY `A`, `B` )";
7697 r = run_query(href, 0, query);
7698 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7699
7700 /* number of primary keys doesn't match */
7701 r = MsiDatabaseMergeA(hdb, href, "MergeErrors");
7703 "Expected ERROR_DATATYPE_MISMATCH, got %d\n", r);
7704
7705 /* nothing in MergeErrors */
7706 query = "SELECT * FROM `MergeErrors`";
7707 r = do_query(hdb, query, &hrec);
7709 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7710
7711 query = "DROP TABLE `One`";
7712 r = run_query(hdb, 0, query);
7713 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7714
7715 query = "DROP TABLE `One`";
7716 r = run_query(href, 0, query);
7717 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7718
7719 query = "CREATE TABLE `One` ( `A` INT, `B` INT, `C` INT PRIMARY KEY `A` )";
7720 r = run_query(hdb, 0, query);
7721 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7722
7723 query = "CREATE TABLE `One` ( `A` INT, `B` INT PRIMARY KEY `A` )";
7724 r = run_query(href, 0, query);
7725 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7726
7727 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 1, 2 )";
7728 r = run_query(href, 0, query);
7729 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7730
7731 /* number of columns doesn't match */
7732 r = MsiDatabaseMergeA(hdb, href, "MergeErrors");
7733 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7734
7735 query = "SELECT * FROM `One`";
7736 r = do_query(hdb, query, &hrec);
7737 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7738
7739 r = MsiRecordGetInteger(hrec, 1);
7740 ok(r == 1, "Expected 1, got %d\n", r);
7741
7742 r = MsiRecordGetInteger(hrec, 2);
7743 ok(r == 2, "Expected 2, got %d\n", r);
7744
7745 r = MsiRecordGetInteger(hrec, 3);
7746 ok(r == MSI_NULL_INTEGER, "Expected MSI_NULL_INTEGER, got %d\n", r);
7747
7748 MsiCloseHandle(hrec);
7749
7750 /* nothing in MergeErrors */
7751 query = "SELECT * FROM `MergeErrors`";
7752 r = do_query(hdb, query, &hrec);
7754 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7755
7756 query = "DROP TABLE `One`";
7757 r = run_query(hdb, 0, query);
7758 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7759
7760 query = "DROP TABLE `One`";
7761 r = run_query(href, 0, query);
7762 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7763
7764 query = "CREATE TABLE `One` ( `A` INT, `B` INT PRIMARY KEY `A` )";
7765 r = run_query(hdb, 0, query);
7766 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7767
7768 query = "CREATE TABLE `One` ( `A` INT, `B` INT, `C` INT PRIMARY KEY `A` )";
7769 r = run_query(href, 0, query);
7770 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7771
7772 query = "INSERT INTO `One` ( `A`, `B`, `C` ) VALUES ( 1, 2, 3 )";
7773 r = run_query(href, 0, query);
7774 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7775
7776 /* number of columns doesn't match */
7777 r = MsiDatabaseMergeA(hdb, href, "MergeErrors");
7778 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7779
7780 query = "SELECT * FROM `One`";
7781 r = do_query(hdb, query, &hrec);
7782 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7783
7784 r = MsiRecordGetInteger(hrec, 1);
7785 ok(r == 1, "Expected 1, got %d\n", r);
7786
7787 r = MsiRecordGetInteger(hrec, 2);
7788 ok(r == 2, "Expected 2, got %d\n", r);
7789
7790 r = MsiRecordGetInteger(hrec, 3);
7791 ok(r == MSI_NULL_INTEGER, "Expected MSI_NULL_INTEGER, got %d\n", r);
7792
7793 MsiCloseHandle(hrec);
7794
7795 /* nothing in MergeErrors */
7796 query = "SELECT * FROM `MergeErrors`";
7797 r = do_query(hdb, query, &hrec);
7799 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7800
7801 query = "DROP TABLE `One`";
7802 r = run_query(hdb, 0, query);
7803 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7804
7805 query = "DROP TABLE `One`";
7806 r = run_query(href, 0, query);
7807 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7808
7809 query = "CREATE TABLE `One` ( `A` INT, `B` INT PRIMARY KEY `A` )";
7810 r = run_query(hdb, 0, query);
7811 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7812
7813 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 1, 1 )";
7814 r = run_query(hdb, 0, query);
7815 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7816
7817 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 2, 2 )";
7818 r = run_query(hdb, 0, query);
7819 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7820
7821 query = "CREATE TABLE `One` ( `A` INT, `B` INT PRIMARY KEY `A` )";
7822 r = run_query(href, 0, query);
7823 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7824
7825 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 1, 2 )";
7826 r = run_query(href, 0, query);
7827 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7828
7829 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 2, 3 )";
7830 r = run_query(href, 0, query);
7831 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7832
7833 /* primary keys match, rows do not */
7834 r = MsiDatabaseMergeA(hdb, href, "MergeErrors");
7836 "Expected ERROR_FUNCTION_FAILED, got %d\n", r);
7837
7838 /* nothing in MergeErrors */
7839 query = "SELECT * FROM `MergeErrors`";
7840 r = do_query(hdb, query, &hrec);
7841 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7842 check_record(hrec, 2, "One", "2");
7843 MsiCloseHandle(hrec);
7844
7845 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `MergeErrors`", &hview);
7846 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7847
7848 r = MsiViewGetColumnInfo(hview, MSICOLINFO_NAMES, &hrec);
7849 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7850 check_record(hrec, 2, "Table", "NumRowMergeConflicts");
7851 MsiCloseHandle(hrec);
7852
7853 r = MsiViewGetColumnInfo(hview, MSICOLINFO_TYPES, &hrec);
7854 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7855 check_record(hrec, 2, "s255", "i2");
7856 MsiCloseHandle(hrec);
7857
7858 MsiViewClose(hview);
7859 MsiCloseHandle(hview);
7860
7861 query = "DROP TABLE `MergeErrors`";
7862 r = run_query(hdb, 0, query);
7863 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7864
7865 query = "DROP TABLE `One`";
7866 r = run_query(hdb, 0, query);
7867 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7868
7869 query = "DROP TABLE `One`";
7870 r = run_query(href, 0, query);
7871 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7872
7873 query = "CREATE TABLE `One` ( `A` INT, `B` CHAR(72) PRIMARY KEY `A` )";
7874 r = run_query(href, 0, query);
7875 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7876
7877 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 1, 'hi' )";
7878 r = run_query(href, 0, query);
7879 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7880
7881 /* table from merged database is not in target database */
7882 r = MsiDatabaseMergeA(hdb, href, "MergeErrors");
7883 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7884
7885 query = "SELECT * FROM `One`";
7886 r = do_query(hdb, query, &hrec);
7887 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7888 check_record(hrec, 2, "1", "hi");
7889 MsiCloseHandle(hrec);
7890
7891 /* nothing in MergeErrors */
7892 query = "SELECT * FROM `MergeErrors`";
7893 r = do_query(hdb, query, &hrec);
7895 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7896
7897 query = "DROP TABLE `One`";
7898 r = run_query(hdb, 0, query);
7899 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7900
7901 query = "DROP TABLE `One`";
7902 r = run_query(href, 0, query);
7903 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7904
7905 query = "CREATE TABLE `One` ( "
7906 "`A` CHAR(72), `B` INT PRIMARY KEY `A` )";
7907 r = run_query(hdb, 0, query);
7908 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7909
7910 query = "CREATE TABLE `One` ( "
7911 "`A` CHAR(72), `B` INT PRIMARY KEY `A` )";
7912 r = run_query(href, 0, query);
7913 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7914
7915 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 'hi', 1 )";
7916 r = run_query(href, 0, query);
7917 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7918
7919 /* primary key is string */
7920 r = MsiDatabaseMergeA(hdb, href, "MergeErrors");
7921 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7922
7923 query = "SELECT * FROM `One`";
7924 r = do_query(hdb, query, &hrec);
7925 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7926 check_record(hrec, 2, "hi", "1");
7927 MsiCloseHandle(hrec);
7928
7929 /* nothing in MergeErrors */
7930 query = "SELECT * FROM `MergeErrors`";
7931 r = do_query(hdb, query, &hrec);
7933 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7934
7935 create_file_data("codepage.idt", "\r\n\r\n850\t_ForceCodepage\r\n", 0);
7936
7938 r = MsiDatabaseImportA(hdb, buf, "codepage.idt");
7939 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7940
7941 query = "DROP TABLE `One`";
7942 r = run_query(hdb, 0, query);
7943 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7944
7945 query = "DROP TABLE `One`";
7946 r = run_query(href, 0, query);
7947 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7948
7949 query = "CREATE TABLE `One` ( "
7950 "`A` INT, `B` CHAR(72) LOCALIZABLE PRIMARY KEY `A` )";
7951 r = run_query(hdb, 0, query);
7952 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7953
7954 query = "CREATE TABLE `One` ( "
7955 "`A` INT, `B` CHAR(72) LOCALIZABLE PRIMARY KEY `A` )";
7956 r = run_query(href, 0, query);
7957 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7958
7959 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 1, 'hi' )";
7960 r = run_query(href, 0, query);
7961 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7962
7963 /* code page does not match */
7964 r = MsiDatabaseMergeA(hdb, href, "MergeErrors");
7965 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7966
7967 query = "SELECT * FROM `One`";
7968 r = do_query(hdb, query, &hrec);
7969 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7970 check_record(hrec, 2, "1", "hi");
7971 MsiCloseHandle(hrec);
7972
7973 /* nothing in MergeErrors */
7974 query = "SELECT * FROM `MergeErrors`";
7975 r = do_query(hdb, query, &hrec);
7977 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7978
7979 query = "DROP TABLE `One`";
7980 r = run_query(hdb, 0, query);
7981 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7982
7983 query = "DROP TABLE `One`";
7984 r = run_query(href, 0, query);
7985 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7986
7987 query = "CREATE TABLE `One` ( `A` INT, `B` OBJECT PRIMARY KEY `A` )";
7988 r = run_query(hdb, 0, query);
7989 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7990
7991 query = "CREATE TABLE `One` ( `A` INT, `B` OBJECT PRIMARY KEY `A` )";
7992 r = run_query(href, 0, query);
7993 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7994
7995 create_file("binary.dat");
7996 hrec = MsiCreateRecord(1);
7997 MsiRecordSetStreamA(hrec, 1, "binary.dat");
7998
7999 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 1, ? )";
8000 r = run_query(href, hrec, query);
8001 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8002
8003 MsiCloseHandle(hrec);
8004
8005 /* binary data to merge */
8006 r = MsiDatabaseMergeA(hdb, href, "MergeErrors");
8007 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8008
8009 query = "SELECT * FROM `One`";
8010 r = do_query(hdb, query, &hrec);
8011 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8012
8013 r = MsiRecordGetInteger(hrec, 1);
8014 ok(r == 1, "Expected 1, got %d\n", r);
8015
8016 size = MAX_PATH;
8018 r = MsiRecordReadStream(hrec, 2, buf, &size);
8019 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8020 ok(!lstrcmpA(buf, "binary.dat\n"),
8021 "Expected \"binary.dat\\n\", got \"%s\"\n", buf);
8022
8023 MsiCloseHandle(hrec);
8024
8025 /* nothing in MergeErrors */
8026 query = "SELECT * FROM `MergeErrors`";
8027 r = do_query(hdb, query, &hrec);
8029 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
8030
8031 query = "DROP TABLE `One`";
8032 r = run_query(hdb, 0, query);
8033 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8034
8035 query = "DROP TABLE `One`";
8036 r = run_query(href, 0, query);
8037 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8038
8039 query = "CREATE TABLE `One` ( `A` INT, `B` CHAR(72) PRIMARY KEY `A` )";
8040 r = run_query(hdb, 0, query);
8041 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8042 r = run_query(href, 0, query);
8043 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8044
8045 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 1, 'foo' )";
8046 r = run_query(href, 0, query);
8047 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8048
8049 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 2, 'bar' )";
8050 r = run_query(href, 0, query);
8051 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8052
8053 r = MsiDatabaseMergeA(hdb, href, "MergeErrors");
8054 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8055
8056 query = "SELECT * FROM `One`";
8057 r = MsiDatabaseOpenViewA(hdb, query, &hview);
8058 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8059 r = MsiViewExecute(hview, 0);
8060 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8061
8062 r = MsiViewFetch(hview, &hrec);
8063 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8064 check_record(hrec, 2, "1", "foo");
8065 MsiCloseHandle(hrec);
8066
8067 r = MsiViewFetch(hview, &hrec);
8068 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8069 check_record(hrec, 2, "2", "bar");
8070 MsiCloseHandle(hrec);
8071
8072 r = MsiViewFetch(hview, &hrec);
8074 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8075
8076 MsiViewClose(hview);
8077 MsiCloseHandle(hview);
8078
8079 MsiCloseHandle(hdb);
8080 MsiCloseHandle(href);
8082 DeleteFileW(L"refdb.msi");
8083 DeleteFileA("codepage.idt");
8084 DeleteFileA("binary.dat");
8085}
8086
8088{
8089 MSIHANDLE hdb, view, rec;
8090 LPCSTR query;
8091 UINT r;
8092 int i;
8093
8094 int vals[4][2] = {
8095 {1,12},
8096 {4,12},
8097 {1,15},
8098 {4,15}};
8099
8100 hdb = create_db();
8101 ok(hdb, "failed to create db\n");
8102
8103 /* Build a pair of tables with the same column names, but unique data */
8104 query = "CREATE TABLE `T1` ( `A` SHORT, `B` SHORT PRIMARY KEY `A`)";
8105 r = run_query(hdb, 0, query);
8106 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8107
8108 query = "INSERT INTO `T1` ( `A`, `B` ) VALUES ( 1, 2 )";
8109 r = run_query(hdb, 0, query);
8110 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8111
8112 query = "INSERT INTO `T1` ( `A`, `B` ) VALUES ( 4, 5 )";
8113 r = run_query(hdb, 0, query);
8114 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8115
8116 query = "CREATE TABLE `T2` ( `A` SHORT, `B` SHORT PRIMARY KEY `A`)";
8117 r = run_query(hdb, 0, query);
8118 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8119
8120 query = "INSERT INTO `T2` ( `A`, `B` ) VALUES ( 11, 12 )";
8121 r = run_query(hdb, 0, query);
8122 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8123
8124 query = "INSERT INTO `T2` ( `A`, `B` ) VALUES ( 14, 15 )";
8125 r = run_query(hdb, 0, query);
8126 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8127
8128
8129 /* Test that selection based on prefixing the column with the table
8130 * actually selects the right data */
8131
8132 query = "SELECT T1.A, T2.B FROM T1,T2";
8133 r = MsiDatabaseOpenViewA(hdb, query, &view);
8134 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8135 r = MsiViewExecute(view, 0);
8136 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8137
8138 for (i = 0; i < 4; i++)
8139 {
8140 r = MsiViewFetch(view, &rec);
8141 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8142
8143 r = MsiRecordGetInteger(rec, 1);
8144 ok(r == vals[i][0], "Expected %d, got %d\n", vals[i][0], r);
8145
8146 r = MsiRecordGetInteger(rec, 2);
8147 ok(r == vals[i][1], "Expected %d, got %d\n", vals[i][1], r);
8148
8149 MsiCloseHandle(rec);
8150 }
8151
8152 r = MsiViewFetch(view, &rec);
8153 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8154
8157 MsiCloseHandle(hdb);
8159}
8160
8161static const UINT ordervals[6][3] =
8162{
8163 { MSI_NULL_INTEGER, 12, 13 },
8164 { 1, 2, 3 },
8165 { 6, 4, 5 },
8166 { 8, 9, 7 },
8167 { 10, 11, MSI_NULL_INTEGER },
8168 { 14, MSI_NULL_INTEGER, 15 }
8169};
8170
8171static void test_insertorder(void)
8172{
8173 MSIHANDLE hdb, view, rec;
8174 LPCSTR query;
8175 UINT r;
8176 int i;
8177
8178 hdb = create_db();
8179 ok(hdb, "failed to create db\n");
8180
8181 query = "CREATE TABLE `T` ( `A` SHORT, `B` SHORT, `C` SHORT PRIMARY KEY `A`)";
8182 r = run_query(hdb, 0, query);
8183 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8184
8185 query = "INSERT INTO `T` ( `A`, `B`, `C` ) VALUES ( 1, 2, 3 )";
8186 r = run_query(hdb, 0, query);
8187 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8188
8189 query = "INSERT INTO `T` ( `B`, `C`, `A` ) VALUES ( 4, 5, 6 )";
8190 r = run_query(hdb, 0, query);
8191 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8192
8193 query = "INSERT INTO `T` ( `C`, `A`, `B` ) VALUES ( 7, 8, 9 )";
8194 r = run_query(hdb, 0, query);
8195 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8196
8197 query = "INSERT INTO `T` ( `A`, `B` ) VALUES ( 10, 11 )";
8198 r = run_query(hdb, 0, query);
8199 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8200
8201 query = "INSERT INTO `T` ( `B`, `C` ) VALUES ( 12, 13 )";
8202 r = run_query(hdb, 0, query);
8203 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8204
8205 /* fails because the primary key already
8206 * has an MSI_NULL_INTEGER value set above
8207 */
8208 query = "INSERT INTO `T` ( `C` ) VALUES ( 14 )";
8209 r = run_query(hdb, 0, query);
8211 "Expected ERROR_FUNCTION_FAILED, got %d\n", r);
8212
8213 /* replicate the error where primary key is set twice */
8214 query = "INSERT INTO `T` ( `A`, `C` ) VALUES ( 1, 14 )";
8215 r = run_query(hdb, 0, query);
8217 "Expected ERROR_FUNCTION_FAILED, got %d\n", r);
8218
8219 query = "INSERT INTO `T` ( `A`, `C` ) VALUES ( 14, 15 )";
8220 r = run_query(hdb, 0, query);
8221 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8222
8223 query = "INSERT INTO `T` VALUES ( 16 )";
8224 r = run_query(hdb, 0, query);
8226 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
8227
8228 query = "INSERT INTO `T` VALUES ( 17, 18 )";
8229 r = run_query(hdb, 0, query);
8231 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
8232
8233 query = "INSERT INTO `T` VALUES ( 19, 20, 21 )";
8234 r = run_query(hdb, 0, query);
8236 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
8237
8238 query = "SELECT * FROM `T`";
8239 r = MsiDatabaseOpenViewA(hdb, query, &view);
8240 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8241 r = MsiViewExecute(view, 0);
8242 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8243
8244 for (i = 0; i < 6; i++)
8245 {
8246 r = MsiViewFetch(view, &rec);
8247 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8248
8249 r = MsiRecordGetInteger(rec, 1);
8250 ok(r == ordervals[i][0], "Expected %d, got %d\n", ordervals[i][0], r);
8251
8252 r = MsiRecordGetInteger(rec, 2);
8253 ok(r == ordervals[i][1], "Expected %d, got %d\n", ordervals[i][1], r);
8254
8255 r = MsiRecordGetInteger(rec, 3);
8256 ok(r == ordervals[i][2], "Expected %d, got %d\n", ordervals[i][2], r);
8257
8258 MsiCloseHandle(rec);
8259 }
8260
8261 r = MsiViewFetch(view, &rec);
8262 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8263
8266
8267 query = "DELETE FROM `T` WHERE `A` IS NULL";
8268 r = run_query(hdb, 0, query);
8269 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8270
8271 query = "INSERT INTO `T` ( `B`, `C` ) VALUES ( 12, 13 ) TEMPORARY";
8272 r = run_query(hdb, 0, query);
8273 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8274
8275 query = "SELECT * FROM `T`";
8276 r = MsiDatabaseOpenViewA(hdb, query, &view);
8277 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8278 r = MsiViewExecute(view, 0);
8279 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8280
8281 for (i = 0; i < 6; i++)
8282 {
8283 r = MsiViewFetch(view, &rec);
8284 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8285
8286 r = MsiRecordGetInteger(rec, 1);
8287 ok(r == ordervals[i][0], "Expected %d, got %d\n", ordervals[i][0], r);
8288
8289 r = MsiRecordGetInteger(rec, 2);
8290 ok(r == ordervals[i][1], "Expected %d, got %d\n", ordervals[i][1], r);
8291
8292 r = MsiRecordGetInteger(rec, 3);
8293 ok(r == ordervals[i][2], "Expected %d, got %d\n", ordervals[i][2], r);
8294
8295 MsiCloseHandle(rec);
8296 }
8297
8298 r = MsiViewFetch(view, &rec);
8299 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8300
8303 MsiCloseHandle(hdb);
8305}
8306
8307static void test_columnorder(void)
8308{
8309 MSIHANDLE hdb, view, rec;
8310 LPCSTR query;
8311 UINT r;
8312
8313 hdb = create_db();
8314 ok(hdb, "failed to create db\n");
8315
8316 /* Each column is a slot:
8317 * ---------------------
8318 * | B | C | A | E | D |
8319 * ---------------------
8320 *
8321 * When a column is selected as a primary key,
8322 * the column occupying the nth primary key slot is swapped
8323 * with the current position of the primary key in question:
8324 *
8325 * set primary key `D`
8326 * --------------------- ---------------------
8327 * | B | C | A | E | D | -> | D | C | A | E | B |
8328 * --------------------- ---------------------
8329 *
8330 * set primary key `E`
8331 * --------------------- ---------------------
8332 * | D | C | A | E | B | -> | D | E | A | C | B |
8333 * --------------------- ---------------------
8334 */
8335
8336 query = "CREATE TABLE `T` ( `B` SHORT NOT NULL, `C` SHORT NOT NULL, "
8337 "`A` CHAR(255), `E` INT, `D` CHAR(255) NOT NULL "
8338 "PRIMARY KEY `D`, `E`)";
8339 r = run_query(hdb, 0, query);
8340 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8341
8342 query = "SELECT * FROM `T`";
8343 r = MsiDatabaseOpenViewA(hdb, query, &view);
8344 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8345
8347 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8348 check_record(rec, 5, "s255", "I2", "S255", "i2", "i2");
8349 MsiCloseHandle(rec);
8350
8352 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8353 check_record(rec, 5, "D", "E", "A", "C", "B");
8354 MsiCloseHandle(rec);
8355
8358
8359 query = "INSERT INTO `T` ( `B`, `C`, `A`, `E`, `D` ) "
8360 "VALUES ( 1, 2, 'a', 3, 'bc' )";
8361 r = run_query(hdb, 0, query);
8362 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8363
8364 query = "SELECT * FROM `T`";
8365 r = do_query(hdb, query, &rec);
8366 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8367 check_record(rec, 5, "bc", "3", "a", "2", "1");
8368 MsiCloseHandle(rec);
8369
8370 query = "SELECT `Table`, `Number`, `Name` FROM `_Columns` WHERE `Table` = 'T'";
8371 r = MsiDatabaseOpenViewA(hdb, query, &view);
8372 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8373 r = MsiViewExecute(view, 0);
8374 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8375
8376 r = MsiViewFetch(view, &rec);
8377 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8378 check_record(rec, 3, "T", "1", "D");
8379 MsiCloseHandle(rec);
8380
8381 r = MsiViewFetch(view, &rec);
8382 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8383 check_record(rec, 3, "T", "2", "E");
8384 MsiCloseHandle(rec);
8385
8386 r = MsiViewFetch(view, &rec);
8387 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8388 check_record(rec, 3, "T", "3", "A");
8389 MsiCloseHandle(rec);
8390
8391 r = MsiViewFetch(view, &rec);
8392 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8393 check_record(rec, 3, "T", "4", "C");
8394 MsiCloseHandle(rec);
8395
8396 r = MsiViewFetch(view, &rec);
8397 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8398 check_record(rec, 3, "T", "5", "B");
8399 MsiCloseHandle(rec);
8400
8401 r = MsiViewFetch(view, &rec);
8402 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8403
8406
8407 query = "CREATE TABLE `Z` ( `B` SHORT NOT NULL, `C` SHORT NOT NULL, "
8408 "`A` CHAR(255), `E` INT, `D` CHAR(255) NOT NULL "
8409 "PRIMARY KEY `C`, `A`, `D`)";
8410 r = run_query(hdb, 0, query);
8411 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8412
8413 query = "SELECT * FROM `Z`";
8414 r = MsiDatabaseOpenViewA(hdb, query, &view);
8415 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8416
8418 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8419 check_record(rec, 5, "i2", "S255", "s255", "I2", "i2");
8420 MsiCloseHandle(rec);
8421
8423 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8424 check_record(rec, 5, "C", "A", "D", "E", "B");
8425 MsiCloseHandle(rec);
8426
8429
8430 query = "INSERT INTO `Z` ( `B`, `C`, `A`, `E`, `D` ) "
8431 "VALUES ( 1, 2, 'a', 3, 'bc' )";
8432 r = run_query(hdb, 0, query);
8433 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8434
8435 query = "SELECT * FROM `Z`";
8436 r = do_query(hdb, query, &rec);
8437 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8438 check_record(rec, 5, "2", "a", "bc", "3", "1");
8439 MsiCloseHandle(rec);
8440
8441 query = "SELECT `Table`, `Number`, `Name` FROM `_Columns` WHERE `Table` = 'T'";
8442 r = MsiDatabaseOpenViewA(hdb, query, &view);
8443 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8444 r = MsiViewExecute(view, 0);
8445 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8446
8447 r = MsiViewFetch(view, &rec);
8448 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8449 check_record(rec, 3, "T", "1", "D");
8450 MsiCloseHandle(rec);
8451
8452 r = MsiViewFetch(view, &rec);
8453 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8454 check_record(rec, 3, "T", "2", "E");
8455 MsiCloseHandle(rec);
8456
8457 r = MsiViewFetch(view, &rec);
8458 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8459 check_record(rec, 3, "T", "3", "A");
8460 MsiCloseHandle(rec);
8461
8462 r = MsiViewFetch(view, &rec);
8463 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8464 check_record(rec, 3, "T", "4", "C");
8465 MsiCloseHandle(rec);
8466
8467 r = MsiViewFetch(view, &rec);
8468 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8469 check_record(rec, 3, "T", "5", "B");
8470 MsiCloseHandle(rec);
8471
8472 r = MsiViewFetch(view, &rec);
8473 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8474
8477
8478 MsiCloseHandle(hdb);
8480}
8481
8482static void test_createtable(void)
8483{
8484 MSIHANDLE hdb, htab = 0, hrec = 0;
8485 LPCSTR query;
8486 UINT res;
8487 DWORD size;
8488 char buffer[0x20];
8489
8490 hdb = create_db();
8491 ok(hdb, "failed to create db\n");
8492
8493 query = "CREATE TABLE `blah` (`foo` CHAR(72) NOT NULL PRIMARY KEY `foo`)";
8494 res = MsiDatabaseOpenViewA( hdb, query, &htab );
8495 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8496 if(res == ERROR_SUCCESS )
8497 {
8498 res = MsiViewExecute( htab, hrec );
8499 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8500
8501 res = MsiViewGetColumnInfo( htab, MSICOLINFO_NAMES, &hrec );
8502 todo_wine ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8503
8504 size = sizeof(buffer);
8505 res = MsiRecordGetStringA(hrec, 1, buffer, &size );
8506 todo_wine ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8507 MsiCloseHandle( hrec );
8508
8509 res = MsiViewClose( htab );
8510 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8511
8512 res = MsiCloseHandle( htab );
8513 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8514 }
8515
8516 query = "CREATE TABLE `a` (`b` INT PRIMARY KEY `b`)";
8517 res = MsiDatabaseOpenViewA( hdb, query, &htab );
8518 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8519 if(res == ERROR_SUCCESS )
8520 {
8521 res = MsiViewExecute( htab, 0 );
8522 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8523
8524 res = MsiViewClose( htab );
8525 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8526
8527 res = MsiCloseHandle( htab );
8528 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8529
8530 query = "SELECT * FROM `a`";
8531 res = MsiDatabaseOpenViewA( hdb, query, &htab );
8532 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8533
8534 res = MsiViewGetColumnInfo( htab, MSICOLINFO_NAMES, &hrec );
8535 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8536 check_record(hrec, 1, "b");
8537 MsiCloseHandle( hrec );
8538
8539 res = MsiViewClose( htab );
8540 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8541
8542 res = MsiCloseHandle( htab );
8543 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8544
8545 res = MsiDatabaseCommit(hdb);
8546 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8547
8548 res = MsiCloseHandle(hdb);
8549 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8550
8552 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8553
8554 query = "SELECT * FROM `a`";
8555 res = MsiDatabaseOpenViewA( hdb, query, &htab );
8556 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8557
8558 res = MsiViewGetColumnInfo( htab, MSICOLINFO_NAMES, &hrec );
8559 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8560 check_record(hrec, 1, "b");
8561 res = MsiCloseHandle( hrec );
8562 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8563
8564 res = MsiViewClose( htab );
8565 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8566
8567 res = MsiCloseHandle( htab );
8568 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8569 }
8570
8571 res = MsiDatabaseCommit(hdb);
8572 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8573
8574 res = MsiCloseHandle(hdb);
8575 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8576
8578}
8579
8580static void test_embedded_nulls(void)
8581{
8582 static const char control_table[] =
8583 "Dialog\tText\n"
8584 "s72\tL0\n"
8585 "Control\tDialog\n"
8586 "LicenseAgreementDlg\ttext\x11\x19text\0text";
8587 UINT r;
8588 DWORD sz;
8589 MSIHANDLE hdb, hrec;
8590 char buffer[32];
8591
8593 ok( r == ERROR_SUCCESS, "failed to open database %u\n", r );
8594
8596 write_file( "temp_file", control_table, sizeof(control_table) );
8597 r = MsiDatabaseImportA( hdb, CURR_DIR, "temp_file" );
8598 ok( r == ERROR_SUCCESS, "failed to import table %u\n", r );
8599 DeleteFileA( "temp_file" );
8600
8601 r = do_query( hdb, "SELECT `Text` FROM `Control` WHERE `Dialog` = 'LicenseAgreementDlg'", &hrec );
8602 ok( r == ERROR_SUCCESS, "query failed %u\n", r );
8603
8604 buffer[0] = 0;
8605 sz = sizeof(buffer);
8606 r = MsiRecordGetStringA( hrec, 1, buffer, &sz );
8607 ok( r == ERROR_SUCCESS, "failed to get string %u\n", r );
8608 ok( !memcmp( "text\r\ntext\ntext", buffer, sizeof("text\r\ntext\ntext") - 1 ), "wrong buffer contents \"%s\"\n", buffer );
8609
8610 MsiCloseHandle( hrec );
8611 MsiCloseHandle( hdb );
8613}
8614
8616{
8617 MSIHANDLE hdb = 0, rec, view;
8618 UINT r;
8619
8621
8623 ok( r == ERROR_SUCCESS , "failed to open database: %u\n", r );
8624
8625 r = try_query( hdb, "CREATE TABLE `t` (`a` CHAR NOT NULL, `b` CHAR PRIMARY KEY `a`)");
8626 ok( r == ERROR_SUCCESS , "query failed: %u\n", r );
8627
8628 r = try_query( hdb, "SELECT `t`.`b` FROM `t` WHERE `t`.`b` = `x`" );
8629 ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %u\n", r );
8630
8631 r = try_query( hdb, "SELECT '', `t`.`b` FROM `t` WHERE `t`.`b` = 'x'" );
8632 ok( r == ERROR_SUCCESS , "query failed: %u\n", r );
8633
8634 r = try_query( hdb, "SELECT *, `t`.`b` FROM `t` WHERE `t`.`b` = 'x'" );
8635 todo_wine ok( r == ERROR_SUCCESS, "query failed: %u\n", r );
8636
8637 r = try_query( hdb, "SELECT 'b', `t`.`b` FROM `t` WHERE `t`.`b` = 'x'" );
8638 ok( r == ERROR_SUCCESS , "query failed: %u\n", r );
8639
8640 r = try_query( hdb, "SELECT `t`.`b`, '' FROM `t` WHERE `t`.`b` = 'x'" );
8641 ok( r == ERROR_SUCCESS , "query failed: %u\n", r );
8642
8643 r = try_query( hdb, "SELECT `t`.`b`, '' FROM `t` WHERE `t`.`b` = 'x' ORDER BY `b`" );
8644 ok( r == ERROR_SUCCESS , "query failed: %u\n", r );
8645
8646 r = try_query( hdb, "SELECT `t`.`b`, '' FROM `t` WHERE `t`.`b` = 'x' ORDER BY 'b'" );
8647 ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %u\n", r );
8648
8649 r = try_query( hdb, "SELECT 't'.'b' FROM `t` WHERE `t`.`b` = 'x'" );
8650 ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %u\n", r );
8651
8652 r = try_query( hdb, "SELECT 'b' FROM `t` WHERE `t`.`b` = 'x'" );
8653 ok( r == ERROR_SUCCESS , "query failed: %u\n", r );
8654
8655 r = try_query( hdb, "INSERT INTO `t` ( `a`, `b` ) VALUES( '1', '2' )" );
8656 ok( r == ERROR_SUCCESS , "query failed: %u\n", r );
8657
8658 r = try_query( hdb, "INSERT INTO `t` ( `a`, `b` ) VALUES( '3', '4' )" );
8659 ok( r == ERROR_SUCCESS , "query failed: %u\n", r );
8660
8661 r = MsiDatabaseOpenViewA( hdb, "SELECT '' FROM `t`", &view );
8662 ok( r == ERROR_SUCCESS, "failed to open database view: %u\n", r );
8663
8664 r = MsiViewExecute( view, 0 );
8665 ok( r == ERROR_SUCCESS, "failed to execute view: %u\n", r );
8666
8667 r = MsiViewFetch( view, &rec );
8668 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r );
8669 check_record(rec, 1, "");
8670 MsiCloseHandle(rec);
8671
8673 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r );
8674 check_record(rec, 1, "");
8675 MsiCloseHandle(rec);
8676
8678 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r );
8679 check_record(rec, 1, "f0");
8680 MsiCloseHandle(rec);
8681
8682 r = MsiViewFetch( view, &rec );
8683 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r );
8684 check_record(rec, 1, "");
8685 MsiCloseHandle( rec );
8686
8687 r = MsiViewFetch( view, &rec );
8688 ok( r == ERROR_NO_MORE_ITEMS, "unexpected result: %u\n", r );
8689 MsiCloseHandle( rec );
8690
8691 MsiViewClose( view );
8693
8694 r = MsiDatabaseOpenViewA( hdb, "SELECT `a`, '' FROM `t`", &view );
8695 ok( r == ERROR_SUCCESS, "failed to open database view: %u\n", r );
8696
8697 r = MsiViewExecute( view, 0 );
8698 ok( r == ERROR_SUCCESS, "failed to execute view: %u\n", r );
8699
8700 r = MsiViewFetch( view, &rec );
8701 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r );
8702 check_record(rec, 2, "1", "");
8703 MsiCloseHandle( rec );
8704
8705 r = MsiViewFetch( view, &rec );
8706 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r );
8707 check_record(rec, 2, "3", "");
8708 MsiCloseHandle( rec );
8709
8710 r = MsiViewFetch( view, &rec );
8711 ok( r == ERROR_NO_MORE_ITEMS, "unexpected result: %u\n", r );
8712 MsiCloseHandle( rec );
8713
8714 MsiViewClose( view );
8716
8717 r = MsiDatabaseOpenViewA( hdb, "SELECT '', `a` FROM `t`", &view );
8718 ok( r == ERROR_SUCCESS, "failed to open database view: %u\n", r );
8719
8720 r = MsiViewExecute( view, 0 );
8721 ok( r == ERROR_SUCCESS, "failed to execute view: %u\n", r );
8722
8723 r = MsiViewFetch( view, &rec );
8724 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r );
8725 check_record(rec, 2, "", "1");
8726 MsiCloseHandle( rec );
8727
8728 r = MsiViewFetch( view, &rec );
8729 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r );
8730 check_record(rec, 2, "", "3");
8731 MsiCloseHandle( rec );
8732
8733 r = MsiViewFetch( view, &rec );
8734 ok( r == ERROR_NO_MORE_ITEMS, "unexpected result: %u\n", r );
8735 MsiCloseHandle( rec );
8736
8737 MsiViewClose( view );
8739
8740 r = MsiDatabaseOpenViewA( hdb, "SELECT `a`, '', `b` FROM `t`", &view );
8741 ok( r == ERROR_SUCCESS, "failed to open database view: %u\n", r );
8742
8743 r = MsiViewExecute( view, 0 );
8744 ok( r == ERROR_SUCCESS, "failed to execute view: %u\n", r );
8745
8746 r = MsiViewFetch( view, &rec );
8747 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r );
8748 check_record(rec, 3, "1", "", "2");
8749 MsiCloseHandle( rec );
8750
8751 r = MsiViewFetch( view, &rec );
8752 ok( r == ERROR_SUCCESS, "unexpected result: %u\n", r );
8753 check_record(rec, 3, "3", "", "4");
8754 MsiCloseHandle( rec );
8755
8756 r = MsiViewFetch( view, &rec );
8757 ok( r == ERROR_NO_MORE_ITEMS, "unexpected result: %u\n", r );
8758 MsiCloseHandle( rec );
8759
8760 MsiViewClose( view );
8762
8763 r = try_query( hdb, "SELECT '' FROM `t` WHERE `t`.`b` = 'x'" );
8764 ok( r == ERROR_SUCCESS , "query failed: %u\n", r );
8765
8766 r = try_query( hdb, "SELECT `` FROM `t` WHERE `t`.`b` = 'x'" );
8767 todo_wine ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %u\n", r );
8768
8769 r = try_query( hdb, "SELECT `b` FROM 't' WHERE `t`.`b` = 'x'" );
8770 ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %u\n", r );
8771
8772 r = try_query( hdb, "SELECT `b` FROM `t` WHERE 'b' = 'x'" );
8773 ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %u\n", r );
8774
8775 r = try_query( hdb, "SELECT `t`.`b`, `` FROM `t` WHERE `t`.`b` = 'x'" );
8776 todo_wine ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %u\n", r );
8777
8778 r = MsiCloseHandle( hdb );
8779 ok(r == ERROR_SUCCESS , "failed to close database: %u\n", r);
8780}
8781
8782static void test_primary_keys(void)
8783{
8784 MSIHANDLE hdb, keys;
8785 char buffer[5];
8786 DWORD size;
8787 UINT r;
8788
8789 hdb = create_db();
8790
8791 r = MsiDatabaseGetPrimaryKeysA(hdb, "T", &keys);
8792 ok(r == ERROR_INVALID_TABLE, "got %u\n", r);
8793
8794 r = run_query(hdb, 0, "CREATE TABLE `T` (`A` SHORT, `B` SHORT, `C` SHORT PRIMARY KEY `A`)");
8795 ok(!r, "got %u\n", r);
8796
8797 r = MsiDatabaseGetPrimaryKeysA(hdb, "T", &keys);
8798 ok(!r, "got %u\n", r);
8799 check_record(keys, 1, "A");
8800 size = sizeof(buffer);
8801 r = MsiRecordGetStringA(keys, 0, buffer, &size);
8802 ok(!r, "got %u\n", r);
8803 ok(!strcmp(buffer, "T"), "got \"%s\"\n", buffer);
8804 MsiCloseHandle(keys);
8805
8806 r = run_query(hdb, 0, "CREATE TABLE `U` (`A` SHORT, `B` SHORT, `C` SHORT PRIMARY KEY `B`, `C`)");
8807 ok(!r, "got %u\n", r);
8808
8809 r = MsiDatabaseGetPrimaryKeysA(hdb, "U", &keys);
8810 ok(!r, "got %u\n", r);
8811 check_record(keys, 2, "B", "C");
8812 size = sizeof(buffer);
8813 r = MsiRecordGetStringA(keys, 0, buffer, &size);
8814 ok(!r, "got %u\n", r);
8815 ok(!strcmp(buffer, "U"), "got \"%s\"\n", buffer);
8816 MsiCloseHandle(keys);
8817 MsiCloseHandle(hdb);
8819}
8820
8821static void test_viewmodify_merge(void)
8822{
8823 MSIHANDLE view, rec, db = create_db();
8824 UINT r;
8825
8826 r = run_query(db, 0, "CREATE TABLE `T` (`A` SHORT, `B` SHORT PRIMARY KEY `A`)");
8827 ok(!r, "got %u\n", r);
8828 r = run_query(db, 0, "INSERT INTO `T` (`A`, `B`) VALUES (1, 2)");
8829 ok(!r, "got %u\n", r);
8830
8831 r = MsiDatabaseOpenViewA(db, "SELECT * FROM `T`", &view);
8832 ok(!r, "got %u\n", r);
8833 r = MsiViewExecute(view, 0);
8834 ok(!r, "got %u\n", r);
8835
8836 rec = MsiCreateRecord(2);
8837 MsiRecordSetInteger(rec, 1, 1);
8838 MsiRecordSetInteger(rec, 2, 2);
8840 ok(!r, "got %u\n", r);
8841
8842 MsiCloseHandle(rec);
8844
8845 r = MsiDatabaseOpenViewA(db, "SELECT * FROM `T`", &view);
8846 ok(!r, "got %u\n", r);
8847 r = MsiViewExecute(view, 0);
8848 ok(!r, "got %u\n", r);
8849
8850 r = MsiViewFetch(view, &rec);
8851 ok(!r, "got %u\n", r);
8852 check_record(rec, 2, "1", "2");
8853 MsiCloseHandle(rec);
8854
8855 r = MsiViewFetch(view, &rec);
8856 ok(r == ERROR_NO_MORE_ITEMS, "got %u\n", r);
8858
8859 r = MsiDatabaseOpenViewA(db, "SELECT * FROM `T`", &view);
8860 ok(!r, "got %u\n", r);
8861 r = MsiViewExecute(view, 0);
8862 ok(!r, "got %u\n", r);
8863
8864 rec = MsiCreateRecord(2);
8865 MsiRecordSetInteger(rec, 1, 1);
8866 MsiRecordSetInteger(rec, 2, 3);
8868 todo_wine
8869 ok(r == ERROR_FUNCTION_FAILED, "got %u\n", r);
8870
8871 MsiRecordSetInteger(rec, 1, 2);
8873 ok(!r, "got %u\n", r);
8874
8875 MsiCloseHandle(rec);
8877
8878 r = MsiDatabaseOpenViewA(db, "SELECT * FROM `T`", &view);
8879 ok(!r, "got %u\n", r);
8880 r = MsiViewExecute(view, 0);
8881 ok(!r, "got %u\n", r);
8882
8883 r = MsiViewFetch(view, &rec);
8884 ok(!r, "got %u\n", r);
8885 check_record(rec, 2, "1", "2");
8886 MsiCloseHandle(rec);
8887
8888 r = MsiViewFetch(view, &rec);
8889 ok(!r, "got %u\n", r);
8890 check_record(rec, 2, "2", "3");
8891 MsiCloseHandle(rec);
8892
8893 r = MsiViewFetch(view, &rec);
8894 ok(r == ERROR_NO_MORE_ITEMS, "got %u\n", r);
8896
8897 r = run_query(db, 0, "CREATE TABLE `U` (`A` SHORT, `B` SHORT, `C` SHORT, `D` SHORT PRIMARY KEY `A`, `B`)");
8898 ok(!r, "got %u\n", r);
8899 r = run_query(db, 0, "INSERT INTO `U` (`A`, `B`, `C`, `D`) VALUES (1, 2, 3, 4)");
8900 ok(!r, "got %u\n", r);
8901
8902 r = MsiDatabaseOpenViewA(db, "SELECT * FROM `U`", &view);
8903 ok(!r, "got %u\n", r);
8904 r = MsiViewExecute(view, 0);
8905 ok(!r, "got %u\n", r);
8906
8907 rec = MsiCreateRecord(4);
8908 MsiRecordSetInteger(rec, 1, 1);
8909 MsiRecordSetInteger(rec, 2, 2);
8910 MsiRecordSetInteger(rec, 3, 3);
8911 MsiRecordSetInteger(rec, 4, 4);
8913 ok(!r, "got %u\n", r);
8914
8915 MsiRecordSetInteger(rec, 3, 4);
8917 todo_wine
8918 ok(r == ERROR_FUNCTION_FAILED, "got %u\n", r);
8919
8920 MsiRecordSetInteger(rec, 2, 4);
8922 ok(!r, "got %u\n", r);
8923
8924 MsiCloseHandle(rec);
8926
8927 r = MsiDatabaseOpenViewA(db, "SELECT * FROM `U`", &view);
8928 ok(!r, "got %u\n", r);
8929 r = MsiViewExecute(view, 0);
8930 ok(!r, "got %u\n", r);
8931
8932 r = MsiViewFetch(view, &rec);
8933 ok(!r, "got %u\n", r);
8934 check_record(rec, 4, "1", "2", "3", "4");
8935 MsiCloseHandle(rec);
8936
8937 r = MsiViewFetch(view, &rec);
8938 ok(!r, "got %u\n", r);
8939 check_record(rec, 4, "1", "4", "4", "4");
8940 MsiCloseHandle(rec);
8941
8942 r = MsiViewFetch(view, &rec);
8943 ok(r == ERROR_NO_MORE_ITEMS, "got %u\n", r);
8945
8946 r = MsiDatabaseOpenViewA(db, "SELECT `A`,`C` FROM `U`", &view);
8947 ok(!r, "got %u\n", r);
8948 r = MsiViewExecute(view, 0);
8949 ok(!r, "got %u\n", r);
8950
8951 rec = MsiCreateRecord(2);
8952 MsiRecordSetInteger(rec, 1, 1);
8953 MsiRecordSetInteger(rec, 2, 2);
8955 ok(!r, "got %u\n", r);
8956
8958 ok(!r, "got %u\n", r);
8959
8960 MsiRecordSetInteger(rec, 2, 3);
8962 todo_wine
8963 ok(r == ERROR_FUNCTION_FAILED, "got %u\n", r);
8964
8965 MsiCloseHandle(rec);
8967
8968 r = MsiDatabaseOpenViewA(db, "SELECT * FROM `U` ORDER BY `B`", &view);
8969 ok(!r, "got %u\n", r);
8970 r = MsiViewExecute(view, 0);
8971 ok(!r, "got %u\n", r);
8972
8973 r = MsiViewFetch(view, &rec);
8974 ok(!r, "got %u\n", r);
8975 check_record(rec, 4, "1", "", "2", "");
8976 MsiCloseHandle(rec);
8977
8978 r = MsiViewFetch(view, &rec);
8979 ok(!r, "got %u\n", r);
8980 check_record(rec, 4, "1", "2", "3", "4");
8981 MsiCloseHandle(rec);
8982
8983 r = MsiViewFetch(view, &rec);
8984 ok(!r, "got %u\n", r);
8985 check_record(rec, 4, "1", "4", "4", "4");
8986 MsiCloseHandle(rec);
8987
8988 r = MsiViewFetch(view, &rec);
8989 ok(r == ERROR_NO_MORE_ITEMS, "got %u\n", r);
8991
8992 r = MsiDatabaseOpenViewA(db, "SELECT `A`,`B`,`C` FROM `U`", &view);
8993 ok(!r, "got %u\n", r);
8994 r = MsiViewExecute(view, 0);
8995 ok(!r, "got %u\n", r);
8996
8997 rec = MsiCreateRecord(3);
8998 MsiRecordSetInteger(rec, 1, 1);
8999 MsiRecordSetInteger(rec, 2, 2);
9000 MsiRecordSetInteger(rec, 3, 3);
9002 todo_wine
9003 ok(r == ERROR_FUNCTION_FAILED, "got %u\n", r);
9004
9005 MsiRecordSetInteger(rec, 1, 1);
9007 MsiRecordSetInteger(rec, 3, 2);
9009 ok(!r, "got %u\n", r);
9010
9011 MsiCloseHandle(rec);
9013
9014 MsiCloseHandle(db);
9016}
9017
9018static void test_viewmodify_insert(void)
9019{
9020 MSIHANDLE view, rec, db = create_db();
9021 UINT r;
9022
9023 r = run_query(db, 0, "CREATE TABLE `T` (`A` SHORT, `B` SHORT PRIMARY KEY `A`)");
9024 ok(!r, "got %u\n", r);
9025
9026 r = MsiDatabaseOpenViewA(db, "SELECT * FROM `T`", &view);
9027 ok(!r, "got %u\n", r);
9028 r = MsiViewExecute(view, 0);
9029 ok(!r, "got %u\n", r);
9030
9031 rec = MsiCreateRecord(2);
9032 MsiRecordSetInteger(rec, 1, 1);
9033 MsiRecordSetInteger(rec, 2, 2);
9035 ok(!r, "got %u\n", r);
9036
9037 MsiCloseHandle(rec);
9039
9040 r = MsiDatabaseOpenViewA(db, "SELECT * FROM `T`", &view);
9041 ok(!r, "got %u\n", r);
9042 r = MsiViewExecute(view, 0);
9043 ok(!r, "got %u\n", r);
9044
9045 r = MsiViewFetch(view, &rec);
9046 ok(!r, "got %u\n", r);
9047 check_record(rec, 2, "1", "2");
9048 MsiCloseHandle(rec);
9049
9050 r = MsiViewFetch(view, &rec);
9051 ok(r == ERROR_NO_MORE_ITEMS, "got %u\n", r);
9053
9054 r = MsiDatabaseOpenViewA(db, "SELECT * FROM `T`", &view);
9055 ok(!r, "got %u\n", r);
9056 r = MsiViewExecute(view, 0);
9057 ok(!r, "got %u\n", r);
9058
9059 rec = MsiCreateRecord(2);
9060 MsiRecordSetInteger(rec, 1, 1);
9061 MsiRecordSetInteger(rec, 2, 2);
9063 ok(r == ERROR_FUNCTION_FAILED, "got %u\n", r);
9064
9065 MsiRecordSetInteger(rec, 2, 3);
9067 ok(r == ERROR_FUNCTION_FAILED, "got %u\n", r);
9068
9069 MsiRecordSetInteger(rec, 1, 3);
9071 ok(!r, "got %u\n", r);
9072
9073 MsiCloseHandle(rec);
9075
9076 r = MsiDatabaseOpenViewA(db, "SELECT * FROM `T`", &view);
9077 ok(!r, "got %u\n", r);
9078 r = MsiViewExecute(view, 0);
9079 ok(!r, "got %u\n", r);
9080
9081 r = MsiViewFetch(view, &rec);
9082 ok(!r, "got %u\n", r);
9083 check_record(rec, 2, "1", "2");
9084 MsiCloseHandle(rec);
9085
9086 r = MsiViewFetch(view, &rec);
9087 ok(!r, "got %u\n", r);
9088 check_record(rec, 2, "3", "3");
9089 MsiCloseHandle(rec);
9090
9091 r = MsiViewFetch(view, &rec);
9092 ok(r == ERROR_NO_MORE_ITEMS, "got %u\n", r);
9094
9095 r = run_query(db, 0, "CREATE TABLE `U` (`A` SHORT, `B` SHORT, `C` SHORT, `D` SHORT PRIMARY KEY `A`, `B`)");
9096 ok(!r, "got %u\n", r);
9097
9098 r = MsiDatabaseOpenViewA(db, "SELECT * FROM `U`", &view);
9099 ok(!r, "got %u\n", r);
9100 r = MsiViewExecute(view, 0);
9101 ok(!r, "got %u\n", r);
9102
9103 rec = MsiCreateRecord(4);
9104 MsiRecordSetInteger(rec, 1, 1);
9105 MsiRecordSetInteger(rec, 2, 2);
9106 MsiRecordSetInteger(rec, 3, 3);
9107 MsiRecordSetInteger(rec, 4, 4);
9109 ok(!r, "got %u\n", r);
9110
9111 MsiRecordSetInteger(rec, 2, 4);
9113 ok(!r, "got %u\n", r);
9114
9115 MsiCloseHandle(rec);
9117
9118 r = MsiDatabaseOpenViewA(db, "SELECT * FROM `U`", &view);
9119 ok(!r, "got %u\n", r);
9120 r = MsiViewExecute(view, 0);
9121 ok(!r, "got %u\n", r);
9122
9123 r = MsiViewFetch(view, &rec);
9124 ok(!r, "got %u\n", r);
9125 check_record(rec, 4, "1", "2", "3", "4");
9126 MsiCloseHandle(rec);
9127
9128 r = MsiViewFetch(view, &rec);
9129 ok(!r, "got %u\n", r);
9130 check_record(rec, 4, "1", "4", "3", "4");
9131 MsiCloseHandle(rec);
9132
9133 r = MsiViewFetch(view, &rec);
9134 ok(r == ERROR_NO_MORE_ITEMS, "got %u\n", r);
9136
9137 r = MsiDatabaseOpenViewA(db, "SELECT `A`,`C` FROM `U`", &view);
9138 ok(!r, "got %u\n", r);
9139 r = MsiViewExecute(view, 0);
9140 ok(!r, "got %u\n", r);
9141
9142 rec = MsiCreateRecord(2);
9143 MsiRecordSetInteger(rec, 1, 1);
9144 MsiRecordSetInteger(rec, 2, 2);
9146 ok(!r, "got %u\n", r);
9147
9149 ok(r == ERROR_FUNCTION_FAILED, "got %u\n", r);
9150
9151 MsiCloseHandle(rec);
9153
9154 r = MsiDatabaseOpenViewA(db, "SELECT * FROM `U` ORDER BY `B`", &view);
9155 ok(!r, "got %u\n", r);
9156 r = MsiViewExecute(view, 0);
9157 ok(!r, "got %u\n", r);
9158
9159 r = MsiViewFetch(view, &rec);
9160 ok(!r, "got %u\n", r);
9161 check_record(rec, 4, "1", "", "2", "");
9162 MsiCloseHandle(rec);
9163
9164 r = MsiViewFetch(view, &rec);
9165 ok(!r, "got %u\n", r);
9166 check_record(rec, 4, "1", "2", "3", "4");
9167 MsiCloseHandle(rec);
9168
9169 r = MsiViewFetch(view, &rec);
9170 ok(!r, "got %u\n", r);
9171 check_record(rec, 4, "1", "4", "3", "4");
9172 MsiCloseHandle(rec);
9173
9174 r = MsiViewFetch(view, &rec);
9175 ok(r == ERROR_NO_MORE_ITEMS, "got %u\n", r);
9177
9178 MsiCloseHandle(db);
9180}
9181
9182static void test_view_get_error(void)
9183{
9184 MSIHANDLE view, rec, db = create_db();
9186 char buffer[5];
9187 DWORD sz;
9188 UINT r;
9189
9190 r = run_query(db, 0, "CREATE TABLE `T` (`A` SHORT, `B` SHORT NOT NULL PRIMARY KEY `A`)");
9191 ok(!r, "got %u\n", r);
9192 r = run_query(db, 0, "INSERT INTO `T` (`A`, `B`) VALUES (1, 2)");
9193 r = run_query(db, 0, "CREATE TABLE `_Validation` ("
9194 "`Table` CHAR(32) NOT NULL, `Column` CHAR(32) NOT NULL, "
9195 "`Nullable` CHAR(4) NOT NULL, `MinValue` INT, `MaxValue` INT, "
9196 "`KeyTable` CHAR(255), `KeyColumn` SHORT, `Category` CHAR(32), "
9197 "`Set` CHAR(255), `Description` CHAR(255) PRIMARY KEY `Table`, `Column`)");
9198 ok(!r, "got %u\n", r);
9199 r = run_query(db, 0, "INSERT INTO `_Validation` (`Table`, `Column`, `Nullable`) VALUES ('T', 'A', 'N')");
9200 ok(!r, "got %u\n", r);
9201 r = run_query(db, 0, "INSERT INTO `_Validation` (`Table`, `Column`, `Nullable`) VALUES ('T', 'B', 'N')");
9202 ok(!r, "got %u\n", r);
9203
9204 r = MsiDatabaseOpenViewA(db, "SELECT * FROM `T`", &view);
9205 ok(!r, "got %u\n", r);
9206
9207 r = MsiViewExecute(view, 0);
9208 ok(!r, "got %u\n", r);
9209
9210 sz = 0;
9211 err = MsiViewGetErrorA(0, NULL, &sz);
9212 ok(err == MSIDBERROR_INVALIDARG, "got %d\n", err);
9213 ok(sz == 0, "got size %lu\n", sz);
9214
9216 ok(err == MSIDBERROR_INVALIDARG, "got %d\n", err);
9217
9218 sz = 0;
9219 err = MsiViewGetErrorA(view, NULL, &sz);
9220 ok(err == MSIDBERROR_NOERROR, "got %d\n", err);
9221 ok(sz == 0, "got size %lu\n", sz);
9222
9223 sz = 0;
9224 strcpy(buffer, "x");
9226 ok(err == MSIDBERROR_MOREDATA, "got %d\n", err);
9227 ok(!strcmp(buffer, "x"), "got \"%s\"\n", buffer);
9228 ok(sz == 0, "got size %lu\n", sz);
9229
9230 sz = 1;
9231 strcpy(buffer, "x");
9233 ok(err == MSIDBERROR_NOERROR, "got %d\n", err);
9234 ok(!buffer[0], "got \"%s\"\n", buffer);
9235 ok(sz == 0, "got size %lu\n", sz);
9236
9237 rec = MsiCreateRecord(2);
9238 MsiRecordSetInteger(rec, 1, 1);
9239 MsiRecordSetInteger(rec, 2, 2);
9241 ok(r == ERROR_INVALID_DATA, "got %u\n", r);
9242
9243 sz = 2;
9244 strcpy(buffer, "x");
9246 ok(err == MSIDBERROR_DUPLICATEKEY, "got %d\n", err);
9247 ok(!strcmp(buffer, "A"), "got \"%s\"\n", buffer);
9248 ok(sz == 1, "got size %lu\n", sz);
9249
9250 sz = 2;
9251 strcpy(buffer, "x");
9253 todo_wine ok(err == MSIDBERROR_NOERROR, "got %d\n", err);
9254 todo_wine ok(!buffer[0], "got \"%s\"\n", buffer);
9255 todo_wine ok(sz == 0, "got size %lu\n", sz);
9256
9258 ok(r == ERROR_INVALID_DATA, "got %u\n", r);
9259
9260 sz = 1;
9261 strcpy(buffer, "x");
9263 ok(err == MSIDBERROR_MOREDATA, "got %d\n", err);
9264 ok(!buffer[0], "got \"%s\"\n", buffer);
9265 ok(sz == 1, "got size %lu\n", sz);
9266
9267 sz = 1;
9268 strcpy(buffer, "x");
9270 todo_wine ok(err == MSIDBERROR_NOERROR, "got %d\n", err);
9271 ok(!buffer[0], "got \"%s\"\n", buffer);
9272 todo_wine ok(sz == 0, "got size %lu\n", sz);
9273
9275 ok(r == ERROR_INVALID_DATA, "got %u\n", r);
9276
9277 sz = 0;
9278 strcpy(buffer, "x");
9280 ok(err == MSIDBERROR_MOREDATA, "got %d\n", err);
9281 ok(!strcmp(buffer, "x"), "got \"%s\"\n", buffer);
9282 ok(sz == 1, "got size %lu\n", sz);
9283
9284 sz = 0;
9285 strcpy(buffer, "x");
9287 ok(err == MSIDBERROR_MOREDATA, "got %d\n", err);
9288 ok(!strcmp(buffer, "x"), "got \"%s\"\n", buffer);
9289 todo_wine ok(sz == 0, "got size %lu\n", sz);
9290
9291 MsiCloseHandle(rec);
9293 MsiCloseHandle(db);
9295}
9296
9298{
9299 MSIHANDLE db = 0, view = 0, rec = 0;
9300 UINT r, i, idset, tries;
9301 const char *query;
9302
9304
9305 /* just MsiOpenDatabase should not create a file */
9307 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
9308
9309 query = "CREATE TABLE `phone` ( "
9310 "`id` INT, `name` CHAR(32), `number` CHAR(32) "
9311 "PRIMARY KEY `id`)";
9312 r = run_query( db, 0, query );
9313 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
9314
9315 query = "INSERT INTO `phone` ( `id`, `name`, `number` )"
9316 "VALUES('1', 'Alan', '5030581')";
9317 r = run_query( db, 0, query );
9318 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
9319
9320 query = "INSERT INTO `phone` ( `id`, `name`, `number` )"
9321 "VALUES('2', 'Barry', '928440')";
9322 r = run_query( db, 0, query );
9323 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
9324
9325 query = "INSERT INTO `phone` ( `id`, `name`, `number` )"
9326 "VALUES('3', 'Cindy', '2937550')";
9327 r = run_query( db, 0, query );
9328 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
9329
9330 query = "SELECT * FROM `phone`";
9331 r = MsiDatabaseOpenViewA( db, query, &view );
9332 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
9333
9334 r = MsiViewExecute( view, 0 );
9335 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
9336
9337 for (tries = 0; tries < 3; tries++)
9338 {
9339 winetest_push_context( "Wraparound attempt #%d", tries );
9340 idset = 0;
9341
9342 for (i = 0; i < 3; i++)
9343 {
9344 winetest_push_context( "Record #%d", i );
9345
9346 r = MsiViewFetch( view, &rec );
9347 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
9348 if (r != ERROR_SUCCESS)
9349 {
9351 break;
9352 }
9353
9354 r = MsiRecordGetInteger(rec, 1);
9355 ok(r >= 1 && r <= 3, "Expected 1 <= id <= 3, got %d\n", r);
9356 if (r < sizeof(idset) * 8)
9357 {
9358 ok(!(idset & (1 << r)), "Duplicate id %d\n", r);
9359 idset |= 1 << r;
9360 }
9361
9362 MsiCloseHandle(rec);
9363
9365 }
9366
9367 r = MsiViewFetch(view, &rec);
9368 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9369
9371 }
9372
9375 MsiCloseHandle(db);
9377}
9378
9380{
9391 test_binary();
9393 test_where();
9396 test_markers();
9399 test_join();
9401 test_alter();
9402 test_integers();
9403 test_update();
9413 test_order();
9416 test_quotes();
9418 test_noquotes();
9425 test_dbmerge();
9439}
#define expect(EXPECTED, GOT)
Definition: SystemMenu.c:483
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
char * strchr(const char *String, int ch)
Definition: utclib.c:501
char * va_list
Definition: acmsvcex.h:78
#define va_end(ap)
Definition: acmsvcex.h:90
#define va_start(ap, A)
Definition: acmsvcex.h:91
#define va_arg(ap, T)
Definition: acmsvcex.h:89
#define stat
Definition: acwin.h:99
#define read
Definition: acwin.h:96
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define START_TEST(x)
Definition: atltest.h:75
#define ok_(x1, x2)
Definition: atltest.h:61
static const WCHAR nameW[]
Definition: main.c:46
#define ARRAY_SIZE(A)
Definition: main.h:33
static void test_quotes(void)
Definition: db.c:6395
static CHAR CURR_DIR[MAX_PATH]
Definition: db.c:2181
static const CHAR bin_import_dat[]
Definition: db.c:2503
static void test_viewgetcolumninfo(void)
Definition: db.c:1284
static UINT package_from_db(MSIHANDLE hdb, MSIHANDLE *handle)
Definition: db.c:3066
static void test_deleterow(void)
Definition: db.c:6335
static UINT create_binary_table(MSIHANDLE hdb)
Definition: db.c:309
static void test_msiimport(void)
Definition: db.c:2368
const void * data
Definition: db.c:2942
static void test_integers(void)
Definition: db.c:4165
static const WCHAR msifile2W[]
Definition: db.c:37
static const char * join_res_first[][2]
Definition: db.c:3346
static void test_defaultdatabase(void)
Definition: db.c:5943
#define add_std_dlls_entry(hdb, values)
Definition: db.c:347
static const WCHAR msifileW[]
Definition: db.c:36
static void test_viewfetch_wraparound(void)
Definition: db.c:9297
static void test_update(void)
Definition: db.c:4274
static const CHAR endlines1[]
Definition: db.c:2194
static void test_getcolinfo(void)
Definition: db.c:1182
static const WCHAR name5[]
Definition: db.c:2881
static const WCHAR data7[]
Definition: db.c:2929
static const WCHAR name8[]
Definition: db.c:2884
static const CHAR endlines2[]
Definition: db.c:2200
static void test_collation(void)
Definition: db.c:4795
static void test_temporary_table(void)
Definition: db.c:3858
#define add_component_entry(hdb, values)
Definition: db.c:334
static const WCHAR data9[]
Definition: db.c:2936
static const char * msifile2
Definition: db.c:34
static void test_noquotes(void)
Definition: db.c:6656
static MSIHANDLE create_db(void)
Definition: db.c:1163
static UINT run_query(MSIHANDLE hdb, MSIHANDLE hrec, const char *query)
Definition: db.c:215
static const CHAR suminfo[]
Definition: db.c:2206
static void test_msiinsert(void)
Definition: db.c:353
static const char * join_res_fourth[][2]
Definition: db.c:3367
static const char * join_res_ninth[][6]
Definition: db.c:3404
static void test_handle_limit(void)
Definition: db.c:2744
static const char * join_res_eighth[][4]
Definition: db.c:3394
static const char * join_res_fifth[][2]
Definition: db.c:3372
static void test_viewmodify_delete_temporary(void)
Definition: db.c:6219
static void enum_stream_names(IStorage *stg)
Definition: db.c:5885
static UINT create_feature_components_table(MSIHANDLE hdb)
Definition: db.c:287
static void test_try_transform(void)
Definition: db.c:3088
static const WCHAR data14[]
Definition: db.c:5869
static const char data8[]
Definition: db.c:2933
static void test_where_viewmodify(void)
Definition: db.c:6983
static const WCHAR name4[]
Definition: db.c:2880
static void test_binary_import(void)
Definition: db.c:2508
static const char data4[]
Definition: db.c:2904
static void WINAPIV check_record_(int line, MSIHANDLE rec, UINT count,...)
Definition: db.c:39
static void test_msidatabase(void)
Definition: db.c:64
static const char * join_res_third[][2]
Definition: db.c:3361
static void test_viewmodify_update(void)
Definition: db.c:5020
static UINT try_query(MSIHANDLE hdb, LPCSTR szQuery)
Definition: db.c:628
static void test_suminfo_import(void)
Definition: db.c:2245
static void test_storages_table(void)
Definition: db.c:7115
static void test_primary_keys(void)
Definition: db.c:8782
static const struct @1674 table_transform_data[]
static void test_viewmodify_delete(void)
Definition: db.c:5781
static const WCHAR name3[]
Definition: db.c:2879
static UINT create_component_table(MSIHANDLE hdb)
Definition: db.c:247
static void test_markers(void)
Definition: db.c:2559
static void test_select_markers(void)
Definition: db.c:4933
static UINT get_columns_table_type(MSIHANDLE hdb, const char *table, UINT field)
Definition: db.c:1253
static void create_file_data(LPCSTR name, LPCSTR data, DWORD size)
Definition: db.c:1505
static const WCHAR name2[]
Definition: db.c:2878
static const WCHAR data2[]
Definition: db.c:2892
static void test_select_with_tablenames(void)
Definition: db.c:8087
static void test_binary(void)
Definition: db.c:1851
static void test_order(void)
Definition: db.c:5970
static const char * join_res_second[][2]
Definition: db.c:3355
static void test_special_tables(void)
Definition: db.c:4543
#define MY_NVIEWS
Definition: db.c:2743
static void test_viewmodify_insert(void)
Definition: db.c:9018
#define add_binary_entry(hdb, values)
Definition: db.c:350
static const WCHAR _StringPool[]
Definition: db.c:5867
static void test_viewmodify_assign(void)
Definition: db.c:5278
static void test_tables_order(void)
Definition: db.c:4581
static void generate_transform_manual(void)
Definition: db.c:2957
static void test_join(void)
Definition: db.c:3414
static const struct @1675 database_table_data[]
static MSIHANDLE get_column_info(MSIHANDLE hdb, const char *query, MSICOLINFO type)
Definition: db.c:1234
static const WCHAR name7[]
Definition: db.c:2883
static void test_createtable(void)
Definition: db.c:8482
static const WCHAR data3[]
Definition: db.c:2900
static const char * msifile
Definition: db.c:33
static void test_viewmodify_merge(void)
Definition: db.c:8821
static const UINT ordervals[6][3]
Definition: db.c:8161
static const WCHAR data11[]
Definition: db.c:5550
static UINT create_custom_action_table(MSIHANDLE hdb)
Definition: db.c:262
static const WCHAR data5[]
Definition: db.c:2906
static UINT do_query(MSIHANDLE hdb, const char *query, MSIHANDLE *phrec)
Definition: db.c:190
static UINT try_query_param(MSIHANDLE hdb, LPCSTR szQuery, MSIHANDLE hrec)
Definition: db.c:603
static void test_columnorder(void)
Definition: db.c:8307
static const WCHAR _StringData[]
Definition: db.c:5866
static void test_select_column_names(void)
Definition: db.c:8615
static UINT run_queryW(MSIHANDLE hdb, MSIHANDLE hrec, const WCHAR *query)
Definition: db.c:231
#define add_feature_components_entry(hdb, values)
Definition: db.c:343
static void generate_transform(void)
Definition: db.c:2783
static void test_forcecodepage(void)
Definition: db.c:6804
static void test_stringtable(void)
Definition: db.c:5576
static const WCHAR name6[]
Definition: db.c:2882
static void test_viewmodify_refresh(void)
Definition: db.c:6874
static const WCHAR name9[]
Definition: db.c:2885
static void test_droptable(void)
Definition: db.c:7360
static UINT add_table_to_db(MSIHANDLE hdb, LPCSTR table_data)
Definition: db.c:2234
static void test_streamtable(void)
Definition: db.c:1528
LPCWSTR name
Definition: db.c:2941
static void test_where(void)
Definition: db.c:2057
static UINT set_summary_info(MSIHANDLE hdb)
Definition: db.c:2998
static void test_rows_order(void)
Definition: db.c:4689
static UINT try_insert_query(MSIHANDLE hdb, LPCSTR szQuery)
Definition: db.c:633
#define create_file(name)
Definition: db.c:1526
static void test_msidecomposedesc(void)
Definition: db.c:511
static void test_carriagereturn(void)
Definition: db.c:6487
static const char * join_res_seventh[][2]
Definition: db.c:3387
static void test_msiexport(void)
Definition: db.c:1372
static void test_insertorder(void)
Definition: db.c:8171
static const WCHAR data13[]
Definition: db.c:5556
static void test_msibadqueries(void)
Definition: db.c:647
static const WCHAR name1[]
Definition: db.c:2877
static const WCHAR data10[]
Definition: db.c:5547
static void test_longstrings(void)
Definition: db.c:1447
static void test_where_not_in_selected(void)
Definition: db.c:1965
static UINT create_directory_table(MSIHANDLE hdb)
Definition: db.c:275
static void test_dbtopackage(void)
Definition: db.c:7234
DWORD size
Definition: db.c:2943
static const char * mstfile
Definition: db.c:35
static void test_viewmodify(void)
Definition: db.c:866
static const CHAR two_primary[]
Definition: db.c:2188
static void test_view_get_error(void)
Definition: db.c:9182
static UINT create_std_dlls_table(MSIHANDLE hdb)
Definition: db.c:298
static void read_file_data(LPCSTR filename, LPSTR buffer)
Definition: db.c:6793
static const WCHAR data1[]
Definition: db.c:2888
static void write_file(const CHAR *filename, const char *data, int data_size)
Definition: db.c:2224
static void test_embedded_nulls(void)
Definition: db.c:8580
static const CHAR import_dat[]
Definition: db.c:6390
#define check_record(rec,...)
Definition: db.c:62
static const WCHAR data6[]
Definition: db.c:2924
static UINT add_entry(const char *file, int line, const char *type, MSIHANDLE hdb, const char *values, const char *insert)
Definition: db.c:320
static const char * join_res_sixth[][2]
Definition: db.c:3377
#define add_custom_action_entry(hdb, values)
Definition: db.c:339
static void test_dbmerge(void)
Definition: db.c:7530
static const WCHAR _Tables[]
Definition: db.c:5865
static void test_alter(void)
Definition: db.c:3968
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static void transform_view(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
Definition: state.c:3964
#define CloseHandle
Definition: compat.h:739
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define FILE_BEGIN
Definition: compat.h:761
#define GetCurrentDirectoryW(x, y)
Definition: compat.h:756
#define CP_ACP
Definition: compat.h:109
#define OPEN_EXISTING
Definition: compat.h:775
#define ReadFile(a, b, c, d, e)
Definition: compat.h:742
#define SetFilePointer
Definition: compat.h:743
#define GetProcAddress(x, y)
Definition: compat.h:753
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define CreateFileA(a, b, c, d, e, f, g)
Definition: compat.h:740
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:105
#define GENERIC_READ
Definition: compat.h:135
#define MAX_PATH
Definition: compat.h:34
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define lstrcpyW
Definition: compat.h:749
#define MultiByteToWideChar
Definition: compat.h:110
#define FILE_SHARE_READ
Definition: compat.h:136
@ VT_LPSTR
Definition: compat.h:2324
@ VT_I4
Definition: compat.h:2298
@ VT_FILETIME
Definition: compat.h:2329
@ VT_I2
Definition: compat.h:2297
#define lstrlenW
Definition: compat.h:750
BOOL WINAPI CopyFileA(IN LPCSTR lpExistingFileName, IN LPCSTR lpNewFileName, IN BOOL bFailIfExists)
Definition: copy.c:404
BOOL WINAPI DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
BOOL WINAPI DeleteFileW(IN LPCWSTR lpFileName)
Definition: delete.c:39
BOOL WINAPI RemoveDirectoryA(IN LPCSTR lpPathName)
Definition: dir.c:714
BOOL WINAPI CreateDirectoryA(IN LPCSTR lpPathName, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: dir.c:37
BOOL WINAPI SetEndOfFile(HANDLE hFile)
Definition: fileinfo.c:1004
DWORD WINAPI GetFileAttributesA(LPCSTR lpFileName)
Definition: fileinfo.c:636
#define STRING_LENGTH
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
DWORD WINAPI GetCurrentDirectoryA(IN DWORD nBufferLength, OUT LPSTR lpBuffer)
Definition: path.c:2146
UINT WINAPI MsiDatabaseImportA(MSIHANDLE handle, const char *szFolder, const char *szFilename)
Definition: database.c:853
UINT WINAPI MsiOpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIHANDLE *phDB)
Definition: database.c:298
UINT WINAPI MsiDatabaseMergeA(MSIHANDLE hDatabase, MSIHANDLE hDatabaseMerge, const char *szTableName)
Definition: database.c:1196
UINT WINAPI MsiDatabaseExportA(MSIHANDLE handle, const char *szTable, const char *szFolder, const char *szFilename)
Definition: database.c:1158
UINT WINAPI MsiCloseHandle(MSIHANDLE handle)
Definition: handle.c:269
UINT WINAPI MsiDoActionA(MSIHANDLE hInstall, LPCSTR szAction)
Definition: install.c:45
UINT WINAPI MsiOpenPackageA(LPCSTR szPackage, MSIHANDLE *phPackage)
Definition: package.c:1669
UINT WINAPI MsiGetPropertyA(MSIHANDLE hinst, const char *name, char *buf, DWORD *sz)
Definition: package.c:2313
int WINAPI MsiRecordGetInteger(MSIHANDLE handle, UINT iField)
Definition: record.c:237
UINT WINAPI MsiRecordGetStringA(MSIHANDLE handle, UINT iField, char *szValue, DWORD *pcchValue)
Definition: record.c:403
MSIHANDLE WINAPI MsiCreateRecord(UINT cParams)
Definition: record.c:92
UINT WINAPI MsiRecordGetStringW(MSIHANDLE handle, UINT iField, WCHAR *szValue, DWORD *pcchValue)
Definition: record.c:482
BOOL WINAPI MsiRecordIsNull(MSIHANDLE handle, UINT iField)
Definition: record.c:333
UINT WINAPI MsiRecordSetInteger(MSIHANDLE handle, UINT iField, int iVal)
Definition: record.c:303
UINT WINAPI MsiRecordSetStreamA(MSIHANDLE hRecord, UINT iField, const char *szFilename)
Definition: record.c:724
UINT WINAPI MsiRecordSetStringA(MSIHANDLE handle, UINT iField, const char *szValue)
Definition: record.c:549
UINT WINAPI MsiRecordReadStream(MSIHANDLE handle, UINT iField, char *buf, DWORD *sz)
Definition: record.c:819
UINT WINAPI MsiRecordGetFieldCount(MSIHANDLE handle)
Definition: record.c:113
UINT WINAPI MsiSummaryInfoSetPropertyA(MSIHANDLE handle, UINT uiProperty, UINT uiDataType, INT iValue, FILETIME *pftValue, const char *szValue)
Definition: suminfo.c:937
UINT WINAPI MsiSummaryInfoGetPropertyA(MSIHANDLE handle, UINT uiProperty, UINT *puiDataType, INT *piValue, FILETIME *pftValue, char *szValueBuf, DWORD *pcchValueBuf)
Definition: suminfo.c:737
UINT WINAPI MsiGetSummaryInformationA(MSIHANDLE hDatabase, const char *szDatabase, UINT uiUpdateCount, MSIHANDLE *pHandle)
Definition: suminfo.c:584
UINT WINAPI MsiSummaryInfoGetPropertyCount(MSIHANDLE hSummaryInfo, UINT *pCount)
Definition: suminfo.c:606
UINT WINAPI MsiSummaryInfoPersist(MSIHANDLE handle)
Definition: suminfo.c:1222
HRESULT WINAPI StgOpenStorage(const OLECHAR *pwcsName, IStorage *pstgPriority, DWORD grfMode, SNB snbExclude, DWORD reserved, IStorage **ppstgOpen)
Definition: storage32.c:8755
HRESULT WINAPI StgCreateDocfile(LPCOLESTR pwcsName, DWORD grfMode, DWORD reserved, IStorage **ppstgOpen)
Definition: storage32.c:8636
struct png_info_def *typedef unsigned char **typedef struct png_info_def *typedef struct png_info_def *typedef struct png_info_def *typedef unsigned char ** row
Definition: typeof.h:78
#define check(expected, result)
Definition: dplayx.c:32
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLsizeiptr size
Definition: glext.h:5919
GLdouble n
Definition: glext.h:7729
GLuint res
Definition: glext.h:9613
GLuint buffer
Definition: glext.h:5915
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLenum mode
Definition: glext.h:6217
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLboolean GLenum GLenum GLvoid * values
Definition: glext.h:5666
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLuint GLfloat * val
Definition: glext.h:7180
GLenum GLsizei len
Definition: glext.h:6722
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
GLintptr offset
Definition: glext.h:5920
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:442
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
const char * filename
Definition: ioapi.h:137
#define wine_dbgstr_w
Definition: kernel32.h:34
LPSTR WINAPI lstrcpyA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:100
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:170
int WINAPI lstrcmpA(LPCSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:18
LPSTR WINAPI lstrcatA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:123
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
#define error(str)
Definition: mkdosfs.c:1605
struct task_struct * current
Definition: linux.c:32
#define CREATE_ALWAYS
Definition: disk.h:72
#define sprintf(buf, format,...)
Definition: sprintf.c:55
static PEXPLICIT_ACCESSW *static HMODULE hmod
Definition: security.c:143
static const WCHAR desc[]
Definition: protectdata.c:36
BOOL expected
Definition: store.c:2063
#define todo_wine
Definition: custom.c:79
static MSIHANDLE create_package_db(void)
Definition: package.c:921
#define PID_TEMPLATE
Definition: suminfo.c:49
#define PID_KEYWORDS
Definition: suminfo.c:47
#define PID_PAGECOUNT
Definition: suminfo.c:56
#define PID_WORDCOUNT
Definition: suminfo.c:57
#define PID_SECURITY
Definition: suminfo.c:61
#define PID_COMMENTS
Definition: suminfo.c:48
#define PID_TITLE
Definition: suminfo.c:44
#define PID_AUTHOR
Definition: suminfo.c:46
#define PID_REVNUMBER
Definition: suminfo.c:51
#define PID_CREATE_DTM
Definition: suminfo.c:54
#define PID_APPNAME
Definition: suminfo.c:60
#define PID_SUBJECT
Definition: suminfo.c:45
#define PID_CODEPAGE
Definition: suminfo.c:43
#define PID_LASTSAVE_DTM
Definition: suminfo.c:55
static HGLOBAL create_storage(void)
Definition: clipboard.c:1289
INTERNETFEATURELIST feature
Definition: misc.c:1719
#define MAX_FEATURE_CHARS
Definition: msi.h:257
UINT WINAPI MsiViewModify(MSIHANDLE hView, MSIMODIFY eModifyMode, MSIHANDLE hRecord)
Definition: msiquery.c:720
UINT WINAPI MsiViewClose(MSIHANDLE hView)
Definition: msiquery.c:469
UINT WINAPI MsiDatabaseApplyTransformA(MSIHANDLE hdb, const char *transform, int error_cond)
Definition: msiquery.c:933
UINT WINAPI MsiViewExecute(MSIHANDLE hView, MSIHANDLE hRec)
Definition: msiquery.c:518
UINT WINAPI MsiDatabaseGenerateTransformA(MSIHANDLE hdb, MSIHANDLE hdbref, const char *szTransformFile, int iReserved1, int iReserved2)
Definition: msiquery.c:949
UINT WINAPI MsiDatabaseGetPrimaryKeysA(MSIHANDLE hdb, const char *table, MSIHANDLE *phRec)
Definition: msiquery.c:1129
UINT WINAPI MsiDatabaseOpenViewW(MSIHANDLE hdb, LPCWSTR szQuery, MSIHANDLE *phView)
Definition: msiquery.c:236
UINT WINAPI MsiDatabaseCommit(MSIHANDLE hdb)
Definition: msiquery.c:963
MSIDBERROR WINAPI MsiViewGetErrorA(MSIHANDLE handle, char *buffer, DWORD *buflen)
Definition: msiquery.c:821
UINT WINAPI MsiViewGetColumnInfo(MSIHANDLE hView, MSICOLINFO info, MSIHANDLE *hRec)
Definition: msiquery.c:642
UINT WINAPI MsiDatabaseOpenViewA(MSIHANDLE hdb, const char *szQuery, MSIHANDLE *phView)
Definition: msiquery.c:88
UINT WINAPI MsiViewFetch(MSIHANDLE hView, MSIHANDLE *record)
Definition: msiquery.c:404
MSICONDITION WINAPI MsiDatabaseIsTablePersistentA(MSIHANDLE hDatabase, const char *szTableName)
Definition: msiquery.c:1148
@ MSIMODIFY_DELETE
Definition: msiquery.h:57
@ MSIMODIFY_REPLACE
Definition: msiquery.h:55
@ MSIMODIFY_MERGE
Definition: msiquery.h:56
@ MSIMODIFY_INSERT_TEMPORARY
Definition: msiquery.h:58
@ MSIMODIFY_UPDATE
Definition: msiquery.h:53
@ MSIMODIFY_VALIDATE_DELETE
Definition: msiquery.h:62
@ MSIMODIFY_SEEK
Definition: msiquery.h:50
@ MSIMODIFY_ASSIGN
Definition: msiquery.h:54
@ MSIMODIFY_VALIDATE_NEW
Definition: msiquery.h:60
@ MSIMODIFY_INSERT
Definition: msiquery.h:52
@ MSIMODIFY_REFRESH
Definition: msiquery.h:51
@ MSIMODIFY_VALIDATE_FIELD
Definition: msiquery.h:61
@ MSIMODIFY_VALIDATE
Definition: msiquery.h:59
@ MSITRANSFORM_ERROR_VIEWTRANSFORM
Definition: msiquery.h:156
@ MSIDBERROR_NOERROR
Definition: msiquery.h:109
@ MSIDBERROR_DUPLICATEKEY
Definition: msiquery.h:110
@ MSIDBERROR_INVALIDARG
Definition: msiquery.h:106
@ MSIDBERROR_MOREDATA
Definition: msiquery.h:107
#define MSIDBOPEN_CREATEDIRECT
Definition: msiquery.h:70
#define MSIDBOPEN_DIRECT
Definition: msiquery.h:68
#define MSIDBOPEN_CREATE
Definition: msiquery.h:69
@ MSICONDITION_FALSE
Definition: msiquery.h:26
@ MSICONDITION_ERROR
Definition: msiquery.h:29
@ MSICONDITION_NONE
Definition: msiquery.h:28
@ MSICONDITION_TRUE
Definition: msiquery.h:27
#define MSIDBOPEN_TRANSACT
Definition: msiquery.h:67
#define MSI_NULL_INTEGER
Definition: msiquery.h:32
#define MSIDBOPEN_READONLY
Definition: msiquery.h:66
@ MSICOLINFO_NAMES
Definition: msiquery.h:36
@ MSICOLINFO_TYPES
Definition: msiquery.h:37
unsigned int UINT
Definition: ndis.h:50
#define GENERIC_WRITE
Definition: nt_native.h:90
#define L(x)
Definition: ntvdm.h:50
#define STGM_CREATE
Definition: objbase.h:926
#define STGM_DIRECT
Definition: objbase.h:914
#define STGM_READWRITE
Definition: objbase.h:919
#define STGM_SHARE_EXCLUSIVE
Definition: objbase.h:923
#define STGM_SHARE_DENY_WRITE
Definition: objbase.h:922
#define STGM_WRITE
Definition: objbase.h:918
#define STGM_READ
Definition: objbase.h:917
#define err(...)
const WCHAR * str
#define WINAPIV
Definition: sdbpapi.h:64
const char int int int static __inline const char * wine_dbgstr_a(const char *s)
Definition: debug.h:187
void __winetest_cdecl winetest_push_context(const char *fmt,...)
void winetest_pop_context(void)
#define memset(x, y, z)
Definition: compat.h:39
#define args
Definition: format.c:66
HRESULT hr
Definition: shlfolder.c:183
Definition: match.c:390
Definition: tftpd.h:80
Definition: tftpd.h:126
Definition: tftpd.h:138
Definition: parser.c:44
Definition: fci.c:127
Definition: parser.c:49
Definition: name.c:39
Definition: stat.h:55
int32_t INT
Definition: typedefs.h:58
uint32_t ULONG
Definition: typedefs.h:59
#define INVALID_FILE_ATTRIBUTES
Definition: vfdcmd.c:23
int ret
#define ZeroMemory
Definition: winbase.h:1712
#define WINAPI
Definition: msvc.h:6
int MSIDBERROR
Definition: winemsi.idl:35
int MSICONDITION
Definition: winemsi.idl:29
unsigned long MSIHANDLE
Definition: winemsi.idl:27
int MSICOLINFO
Definition: winemsi.idl:32
#define ERROR_NO_DATA
Definition: winerror.h:284
#define ERROR_OPEN_FAILED
Definition: winerror.h:184
#define ERROR_INSTALL_PACKAGE_REJECTED
Definition: winerror.h:983
#define ERROR_INVALID_TABLE
Definition: winerror.h:986
#define ERROR_BAD_QUERY_SYNTAX
Definition: winerror.h:973
#define ERROR_FUNCTION_FAILED
Definition: winerror.h:985
#define ERROR_DATATYPE_MISMATCH
Definition: winerror.h:987
#define ERROR_INVALID_DATA
Definition: winerror.h:116
static int insert
Definition: xmllint.c:138
const char * LPCSTR
Definition: xmlstorage.h:183
char * LPSTR
Definition: xmlstorage.h:182
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
char CHAR
Definition: xmlstorage.h:175
unsigned char BYTE
Definition: xxhash.c:193