2 * Copyright (C) 2005 Mike McCormack for CodeWeavers
4 * A test program for MSI database files.
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.
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.
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
32 #include "wine/test.h"
34 static const char *msifile = "winetest-db.msi";
35 static const char *msifile2 = "winetst2-db.msi";
36 static const char *mstfile = "winetst-db.mst";
37 static const WCHAR msifileW[] = {'w','i','n','e','t','e','s','t','-','d','b','.','m','s','i',0};
39 static void test_msidatabase(void)
41 MSIHANDLE hdb = 0, hdb2 = 0;
46 res = MsiOpenDatabase( msifile, msifile2, &hdb );
47 ok( res == ERROR_OPEN_FAILED, "expected failure\n");
49 res = MsiOpenDatabase( msifile, (LPSTR) 0xff, &hdb );
50 ok( res == ERROR_INVALID_PARAMETER, "expected failure\n");
52 res = MsiCloseHandle( hdb );
53 ok( res == ERROR_SUCCESS , "Failed to close database\n" );
55 /* create an empty database */
56 res = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb );
57 ok( res == ERROR_SUCCESS , "Failed to create database\n" );
59 res = MsiDatabaseCommit( hdb );
60 ok( res == ERROR_SUCCESS , "Failed to commit database\n" );
62 ok( INVALID_FILE_ATTRIBUTES != GetFileAttributes( msifile ), "database should exist\n");
64 res = MsiCloseHandle( hdb );
65 ok( res == ERROR_SUCCESS , "Failed to close database\n" );
66 res = MsiOpenDatabase( msifile, msifile2, &hdb2 );
67 ok( res == ERROR_SUCCESS , "Failed to open database\n" );
69 ok( INVALID_FILE_ATTRIBUTES != GetFileAttributes( msifile2 ), "database should exist\n");
71 res = MsiDatabaseCommit( hdb2 );
72 ok( res == ERROR_SUCCESS , "Failed to commit database\n" );
74 res = MsiCloseHandle( hdb2 );
75 ok( res == ERROR_SUCCESS , "Failed to close database\n" );
77 res = MsiOpenDatabase( msifile, msifile2, &hdb2 );
78 ok( res == ERROR_SUCCESS , "Failed to open database\n" );
80 res = MsiCloseHandle( hdb2 );
81 ok( res == ERROR_SUCCESS , "Failed to close database\n" );
83 ok( INVALID_FILE_ATTRIBUTES == GetFileAttributes( msifile2 ), "uncommitted database should not exist\n");
85 res = MsiOpenDatabase( msifile, msifile2, &hdb2 );
86 ok( res == ERROR_SUCCESS , "Failed to close database\n" );
88 res = MsiDatabaseCommit( hdb2 );
89 ok( res == ERROR_SUCCESS , "Failed to commit database\n" );
91 res = MsiCloseHandle( hdb2 );
92 ok( res == ERROR_SUCCESS , "Failed to close database\n" );
94 ok( INVALID_FILE_ATTRIBUTES != GetFileAttributes( msifile2 ), "committed database should exist\n");
96 res = MsiOpenDatabase( msifile, MSIDBOPEN_READONLY, &hdb );
97 ok( res == ERROR_SUCCESS , "Failed to open database\n" );
99 res = MsiCloseHandle( hdb );
100 ok( res == ERROR_SUCCESS , "Failed to close database\n" );
102 res = MsiOpenDatabase( msifile, MSIDBOPEN_DIRECT, &hdb );
103 ok( res == ERROR_SUCCESS , "Failed to open database\n" );
105 res = MsiCloseHandle( hdb );
106 ok( res == ERROR_SUCCESS , "Failed to close database\n" );
108 res = MsiOpenDatabase( msifile, MSIDBOPEN_TRANSACT, &hdb );
109 ok( res == ERROR_SUCCESS , "Failed to open database\n" );
111 res = MsiCloseHandle( hdb );
112 ok( res == ERROR_SUCCESS , "Failed to close database\n" );
113 ok( INVALID_FILE_ATTRIBUTES != GetFileAttributes( msifile ), "database should exist\n");
115 /* MSIDBOPEN_CREATE deletes the database if MsiCommitDatabase isn't called */
116 res = MsiOpenDatabase( msifile, MSIDBOPEN_CREATE, &hdb );
117 ok( res == ERROR_SUCCESS , "Failed to open database\n" );
119 ok( INVALID_FILE_ATTRIBUTES != GetFileAttributes( msifile ), "database should exist\n");
121 res = MsiCloseHandle( hdb );
122 ok( res == ERROR_SUCCESS , "Failed to close database\n" );
124 ok( INVALID_FILE_ATTRIBUTES == GetFileAttributes( msifile ), "database should exist\n");
126 res = MsiOpenDatabase( msifile, MSIDBOPEN_CREATE, &hdb );
127 ok( res == ERROR_SUCCESS , "Failed to open database\n" );
129 res = MsiDatabaseCommit( hdb );
130 ok( res == ERROR_SUCCESS , "Failed to commit database\n" );
132 ok( INVALID_FILE_ATTRIBUTES != GetFileAttributes( msifile ), "database should exist\n");
134 res = MsiCloseHandle( hdb );
135 ok( res == ERROR_SUCCESS , "Failed to close database\n" );
137 res = DeleteFile( msifile2 );
138 ok( res == TRUE, "Failed to delete database\n" );
140 res = DeleteFile( msifile );
141 ok( res == TRUE, "Failed to delete database\n" );
144 static UINT do_query(MSIHANDLE hdb, const char *query, MSIHANDLE *phrec)
152 /* open a select query */
153 r = MsiDatabaseOpenView(hdb, query, &hview);
154 if (r != ERROR_SUCCESS)
156 r = MsiViewExecute(hview, 0);
157 if (r != ERROR_SUCCESS)
159 ret = MsiViewFetch(hview, phrec);
160 r = MsiViewClose(hview);
161 if (r != ERROR_SUCCESS)
163 r = MsiCloseHandle(hview);
164 if (r != ERROR_SUCCESS)
169 static UINT run_query( MSIHANDLE hdb, MSIHANDLE hrec, const char *query )
174 r = MsiDatabaseOpenView(hdb, query, &hview);
175 if( r != ERROR_SUCCESS )
178 r = MsiViewExecute(hview, hrec);
179 if( r == ERROR_SUCCESS )
180 r = MsiViewClose(hview);
181 MsiCloseHandle(hview);
185 static UINT run_queryW( MSIHANDLE hdb, MSIHANDLE hrec, const WCHAR *query )
190 r = MsiDatabaseOpenViewW(hdb, query, &hview);
191 if( r != ERROR_SUCCESS )
194 r = MsiViewExecute(hview, hrec);
195 if( r == ERROR_SUCCESS )
196 r = MsiViewClose(hview);
197 MsiCloseHandle(hview);
201 static UINT create_component_table( MSIHANDLE hdb )
203 return run_query( hdb, 0,
204 "CREATE TABLE `Component` ( "
205 "`Component` CHAR(72) NOT NULL, "
206 "`ComponentId` CHAR(38), "
207 "`Directory_` CHAR(72) NOT NULL, "
208 "`Attributes` SHORT NOT NULL, "
209 "`Condition` CHAR(255), "
210 "`KeyPath` CHAR(72) "
211 "PRIMARY KEY `Component`)" );
214 static UINT create_custom_action_table( MSIHANDLE hdb )
216 return run_query( hdb, 0,
217 "CREATE TABLE `CustomAction` ( "
218 "`Action` CHAR(72) NOT NULL, "
219 "`Type` SHORT NOT NULL, "
220 "`Source` CHAR(72), "
221 "`Target` CHAR(255) "
222 "PRIMARY KEY `Action`)" );
225 static UINT create_directory_table( MSIHANDLE hdb )
227 return run_query( hdb, 0,
228 "CREATE TABLE `Directory` ( "
229 "`Directory` CHAR(255) NOT NULL, "
230 "`Directory_Parent` CHAR(255), "
231 "`DefaultDir` CHAR(255) NOT NULL "
232 "PRIMARY KEY `Directory`)" );
235 static UINT create_feature_components_table( MSIHANDLE hdb )
237 return run_query( hdb, 0,
238 "CREATE TABLE `FeatureComponents` ( "
239 "`Feature_` CHAR(38) NOT NULL, "
240 "`Component_` CHAR(72) NOT NULL "
241 "PRIMARY KEY `Feature_`, `Component_` )" );
244 static UINT create_std_dlls_table( MSIHANDLE hdb )
246 return run_query( hdb, 0,
247 "CREATE TABLE `StdDlls` ( "
248 "`File` CHAR(255) NOT NULL, "
249 "`Binary_` CHAR(72) NOT NULL "
250 "PRIMARY KEY `File` )" );
253 static UINT create_binary_table( MSIHANDLE hdb )
255 return run_query( hdb, 0,
256 "CREATE TABLE `Binary` ( "
257 "`Name` CHAR(72) NOT NULL, "
258 "`Data` CHAR(72) NOT NULL "
259 "PRIMARY KEY `Name` )" );
262 #define make_add_entry(type, qtext) \
263 static UINT add##_##type##_##entry( MSIHANDLE hdb, const char *values ) \
265 char insert[] = qtext; \
268 sz = strlen(values) + sizeof insert; \
269 query = HeapAlloc(GetProcessHeap(),0,sz); \
270 sprintf(query,insert,values); \
271 r = run_query( hdb, 0, query ); \
272 HeapFree(GetProcessHeap(), 0, query); \
276 make_add_entry(component,
277 "INSERT INTO `Component` "
278 "(`Component`, `ComponentId`, `Directory_`, "
279 "`Attributes`, `Condition`, `KeyPath`) VALUES( %s )")
281 make_add_entry(custom_action,
282 "INSERT INTO `CustomAction` "
283 "(`Action`, `Type`, `Source`, `Target`) VALUES( %s )")
285 make_add_entry(feature_components,
286 "INSERT INTO `FeatureComponents` "
287 "(`Feature_`, `Component_`) VALUES( %s )")
289 make_add_entry(std_dlls,
290 "INSERT INTO `StdDlls` (`File`, `Binary_`) VALUES( %s )")
292 make_add_entry(binary,
293 "INSERT INTO `Binary` (`Name`, `Data`) VALUES( %s )")
295 static void test_msiinsert(void)
297 MSIHANDLE hdb = 0, hview = 0, hrec = 0;
305 /* just MsiOpenDatabase should not create a file */
306 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
307 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n");
310 query = "CREATE TABLE `phone` ( "
311 "`id` INT, `name` CHAR(32), `number` CHAR(32) "
313 r = MsiDatabaseOpenView(hdb, query, &hview);
314 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
315 r = MsiViewExecute(hview, 0);
316 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
317 r = MsiViewClose(hview);
318 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
319 r = MsiCloseHandle(hview);
320 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
322 /* insert a value into it */
323 query = "INSERT INTO `phone` ( `id`, `name`, `number` )"
324 "VALUES('1', 'Abe', '8675309')";
325 r = MsiDatabaseOpenView(hdb, query, &hview);
326 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
327 r = MsiViewExecute(hview, 0);
328 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
329 r = MsiViewClose(hview);
330 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
331 r = MsiCloseHandle(hview);
332 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
334 query = "SELECT * FROM `phone` WHERE `id` = 1";
335 r = do_query(hdb, query, &hrec);
336 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
338 /* check the record contains what we put in it */
339 r = MsiRecordGetFieldCount(hrec);
340 ok(r == 3, "record count wrong\n");
342 r = MsiRecordIsNull(hrec, 0);
343 ok(r == FALSE, "field 0 not null\n");
345 r = MsiRecordGetInteger(hrec, 1);
346 ok(r == 1, "field 1 contents wrong\n");
348 r = MsiRecordGetString(hrec, 2, buf, &sz);
349 ok(r == ERROR_SUCCESS, "field 2 content fetch failed\n");
350 ok(!strcmp(buf,"Abe"), "field 2 content incorrect\n");
352 r = MsiRecordGetString(hrec, 3, buf, &sz);
353 ok(r == ERROR_SUCCESS, "field 3 content fetch failed\n");
354 ok(!strcmp(buf,"8675309"), "field 3 content incorrect\n");
356 r = MsiCloseHandle(hrec);
357 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
359 /* open a select query */
361 query = "SELECT * FROM `phone` WHERE `id` >= 10";
362 r = do_query(hdb, query, &hrec);
363 ok(r == ERROR_NO_MORE_ITEMS, "MsiViewFetch failed\n");
364 ok(hrec == 0, "hrec should be null\n");
366 r = MsiCloseHandle(hrec);
367 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
369 query = "SELECT * FROM `phone` WHERE `id` < 0";
370 r = do_query(hdb, query, &hrec);
371 ok(r == ERROR_NO_MORE_ITEMS, "MsiViewFetch failed\n");
373 query = "SELECT * FROM `phone` WHERE `id` <= 0";
374 r = do_query(hdb, query, &hrec);
375 ok(r == ERROR_NO_MORE_ITEMS, "MsiViewFetch failed\n");
377 query = "SELECT * FROM `phone` WHERE `id` <> 1";
378 r = do_query(hdb, query, &hrec);
379 ok(r == ERROR_NO_MORE_ITEMS, "MsiViewFetch failed\n");
381 query = "SELECT * FROM `phone` WHERE `id` > 10";
382 r = do_query(hdb, query, &hrec);
383 ok(r == ERROR_NO_MORE_ITEMS, "MsiViewFetch failed\n");
385 /* now try a few bad INSERT xqueries */
386 query = "INSERT INTO `phone` ( `id`, `name`, `number` )"
388 r = MsiDatabaseOpenView(hdb, query, &hview);
389 ok(r == ERROR_BAD_QUERY_SYNTAX, "MsiDatabaseOpenView failed\n");
391 /* construct a record to insert */
392 hrec = MsiCreateRecord(4);
393 r = MsiRecordSetInteger(hrec, 1, 2);
394 ok(r == ERROR_SUCCESS, "MsiRecordSetInteger failed\n");
395 r = MsiRecordSetString(hrec, 2, "Adam");
396 ok(r == ERROR_SUCCESS, "MsiRecordSetString failed\n");
397 r = MsiRecordSetString(hrec, 3, "96905305");
398 ok(r == ERROR_SUCCESS, "MsiRecordSetString failed\n");
400 /* insert another value, using a record and wildcards */
401 query = "INSERT INTO `phone` ( `id`, `name`, `number` )"
403 r = MsiDatabaseOpenView(hdb, query, &hview);
404 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
406 if (r == ERROR_SUCCESS)
408 r = MsiViewExecute(hview, hrec);
409 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
410 r = MsiViewClose(hview);
411 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
412 r = MsiCloseHandle(hview);
413 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
415 r = MsiCloseHandle(hrec);
416 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
418 r = MsiViewFetch(0, NULL);
419 ok(r == ERROR_INVALID_PARAMETER, "MsiViewFetch failed\n");
421 r = MsiDatabaseCommit(hdb);
422 ok(r == ERROR_SUCCESS, "MsiDatabaseCommit failed\n");
424 r = MsiCloseHandle(hdb);
425 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
427 r = DeleteFile(msifile);
428 ok(r == TRUE, "file didn't exist after commit\n");
431 typedef UINT (WINAPI *fnMsiDecomposeDescriptorA)(LPCSTR, LPCSTR, LPSTR, LPSTR, DWORD *);
432 static fnMsiDecomposeDescriptorA pMsiDecomposeDescriptorA;
434 static void test_msidecomposedesc(void)
436 char prod[MAX_FEATURE_CHARS+1], comp[MAX_FEATURE_CHARS+1], feature[MAX_FEATURE_CHARS+1];
442 hmod = GetModuleHandle("msi.dll");
443 pMsiDecomposeDescriptorA = (fnMsiDecomposeDescriptorA)
444 GetProcAddress(hmod, "MsiDecomposeDescriptorA");
445 if (!pMsiDecomposeDescriptorA)
448 /* test a valid feature descriptor */
449 desc = "']gAVn-}f(ZXfeAR6.jiFollowTheWhiteRabbit>3w2x^IGfe?CxI5heAvk.";
451 r = pMsiDecomposeDescriptorA(desc, prod, feature, comp, &len);
452 ok(r == ERROR_SUCCESS, "returned an error\n");
453 ok(len == strlen(desc), "length was wrong\n");
454 ok(strcmp(prod,"{90110409-6000-11D3-8CFE-0150048383C9}")==0, "product wrong\n");
455 ok(strcmp(feature,"FollowTheWhiteRabbit")==0, "feature wrong\n");
456 ok(strcmp(comp,"{A7CD68DB-EF74-49C8-FBB2-A7C463B2AC24}")==0,"component wrong\n");
458 /* test an invalid feature descriptor with too many characters */
459 desc = "']gAVn-}f(ZXfeAR6.ji"
460 "ThisWillFailIfTheresMoreThanAGuidsChars>"
461 "3w2x^IGfe?CxI5heAvk.";
463 r = pMsiDecomposeDescriptorA(desc, prod, feature, comp, &len);
464 ok(r == ERROR_INVALID_PARAMETER, "returned wrong error\n");
467 * Test a valid feature descriptor with the
468 * maximum number of characters and some trailing characters.
470 desc = "']gAVn-}f(ZXfeAR6.ji"
471 "ThisWillWorkIfTheresLTEThanAGuidsChars>"
472 "3w2x^IGfe?CxI5heAvk."
475 r = pMsiDecomposeDescriptorA(desc, prod, feature, comp, &len);
476 ok(r == ERROR_SUCCESS, "returned wrong error\n");
477 ok(len == (strlen(desc) - strlen("extra")), "length wrong\n");
480 r = pMsiDecomposeDescriptorA(desc, prod, feature, NULL, &len);
481 ok(r == ERROR_SUCCESS, "returned wrong error\n");
482 ok(len == (strlen(desc) - strlen("extra")), "length wrong\n");
485 r = pMsiDecomposeDescriptorA(desc, prod, NULL, NULL, &len);
486 ok(r == ERROR_SUCCESS, "returned wrong error\n");
487 ok(len == (strlen(desc) - strlen("extra")), "length wrong\n");
490 r = pMsiDecomposeDescriptorA(desc, NULL, NULL, NULL, &len);
491 ok(r == ERROR_SUCCESS, "returned wrong error\n");
492 ok(len == (strlen(desc) - strlen("extra")), "length wrong\n");
495 r = pMsiDecomposeDescriptorA(NULL, NULL, NULL, NULL, &len);
496 ok(r == ERROR_INVALID_PARAMETER, "returned wrong error\n");
497 ok(len == 0, "length wrong\n");
499 r = pMsiDecomposeDescriptorA(desc, NULL, NULL, NULL, NULL);
500 ok(r == ERROR_SUCCESS, "returned wrong error\n");
503 static UINT try_query_param( MSIHANDLE hdb, LPCSTR szQuery, MSIHANDLE hrec )
508 res = MsiDatabaseOpenView( hdb, szQuery, &htab );
509 if(res == ERROR_SUCCESS )
513 r = MsiViewExecute( htab, hrec );
514 if(r != ERROR_SUCCESS )
517 r = MsiViewClose( htab );
518 if(r != ERROR_SUCCESS )
521 r = MsiCloseHandle( htab );
522 if(r != ERROR_SUCCESS )
528 static UINT try_query( MSIHANDLE hdb, LPCSTR szQuery )
530 return try_query_param( hdb, szQuery, 0 );
533 static UINT try_insert_query( MSIHANDLE hdb, LPCSTR szQuery )
538 hrec = MsiCreateRecord( 1 );
539 MsiRecordSetString( hrec, 1, "Hello");
541 r = try_query_param( hdb, szQuery, hrec );
543 MsiCloseHandle( hrec );
547 static void test_msibadqueries(void)
554 /* just MsiOpenDatabase should not create a file */
555 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
556 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n");
558 r = MsiDatabaseCommit( hdb );
559 ok(r == ERROR_SUCCESS , "Failed to commit database\n");
561 r = MsiCloseHandle( hdb );
562 ok(r == ERROR_SUCCESS , "Failed to close database\n");
564 /* open it readonly */
565 r = MsiOpenDatabase(msifile, MSIDBOPEN_READONLY, &hdb );
566 ok(r == ERROR_SUCCESS , "Failed to open database r/o\n");
568 /* add a table to it */
569 r = try_query( hdb, "select * from _Tables");
570 ok(r == ERROR_SUCCESS , "query 1 failed\n");
572 r = MsiCloseHandle( hdb );
573 ok(r == ERROR_SUCCESS , "Failed to close database r/o\n");
575 /* open it read/write */
576 r = MsiOpenDatabase(msifile, MSIDBOPEN_TRANSACT, &hdb );
577 ok(r == ERROR_SUCCESS , "Failed to open database r/w\n");
579 /* a bunch of test queries that fail with the native MSI */
581 r = try_query( hdb, "CREATE TABLE");
582 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2a return code\n");
584 r = try_query( hdb, "CREATE TABLE `a`");
585 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2b return code\n");
587 r = try_query( hdb, "CREATE TABLE `a` ()");
588 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2c return code\n");
590 r = try_query( hdb, "CREATE TABLE `a` (`b`)");
591 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2d return code\n");
593 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(72) )");
594 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2e return code\n");
596 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(72) NOT NULL)");
597 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2f return code\n");
599 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(72) NOT NULL PRIMARY)");
600 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2g return code\n");
602 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(72) NOT NULL PRIMARY KEY)");
603 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2h return code\n");
605 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(72) NOT NULL PRIMARY KEY)");
606 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2i return code\n");
608 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(72) NOT NULL PRIMARY KEY 'b')");
609 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2j return code\n");
611 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(72) NOT NULL PRIMARY KEY `b')");
612 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2k return code\n");
614 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(72) NOT NULL PRIMARY KEY `b')");
615 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2l return code\n");
617 r = try_query( hdb, "CREATE TABLE `a` (`b` CHA(72) NOT NULL PRIMARY KEY `b`)");
618 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2m return code\n");
620 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(-1) NOT NULL PRIMARY KEY `b`)");
621 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2n return code\n");
623 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(720) NOT NULL PRIMARY KEY `b`)");
624 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2o return code\n");
626 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(72) NOT NULL KEY `b`)");
627 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2p return code\n");
629 r = try_query( hdb, "CREATE TABLE `a` (`` CHAR(72) NOT NULL PRIMARY KEY `b`)");
630 ok(r == ERROR_BAD_QUERY_SYNTAX , "invalid query 2p return code\n");
632 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(72) NOT NULL PRIMARY KEY `b`)");
633 ok(r == ERROR_SUCCESS , "valid query 2z failed\n");
635 r = try_query( hdb, "CREATE TABLE `a` (`b` CHAR(72) NOT NULL PRIMARY KEY `b`)");
636 ok(r == ERROR_BAD_QUERY_SYNTAX , "created same table again\n");
638 r = try_query( hdb, "CREATE TABLE `aa` (`b` CHAR(72) NOT NULL, `c` "
639 "CHAR(72), `d` CHAR(255) NOT NULL LOCALIZABLE PRIMARY KEY `b`)");
640 ok(r == ERROR_SUCCESS , "query 4 failed\n");
642 r = MsiDatabaseCommit( hdb );
643 ok(r == ERROR_SUCCESS , "Failed to commit database after write\n");
645 r = try_query( hdb, "CREATE TABLE `blah` (`foo` CHAR(72) NOT NULL "
646 "PRIMARY KEY `foo`)");
647 ok(r == ERROR_SUCCESS , "query 4 failed\n");
649 r = try_insert_query( hdb, "insert into a ( `b` ) VALUES ( ? )");
650 ok(r == ERROR_SUCCESS , "failed to insert record in db\n");
652 r = MsiDatabaseCommit( hdb );
653 ok(r == ERROR_SUCCESS , "Failed to commit database after write\n");
655 r = try_query( hdb, "CREATE TABLE `boo` (`foo` CHAR(72) NOT NULL "
656 "PRIMARY KEY `ba`)");
657 ok(r != ERROR_SUCCESS , "query 5 succeeded\n");
659 r = try_query( hdb,"CREATE TABLE `bee` (`foo` CHAR(72) NOT NULL )");
660 ok(r != ERROR_SUCCESS , "query 6 succeeded\n");
662 r = try_query( hdb, "CREATE TABLE `temp` (`t` CHAR(72) NOT NULL "
664 ok(r == ERROR_SUCCESS , "query 7 failed\n");
666 r = try_query( hdb, "CREATE TABLE `c` (`b` CHAR NOT NULL PRIMARY KEY `b`)");
667 ok(r == ERROR_SUCCESS , "query 8 failed\n");
669 r = try_query( hdb, "select * from c");
670 ok(r == ERROR_SUCCESS , "query failed\n");
672 r = try_query( hdb, "select * from c where b = 'x");
673 ok(r == ERROR_BAD_QUERY_SYNTAX, "query failed\n");
675 r = try_query( hdb, "select * from c where b = 'x'");
676 ok(r == ERROR_SUCCESS, "query failed\n");
678 r = try_query( hdb, "select * from 'c'");
679 ok(r == ERROR_BAD_QUERY_SYNTAX, "query failed\n");
681 r = try_query( hdb, "select * from ''");
682 ok(r == ERROR_BAD_QUERY_SYNTAX, "query failed\n");
684 r = try_query( hdb, "select * from c where b = x");
685 ok(r == ERROR_BAD_QUERY_SYNTAX, "query failed\n");
687 r = try_query( hdb, "select * from c where b = \"x\"");
688 ok(r == ERROR_BAD_QUERY_SYNTAX, "query failed\n");
690 r = try_query( hdb, "select * from c where b = 'x'");
691 ok(r == ERROR_SUCCESS, "query failed\n");
693 r = try_query( hdb, "select * from c where b = '\"x'");
694 ok(r == ERROR_SUCCESS, "query failed\n");
696 if (0) /* FIXME: this query causes trouble with other tests */
698 r = try_query( hdb, "select * from c where b = '\\\'x'");
699 ok(r == ERROR_BAD_QUERY_SYNTAX, "query failed\n");
702 r = try_query( hdb, "select * from 'c'");
703 ok(r == ERROR_BAD_QUERY_SYNTAX, "query failed\n");
705 r = try_query( hdb, "CREATE TABLE `\5a` (`b` CHAR NOT NULL PRIMARY KEY `b`)" );
706 ok( r == ERROR_SUCCESS , "query failed: %u\n", r );
708 r = try_query( hdb, "SELECT * FROM \5a" );
709 ok( r == ERROR_SUCCESS , "query failed: %u\n", r );
711 r = try_query( hdb, "CREATE TABLE `a\5` (`b` CHAR NOT NULL PRIMARY KEY `b`)" );
712 ok( r == ERROR_SUCCESS , "query failed: %u\n", r );
714 r = try_query( hdb, "SELECT * FROM a\5" );
715 ok( r == ERROR_SUCCESS , "query failed: %u\n", r );
717 r = try_query( hdb, "CREATE TABLE `-a` (`b` CHAR NOT NULL PRIMARY KEY `b`)" );
718 ok( r == ERROR_SUCCESS , "query failed: %u\n", r );
720 r = try_query( hdb, "SELECT * FROM -a" );
721 todo_wine ok( r == ERROR_SUCCESS , "query failed: %u\n", r );
723 r = try_query( hdb, "CREATE TABLE `a-` (`b` CHAR NOT NULL PRIMARY KEY `b`)" );
724 ok( r == ERROR_SUCCESS , "query failed: %u\n", r );
726 r = try_query( hdb, "SELECT * FROM a-" );
727 ok( r == ERROR_SUCCESS , "query failed: %u\n", r );
729 r = MsiCloseHandle( hdb );
730 ok(r == ERROR_SUCCESS , "Failed to close database transact\n");
732 r = DeleteFile( msifile );
733 ok(r == TRUE, "file didn't exist after commit\n");
736 static void test_viewmodify(void)
738 MSIHANDLE hdb = 0, hview = 0, hrec = 0;
747 /* just MsiOpenDatabase should not create a file */
748 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
749 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n");
751 query = "CREATE TABLE `phone` ( "
752 "`id` INT, `name` CHAR(32), `number` CHAR(32) "
754 r = run_query( hdb, 0, query );
755 ok(r == ERROR_SUCCESS, "query failed\n");
757 query = "CREATE TABLE `_Validation` ( "
758 "`Table` CHAR(32) NOT NULL, `Column` CHAR(32) NOT NULL, "
759 "`Nullable` CHAR(4) NOT NULL, `MinValue` INT, `MaxValue` INT, "
760 "`KeyTable` CHAR(255), `KeyColumn` SHORT, `Category` CHAR(32), "
761 "`Set` CHAR(255), `Description` CHAR(255) PRIMARY KEY `Table`, `Column`)";
762 r = run_query( hdb, 0, query );
763 ok(r == ERROR_SUCCESS, "query failed\n");
765 query = "INSERT INTO `_Validation` ( `Table`, `Column`, `Nullable` ) "
766 "VALUES('phone', 'id', 'N')";
767 r = run_query( hdb, 0, query );
768 ok(r == ERROR_SUCCESS, "query failed\n");
770 /* check what the error function reports without doing anything */
772 /* passing NULL as the 3rd param make function to crash on older platforms */
773 err = MsiViewGetError( 0, NULL, &sz );
774 ok(err == MSIDBERROR_INVALIDARG, "MsiViewGetError return\n");
777 query = "SELECT * FROM `phone`";
778 r = MsiDatabaseOpenView(hdb, query, &hview);
779 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
781 /* see what happens with a good hview and bad args */
782 err = MsiViewGetError( hview, NULL, NULL );
783 ok(err == MSIDBERROR_INVALIDARG || err == MSIDBERROR_NOERROR,
784 "MsiViewGetError returns %u (expected -3)\n", err);
785 err = MsiViewGetError( hview, buffer, NULL );
786 ok(err == MSIDBERROR_INVALIDARG, "MsiViewGetError return\n");
788 /* see what happens with a zero length buffer */
791 err = MsiViewGetError( hview, buffer, &sz );
792 ok(err == MSIDBERROR_MOREDATA, "MsiViewGetError return\n");
793 ok(buffer[0] == 'x', "buffer cleared\n");
794 ok(sz == 0, "size not zero\n");
796 /* ok this one is strange */
798 err = MsiViewGetError( hview, NULL, &sz );
799 ok(err == MSIDBERROR_NOERROR, "MsiViewGetError return\n");
800 ok(sz == 0, "size not zero\n");
802 /* see if it really has an error */
805 err = MsiViewGetError( hview, buffer, &sz );
806 ok(err == MSIDBERROR_NOERROR, "MsiViewGetError return\n");
807 ok(buffer[0] == 0, "buffer not cleared\n");
808 ok(sz == 0, "size not zero\n");
810 r = MsiViewExecute(hview, 0);
811 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
813 /* try some invalid records */
814 r = MsiViewModify(hview, MSIMODIFY_INSERT, 0 );
815 ok(r == ERROR_INVALID_HANDLE, "MsiViewModify failed\n");
816 r = MsiViewModify(hview, -1, 0 );
817 ok(r == ERROR_INVALID_HANDLE, "MsiViewModify failed\n");
819 /* try an small record */
820 hrec = MsiCreateRecord(1);
821 r = MsiViewModify(hview, -1, hrec );
822 ok(r == ERROR_INVALID_DATA, "MsiViewModify failed\n");
826 err = MsiViewGetError( hview, buffer, &sz );
827 ok(err == MSIDBERROR_NOERROR, "MsiViewGetError return\n");
828 ok(buffer[0] == 0, "buffer not cleared\n");
829 ok(sz == 0, "size not zero\n");
831 r = MsiCloseHandle(hrec);
832 ok(r == ERROR_SUCCESS, "failed to close record\n");
834 /* insert a valid record */
835 hrec = MsiCreateRecord(3);
837 r = MsiRecordSetInteger(hrec, 1, 1);
838 ok(r == ERROR_SUCCESS, "failed to set integer\n");
839 r = MsiRecordSetString(hrec, 2, "bob");
840 ok(r == ERROR_SUCCESS, "failed to set string\n");
841 r = MsiRecordSetString(hrec, 3, "7654321");
842 ok(r == ERROR_SUCCESS, "failed to set string\n");
844 r = MsiViewExecute(hview, 0);
845 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
846 r = MsiViewModify(hview, MSIMODIFY_INSERT_TEMPORARY, hrec );
847 ok(r == ERROR_SUCCESS, "MsiViewModify failed\n");
850 r = MsiViewExecute(hview, 0);
851 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
853 r = MsiViewModify(hview, MSIMODIFY_VALIDATE_NEW, hrec );
854 ok(r == ERROR_INVALID_DATA, "MsiViewModify failed %u\n", r);
858 err = MsiViewGetError( hview, buffer, &sz );
859 ok(err == MSIDBERROR_DUPLICATEKEY, "MsiViewGetError returned %u\n", err);
860 ok(!strcmp(buffer, "id"), "expected \"id\" c, got \"%s\"\n", buffer);
861 ok(sz == 2, "size not 2\n");
863 /* insert the same thing again */
864 r = MsiViewExecute(hview, 0);
865 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
867 /* should fail ... */
868 r = MsiViewModify(hview, MSIMODIFY_INSERT_TEMPORARY, hrec );
869 ok(r == ERROR_FUNCTION_FAILED, "MsiViewModify failed\n");
871 r = MsiCloseHandle(hrec);
872 ok(r == ERROR_SUCCESS, "failed to close record\n");
874 r = MsiViewClose(hview);
875 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
876 r = MsiCloseHandle(hview);
877 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
879 query = "SELECT * FROM `phone`";
880 r = MsiDatabaseOpenView(hdb, query, &hview);
881 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
883 r = MsiViewExecute(hview, 0);
884 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
886 r = MsiViewFetch(hview, &hrec);
887 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
889 r = MsiRecordGetInteger(hrec, 1);
890 ok(r == 1, "Expected 1, got %d\n", r);
893 r = MsiRecordGetString(hrec, 2, buffer, &sz);
894 ok(r == ERROR_SUCCESS, "MsiRecordGetString failed\n");
895 ok(!lstrcmp(buffer, "bob"), "Expected bob, got %s\n", buffer);
898 r = MsiRecordGetString(hrec, 3, buffer, &sz);
899 ok(r == ERROR_SUCCESS, "MsiRecordGetString failed\n");
900 ok(!lstrcmp(buffer, "7654321"), "Expected 7654321, got %s\n", buffer);
902 /* update the view, non-primary key */
903 r = MsiRecordSetString(hrec, 3, "3141592");
904 ok(r == ERROR_SUCCESS, "MsiRecordSetString failed\n");
906 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec);
907 ok(r == ERROR_SUCCESS, "MsiViewModify failed\n");
910 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec);
911 ok(r == ERROR_SUCCESS, "MsiViewModify failed: %d\n", r);
913 /* update the view, primary key */
914 r = MsiRecordSetInteger(hrec, 1, 5);
915 ok(r == ERROR_SUCCESS, "MsiRecordSetInteger failed\n");
917 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec);
918 ok(r == ERROR_FUNCTION_FAILED, "MsiViewModify failed\n");
920 r = MsiCloseHandle(hrec);
921 ok(r == ERROR_SUCCESS, "failed to close record\n");
923 r = MsiViewClose(hview);
924 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
925 r = MsiCloseHandle(hview);
926 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
928 query = "SELECT * FROM `phone`";
929 r = MsiDatabaseOpenView(hdb, query, &hview);
930 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
932 r = MsiViewExecute(hview, 0);
933 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
935 r = MsiViewFetch(hview, &hrec);
936 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
938 r = MsiRecordGetInteger(hrec, 1);
939 ok(r == 1, "Expected 1, got %d\n", r);
942 r = MsiRecordGetString(hrec, 2, buffer, &sz);
943 ok(r == ERROR_SUCCESS, "MsiRecordGetString failed\n");
944 ok(!lstrcmp(buffer, "bob"), "Expected bob, got %s\n", buffer);
947 r = MsiRecordGetString(hrec, 3, buffer, &sz);
948 ok(r == ERROR_SUCCESS, "MsiRecordGetString failed\n");
949 ok(!lstrcmp(buffer, "3141592"), "Expected 3141592, got %s\n", buffer);
951 r = MsiCloseHandle(hrec);
952 ok(r == ERROR_SUCCESS, "failed to close record\n");
954 /* use a record that doesn't come from a view fetch */
955 hrec = MsiCreateRecord(3);
956 ok(hrec != 0, "MsiCreateRecord failed\n");
958 r = MsiRecordSetInteger(hrec, 1, 3);
959 ok(r == ERROR_SUCCESS, "failed to set integer\n");
960 r = MsiRecordSetString(hrec, 2, "jane");
961 ok(r == ERROR_SUCCESS, "failed to set string\n");
962 r = MsiRecordSetString(hrec, 3, "112358");
963 ok(r == ERROR_SUCCESS, "failed to set string\n");
965 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec);
966 ok(r == ERROR_FUNCTION_FAILED, "Expected ERROR_FUNCTION_FAILED, got %d\n", r);
968 r = MsiCloseHandle(hrec);
969 ok(r == ERROR_SUCCESS, "failed to close record\n");
971 /* use a record that doesn't come from a view fetch, primary key matches */
972 hrec = MsiCreateRecord(3);
973 ok(hrec != 0, "MsiCreateRecord failed\n");
975 r = MsiRecordSetInteger(hrec, 1, 1);
976 ok(r == ERROR_SUCCESS, "failed to set integer\n");
977 r = MsiRecordSetString(hrec, 2, "jane");
978 ok(r == ERROR_SUCCESS, "failed to set string\n");
979 r = MsiRecordSetString(hrec, 3, "112358");
980 ok(r == ERROR_SUCCESS, "failed to set string\n");
982 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec);
983 ok(r == ERROR_FUNCTION_FAILED, "MsiViewModify failed\n");
985 r = MsiCloseHandle(hrec);
986 ok(r == ERROR_SUCCESS, "failed to close record\n");
988 hrec = MsiCreateRecord(3);
990 r = MsiRecordSetInteger(hrec, 1, 2);
991 ok(r == ERROR_SUCCESS, "failed to set integer\n");
992 r = MsiRecordSetString(hrec, 2, "nick");
993 ok(r == ERROR_SUCCESS, "failed to set string\n");
994 r = MsiRecordSetString(hrec, 3, "141421");
995 ok(r == ERROR_SUCCESS, "failed to set string\n");
997 r = MsiViewExecute(hview, 0);
998 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
999 r = MsiViewModify(hview, MSIMODIFY_INSERT_TEMPORARY, hrec );
1000 ok(r == ERROR_SUCCESS, "MsiViewModify failed\n");
1002 r = MsiCloseHandle(hrec);
1003 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
1004 r = MsiViewClose(hview);
1005 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
1006 r = MsiCloseHandle(hview);
1007 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
1009 query = "SELECT * FROM `phone` WHERE `id` = 1";
1010 r = MsiDatabaseOpenView(hdb, query, &hview);
1011 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
1012 r = MsiViewExecute(hview, 0);
1013 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
1014 r = MsiViewFetch(hview, &hrec);
1015 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
1017 /* change the id to match the second row */
1018 r = MsiRecordSetInteger(hrec, 1, 2);
1019 ok(r == ERROR_SUCCESS, "failed to set integer\n");
1020 r = MsiRecordSetString(hrec, 2, "jerry");
1021 ok(r == ERROR_SUCCESS, "failed to set string\n");
1023 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec);
1024 ok(r == ERROR_FUNCTION_FAILED, "MsiViewModify failed\n");
1026 r = MsiCloseHandle(hrec);
1027 ok(r == ERROR_SUCCESS, "failed to close record\n");
1028 r = MsiViewClose(hview);
1029 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
1030 r = MsiCloseHandle(hview);
1031 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
1033 /* broader search */
1034 query = "SELECT * FROM `phone` ORDER BY `id`";
1035 r = MsiDatabaseOpenView(hdb, query, &hview);
1036 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
1037 r = MsiViewExecute(hview, 0);
1038 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
1039 r = MsiViewFetch(hview, &hrec);
1040 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
1042 /* change the id to match the second row */
1043 r = MsiRecordSetInteger(hrec, 1, 2);
1044 ok(r == ERROR_SUCCESS, "failed to set integer\n");
1045 r = MsiRecordSetString(hrec, 2, "jerry");
1046 ok(r == ERROR_SUCCESS, "failed to set string\n");
1048 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec);
1049 ok(r == ERROR_FUNCTION_FAILED, "MsiViewModify failed\n");
1051 r = MsiCloseHandle(hrec);
1052 ok(r == ERROR_SUCCESS, "failed to close record\n");
1053 r = MsiViewClose(hview);
1054 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
1055 r = MsiCloseHandle(hview);
1056 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
1058 r = MsiCloseHandle( hdb );
1059 ok(r == ERROR_SUCCESS, "MsiOpenDatabase close failed\n");
1062 static MSIHANDLE create_db(void)
1067 DeleteFile(msifile);
1069 /* create an empty database */
1070 res = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb );
1071 ok( res == ERROR_SUCCESS , "Failed to create database\n" );
1072 if( res != ERROR_SUCCESS )
1075 res = MsiDatabaseCommit( hdb );
1076 ok( res == ERROR_SUCCESS , "Failed to commit database\n" );
1081 static void test_getcolinfo(void)
1083 MSIHANDLE hdb, hview = 0, rec = 0;
1088 /* create an empty db */
1090 ok( hdb, "failed to create db\n");
1092 /* tables should be present */
1093 r = MsiDatabaseOpenView(hdb, "select * from _Tables", &hview);
1094 ok( r == ERROR_SUCCESS, "failed to open query\n");
1096 r = MsiViewExecute(hview, 0);
1097 ok( r == ERROR_SUCCESS, "failed to execute query\n");
1099 /* check that NAMES works */
1101 r = MsiViewGetColumnInfo( hview, MSICOLINFO_NAMES, &rec );
1102 ok( r == ERROR_SUCCESS, "failed to get names\n");
1104 r = MsiRecordGetString(rec, 1, buffer, &sz );
1105 ok( r == ERROR_SUCCESS, "failed to get string\n");
1106 ok( !strcmp(buffer,"Name"), "_Tables has wrong column name\n");
1107 r = MsiCloseHandle( rec );
1108 ok( r == ERROR_SUCCESS, "failed to close record handle\n");
1110 /* check that TYPES works */
1112 r = MsiViewGetColumnInfo( hview, MSICOLINFO_TYPES, &rec );
1113 ok( r == ERROR_SUCCESS, "failed to get names\n");
1115 r = MsiRecordGetString(rec, 1, buffer, &sz );
1116 ok( r == ERROR_SUCCESS, "failed to get string\n");
1117 ok( !strcmp(buffer,"s64"), "_Tables has wrong column type\n");
1118 r = MsiCloseHandle( rec );
1119 ok( r == ERROR_SUCCESS, "failed to close record handle\n");
1121 /* check that invalid values fail */
1123 r = MsiViewGetColumnInfo( hview, 100, &rec );
1124 ok( r == ERROR_INVALID_PARAMETER, "wrong error code\n");
1125 ok( rec == 0, "returned a record\n");
1127 r = MsiViewGetColumnInfo( hview, MSICOLINFO_TYPES, NULL );
1128 ok( r == ERROR_INVALID_PARAMETER, "wrong error code\n");
1130 r = MsiViewGetColumnInfo( 0, MSICOLINFO_TYPES, &rec );
1131 ok( r == ERROR_INVALID_HANDLE, "wrong error code\n");
1133 r = MsiViewClose(hview);
1134 ok( r == ERROR_SUCCESS, "failed to close view\n");
1135 r = MsiCloseHandle(hview);
1136 ok( r == ERROR_SUCCESS, "failed to close view handle\n");
1137 r = MsiCloseHandle(hdb);
1138 ok( r == ERROR_SUCCESS, "failed to close database\n");
1141 static MSIHANDLE get_column_info(MSIHANDLE hdb, const char *query, MSICOLINFO type)
1143 MSIHANDLE hview = 0, rec = 0;
1146 r = MsiDatabaseOpenView(hdb, query, &hview);
1147 if( r != ERROR_SUCCESS )
1150 r = MsiViewExecute(hview, 0);
1151 if( r == ERROR_SUCCESS )
1153 MsiViewGetColumnInfo( hview, type, &rec );
1155 MsiViewClose(hview);
1156 MsiCloseHandle(hview);
1160 static UINT get_columns_table_type(MSIHANDLE hdb, const char *table, UINT field)
1162 MSIHANDLE hview = 0, rec = 0;
1166 sprintf(query, "select * from `_Columns` where `Table` = '%s'", table );
1168 r = MsiDatabaseOpenView(hdb, query, &hview);
1169 if( r != ERROR_SUCCESS )
1172 r = MsiViewExecute(hview, 0);
1173 if( r == ERROR_SUCCESS )
1177 r = MsiViewFetch( hview, &rec );
1178 if( r != ERROR_SUCCESS)
1180 r = MsiRecordGetInteger( rec, 2 );
1182 type = MsiRecordGetInteger( rec, 4 );
1183 MsiCloseHandle( rec );
1186 MsiViewClose(hview);
1187 MsiCloseHandle(hview);
1191 static BOOL check_record( MSIHANDLE rec, UINT field, LPCSTR val )
1198 r = MsiRecordGetString( rec, field, buffer, &sz );
1199 return (r == ERROR_SUCCESS ) && !strcmp(val, buffer);
1202 static void test_viewgetcolumninfo(void)
1204 MSIHANDLE hdb = 0, rec;
1208 ok( hdb, "failed to create db\n");
1210 r = run_query( hdb, 0,
1211 "CREATE TABLE `Properties` "
1212 "( `Property` CHAR(255), "
1213 " `Value` CHAR(1), "
1215 " `Integervalue` INTEGER, "
1216 " `Shortvalue` SHORT, "
1217 " `Longvalue` LONG, "
1218 " `Longcharvalue` LONGCHAR "
1219 " PRIMARY KEY `Property`)" );
1220 ok( r == ERROR_SUCCESS , "Failed to create table\n" );
1222 /* check the column types */
1223 rec = get_column_info( hdb, "select * from `Properties`", MSICOLINFO_TYPES );
1224 ok( rec, "failed to get column info record\n" );
1226 ok( check_record( rec, 1, "S255"), "wrong record type\n");
1227 ok( check_record( rec, 2, "S1"), "wrong record type\n");
1228 ok( check_record( rec, 3, "I2"), "wrong record type\n");
1229 ok( check_record( rec, 4, "I2"), "wrong record type\n");
1230 ok( check_record( rec, 5, "I2"), "wrong record type\n");
1231 ok( check_record( rec, 6, "I4"), "wrong record type\n");
1232 ok( check_record( rec, 7, "S0"), "wrong record type\n");
1234 MsiCloseHandle( rec );
1236 /* check the type in _Columns */
1237 ok( 0x3dff == get_columns_table_type(hdb, "Properties", 1 ), "_columns table wrong\n");
1238 ok( 0x1d01 == get_columns_table_type(hdb, "Properties", 2 ), "_columns table wrong\n");
1239 ok( 0x1502 == get_columns_table_type(hdb, "Properties", 3 ), "_columns table wrong\n");
1240 ok( 0x1502 == get_columns_table_type(hdb, "Properties", 4 ), "_columns table wrong\n");
1241 ok( 0x1502 == get_columns_table_type(hdb, "Properties", 5 ), "_columns table wrong\n");
1242 ok( 0x1104 == get_columns_table_type(hdb, "Properties", 6 ), "_columns table wrong\n");
1243 ok( 0x1d00 == get_columns_table_type(hdb, "Properties", 7 ), "_columns table wrong\n");
1245 /* now try the names */
1246 rec = get_column_info( hdb, "select * from `Properties`", MSICOLINFO_NAMES );
1247 ok( rec, "failed to get column info record\n" );
1249 ok( check_record( rec, 1, "Property"), "wrong record type\n");
1250 ok( check_record( rec, 2, "Value"), "wrong record type\n");
1251 ok( check_record( rec, 3, "Intvalue"), "wrong record type\n");
1252 ok( check_record( rec, 4, "Integervalue"), "wrong record type\n");
1253 ok( check_record( rec, 5, "Shortvalue"), "wrong record type\n");
1254 ok( check_record( rec, 6, "Longvalue"), "wrong record type\n");
1255 ok( check_record( rec, 7, "Longcharvalue"), "wrong record type\n");
1257 MsiCloseHandle( rec );
1259 r = run_query( hdb, 0,
1260 "CREATE TABLE `Binary` "
1261 "( `Name` CHAR(255), `Data` OBJECT PRIMARY KEY `Name`)" );
1262 ok( r == ERROR_SUCCESS , "Failed to create table\n" );
1264 /* check the column types */
1265 rec = get_column_info( hdb, "select * from `Binary`", MSICOLINFO_TYPES );
1266 ok( rec, "failed to get column info record\n" );
1268 ok( check_record( rec, 1, "S255"), "wrong record type\n");
1269 ok( check_record( rec, 2, "V0"), "wrong record type\n");
1271 MsiCloseHandle( rec );
1273 /* check the type in _Columns */
1274 ok( 0x3dff == get_columns_table_type(hdb, "Binary", 1 ), "_columns table wrong\n");
1275 ok( 0x1900 == get_columns_table_type(hdb, "Binary", 2 ), "_columns table wrong\n");
1277 /* now try the names */
1278 rec = get_column_info( hdb, "select * from `Binary`", MSICOLINFO_NAMES );
1279 ok( rec, "failed to get column info record\n" );
1281 ok( check_record( rec, 1, "Name"), "wrong record type\n");
1282 ok( check_record( rec, 2, "Data"), "wrong record type\n");
1283 MsiCloseHandle( rec );
1285 r = run_query( hdb, 0,
1286 "CREATE TABLE `UIText` "
1287 "( `Key` CHAR(72) NOT NULL, `Text` CHAR(255) LOCALIZABLE PRIMARY KEY `Key`)" );
1288 ok( r == ERROR_SUCCESS , "Failed to create table\n" );
1290 ok( 0x2d48 == get_columns_table_type(hdb, "UIText", 1 ), "_columns table wrong\n");
1291 ok( 0x1fff == get_columns_table_type(hdb, "UIText", 2 ), "_columns table wrong\n");
1293 rec = get_column_info( hdb, "select * from `UIText`", MSICOLINFO_NAMES );
1294 ok( rec, "failed to get column info record\n" );
1295 ok( check_record( rec, 1, "Key"), "wrong record type\n");
1296 ok( check_record( rec, 2, "Text"), "wrong record type\n");
1297 MsiCloseHandle( rec );
1299 rec = get_column_info( hdb, "select * from `UIText`", MSICOLINFO_TYPES );
1300 ok( rec, "failed to get column info record\n" );
1301 ok( check_record( rec, 1, "s72"), "wrong record type\n");
1302 ok( check_record( rec, 2, "L255"), "wrong record type\n");
1303 MsiCloseHandle( rec );
1305 MsiCloseHandle( hdb );
1308 static void test_msiexport(void)
1310 MSIHANDLE hdb = 0, hview = 0;
1313 char path[MAX_PATH];
1314 const char file[] = "phone.txt";
1318 const char expected[] =
1319 "id\tname\tnumber\r\n"
1322 "1\tAbe\t8675309\r\n";
1324 DeleteFile(msifile);
1326 /* just MsiOpenDatabase should not create a file */
1327 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
1328 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n");
1330 /* create a table */
1331 query = "CREATE TABLE `phone` ( "
1332 "`id` INT, `name` CHAR(32), `number` CHAR(32) "
1333 "PRIMARY KEY `id`)";
1334 r = MsiDatabaseOpenView(hdb, query, &hview);
1335 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
1336 r = MsiViewExecute(hview, 0);
1337 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
1338 r = MsiViewClose(hview);
1339 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
1340 r = MsiCloseHandle(hview);
1341 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
1343 /* insert a value into it */
1344 query = "INSERT INTO `phone` ( `id`, `name`, `number` )"
1345 "VALUES('1', 'Abe', '8675309')";
1346 r = MsiDatabaseOpenView(hdb, query, &hview);
1347 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
1348 r = MsiViewExecute(hview, 0);
1349 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
1350 r = MsiViewClose(hview);
1351 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
1352 r = MsiCloseHandle(hview);
1353 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
1355 GetCurrentDirectory(MAX_PATH, path);
1357 r = MsiDatabaseExport(hdb, "phone", path, file);
1358 ok(r == ERROR_SUCCESS, "MsiDatabaseExport failed\n");
1360 MsiCloseHandle(hdb);
1362 lstrcat(path, "\\");
1363 lstrcat(path, file);
1365 /* check the data that was written */
1367 memset(buffer, 0, sizeof buffer);
1368 handle = CreateFile(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
1369 if (handle != INVALID_HANDLE_VALUE)
1371 ReadFile(handle, buffer, sizeof buffer, &length, NULL);
1372 CloseHandle(handle);
1376 ok(0, "failed to open file %s\n", path);
1378 ok( length == strlen(expected), "length of data wrong\n");
1379 ok( !lstrcmp(buffer, expected), "data doesn't match\n");
1380 DeleteFile(msifile);
1383 static void test_longstrings(void)
1385 const char insert_query[] =
1386 "INSERT INTO `strings` ( `id`, `val` ) VALUES('1', 'Z')";
1388 MSIHANDLE hdb = 0, hview = 0, hrec = 0;
1391 const DWORD STRING_LENGTH = 0x10005;
1393 DeleteFile(msifile);
1394 /* just MsiOpenDatabase should not create a file */
1395 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
1396 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n");
1398 /* create a table */
1400 "CREATE TABLE `strings` ( `id` INT, `val` CHAR(0) PRIMARY KEY `id`)");
1401 ok(r == ERROR_SUCCESS, "query failed\n");
1403 /* try a insert a very long string */
1404 str = HeapAlloc(GetProcessHeap(), 0, STRING_LENGTH+sizeof insert_query);
1405 len = strchr(insert_query, 'Z') - insert_query;
1406 strcpy(str, insert_query);
1407 memset(str+len, 'Z', STRING_LENGTH);
1408 strcpy(str+len+STRING_LENGTH, insert_query+len+1);
1409 r = try_query( hdb, str );
1410 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
1412 HeapFree(GetProcessHeap(), 0, str);
1414 MsiDatabaseCommit(hdb);
1415 ok(r == ERROR_SUCCESS, "MsiDatabaseCommit failed\n");
1416 MsiCloseHandle(hdb);
1418 r = MsiOpenDatabase(msifile, MSIDBOPEN_READONLY, &hdb);
1419 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n");
1421 r = MsiDatabaseOpenView(hdb, "select * from `strings` where `id` = 1", &hview);
1422 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
1424 r = MsiViewExecute(hview, 0);
1425 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
1427 r = MsiViewFetch(hview, &hrec);
1428 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
1430 MsiViewClose(hview);
1431 MsiCloseHandle(hview);
1433 r = MsiRecordGetString(hrec, 2, NULL, &len);
1434 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
1435 ok(len == STRING_LENGTH, "string length wrong\n");
1437 MsiCloseHandle(hrec);
1438 MsiCloseHandle(hdb);
1439 DeleteFile(msifile);
1442 static void create_file_data(LPCSTR name, LPCSTR data, DWORD size)
1447 file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
1448 if (file == INVALID_HANDLE_VALUE)
1451 WriteFile(file, data, strlen(data), &written, NULL);
1452 WriteFile(file, "\n", strlen("\n"), &written, NULL);
1456 SetFilePointer(file, size, NULL, FILE_BEGIN);
1463 #define create_file(name) create_file_data(name, name, 0)
1465 static void test_streamtable(void)
1467 MSIHANDLE hdb = 0, rec, view, hsi;
1468 char file[MAX_PATH];
1474 ok( hdb, "failed to create db\n");
1476 r = run_query( hdb, 0,
1477 "CREATE TABLE `Properties` "
1478 "( `Property` CHAR(255), `Value` CHAR(1) PRIMARY KEY `Property`)" );
1479 ok( r == ERROR_SUCCESS , "Failed to create table\n" );
1481 r = run_query( hdb, 0,
1482 "INSERT INTO `Properties` "
1483 "( `Value`, `Property` ) VALUES ( 'Prop', 'value' )" );
1484 ok( r == ERROR_SUCCESS, "Failed to add to table\n" );
1486 r = MsiDatabaseCommit( hdb );
1487 ok( r == ERROR_SUCCESS , "Failed to commit database\n" );
1489 MsiCloseHandle( hdb );
1491 r = MsiOpenDatabase(msifile, MSIDBOPEN_TRANSACT, &hdb );
1492 ok( r == ERROR_SUCCESS , "Failed to open database\n" );
1494 /* check the column types */
1495 rec = get_column_info( hdb, "select * from `_Streams`", MSICOLINFO_TYPES );
1496 ok( rec, "failed to get column info record\n" );
1498 ok( check_record( rec, 1, "s62"), "wrong record type\n");
1499 ok( check_record( rec, 2, "V0"), "wrong record type\n");
1501 MsiCloseHandle( rec );
1503 /* now try the names */
1504 rec = get_column_info( hdb, "select * from `_Streams`", MSICOLINFO_NAMES );
1505 ok( rec, "failed to get column info record\n" );
1507 ok( check_record( rec, 1, "Name"), "wrong record type\n");
1508 ok( check_record( rec, 2, "Data"), "wrong record type\n");
1510 MsiCloseHandle( rec );
1512 r = MsiDatabaseOpenView( hdb,
1513 "SELECT * FROM `_Streams` WHERE `Name` = '\5SummaryInformation'", &view );
1514 ok( r == ERROR_SUCCESS, "Failed to open database view: %u\n", r );
1516 r = MsiViewExecute( view, 0 );
1517 ok( r == ERROR_SUCCESS, "Failed to execute view: %u\n", r );
1519 r = MsiViewFetch( view, &rec );
1520 ok( r == ERROR_NO_MORE_ITEMS, "Unexpected result: %u\n", r );
1522 MsiCloseHandle( rec );
1523 MsiViewClose( view );
1524 MsiCloseHandle( view );
1526 /* create a summary information stream */
1527 r = MsiGetSummaryInformationA( hdb, NULL, 1, &hsi );
1528 ok( r == ERROR_SUCCESS, "Failed to get summary information handle: %u\n", r );
1530 r = MsiSummaryInfoSetPropertyA( hsi, PID_SECURITY, VT_I4, 2, NULL, NULL );
1531 ok( r == ERROR_SUCCESS, "Failed to set property: %u\n", r );
1533 r = MsiSummaryInfoPersist( hsi );
1534 ok( r == ERROR_SUCCESS, "Failed to save summary information: %u\n", r );
1536 MsiCloseHandle( hsi );
1538 r = MsiDatabaseOpenView( hdb,
1539 "SELECT * FROM `_Streams` WHERE `Name` = '\5SummaryInformation'", &view );
1540 ok( r == ERROR_SUCCESS, "Failed to open database view: %u\n", r );
1542 r = MsiViewExecute( view, 0 );
1543 ok( r == ERROR_SUCCESS, "Failed to execute view: %u\n", r );
1545 r = MsiViewFetch( view, &rec );
1546 ok( r == ERROR_SUCCESS, "Unexpected result: %u\n", r );
1548 MsiCloseHandle( rec );
1549 MsiViewClose( view );
1550 MsiCloseHandle( view );
1552 /* insert a file into the _Streams table */
1553 create_file( "test.txt" );
1555 rec = MsiCreateRecord( 2 );
1556 MsiRecordSetString( rec, 1, "data" );
1558 r = MsiRecordSetStream( rec, 2, "test.txt" );
1559 ok( r == ERROR_SUCCESS, "Failed to add stream data to the record: %d\n", r);
1561 DeleteFile("test.txt");
1563 r = MsiDatabaseOpenView( hdb,
1564 "INSERT INTO `_Streams` ( `Name`, `Data` ) VALUES ( ?, ? )", &view );
1565 ok( r == ERROR_SUCCESS, "Failed to open database view: %d\n", r);
1567 r = MsiViewExecute( view, rec );
1568 ok( r == ERROR_SUCCESS, "Failed to execute view: %d\n", r);
1570 MsiCloseHandle( rec );
1571 MsiViewClose( view );
1572 MsiCloseHandle( view );
1574 /* insert another one */
1575 create_file( "test1.txt" );
1577 rec = MsiCreateRecord( 2 );
1578 MsiRecordSetString( rec, 1, "data1" );
1580 r = MsiRecordSetStream( rec, 2, "test1.txt" );
1581 ok( r == ERROR_SUCCESS, "Failed to add stream data to the record: %d\n", r);
1583 DeleteFile("test1.txt");
1585 r = MsiDatabaseOpenView( hdb,
1586 "INSERT INTO `_Streams` ( `Name`, `Data` ) VALUES ( ?, ? )", &view );
1587 ok( r == ERROR_SUCCESS, "Failed to open database view: %d\n", r);
1589 r = MsiViewExecute( view, rec );
1590 ok( r == ERROR_SUCCESS, "Failed to execute view: %d\n", r);
1592 MsiCloseHandle( rec );
1593 MsiViewClose( view );
1594 MsiCloseHandle( view );
1596 r = MsiDatabaseOpenView( hdb,
1597 "SELECT `Name`, `Data` FROM `_Streams` WHERE `Name` = 'data'", &view );
1598 ok( r == ERROR_SUCCESS, "Failed to open database view: %d\n", r);
1600 r = MsiViewExecute( view, 0 );
1601 ok( r == ERROR_SUCCESS, "Failed to execute view: %d\n", r);
1603 r = MsiViewFetch( view, &rec );
1604 ok( r == ERROR_SUCCESS, "Failed to fetch record: %d\n", r);
1607 r = MsiRecordGetString( rec, 1, file, &size );
1608 ok( r == ERROR_SUCCESS, "Failed to get string: %d\n", r);
1609 ok( !lstrcmp(file, "data"), "Expected 'data', got %s\n", file);
1612 memset(buf, 0, MAX_PATH);
1613 r = MsiRecordReadStream( rec, 2, buf, &size );
1614 ok( r == ERROR_SUCCESS, "Failed to get stream: %d\n", r);
1615 ok( !lstrcmp(buf, "test.txt\n"), "Expected 'test.txt\\n', got %s\n", buf);
1617 MsiCloseHandle( rec );
1618 MsiViewClose( view );
1619 MsiCloseHandle( view );
1621 r = MsiDatabaseOpenView( hdb,
1622 "SELECT `Name`, `Data` FROM `_Streams` WHERE `Name` = 'data1'", &view );
1623 ok( r == ERROR_SUCCESS, "Failed to open database view: %d\n", r);
1625 r = MsiViewExecute( view, 0 );
1626 ok( r == ERROR_SUCCESS, "Failed to execute view: %d\n", r);
1628 r = MsiViewFetch( view, &rec );
1629 ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1632 r = MsiRecordGetString( rec, 1, file, &size );
1633 ok( r == ERROR_SUCCESS, "Failed to get string: %d\n", r);
1634 ok( !lstrcmp(file, "data1"), "Expected 'data1', got %s\n", file);
1637 memset(buf, 0, MAX_PATH);
1638 r = MsiRecordReadStream( rec, 2, buf, &size );
1639 ok( r == ERROR_SUCCESS, "Failed to get stream: %d\n", r);
1640 ok( !lstrcmp(buf, "test1.txt\n"), "Expected 'test1.txt\\n', got %s\n", buf);
1642 MsiCloseHandle( rec );
1643 MsiViewClose( view );
1644 MsiCloseHandle( view );
1646 /* perform an update */
1647 create_file( "test2.txt" );
1648 rec = MsiCreateRecord( 1 );
1650 r = MsiRecordSetStream( rec, 1, "test2.txt" );
1651 ok( r == ERROR_SUCCESS, "Failed to add stream data to the record: %d\n", r);
1653 DeleteFile("test2.txt");
1655 r = MsiDatabaseOpenView( hdb,
1656 "UPDATE `_Streams` SET `Data` = ? WHERE `Name` = 'data1'", &view );
1657 ok( r == ERROR_SUCCESS, "Failed to open database view: %d\n", r);
1659 r = MsiViewExecute( view, rec );
1660 ok( r == ERROR_SUCCESS, "Failed to execute view: %d\n", r);
1662 MsiCloseHandle( rec );
1663 MsiViewClose( view );
1664 MsiCloseHandle( view );
1666 r = MsiDatabaseOpenView( hdb,
1667 "SELECT `Name`, `Data` FROM `_Streams` WHERE `Name` = 'data1'", &view );
1668 ok( r == ERROR_SUCCESS, "Failed to open database view: %d\n", r);
1670 r = MsiViewExecute( view, 0 );
1671 ok( r == ERROR_SUCCESS, "Failed to execute view: %d\n", r);
1673 r = MsiViewFetch( view, &rec );
1674 ok( r == ERROR_SUCCESS, "Failed to fetch record: %d\n", r);
1677 r = MsiRecordGetString( rec, 1, file, &size );
1678 ok( r == ERROR_SUCCESS, "Failed to get string: %d\n", r);
1679 ok( !lstrcmp(file, "data1"), "Expected 'data1', got %s\n", file);
1682 memset(buf, 0, MAX_PATH);
1683 r = MsiRecordReadStream( rec, 2, buf, &size );
1684 ok( r == ERROR_SUCCESS, "Failed to get stream: %d\n", r);
1685 todo_wine ok( !lstrcmp(buf, "test2.txt\n"), "Expected 'test2.txt\\n', got %s\n", buf);
1687 MsiCloseHandle( rec );
1688 MsiViewClose( view );
1689 MsiCloseHandle( view );
1690 MsiCloseHandle( hdb );
1691 DeleteFile(msifile);
1694 static void test_binary(void)
1696 MSIHANDLE hdb = 0, rec;
1697 char file[MAX_PATH];
1703 /* insert a file into the Binary table */
1704 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb );
1705 ok( r == ERROR_SUCCESS , "Failed to open database\n" );
1707 query = "CREATE TABLE `Binary` ( `Name` CHAR(72) NOT NULL, `ID` INT NOT NULL, `Data` OBJECT PRIMARY KEY `Name`, `ID`)";
1708 r = run_query( hdb, 0, query );
1709 ok( r == ERROR_SUCCESS, "Cannot create Binary table: %d\n", r );
1711 create_file( "test.txt" );
1712 rec = MsiCreateRecord( 1 );
1713 r = MsiRecordSetStream( rec, 1, "test.txt" );
1714 ok( r == ERROR_SUCCESS, "Failed to add stream data to the record: %d\n", r);
1715 DeleteFile( "test.txt" );
1717 query = "INSERT INTO `Binary` ( `Name`, `ID`, `Data` ) VALUES ( 'filename1', 1, ? )";
1718 r = run_query( hdb, rec, query );
1719 ok( r == ERROR_SUCCESS, "Insert into Binary table failed: %d\n", r );
1721 r = MsiCloseHandle( rec );
1722 ok( r == ERROR_SUCCESS , "Failed to close record handle\n" );
1724 r = MsiDatabaseCommit( hdb );
1725 ok( r == ERROR_SUCCESS , "Failed to commit database\n" );
1727 r = MsiCloseHandle( hdb );
1728 ok( r == ERROR_SUCCESS , "Failed to close database\n" );
1730 /* read file from the Stream table */
1731 r = MsiOpenDatabase( msifile, MSIDBOPEN_READONLY, &hdb );
1732 ok( r == ERROR_SUCCESS , "Failed to open database\n" );
1734 query = "SELECT * FROM `_Streams`";
1735 r = do_query( hdb, query, &rec );
1736 ok( r == ERROR_SUCCESS, "SELECT query failed: %d\n", r );
1739 r = MsiRecordGetString( rec, 1, file, &size );
1740 ok( r == ERROR_SUCCESS, "Failed to get string: %d\n", r );
1741 ok( !lstrcmp(file, "Binary.filename1.1"), "Expected 'Binary.filename1.1', got %s\n", file );
1744 memset( buf, 0, MAX_PATH );
1745 r = MsiRecordReadStream( rec, 2, buf, &size );
1746 ok( r == ERROR_SUCCESS, "Failed to get stream: %d\n", r );
1747 ok( !lstrcmp(buf, "test.txt\n"), "Expected 'test.txt\\n', got %s\n", buf );
1749 r = MsiCloseHandle( rec );
1750 ok( r == ERROR_SUCCESS , "Failed to close record handle\n" );
1752 /* read file from the Binary table */
1753 query = "SELECT * FROM `Binary`";
1754 r = do_query( hdb, query, &rec );
1755 ok( r == ERROR_SUCCESS, "SELECT query failed: %d\n", r );
1758 r = MsiRecordGetString( rec, 1, file, &size );
1759 ok( r == ERROR_SUCCESS, "Failed to get string: %d\n", r );
1760 ok( !lstrcmp(file, "filename1"), "Expected 'filename1', got %s\n", file );
1763 memset( buf, 0, MAX_PATH );
1764 r = MsiRecordReadStream( rec, 3, buf, &size );
1765 ok( r == ERROR_SUCCESS, "Failed to get stream: %d\n", r );
1766 ok( !lstrcmp(buf, "test.txt\n"), "Expected 'test.txt\\n', got %s\n", buf );
1768 r = MsiCloseHandle( rec );
1769 ok( r == ERROR_SUCCESS , "Failed to close record handle\n" );
1771 r = MsiCloseHandle( hdb );
1772 ok( r == ERROR_SUCCESS , "Failed to close database\n" );
1774 DeleteFile( msifile );
1777 static void test_where_not_in_selected(void)
1779 MSIHANDLE hdb = 0, rec, view;
1784 ok( hdb, "failed to create db\n");
1786 r = run_query(hdb, 0,
1787 "CREATE TABLE `IESTable` ("
1788 "`Action` CHAR(64), "
1789 "`Condition` CHAR(64), "
1790 "`Sequence` LONG PRIMARY KEY `Sequence`)");
1791 ok( r == S_OK, "Cannot create IESTable table: %d\n", r);
1793 r = run_query(hdb, 0,
1794 "CREATE TABLE `CATable` ("
1795 "`Action` CHAR(64), "
1796 "`Type` LONG PRIMARY KEY `Type`)");
1797 ok( r == S_OK, "Cannot create CATable table: %d\n", r);
1799 r = run_query(hdb, 0, "INSERT INTO `IESTable` "
1800 "( `Action`, `Condition`, `Sequence`) "
1801 "VALUES ( 'clean', 'cond4', 4)");
1802 ok( r == S_OK, "cannot add entry to IESTable table:%d\n", r );
1804 r = run_query(hdb, 0, "INSERT INTO `IESTable` "
1805 "( `Action`, `Condition`, `Sequence`) "
1806 "VALUES ( 'depends', 'cond1', 1)");
1807 ok( r == S_OK, "cannot add entry to IESTable table:%d\n", r );
1809 r = run_query(hdb, 0, "INSERT INTO `IESTable` "
1810 "( `Action`, `Condition`, `Sequence`) "
1811 "VALUES ( 'build', 'cond2', 2)");
1812 ok( r == S_OK, "cannot add entry to IESTable table:%d\n", r );
1814 r = run_query(hdb, 0, "INSERT INTO `IESTable` "
1815 "( `Action`, `Condition`, `Sequence`) "
1816 "VALUES ( 'build2', 'cond6', 6)");
1817 ok( r == S_OK, "cannot add entry to IESTable table:%d\n", r );
1819 r = run_query(hdb, 0, "INSERT INTO `IESTable` "
1820 "( `Action`, `Condition`, `Sequence`) "
1821 "VALUES ( 'build', 'cond3', 3)");
1822 ok(r == S_OK, "cannot add entry to IESTable table:%d\n", r );
1824 r = run_query(hdb, 0, "INSERT INTO `CATable` "
1825 "( `Action`, `Type` ) "
1826 "VALUES ( 'build', 32)");
1827 ok(r == S_OK, "cannot add entry to CATable table:%d\n", r );
1829 r = run_query(hdb, 0, "INSERT INTO `CATable` "
1830 "( `Action`, `Type` ) "
1831 "VALUES ( 'depends', 64)");
1832 ok(r == S_OK, "cannot add entry to CATable table:%d\n", r );
1834 r = run_query(hdb, 0, "INSERT INTO `CATable` "
1835 "( `Action`, `Type` ) "
1836 "VALUES ( 'clean', 63)");
1837 ok(r == S_OK, "cannot add entry to CATable table:%d\n", r );
1839 r = run_query(hdb, 0, "INSERT INTO `CATable` "
1840 "( `Action`, `Type` ) "
1841 "VALUES ( 'build2', 34)");
1842 ok(r == S_OK, "cannot add entry to CATable table:%d\n", r );
1843 query = "Select IESTable.Condition from CATable, IESTable where "
1844 "CATable.Action = IESTable.Action and CATable.Type = 32";
1845 r = MsiDatabaseOpenView(hdb, query, &view);
1846 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r );
1848 r = MsiViewExecute(view, 0);
1849 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r );
1851 r = MsiViewFetch(view, &rec);
1852 ok( r == ERROR_SUCCESS, "failed to fetch view: %d\n", r );
1854 ok( check_record( rec, 1, "cond2"), "wrong condition\n");
1856 MsiCloseHandle( rec );
1857 r = MsiViewFetch(view, &rec);
1858 ok( r == ERROR_SUCCESS, "failed to fetch view: %d\n", r );
1860 ok( check_record( rec, 1, "cond3"), "wrong condition\n");
1862 MsiCloseHandle( rec );
1864 MsiCloseHandle(view);
1866 MsiCloseHandle( hdb );
1867 DeleteFile(msifile);
1872 static void test_where(void)
1874 MSIHANDLE hdb = 0, rec, view;
1882 ok( hdb, "failed to create db\n");
1884 r = run_query( hdb, 0,
1885 "CREATE TABLE `Media` ("
1886 "`DiskId` SHORT NOT NULL, "
1887 "`LastSequence` LONG, "
1888 "`DiskPrompt` CHAR(64) LOCALIZABLE, "
1889 "`Cabinet` CHAR(255), "
1890 "`VolumeLabel` CHAR(32), "
1891 "`Source` CHAR(72) "
1892 "PRIMARY KEY `DiskId`)" );
1893 ok( r == S_OK, "cannot create Media table: %d\n", r );
1895 r = run_query( hdb, 0, "INSERT INTO `Media` "
1896 "( `DiskId`, `LastSequence`, `DiskPrompt`, `Cabinet`, `VolumeLabel`, `Source` ) "
1897 "VALUES ( 1, 0, '', 'zero.cab', '', '' )" );
1898 ok( r == S_OK, "cannot add file to the Media table: %d\n", r );
1900 r = run_query( hdb, 0, "INSERT INTO `Media` "
1901 "( `DiskId`, `LastSequence`, `DiskPrompt`, `Cabinet`, `VolumeLabel`, `Source` ) "
1902 "VALUES ( 2, 1, '', 'one.cab', '', '' )" );
1903 ok( r == S_OK, "cannot add file to the Media table: %d\n", r );
1905 r = run_query( hdb, 0, "INSERT INTO `Media` "
1906 "( `DiskId`, `LastSequence`, `DiskPrompt`, `Cabinet`, `VolumeLabel`, `Source` ) "
1907 "VALUES ( 3, 2, '', 'two.cab', '', '' )" );
1908 ok( r == S_OK, "cannot add file to the Media table: %d\n", r );
1910 query = "SELECT * FROM `Media`";
1911 r = do_query(hdb, query, &rec);
1912 ok(r == ERROR_SUCCESS, "MsiViewFetch failed: %d\n", r);
1913 ok( check_record( rec, 4, "zero.cab"), "wrong cabinet\n");
1914 MsiCloseHandle( rec );
1916 query = "SELECT * FROM `Media` WHERE `LastSequence` >= 1";
1917 r = do_query(hdb, query, &rec);
1918 ok(r == ERROR_SUCCESS, "MsiViewFetch failed: %d\n", r);
1919 ok( check_record( rec, 4, "one.cab"), "wrong cabinet\n");
1921 r = MsiRecordGetInteger(rec, 1);
1922 ok( 2 == r, "field wrong\n");
1923 r = MsiRecordGetInteger(rec, 2);
1924 ok( 1 == r, "field wrong\n");
1925 MsiCloseHandle( rec );
1927 query = "SELECT `DiskId` FROM `Media` WHERE `LastSequence` >= 1 AND DiskId >= 0";
1928 r = MsiDatabaseOpenView(hdb, query, &view);
1929 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r );
1931 r = MsiViewExecute(view, 0);
1932 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r );
1934 r = MsiViewFetch(view, &rec);
1935 ok( r == ERROR_SUCCESS, "failed to fetch view: %d\n", r );
1937 count = MsiRecordGetFieldCount( rec );
1938 ok( count == 1, "Expected 1 record fields, got %d\n", count );
1941 r = MsiRecordGetString( rec, 1, buf, &size );
1942 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r );
1943 ok( !lstrcmp( buf, "2" ),
1944 "For (row %d, column 1) expected '%d', got %s\n", 0, 2, buf );
1945 MsiCloseHandle( rec );
1947 r = MsiViewFetch(view, &rec);
1948 ok( r == ERROR_SUCCESS, "failed to fetch view: %d\n", r );
1951 r = MsiRecordGetString( rec, 1, buf, &size );
1952 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r );
1953 ok( !lstrcmp( buf, "3" ),
1954 "For (row %d, column 1) expected '%d', got %s\n", 1, 3, buf );
1955 MsiCloseHandle( rec );
1957 r = MsiViewFetch(view, &rec);
1958 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r );
1961 MsiCloseHandle(view);
1963 MsiCloseHandle( rec );
1966 query = "SELECT * FROM `Media` WHERE `DiskPrompt` IS NULL";
1967 r = do_query(hdb, query, &rec);
1968 ok( r == ERROR_SUCCESS, "query failed: %d\n", r );
1969 MsiCloseHandle( rec );
1972 query = "SELECT * FROM `Media` WHERE `DiskPrompt` < 'Cabinet'";
1973 r = do_query(hdb, query, &rec);
1974 ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %d\n", r );
1975 MsiCloseHandle( rec );
1978 query = "SELECT * FROM `Media` WHERE `DiskPrompt` > 'Cabinet'";
1979 r = do_query(hdb, query, &rec);
1980 ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %d\n", r );
1981 MsiCloseHandle( rec );
1984 query = "SELECT * FROM `Media` WHERE `DiskPrompt` <> 'Cabinet'";
1985 r = do_query(hdb, query, &rec);
1986 ok( r == ERROR_SUCCESS, "query failed: %d\n", r );
1987 MsiCloseHandle( rec );
1990 query = "SELECT * FROM `Media` WHERE `DiskPrompt` = 'Cabinet'";
1991 r = do_query(hdb, query, &rec);
1992 ok( r == ERROR_NO_MORE_ITEMS, "query failed: %d\n", r );
1993 MsiCloseHandle( rec );
1995 rec = MsiCreateRecord(1);
1996 MsiRecordSetString(rec, 1, "");
1998 query = "SELECT * FROM `Media` WHERE `DiskPrompt` = ?";
1999 r = MsiDatabaseOpenView(hdb, query, &view);
2000 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2001 r = MsiViewExecute(view, rec);
2002 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2004 MsiCloseHandle(rec);
2006 r = MsiViewFetch(view, &rec);
2007 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2009 MsiCloseHandle(rec);
2011 MsiCloseHandle(view);
2013 MsiCloseHandle( hdb );
2014 DeleteFile(msifile);
2017 static CHAR CURR_DIR[MAX_PATH];
2019 static const CHAR test_data[] = "FirstPrimaryColumn\tSecondPrimaryColumn\tShortInt\tShortIntNullable\tLongInt\tLongIntNullable\tString\tLocalizableString\tLocalizableStringNullable\n"
2020 "s255\ti2\ti2\tI2\ti4\tI4\tS255\tS0\ts0\n"
2021 "TestTable\tFirstPrimaryColumn\n"
2022 "stringage\t5\t2\t\t2147483640\t-2147483640\tanother string\tlocalizable\tduh\n";
2024 static const CHAR two_primary[] = "PrimaryOne\tPrimaryTwo\n"
2026 "TwoPrimary\tPrimaryOne\tPrimaryTwo\n"
2030 static const CHAR endlines1[] = "A\tB\tC\tD\tE\tF\r\n"
2031 "s72\ts72\ts72\ts72\ts72\ts72\n"
2033 "a\tb\tc\td\te\tf\n"
2034 "g\th\ti\t\rj\tk\tl\r\n";
2036 static const CHAR endlines2[] = "A\tB\tC\tD\tE\tF\r"
2037 "s72\ts72\ts72\ts72\ts72\ts72\n"
2039 "a\tb\tc\td\te\tf\n"
2040 "g\th\ti\tj\tk\tl\r\n";
2042 static const CHAR suminfo[] = "PropertyId\tValue\n"
2044 "_SummaryInformation\tPropertyId\n"
2046 "2\tInstaller Database\n"
2047 "3\tInstaller description\n"
2050 "6\tInstaller comments\n"
2051 "7\tIntel;1033,2057\n"
2052 "9\t{12345678-1234-1234-1234-123456789012}\n"
2053 "12\t2009/04/12 15:46:11\n"
2054 "13\t2009/04/12 15:46:11\n"
2060 static void write_file(const CHAR *filename, const char *data, int data_size)
2064 HANDLE hf = CreateFile(filename, GENERIC_WRITE, 0, NULL,
2065 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
2067 WriteFile(hf, data, data_size, &size, NULL);
2071 static UINT add_table_to_db(MSIHANDLE hdb, LPCSTR table_data)
2075 write_file("temp_file", table_data, (lstrlen(table_data) - 1) * sizeof(char));
2076 r = MsiDatabaseImportA(hdb, CURR_DIR, "temp_file");
2077 DeleteFileA("temp_file");
2082 static void test_suminfo_import(void)
2084 MSIHANDLE hdb, hsi, view = 0;
2086 UINT r, count, size, type;
2091 GetCurrentDirectoryA(MAX_PATH, CURR_DIR);
2093 r = MsiOpenDatabaseA(msifile, MSIDBOPEN_CREATE, &hdb);
2094 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2096 r = add_table_to_db(hdb, suminfo);
2097 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2099 /* _SummaryInformation is not imported as a regular table... */
2101 query = "SELECT * FROM `_SummaryInformation`";
2102 r = MsiDatabaseOpenViewA(hdb, query, &view);
2103 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %u\n", r);
2104 MsiCloseHandle(view);
2106 /* ...its data is added to the special summary information stream */
2108 r = MsiGetSummaryInformationA(hdb, NULL, 0, &hsi);
2109 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2111 r = MsiSummaryInfoGetPropertyCount(hsi, &count);
2112 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2113 ok(count == 14, "Expected 14, got %u\n", count);
2115 r = MsiSummaryInfoGetPropertyA(hsi, PID_CODEPAGE, &type, &int_value, NULL, NULL, NULL);
2116 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2117 ok(type == VT_I2, "Expected VT_I2, got %u\n", type);
2118 ok(int_value == 1252, "Expected 1252, got %d\n", int_value);
2120 size = sizeof(str_value);
2121 r = MsiSummaryInfoGetPropertyA(hsi, PID_TITLE, &type, NULL, NULL, str_value, &size);
2122 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2123 ok(type == VT_LPSTR, "Expected VT_LPSTR, got %u\n", type);
2124 ok(size == 18, "Expected 18, got %u\n", size);
2125 ok(!strcmp(str_value, "Installer Database"),
2126 "Expected \"Installer Database\", got %s\n", str_value);
2128 size = sizeof(str_value);
2129 r = MsiSummaryInfoGetPropertyA(hsi, PID_SUBJECT, &type, NULL, NULL, str_value, &size);
2130 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2131 ok(type == VT_LPSTR, "Expected VT_LPSTR, got %u\n", type);
2132 ok(!strcmp(str_value, "Installer description"),
2133 "Expected \"Installer description\", got %s\n", str_value);
2135 size = sizeof(str_value);
2136 r = MsiSummaryInfoGetPropertyA(hsi, PID_AUTHOR, &type, NULL, NULL, str_value, &size);
2137 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2138 ok(type == VT_LPSTR, "Expected VT_LPSTR, got %u\n", type);
2139 ok(!strcmp(str_value, "WineHQ"),
2140 "Expected \"WineHQ\", got %s\n", str_value);
2142 size = sizeof(str_value);
2143 r = MsiSummaryInfoGetPropertyA(hsi, PID_KEYWORDS, &type, NULL, NULL, str_value, &size);
2144 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2145 ok(type == VT_LPSTR, "Expected VT_LPSTR, got %u\n", type);
2146 ok(!strcmp(str_value, "Installer"),
2147 "Expected \"Installer\", got %s\n", str_value);
2149 size = sizeof(str_value);
2150 r = MsiSummaryInfoGetPropertyA(hsi, PID_COMMENTS, &type, NULL, NULL, str_value, &size);
2151 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2152 ok(type == VT_LPSTR, "Expected VT_LPSTR, got %u\n", type);
2153 ok(!strcmp(str_value, "Installer comments"),
2154 "Expected \"Installer comments\", got %s\n", str_value);
2156 size = sizeof(str_value);
2157 r = MsiSummaryInfoGetPropertyA(hsi, PID_TEMPLATE, &type, NULL, NULL, str_value, &size);
2158 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2159 ok(type == VT_LPSTR, "Expected VT_LPSTR, got %u\n", type);
2160 ok(!strcmp(str_value, "Intel;1033,2057"),
2161 "Expected \"Intel;1033,2057\", got %s\n", str_value);
2163 size = sizeof(str_value);
2164 r = MsiSummaryInfoGetPropertyA(hsi, PID_REVNUMBER, &type, NULL, NULL, str_value, &size);
2165 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2166 ok(type == VT_LPSTR, "Expected VT_LPSTR, got %u\n", type);
2167 ok(!strcmp(str_value, "{12345678-1234-1234-1234-123456789012}"),
2168 "Expected \"{12345678-1234-1234-1234-123456789012}\", got %s\n", str_value);
2170 r = MsiSummaryInfoGetPropertyA(hsi, PID_CREATE_DTM, &type, NULL, &ft_value, NULL, NULL);
2171 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2172 ok(type == VT_FILETIME, "Expected VT_FILETIME, got %u\n", type);
2174 r = MsiSummaryInfoGetPropertyA(hsi, PID_LASTSAVE_DTM, &type, NULL, &ft_value, NULL, NULL);
2175 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2176 ok(type == VT_FILETIME, "Expected VT_FILETIME, got %u\n", type);
2178 r = MsiSummaryInfoGetPropertyA(hsi, PID_PAGECOUNT, &type, &int_value, NULL, NULL, NULL);
2179 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2180 ok(type == VT_I4, "Expected VT_I4, got %u\n", type);
2181 ok(int_value == 200, "Expected 200, got %d\n", int_value);
2183 r = MsiSummaryInfoGetPropertyA(hsi, PID_WORDCOUNT, &type, &int_value, NULL, NULL, NULL);
2184 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2185 ok(type == VT_I4, "Expected VT_I4, got %u\n", type);
2186 ok(int_value == 2, "Expected 2, got %d\n", int_value);
2188 r = MsiSummaryInfoGetPropertyA(hsi, PID_SECURITY, &type, &int_value, NULL, NULL, NULL);
2189 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2190 ok(type == VT_I4, "Expected VT_I4, got %u\n", type);
2191 ok(int_value == 2, "Expected 2, got %d\n", int_value);
2193 size = sizeof(str_value);
2194 r = MsiSummaryInfoGetPropertyA(hsi, PID_APPNAME, &type, NULL, NULL, str_value, &size);
2195 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2196 ok(type == VT_LPSTR, "Expected VT_LPSTR, got %u\n", type);
2197 ok(!strcmp(str_value, "Vim"), "Expected \"Vim\", got %s\n", str_value);
2199 MsiCloseHandle(hsi);
2200 MsiCloseHandle(hdb);
2201 DeleteFileA(msifile);
2204 static void test_msiimport(void)
2206 MSIHANDLE hdb, view, rec;
2211 GetCurrentDirectoryA(MAX_PATH, CURR_DIR);
2213 r = MsiOpenDatabaseA(msifile, MSIDBOPEN_CREATE, &hdb);
2214 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2216 r = add_table_to_db(hdb, test_data);
2217 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2219 r = add_table_to_db(hdb, two_primary);
2220 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2222 r = add_table_to_db(hdb, endlines1);
2223 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2225 r = add_table_to_db(hdb, endlines2);
2226 ok(r == ERROR_FUNCTION_FAILED, "Expected ERROR_FUNCTION_FAILED, got %d\n", r);
2228 query = "SELECT * FROM `TestTable`";
2229 r = MsiDatabaseOpenView(hdb, query, &view);
2230 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2232 r = MsiViewGetColumnInfo(view, MSICOLINFO_NAMES, &rec);
2233 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2234 count = MsiRecordGetFieldCount(rec);
2235 ok(count == 9, "Expected 9, got %d\n", count);
2236 ok(check_record(rec, 1, "FirstPrimaryColumn"), "Expected FirstPrimaryColumn\n");
2237 ok(check_record(rec, 2, "SecondPrimaryColumn"), "Expected SecondPrimaryColumn\n");
2238 ok(check_record(rec, 3, "ShortInt"), "Expected ShortInt\n");
2239 ok(check_record(rec, 4, "ShortIntNullable"), "Expected ShortIntNullalble\n");
2240 ok(check_record(rec, 5, "LongInt"), "Expected LongInt\n");
2241 ok(check_record(rec, 6, "LongIntNullable"), "Expected LongIntNullalble\n");
2242 ok(check_record(rec, 7, "String"), "Expected String\n");
2243 ok(check_record(rec, 8, "LocalizableString"), "Expected LocalizableString\n");
2244 ok(check_record(rec, 9, "LocalizableStringNullable"), "Expected LocalizableStringNullable\n");
2245 MsiCloseHandle(rec);
2247 r = MsiViewGetColumnInfo(view, MSICOLINFO_TYPES, &rec);
2248 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2249 count = MsiRecordGetFieldCount(rec);
2250 ok(count == 9, "Expected 9, got %d\n", count);
2251 ok(check_record(rec, 1, "s255"), "Expected s255\n");
2252 ok(check_record(rec, 2, "i2"), "Expected i2\n");
2253 ok(check_record(rec, 3, "i2"), "Expected i2\n");
2254 ok(check_record(rec, 4, "I2"), "Expected I2\n");
2255 ok(check_record(rec, 5, "i4"), "Expected i4\n");
2256 ok(check_record(rec, 6, "I4"), "Expected I4\n");
2257 ok(check_record(rec, 7, "S255"), "Expected S255\n");
2258 ok(check_record(rec, 8, "S0"), "Expected S0\n");
2259 ok(check_record(rec, 9, "s0"), "Expected s0\n");
2260 MsiCloseHandle(rec);
2262 query = "SELECT * FROM `TestTable`";
2263 r = do_query(hdb, query, &rec);
2264 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2265 ok(check_record(rec, 1, "stringage"), "Expected 'stringage'\n");
2266 ok(check_record(rec, 7, "another string"), "Expected 'another string'\n");
2267 ok(check_record(rec, 8, "localizable"), "Expected 'localizable'\n");
2268 ok(check_record(rec, 9, "duh"), "Expected 'duh'\n");
2270 i = MsiRecordGetInteger(rec, 2);
2271 ok(i == 5, "Expected 5, got %d\n", i);
2273 i = MsiRecordGetInteger(rec, 3);
2274 ok(i == 2, "Expected 2, got %d\n", i);
2276 i = MsiRecordGetInteger(rec, 4);
2277 ok(i == MSI_NULL_INTEGER, "Expected MSI_NULL_INTEGER, got %d\n", i);
2279 i = MsiRecordGetInteger(rec, 5);
2280 ok(i == 2147483640, "Expected 2147483640, got %d\n", i);
2282 i = MsiRecordGetInteger(rec, 6);
2283 ok(i == -2147483640, "Expected -2147483640, got %d\n", i);
2285 MsiCloseHandle(rec);
2287 MsiCloseHandle(view);
2289 query = "SELECT * FROM `TwoPrimary`";
2290 r = MsiDatabaseOpenView(hdb, query, &view);
2291 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2293 r = MsiViewGetColumnInfo(view, MSICOLINFO_NAMES, &rec);
2294 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2295 count = MsiRecordGetFieldCount(rec);
2296 ok(count == 2, "Expected 2, got %d\n", count);
2297 ok(check_record(rec, 1, "PrimaryOne"), "Expected PrimaryOne\n");
2298 ok(check_record(rec, 2, "PrimaryTwo"), "Expected PrimaryTwo\n");
2300 MsiCloseHandle(rec);
2302 r = MsiViewGetColumnInfo(view, MSICOLINFO_TYPES, &rec);
2303 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2304 count = MsiRecordGetFieldCount(rec);
2305 ok(count == 2, "Expected 2, got %d\n", count);
2306 ok(check_record(rec, 1, "s255"), "Expected s255\n");
2307 ok(check_record(rec, 2, "s255"), "Expected s255\n");
2308 MsiCloseHandle(rec);
2310 r = MsiViewExecute(view, 0);
2311 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2313 r = MsiViewFetch(view, &rec);
2314 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2316 ok(check_record(rec, 1, "papaya"), "Expected 'papaya'\n");
2317 ok(check_record(rec, 2, "leaf"), "Expected 'leaf'\n");
2319 MsiCloseHandle(rec);
2321 r = MsiViewFetch(view, &rec);
2322 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2324 ok(check_record(rec, 1, "papaya"), "Expected 'papaya'\n");
2325 ok(check_record(rec, 2, "flower"), "Expected 'flower'\n");
2327 MsiCloseHandle(rec);
2329 r = MsiViewFetch(view, &rec);
2330 ok(r == ERROR_NO_MORE_ITEMS,
2331 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
2333 r = MsiViewClose(view);
2334 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2336 MsiCloseHandle(view);
2338 query = "SELECT * FROM `Table`";
2339 r = MsiDatabaseOpenView(hdb, query, &view);
2340 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2342 r = MsiViewGetColumnInfo(view, MSICOLINFO_NAMES, &rec);
2343 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2344 count = MsiRecordGetFieldCount(rec);
2345 ok(count == 6, "Expected 6, got %d\n", count);
2346 ok(check_record(rec, 1, "A"), "Expected A\n");
2347 ok(check_record(rec, 2, "B"), "Expected B\n");
2348 ok(check_record(rec, 3, "C"), "Expected C\n");
2349 ok(check_record(rec, 4, "D"), "Expected D\n");
2350 ok(check_record(rec, 5, "E"), "Expected E\n");
2351 ok(check_record(rec, 6, "F"), "Expected F\n");
2352 MsiCloseHandle(rec);
2354 r = MsiViewGetColumnInfo(view, MSICOLINFO_TYPES, &rec);
2355 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2356 count = MsiRecordGetFieldCount(rec);
2357 ok(count == 6, "Expected 6, got %d\n", count);
2358 ok(check_record(rec, 1, "s72"), "Expected s72\n");
2359 ok(check_record(rec, 2, "s72"), "Expected s72\n");
2360 ok(check_record(rec, 3, "s72"), "Expected s72\n");
2361 ok(check_record(rec, 4, "s72"), "Expected s72\n");
2362 ok(check_record(rec, 5, "s72"), "Expected s72\n");
2363 ok(check_record(rec, 6, "s72"), "Expected s72\n");
2364 MsiCloseHandle(rec);
2367 MsiCloseHandle(view);
2369 query = "SELECT * FROM `Table`";
2370 r = MsiDatabaseOpenView(hdb, query, &view);
2371 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2373 r = MsiViewExecute(view, 0);
2374 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2376 r = MsiViewFetch(view, &rec);
2377 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2378 ok(check_record(rec, 1, "a"), "Expected 'a'\n");
2379 ok(check_record(rec, 2, "b"), "Expected 'b'\n");
2380 ok(check_record(rec, 3, "c"), "Expected 'c'\n");
2381 ok(check_record(rec, 4, "d"), "Expected 'd'\n");
2382 ok(check_record(rec, 5, "e"), "Expected 'e'\n");
2383 ok(check_record(rec, 6, "f"), "Expected 'f'\n");
2385 MsiCloseHandle(rec);
2387 r = MsiViewFetch(view, &rec);
2388 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2389 ok(check_record(rec, 1, "g"), "Expected 'g'\n");
2390 ok(check_record(rec, 2, "h"), "Expected 'h'\n");
2391 ok(check_record(rec, 3, "i"), "Expected 'i'\n");
2392 ok(check_record(rec, 4, "j"), "Expected 'j'\n");
2393 ok(check_record(rec, 5, "k"), "Expected 'k'\n");
2394 ok(check_record(rec, 6, "l"), "Expected 'l'\n");
2396 MsiCloseHandle(rec);
2398 r = MsiViewFetch(view, &rec);
2399 ok(r == ERROR_NO_MORE_ITEMS,
2400 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
2403 MsiCloseHandle(view);
2404 MsiCloseHandle(hdb);
2405 DeleteFileA(msifile);
2408 static const CHAR bin_import_dat[] = "Name\tData\r\n"
2411 "filename1\tfilename1.ibd\r\n";
2413 static void test_binary_import(void)
2415 MSIHANDLE hdb = 0, rec;
2416 char file[MAX_PATH];
2418 char path[MAX_PATH];
2423 /* create files to import */
2424 write_file("bin_import.idt", bin_import_dat,
2425 (sizeof(bin_import_dat) - 1) * sizeof(char));
2426 CreateDirectory("bin_import", NULL);
2427 create_file_data("bin_import/filename1.ibd", "just some words", 15);
2429 /* import files into database */
2430 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
2431 ok( r == ERROR_SUCCESS , "Failed to open database\n");
2433 GetCurrentDirectory(MAX_PATH, path);
2434 r = MsiDatabaseImport(hdb, path, "bin_import.idt");
2435 ok(r == ERROR_SUCCESS , "Failed to import Binary table\n");
2437 /* read file from the Binary table */
2438 query = "SELECT * FROM `Binary`";
2439 r = do_query(hdb, query, &rec);
2440 ok(r == ERROR_SUCCESS, "SELECT query failed: %d\n", r);
2443 r = MsiRecordGetString(rec, 1, file, &size);
2444 ok(r == ERROR_SUCCESS, "Failed to get string: %d\n", r);
2445 ok(!lstrcmp(file, "filename1"), "Expected 'filename1', got %s\n", file);
2448 memset(buf, 0, MAX_PATH);
2449 r = MsiRecordReadStream(rec, 2, buf, &size);
2450 ok(r == ERROR_SUCCESS, "Failed to get stream: %d\n", r);
2451 ok(!lstrcmp(buf, "just some words"),
2452 "Expected 'just some words', got %s\n", buf);
2454 r = MsiCloseHandle(rec);
2455 ok(r == ERROR_SUCCESS , "Failed to close record handle\n");
2457 r = MsiCloseHandle(hdb);
2458 ok(r == ERROR_SUCCESS , "Failed to close database\n");
2460 DeleteFile("bin_import/filename1.ibd");
2461 RemoveDirectory("bin_import");
2462 DeleteFile("bin_import.idt");
2465 static void test_markers(void)
2472 ok( hdb, "failed to create db\n");
2474 rec = MsiCreateRecord(3);
2475 MsiRecordSetString(rec, 1, "Table");
2476 MsiRecordSetString(rec, 2, "Apples");
2477 MsiRecordSetString(rec, 3, "Oranges");
2479 /* try a legit create */
2480 query = "CREATE TABLE `Table` ( `One` SHORT NOT NULL, `Two` CHAR(255) PRIMARY KEY `One`)";
2481 r = run_query(hdb, 0, query);
2482 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2483 MsiCloseHandle(rec);
2485 /* try table name as marker */
2486 rec = MsiCreateRecord(1);
2487 MsiRecordSetString(rec, 1, "Fable");
2488 query = "CREATE TABLE `?` ( `One` SHORT NOT NULL, `Two` CHAR(255) PRIMARY KEY `One`)";
2489 r = run_query(hdb, rec, query);
2490 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2492 /* verify that we just created a table called '?', not 'Fable' */
2493 r = try_query(hdb, "SELECT * from `Fable`");
2494 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
2496 r = try_query(hdb, "SELECT * from `?`");
2497 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2499 /* try table name as marker without backticks */
2500 MsiRecordSetString(rec, 1, "Mable");
2501 query = "CREATE TABLE ? ( `One` SHORT NOT NULL, `Two` CHAR(255) PRIMARY KEY `One`)";
2502 r = run_query(hdb, rec, query);
2503 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
2505 /* try one column name as marker */
2506 MsiRecordSetString(rec, 1, "One");
2507 query = "CREATE TABLE `Mable` ( `?` SHORT NOT NULL, `Two` CHAR(255) PRIMARY KEY `One`)";
2508 r = run_query(hdb, rec, query);
2509 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
2510 MsiCloseHandle(rec);
2512 /* try column names as markers */
2513 rec = MsiCreateRecord(2);
2514 MsiRecordSetString(rec, 1, "One");
2515 MsiRecordSetString(rec, 2, "Two");
2516 query = "CREATE TABLE `Mable` ( `?` SHORT NOT NULL, `?` CHAR(255) PRIMARY KEY `One`)";
2517 r = run_query(hdb, rec, query);
2518 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
2519 MsiCloseHandle(rec);
2521 /* try names with backticks */
2522 rec = MsiCreateRecord(3);
2523 MsiRecordSetString(rec, 1, "One");
2524 MsiRecordSetString(rec, 2, "Two");
2525 MsiRecordSetString(rec, 3, "One");
2526 query = "CREATE TABLE `Mable` ( `?` SHORT NOT NULL, `?` CHAR(255) PRIMARY KEY `?`)";
2527 r = run_query(hdb, rec, query);
2528 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
2530 /* try names with backticks, minus definitions */
2531 query = "CREATE TABLE `Mable` ( `?`, `?` PRIMARY KEY `?`)";
2532 r = run_query(hdb, rec, query);
2533 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
2535 /* try names without backticks */
2536 query = "CREATE TABLE `Mable` ( ? SHORT NOT NULL, ? CHAR(255) PRIMARY KEY ?)";
2537 r = run_query(hdb, rec, query);
2538 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
2539 MsiCloseHandle(rec);
2541 /* try one long marker */
2542 rec = MsiCreateRecord(1);
2543 MsiRecordSetString(rec, 1, "`One` SHORT NOT NULL, `Two` CHAR(255) PRIMARY KEY `One`");
2544 query = "CREATE TABLE `Mable` ( ? )";
2545 r = run_query(hdb, rec, query);
2546 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
2547 MsiCloseHandle(rec);
2549 /* try all names as markers */
2550 rec = MsiCreateRecord(4);
2551 MsiRecordSetString(rec, 1, "Mable");
2552 MsiRecordSetString(rec, 2, "One");
2553 MsiRecordSetString(rec, 3, "Two");
2554 MsiRecordSetString(rec, 4, "One");
2555 query = "CREATE TABLE `?` ( `?` SHORT NOT NULL, `?` CHAR(255) PRIMARY KEY `?`)";
2556 r = run_query(hdb, rec, query);
2557 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
2558 MsiCloseHandle(rec);
2560 /* try a legit insert */
2561 query = "INSERT INTO `Table` ( `One`, `Two` ) VALUES ( 5, 'hello' )";
2562 r = run_query(hdb, 0, query);
2563 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2565 r = try_query(hdb, "SELECT * from `Table`");
2566 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2568 /* try values as markers */
2569 rec = MsiCreateRecord(2);
2570 MsiRecordSetInteger(rec, 1, 4);
2571 MsiRecordSetString(rec, 2, "hi");
2572 query = "INSERT INTO `Table` ( `One`, `Two` ) VALUES ( ?, '?' )";
2573 r = run_query(hdb, rec, query);
2574 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2575 MsiCloseHandle(rec);
2577 /* try column names and values as markers */
2578 rec = MsiCreateRecord(4);
2579 MsiRecordSetString(rec, 1, "One");
2580 MsiRecordSetString(rec, 2, "Two");
2581 MsiRecordSetInteger(rec, 3, 5);
2582 MsiRecordSetString(rec, 4, "hi");
2583 query = "INSERT INTO `Table` ( `?`, `?` ) VALUES ( ?, '?' )";
2584 r = run_query(hdb, rec, query);
2585 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
2586 MsiCloseHandle(rec);
2588 /* try column names as markers */
2589 rec = MsiCreateRecord(2);
2590 MsiRecordSetString(rec, 1, "One");
2591 MsiRecordSetString(rec, 2, "Two");
2592 query = "INSERT INTO `Table` ( `?`, `?` ) VALUES ( 3, 'yellow' )";
2593 r = run_query(hdb, rec, query);
2594 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
2595 MsiCloseHandle(rec);
2597 /* try table name as a marker */
2598 rec = MsiCreateRecord(1);
2599 MsiRecordSetString(rec, 1, "Table");
2600 query = "INSERT INTO `?` ( `One`, `Two` ) VALUES ( 2, 'green' )";
2601 r = run_query(hdb, rec, query);
2602 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2603 MsiCloseHandle(rec);
2605 /* try table name and values as markers */
2606 rec = MsiCreateRecord(3);
2607 MsiRecordSetString(rec, 1, "Table");
2608 MsiRecordSetInteger(rec, 2, 10);
2609 MsiRecordSetString(rec, 3, "haha");
2610 query = "INSERT INTO `?` ( `One`, `Two` ) VALUES ( ?, '?' )";
2611 r = run_query(hdb, rec, query);
2612 ok(r == ERROR_FUNCTION_FAILED, "Expected ERROR_FUNCTION_FAILED, got %d\n", r);
2613 MsiCloseHandle(rec);
2615 /* try all markers */
2616 rec = MsiCreateRecord(5);
2617 MsiRecordSetString(rec, 1, "Table");
2618 MsiRecordSetString(rec, 1, "One");
2619 MsiRecordSetString(rec, 1, "Two");
2620 MsiRecordSetInteger(rec, 2, 10);
2621 MsiRecordSetString(rec, 3, "haha");
2622 query = "INSERT INTO `?` ( `?`, `?` ) VALUES ( ?, '?' )";
2623 r = run_query(hdb, rec, query);
2624 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
2625 MsiCloseHandle(rec);
2627 /* insert an integer as a string */
2628 rec = MsiCreateRecord(2);
2629 MsiRecordSetString(rec, 1, "11");
2630 MsiRecordSetString(rec, 2, "hi");
2631 query = "INSERT INTO `Table` ( `One`, `Two` ) VALUES ( ?, '?' )";
2632 r = run_query(hdb, rec, query);
2633 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2634 MsiCloseHandle(rec);
2636 /* leave off the '' for the string */
2637 rec = MsiCreateRecord(2);
2638 MsiRecordSetInteger(rec, 1, 12);
2639 MsiRecordSetString(rec, 2, "hi");
2640 query = "INSERT INTO `Table` ( `One`, `Two` ) VALUES ( ?, ? )";
2641 r = run_query(hdb, rec, query);
2642 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2643 MsiCloseHandle(rec);
2645 MsiCloseHandle(hdb);
2646 DeleteFileA(msifile);
2649 #define MY_NVIEWS 4000 /* Largest installer I've seen uses < 2k */
2650 static void test_handle_limit(void)
2654 MSIHANDLE hviews[MY_NVIEWS];
2657 /* create an empty db */
2659 ok( hdb, "failed to create db\n");
2661 memset(hviews, 0, sizeof(hviews));
2663 for (i=0; i<MY_NVIEWS; i++) {
2664 static char szQueryBuf[256] = "SELECT * from `_Tables`";
2665 hviews[i] = 0xdeadbeeb;
2666 r = MsiDatabaseOpenView(hdb, szQueryBuf, &hviews[i]);
2667 if( r != ERROR_SUCCESS || hviews[i] == 0xdeadbeeb ||
2668 hviews[i] == 0 || (i && (hviews[i] == hviews[i-1])))
2672 ok( i == MY_NVIEWS, "problem opening views\n");
2674 for (i=0; i<MY_NVIEWS; i++) {
2675 if (hviews[i] != 0 && hviews[i] != 0xdeadbeeb) {
2676 MsiViewClose(hviews[i]);
2677 r = MsiCloseHandle(hviews[i]);
2678 if (r != ERROR_SUCCESS)
2683 ok( i == MY_NVIEWS, "problem closing views\n");
2685 r = MsiCloseHandle(hdb);
2686 ok( r == ERROR_SUCCESS, "failed to close database\n");
2689 static void generate_transform(void)
2691 MSIHANDLE hdb1, hdb2, hrec;
2695 /* start with two identical databases */
2696 CopyFile(msifile2, msifile, FALSE);
2698 r = MsiOpenDatabase(msifile, MSIDBOPEN_TRANSACT, &hdb1 );
2699 ok( r == ERROR_SUCCESS , "Failed to create database\n" );
2701 r = MsiDatabaseCommit( hdb1 );
2702 ok( r == ERROR_SUCCESS , "Failed to commit database\n" );
2704 r = MsiOpenDatabase(msifile2, MSIDBOPEN_READONLY, &hdb2 );
2705 ok( r == ERROR_SUCCESS , "Failed to create database\n" );
2707 /* the transform between two identical database should be empty */
2708 r = MsiDatabaseGenerateTransform(hdb1, hdb2, NULL, 0, 0);
2710 ok( r == ERROR_NO_DATA, "return code %d, should be ERROR_NO_DATA\n", r );
2713 query = "CREATE TABLE `AAR` ( `BAR` SHORT NOT NULL, `CAR` CHAR(255) PRIMARY KEY `CAR`)";
2714 r = run_query(hdb1, 0, query);
2715 ok(r == ERROR_SUCCESS, "failed to add table\n");
2717 query = "INSERT INTO `AAR` ( `BAR`, `CAR` ) VALUES ( 1, 'vw' )";
2718 r = run_query(hdb1, 0, query);
2719 ok(r == ERROR_SUCCESS, "failed to add row 1\n");
2721 query = "INSERT INTO `AAR` ( `BAR`, `CAR` ) VALUES ( 2, 'bmw' )";
2722 r = run_query(hdb1, 0, query);
2723 ok(r == ERROR_SUCCESS, "failed to add row 2\n");
2725 query = "UPDATE `MOO` SET `OOO` = 'c' WHERE `NOO` = 1";
2726 r = run_query(hdb1, 0, query);
2727 ok(r == ERROR_SUCCESS, "failed to modify row\n");
2729 query = "DELETE FROM `MOO` WHERE `NOO` = 3";
2730 r = run_query(hdb1, 0, query);
2731 ok(r == ERROR_SUCCESS, "failed to delete row\n");
2733 hrec = MsiCreateRecord(2);
2734 r = MsiRecordSetInteger(hrec, 1, 1);
2735 ok(r == ERROR_SUCCESS, "failed to set integer\n");
2737 write_file("testdata.bin", "naengmyon", 9);
2738 r = MsiRecordSetStream(hrec, 2, "testdata.bin");
2739 ok(r == ERROR_SUCCESS, "failed to set stream\n");
2741 query = "INSERT INTO `BINARY` ( `ID`, `BLOB` ) VALUES ( ?, ? )";
2742 r = run_query(hdb1, hrec, query);
2743 ok(r == ERROR_SUCCESS, "failed to add row with blob\n");
2745 MsiCloseHandle(hrec);
2747 query = "ALTER TABLE `MOO` ADD `COW` INTEGER";
2748 r = run_query(hdb1, 0, query);
2749 ok(r == ERROR_SUCCESS, "failed to add column\n");
2751 query = "ALTER TABLE `MOO` ADD `PIG` INTEGER";
2752 r = run_query(hdb1, 0, query);
2753 ok(r == ERROR_SUCCESS, "failed to add column\n");
2755 query = "UPDATE `MOO` SET `PIG` = 5 WHERE `NOO` = 1";
2756 r = run_query(hdb1, 0, query);
2757 ok(r == ERROR_SUCCESS, "failed to modify row\n");
2759 query = "CREATE TABLE `Property` ( `Property` CHAR(72) NOT NULL, "
2760 "`Value` CHAR(0) PRIMARY KEY `Property`)";
2761 r = run_query(hdb1, 0, query);
2762 ok(r == ERROR_SUCCESS, "failed to add property table\n");
2764 query = "INSERT INTO `Property` ( `Property`, `Value` ) VALUES ( 'prop', 'val' )";
2765 r = run_query(hdb1, 0, query);
2766 ok(r == ERROR_SUCCESS, "failed to add property\n");
2768 /* database needs to be committed */
2769 MsiDatabaseCommit(hdb1);
2771 r = MsiDatabaseGenerateTransform(hdb1, hdb2, mstfile, 0, 0);
2772 ok( r == ERROR_SUCCESS, "return code %d, should be ERROR_SUCCESS\n", r );
2774 MsiCloseHandle( hdb1 );
2775 MsiCloseHandle( hdb2 );
2777 DeleteFile("testdata.bin");
2780 /* data for generating a transform */
2782 /* tables transform names - encoded as they would be in an msi database file */
2783 static const WCHAR name1[] = { 0x4840, 0x3a8a, 0x481b, 0 }; /* AAR */
2784 static const WCHAR name2[] = { 0x4840, 0x3b3f, 0x43f2, 0x4438, 0x45b1, 0 }; /* _Columns */
2785 static const WCHAR name3[] = { 0x4840, 0x3f7f, 0x4164, 0x422f, 0x4836, 0 }; /* _Tables */
2786 static const WCHAR name4[] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3b6a, 0x45e4, 0x4824, 0 }; /* _StringData */
2787 static const WCHAR name5[] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3e6a, 0x44b2, 0x482f, 0 }; /* _StringPool */
2788 static const WCHAR name6[] = { 0x4840, 0x3e16, 0x4818, 0}; /* MOO */
2789 static const WCHAR name7[] = { 0x4840, 0x3c8b, 0x3a97, 0x409b, 0 }; /* BINARY */
2790 static const WCHAR name8[] = { 0x3c8b, 0x3a97, 0x409b, 0x387e, 0 }; /* BINARY.1 */
2791 static const WCHAR name9[] = { 0x4840, 0x4559, 0x44f2, 0x4568, 0x4737, 0 }; /* Property */
2793 /* data in each table */
2794 static const WCHAR data1[] = { /* AAR */
2795 0x0201, 0x0008, 0x8001, /* 0x0201 = add row (1), two shorts */
2796 0x0201, 0x0009, 0x8002,
2798 static const WCHAR data2[] = { /* _Columns */
2799 0x0401, 0x0001, 0x8003, 0x0002, 0x9502,
2800 0x0401, 0x0001, 0x8004, 0x0003, 0x9502,
2801 0x0401, 0x0005, 0x0000, 0x0006, 0xbdff, /* 0x0401 = add row (1), 4 shorts */
2802 0x0401, 0x0005, 0x0000, 0x0007, 0x8502,
2803 0x0401, 0x000a, 0x0000, 0x000a, 0xad48,
2804 0x0401, 0x000a, 0x0000, 0x000b, 0x9d00,
2806 static const WCHAR data3[] = { /* _Tables */
2807 0x0101, 0x0005, /* 0x0101 = add row (1), 1 short */
2810 static const char data4[] = /* _StringData */
2811 "MOOCOWPIGcAARCARBARvwbmwPropertyValuepropval"; /* all the strings squashed together */
2812 static const WCHAR data5[] = { /* _StringPool */
2814 0, 0, /* string 0 '' */
2815 3, 2, /* string 1 'MOO' */
2816 3, 1, /* string 2 'COW' */
2817 3, 1, /* string 3 'PIG' */
2818 1, 1, /* string 4 'c' */
2819 3, 3, /* string 5 'AAR' */
2820 3, 1, /* string 6 'CAR' */
2821 3, 1, /* string 7 'BAR' */
2822 2, 1, /* string 8 'vw' */
2823 3, 1, /* string 9 'bmw' */
2824 8, 4, /* string 10 'Property' */
2825 5, 1, /* string 11 'Value' */
2826 4, 1, /* string 12 'prop' */
2827 3, 1, /* string 13 'val' */
2829 /* update row, 0x0002 is a bitmask of present column data, keys are excluded */
2830 static const WCHAR data6[] = { /* MOO */
2831 0x000a, 0x8001, 0x0004, 0x8005, /* update row */
2832 0x0000, 0x8003, /* delete row */
2835 static const WCHAR data7[] = { /* BINARY */
2836 0x0201, 0x8001, 0x0001,
2839 static const char data8[] = /* stream data for the BINARY table */
2842 static const WCHAR data9[] = { /* Property */
2843 0x0201, 0x000c, 0x000d,
2846 static const struct {
2850 } table_transform_data[] =
2852 { name1, data1, sizeof data1 },
2853 { name2, data2, sizeof data2 },
2854 { name3, data3, sizeof data3 },
2855 { name4, data4, sizeof data4 - 1 },
2856 { name5, data5, sizeof data5 },
2857 { name6, data6, sizeof data6 },
2858 { name7, data7, sizeof data7 },
2859 { name8, data8, sizeof data8 - 1 },
2860 { name9, data9, sizeof data9 },
2863 #define NUM_TRANSFORM_TABLES (sizeof table_transform_data/sizeof table_transform_data[0])
2865 static void generate_transform_manual(void)
2867 IStorage *stg = NULL;
2872 const DWORD mode = STGM_CREATE|STGM_READWRITE|STGM_DIRECT|STGM_SHARE_EXCLUSIVE;
2874 const CLSID CLSID_MsiTransform = { 0xc1082,0,0,{0xc0,0,0,0,0,0,0,0x46}};
2876 MultiByteToWideChar(CP_ACP, 0, mstfile, -1, name, 0x20);
2878 r = StgCreateDocfile(name, mode, 0, &stg);
2879 ok(r == S_OK, "failed to create storage\n");
2883 r = IStorage_SetClass( stg, &CLSID_MsiTransform );
2884 ok(r == S_OK, "failed to set storage type\n");
2886 for (i=0; i<NUM_TRANSFORM_TABLES; i++)
2888 r = IStorage_CreateStream( stg, table_transform_data[i].name,
2889 STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm );
2892 ok(0, "failed to create stream %08x\n", r);
2896 r = IStream_Write( stm, table_transform_data[i].data,
2897 table_transform_data[i].size, &count );
2898 if (FAILED(r) || count != table_transform_data[i].size)
2899 ok(0, "failed to write stream\n");
2900 IStream_Release(stm);
2903 IStorage_Release(stg);
2906 static UINT set_summary_info(MSIHANDLE hdb)
2911 /* build summary info */
2912 res = MsiGetSummaryInformation(hdb, NULL, 7, &suminfo);
2913 ok( res == ERROR_SUCCESS , "Failed to open summaryinfo\n" );
2915 res = MsiSummaryInfoSetProperty(suminfo,2, VT_LPSTR, 0,NULL,
2916 "Installation Database");
2917 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
2919 res = MsiSummaryInfoSetProperty(suminfo,3, VT_LPSTR, 0,NULL,
2920 "Installation Database");
2921 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
2923 res = MsiSummaryInfoSetProperty(suminfo,4, VT_LPSTR, 0,NULL,
2925 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
2927 res = MsiSummaryInfoSetProperty(suminfo,7, VT_LPSTR, 0,NULL,
2929 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
2931 res = MsiSummaryInfoSetProperty(suminfo,9, VT_LPSTR, 0,NULL,
2932 "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}");
2933 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
2935 res = MsiSummaryInfoSetProperty(suminfo, 14, VT_I4, 100, NULL, NULL);
2936 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
2938 res = MsiSummaryInfoSetProperty(suminfo, 15, VT_I4, 0, NULL, NULL);
2939 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
2941 res = MsiSummaryInfoPersist(suminfo);
2942 ok( res == ERROR_SUCCESS , "Failed to make summary info persist\n" );
2944 res = MsiCloseHandle( suminfo);
2945 ok( res == ERROR_SUCCESS , "Failed to close suminfo\n" );
2950 static MSIHANDLE create_package_db(LPCSTR filename)
2955 DeleteFile(msifile);
2957 /* create an empty database */
2958 res = MsiOpenDatabase(filename, MSIDBOPEN_CREATE, &hdb );
2959 ok( res == ERROR_SUCCESS , "Failed to create database\n" );
2960 if( res != ERROR_SUCCESS )
2963 res = MsiDatabaseCommit( hdb );
2964 ok( res == ERROR_SUCCESS , "Failed to commit database\n" );
2966 res = set_summary_info(hdb);
2967 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
2969 res = create_directory_table(hdb);
2970 ok( res == ERROR_SUCCESS , "Failed to create directory table\n" );
2975 static UINT package_from_db(MSIHANDLE hdb, MSIHANDLE *handle)
2981 sprintf(szPackage, "#%u", hdb);
2982 res = MsiOpenPackage(szPackage, &hPackage);
2983 if (res != ERROR_SUCCESS)
2986 res = MsiCloseHandle(hdb);
2987 if (res != ERROR_SUCCESS)
2989 MsiCloseHandle(hPackage);
2994 return ERROR_SUCCESS;
2997 static void test_try_transform(void)
2999 MSIHANDLE hdb, hview, hrec, hpkg = 0;
3003 char buffer[MAX_PATH];
3005 DeleteFile(msifile);
3006 DeleteFile(mstfile);
3008 /* create the database */
3009 hdb = create_package_db(msifile);
3010 ok(hdb, "Failed to create package db\n");
3012 query = "CREATE TABLE `MOO` ( `NOO` SHORT NOT NULL, `OOO` CHAR(255) PRIMARY KEY `NOO`)";
3013 r = run_query(hdb, 0, query);
3014 ok(r == ERROR_SUCCESS, "failed to add table\n");
3016 query = "INSERT INTO `MOO` ( `NOO`, `OOO` ) VALUES ( 1, 'a' )";
3017 r = run_query(hdb, 0, query);
3018 ok(r == ERROR_SUCCESS, "failed to add row\n");
3020 query = "INSERT INTO `MOO` ( `NOO`, `OOO` ) VALUES ( 2, 'b' )";
3021 r = run_query(hdb, 0, query);
3022 ok(r == ERROR_SUCCESS, "failed to add row\n");
3024 query = "INSERT INTO `MOO` ( `NOO`, `OOO` ) VALUES ( 3, 'c' )";
3025 r = run_query(hdb, 0, query);
3026 ok(r == ERROR_SUCCESS, "failed to add row\n");
3028 query = "CREATE TABLE `BINARY` ( `ID` SHORT NOT NULL, `BLOB` OBJECT PRIMARY KEY `ID`)";
3029 r = run_query(hdb, 0, query);
3030 ok(r == ERROR_SUCCESS, "failed to add table\n");
3032 hrec = MsiCreateRecord(2);
3033 r = MsiRecordSetInteger(hrec, 1, 2);
3034 ok(r == ERROR_SUCCESS, "failed to set integer\n");
3036 write_file("testdata.bin", "lamyon", 6);
3037 r = MsiRecordSetStream(hrec, 2, "testdata.bin");
3038 ok(r == ERROR_SUCCESS, "failed to set stream\n");
3040 query = "INSERT INTO `BINARY` ( `ID`, `BLOB` ) VALUES ( ?, ? )";
3041 r = run_query(hdb, hrec, query);
3042 ok(r == ERROR_SUCCESS, "failed to add row with blob\n");
3044 MsiCloseHandle(hrec);
3046 r = MsiDatabaseCommit( hdb );
3047 ok( r == ERROR_SUCCESS , "Failed to commit database\n" );
3049 MsiCloseHandle( hdb );
3050 DeleteFileA("testdata.bin");
3053 * Both these generate an equivalent transform,
3054 * but the first doesn't work in Wine yet
3055 * because MsiDatabaseGenerateTransform is unimplemented.
3058 generate_transform();
3060 generate_transform_manual();
3062 r = MsiOpenDatabase(msifile, MSIDBOPEN_DIRECT, &hdb );
3063 ok( r == ERROR_SUCCESS , "Failed to create database\n" );
3065 r = MsiDatabaseApplyTransform( hdb, mstfile, 0 );
3066 ok( r == ERROR_SUCCESS, "return code %d, should be ERROR_SUCCESS\n", r );
3068 MsiDatabaseCommit( hdb );
3070 /* check new values */
3072 query = "select `BAR`,`CAR` from `AAR` where `BAR` = 1 AND `CAR` = 'vw'";
3073 r = do_query(hdb, query, &hrec);
3074 ok(r == ERROR_SUCCESS, "select query failed\n");
3075 MsiCloseHandle(hrec);
3077 query = "select `BAR`,`CAR` from `AAR` where `BAR` = 2 AND `CAR` = 'bmw'";
3079 r = do_query(hdb, query, &hrec);
3080 ok(r == ERROR_SUCCESS, "select query failed\n");
3081 MsiCloseHandle(hrec);
3083 /* check updated values */
3085 query = "select `NOO`,`OOO` from `MOO` where `NOO` = 1 AND `OOO` = 'c'";
3086 r = do_query(hdb, query, &hrec);
3087 ok(r == ERROR_SUCCESS, "select query failed\n");
3088 MsiCloseHandle(hrec);
3090 /* check unchanged value */
3092 query = "select `NOO`,`OOO` from `MOO` where `NOO` = 2 AND `OOO` = 'b'";
3093 r = do_query(hdb, query, &hrec);
3094 ok(r == ERROR_SUCCESS, "select query failed\n");
3095 MsiCloseHandle(hrec);
3097 /* check deleted value */
3099 query = "select * from `MOO` where `NOO` = 3";
3100 r = do_query(hdb, query, &hrec);
3101 ok(r == ERROR_NO_MORE_ITEMS, "select query failed\n");
3102 if (hrec) MsiCloseHandle(hrec);
3104 /* check added stream */
3106 query = "select `BLOB` from `BINARY` where `ID` = 1";
3107 r = do_query(hdb, query, &hrec);
3108 ok(r == ERROR_SUCCESS, "select query failed\n");
3110 /* check the contents of the stream */
3112 r = MsiRecordReadStream( hrec, 1, buffer, &sz );
3113 ok(r == ERROR_SUCCESS, "read stream failed\n");
3114 ok(!memcmp(buffer, "naengmyon", 9), "stream data was wrong\n");
3115 ok(sz == 9, "stream data was wrong size\n");
3116 if (hrec) MsiCloseHandle(hrec);
3118 /* check the validity of the table with a deleted row */
3120 query = "select * from `MOO`";
3121 r = MsiDatabaseOpenView(hdb, query, &hview);
3122 ok(r == ERROR_SUCCESS, "open view failed\n");
3124 r = MsiViewExecute(hview, 0);
3125 ok(r == ERROR_SUCCESS, "view execute failed\n");
3127 r = MsiViewFetch(hview, &hrec);
3128 ok(r == ERROR_SUCCESS, "view fetch failed\n");
3130 r = MsiRecordGetInteger(hrec, 1);
3131 ok(r == 1, "Expected 1, got %d\n", r);
3134 r = MsiRecordGetString(hrec, 2, buffer, &sz);
3135 ok(r == ERROR_SUCCESS, "record get string failed\n");
3136 ok(!lstrcmpA(buffer, "c"), "Expected c, got %s\n", buffer);
3138 r = MsiRecordGetInteger(hrec, 3);
3139 ok(r == 0x80000000, "Expected 0x80000000, got %d\n", r);
3141 r = MsiRecordGetInteger(hrec, 4);
3142 ok(r == 5, "Expected 5, got %d\n", r);
3144 MsiCloseHandle(hrec);
3146 r = MsiViewFetch(hview, &hrec);
3147 ok(r == ERROR_SUCCESS, "view fetch failed\n");
3149 r = MsiRecordGetInteger(hrec, 1);
3150 ok(r == 2, "Expected 2, got %d\n", r);
3153 r = MsiRecordGetString(hrec, 2, buffer, &sz);
3154 ok(r == ERROR_SUCCESS, "record get string failed\n");
3155 ok(!lstrcmpA(buffer, "b"), "Expected b, got %s\n", buffer);
3157 r = MsiRecordGetInteger(hrec, 3);
3158 ok(r == 0x80000000, "Expected 0x80000000, got %d\n", r);
3160 r = MsiRecordGetInteger(hrec, 4);
3161 ok(r == 0x80000000, "Expected 0x80000000, got %d\n", r);
3163 MsiCloseHandle(hrec);
3165 r = MsiViewFetch(hview, &hrec);
3166 ok(r == ERROR_NO_MORE_ITEMS, "view fetch succeeded\n");
3168 MsiCloseHandle(hrec);
3169 MsiViewClose(hview);
3170 MsiCloseHandle(hview);
3172 /* check that the property was added */
3173 r = package_from_db(hdb, &hpkg);
3174 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
3176 skip("Not enough rights to perform tests\n");
3179 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3182 r = MsiGetProperty(hpkg, "prop", buffer, &sz);
3183 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3184 ok(!lstrcmp(buffer, "val"), "Expected val, got %s\n", buffer);
3186 MsiCloseHandle(hpkg);
3189 MsiCloseHandle(hdb);
3190 DeleteFile(msifile);
3191 DeleteFile(mstfile);
3196 const CHAR one[MAX_PATH];
3197 const CHAR two[MAX_PATH];
3200 struct join_res_4col
3202 const CHAR one[MAX_PATH];
3203 const CHAR two[MAX_PATH];
3204 const CHAR three[MAX_PATH];
3205 const CHAR four[MAX_PATH];
3208 struct join_res_uint
3218 static const struct join_res join_res_first[] =
3220 { "alveolar", "procerus" },
3221 { "septum", "procerus" },
3222 { "septum", "nasalis" },
3223 { "ramus", "nasalis" },
3224 { "malar", "mentalis" },
3227 static const struct join_res join_res_second[] =
3229 { "nasal", "septum" },
3230 { "mandible", "ramus" },
3233 static const struct join_res join_res_third[] =
3235 { "msvcp.dll", "abcdefgh" },
3236 { "msvcr.dll", "ijklmnop" },
3239 static const struct join_res join_res_fourth[] =
3241 { "msvcp.dll.01234", "single.dll.31415" },
3244 static const struct join_res join_res_fifth[] =
3246 { "malar", "procerus" },
3249 static const struct join_res join_res_sixth[] =
3251 { "malar", "procerus" },
3252 { "malar", "procerus" },
3253 { "malar", "nasalis" },
3254 { "malar", "nasalis" },
3255 { "malar", "nasalis" },
3256 { "malar", "mentalis" },
3259 static const struct join_res join_res_seventh[] =
3261 { "malar", "nasalis" },
3262 { "malar", "nasalis" },
3263 { "malar", "nasalis" },
3266 static const struct join_res_4col join_res_eighth[] =
3268 { "msvcp.dll", "msvcp.dll.01234", "msvcp.dll.01234", "abcdefgh" },
3269 { "msvcr.dll", "msvcr.dll.56789", "msvcp.dll.01234", "abcdefgh" },
3270 { "msvcp.dll", "msvcp.dll.01234", "msvcr.dll.56789", "ijklmnop" },
3271 { "msvcr.dll", "msvcr.dll.56789", "msvcr.dll.56789", "ijklmnop" },
3272 { "msvcp.dll", "msvcp.dll.01234", "single.dll.31415", "msvcp.dll" },
3273 { "msvcr.dll", "msvcr.dll.56789", "single.dll.31415", "msvcp.dll" },
3276 static const struct join_res_uint join_res_ninth[] =
3278 { 1, 2, 3, 4, 7, 8 },
3279 { 1, 2, 5, 6, 7, 8 },
3280 { 1, 2, 3, 4, 9, 10 },
3281 { 1, 2, 5, 6, 9, 10 },
3282 { 1, 2, 3, 4, 11, 12 },
3283 { 1, 2, 5, 6, 11, 12 },
3286 static void test_join(void)
3288 MSIHANDLE hdb, hview, hrec;
3296 ok( hdb, "failed to create db\n");
3298 r = create_component_table( hdb );
3299 ok( r == ERROR_SUCCESS, "cannot create Component table: %d\n", r );
3301 r = add_component_entry( hdb, "'zygomatic', 'malar', 'INSTALLDIR', 0, '', ''" );
3302 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
3304 r = add_component_entry( hdb, "'maxilla', 'alveolar', 'INSTALLDIR', 0, '', ''" );
3305 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
3307 r = add_component_entry( hdb, "'nasal', 'septum', 'INSTALLDIR', 0, '', ''" );
3308 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
3310 r = add_component_entry( hdb, "'mandible', 'ramus', 'INSTALLDIR', 0, '', ''" );
3311 ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
3313 r = create_feature_components_table( hdb );
3314 ok( r == ERROR_SUCCESS, "cannot create FeatureComponents table: %d\n", r );
3316 r = add_feature_components_entry( hdb, "'procerus', 'maxilla'" );
3317 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
3319 r = add_feature_components_entry( hdb, "'procerus', 'nasal'" );
3320 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
3322 r = add_feature_components_entry( hdb, "'nasalis', 'nasal'" );
3323 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
3325 r = add_feature_components_entry( hdb, "'nasalis', 'mandible'" );
3326 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
3328 r = add_feature_components_entry( hdb, "'nasalis', 'notacomponent'" );
3329 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
3331 r = add_feature_components_entry( hdb, "'mentalis', 'zygomatic'" );
3332 ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
3334 r = create_std_dlls_table( hdb );
3335 ok( r == ERROR_SUCCESS, "cannot create StdDlls table: %d\n", r );
3337 r = add_std_dlls_entry( hdb, "'msvcp.dll', 'msvcp.dll.01234'" );
3338 ok( r == ERROR_SUCCESS, "cannot add std dlls: %d\n", r );
3340 r = add_std_dlls_entry( hdb, "'msvcr.dll', 'msvcr.dll.56789'" );
3341 ok( r == ERROR_SUCCESS, "cannot add std dlls: %d\n", r );
3343 r = create_binary_table( hdb );
3344 ok( r == ERROR_SUCCESS, "cannot create Binary table: %d\n", r );
3346 r = add_binary_entry( hdb, "'msvcp.dll.01234', 'abcdefgh'" );
3347 ok( r == ERROR_SUCCESS, "cannot add binary: %d\n", r );
3349 r = add_binary_entry( hdb, "'msvcr.dll.56789', 'ijklmnop'" );
3350 ok( r == ERROR_SUCCESS, "cannot add binary: %d\n", r );
3352 r = add_binary_entry( hdb, "'single.dll.31415', 'msvcp.dll'" );
3353 ok( r == ERROR_SUCCESS, "cannot add binary: %d\n", r );
3355 query = "CREATE TABLE `One` (`A` SHORT, `B` SHORT PRIMARY KEY `A`)";
3356 r = run_query( hdb, 0, query);
3357 ok(r == ERROR_SUCCESS, "cannot create table: %d\n", r );
3359 query = "CREATE TABLE `Two` (`C` SHORT, `D` SHORT PRIMARY KEY `C`)";
3360 r = run_query( hdb, 0, query);
3361 ok(r == ERROR_SUCCESS, "cannot create table: %d\n", r );
3363 query = "CREATE TABLE `Three` (`E` SHORT, `F` SHORT PRIMARY KEY `E`)";
3364 r = run_query( hdb, 0, query);
3365 ok(r == ERROR_SUCCESS, "cannot create table: %d\n", r );
3367 query = "INSERT INTO `One` (`A`, `B`) VALUES (1, 2)";
3368 r = run_query( hdb, 0, query);
3369 ok(r == ERROR_SUCCESS, "cannot insert into table: %d\n", r );
3371 query = "INSERT INTO `Two` (`C`, `D`) VALUES (3, 4)";
3372 r = run_query( hdb, 0, query);
3373 ok(r == ERROR_SUCCESS, "cannot insert into table: %d\n", r );
3375 query = "INSERT INTO `Two` (`C`, `D`) VALUES (5, 6)";
3376 r = run_query( hdb, 0, query);
3377 ok(r == ERROR_SUCCESS, "cannot insert into table: %d\n", r );
3379 query = "INSERT INTO `Three` (`E`, `F`) VALUES (7, 8)";
3380 r = run_query( hdb, 0, query);
3381 ok(r == ERROR_SUCCESS, "cannot insert into table: %d\n", r );
3383 query = "INSERT INTO `Three` (`E`, `F`) VALUES (9, 10)";
3384 r = run_query( hdb, 0, query);
3385 ok(r == ERROR_SUCCESS, "cannot insert into table: %d\n", r );
3387 query = "INSERT INTO `Three` (`E`, `F`) VALUES (11, 12)";
3388 r = run_query( hdb, 0, query);
3389 ok(r == ERROR_SUCCESS, "cannot insert into table: %d\n", r );
3391 query = "CREATE TABLE `Four` (`G` SHORT, `H` SHORT PRIMARY KEY `G`)";
3392 r = run_query( hdb, 0, query);
3393 ok(r == ERROR_SUCCESS, "cannot create table: %d\n", r );
3395 query = "CREATE TABLE `Five` (`I` SHORT, `J` SHORT PRIMARY KEY `I`)";
3396 r = run_query( hdb, 0, query);
3397 ok(r == ERROR_SUCCESS, "cannot create table: %d\n", r );
3399 query = "INSERT INTO `Five` (`I`, `J`) VALUES (13, 14)";
3400 r = run_query( hdb, 0, query);
3401 ok(r == ERROR_SUCCESS, "cannot insert into table: %d\n", r );
3403 query = "INSERT INTO `Five` (`I`, `J`) VALUES (15, 16)";
3404 r = run_query( hdb, 0, query);
3405 ok(r == ERROR_SUCCESS, "cannot insert into table: %d\n", r );
3407 query = "SELECT `Component`.`ComponentId`, `FeatureComponents`.`Feature_` "
3408 "FROM `Component`, `FeatureComponents` "
3409 "WHERE `Component`.`Component` = `FeatureComponents`.`Component_` "
3410 "ORDER BY `Feature_`";
3411 r = MsiDatabaseOpenView(hdb, query, &hview);
3412 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r );
3414 r = MsiViewExecute(hview, 0);
3415 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r );
3418 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS)
3420 count = MsiRecordGetFieldCount( hrec );
3421 ok( count == 2, "Expected 2 record fields, got %d\n", count );
3424 r = MsiRecordGetString( hrec, 1, buf, &size );
3425 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r );
3426 ok( !lstrcmp( buf, join_res_first[i].one ),
3427 "For (row %d, column 1) expected '%s', got %s\n", i, join_res_first[i].one, buf );
3430 r = MsiRecordGetString( hrec, 2, buf, &size );
3431 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r );
3432 ok( !lstrcmp( buf, join_res_first[i].two ),
3433 "For (row %d, column 2) expected '%s', got %s\n", i, join_res_first[i].two, buf );
3436 MsiCloseHandle(hrec);
3439 ok( i == 5, "Expected 5 rows, got %d\n", i );
3440 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r );
3442 MsiViewClose(hview);
3443 MsiCloseHandle(hview);
3445 /* try a join without a WHERE condition */
3446 query = "SELECT `Component`.`ComponentId`, `FeatureComponents`.`Feature_` "
3447 "FROM `Component`, `FeatureComponents` ";
3448 r = MsiDatabaseOpenView(hdb, query, &hview);
3449 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r );
3451 r = MsiViewExecute(hview, 0);
3452 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r );
3455 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS)
3458 MsiCloseHandle(hrec);
3460 ok( i == 24, "Expected 24 rows, got %d\n", i );
3462 MsiViewClose(hview);
3463 MsiCloseHandle(hview);
3465 query = "SELECT DISTINCT Component, ComponentId FROM FeatureComponents, Component "
3466 "WHERE FeatureComponents.Component_=Component.Component "
3467 "AND (Feature_='nasalis') ORDER BY Feature_";
3468 r = MsiDatabaseOpenView(hdb, query, &hview);
3469 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r );
3471 r = MsiViewExecute(hview, 0);
3472 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r );
3475 data_correct = TRUE;
3476 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS)
3478 count = MsiRecordGetFieldCount( hrec );
3479 ok( count == 2, "Expected 2 record fields, got %d\n", count );
3482 r = MsiRecordGetString( hrec, 1, buf, &size );
3483 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r );
3484 if( lstrcmp( buf, join_res_second[i].one ))
3485 data_correct = FALSE;
3488 r = MsiRecordGetString( hrec, 2, buf, &size );
3489 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r );
3490 if( lstrcmp( buf, join_res_second[i].two ))
3491 data_correct = FALSE;
3494 MsiCloseHandle(hrec);
3497 ok( data_correct, "data returned in the wrong order\n");
3499 ok( i == 2, "Expected 2 rows, got %d\n", i );
3500 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r );
3502 MsiViewClose(hview);
3503 MsiCloseHandle(hview);
3505 query = "SELECT `StdDlls`.`File`, `Binary`.`Data` "
3506 "FROM `StdDlls`, `Binary` "
3507 "WHERE `StdDlls`.`Binary_` = `Binary`.`Name` "
3509 r = MsiDatabaseOpenView(hdb, query, &hview);
3510 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r );
3512 r = MsiViewExecute(hview, 0);
3513 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r );
3516 data_correct = TRUE;
3517 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS)
3519 count = MsiRecordGetFieldCount( hrec );
3520 ok( count == 2, "Expected 2 record fields, got %d\n", count );
3523 r = MsiRecordGetString( hrec, 1, buf, &size );
3524 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r );
3525 if( lstrcmp( buf, join_res_third[i].one ) )
3526 data_correct = FALSE;
3529 r = MsiRecordGetString( hrec, 2, buf, &size );
3530 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r );
3531 if( lstrcmp( buf, join_res_third[i].two ) )
3532 data_correct = FALSE;
3535 MsiCloseHandle(hrec);
3537 ok( data_correct, "data returned in the wrong order\n");
3539 ok( i == 2, "Expected 2 rows, got %d\n", i );
3541 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r );
3543 MsiViewClose(hview);
3544 MsiCloseHandle(hview);
3546 query = "SELECT `StdDlls`.`Binary_`, `Binary`.`Name` "
3547 "FROM `StdDlls`, `Binary` "
3548 "WHERE `StdDlls`.`File` = `Binary`.`Data` "
3550 r = MsiDatabaseOpenView(hdb, query, &hview);
3551 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r );
3553 r = MsiViewExecute(hview, 0);
3554 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r );
3557 data_correct = TRUE;
3558 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS)
3560 count = MsiRecordGetFieldCount( hrec );
3561 ok( count == 2, "Expected 2 record fields, got %d\n", count );
3564 r = MsiRecordGetString( hrec, 1, buf, &size );
3565 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r );
3566 if( lstrcmp( buf, join_res_fourth[i].one ))
3567 data_correct = FALSE;
3570 r = MsiRecordGetString( hrec, 2, buf, &size );
3571 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r );
3572 if( lstrcmp( buf, join_res_fourth[i].two ))
3573 data_correct = FALSE;
3576 MsiCloseHandle(hrec);
3578 ok( data_correct, "data returned in the wrong order\n");
3580 ok( i == 1, "Expected 1 rows, got %d\n", i );
3581 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r );
3583 MsiViewClose(hview);
3584 MsiCloseHandle(hview);
3586 query = "SELECT `Component`.`ComponentId`, `FeatureComponents`.`Feature_` "
3587 "FROM `Component`, `FeatureComponents` "
3588 "WHERE `Component`.`Component` = 'zygomatic' "
3589 "AND `FeatureComponents`.`Component_` = 'maxilla' "
3590 "ORDER BY `Feature_`";
3591 r = MsiDatabaseOpenView(hdb, query, &hview);
3592 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r );
3594 r = MsiViewExecute(hview, 0);
3595 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r );
3598 data_correct = TRUE;
3599 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS)
3601 count = MsiRecordGetFieldCount( hrec );
3602 ok( count == 2, "Expected 2 record fields, got %d\n", count );
3605 r = MsiRecordGetString( hrec, 1, buf, &size );
3606 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r );
3607 if( lstrcmp( buf, join_res_fifth[i].one ))
3608 data_correct = FALSE;
3611 r = MsiRecordGetString( hrec, 2, buf, &size );
3612 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r );
3613 if( lstrcmp( buf, join_res_fifth[i].two ))
3614 data_correct = FALSE;
3617 MsiCloseHandle(hrec);
3619 ok( data_correct, "data returned in the wrong order\n");
3621 ok( i == 1, "Expected 1 rows, got %d\n", i );
3622 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r );
3624 MsiViewClose(hview);
3625 MsiCloseHandle(hview);
3627 query = "SELECT `Component`.`ComponentId`, `FeatureComponents`.`Feature_` "
3628 "FROM `Component`, `FeatureComponents` "
3629 "WHERE `Component` = 'zygomatic' "
3630 "ORDER BY `Feature_`";
3631 r = MsiDatabaseOpenView(hdb, query, &hview);
3632 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r );
3634 r = MsiViewExecute(hview, 0);
3635 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r );
3638 data_correct = TRUE;
3639 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS)
3641 count = MsiRecordGetFieldCount( hrec );
3642 ok( count == 2, "Expected 2 record fields, got %d\n", count );
3645 r = MsiRecordGetString( hrec, 1, buf, &size );
3646 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r );
3647 if( lstrcmp( buf, join_res_sixth[i].one ))
3648 data_correct = FALSE;
3651 r = MsiRecordGetString( hrec, 2, buf, &size );
3652 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r );
3653 if( lstrcmp( buf, join_res_sixth[i].two ))
3654 data_correct = FALSE;
3657 MsiCloseHandle(hrec);
3659 ok( data_correct, "data returned in the wrong order\n");
3661 ok( i == 6, "Expected 6 rows, got %d\n", i );
3662 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r );
3664 MsiViewClose(hview);
3665 MsiCloseHandle(hview);
3667 query = "SELECT `Component`.`ComponentId`, `FeatureComponents`.`Feature_` "
3668 "FROM `Component`, `FeatureComponents` "
3669 "WHERE `Component` = 'zygomatic' "
3670 "AND `Feature_` = 'nasalis' "
3671 "ORDER BY `Feature_`";
3672 r = MsiDatabaseOpenView(hdb, query, &hview);
3673 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r );
3675 r = MsiViewExecute(hview, 0);
3676 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r );
3679 data_correct = TRUE;
3680 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS)
3682 count = MsiRecordGetFieldCount( hrec );
3683 ok( count == 2, "Expected 2 record fields, got %d\n", count );
3686 r = MsiRecordGetString( hrec, 1, buf, &size );
3687 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r );
3688 if( lstrcmp( buf, join_res_seventh[i].one ))
3689 data_correct = FALSE;
3692 r = MsiRecordGetString( hrec, 2, buf, &size );
3693 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r );
3694 if( lstrcmp( buf, join_res_seventh[i].two ))
3695 data_correct = FALSE;
3698 MsiCloseHandle(hrec);
3701 ok( data_correct, "data returned in the wrong order\n");
3702 ok( i == 3, "Expected 3 rows, got %d\n", i );
3703 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r );
3705 MsiViewClose(hview);
3706 MsiCloseHandle(hview);
3708 query = "SELECT `StdDlls`.`File`, `Binary`.`Data` "
3709 "FROM `StdDlls`, `Binary` ";
3710 r = MsiDatabaseOpenView(hdb, query, &hview);
3711 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r );
3713 r = MsiViewExecute(hview, 0);
3714 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r );
3717 data_correct = TRUE;
3718 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS)
3720 count = MsiRecordGetFieldCount( hrec );
3721 ok( count == 2, "Expected 2 record fields, got %d\n", count );
3724 r = MsiRecordGetString( hrec, 1, buf, &size );
3725 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r );
3726 if( lstrcmp( buf, join_res_eighth[i].one ))
3727 data_correct = FALSE;
3730 r = MsiRecordGetString( hrec, 2, buf, &size );
3731 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r );
3732 if( lstrcmp( buf, join_res_eighth[i].four ))
3733 data_correct = FALSE;
3736 MsiCloseHandle(hrec);
3739 ok( data_correct, "data returned in the wrong order\n");
3740 ok( i == 6, "Expected 6 rows, got %d\n", i );
3741 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r );
3743 MsiViewClose(hview);
3744 MsiCloseHandle(hview);
3746 query = "SELECT * FROM `StdDlls`, `Binary` ";
3747 r = MsiDatabaseOpenView(hdb, query, &hview);
3748 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r );
3750 r = MsiViewExecute(hview, 0);
3751 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r );
3754 data_correct = TRUE;
3755 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS)
3757 count = MsiRecordGetFieldCount( hrec );
3758 ok( count == 4, "Expected 4 record fields, got %d\n", count );
3761 r = MsiRecordGetString( hrec, 1, buf, &size );
3762 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r );
3763 if( lstrcmp( buf, join_res_eighth[i].one ))
3764 data_correct = FALSE;
3767 r = MsiRecordGetString( hrec, 2, buf, &size );
3768 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r );
3769 if( lstrcmp( buf, join_res_eighth[i].two ))
3770 data_correct = FALSE;
3773 r = MsiRecordGetString( hrec, 3, buf, &size );
3774 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r );
3775 if( lstrcmp( buf, join_res_eighth[i].three ))
3776 data_correct = FALSE;
3779 r = MsiRecordGetString( hrec, 4, buf, &size );
3780 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r );
3781 if( lstrcmp( buf, join_res_eighth[i].four ))
3782 data_correct = FALSE;
3785 MsiCloseHandle(hrec);
3787 ok( data_correct, "data returned in the wrong order\n");
3789 ok( i == 6, "Expected 6 rows, got %d\n", i );
3790 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r );
3792 MsiViewClose(hview);
3793 MsiCloseHandle(hview);
3795 query = "SELECT * FROM `One`, `Two`, `Three` ";
3796 r = MsiDatabaseOpenView(hdb, query, &hview);
3797 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r );
3799 r = MsiViewExecute(hview, 0);
3800 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r );
3803 data_correct = TRUE;
3804 while ((r = MsiViewFetch(hview, &hrec)) == ERROR_SUCCESS)
3806 count = MsiRecordGetFieldCount( hrec );
3807 ok( count == 6, "Expected 6 record fields, got %d\n", count );
3809 r = MsiRecordGetInteger( hrec, 1 );
3810 if( r != join_res_ninth[i].one )
3811 data_correct = FALSE;
3813 r = MsiRecordGetInteger( hrec, 2 );
3814 if( r != join_res_ninth[i].two )
3815 data_correct = FALSE;
3817 r = MsiRecordGetInteger( hrec, 3 );
3818 if( r != join_res_ninth[i].three )
3819 data_correct = FALSE;
3821 r = MsiRecordGetInteger( hrec, 4 );
3822 if( r != join_res_ninth[i].four )
3823 data_correct = FALSE;
3825 r = MsiRecordGetInteger( hrec, 5 );
3826 if( r != join_res_ninth[i].five )
3827 data_correct = FALSE;
3829 r = MsiRecordGetInteger( hrec, 6);
3830 if( r != join_res_ninth[i].six )
3831 data_correct = FALSE;
3834 MsiCloseHandle(hrec);
3836 ok( data_correct, "data returned in the wrong order\n");
3838 ok( i == 6, "Expected 6 rows, got %d\n", i );
3839 ok( r == ERROR_NO_MORE_ITEMS, "expected no more items: %d\n", r );
3841 MsiViewClose(hview);
3842 MsiCloseHandle(hview);
3844 query = "SELECT * FROM `Four`, `Five`";
3845 r = MsiDatabaseOpenView(hdb, query, &hview);
3846 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r );
3848 r = MsiViewExecute(hview, 0);
3849 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r );
3851 r = MsiViewFetch(hview, &hrec);
3852 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
3854 MsiViewClose(hview);
3855 MsiCloseHandle(hview);
3857 query = "SELECT * FROM `Nonexistent`, `One`";
3858 r = MsiDatabaseOpenView(hdb, query, &hview);
3859 ok( r == ERROR_BAD_QUERY_SYNTAX,
3860 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r );
3862 /* try updating a row in a join table */
3863 query = "SELECT `Component`.`ComponentId`, `FeatureComponents`.`Feature_` "
3864 "FROM `Component`, `FeatureComponents` "
3865 "WHERE `Component`.`Component` = `FeatureComponents`.`Component_` "
3866 "ORDER BY `Feature_`";
3867 r = MsiDatabaseOpenView(hdb, query, &hview);
3868 ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r );
3870 r = MsiViewExecute(hview, 0);
3871 ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r );
3873 r = MsiViewFetch(hview, &hrec);
3874 ok( r == ERROR_SUCCESS, "failed to fetch view: %d\n", r );
3876 r = MsiRecordSetString( hrec, 1, "epicranius" );
3877 ok( r == ERROR_SUCCESS, "failed to set string: %d\n", r );
3879 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec);
3880 ok( r == ERROR_SUCCESS, "failed to update row: %d\n", r );
3882 /* try another valid operation for joins */
3883 r = MsiViewModify(hview, MSIMODIFY_REFRESH, hrec);
3884 todo_wine ok( r == ERROR_SUCCESS, "failed to refresh row: %d\n", r );
3886 /* try an invalid operation for joins */
3887 r = MsiViewModify(hview, MSIMODIFY_DELETE, hrec);
3888 ok( r == ERROR_FUNCTION_FAILED, "unexpected result: %d\n", r );
3890 r = MsiRecordSetString( hrec, 2, "epicranius" );
3891 ok( r == ERROR_SUCCESS, "failed to set string: %d\n", r );
3893 /* primary key cannot be updated */
3894 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec);
3895 todo_wine ok( r == ERROR_FUNCTION_FAILED, "failed to update row: %d\n", r );
3897 MsiCloseHandle(hrec);
3898 MsiViewClose(hview);
3899 MsiCloseHandle(hview);
3901 r = MsiDatabaseOpenView(hdb, query, &hview);
3902 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
3904 r = MsiViewExecute(hview, 0);
3905 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
3907 r = MsiViewFetch(hview, &hrec);
3908 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
3911 r = MsiRecordGetString( hrec, 1, buf, &size );
3912 ok( r == ERROR_SUCCESS, "failed to get record string: %d\n", r );
3913 ok( !lstrcmp( buf, "epicranius" ), "expected 'epicranius', got %s\n", buf );
3915 MsiCloseHandle(hrec);
3916 MsiViewClose(hview);
3917 MsiCloseHandle(hview);
3919 MsiCloseHandle(hdb);
3920 DeleteFile(msifile);
3923 static void test_temporary_table(void)
3926 MSIHANDLE hdb = 0, view = 0, rec;
3932 cond = MsiDatabaseIsTablePersistent(0, NULL);
3933 ok( cond == MSICONDITION_ERROR, "wrong return condition\n");
3936 ok( hdb, "failed to create db\n");
3938 cond = MsiDatabaseIsTablePersistent(hdb, NULL);
3939 ok( cond == MSICONDITION_ERROR, "wrong return condition\n");
3941 cond = MsiDatabaseIsTablePersistent(hdb, "_Tables");
3942 ok( cond == MSICONDITION_NONE, "wrong return condition\n");
3944 cond = MsiDatabaseIsTablePersistent(hdb, "_Columns");
3945 ok( cond == MSICONDITION_NONE, "wrong return condition\n");
3947 cond = MsiDatabaseIsTablePersistent(hdb, "_Storages");
3948 ok( cond == MSICONDITION_NONE, "wrong return condition\n");
3950 cond = MsiDatabaseIsTablePersistent(hdb, "_Streams");
3951 ok( cond == MSICONDITION_NONE, "wrong return condition\n");
3953 query = "CREATE TABLE `P` ( `B` SHORT NOT NULL, `C` CHAR(255) PRIMARY KEY `C`)";
3954 r = run_query(hdb, 0, query);
3955 ok(r == ERROR_SUCCESS, "failed to add table\n");
3957 cond = MsiDatabaseIsTablePersistent(hdb, "P");
3958 ok( cond == MSICONDITION_TRUE, "wrong return condition\n");
3960 query = "CREATE TABLE `P2` ( `B` SHORT NOT NULL, `C` CHAR(255) PRIMARY KEY `C`) HOLD";
3961 r = run_query(hdb, 0, query);
3962 ok(r == ERROR_SUCCESS, "failed to add table\n");
3964 cond = MsiDatabaseIsTablePersistent(hdb, "P2");
3965 ok( cond == MSICONDITION_TRUE, "wrong return condition\n");
3967 query = "CREATE TABLE `T` ( `B` SHORT NOT NULL TEMPORARY, `C` CHAR(255) TEMPORARY PRIMARY KEY `C`) HOLD";
3968 r = run_query(hdb, 0, query);
3969 ok(r == ERROR_SUCCESS, "failed to add table\n");
3971 cond = MsiDatabaseIsTablePersistent(hdb, "T");
3972 ok( cond == MSICONDITION_FALSE, "wrong return condition\n");
3974 query = "CREATE TABLE `T2` ( `B` SHORT NOT NULL TEMPORARY, `C` CHAR(255) TEMPORARY PRIMARY KEY `C`)";
3975 r = run_query(hdb, 0, query);
3976 ok(r == ERROR_SUCCESS, "failed to add table\n");
3978 query = "SELECT * FROM `T2`";
3979 r = MsiDatabaseOpenView(hdb, query, &view);
3980 ok(r == ERROR_BAD_QUERY_SYNTAX,
3981 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
3983 cond = MsiDatabaseIsTablePersistent(hdb, "T2");
3984 ok( cond == MSICONDITION_NONE, "wrong return condition\n");
3986 query = "CREATE TABLE `T3` ( `B` SHORT NOT NULL TEMPORARY, `C` CHAR(255) PRIMARY KEY `C`)";
3987 r = run_query(hdb, 0, query);
3988 ok(r == ERROR_SUCCESS, "failed to add table\n");
3990 cond = MsiDatabaseIsTablePersistent(hdb, "T3");
3991 ok( cond == MSICONDITION_TRUE, "wrong return condition\n");
3993 query = "CREATE TABLE `T4` ( `B` SHORT NOT NULL, `C` CHAR(255) TEMPORARY PRIMARY KEY `C`)";
3994 r = run_query(hdb, 0, query);
3995 ok(r == ERROR_FUNCTION_FAILED, "failed to add table\n");
3997 cond = MsiDatabaseIsTablePersistent(hdb, "T4");
3998 ok( cond == MSICONDITION_NONE, "wrong return condition\n");
4000 query = "CREATE TABLE `T5` ( `B` SHORT NOT NULL TEMP, `C` CHAR(255) TEMP PRIMARY KEY `C`) HOLD";
4001 r = run_query(hdb, 0, query);
4002 ok(r == ERROR_BAD_QUERY_SYNTAX, "failed to add table\n");
4004 query = "select * from `T`";
4005 r = MsiDatabaseOpenView(hdb, query, &view);
4006 ok(r == ERROR_SUCCESS, "failed to query table\n");
4007 r = MsiViewGetColumnInfo(view, MSICOLINFO_TYPES, &rec);
4008 ok(r == ERROR_SUCCESS, "failed to get column info\n");
4011 r = MsiRecordGetString(rec, 1, buf, &sz);
4012 ok(r == ERROR_SUCCESS, "failed to get string\n");
4013 ok( 0 == strcmp("G255", buf), "wrong column type\n");
4016 r = MsiRecordGetString(rec, 2, buf, &sz);
4017 ok(r == ERROR_SUCCESS, "failed to get string\n");
4018 ok( 0 == strcmp("j2", buf), "wrong column type\n");
4020 MsiCloseHandle( rec );
4021 MsiViewClose( view );
4022 MsiCloseHandle( view );
4024 /* query the table data */
4026 r = do_query(hdb, "select * from `_Tables` where `Name` = 'T'", &rec);
4027 ok( r == ERROR_SUCCESS, "temporary table exists in _Tables\n");
4028 MsiCloseHandle( rec );
4030 /* query the column data */
4032 r = do_query(hdb, "select * from `_Columns` where `Table` = 'T' AND `Name` = 'B'", &rec);
4033 ok( r == ERROR_NO_MORE_ITEMS, "temporary table exists in _Columns\n");
4034 if (rec) MsiCloseHandle( rec );
4036 r = do_query(hdb, "select * from `_Columns` where `Table` = 'T' AND `Name` = 'C'", &rec);
4037 ok( r == ERROR_NO_MORE_ITEMS, "temporary table exists in _Columns\n");
4038 if (rec) MsiCloseHandle( rec );
4040 MsiCloseHandle( hdb );
4042 DeleteFile(msifile);
4045 static void test_alter(void)
4053 ok( hdb, "failed to create db\n");
4055 query = "CREATE TABLE `T` ( `B` SHORT NOT NULL TEMPORARY, `C` CHAR(255) TEMPORARY PRIMARY KEY `C`) HOLD";
4056 r = run_query(hdb, 0, query);
4057 ok(r == ERROR_SUCCESS, "failed to add table\n");
4059 cond = MsiDatabaseIsTablePersistent(hdb, "T");
4060 ok( cond == MSICONDITION_FALSE, "wrong return condition\n");
4062 query = "ALTER TABLE `T` HOLD";
4063 r = run_query(hdb, 0, query);
4064 ok(r == ERROR_SUCCESS, "failed to hold table %d\n", r);
4066 query = "ALTER TABLE `T` FREE";
4067 r = run_query(hdb, 0, query);
4068 ok(r == ERROR_SUCCESS, "failed to free table\n");
4070 query = "ALTER TABLE `T` FREE";
4071 r = run_query(hdb, 0, query);
4072 ok(r == ERROR_SUCCESS, "failed to free table\n");
4074 query = "ALTER TABLE `T` FREE";
4075 r = run_query(hdb, 0, query);
4076 ok(r == ERROR_BAD_QUERY_SYNTAX, "failed to free table\n");
4078 query = "ALTER TABLE `T` HOLD";
4079 r = run_query(hdb, 0, query);
4080 ok(r == ERROR_BAD_QUERY_SYNTAX, "failed to hold table %d\n", r);
4082 /* table T is removed */
4083 query = "SELECT * FROM `T`";
4084 r = run_query(hdb, 0, query);
4085 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
4087 /* create the table again */
4088 query = "CREATE TABLE `U` ( `A` INTEGER, `B` INTEGER PRIMARY KEY `B`)";
4089 r = run_query(hdb, 0, query);
4090 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4092 /* up the ref count */
4093 query = "ALTER TABLE `U` HOLD";
4094 r = run_query(hdb, 0, query);
4095 ok(r == ERROR_SUCCESS, "failed to free table\n");
4097 /* add column, no data type */
4098 query = "ALTER TABLE `U` ADD `C`";
4099 r = run_query(hdb, 0, query);
4100 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
4102 query = "ALTER TABLE `U` ADD `C` INTEGER";
4103 r = run_query(hdb, 0, query);
4104 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4106 /* add column C again */
4107 query = "ALTER TABLE `U` ADD `C` INTEGER";
4108 r = run_query(hdb, 0, query);
4109 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
4111 query = "ALTER TABLE `U` ADD `D` INTEGER TEMPORARY";
4112 r = run_query(hdb, 0, query);
4113 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4115 query = "INSERT INTO `U` ( `A`, `B`, `C`, `D` ) VALUES ( 1, 2, 3, 4 )";
4116 r = run_query(hdb, 0, query);
4117 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4119 query = "ALTER TABLE `U` ADD `D` INTEGER TEMPORARY HOLD";
4120 r = run_query(hdb, 0, query);
4121 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
4123 query = "INSERT INTO `U` ( `A`, `B`, `C`, `D` ) VALUES ( 5, 6, 7, 8 )";
4124 r = run_query(hdb, 0, query);
4125 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4127 query = "SELECT * FROM `U` WHERE `D` = 8";
4128 r = run_query(hdb, 0, query);
4129 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4131 query = "ALTER TABLE `U` ADD `D` INTEGER TEMPORARY FREE";
4132 r = run_query(hdb, 0, query);
4133 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
4135 query = "ALTER COLUMN `D` FREE";
4136 r = run_query(hdb, 0, query);
4137 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
4139 /* drop the ref count */
4140 query = "ALTER TABLE `U` FREE";
4141 r = run_query(hdb, 0, query);
4142 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4144 /* table is not empty */
4145 query = "SELECT * FROM `U`";
4146 r = run_query(hdb, 0, query);
4147 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4149 /* column D is removed */
4150 query = "SELECT * FROM `U` WHERE `D` = 8";
4151 r = run_query(hdb, 0, query);
4152 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
4154 query = "INSERT INTO `U` ( `A`, `B`, `C`, `D` ) VALUES ( 9, 10, 11, 12 )";
4155 r = run_query(hdb, 0, query);
4156 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
4158 /* add the column again */
4159 query = "ALTER TABLE `U` ADD `E` INTEGER TEMPORARY HOLD";
4160 r = run_query(hdb, 0, query);
4161 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4163 /* up the ref count */
4164 query = "ALTER TABLE `U` HOLD";
4165 r = run_query(hdb, 0, query);
4166 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4168 query = "INSERT INTO `U` ( `A`, `B`, `C`, `E` ) VALUES ( 13, 14, 15, 16 )";
4169 r = run_query(hdb, 0, query);
4170 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4172 query = "SELECT * FROM `U` WHERE `E` = 16";
4173 r = run_query(hdb, 0, query);
4174 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4176 /* drop the ref count */
4177 query = "ALTER TABLE `U` FREE";
4178 r = run_query(hdb, 0, query);
4179 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4181 query = "INSERT INTO `U` ( `A`, `B`, `C`, `E` ) VALUES ( 17, 18, 19, 20 )";
4182 r = run_query(hdb, 0, query);
4183 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4185 query = "SELECT * FROM `U` WHERE `E` = 20";
4186 r = run_query(hdb, 0, query);
4187 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4189 /* drop the ref count */
4190 query = "ALTER TABLE `U` FREE";
4191 r = run_query(hdb, 0, query);
4192 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4194 /* table still exists */
4195 query = "SELECT * FROM `U`";
4196 r = run_query(hdb, 0, query);
4197 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4199 /* col E is removed */
4200 query = "SELECT * FROM `U` WHERE `E` = 20";
4201 r = run_query(hdb, 0, query);
4202 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
4204 query = "INSERT INTO `U` ( `A`, `B`, `C`, `E` ) VALUES ( 20, 21, 22, 23 )";
4205 r = run_query(hdb, 0, query);
4206 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
4208 /* drop the ref count once more */
4209 query = "ALTER TABLE `U` FREE";
4210 r = run_query(hdb, 0, query);
4211 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4213 /* table still exists */
4214 query = "SELECT * FROM `U`";
4215 r = run_query(hdb, 0, query);
4216 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4218 MsiCloseHandle( hdb );
4219 DeleteFile(msifile);
4222 static void test_integers(void)
4224 MSIHANDLE hdb = 0, view = 0, rec = 0;
4229 /* just MsiOpenDatabase should not create a file */
4230 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
4231 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n");
4233 /* create a table */
4234 query = "CREATE TABLE `integers` ( "
4235 "`one` SHORT, `two` INT, `three` INTEGER, `four` LONG, "
4236 "`five` SHORT NOT NULL, `six` INT NOT NULL, "
4237 "`seven` INTEGER NOT NULL, `eight` LONG NOT NULL "
4238 "PRIMARY KEY `one`)";
4239 r = MsiDatabaseOpenView(hdb, query, &view);
4240 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
4241 r = MsiViewExecute(view, 0);
4242 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
4243 r = MsiViewClose(view);
4244 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
4245 r = MsiCloseHandle(view);
4246 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
4248 query = "SELECT * FROM `integers`";
4249 r = MsiDatabaseOpenView(hdb, query, &view);
4250 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4252 r = MsiViewGetColumnInfo(view, MSICOLINFO_NAMES, &rec);
4253 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4254 count = MsiRecordGetFieldCount(rec);
4255 ok(count == 8, "Expected 8, got %d\n", count);
4256 ok(check_record(rec, 1, "one"), "Expected one\n");
4257 ok(check_record(rec, 2, "two"), "Expected two\n");
4258 ok(check_record(rec, 3, "three"), "Expected three\n");
4259 ok(check_record(rec, 4, "four"), "Expected four\n");
4260 ok(check_record(rec, 5, "five"), "Expected five\n");
4261 ok(check_record(rec, 6, "six"), "Expected six\n");
4262 ok(check_record(rec, 7, "seven"), "Expected seven\n");
4263 ok(check_record(rec, 8, "eight"), "Expected eight\n");
4264 MsiCloseHandle(rec);
4266 r = MsiViewGetColumnInfo(view, MSICOLINFO_TYPES, &rec);
4267 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4268 count = MsiRecordGetFieldCount(rec);
4269 ok(count == 8, "Expected 8, got %d\n", count);
4270 ok(check_record(rec, 1, "I2"), "Expected I2\n");
4271 ok(check_record(rec, 2, "I2"), "Expected I2\n");
4272 ok(check_record(rec, 3, "I2"), "Expected I2\n");
4273 ok(check_record(rec, 4, "I4"), "Expected I4\n");
4274 ok(check_record(rec, 5, "i2"), "Expected i2\n");
4275 ok(check_record(rec, 6, "i2"), "Expected i2\n");
4276 ok(check_record(rec, 7, "i2"), "Expected i2\n");
4277 ok(check_record(rec, 8, "i4"), "Expected i4\n");
4278 MsiCloseHandle(rec);
4281 MsiCloseHandle(view);
4283 /* insert values into it, NULL where NOT NULL is specified */
4284 query = "INSERT INTO `integers` ( `one`, `two`, `three`, `four`, `five`, `six`, `seven`, `eight` )"
4285 "VALUES('', '', '', '', '', '', '', '')";
4286 r = MsiDatabaseOpenView(hdb, query, &view);
4287 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4288 r = MsiViewExecute(view, 0);
4289 ok(r == ERROR_FUNCTION_FAILED, "Expected ERROR_FUNCTION_FAILED, got %d\n", r);
4292 MsiCloseHandle(view);
4294 query = "SELECT * FROM `integers`";
4295 r = do_query(hdb, query, &rec);
4296 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
4298 r = MsiRecordGetFieldCount(rec);
4299 ok(r == -1, "record count wrong: %d\n", r);
4301 MsiCloseHandle(rec);
4303 /* insert legitimate values into it */
4304 query = "INSERT INTO `integers` ( `one`, `two`, `three`, `four`, `five`, `six`, `seven`, `eight` )"
4305 "VALUES('', '2', '', '4', '5', '6', '7', '8')";
4306 r = MsiDatabaseOpenView(hdb, query, &view);
4307 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4308 r = MsiViewExecute(view, 0);
4309 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4311 query = "SELECT * FROM `integers`";
4312 r = do_query(hdb, query, &rec);
4313 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4315 r = MsiRecordGetFieldCount(rec);
4316 ok(r == 8, "record count wrong: %d\n", r);
4318 i = MsiRecordGetInteger(rec, 1);
4319 ok(i == MSI_NULL_INTEGER, "Expected MSI_NULL_INTEGER, got %d\n", i);
4320 i = MsiRecordGetInteger(rec, 3);
4321 ok(i == MSI_NULL_INTEGER, "Expected MSI_NULL_INTEGER, got %d\n", i);
4322 i = MsiRecordGetInteger(rec, 2);
4323 ok(i == 2, "Expected 2, got %d\n", i);
4324 i = MsiRecordGetInteger(rec, 4);
4325 ok(i == 4, "Expected 4, got %d\n", i);
4326 i = MsiRecordGetInteger(rec, 5);
4327 ok(i == 5, "Expected 5, got %d\n", i);
4328 i = MsiRecordGetInteger(rec, 6);
4329 ok(i == 6, "Expected 6, got %d\n", i);
4330 i = MsiRecordGetInteger(rec, 7);
4331 ok(i == 7, "Expected 7, got %d\n", i);
4332 i = MsiRecordGetInteger(rec, 8);
4333 ok(i == 8, "Expected 8, got %d\n", i);
4335 MsiCloseHandle(rec);
4337 MsiCloseHandle(view);
4339 r = MsiDatabaseCommit(hdb);
4340 ok(r == ERROR_SUCCESS, "MsiDatabaseCommit failed\n");
4342 r = MsiCloseHandle(hdb);
4343 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
4345 r = DeleteFile(msifile);
4346 ok(r == TRUE, "file didn't exist after commit\n");
4349 static void test_update(void)
4351 MSIHANDLE hdb = 0, view = 0, rec = 0;
4352 CHAR result[MAX_PATH];
4357 /* just MsiOpenDatabase should not create a file */
4358 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
4359 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n");
4361 /* create the Control table */
4362 query = "CREATE TABLE `Control` ( "
4363 "`Dialog_` CHAR(72) NOT NULL, `Control` CHAR(50) NOT NULL, `Type` SHORT NOT NULL, "
4364 "`X` SHORT NOT NULL, `Y` SHORT NOT NULL, `Width` SHORT NOT NULL, `Height` SHORT NOT NULL,"
4365 "`Attributes` LONG, `Property` CHAR(50), `Text` CHAR(0) LOCALIZABLE, "
4366 "`Control_Next` CHAR(50), `Help` CHAR(50) LOCALIZABLE PRIMARY KEY `Dialog_`, `Control`)";
4367 r = MsiDatabaseOpenView(hdb, query, &view);
4368 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
4369 r = MsiViewExecute(view, 0);
4370 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
4371 r = MsiViewClose(view);
4372 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
4373 r = MsiCloseHandle(view);
4374 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
4377 query = "INSERT INTO `Control` ( "
4378 "`Dialog_`, `Control`, `Type`, `X`, `Y`, `Width`, `Height`, "
4379 "`Property`, `Text`, `Control_Next`, `Help` )"
4380 "VALUES('ErrorDialog', 'ErrorText', '1', '5', '5', '5', '5', '', '', '', '')";
4381 r = MsiDatabaseOpenView(hdb, query, &view);
4382 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4383 r = MsiViewExecute(view, 0);
4384 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4385 r = MsiViewClose(view);
4386 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
4387 r = MsiCloseHandle(view);
4388 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
4390 /* add a second control */
4391 query = "INSERT INTO `Control` ( "
4392 "`Dialog_`, `Control`, `Type`, `X`, `Y`, `Width`, `Height`, "
4393 "`Property`, `Text`, `Control_Next`, `Help` )"
4394 "VALUES('ErrorDialog', 'Button', '1', '5', '5', '5', '5', '', '', '', '')";
4395 r = MsiDatabaseOpenView(hdb, query, &view);
4396 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4397 r = MsiViewExecute(view, 0);
4398 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4399 r = MsiViewClose(view);
4400 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
4401 r = MsiCloseHandle(view);
4402 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
4404 /* add a third control */
4405 query = "INSERT INTO `Control` ( "
4406 "`Dialog_`, `Control`, `Type`, `X`, `Y`, `Width`, `Height`, "
4407 "`Property`, `Text`, `Control_Next`, `Help` )"
4408 "VALUES('AnotherDialog', 'ErrorText', '1', '5', '5', '5', '5', '', '', '', '')";
4409 r = MsiDatabaseOpenView(hdb, query, &view);
4410 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4411 r = MsiViewExecute(view, 0);
4412 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4413 r = MsiViewClose(view);
4414 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
4415 r = MsiCloseHandle(view);
4416 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
4419 query = "UPDATE `NotATable` SET `Text` = 'this is text' WHERE `Dialog_` = 'ErrorDialog'";
4420 r = MsiDatabaseOpenView(hdb, query, &view);
4421 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
4423 /* bad set column */
4424 query = "UPDATE `Control` SET `NotAColumn` = 'this is text' WHERE `Dialog_` = 'ErrorDialog'";
4425 r = MsiDatabaseOpenView(hdb, query, &view);
4426 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
4428 /* bad where condition */
4429 query = "UPDATE `Control` SET `Text` = 'this is text' WHERE `NotAColumn` = 'ErrorDialog'";
4430 r = MsiDatabaseOpenView(hdb, query, &view);
4431 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
4433 /* just the dialog_ specified */
4434 query = "UPDATE `Control` SET `Text` = 'this is text' WHERE `Dialog_` = 'ErrorDialog'";
4435 r = MsiDatabaseOpenView(hdb, query, &view);
4436 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4437 r = MsiViewExecute(view, 0);
4438 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4439 r = MsiViewClose(view);
4440 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
4441 r = MsiCloseHandle(view);
4442 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
4444 /* check the modified text */
4445 query = "SELECT `Text` FROM `Control` WHERE `Control` = 'ErrorText'";
4446 r = MsiDatabaseOpenView(hdb, query, &view);
4447 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4448 r = MsiViewExecute(view, 0);
4449 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4451 r = MsiViewFetch(view, &rec);
4452 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4455 r = MsiRecordGetString(rec, 1, result, &size);
4456 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4457 ok(!lstrcmp(result, "this is text"), "Expected `this is text`, got %s\n", result);
4459 MsiCloseHandle(rec);
4461 r = MsiViewFetch(view, &rec);
4462 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4465 r = MsiRecordGetString(rec, 1, result, &size);
4466 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4467 ok(!lstrlen(result), "Expected an empty string, got %s\n", result);
4469 MsiCloseHandle(rec);
4471 r = MsiViewFetch(view, &rec);
4472 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
4474 r = MsiViewClose(view);
4475 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
4476 r = MsiCloseHandle(view);
4477 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
4479 /* dialog_ and control specified */
4480 query = "UPDATE `Control` SET `Text` = 'this is text' WHERE `Dialog_` = 'ErrorDialog' AND `Control` = 'ErrorText'";
4481 r = MsiDatabaseOpenView(hdb, query, &view);
4482 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4483 r = MsiViewExecute(view, 0);
4484 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4485 r = MsiViewClose(view);
4486 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
4487 r = MsiCloseHandle(view);
4488 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
4490 /* check the modified text */
4491 query = "SELECT `Text` FROM `Control` WHERE `Control` = 'ErrorText'";
4492 r = MsiDatabaseOpenView(hdb, query, &view);
4493 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4494 r = MsiViewExecute(view, 0);
4495 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4497 r = MsiViewFetch(view, &rec);
4498 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4501 r = MsiRecordGetString(rec, 1, result, &size);
4502 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4503 ok(!lstrcmp(result, "this is text"), "Expected `this is text`, got %s\n", result);
4505 MsiCloseHandle(rec);
4507 r = MsiViewFetch(view, &rec);
4508 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4511 r = MsiRecordGetString(rec, 1, result, &size);
4512 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4513 ok(!lstrlen(result), "Expected an empty string, got %s\n", result);
4515 MsiCloseHandle(rec);
4517 r = MsiViewFetch(view, &rec);
4518 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
4520 r = MsiViewClose(view);
4521 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
4522 r = MsiCloseHandle(view);
4523 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
4525 /* no where condition */
4526 query = "UPDATE `Control` SET `Text` = 'this is text'";
4527 r = MsiDatabaseOpenView(hdb, query, &view);
4528 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4529 r = MsiViewExecute(view, 0);
4530 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4531 r = MsiViewClose(view);
4532 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
4533 r = MsiCloseHandle(view);
4534 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
4536 /* check the modified text */
4537 query = "SELECT `Text` FROM `Control`";
4538 r = MsiDatabaseOpenView(hdb, query, &view);
4539 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4540 r = MsiViewExecute(view, 0);
4541 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4543 r = MsiViewFetch(view, &rec);
4544 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4547 r = MsiRecordGetString(rec, 1, result, &size);
4548 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4549 ok(!lstrcmp(result, "this is text"), "Expected `this is text`, got %s\n", result);
4551 MsiCloseHandle(rec);
4553 r = MsiViewFetch(view, &rec);
4554 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4557 r = MsiRecordGetString(rec, 1, result, &size);
4558 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4559 ok(!lstrcmp(result, "this is text"), "Expected `this is text`, got %s\n", result);
4561 MsiCloseHandle(rec);
4563 r = MsiViewFetch(view, &rec);
4564 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4567 r = MsiRecordGetString(rec, 1, result, &size);
4568 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4569 ok(!lstrcmp(result, "this is text"), "Expected `this is text`, got %s\n", result);
4571 MsiCloseHandle(rec);
4573 r = MsiViewFetch(view, &rec);
4574 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
4576 r = MsiViewClose(view);
4577 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
4578 r = MsiCloseHandle(view);
4579 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
4581 query = "CREATE TABLE `Apple` ( `Banana` CHAR(72) NOT NULL, "
4582 "`Orange` CHAR(72), `Pear` INT PRIMARY KEY `Banana`)";
4583 r = run_query(hdb, 0, query);
4584 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4586 query = "INSERT INTO `Apple` ( `Banana`, `Orange`, `Pear` )"
4587 "VALUES('one', 'two', 3)";
4588 r = run_query(hdb, 0, query);
4589 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4591 query = "INSERT INTO `Apple` ( `Banana`, `Orange`, `Pear` )"
4592 "VALUES('three', 'four', 5)";
4593 r = run_query(hdb, 0, query);
4594 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4596 query = "INSERT INTO `Apple` ( `Banana`, `Orange`, `Pear` )"
4597 "VALUES('six', 'two', 7)";
4598 r = run_query(hdb, 0, query);
4599 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4601 rec = MsiCreateRecord(2);
4602 MsiRecordSetInteger(rec, 1, 8);
4603 MsiRecordSetString(rec, 2, "two");
4605 query = "UPDATE `Apple` SET `Pear` = ? WHERE `Orange` = ?";
4606 r = run_query(hdb, rec, query);
4607 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4609 MsiCloseHandle(rec);
4611 query = "SELECT `Pear` FROM `Apple` ORDER BY `Orange`";
4612 r = MsiDatabaseOpenView(hdb, query, &view);
4613 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4614 r = MsiViewExecute(view, 0);
4615 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4617 r = MsiViewFetch(view, &rec);
4618 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4620 r = MsiRecordGetInteger(rec, 1);
4621 ok(r == 8, "Expected 8, got %d\n", r);
4623 MsiCloseHandle(rec);
4625 r = MsiViewFetch(view, &rec);
4626 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4628 r = MsiRecordGetInteger(rec, 1);
4629 ok(r == 8, "Expected 8, got %d\n", r);
4631 MsiCloseHandle(rec);
4633 r = MsiViewFetch(view, &rec);
4634 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4636 r = MsiRecordGetInteger(rec, 1);
4637 ok(r == 5, "Expected 5, got %d\n", r);
4639 MsiCloseHandle(rec);
4641 r = MsiViewFetch(view, &rec);
4642 ok(r == ERROR_NO_MORE_ITEMS, "Expectd ERROR_NO_MORE_ITEMS, got %d\n", r);
4645 MsiCloseHandle(view);
4647 r = MsiDatabaseCommit(hdb);
4648 ok(r == ERROR_SUCCESS, "MsiDatabaseCommit failed\n");
4649 r = MsiCloseHandle(hdb);
4650 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
4652 DeleteFile(msifile);
4655 static void test_special_tables(void)
4661 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
4662 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n");
4664 query = "CREATE TABLE `_Properties` ( "
4665 "`foo` INT NOT NULL, `bar` INT LOCALIZABLE PRIMARY KEY `foo`)";
4666 r = run_query(hdb, 0, query);
4667 ok(r == ERROR_SUCCESS, "failed to create table\n");
4669 query = "CREATE TABLE `_Storages` ( "
4670 "`foo` INT NOT NULL, `bar` INT LOCALIZABLE PRIMARY KEY `foo`)";
4671 r = run_query(hdb, 0, query);
4672 ok(r == ERROR_BAD_QUERY_SYNTAX, "created _Streams table\n");
4674 query = "CREATE TABLE `_Streams` ( "
4675 "`foo` INT NOT NULL, `bar` INT LOCALIZABLE PRIMARY KEY `foo`)";
4676 r = run_query(hdb, 0, query);
4677 ok(r == ERROR_BAD_QUERY_SYNTAX, "created _Streams table\n");
4679 query = "CREATE TABLE `_Tables` ( "
4680 "`foo` INT NOT NULL, `bar` INT LOCALIZABLE PRIMARY KEY `foo`)";
4681 r = run_query(hdb, 0, query);
4682 ok(r == ERROR_BAD_QUERY_SYNTAX, "created _Tables table\n");
4684 query = "CREATE TABLE `_Columns` ( "
4685 "`foo` INT NOT NULL, `bar` INT LOCALIZABLE PRIMARY KEY `foo`)";
4686 r = run_query(hdb, 0, query);
4687 ok(r == ERROR_BAD_QUERY_SYNTAX, "created _Columns table\n");
4689 r = MsiCloseHandle(hdb);
4690 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
4693 static void test_tables_order(void)
4696 MSIHANDLE hdb = 0, hview = 0, hrec = 0;
4701 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
4702 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n");
4704 query = "CREATE TABLE `foo` ( "
4705 "`baz` INT NOT NULL PRIMARY KEY `baz`)";
4706 r = run_query(hdb, 0, query);
4707 ok(r == ERROR_SUCCESS, "failed to create table\n");
4709 query = "CREATE TABLE `bar` ( "
4710 "`foo` INT NOT NULL PRIMARY KEY `foo`)";
4711 r = run_query(hdb, 0, query);
4712 ok(r == ERROR_SUCCESS, "failed to create table\n");
4714 query = "CREATE TABLE `baz` ( "
4715 "`bar` INT NOT NULL, "
4716 "`baz` INT NOT NULL, "
4717 "`foo` INT NOT NULL PRIMARY KEY `bar`)";
4718 r = run_query(hdb, 0, query);
4719 ok(r == ERROR_SUCCESS, "failed to create table\n");
4721 /* The names of the tables in the _Tables table must
4722 be in the same order as these names are created in
4723 the strings table. */
4724 query = "SELECT * FROM `_Tables`";
4725 r = MsiDatabaseOpenView(hdb, query, &hview);
4726 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
4727 r = MsiViewExecute(hview, 0);
4728 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
4730 r = MsiViewFetch(hview, &hrec);
4731 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
4732 sz = sizeof(buffer);
4733 r = MsiRecordGetString(hrec, 1, buffer, &sz);
4734 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4735 ok(!lstrcmp(buffer, "foo"), "Expected foo, got %s\n", buffer);
4736 r = MsiCloseHandle(hrec);
4737 ok(r == ERROR_SUCCESS, "failed to close record\n");
4739 r = MsiViewFetch(hview, &hrec);
4740 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
4741 sz = sizeof(buffer);
4742 r = MsiRecordGetString(hrec, 1, buffer, &sz);
4743 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4744 ok(!lstrcmp(buffer, "baz"), "Expected baz, got %s\n", buffer);
4745 r = MsiCloseHandle(hrec);
4746 ok(r == ERROR_SUCCESS, "failed to close record\n");
4748 r = MsiViewFetch(hview, &hrec);
4749 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
4750 sz = sizeof(buffer);
4751 r = MsiRecordGetString(hrec, 1, buffer, &sz);
4752 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4753 ok(!lstrcmp(buffer, "bar"), "Expected bar, got %s\n", buffer);
4754 r = MsiCloseHandle(hrec);
4755 ok(r == ERROR_SUCCESS, "failed to close record\n");
4757 r = MsiViewClose(hview);
4758 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
4759 r = MsiCloseHandle(hview);
4760 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
4762 /* The names of the tables in the _Columns table must
4763 be in the same order as these names are created in
4764 the strings table. */
4765 query = "SELECT * FROM `_Columns`";
4766 r = MsiDatabaseOpenView(hdb, query, &hview);
4767 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
4768 r = MsiViewExecute(hview, 0);
4769 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
4771 r = MsiViewFetch(hview, &hrec);
4772 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
4773 sz = sizeof(buffer);
4774 r = MsiRecordGetString(hrec, 1, buffer, &sz);
4775 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4776 ok(!lstrcmp(buffer, "foo"), "Expected foo, got %s\n", buffer);
4777 sz = sizeof(buffer);
4778 r = MsiRecordGetString(hrec, 3, buffer, &sz);
4779 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4780 ok(!lstrcmp(buffer, "baz"), "Expected baz, got %s\n", buffer);
4781 r = MsiCloseHandle(hrec);
4782 ok(r == ERROR_SUCCESS, "failed to close record\n");
4784 r = MsiViewFetch(hview, &hrec);
4785 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
4786 sz = sizeof(buffer);
4787 r = MsiRecordGetString(hrec, 1, buffer, &sz);
4788 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4789 ok(!lstrcmp(buffer, "baz"), "Expected baz, got %s\n", buffer);
4790 sz = sizeof(buffer);
4791 r = MsiRecordGetString(hrec, 3, buffer, &sz);
4792 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4793 ok(!lstrcmp(buffer, "bar"), "Expected bar, got %s\n", buffer);
4794 r = MsiCloseHandle(hrec);
4795 ok(r == ERROR_SUCCESS, "failed to close record\n");
4797 r = MsiViewFetch(hview, &hrec);
4798 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
4799 sz = sizeof(buffer);
4800 r = MsiRecordGetString(hrec, 1, buffer, &sz);
4801 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4802 ok(!lstrcmp(buffer, "baz"), "Expected baz, got %s\n", buffer);
4803 sz = sizeof(buffer);
4804 r = MsiRecordGetString(hrec, 3, buffer, &sz);
4805 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4806 ok(!lstrcmp(buffer, "baz"), "Expected baz, got %s\n", buffer);
4807 r = MsiCloseHandle(hrec);
4808 ok(r == ERROR_SUCCESS, "failed to close record\n");
4810 r = MsiViewFetch(hview, &hrec);
4811 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
4812 sz = sizeof(buffer);
4813 r = MsiRecordGetString(hrec, 1, buffer, &sz);
4814 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4815 ok(!lstrcmp(buffer, "baz"), "Expected baz, got %s\n", buffer);
4816 sz = sizeof(buffer);
4817 r = MsiRecordGetString(hrec, 3, buffer, &sz);
4818 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4819 ok(!lstrcmp(buffer, "foo"), "Expected foo, got %s\n", buffer);
4820 r = MsiCloseHandle(hrec);
4821 ok(r == ERROR_SUCCESS, "failed to close record\n");
4823 r = MsiViewFetch(hview, &hrec);
4824 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
4825 sz = sizeof(buffer);
4826 r = MsiRecordGetString(hrec, 1, buffer, &sz);
4827 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4828 ok(!lstrcmp(buffer, "bar"), "Expected bar, got %s\n", buffer);
4829 sz = sizeof(buffer);
4830 r = MsiRecordGetString(hrec, 3, buffer, &sz);
4831 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4832 ok(!lstrcmp(buffer, "foo"), "Expected foo, got %s\n", buffer);
4833 r = MsiCloseHandle(hrec);
4834 ok(r == ERROR_SUCCESS, "failed to close record\n");
4836 r = MsiViewClose(hview);
4837 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
4838 r = MsiCloseHandle(hview);
4839 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
4841 r = MsiCloseHandle(hdb);
4842 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
4844 DeleteFile(msifile);
4847 static void test_rows_order(void)
4850 MSIHANDLE hdb = 0, hview = 0, hrec = 0;
4855 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
4856 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n");
4858 query = "CREATE TABLE `foo` ( "
4859 "`bar` LONGCHAR NOT NULL PRIMARY KEY `bar`)";
4860 r = run_query(hdb, 0, query);
4861 ok(r == ERROR_SUCCESS, "failed to create table\n");
4863 r = run_query(hdb, 0, "INSERT INTO `foo` "
4864 "( `bar` ) VALUES ( 'A' )");
4865 ok(r == ERROR_SUCCESS, "cannot add value to table\n");
4867 r = run_query(hdb, 0, "INSERT INTO `foo` "
4868 "( `bar` ) VALUES ( 'B' )");
4869 ok(r == ERROR_SUCCESS, "cannot add value to table\n");
4871 r = run_query(hdb, 0, "INSERT INTO `foo` "
4872 "( `bar` ) VALUES ( 'C' )");
4873 ok(r == ERROR_SUCCESS, "cannot add value to table\n");
4875 r = run_query(hdb, 0, "INSERT INTO `foo` "
4876 "( `bar` ) VALUES ( 'D' )");
4877 ok(r == ERROR_SUCCESS, "cannot add value to table\n");
4879 r = run_query(hdb, 0, "INSERT INTO `foo` "
4880 "( `bar` ) VALUES ( 'E' )");
4881 ok(r == ERROR_SUCCESS, "cannot add value to table\n");
4883 r = run_query(hdb, 0, "INSERT INTO `foo` "
4884 "( `bar` ) VALUES ( 'F' )");
4885 ok(r == ERROR_SUCCESS, "cannot add value to table\n");
4887 query = "CREATE TABLE `bar` ( "
4888 "`foo` LONGCHAR NOT NULL, "
4889 "`baz` LONGCHAR NOT NULL "
4890 "PRIMARY KEY `foo` )";
4891 r = run_query(hdb, 0, query);
4892 ok(r == ERROR_SUCCESS, "failed to create table\n");
4894 r = run_query(hdb, 0, "INSERT INTO `bar` "
4895 "( `foo`, `baz` ) VALUES ( 'C', 'E' )");
4896 ok(r == ERROR_SUCCESS, "cannot add value to table\n");
4898 r = run_query(hdb, 0, "INSERT INTO `bar` "
4899 "( `foo`, `baz` ) VALUES ( 'F', 'A' )");
4900 ok(r == ERROR_SUCCESS, "cannot add value to table\n");
4902 r = run_query(hdb, 0, "INSERT INTO `bar` "
4903 "( `foo`, `baz` ) VALUES ( 'A', 'B' )");
4904 ok(r == ERROR_SUCCESS, "cannot add value to table\n");
4906 r = run_query(hdb, 0, "INSERT INTO `bar` "
4907 "( `foo`, `baz` ) VALUES ( 'D', 'E' )");
4908 ok(r == ERROR_SUCCESS, "cannot add value to table\n");
4910 /* The rows of the table must be ordered by the column values of
4911 each row. For strings, the column value is the string id
4912 in the string table. */
4914 query = "SELECT * FROM `bar`";
4915 r = MsiDatabaseOpenView(hdb, query, &hview);
4916 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
4917 r = MsiViewExecute(hview, 0);
4918 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
4920 r = MsiViewFetch(hview, &hrec);
4921 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
4922 sz = sizeof(buffer);
4923 r = MsiRecordGetString(hrec, 1, buffer, &sz);
4924 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4925 ok(!lstrcmp(buffer, "A"), "Expected A, got %s\n", buffer);
4926 sz = sizeof(buffer);
4927 r = MsiRecordGetString(hrec, 2, buffer, &sz);
4928 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4929 ok(!lstrcmp(buffer, "B"), "Expected B, got %s\n", buffer);
4930 r = MsiCloseHandle(hrec);
4931 ok(r == ERROR_SUCCESS, "failed to close record\n");
4933 r = MsiViewFetch(hview, &hrec);
4934 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
4935 sz = sizeof(buffer);
4936 r = MsiRecordGetString(hrec, 1, buffer, &sz);
4937 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4938 ok(!lstrcmp(buffer, "C"), "Expected E, got %s\n", buffer);
4939 sz = sizeof(buffer);
4940 r = MsiRecordGetString(hrec, 2, buffer, &sz);
4941 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4942 ok(!lstrcmp(buffer, "E"), "Expected E, got %s\n", buffer);
4943 r = MsiCloseHandle(hrec);
4944 ok(r == ERROR_SUCCESS, "failed to close record\n");
4946 r = MsiViewFetch(hview, &hrec);
4947 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
4948 sz = sizeof(buffer);
4949 r = MsiRecordGetString(hrec, 1, buffer, &sz);
4950 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4951 ok(!lstrcmp(buffer, "D"), "Expected D, got %s\n", buffer);
4952 sz = sizeof(buffer);
4953 r = MsiRecordGetString(hrec, 2, buffer, &sz);
4954 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4955 ok(!lstrcmp(buffer, "E"), "Expected E, got %s\n", buffer);
4956 r = MsiCloseHandle(hrec);
4957 ok(r == ERROR_SUCCESS, "failed to close record\n");
4959 r = MsiViewFetch(hview, &hrec);
4960 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
4961 sz = sizeof(buffer);
4962 r = MsiRecordGetString(hrec, 1, buffer, &sz);
4963 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4964 ok(!lstrcmp(buffer, "F"), "Expected F, got %s\n", buffer);
4965 sz = sizeof(buffer);
4966 r = MsiRecordGetString(hrec, 2, buffer, &sz);
4967 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4968 ok(!lstrcmp(buffer, "A"), "Expected A, got %s\n", buffer);
4969 r = MsiCloseHandle(hrec);
4970 ok(r == ERROR_SUCCESS, "failed to close record\n");
4972 r = MsiViewClose(hview);
4973 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
4974 r = MsiCloseHandle(hview);
4975 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
4977 r = MsiCloseHandle(hdb);
4978 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
4980 DeleteFile(msifile);
4983 static void test_collation(void)
4985 static const WCHAR query1[] =
4986 {'I','N','S','E','R','T',' ','I','N','T','O',' ','`','b','a','r','`',' ',
4987 '(','`','f','o','o','`',',','`','b','a','z','`',')',' ','V','A','L','U','E','S',' ',
4988 '(','\'','a',0x30a,'\'',',','\'','C','\'',')',0};
4989 static const WCHAR query2[] =
4990 {'I','N','S','E','R','T',' ','I','N','T','O',' ','`','b','a','r','`',' ',
4991 '(','`','f','o','o','`',',','`','b','a','z','`',')',' ','V','A','L','U','E','S',' ',
4992 '(','\'',0xe5,'\'',',','\'','D','\'',')',0};
4993 static const WCHAR query3[] =
4994 {'C','R','E','A','T','E',' ','T','A','B','L','E',' ','`','b','a','z','`',' ',
4995 '(',' ','`','a',0x30a,'`',' ','L','O','N','G','C','H','A','R',' ','N','O','T',' ','N','U','L','L',',',
4996 ' ','`',0xe5,'`',' ','L','O','N','G','C','H','A','R',' ','N','O','T',' ','N','U','L','L',' ',
4997 'P','R','I','M','A','R','Y',' ','K','E','Y',' ','`','a',0x30a,'`',')',0};
4998 static const WCHAR query4[] =
4999 {'C','R','E','A','T','E',' ','T','A','B','L','E',' ','`','a',0x30a,'`',' ',
5000 '(',' ','`','f','o','o','`',' ','L','O','N','G','C','H','A','R',' ','N','O','T',' ',
5001 'N','U','L','L',' ','P','R','I','M','A','R','Y',' ','K','E','Y',' ','`','f','o','o','`',')',0};
5002 static const WCHAR query5[] =
5003 {'C','R','E','A','T','E',' ','T','A','B','L','E',' ','`',0xe5,'`',' ',
5004 '(',' ','`','f','o','o','`',' ','L','O','N','G','C','H','A','R',' ','N','O','T',' ',
5005 'N','U','L','L',' ','P','R','I','M','A','R','Y',' ','K','E','Y',' ','`','f','o','o','`',')',0};
5006 static const WCHAR query6[] =
5007 {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','`','b','a','r','`',' ','W','H','E','R','E',
5008 ' ','`','f','o','o','`',' ','=','\'',0xe5,'\'',0};
5009 static const WCHAR letter_C[] = {'C',0};
5010 static const WCHAR letter_D[] = {'D',0};
5011 static const WCHAR letter_a_ring[] = {'a',0x30a,0};
5012 static const WCHAR letter_a_with_ring[] = {0xe5,0};
5014 MSIHANDLE hdb = 0, hview = 0, hrec = 0;
5020 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
5021 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n");
5023 query = "CREATE TABLE `bar` ( "
5024 "`foo` LONGCHAR NOT NULL, "
5025 "`baz` LONGCHAR NOT NULL "
5026 "PRIMARY KEY `foo` )";
5027 r = run_query(hdb, 0, query);
5028 ok(r == ERROR_SUCCESS, "failed to create table\n");
5030 r = run_query(hdb, 0, query);
5031 ok(r == ERROR_BAD_QUERY_SYNTAX, "wrong error %u\n", r);
5033 r = run_query(hdb, 0, "INSERT INTO `bar` "
5034 "( `foo`, `baz` ) VALUES ( '\2', 'A' )");
5035 ok(r == ERROR_SUCCESS, "cannot add value to table %u\n", r);
5037 r = run_query(hdb, 0, "INSERT INTO `bar` "
5038 "( `foo`, `baz` ) VALUES ( '\1', 'B' )");
5039 ok(r == ERROR_SUCCESS, "cannot add value to table %u\n", r);
5041 r = run_queryW(hdb, 0, query1);
5042 ok(r == ERROR_SUCCESS, "cannot add value to table %u\n", r);
5044 r = run_queryW(hdb, 0, query2);
5045 ok(r == ERROR_SUCCESS, "cannot add value to table %u\n", r);
5047 r = run_queryW(hdb, 0, query3);
5048 ok(r == ERROR_SUCCESS, "cannot create table %u\n", r);
5050 r = run_queryW(hdb, 0, query4);
5051 ok(r == ERROR_SUCCESS, "cannot create table %u\n", r);
5053 r = run_queryW(hdb, 0, query5);
5054 ok(r == ERROR_SUCCESS, "cannot create table %u\n", r);
5056 query = "SELECT * FROM `bar`";
5057 r = MsiDatabaseOpenView(hdb, query, &hview);
5058 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
5059 r = MsiViewExecute(hview, 0);
5060 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
5062 r = MsiViewFetch(hview, &hrec);
5063 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
5064 sz = sizeof(buffer);
5065 r = MsiRecordGetString(hrec, 1, buffer, &sz);
5066 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5067 ok(!lstrcmp(buffer, "\2"), "Expected \\2, got '%s'\n", buffer);
5068 sz = sizeof(buffer);
5069 r = MsiRecordGetString(hrec, 2, buffer, &sz);
5070 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5071 ok(!lstrcmp(buffer, "A"), "Expected A, got '%s'\n", buffer);
5072 MsiCloseHandle(hrec);
5074 r = MsiViewFetch(hview, &hrec);
5075 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
5076 sz = sizeof(buffer);
5077 r = MsiRecordGetString(hrec, 1, buffer, &sz);
5078 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5079 ok(!lstrcmp(buffer, "\1"), "Expected \\1, got '%s'\n", buffer);
5080 sz = sizeof(buffer);
5081 r = MsiRecordGetString(hrec, 2, buffer, &sz);
5082 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5083 ok(!lstrcmp(buffer, "B"), "Expected B, got '%s'\n", buffer);
5084 MsiCloseHandle(hrec);
5086 r = MsiViewFetch(hview, &hrec);
5087 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
5088 sz = sizeof(bufferW) / sizeof(bufferW[0]);
5089 r = MsiRecordGetStringW(hrec, 1, bufferW, &sz);
5090 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5091 ok(!memcmp(bufferW, letter_a_ring, sizeof(letter_a_ring)),
5092 "Expected %s, got %s\n", wine_dbgstr_w(letter_a_ring), wine_dbgstr_w(bufferW));
5093 sz = sizeof(bufferW) / sizeof(bufferW[0]);
5094 r = MsiRecordGetStringW(hrec, 2, bufferW, &sz);
5095 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5096 ok(!lstrcmpW(bufferW, letter_C), "Expected C, got %s\n", wine_dbgstr_w(bufferW));
5097 MsiCloseHandle(hrec);
5099 r = MsiViewFetch(hview, &hrec);
5100 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
5101 sz = sizeof(bufferW) / sizeof(bufferW[0]);
5102 r = MsiRecordGetStringW(hrec, 1, bufferW, &sz);
5103 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5104 ok(!memcmp(bufferW, letter_a_with_ring, sizeof(letter_a_with_ring)),
5105 "Expected %s, got %s\n", wine_dbgstr_w(letter_a_with_ring), wine_dbgstr_w(bufferW));
5106 sz = sizeof(bufferW) / sizeof(bufferW[0]);
5107 r = MsiRecordGetStringW(hrec, 2, bufferW, &sz);
5108 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5109 ok(!lstrcmpW(bufferW, letter_D), "Expected D, got %s\n", wine_dbgstr_w(bufferW));
5110 MsiCloseHandle(hrec);
5112 r = MsiViewClose(hview);
5113 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
5114 r = MsiCloseHandle(hview);
5115 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
5117 r = MsiDatabaseOpenViewW(hdb, query6, &hview);
5118 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
5119 r = MsiViewExecute(hview, 0);
5120 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
5122 r = MsiViewFetch(hview, &hrec);
5123 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
5124 sz = sizeof(bufferW) / sizeof(bufferW[0]);
5125 r = MsiRecordGetStringW(hrec, 1, bufferW, &sz);
5126 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5127 ok(!memcmp(bufferW, letter_a_with_ring, sizeof(letter_a_with_ring)),
5128 "Expected %s, got %s\n", wine_dbgstr_w(letter_a_with_ring), wine_dbgstr_w(bufferW));
5129 sz = sizeof(bufferW) / sizeof(bufferW[0]);
5130 r = MsiRecordGetStringW(hrec, 2, bufferW, &sz);
5131 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5132 ok(!lstrcmpW(bufferW, letter_D), "Expected D, got %s\n", wine_dbgstr_w(bufferW));
5133 MsiCloseHandle(hrec);
5135 r = MsiViewFetch(hview, &hrec);
5136 ok(r == ERROR_NO_MORE_ITEMS, "MsiViewFetch failed\n");
5138 r = MsiViewClose(hview);
5139 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
5140 r = MsiCloseHandle(hview);
5141 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
5143 r = MsiCloseHandle(hdb);
5144 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
5146 DeleteFile(msifile);
5149 static void test_select_markers(void)
5151 MSIHANDLE hdb = 0, rec, view, res;
5158 ok( hdb, "failed to create db\n");
5160 r = run_query(hdb, 0,
5161 "CREATE TABLE `Table` (`One` CHAR(72), `Two` CHAR(72), `Three` SHORT PRIMARY KEY `One`, `Two`, `Three`)");
5162 ok(r == S_OK, "cannot create table: %d\n", r);
5164 r = run_query(hdb, 0, "INSERT INTO `Table` "
5165 "( `One`, `Two`, `Three` ) VALUES ( 'apple', 'one', 1 )");
5166 ok(r == S_OK, "cannot add file to the Media table: %d\n", r);
5168 r = run_query(hdb, 0, "INSERT INTO `Table` "
5169 "( `One`, `Two`, `Three` ) VALUES ( 'apple', 'two', 1 )");
5170 ok(r == S_OK, "cannot add file to the Media table: %d\n", r);
5172 r = run_query(hdb, 0, "INSERT INTO `Table` "
5173 "( `One`, `Two`, `Three` ) VALUES ( 'apple', 'two', 2 )");
5174 ok(r == S_OK, "cannot add file to the Media table: %d\n", r);
5176 r = run_query(hdb, 0, "INSERT INTO `Table` "
5177 "( `One`, `Two`, `Three` ) VALUES ( 'banana', 'three', 3 )");
5178 ok(r == S_OK, "cannot add file to the Media table: %d\n", r);
5180 rec = MsiCreateRecord(2);
5181 MsiRecordSetString(rec, 1, "apple");
5182 MsiRecordSetString(rec, 2, "two");
5184 query = "SELECT * FROM `Table` WHERE `One`=? AND `Two`=? ORDER BY `Three`";
5185 r = MsiDatabaseOpenView(hdb, query, &view);
5186 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5188 r = MsiViewExecute(view, rec);
5189 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5191 r = MsiViewFetch(view, &res);
5192 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5195 r = MsiRecordGetString(res, 1, buf, &size);
5196 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5197 ok(!lstrcmp(buf, "apple"), "Expected apple, got %s\n", buf);
5200 r = MsiRecordGetString(res, 2, buf, &size);
5201 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5202 ok(!lstrcmp(buf, "two"), "Expected two, got %s\n", buf);
5204 r = MsiRecordGetInteger(res, 3);
5205 ok(r == 1, "Expected 1, got %d\n", r);
5207 MsiCloseHandle(res);
5209 r = MsiViewFetch(view, &res);
5210 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5213 r = MsiRecordGetString(res, 1, buf, &size);
5214 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5215 ok(!lstrcmp(buf, "apple"), "Expected apple, got %s\n", buf);
5218 r = MsiRecordGetString(res, 2, buf, &size);
5219 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5220 ok(!lstrcmp(buf, "two"), "Expected two, got %s\n", buf);
5222 r = MsiRecordGetInteger(res, 3);
5223 ok(r == 2, "Expected 2, got %d\n", r);
5225 MsiCloseHandle(res);
5227 r = MsiViewFetch(view, &res);
5228 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
5230 MsiCloseHandle(rec);
5232 MsiCloseHandle(view);
5234 rec = MsiCreateRecord(2);
5235 MsiRecordSetString(rec, 1, "one");
5236 MsiRecordSetInteger(rec, 2, 1);
5238 query = "SELECT * FROM `Table` WHERE `Two`<>? AND `Three`>? ORDER BY `Three`";
5239 r = MsiDatabaseOpenView(hdb, query, &view);
5240 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5241 r = MsiViewExecute(view, rec);
5242 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5244 r = MsiViewFetch(view, &res);
5245 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5248 r = MsiRecordGetString(res, 1, buf, &size);
5249 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5250 ok(!lstrcmp(buf, "apple"), "Expected apple, got %s\n", buf);
5253 r = MsiRecordGetString(res, 2, buf, &size);
5254 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5255 ok(!lstrcmp(buf, "two"), "Expected two, got %s\n", buf);
5257 r = MsiRecordGetInteger(res, 3);
5258 ok(r == 2, "Expected 2, got %d\n", r);
5260 MsiCloseHandle(res);
5262 r = MsiViewFetch(view, &res);
5263 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5266 r = MsiRecordGetString(res, 1, buf, &size);
5267 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5268 ok(!lstrcmp(buf, "banana"), "Expected banana, got %s\n", buf);
5271 r = MsiRecordGetString(res, 2, buf, &size);
5272 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5273 ok(!lstrcmp(buf, "three"), "Expected three, got %s\n", buf);
5275 r = MsiRecordGetInteger(res, 3);
5276 ok(r == 3, "Expected 3, got %d\n", r);
5278 MsiCloseHandle(res);
5280 r = MsiViewFetch(view, &res);
5281 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
5283 MsiCloseHandle(rec);
5285 MsiCloseHandle(view);
5286 MsiCloseHandle(hdb);
5287 DeleteFile(msifile);
5290 static void test_viewmodify_update(void)
5292 MSIHANDLE hdb = 0, hview = 0, hrec = 0;
5293 UINT i, test_max, offset, count;
5297 DeleteFile(msifile);
5299 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
5300 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n");
5302 query = "CREATE TABLE `table` (`A` INT, `B` INT PRIMARY KEY `A`)";
5303 r = run_query( hdb, 0, query );
5304 ok(r == ERROR_SUCCESS, "query failed\n");
5306 query = "INSERT INTO `table` (`A`, `B`) VALUES (1, 2)";
5307 r = run_query( hdb, 0, query );
5308 ok(r == ERROR_SUCCESS, "query failed\n");
5310 query = "INSERT INTO `table` (`A`, `B`) VALUES (3, 4)";
5311 r = run_query( hdb, 0, query );
5312 ok(r == ERROR_SUCCESS, "query failed\n");
5314 query = "INSERT INTO `table` (`A`, `B`) VALUES (5, 6)";
5315 r = run_query( hdb, 0, query );
5316 ok(r == ERROR_SUCCESS, "query failed\n");
5318 query = "SELECT `B` FROM `table`";
5319 r = MsiDatabaseOpenView(hdb, query, &hview);
5320 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
5321 r = MsiViewExecute(hview, 0);
5322 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
5323 r = MsiViewFetch(hview, &hrec);
5324 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
5326 r = MsiRecordSetInteger(hrec, 1, 0);
5327 ok(r == ERROR_SUCCESS, "failed to set integer\n");
5329 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec);
5330 ok(r == ERROR_SUCCESS, "MsiViewModify failed: %d\n", r);
5332 r = MsiCloseHandle(hrec);
5333 ok(r == ERROR_SUCCESS, "failed to close record\n");
5335 r = MsiViewClose(hview);
5336 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
5337 r = MsiCloseHandle(hview);
5338 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
5340 query = "SELECT * FROM `table`";
5341 r = MsiDatabaseOpenView(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 r = MsiViewFetch(hview, &hrec);
5346 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
5348 r = MsiRecordGetInteger(hrec, 1);
5349 ok(r == 1, "Expected 1, got %d\n", r);
5350 r = MsiRecordGetInteger(hrec, 2);
5351 ok(r == 0, "Expected 0, got %d\n", r);
5353 r = MsiCloseHandle(hrec);
5354 ok(r == ERROR_SUCCESS, "failed to close record\n");
5356 r = MsiViewFetch(hview, &hrec);
5357 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
5359 r = MsiRecordGetInteger(hrec, 1);
5360 ok(r == 3, "Expected 3, got %d\n", r);
5361 r = MsiRecordGetInteger(hrec, 2);
5362 ok(r == 4, "Expected 4, got %d\n", r);
5364 r = MsiCloseHandle(hrec);
5365 ok(r == ERROR_SUCCESS, "failed to close record\n");
5367 r = MsiViewFetch(hview, &hrec);
5368 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
5370 r = MsiRecordGetInteger(hrec, 1);
5371 ok(r == 5, "Expected 5, got %d\n", r);
5372 r = MsiRecordGetInteger(hrec, 2);
5373 ok(r == 6, "Expected 6, got %d\n", r);
5375 r = MsiCloseHandle(hrec);
5376 ok(r == ERROR_SUCCESS, "failed to close record\n");
5378 r = MsiViewFetch(hview, &hrec);
5379 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
5381 r = MsiViewClose(hview);
5382 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
5383 r = MsiCloseHandle(hview);
5384 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
5386 /* loop through all elements */
5387 query = "SELECT `B` FROM `table`";
5388 r = MsiDatabaseOpenView(hdb, query, &hview);
5389 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
5390 r = MsiViewExecute(hview, 0);
5391 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
5395 r = MsiViewFetch(hview, &hrec);
5396 if (r != ERROR_SUCCESS)
5399 r = MsiRecordSetInteger(hrec, 1, 0);
5400 ok(r == ERROR_SUCCESS, "failed to set integer\n");
5402 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec);
5403 ok(r == ERROR_SUCCESS, "MsiViewModify failed: %d\n", r);
5405 r = MsiCloseHandle(hrec);
5406 ok(r == ERROR_SUCCESS, "failed to close record\n");
5409 r = MsiViewClose(hview);
5410 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
5411 r = MsiCloseHandle(hview);
5412 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
5414 query = "SELECT * FROM `table`";
5415 r = MsiDatabaseOpenView(hdb, query, &hview);
5416 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
5417 r = MsiViewExecute(hview, 0);
5418 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
5419 r = MsiViewFetch(hview, &hrec);
5420 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
5422 r = MsiRecordGetInteger(hrec, 1);
5423 ok(r == 1, "Expected 1, got %d\n", r);
5424 r = MsiRecordGetInteger(hrec, 2);
5425 ok(r == 0, "Expected 0, got %d\n", r);
5427 r = MsiCloseHandle(hrec);
5428 ok(r == ERROR_SUCCESS, "failed to close record\n");
5430 r = MsiViewFetch(hview, &hrec);
5431 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
5433 r = MsiRecordGetInteger(hrec, 1);
5434 ok(r == 3, "Expected 3, got %d\n", r);
5435 r = MsiRecordGetInteger(hrec, 2);
5436 ok(r == 0, "Expected 0, got %d\n", r);
5438 r = MsiCloseHandle(hrec);
5439 ok(r == ERROR_SUCCESS, "failed to close record\n");
5441 r = MsiViewFetch(hview, &hrec);
5442 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
5444 r = MsiRecordGetInteger(hrec, 1);
5445 ok(r == 5, "Expected 5, got %d\n", r);
5446 r = MsiRecordGetInteger(hrec, 2);
5447 ok(r == 0, "Expected 0, got %d\n", r);
5449 r = MsiCloseHandle(hrec);
5450 ok(r == ERROR_SUCCESS, "failed to close record\n");
5452 r = MsiViewFetch(hview, &hrec);
5453 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
5455 r = MsiViewClose(hview);
5456 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
5457 r = MsiCloseHandle(hview);
5458 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
5460 query = "CREATE TABLE `table2` (`A` INT, `B` INT PRIMARY KEY `A`)";
5461 r = run_query( hdb, 0, query );
5462 ok(r == ERROR_SUCCESS, "query failed\n");
5464 query = "INSERT INTO `table2` (`A`, `B`) VALUES (?, ?)";
5465 r = MsiDatabaseOpenView( hdb, query, &hview );
5466 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
5470 for(i = 0; i < test_max; i++)
5473 hrec = MsiCreateRecord( 2 );
5474 MsiRecordSetInteger( hrec, 1, test_max - i );
5475 MsiRecordSetInteger( hrec, 2, i );
5477 r = MsiViewExecute( hview, hrec );
5478 ok(r == ERROR_SUCCESS, "Got %d\n", r);
5480 r = MsiCloseHandle( hrec );
5481 ok(r == ERROR_SUCCESS, "Got %d\n", r);
5484 r = MsiViewClose( hview );
5485 ok(r == ERROR_SUCCESS, "Got %d\n", r);
5486 r = MsiCloseHandle( hview );
5487 ok(r == ERROR_SUCCESS, "Got %d\n", r);
5490 query = "SELECT * FROM `table2` ORDER BY `B`";
5491 r = MsiDatabaseOpenView( hdb, query, &hview);
5492 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
5493 r = MsiViewExecute( hview, 0 );
5494 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
5497 while (MsiViewFetch( hview, &hrec ) == ERROR_SUCCESS)
5499 UINT b = MsiRecordGetInteger( hrec, 2 );
5501 r = MsiRecordSetInteger( hrec, 2, b + offset);
5502 ok(r == ERROR_SUCCESS, "Got %d\n", r);
5504 r = MsiViewModify( hview, MSIMODIFY_UPDATE, hrec );
5505 ok(r == ERROR_SUCCESS, "Got %d\n", r);
5507 r = MsiCloseHandle(hrec);
5508 ok(r == ERROR_SUCCESS, "failed to close record\n");
5511 ok(count == test_max, "Got count %d\n", count);
5513 r = MsiViewClose(hview);
5514 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
5515 r = MsiCloseHandle(hview);
5516 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
5519 query = "SELECT * FROM `table2` ORDER BY `B`";
5520 r = MsiDatabaseOpenView( hdb, query, &hview);
5521 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
5522 r = MsiViewExecute( hview, 0 );
5523 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
5526 while (MsiViewFetch( hview, &hrec ) == ERROR_SUCCESS)
5528 UINT a = MsiRecordGetInteger( hrec, 1 );
5529 UINT b = MsiRecordGetInteger( hrec, 2 );
5530 ok( ( test_max - a + offset) == b, "Got (%d, %d), expected (%d, %d)\n",
5531 a, b, test_max - a + offset, b);
5533 r = MsiCloseHandle(hrec);
5534 ok(r == ERROR_SUCCESS, "failed to close record\n");
5537 ok(count == test_max, "Got count %d\n", count);
5539 r = MsiViewClose(hview);
5540 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
5541 r = MsiCloseHandle(hview);
5542 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
5544 r = MsiCloseHandle( hdb );
5545 ok(r == ERROR_SUCCESS, "MsiOpenDatabase close failed\n");
5548 static void test_viewmodify_assign(void)
5550 MSIHANDLE hdb = 0, hview = 0, hrec = 0;
5554 /* setup database */
5555 DeleteFile(msifile);
5557 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
5558 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n");
5560 query = "CREATE TABLE `table` (`A` INT, `B` INT PRIMARY KEY `A`)";
5561 r = run_query( hdb, 0, query );
5562 ok(r == ERROR_SUCCESS, "query failed\n");
5564 /* assign to view, new primary key */
5565 query = "SELECT * FROM `table`";
5566 r = MsiDatabaseOpenView(hdb, query, &hview);
5567 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
5568 r = MsiViewExecute(hview, 0);
5569 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
5571 hrec = MsiCreateRecord(2);
5572 ok(hrec != 0, "MsiCreateRecord failed\n");
5574 r = MsiRecordSetInteger(hrec, 1, 1);
5575 ok(r == ERROR_SUCCESS, "failed to set integer\n");
5576 r = MsiRecordSetInteger(hrec, 2, 2);
5577 ok(r == ERROR_SUCCESS, "failed to set integer\n");
5579 r = MsiViewModify(hview, MSIMODIFY_ASSIGN, hrec);
5580 ok(r == ERROR_SUCCESS, "MsiViewModify failed: %d\n", r);
5582 r = MsiCloseHandle(hrec);
5583 ok(r == ERROR_SUCCESS, "failed to close record\n");
5585 r = MsiViewClose(hview);
5586 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
5587 r = MsiCloseHandle(hview);
5588 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
5590 query = "SELECT * FROM `table`";
5591 r = MsiDatabaseOpenView(hdb, query, &hview);
5592 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
5593 r = MsiViewExecute(hview, 0);
5594 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
5595 r = MsiViewFetch(hview, &hrec);
5596 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
5598 r = MsiRecordGetInteger(hrec, 1);
5599 ok(r == 1, "Expected 1, got %d\n", r);
5600 r = MsiRecordGetInteger(hrec, 2);
5601 ok(r == 2, "Expected 2, got %d\n", r);
5603 r = MsiCloseHandle(hrec);
5604 ok(r == ERROR_SUCCESS, "failed to close record\n");
5606 r = MsiViewFetch(hview, &hrec);
5607 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
5609 r = MsiViewClose(hview);
5610 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
5611 r = MsiCloseHandle(hview);
5612 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
5614 /* assign to view, primary key matches */
5615 query = "SELECT * FROM `table`";
5616 r = MsiDatabaseOpenView(hdb, query, &hview);
5617 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
5618 r = MsiViewExecute(hview, 0);
5619 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
5621 hrec = MsiCreateRecord(2);
5622 ok(hrec != 0, "MsiCreateRecord failed\n");
5624 r = MsiRecordSetInteger(hrec, 1, 1);
5625 ok(r == ERROR_SUCCESS, "failed to set integer\n");
5626 r = MsiRecordSetInteger(hrec, 2, 4);
5627 ok(r == ERROR_SUCCESS, "failed to set integer\n");
5629 r = MsiViewModify(hview, MSIMODIFY_ASSIGN, hrec);
5630 ok(r == ERROR_SUCCESS, "MsiViewModify failed: %d\n", r);
5632 r = MsiCloseHandle(hrec);
5633 ok(r == ERROR_SUCCESS, "failed to close record\n");
5635 r = MsiViewClose(hview);
5636 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
5637 r = MsiCloseHandle(hview);
5638 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
5640 query = "SELECT * FROM `table`";
5641 r = MsiDatabaseOpenView(hdb, query, &hview);
5642 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
5643 r = MsiViewExecute(hview, 0);
5644 ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
5645 r = MsiViewFetch(hview, &hrec);
5646 ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
5648 r = MsiRecordGetInteger(hrec, 1);
5649 ok(r == 1, "Expected 1, got %d\n", r);
5650 r = MsiRecordGetInteger(hrec, 2);
5651 ok(r == 4, "Expected 4, got %d\n", r);
5653 r = MsiCloseHandle(hrec);
5654 ok(r == ERROR_SUCCESS, "failed to close record\n");
5656 r = MsiViewFetch(hview, &hrec);
5657 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
5659 r = MsiViewClose(hview);
5660 ok(r == ERROR_SUCCESS, "MsiViewClose failed\n");
5661 r = MsiCloseHandle(hview);
5662 ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n");
5664 /* close database */
5665 r = MsiCloseHandle( hdb );
5666 ok(r == ERROR_SUCCESS, "MsiOpenDatabase close failed\n");
5669 static const WCHAR data10[] = { /* MOO */
5672 static const WCHAR data11[] = { /* AAR */
5676 static const char data12[] = /* _StringData */
5677 "MOOABAARCDonetwofourfive";
5678 static const WCHAR data13[] = { /* _StringPool */
5680 0, 0, /* string 0 '' */
5681 0, 0, /* string 1 '' */
5682 0, 0, /* string 2 '' */
5683 0, 0, /* string 3 '' */
5684 0, 0, /* string 4 '' */
5685 3, 3, /* string 5 'MOO' */
5686 1, 1, /* string 6 'A' */
5687 1, 1, /* string 7 'B' */
5688 3, 3, /* string 8 'AAR' */
5689 1, 1, /* string 9 'C' */
5690 1, 1, /* string a 'D' */
5691 3, 1, /* string b 'one' */
5692 3, 1, /* string c 'two' */
5693 0, 0, /* string d '' */
5694 4, 1, /* string e 'four' */
5695 4, 1, /* string f 'five' */
5698 static void test_stringtable(void)
5700 MSIHANDLE hdb = 0, hview = 0, hrec = 0;
5701 IStorage *stg = NULL;
5706 char buffer[MAX_PATH];
5707 WCHAR data[MAX_PATH];
5711 static const DWORD mode = STGM_DIRECT | STGM_READ | STGM_SHARE_DENY_WRITE;
5712 static const WCHAR stringdata[] = {0x4840, 0x3f3f, 0x4577, 0x446c, 0x3b6a, 0x45e4, 0x4824, 0}; /* _StringData */
5713 static const WCHAR stringpool[] = {0x4840, 0x3f3f, 0x4577, 0x446c, 0x3e6a, 0x44b2, 0x482f, 0}; /* _StringPool */
5714 static const WCHAR moo[] = {0x4840, 0x3e16, 0x4818, 0}; /* MOO */
5715 static const WCHAR aar[] = {0x4840, 0x3a8a, 0x481b, 0}; /* AAR */
5717 DeleteFile(msifile);
5719 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
5720 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5722 query = "CREATE TABLE `MOO` (`A` INT, `B` CHAR(72) PRIMARY KEY `A`)";
5723 r = run_query(hdb, 0, query);
5724 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5726 query = "CREATE TABLE `AAR` (`C` INT, `D` CHAR(72) PRIMARY KEY `C`)";
5727 r = run_query(hdb, 0, query);
5728 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5730 /* insert persistent row */
5731 query = "INSERT INTO `MOO` (`A`, `B`) VALUES (1, 'one')";
5732 r = run_query(hdb, 0, query);
5733 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5735 /* insert persistent row */
5736 query = "INSERT INTO `AAR` (`C`, `D`) VALUES (2, 'two')";
5737 r = run_query(hdb, 0, query);
5738 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5741 query = "SELECT * FROM `MOO`";
5742 r = MsiDatabaseOpenView(hdb, query, &hview);
5743 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5744 r = MsiViewExecute(hview, 0);
5745 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5747 hrec = MsiCreateRecord(2);
5749 r = MsiRecordSetInteger(hrec, 1, 3);
5750 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5751 r = MsiRecordSetString(hrec, 2, "three");
5752 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5754 /* insert a nonpersistent row */
5755 r = MsiViewModify(hview, MSIMODIFY_INSERT_TEMPORARY, hrec);
5756 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5758 r = MsiCloseHandle(hrec);
5759 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5760 r = MsiViewClose(hview);
5761 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5762 r = MsiCloseHandle(hview);
5763 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5765 /* insert persistent row */
5766 query = "INSERT INTO `MOO` (`A`, `B`) VALUES (4, 'four')";
5767 r = run_query(hdb, 0, query);
5768 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5770 /* insert persistent row */
5771 query = "INSERT INTO `AAR` (`C`, `D`) VALUES (5, 'five')";
5772 r = run_query(hdb, 0, query);
5773 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5775 r = MsiDatabaseCommit(hdb);
5776 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5778 r = MsiCloseHandle(hdb);
5779 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5781 r = MsiOpenDatabase(msifile, MSIDBOPEN_READONLY, &hdb);
5782 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5784 query = "SELECT * FROM `MOO`";
5785 r = MsiDatabaseOpenView(hdb, query, &hview);
5786 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5788 r = MsiViewExecute(hview, 0);
5789 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5791 r = MsiViewFetch(hview, &hrec);
5792 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5794 r = MsiRecordGetFieldCount(hrec);
5795 ok(r == 2, "Expected 2, got %d\n", r);
5797 r = MsiRecordGetInteger(hrec, 1);
5798 ok(r == 1, "Expected 1, got %d\n", r);
5800 sz = sizeof(buffer);
5801 r = MsiRecordGetString(hrec, 2, buffer, &sz);
5802 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5803 ok(!lstrcmp(buffer, "one"), "Expected one, got '%s'\n", buffer);
5805 r = MsiCloseHandle(hrec);
5806 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5808 r = MsiViewFetch(hview, &hrec);
5809 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
5811 r = MsiViewClose(hview);
5812 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5813 r = MsiCloseHandle(hview);
5814 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5815 r = MsiCloseHandle(hrec);
5816 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5818 query = "SELECT * FROM `AAR`";
5819 r = MsiDatabaseOpenView(hdb, query, &hview);
5820 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5822 r = MsiViewExecute(hview, 0);
5823 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5825 r = MsiViewFetch(hview, &hrec);
5826 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5828 r = MsiRecordGetFieldCount(hrec);
5829 ok(r == 2, "Expected 2, got %d\n", r);
5831 r = MsiRecordGetInteger(hrec, 1);
5832 ok(r == 2, "Expected 2, got %d\n", r);
5834 sz = sizeof(buffer);
5835 r = MsiRecordGetString(hrec, 2, buffer, &sz);
5836 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5837 ok(!lstrcmp(buffer, "two"), "Expected two, got '%s'\n", buffer);
5839 r = MsiCloseHandle(hrec);
5840 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5842 r = MsiViewFetch(hview, &hrec);
5843 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5845 r = MsiRecordGetFieldCount(hrec);
5846 ok(r == 2, "Expected 2, got %d\n", r);
5848 r = MsiRecordGetInteger(hrec, 1);
5849 ok(r == 5, "Expected 5, got %d\n", r);
5851 sz = sizeof(buffer);
5852 r = MsiRecordGetString(hrec, 2, buffer, &sz);
5853 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5854 ok(!lstrcmp(buffer, "five"), "Expected five, got '%s'\n", buffer);
5856 r = MsiCloseHandle(hrec);
5857 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5859 r = MsiViewFetch(hview, &hrec);
5860 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
5862 r = MsiViewClose(hview);
5863 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5864 r = MsiCloseHandle(hview);
5865 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5866 r = MsiCloseHandle(hrec);
5867 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5868 r = MsiCloseHandle(hdb);
5869 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5871 MultiByteToWideChar(CP_ACP, 0, msifile, -1, name, 0x20);
5872 hr = StgOpenStorage(name, NULL, mode, NULL, 0, &stg);
5873 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
5874 ok(stg != NULL, "Expected non-NULL storage\n");
5876 hr = IStorage_OpenStream(stg, moo, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stm);
5877 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
5878 ok(stm != NULL, "Expected non-NULL stream\n");
5880 hr = IStream_Read(stm, data, MAX_PATH, &read);
5881 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
5882 ok(read == 4, "Expected 4, got %d\n", read);
5883 todo_wine ok(!memcmp(data, data10, read), "Unexpected data\n");
5885 hr = IStream_Release(stm);
5886 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
5888 hr = IStorage_OpenStream(stg, aar, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stm);
5889 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
5890 ok(stm != NULL, "Expected non-NULL stream\n");
5892 hr = IStream_Read(stm, data, MAX_PATH, &read);
5893 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
5894 ok(read == 8, "Expected 8, got %d\n", read);
5897 ok(!memcmp(data, data11, read), "Unexpected data\n");
5900 hr = IStream_Release(stm);
5901 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
5903 hr = IStorage_OpenStream(stg, stringdata, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stm);
5904 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
5905 ok(stm != NULL, "Expected non-NULL stream\n");
5907 hr = IStream_Read(stm, buffer, MAX_PATH, &read);
5908 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
5909 ok(read == 24, "Expected 24, got %d\n", read);
5910 ok(!memcmp(buffer, data12, read), "Unexpected data\n");
5912 hr = IStream_Release(stm);
5913 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
5915 hr = IStorage_OpenStream(stg, stringpool, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stm);
5916 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
5917 ok(stm != NULL, "Expected non-NULL stream\n");
5919 hr = IStream_Read(stm, data, MAX_PATH, &read);
5920 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
5923 ok(read == 64, "Expected 64, got %d\n", read);
5924 ok(!memcmp(data, data13, read), "Unexpected data\n");
5927 hr = IStream_Release(stm);
5928 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
5930 hr = IStorage_Release(stg);
5931 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
5933 DeleteFileA(msifile);
5936 static void test_viewmodify_delete(void)
5938 MSIHANDLE hdb = 0, hview = 0, hrec = 0;
5944 DeleteFile(msifile);
5946 /* just MsiOpenDatabase should not create a file */
5947 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
5948 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5950 query = "CREATE TABLE `phone` ( "
5951 "`id` INT, `name` CHAR(32), `number` CHAR(32) "
5952 "PRIMARY KEY `id`)";
5953 r = run_query(hdb, 0, query);
5954 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5956 query = "INSERT INTO `phone` ( `id`, `name`, `number` )"
5957 "VALUES('1', 'Alan', '5030581')";
5958 r = run_query(hdb, 0, query);
5959 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5961 query = "INSERT INTO `phone` ( `id`, `name`, `number` )"
5962 "VALUES('2', 'Barry', '928440')";
5963 r = run_query(hdb, 0, query);
5964 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5966 query = "INSERT INTO `phone` ( `id`, `name`, `number` )"
5967 "VALUES('3', 'Cindy', '2937550')";
5968 r = run_query(hdb, 0, query);
5969 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5971 query = "SELECT * FROM `phone` WHERE `id` <= 2";
5972 r = MsiDatabaseOpenView(hdb, query, &hview);
5973 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5974 r = MsiViewExecute(hview, 0);
5975 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5976 r = MsiViewFetch(hview, &hrec);
5977 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5980 r = MsiViewModify(hview, MSIMODIFY_DELETE, hrec);
5981 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5983 r = MsiCloseHandle(hrec);
5984 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5985 r = MsiViewFetch(hview, &hrec);
5986 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5989 r = MsiViewModify(hview, MSIMODIFY_DELETE, hrec);
5990 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5992 r = MsiCloseHandle(hrec);
5993 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5994 r = MsiViewClose(hview);
5995 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5996 r = MsiCloseHandle(hview);
5997 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5999 query = "SELECT * FROM `phone`";
6000 r = MsiDatabaseOpenView(hdb, query, &hview);
6001 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6002 r = MsiViewExecute(hview, 0);
6003 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6004 r = MsiViewFetch(hview, &hrec);
6005 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6007 r = MsiRecordGetInteger(hrec, 1);
6008 ok(r == 3, "Expected 3, got %d\n", r);
6010 sz = sizeof(buffer);
6011 r = MsiRecordGetString(hrec, 2, buffer, &sz);
6012 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6013 ok(!lstrcmp(buffer, "Cindy"), "Expected Cindy, got %s\n", buffer);
6015 sz = sizeof(buffer);
6016 r = MsiRecordGetString(hrec, 3, buffer, &sz);
6017 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6018 ok(!lstrcmp(buffer, "2937550"), "Expected 2937550, got %s\n", buffer);
6020 r = MsiCloseHandle(hrec);
6021 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6023 r = MsiViewFetch(hview, &hrec);
6024 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
6026 r = MsiViewClose(hview);
6027 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6028 r = MsiCloseHandle(hview);
6029 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6030 r = MsiCloseHandle(hdb);
6031 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6034 static const WCHAR _Tables[] = {0x4840, 0x3f7f, 0x4164, 0x422f, 0x4836, 0};
6035 static const WCHAR _StringData[] = {0x4840, 0x3f3f, 0x4577, 0x446c, 0x3b6a, 0x45e4, 0x4824, 0};
6036 static const WCHAR _StringPool[] = {0x4840, 0x3f3f, 0x4577, 0x446c, 0x3e6a, 0x44b2, 0x482f, 0};
6038 static const WCHAR data14[] = { /* _StringPool */
6040 0, 0, /* string 0 '' */
6043 static const struct {
6047 } database_table_data[] =
6050 {_StringData, NULL, 0},
6051 {_StringPool, data14, sizeof data14},
6054 static void enum_stream_names(IStorage *stg)
6056 IEnumSTATSTG *stgenum = NULL;
6061 BYTE data[MAX_PATH];
6062 BYTE check[MAX_PATH];
6065 memset(check, 'a', MAX_PATH);
6067 hr = IStorage_EnumElements(stg, 0, NULL, 0, &stgenum);
6068 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
6074 hr = IEnumSTATSTG_Next(stgenum, 1, &stat, &count);
6075 if(FAILED(hr) || !count)
6078 ok(!lstrcmpW(stat.pwcsName, database_table_data[n].name),
6079 "Expected table %d name to match\n", n);
6082 hr = IStorage_OpenStream(stg, stat.pwcsName, NULL,
6083 STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stm);
6084 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
6085 ok(stm != NULL, "Expected non-NULL stream\n");
6087 CoTaskMemFree(stat.pwcsName);
6090 memset(data, 'a', MAX_PATH);
6091 hr = IStream_Read(stm, data, sz, &count);
6092 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
6094 ok(count == database_table_data[n].size,
6095 "Expected %d, got %d\n", database_table_data[n].size, count);
6097 if (!database_table_data[n].size)
6098 ok(!memcmp(data, check, MAX_PATH), "data should not be changed\n");
6100 ok(!memcmp(data, database_table_data[n].data, database_table_data[n].size),
6101 "Expected table %d data to match\n", n);
6103 IStream_Release(stm);
6107 ok(n == 3, "Expected 3, got %d\n", n);
6109 IEnumSTATSTG_Release(stgenum);
6112 static void test_defaultdatabase(void)
6117 IStorage *stg = NULL;
6119 DeleteFile(msifile);
6121 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
6122 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6124 r = MsiDatabaseCommit(hdb);
6125 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6127 MsiCloseHandle(hdb);
6129 hr = StgOpenStorage(msifileW, NULL, STGM_READ | STGM_SHARE_DENY_WRITE, NULL, 0, &stg);
6130 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
6131 ok(stg != NULL, "Expected non-NULL stg\n");
6133 enum_stream_names(stg);
6135 IStorage_Release(stg);
6136 DeleteFileA(msifile);
6139 static void test_order(void)
6141 MSIHANDLE hdb, hview, hrec;
6142 CHAR buffer[MAX_PATH];
6148 ok(hdb, "failed to create db\n");
6150 query = "CREATE TABLE `Empty` ( `A` SHORT NOT NULL PRIMARY KEY `A`)";
6151 r = run_query(hdb, 0, query);
6152 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6154 query = "CREATE TABLE `Mesa` ( `A` SHORT NOT NULL, `B` SHORT, `C` SHORT PRIMARY KEY `A`)";
6155 r = run_query(hdb, 0, query);
6156 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6158 query = "INSERT INTO `Mesa` ( `A`, `B`, `C` ) VALUES ( 1, 2, 9 )";
6159 r = run_query(hdb, 0, query);
6160 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6162 query = "INSERT INTO `Mesa` ( `A`, `B`, `C` ) VALUES ( 3, 4, 7 )";
6163 r = run_query(hdb, 0, query);
6164 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6166 query = "INSERT INTO `Mesa` ( `A`, `B`, `C` ) VALUES ( 5, 6, 8 )";
6167 r = run_query(hdb, 0, query);
6168 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6170 query = "CREATE TABLE `Sideboard` ( `D` SHORT NOT NULL, `E` SHORT, `F` SHORT PRIMARY KEY `D`)";
6171 r = run_query(hdb, 0, query);
6172 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6174 query = "INSERT INTO `Sideboard` ( `D`, `E`, `F` ) VALUES ( 10, 11, 18 )";
6175 r = run_query(hdb, 0, query);
6176 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6178 query = "INSERT INTO `Sideboard` ( `D`, `E`, `F` ) VALUES ( 12, 13, 16 )";
6179 r = run_query(hdb, 0, query);
6180 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6182 query = "INSERT INTO `Sideboard` ( `D`, `E`, `F` ) VALUES ( 14, 15, 17 )";
6183 r = run_query(hdb, 0, query);
6184 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6186 query = "SELECT `A`, `B` FROM `Mesa` ORDER BY `C`";
6187 r = MsiDatabaseOpenView(hdb, query, &hview);
6188 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6189 r = MsiViewExecute(hview, 0);
6190 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6192 r = MsiViewFetch(hview, &hrec);
6193 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6195 val = MsiRecordGetInteger(hrec, 1);
6196 ok(val == 3, "Expected 3, got %d\n", val);
6198 val = MsiRecordGetInteger(hrec, 2);
6199 ok(val == 4, "Expected 3, got %d\n", val);
6201 MsiCloseHandle(hrec);
6203 r = MsiViewFetch(hview, &hrec);
6204 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6206 val = MsiRecordGetInteger(hrec, 1);
6207 ok(val == 5, "Expected 5, got %d\n", val);
6209 val = MsiRecordGetInteger(hrec, 2);
6210 ok(val == 6, "Expected 6, got %d\n", val);
6212 MsiCloseHandle(hrec);
6214 r = MsiViewFetch(hview, &hrec);
6215 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6217 val = MsiRecordGetInteger(hrec, 1);
6218 ok(val == 1, "Expected 1, got %d\n", val);
6220 val = MsiRecordGetInteger(hrec, 2);
6221 ok(val == 2, "Expected 2, got %d\n", val);
6223 MsiCloseHandle(hrec);
6225 r = MsiViewFetch(hview, &hrec);
6226 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
6228 MsiViewClose(hview);
6229 MsiCloseHandle(hview);
6231 query = "SELECT `A`, `D` FROM `Mesa`, `Sideboard` ORDER BY `F`";
6232 r = MsiDatabaseOpenView(hdb, query, &hview);
6233 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6234 r = MsiViewExecute(hview, 0);
6235 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6237 r = MsiViewFetch(hview, &hrec);
6238 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6240 val = MsiRecordGetInteger(hrec, 1);
6241 ok(val == 1, "Expected 1, got %d\n", val);
6243 val = MsiRecordGetInteger(hrec, 2);
6244 ok(val == 12, "Expected 12, got %d\n", val);
6246 MsiCloseHandle(hrec);
6248 r = MsiViewFetch(hview, &hrec);
6249 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6251 val = MsiRecordGetInteger(hrec, 1);
6252 ok(val == 3, "Expected 3, got %d\n", val);
6254 val = MsiRecordGetInteger(hrec, 2);
6255 ok(val == 12, "Expected 12, got %d\n", val);
6257 MsiCloseHandle(hrec);
6259 r = MsiViewFetch(hview, &hrec);
6260 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6262 val = MsiRecordGetInteger(hrec, 1);
6263 ok(val == 5, "Expected 5, got %d\n", val);
6265 val = MsiRecordGetInteger(hrec, 2);
6266 ok(val == 12, "Expected 12, got %d\n", val);
6268 MsiCloseHandle(hrec);
6270 r = MsiViewFetch(hview, &hrec);
6271 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6273 val = MsiRecordGetInteger(hrec, 1);
6274 ok(val == 1, "Expected 1, got %d\n", val);
6276 val = MsiRecordGetInteger(hrec, 2);
6277 ok(val == 14, "Expected 14, got %d\n", val);
6279 MsiCloseHandle(hrec);
6281 r = MsiViewFetch(hview, &hrec);
6282 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6284 val = MsiRecordGetInteger(hrec, 1);
6285 ok(val == 3, "Expected 3, got %d\n", val);
6287 val = MsiRecordGetInteger(hrec, 2);
6288 ok(val == 14, "Expected 14, got %d\n", val);
6290 MsiCloseHandle(hrec);
6292 r = MsiViewFetch(hview, &hrec);
6293 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6295 val = MsiRecordGetInteger(hrec, 1);
6296 ok(val == 5, "Expected 5, got %d\n", val);
6298 val = MsiRecordGetInteger(hrec, 2);
6299 ok(val == 14, "Expected 14, got %d\n", val);
6301 MsiCloseHandle(hrec);
6303 r = MsiViewFetch(hview, &hrec);
6304 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6306 val = MsiRecordGetInteger(hrec, 1);
6307 ok(val == 1, "Expected 1, got %d\n", val);
6309 val = MsiRecordGetInteger(hrec, 2);
6310 ok(val == 10, "Expected 10, got %d\n", val);
6312 MsiCloseHandle(hrec);
6314 r = MsiViewFetch(hview, &hrec);
6315 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6317 val = MsiRecordGetInteger(hrec, 1);
6318 ok(val == 3, "Expected 3, got %d\n", val);
6320 val = MsiRecordGetInteger(hrec, 2);
6321 ok(val == 10, "Expected 10, got %d\n", val);
6323 MsiCloseHandle(hrec);
6325 r = MsiViewFetch(hview, &hrec);
6326 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6328 val = MsiRecordGetInteger(hrec, 1);
6329 ok(val == 5, "Expected 5, got %d\n", val);
6331 val = MsiRecordGetInteger(hrec, 2);
6332 ok(val == 10, "Expected 10, got %d\n", val);
6334 MsiCloseHandle(hrec);
6336 r = MsiViewFetch(hview, &hrec);
6337 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
6339 MsiViewClose(hview);
6340 MsiCloseHandle(hview);
6342 query = "SELECT * FROM `Empty` ORDER BY `A`";
6343 r = MsiDatabaseOpenView(hdb, query, &hview);
6344 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6345 r = MsiViewExecute(hview, 0);
6346 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6348 r = MsiViewFetch(hview, &hrec);
6349 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
6351 MsiViewClose(hview);
6352 MsiCloseHandle(hview);
6354 query = "CREATE TABLE `Buffet` ( `One` CHAR(72), `Two` SHORT PRIMARY KEY `One`)";
6355 r = run_query(hdb, 0, query);
6356 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6358 query = "INSERT INTO `Buffet` ( `One`, `Two` ) VALUES ( 'uno', 2)";
6359 r = run_query(hdb, 0, query);
6360 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6362 query = "INSERT INTO `Buffet` ( `One`, `Two` ) VALUES ( 'dos', 3)";
6363 r = run_query(hdb, 0, query);
6364 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6366 query = "INSERT INTO `Buffet` ( `One`, `Two` ) VALUES ( 'tres', 1)";
6367 r = run_query(hdb, 0, query);
6368 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6370 query = "SELECT * FROM `Buffet` WHERE `One` = 'dos' ORDER BY `Two`";
6371 r = MsiDatabaseOpenView(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);
6376 r = MsiViewFetch(hview, &hrec);
6377 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6379 sz = sizeof(buffer);
6380 r = MsiRecordGetString(hrec, 1, buffer, &sz);
6381 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6382 ok(!lstrcmp(buffer, "dos"), "Expected \"dos\", got \"%s\"\n", buffer);
6384 r = MsiRecordGetInteger(hrec, 2);
6385 ok(r == 3, "Expected 3, got %d\n", r);
6387 MsiCloseHandle(hrec);
6389 r = MsiViewFetch(hview, &hrec);
6390 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
6392 MsiViewClose(hview);
6393 MsiCloseHandle(hview);
6394 MsiCloseHandle(hdb);
6397 static void test_viewmodify_delete_temporary(void)
6399 MSIHANDLE hdb, hview, hrec;
6403 DeleteFile(msifile);
6405 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
6406 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6408 query = "CREATE TABLE `Table` ( `A` SHORT PRIMARY KEY `A` )";
6409 r = run_query(hdb, 0, query);
6410 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6412 query = "SELECT * FROM `Table`";
6413 r = MsiDatabaseOpenView(hdb, query, &hview);
6414 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6415 r = MsiViewExecute(hview, 0);
6416 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6418 hrec = MsiCreateRecord(1);
6419 MsiRecordSetInteger(hrec, 1, 1);
6421 r = MsiViewModify(hview, MSIMODIFY_INSERT, hrec);
6422 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6424 MsiCloseHandle(hrec);
6426 hrec = MsiCreateRecord(1);
6427 MsiRecordSetInteger(hrec, 1, 2);
6429 r = MsiViewModify(hview, MSIMODIFY_INSERT_TEMPORARY, hrec);
6430 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6432 MsiCloseHandle(hrec);
6434 hrec = MsiCreateRecord(1);
6435 MsiRecordSetInteger(hrec, 1, 3);
6437 r = MsiViewModify(hview, MSIMODIFY_INSERT, hrec);
6438 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6440 MsiCloseHandle(hrec);
6442 hrec = MsiCreateRecord(1);
6443 MsiRecordSetInteger(hrec, 1, 4);
6445 r = MsiViewModify(hview, MSIMODIFY_INSERT_TEMPORARY, hrec);
6446 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6448 MsiCloseHandle(hrec);
6449 MsiViewClose(hview);
6450 MsiCloseHandle(hview);
6452 query = "SELECT * FROM `Table` WHERE `A` = 2";
6453 r = MsiDatabaseOpenView(hdb, query, &hview);
6454 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6455 r = MsiViewExecute(hview, 0);
6456 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6457 r = MsiViewFetch(hview, &hrec);
6458 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6460 r = MsiViewModify(hview, MSIMODIFY_DELETE, hrec);
6461 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6463 MsiCloseHandle(hrec);
6464 MsiViewClose(hview);
6465 MsiCloseHandle(hview);
6467 query = "SELECT * FROM `Table` WHERE `A` = 3";
6468 r = MsiDatabaseOpenView(hdb, query, &hview);
6469 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6470 r = MsiViewExecute(hview, 0);
6471 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6472 r = MsiViewFetch(hview, &hrec);
6473 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6475 r = MsiViewModify(hview, MSIMODIFY_DELETE, hrec);
6476 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6478 MsiCloseHandle(hrec);
6479 MsiViewClose(hview);
6480 MsiCloseHandle(hview);
6482 query = "SELECT * FROM `Table` ORDER BY `A`";
6483 r = MsiDatabaseOpenView(hdb, query, &hview);
6484 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6485 r = MsiViewExecute(hview, 0);
6486 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6488 r = MsiViewFetch(hview, &hrec);
6489 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6491 r = MsiRecordGetInteger(hrec, 1);
6492 ok(r == 1, "Expected 1, got %d\n", r);
6494 MsiCloseHandle(hrec);
6496 r = MsiViewFetch(hview, &hrec);
6497 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6499 r = MsiRecordGetInteger(hrec, 1);
6500 ok(r == 4, "Expected 4, got %d\n", r);
6502 MsiCloseHandle(hrec);
6504 r = MsiViewFetch(hview, &hrec);
6505 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
6507 MsiViewClose(hview);
6508 MsiCloseHandle(hview);
6509 MsiCloseHandle(hdb);
6510 DeleteFileA(msifile);
6513 static void test_deleterow(void)
6515 MSIHANDLE hdb, hview, hrec;
6521 DeleteFile(msifile);
6523 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
6524 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6526 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )";
6527 r = run_query(hdb, 0, query);
6528 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6530 query = "INSERT INTO `Table` (`A`) VALUES ('one')";
6531 r = run_query(hdb, 0, query);
6532 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6534 query = "INSERT INTO `Table` (`A`) VALUES ('two')";
6535 r = run_query(hdb, 0, query);
6536 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6538 query = "DELETE FROM `Table` WHERE `A` = 'one'";
6539 r = run_query(hdb, 0, query);
6540 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6542 r = MsiDatabaseCommit(hdb);
6543 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6545 MsiCloseHandle(hdb);
6547 r = MsiOpenDatabase(msifile, MSIDBOPEN_READONLY, &hdb);
6548 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6550 query = "SELECT * FROM `Table`";
6551 r = MsiDatabaseOpenView(hdb, query, &hview);
6552 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6553 r = MsiViewExecute(hview, 0);
6554 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6556 r = MsiViewFetch(hview, &hrec);
6557 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6560 r = MsiRecordGetStringA(hrec, 1, buf, &size);
6561 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6562 ok(!lstrcmpA(buf, "two"), "Expected two, got %s\n", buf);
6564 MsiCloseHandle(hrec);
6566 r = MsiViewFetch(hview, &hrec);
6567 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
6569 MsiViewClose(hview);
6570 MsiCloseHandle(hview);
6571 MsiCloseHandle(hdb);
6572 DeleteFileA(msifile);
6575 static const CHAR import_dat[] = "A\n"
6578 "This is a new 'string' ok\n";
6580 static void test_quotes(void)
6582 MSIHANDLE hdb, hview, hrec;
6588 DeleteFile(msifile);
6590 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
6591 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6593 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )";
6594 r = run_query(hdb, 0, query);
6595 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6597 query = "INSERT INTO `Table` ( `A` ) VALUES ( 'This is a 'string' ok' )";
6598 r = run_query(hdb, 0, query);
6599 ok(r == ERROR_BAD_QUERY_SYNTAX,
6600 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6602 query = "INSERT INTO `Table` ( `A` ) VALUES ( \"This is a 'string' ok\" )";
6603 r = run_query(hdb, 0, query);
6604 ok(r == ERROR_BAD_QUERY_SYNTAX,
6605 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6607 query = "INSERT INTO `Table` ( `A` ) VALUES ( \"test\" )";
6608 r = run_query(hdb, 0, query);
6609 ok(r == ERROR_BAD_QUERY_SYNTAX,
6610 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6612 query = "INSERT INTO `Table` ( `A` ) VALUES ( 'This is a ''string'' ok' )";
6613 r = run_query(hdb, 0, query);
6614 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6616 query = "INSERT INTO `Table` ( `A` ) VALUES ( 'This is a '''string''' ok' )";
6617 r = run_query(hdb, 0, query);
6618 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6620 query = "INSERT INTO `Table` ( `A` ) VALUES ( 'This is a \'string\' ok' )";
6621 r = run_query(hdb, 0, query);
6622 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6624 query = "INSERT INTO `Table` ( `A` ) VALUES ( 'This is a \"string\" ok' )";
6625 r = run_query(hdb, 0, query);
6626 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6628 query = "SELECT * FROM `Table`";
6629 r = MsiDatabaseOpenView(hdb, query, &hview);
6630 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6632 r = MsiViewExecute(hview, 0);
6633 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6635 r = MsiViewFetch(hview, &hrec);
6636 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6639 r = MsiRecordGetString(hrec, 1, buf, &size);
6640 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6641 ok(!lstrcmp(buf, "This is a \"string\" ok"),
6642 "Expected \"This is a \"string\" ok\", got %s\n", buf);
6644 MsiCloseHandle(hrec);
6646 r = MsiViewFetch(hview, &hrec);
6647 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
6649 MsiViewClose(hview);
6650 MsiCloseHandle(hview);
6652 write_file("import.idt", import_dat, (sizeof(import_dat) - 1) * sizeof(char));
6654 r = MsiDatabaseImportA(hdb, CURR_DIR, "import.idt");
6655 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6657 DeleteFileA("import.idt");
6659 query = "SELECT * FROM `Table`";
6660 r = MsiDatabaseOpenView(hdb, query, &hview);
6661 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6663 r = MsiViewExecute(hview, 0);
6664 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6666 r = MsiViewFetch(hview, &hrec);
6667 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6670 r = MsiRecordGetString(hrec, 1, buf, &size);
6671 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6672 ok(!lstrcmp(buf, "This is a new 'string' ok"),
6673 "Expected \"This is a new 'string' ok\", got %s\n", buf);
6675 MsiCloseHandle(hrec);
6677 r = MsiViewFetch(hview, &hrec);
6678 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
6680 MsiViewClose(hview);
6681 MsiCloseHandle(hview);
6682 MsiCloseHandle(hdb);
6683 DeleteFileA(msifile);
6686 static void test_carriagereturn(void)
6688 MSIHANDLE hdb, hview, hrec;
6694 DeleteFile(msifile);
6696 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
6697 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6699 query = "CREATE TABLE `Table`\r ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )";
6700 r = run_query(hdb, 0, query);
6701 ok(r == ERROR_BAD_QUERY_SYNTAX,
6702 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6704 query = "CREATE TABLE `Table` \r( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )";
6705 r = run_query(hdb, 0, query);
6706 ok(r == ERROR_BAD_QUERY_SYNTAX,
6707 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6709 query = "CREATE\r TABLE `Table` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )";
6710 r = run_query(hdb, 0, query);
6711 ok(r == ERROR_BAD_QUERY_SYNTAX,
6712 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6714 query = "CREATE TABLE\r `Table` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )";
6715 r = run_query(hdb, 0, query);
6716 ok(r == ERROR_BAD_QUERY_SYNTAX,
6717 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6719 query = "CREATE TABLE `Table` (\r `A` CHAR(72) NOT NULL PRIMARY KEY `A` )";
6720 r = run_query(hdb, 0, query);
6721 ok(r == ERROR_BAD_QUERY_SYNTAX,
6722 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6724 query = "CREATE TABLE `Table` ( `A`\r CHAR(72) NOT NULL PRIMARY KEY `A` )";
6725 r = run_query(hdb, 0, query);
6726 ok(r == ERROR_BAD_QUERY_SYNTAX,
6727 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6729 query = "CREATE TABLE `Table` ( `A` CHAR(72)\r NOT NULL PRIMARY KEY `A` )";
6730 r = run_query(hdb, 0, query);
6731 ok(r == ERROR_BAD_QUERY_SYNTAX,
6732 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6734 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT\r NULL PRIMARY KEY `A` )";
6735 r = run_query(hdb, 0, query);
6736 ok(r == ERROR_BAD_QUERY_SYNTAX,
6737 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6739 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT \rNULL PRIMARY KEY `A` )";
6740 r = run_query(hdb, 0, query);
6741 ok(r == ERROR_BAD_QUERY_SYNTAX,
6742 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6744 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL\r PRIMARY KEY `A` )";
6745 r = run_query(hdb, 0, query);
6746 ok(r == ERROR_BAD_QUERY_SYNTAX,
6747 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6749 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL \rPRIMARY KEY `A` )";
6750 r = run_query(hdb, 0, query);
6751 ok(r == ERROR_BAD_QUERY_SYNTAX,
6752 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6754 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL PRIMARY\r KEY `A` )";
6755 r = run_query(hdb, 0, query);
6756 ok(r == ERROR_BAD_QUERY_SYNTAX,
6757 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6759 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL PRIMARY \rKEY `A` )";
6760 r = run_query(hdb, 0, query);
6761 ok(r == ERROR_BAD_QUERY_SYNTAX,
6762 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6764 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL PRIMARY KEY\r `A` )";
6765 r = run_query(hdb, 0, query);
6766 ok(r == ERROR_BAD_QUERY_SYNTAX,
6767 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6769 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A`\r )";
6770 r = run_query(hdb, 0, query);
6771 ok(r == ERROR_BAD_QUERY_SYNTAX,
6772 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6774 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )\r";
6775 r = run_query(hdb, 0, query);
6776 ok(r == ERROR_BAD_QUERY_SYNTAX,
6777 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6779 query = "CREATE TABLE `\rOne` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )";
6780 r = run_query(hdb, 0, query);
6781 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6783 query = "CREATE TABLE `Tw\ro` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )";
6784 r = run_query(hdb, 0, query);
6785 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6787 query = "CREATE TABLE `Three\r` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )";
6788 r = run_query(hdb, 0, query);
6789 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6791 query = "CREATE TABLE `Four` ( `A\r` CHAR(72) NOT NULL PRIMARY KEY `A` )";
6792 r = run_query(hdb, 0, query);
6793 ok(r == ERROR_BAD_QUERY_SYNTAX,
6794 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6796 query = "CREATE TABLE `Four` ( `\rA` CHAR(72) NOT NULL PRIMARY KEY `A` )";
6797 r = run_query(hdb, 0, query);
6798 ok(r == ERROR_BAD_QUERY_SYNTAX,
6799 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6801 query = "CREATE TABLE `Four` ( `A` CHAR(72\r) NOT NULL PRIMARY KEY `A` )";
6802 r = run_query(hdb, 0, query);
6803 ok(r == ERROR_BAD_QUERY_SYNTAX,
6804 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6806 query = "CREATE TABLE `Four` ( `A` CHAR(\r72) NOT NULL PRIMARY KEY `A` )";
6807 r = run_query(hdb, 0, query);
6808 ok(r == ERROR_BAD_QUERY_SYNTAX,
6809 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6811 query = "CREATE TABLE `Four` ( `A` CHAR(72) NOT NULL PRIMARY KEY `\rA` )";
6812 r = run_query(hdb, 0, query);
6813 ok(r == ERROR_BAD_QUERY_SYNTAX,
6814 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6816 query = "CREATE TABLE `Four` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A\r` )";
6817 r = run_query(hdb, 0, query);
6818 ok(r == ERROR_BAD_QUERY_SYNTAX,
6819 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6821 query = "CREATE TABLE `Four` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A\r` )";
6822 r = run_query(hdb, 0, query);
6823 ok(r == ERROR_BAD_QUERY_SYNTAX,
6824 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6826 query = "SELECT * FROM `_Tables`";
6827 r = MsiDatabaseOpenView(hdb, query, &hview);
6828 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6829 r = MsiViewExecute(hview, 0);
6830 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6832 r = MsiViewFetch(hview, &hrec);
6833 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6836 r = MsiRecordGetStringA(hrec, 1, buf, &size);
6837 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6838 ok(!lstrcmpA(buf, "\rOne"), "Expected \"\\rOne\", got \"%s\"\n", buf);
6840 MsiCloseHandle(hrec);
6842 r = MsiViewFetch(hview, &hrec);
6843 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6846 r = MsiRecordGetStringA(hrec, 1, buf, &size);
6847 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6848 ok(!lstrcmpA(buf, "Tw\ro"), "Expected \"Tw\\ro\", got \"%s\"\n", buf);
6850 MsiCloseHandle(hrec);
6852 r = MsiViewFetch(hview, &hrec);
6853 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6856 r = MsiRecordGetStringA(hrec, 1, buf, &size);
6857 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6858 ok(!lstrcmpA(buf, "Three\r"), "Expected \"Three\r\", got \"%s\"\n", buf);
6860 MsiCloseHandle(hrec);
6862 r = MsiViewFetch(hview, &hrec);
6863 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
6865 MsiViewClose(hview);
6866 MsiCloseHandle(hview);
6868 MsiCloseHandle(hdb);
6869 DeleteFileA(msifile);
6872 static void test_noquotes(void)
6874 MSIHANDLE hdb, hview, hrec;
6880 DeleteFile(msifile);
6882 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
6883 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6885 query = "CREATE TABLE Table ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )";
6886 r = run_query(hdb, 0, query);
6887 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
6889 query = "CREATE TABLE `Table` ( A CHAR(72) NOT NULL PRIMARY KEY `A` )";
6890 r = run_query(hdb, 0, query);
6891 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6893 query = "CREATE TABLE `Table2` ( `A` CHAR(72) NOT NULL PRIMARY KEY A )";
6894 r = run_query(hdb, 0, query);
6895 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6897 query = "CREATE TABLE `Table3` ( A CHAR(72) NOT NULL PRIMARY KEY A )";
6898 r = run_query(hdb, 0, query);
6899 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6901 query = "SELECT * FROM `_Tables`";
6902 r = MsiDatabaseOpenView(hdb, query, &hview);
6903 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6904 r = MsiViewExecute(hview, 0);
6905 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6907 r = MsiViewFetch(hview, &hrec);
6908 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6911 r = MsiRecordGetStringA(hrec, 1, buf, &size);
6912 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6913 ok(!lstrcmpA(buf, "Table"), "Expected \"Table\", got \"%s\"\n", buf);
6915 MsiCloseHandle(hrec);
6917 r = MsiViewFetch(hview, &hrec);
6918 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6921 r = MsiRecordGetStringA(hrec, 1, buf, &size);
6922 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6923 ok(!lstrcmpA(buf, "Table2"), "Expected \"Table2\", got \"%s\"\n", buf);
6925 MsiCloseHandle(hrec);
6927 r = MsiViewFetch(hview, &hrec);
6928 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6931 r = MsiRecordGetStringA(hrec, 1, buf, &size);
6932 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6933 ok(!lstrcmpA(buf, "Table3"), "Expected \"Table3\", got \"%s\"\n", buf);
6935 MsiCloseHandle(hrec);
6937 r = MsiViewFetch(hview, &hrec);
6938 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
6940 MsiViewClose(hview);
6941 MsiCloseHandle(hview);
6943 query = "SELECT * FROM `_Columns`";
6944 r = MsiDatabaseOpenView(hdb, query, &hview);
6945 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6946 r = MsiViewExecute(hview, 0);
6947 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6949 r = MsiViewFetch(hview, &hrec);
6950 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6953 r = MsiRecordGetStringA(hrec, 1, buf, &size);
6954 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6955 ok(!lstrcmpA(buf, "Table"), "Expected \"Table\", got \"%s\"\n", buf);
6957 r = MsiRecordGetInteger(hrec, 2);
6958 ok(r == 1, "Expected 1, got %d\n", r);
6961 r = MsiRecordGetStringA(hrec, 3, buf, &size);
6962 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6963 ok(!lstrcmpA(buf, "A"), "Expected \"A\", got \"%s\"\n", buf);
6965 MsiCloseHandle(hrec);
6967 r = MsiViewFetch(hview, &hrec);
6968 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6971 r = MsiRecordGetStringA(hrec, 1, buf, &size);
6972 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6973 ok(!lstrcmpA(buf, "Table2"), "Expected \"Table2\", got \"%s\"\n", buf);
6975 r = MsiRecordGetInteger(hrec, 2);
6976 ok(r == 1, "Expected 1, got %d\n", r);
6979 r = MsiRecordGetStringA(hrec, 3, buf, &size);
6980 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6981 ok(!lstrcmpA(buf, "A"), "Expected \"A\", got \"%s\"\n", buf);
6983 MsiCloseHandle(hrec);
6985 r = MsiViewFetch(hview, &hrec);
6986 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6989 r = MsiRecordGetStringA(hrec, 1, buf, &size);
6990 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6991 ok(!lstrcmpA(buf, "Table3"), "Expected \"Table3\", got \"%s\"\n", buf);
6993 r = MsiRecordGetInteger(hrec, 2);
6994 ok(r == 1, "Expected 1, got %d\n", r);
6997 r = MsiRecordGetStringA(hrec, 3, buf, &size);
6998 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6999 ok(!lstrcmpA(buf, "A"), "Expected \"A\", got \"%s\"\n", buf);
7001 MsiCloseHandle(hrec);
7003 r = MsiViewFetch(hview, &hrec);
7004 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7006 MsiViewClose(hview);
7007 MsiCloseHandle(hview);
7009 query = "INSERT INTO Table ( `A` ) VALUES ( 'hi' )";
7010 r = run_query(hdb, 0, query);
7011 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7013 query = "INSERT INTO `Table` ( A ) VALUES ( 'hi' )";
7014 r = run_query(hdb, 0, query);
7015 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7017 query = "INSERT INTO `Table` ( `A` ) VALUES ( hi )";
7018 r = run_query(hdb, 0, query);
7019 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7021 query = "SELECT * FROM Table WHERE `A` = 'hi'";
7022 r = run_query(hdb, 0, query);
7023 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7025 query = "SELECT * FROM `Table` WHERE `A` = hi";
7026 r = run_query(hdb, 0, query);
7027 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7029 query = "SELECT * FROM Table";
7030 r = run_query(hdb, 0, query);
7031 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7033 query = "SELECT * FROM Table2";
7034 r = MsiDatabaseOpenView(hdb, query, &hview);
7035 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7036 r = MsiViewExecute(hview, 0);
7037 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7039 r = MsiViewFetch(hview, &hrec);
7040 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7042 MsiViewClose(hview);
7043 MsiCloseHandle(hview);
7045 query = "SELECT * FROM `Table` WHERE A = 'hi'";
7046 r = MsiDatabaseOpenView(hdb, query, &hview);
7047 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7048 r = MsiViewExecute(hview, 0);
7049 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7051 r = MsiViewFetch(hview, &hrec);
7052 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7055 r = MsiRecordGetStringA(hrec, 1, buf, &size);
7056 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7057 ok(!lstrcmpA(buf, "hi"), "Expected \"hi\", got \"%s\"\n", buf);
7059 MsiCloseHandle(hrec);
7061 r = MsiViewFetch(hview, &hrec);
7062 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7064 MsiViewClose(hview);
7065 MsiCloseHandle(hview);
7066 MsiCloseHandle(hdb);
7067 DeleteFileA(msifile);
7070 static void read_file_data(LPCSTR filename, LPSTR buffer)
7075 file = CreateFileA( filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL );
7076 ZeroMemory(buffer, MAX_PATH);
7077 ReadFile(file, buffer, MAX_PATH, &read, NULL);
7081 static void test_forcecodepage(void)
7085 char buffer[MAX_PATH];
7088 DeleteFile(msifile);
7089 GetCurrentDirectoryA(MAX_PATH, CURR_DIR);
7091 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
7092 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7094 query = "SELECT * FROM `_ForceCodepage`";
7095 r = run_query(hdb, 0, query);
7096 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7098 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )";
7099 r = run_query(hdb, 0, query);
7100 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7102 query = "SELECT * FROM `_ForceCodepage`";
7103 r = run_query(hdb, 0, query);
7104 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7106 r = MsiDatabaseCommit(hdb);
7107 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7109 query = "SELECT * FROM `_ForceCodepage`";
7110 r = run_query(hdb, 0, query);
7111 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7113 MsiCloseHandle(hdb);
7115 r = MsiOpenDatabase(msifile, MSIDBOPEN_DIRECT, &hdb);
7116 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7118 query = "SELECT * FROM `_ForceCodepage`";
7119 r = run_query(hdb, 0, query);
7120 ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7122 r = MsiDatabaseExport(hdb, "_ForceCodepage", CURR_DIR, "forcecodepage.idt");
7123 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7125 read_file_data("forcecodepage.idt", buffer);
7126 ok(!lstrcmpA(buffer, "\r\n\r\n0\t_ForceCodepage\r\n"),
7127 "Expected \"\r\n\r\n0\t_ForceCodepage\r\n\", got \"%s\"\n", buffer);
7129 create_file_data("forcecodepage.idt", "\r\n\r\n850\t_ForceCodepage\r\n", 0);
7131 r = MsiDatabaseImportA(hdb, CURR_DIR, "forcecodepage.idt");
7132 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7134 r = MsiDatabaseExport(hdb, "_ForceCodepage", CURR_DIR, "forcecodepage.idt");
7135 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7137 read_file_data("forcecodepage.idt", buffer);
7138 ok(!lstrcmpA(buffer, "\r\n\r\n850\t_ForceCodepage\r\n"),
7139 "Expected \"\r\n\r\n850\t_ForceCodepage\r\n\", got \"%s\"\n", buffer);
7141 create_file_data("forcecodepage.idt", "\r\n\r\n9999\t_ForceCodepage\r\n", 0);
7143 r = MsiDatabaseImportA(hdb, CURR_DIR, "forcecodepage.idt");
7144 ok(r == ERROR_FUNCTION_FAILED, "Expected ERROR_SUCCESS, got %d\n", r);
7146 MsiCloseHandle(hdb);
7147 DeleteFileA(msifile);
7148 DeleteFileA("forcecodepage.idt");
7151 static void test_viewmodify_refresh(void)
7153 MSIHANDLE hdb, hview, hrec;
7155 char buffer[MAX_PATH];
7159 DeleteFile(msifile);
7161 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
7162 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7164 query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL, `B` INT PRIMARY KEY `A` )";
7165 r = run_query(hdb, 0, query);
7166 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7168 query = "INSERT INTO `Table` ( `A`, `B` ) VALUES ( 'hi', 1 )";
7169 r = run_query(hdb, 0, query);
7170 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7172 query = "SELECT * FROM `Table`";
7173 r = MsiDatabaseOpenView(hdb, query, &hview);
7174 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7175 r = MsiViewExecute(hview, 0);
7176 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7178 r = MsiViewFetch(hview, &hrec);
7179 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7181 query = "UPDATE `Table` SET `B` = 2 WHERE `A` = 'hi'";
7182 r = run_query(hdb, 0, query);
7183 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7185 r = MsiViewModify(hview, MSIMODIFY_REFRESH, hrec);
7186 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7189 r = MsiRecordGetStringA(hrec, 1, buffer, &size);
7190 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7191 ok(!lstrcmpA(buffer, "hi"), "Expected \"hi\", got \"%s\"\n", buffer);
7192 ok(size == 2, "Expected 2, got %d\n", size);
7194 r = MsiRecordGetInteger(hrec, 2);
7195 ok(r == 2, "Expected 2, got %d\n", r);
7197 MsiCloseHandle(hrec);
7198 MsiViewClose(hview);
7199 MsiCloseHandle(hview);
7201 query = "INSERT INTO `Table` ( `A`, `B` ) VALUES ( 'hello', 3 )";
7202 r = run_query(hdb, 0, query);
7203 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7205 query = "SELECT * FROM `Table` WHERE `B` = 3";
7206 r = MsiDatabaseOpenView(hdb, query, &hview);
7207 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7208 r = MsiViewExecute(hview, 0);
7209 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7211 r = MsiViewFetch(hview, &hrec);
7212 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7214 query = "UPDATE `Table` SET `B` = 2 WHERE `A` = 'hello'";
7215 r = run_query(hdb, 0, query);
7216 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7218 query = "INSERT INTO `Table` ( `A`, `B` ) VALUES ( 'hithere', 3 )";
7219 r = run_query(hdb, 0, query);
7220 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7222 r = MsiViewModify(hview, MSIMODIFY_REFRESH, hrec);
7223 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7226 r = MsiRecordGetStringA(hrec, 1, buffer, &size);
7227 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7228 ok(!lstrcmpA(buffer, "hello"), "Expected \"hello\", got \"%s\"\n", buffer);
7229 ok(size == 5, "Expected 5, got %d\n", size);
7231 r = MsiRecordGetInteger(hrec, 2);
7232 ok(r == 2, "Expected 2, got %d\n", r);
7234 MsiCloseHandle(hrec);
7235 MsiViewClose(hview);
7236 MsiCloseHandle(hview);
7237 MsiCloseHandle(hdb);
7238 DeleteFileA(msifile);
7241 static void test_where_viewmodify(void)
7243 MSIHANDLE hdb, hview, hrec;
7247 DeleteFile(msifile);
7249 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
7250 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7252 query = "CREATE TABLE `Table` ( `A` INT, `B` INT PRIMARY KEY `A` )";
7253 r = run_query(hdb, 0, query);
7254 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7256 query = "INSERT INTO `Table` ( `A`, `B` ) VALUES ( 1, 2 )";
7257 r = run_query(hdb, 0, query);
7258 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7260 query = "INSERT INTO `Table` ( `A`, `B` ) VALUES ( 3, 4 )";
7261 r = run_query(hdb, 0, query);
7262 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7264 query = "INSERT INTO `Table` ( `A`, `B` ) VALUES ( 5, 6 )";
7265 r = run_query(hdb, 0, query);
7266 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7268 /* `B` = 3 doesn't match, but the view shouldn't be executed */
7269 query = "SELECT * FROM `Table` WHERE `B` = 3";
7270 r = MsiDatabaseOpenView(hdb, query, &hview);
7271 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7273 hrec = MsiCreateRecord(2);
7274 MsiRecordSetInteger(hrec, 1, 7);
7275 MsiRecordSetInteger(hrec, 2, 8);
7277 r = MsiViewModify(hview, MSIMODIFY_INSERT_TEMPORARY, hrec);
7278 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7280 MsiCloseHandle(hrec);
7281 MsiViewClose(hview);
7282 MsiCloseHandle(hview);
7284 query = "SELECT * FROM `Table` WHERE `A` = 7";
7285 r = MsiDatabaseOpenView(hdb, query, &hview);
7286 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7287 r = MsiViewExecute(hview, 0);
7288 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7290 r = MsiViewFetch(hview, &hrec);
7291 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7293 r = MsiRecordGetInteger(hrec, 1);
7294 ok(r == 7, "Expected 7, got %d\n", r);
7296 r = MsiRecordGetInteger(hrec, 2);
7297 ok(r == 8, "Expected 8, got %d\n", r);
7299 MsiRecordSetInteger(hrec, 2, 9);
7301 r = MsiViewModify(hview, MSIMODIFY_UPDATE, hrec);
7302 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7304 MsiCloseHandle(hrec);
7305 MsiViewClose(hview);
7306 MsiCloseHandle(hview);
7308 query = "SELECT * FROM `Table` WHERE `A` = 7";
7309 r = MsiDatabaseOpenView(hdb, query, &hview);
7310 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7311 r = MsiViewExecute(hview, 0);
7312 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7314 r = MsiViewFetch(hview, &hrec);
7315 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7317 r = MsiRecordGetInteger(hrec, 1);
7318 ok(r == 7, "Expected 7, got %d\n", r);
7320 r = MsiRecordGetInteger(hrec, 2);
7321 ok(r == 9, "Expected 9, got %d\n", r);
7323 query = "UPDATE `Table` SET `B` = 10 WHERE `A` = 7";
7324 r = run_query(hdb, 0, query);
7325 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7327 r = MsiViewModify(hview, MSIMODIFY_REFRESH, hrec);
7328 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7330 r = MsiRecordGetInteger(hrec, 1);
7331 ok(r == 7, "Expected 7, got %d\n", r);
7333 r = MsiRecordGetInteger(hrec, 2);
7334 ok(r == 10, "Expected 10, got %d\n", r);
7336 MsiCloseHandle(hrec);
7337 MsiViewClose(hview);
7338 MsiCloseHandle(hview);
7339 MsiCloseHandle(hdb);
7342 static BOOL create_storage(LPCSTR name)
7344 WCHAR nameW[MAX_PATH];
7351 MultiByteToWideChar(CP_ACP, 0, name, -1, nameW, MAX_PATH);
7352 hr = StgCreateDocfile(nameW, STGM_CREATE | STGM_READWRITE |
7353 STGM_DIRECT | STGM_SHARE_EXCLUSIVE, 0, &stg);
7357 hr = IStorage_CreateStream(stg, nameW, STGM_WRITE | STGM_SHARE_EXCLUSIVE,
7362 hr = IStream_Write(stm, "stgdata", 8, &count);
7367 IStream_Release(stm);
7368 IStorage_Release(stg);
7373 static void test_storages_table(void)
7375 MSIHANDLE hdb, hview, hrec;
7376 IStorage *stg, *inner;
7378 char file[MAX_PATH];
7380 WCHAR name[MAX_PATH];
7387 ok(hdb, "failed to create db\n");
7389 r = MsiDatabaseCommit(hdb);
7390 ok(r == ERROR_SUCCESS , "Failed to commit database\n");
7392 MsiCloseHandle(hdb);
7394 r = MsiOpenDatabase(msifile, MSIDBOPEN_TRANSACT, &hdb);
7395 ok(r == ERROR_SUCCESS , "Failed to open database\n");
7397 /* check the column types */
7398 hrec = get_column_info(hdb, "SELECT * FROM `_Storages`", MSICOLINFO_TYPES);
7399 ok(hrec, "failed to get column info hrecord\n");
7400 ok(check_record(hrec, 1, "s62"), "wrong hrecord type\n");
7401 ok(check_record(hrec, 2, "V0"), "wrong hrecord type\n");
7403 MsiCloseHandle(hrec);
7405 /* now try the names */
7406 hrec = get_column_info(hdb, "SELECT * FROM `_Storages`", MSICOLINFO_NAMES);
7407 ok(hrec, "failed to get column info hrecord\n");
7408 ok(check_record(hrec, 1, "Name"), "wrong hrecord type\n");
7409 ok(check_record(hrec, 2, "Data"), "wrong hrecord type\n");
7411 MsiCloseHandle(hrec);
7413 create_storage("storage.bin");
7415 hrec = MsiCreateRecord(2);
7416 MsiRecordSetString(hrec, 1, "stgname");
7418 r = MsiRecordSetStream(hrec, 2, "storage.bin");
7419 ok(r == ERROR_SUCCESS, "Failed to add stream data to the hrecord: %d\n", r);
7421 DeleteFileA("storage.bin");
7423 query = "INSERT INTO `_Storages` (`Name`, `Data`) VALUES (?, ?)";
7424 r = MsiDatabaseOpenView(hdb, query, &hview);
7425 ok(r == ERROR_SUCCESS, "Failed to open database hview: %d\n", r);
7427 r = MsiViewExecute(hview, hrec);
7428 ok(r == ERROR_SUCCESS, "Failed to execute hview: %d\n", r);
7430 MsiCloseHandle(hrec);
7431 MsiViewClose(hview);
7432 MsiCloseHandle(hview);
7434 query = "SELECT `Name`, `Data` FROM `_Storages`";
7435 r = MsiDatabaseOpenView(hdb, query, &hview);
7436 ok(r == ERROR_SUCCESS, "Failed to open database hview: %d\n", r);
7438 r = MsiViewExecute(hview, 0);
7439 ok(r == ERROR_SUCCESS, "Failed to execute hview: %d\n", r);
7441 r = MsiViewFetch(hview, &hrec);
7442 ok(r == ERROR_SUCCESS, "Failed to fetch hrecord: %d\n", r);
7445 r = MsiRecordGetString(hrec, 1, file, &size);
7446 ok(r == ERROR_SUCCESS, "Failed to get string: %d\n", r);
7447 ok(!lstrcmp(file, "stgname"), "Expected \"stgname\", got \"%s\"\n", file);
7450 lstrcpyA(buf, "apple");
7451 r = MsiRecordReadStream(hrec, 2, buf, &size);
7452 ok(r == ERROR_INVALID_DATA, "Expected ERROR_INVALID_DATA, got %d\n", r);
7453 ok(!lstrcmp(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7454 ok(size == 0, "Expected 0, got %d\n", size);
7456 MsiCloseHandle(hrec);
7458 r = MsiViewFetch(hview, &hrec);
7459 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7461 MsiViewClose(hview);
7462 MsiCloseHandle(hview);
7464 MsiDatabaseCommit(hdb);
7465 MsiCloseHandle(hdb);
7467 MultiByteToWideChar(CP_ACP, 0, msifile, -1, name, MAX_PATH);
7468 hr = StgOpenStorage(name, NULL, STGM_DIRECT | STGM_READ |
7469 STGM_SHARE_DENY_WRITE, NULL, 0, &stg);
7470 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
7471 ok(stg != NULL, "Expected non-NULL storage\n");
7473 MultiByteToWideChar(CP_ACP, 0, "stgname", -1, name, MAX_PATH);
7474 hr = IStorage_OpenStorage(stg, name, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE,
7476 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
7477 ok(inner != NULL, "Expected non-NULL storage\n");
7479 MultiByteToWideChar(CP_ACP, 0, "storage.bin", -1, name, MAX_PATH);
7480 hr = IStorage_OpenStream(inner, name, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stm);
7481 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
7482 ok(stm != NULL, "Expected non-NULL stream\n");
7484 hr = IStream_Read(stm, buf, MAX_PATH, &size);
7485 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
7486 ok(size == 8, "Expected 8, got %d\n", size);
7487 ok(!lstrcmpA(buf, "stgdata"), "Expected \"stgdata\", got \"%s\"\n", buf);
7489 IStream_Release(stm);
7490 IStorage_Release(inner);
7492 IStorage_Release(stg);
7493 DeleteFileA(msifile);
7496 static void test_dbtopackage(void)
7498 MSIHANDLE hdb, hpkg;
7499 CHAR package[12], buf[MAX_PATH];
7503 /* create an empty database, transact mode */
7504 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
7505 ok(r == ERROR_SUCCESS, "Failed to create database\n");
7507 set_summary_info(hdb);
7509 r = create_directory_table(hdb);
7510 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7512 r = create_custom_action_table(hdb);
7513 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7515 r = add_custom_action_entry(hdb, "'SetProp', 51, 'MYPROP', 'grape'");
7516 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7518 sprintf(package, "#%u", hdb);
7519 r = MsiOpenPackage(package, &hpkg);
7520 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
7522 skip("Not enough rights to perform tests\n");
7525 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7527 /* property is not set yet */
7529 lstrcpyA(buf, "kiwi");
7530 r = MsiGetProperty(hpkg, "MYPROP", buf, &size);
7531 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7532 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
7533 ok(size == 0, "Expected 0, got %d\n", size);
7535 /* run the custom action to set the property */
7536 r = MsiDoAction(hpkg, "SetProp");
7537 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7539 /* property is now set */
7541 lstrcpyA(buf, "kiwi");
7542 r = MsiGetProperty(hpkg, "MYPROP", buf, &size);
7543 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7544 ok(!lstrcmpA(buf, "grape"), "Expected \"grape\", got \"%s\"\n", buf);
7545 ok(size == 5, "Expected 5, got %d\n", size);
7547 MsiCloseHandle(hpkg);
7549 /* reset the package */
7550 r = MsiOpenPackage(package, &hpkg);
7551 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7553 /* property is not set anymore */
7555 lstrcpyA(buf, "kiwi");
7556 r = MsiGetProperty(hpkg, "MYPROP", buf, &size);
7557 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7560 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
7561 ok(size == 0, "Expected 0, got %d\n", size);
7564 MsiCloseHandle(hdb);
7565 MsiCloseHandle(hpkg);
7567 /* create an empty database, direct mode */
7568 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATEDIRECT, &hdb);
7569 ok(r == ERROR_SUCCESS, "Failed to create database\n");
7571 set_summary_info(hdb);
7573 r = create_directory_table(hdb);
7574 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7576 r = create_custom_action_table(hdb);
7577 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7579 r = add_custom_action_entry(hdb, "'SetProp', 51, 'MYPROP', 'grape'");
7580 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7582 sprintf(package, "#%u", hdb);
7583 r = MsiOpenPackage(package, &hpkg);
7584 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7586 /* property is not set yet */
7588 lstrcpyA(buf, "kiwi");
7589 r = MsiGetProperty(hpkg, "MYPROP", buf, &size);
7590 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7591 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
7592 ok(size == 0, "Expected 0, got %d\n", size);
7594 /* run the custom action to set the property */
7595 r = MsiDoAction(hpkg, "SetProp");
7596 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7598 /* property is now set */
7600 lstrcpyA(buf, "kiwi");
7601 r = MsiGetProperty(hpkg, "MYPROP", buf, &size);
7602 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7603 ok(!lstrcmpA(buf, "grape"), "Expected \"grape\", got \"%s\"\n", buf);
7604 ok(size == 5, "Expected 5, got %d\n", size);
7606 MsiCloseHandle(hpkg);
7608 /* reset the package */
7609 r = MsiOpenPackage(package, &hpkg);
7610 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7612 /* property is not set anymore */
7614 lstrcpyA(buf, "kiwi");
7615 r = MsiGetProperty(hpkg, "MYPROP", buf, &size);
7616 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7619 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
7620 ok(size == 0, "Expected 0, got %d\n", size);
7623 MsiCloseHandle(hpkg);
7626 MsiCloseHandle(hdb);
7627 DeleteFileA(msifile);
7630 static void test_droptable(void)
7632 MSIHANDLE hdb, hview, hrec;
7638 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
7639 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7641 query = "CREATE TABLE `One` ( `A` INT PRIMARY KEY `A` )";
7642 r = run_query(hdb, 0, query);
7643 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7645 query = "SELECT * FROM `One`";
7646 r = do_query(hdb, query, &hrec);
7647 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7649 query = "SELECT * FROM `_Tables` WHERE `Name` = 'One'";
7650 r = MsiDatabaseOpenViewA(hdb, query, &hview);
7651 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7652 r = MsiViewExecute(hview, 0);
7653 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7655 r = MsiViewFetch(hview, &hrec);
7656 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7659 r = MsiRecordGetStringA(hrec, 1, buf, &size);
7660 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7661 ok(!lstrcmpA(buf, "One"), "Expected \"One\", got \"%s\"\n", buf);
7663 MsiCloseHandle(hrec);
7664 MsiViewClose(hview);
7665 MsiCloseHandle(hview);
7667 query = "SELECT * FROM `_Columns` WHERE `Table` = 'One'";
7668 r = MsiDatabaseOpenViewA(hdb, query, &hview);
7669 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7670 r = MsiViewExecute(hview, 0);
7671 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7673 r = MsiViewFetch(hview, &hrec);
7674 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7677 r = MsiRecordGetStringA(hrec, 1, buf, &size);
7678 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7679 ok(!lstrcmpA(buf, "One"), "Expected \"One\", got \"%s\"\n", buf);
7681 r = MsiRecordGetInteger(hrec, 2);
7682 ok(r == 1, "Expected 1, got %d\n", r);
7685 r = MsiRecordGetStringA(hrec, 3, buf, &size);
7686 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7687 ok(!lstrcmpA(buf, "A"), "Expected \"A\", got \"%s\"\n", buf);
7689 MsiCloseHandle(hrec);
7691 r = MsiViewFetch(hview, &hrec);
7692 ok(r == ERROR_NO_MORE_ITEMS,
7693 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7695 MsiViewClose(hview);
7696 MsiCloseHandle(hview);
7698 query = "DROP `One`";
7699 r = run_query(hdb, 0, query);
7700 ok(r == ERROR_BAD_QUERY_SYNTAX,
7701 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7703 query = "DROP TABLE";
7704 r = run_query(hdb, 0, query);
7705 ok(r == ERROR_BAD_QUERY_SYNTAX,
7706 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7708 query = "DROP TABLE `One`";
7710 r = MsiDatabaseOpenViewA(hdb, query, &hview);
7711 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7712 r = MsiViewExecute(hview, 0);
7713 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7715 r = MsiViewFetch(hview, &hrec);
7716 ok(r == ERROR_FUNCTION_FAILED,
7717 "Expected ERROR_FUNCTION_FAILED, got %d\n", r);
7719 MsiViewClose(hview);
7720 MsiCloseHandle(hview);
7722 query = "SELECT * FROM `IDontExist`";
7723 r = do_query(hdb, query, &hrec);
7724 ok(r == ERROR_BAD_QUERY_SYNTAX,
7725 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7727 query = "SELECT * FROM `One`";
7728 r = do_query(hdb, query, &hrec);
7729 ok(r == ERROR_BAD_QUERY_SYNTAX,
7730 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7732 query = "CREATE TABLE `One` ( `A` INT PRIMARY KEY `A` )";
7733 r = run_query(hdb, 0, query);
7734 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7736 query = "DROP TABLE One";
7737 r = run_query(hdb, 0, query);
7738 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7740 query = "SELECT * FROM `One`";
7741 r = do_query(hdb, query, &hrec);
7742 ok(r == ERROR_BAD_QUERY_SYNTAX,
7743 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7745 query = "SELECT * FROM `_Tables` WHERE `Name` = 'One'";
7746 r = do_query(hdb, query, &hrec);
7747 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7749 query = "SELECT * FROM `_Columns` WHERE `Table` = 'One'";
7750 r = do_query(hdb, query, &hrec);
7751 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7753 query = "CREATE TABLE `One` ( `B` INT, `C` INT PRIMARY KEY `B` )";
7754 r = run_query(hdb, 0, query);
7755 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7757 query = "SELECT * FROM `One`";
7758 r = do_query(hdb, query, &hrec);
7759 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7761 query = "SELECT * FROM `_Tables` WHERE `Name` = 'One'";
7762 r = MsiDatabaseOpenViewA(hdb, query, &hview);
7763 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7764 r = MsiViewExecute(hview, 0);
7765 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7767 r = MsiViewFetch(hview, &hrec);
7768 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7771 r = MsiRecordGetStringA(hrec, 1, buf, &size);
7772 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7773 ok(!lstrcmpA(buf, "One"), "Expected \"One\", got \"%s\"\n", buf);
7775 MsiCloseHandle(hrec);
7776 MsiViewClose(hview);
7777 MsiCloseHandle(hview);
7779 query = "SELECT * FROM `_Columns` WHERE `Table` = 'One'";
7780 r = MsiDatabaseOpenViewA(hdb, query, &hview);
7781 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7782 r = MsiViewExecute(hview, 0);
7783 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7785 r = MsiViewFetch(hview, &hrec);
7786 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7789 r = MsiRecordGetStringA(hrec, 1, buf, &size);
7790 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7791 ok(!lstrcmpA(buf, "One"), "Expected \"One\", got \"%s\"\n", buf);
7793 r = MsiRecordGetInteger(hrec, 2);
7794 ok(r == 1, "Expected 1, got %d\n", r);
7797 r = MsiRecordGetStringA(hrec, 3, buf, &size);
7798 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7799 ok(!lstrcmpA(buf, "B"), "Expected \"B\", got \"%s\"\n", buf);
7801 MsiCloseHandle(hrec);
7803 r = MsiViewFetch(hview, &hrec);
7804 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7807 r = MsiRecordGetStringA(hrec, 1, buf, &size);
7808 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7809 ok(!lstrcmpA(buf, "One"), "Expected \"One\", got \"%s\"\n", buf);
7811 r = MsiRecordGetInteger(hrec, 2);
7812 ok(r == 2, "Expected 2, got %d\n", r);
7815 r = MsiRecordGetStringA(hrec, 3, buf, &size);
7816 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7817 ok(!lstrcmpA(buf, "C"), "Expected \"C\", got \"%s\"\n", buf);
7819 MsiCloseHandle(hrec);
7821 r = MsiViewFetch(hview, &hrec);
7822 ok(r == ERROR_NO_MORE_ITEMS,
7823 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7825 MsiViewClose(hview);
7826 MsiCloseHandle(hview);
7828 query = "DROP TABLE One";
7829 r = run_query(hdb, 0, query);
7830 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7832 query = "SELECT * FROM `One`";
7833 r = do_query(hdb, query, &hrec);
7834 ok(r == ERROR_BAD_QUERY_SYNTAX,
7835 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7837 query = "SELECT * FROM `_Tables` WHERE `Name` = 'One'";
7838 r = do_query(hdb, query, &hrec);
7839 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7841 query = "SELECT * FROM `_Columns` WHERE `Table` = 'One'";
7842 r = do_query(hdb, query, &hrec);
7843 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7845 MsiCloseHandle(hdb);
7846 DeleteFileA(msifile);
7849 static void test_dbmerge(void)
7851 MSIHANDLE hdb, href, hview, hrec;
7857 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
7858 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7860 r = MsiOpenDatabase("refdb.msi", MSIDBOPEN_CREATE, &href);
7861 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7863 /* hDatabase is invalid */
7864 r = MsiDatabaseMergeA(0, href, "MergeErrors");
7865 ok(r == ERROR_INVALID_HANDLE,
7866 "Expected ERROR_INVALID_HANDLE, got %d\n", r);
7868 /* hDatabaseMerge is invalid */
7869 r = MsiDatabaseMergeA(hdb, 0, "MergeErrors");
7870 ok(r == ERROR_INVALID_HANDLE,
7871 "Expected ERROR_INVALID_HANDLE, got %d\n", r);
7873 /* szTableName is NULL */
7874 r = MsiDatabaseMergeA(hdb, href, NULL);
7875 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7877 /* szTableName is empty */
7878 r = MsiDatabaseMergeA(hdb, href, "");
7879 ok(r == ERROR_INVALID_TABLE, "Expected ERROR_INVALID_TABLE, got %d\n", r);
7881 /* both DBs empty, szTableName is valid */
7882 r = MsiDatabaseMergeA(hdb, href, "MergeErrors");
7883 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7885 query = "CREATE TABLE `One` ( `A` INT PRIMARY KEY `A` )";
7886 r = run_query(hdb, 0, query);
7887 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7889 query = "CREATE TABLE `One` ( `A` CHAR(72) PRIMARY KEY `A` )";
7890 r = run_query(href, 0, query);
7891 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7893 /* column types don't match */
7894 r = MsiDatabaseMergeA(hdb, href, "MergeErrors");
7895 ok(r == ERROR_DATATYPE_MISMATCH,
7896 "Expected ERROR_DATATYPE_MISMATCH, got %d\n", r);
7898 /* nothing in MergeErrors */
7899 query = "SELECT * FROM `MergeErrors`";
7900 r = do_query(hdb, query, &hrec);
7901 ok(r == ERROR_BAD_QUERY_SYNTAX,
7902 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7904 query = "DROP TABLE `One`";
7905 r = run_query(hdb, 0, query);
7906 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7908 query = "DROP TABLE `One`";
7909 r = run_query(href, 0, query);
7910 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7912 query = "CREATE TABLE `One` ( "
7915 "`C` CHAR(64) LOCALIZABLE, "
7917 "`E` CHAR(72) NOT NULL, "
7918 "`F` CHAR(56) NOT NULL, "
7919 "`G` CHAR(64) NOT NULL LOCALIZABLE, "
7920 "`H` LONGCHAR NOT NULL "
7921 "PRIMARY KEY `A` )";
7922 r = run_query(hdb, 0, query);
7923 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7925 query = "CREATE TABLE `One` ( "
7930 "`E` CHAR(64) NOT NULL, "
7931 "`F` CHAR(64) NOT NULL, "
7932 "`G` CHAR(64) NOT NULL, "
7933 "`H` CHAR(64) NOT NULL "
7934 "PRIMARY KEY `A` )";
7935 r = run_query(href, 0, query);
7936 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7938 /* column sting types don't match exactly */
7939 r = MsiDatabaseMergeA(hdb, href, "MergeErrors");
7940 ok(r == ERROR_SUCCESS,
7941 "Expected ERROR_SUCCESS, got %d\n", r);
7943 /* nothing in MergeErrors */
7944 query = "SELECT * FROM `MergeErrors`";
7945 r = do_query(hdb, query, &hrec);
7946 ok(r == ERROR_BAD_QUERY_SYNTAX,
7947 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7949 query = "DROP TABLE `One`";
7950 r = run_query(hdb, 0, query);
7951 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7953 query = "DROP TABLE `One`";
7954 r = run_query(href, 0, query);
7955 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7957 query = "CREATE TABLE `One` ( `A` INT, `B` INT PRIMARY KEY `A` )";
7958 r = run_query(hdb, 0, query);
7959 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7961 query = "CREATE TABLE `One` ( `A` INT, `C` INT PRIMARY KEY `A` )";
7962 r = run_query(href, 0, query);
7963 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7965 /* column names don't match */
7966 r = MsiDatabaseMergeA(hdb, href, "MergeErrors");
7967 ok(r == ERROR_DATATYPE_MISMATCH,
7968 "Expected ERROR_DATATYPE_MISMATCH, got %d\n", r);
7970 /* nothing in MergeErrors */
7971 query = "SELECT * FROM `MergeErrors`";
7972 r = do_query(hdb, query, &hrec);
7973 ok(r == ERROR_BAD_QUERY_SYNTAX,
7974 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
7976 query = "DROP TABLE `One`";
7977 r = run_query(hdb, 0, query);
7978 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7980 query = "DROP TABLE `One`";
7981 r = run_query(href, 0, query);
7982 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7984 query = "CREATE TABLE `One` ( `A` INT, `B` INT PRIMARY KEY `A` )";
7985 r = run_query(hdb, 0, query);
7986 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7988 query = "CREATE TABLE `One` ( `A` INT, `B` INT PRIMARY KEY `B` )";
7989 r = run_query(href, 0, query);
7990 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7992 /* primary keys don't match */
7993 r = MsiDatabaseMergeA(hdb, href, "MergeErrors");
7994 ok(r == ERROR_DATATYPE_MISMATCH,
7995 "Expected ERROR_DATATYPE_MISMATCH, got %d\n", r);
7997 /* nothing in MergeErrors */
7998 query = "SELECT * FROM `MergeErrors`";
7999 r = do_query(hdb, query, &hrec);
8000 ok(r == ERROR_BAD_QUERY_SYNTAX,
8001 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
8003 query = "DROP TABLE `One`";
8004 r = run_query(hdb, 0, query);
8005 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8007 query = "DROP TABLE `One`";
8008 r = run_query(href, 0, query);
8009 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8011 query = "CREATE TABLE `One` ( `A` INT, `B` INT PRIMARY KEY `A` )";
8012 r = run_query(hdb, 0, query);
8013 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8015 query = "CREATE TABLE `One` ( `A` INT, `B` INT PRIMARY KEY `A`, `B` )";
8016 r = run_query(href, 0, query);
8017 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8019 /* number of primary keys doesn't match */
8020 r = MsiDatabaseMergeA(hdb, href, "MergeErrors");
8021 ok(r == ERROR_DATATYPE_MISMATCH,
8022 "Expected ERROR_DATATYPE_MISMATCH, got %d\n", r);
8024 /* nothing in MergeErrors */
8025 query = "SELECT * FROM `MergeErrors`";
8026 r = do_query(hdb, query, &hrec);
8027 ok(r == ERROR_BAD_QUERY_SYNTAX,
8028 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
8030 query = "DROP TABLE `One`";
8031 r = run_query(hdb, 0, query);
8032 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8034 query = "DROP TABLE `One`";
8035 r = run_query(href, 0, query);
8036 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8038 query = "CREATE TABLE `One` ( `A` INT, `B` INT, `C` INT PRIMARY KEY `A` )";
8039 r = run_query(hdb, 0, query);
8040 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8042 query = "CREATE TABLE `One` ( `A` INT, `B` INT PRIMARY KEY `A` )";
8043 r = run_query(href, 0, query);
8044 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8046 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 1, 2 )";
8047 r = run_query(href, 0, query);
8048 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8050 /* number of columns doesn't match */
8051 r = MsiDatabaseMergeA(hdb, href, "MergeErrors");
8052 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8054 query = "SELECT * FROM `One`";
8055 r = do_query(hdb, query, &hrec);
8056 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8058 r = MsiRecordGetInteger(hrec, 1);
8059 ok(r == 1, "Expected 1, got %d\n", r);
8061 r = MsiRecordGetInteger(hrec, 2);
8062 ok(r == 2, "Expected 2, got %d\n", r);
8064 r = MsiRecordGetInteger(hrec, 3);
8065 ok(r == MSI_NULL_INTEGER, "Expected MSI_NULL_INTEGER, got %d\n", r);
8067 MsiCloseHandle(hrec);
8069 /* nothing in MergeErrors */
8070 query = "SELECT * FROM `MergeErrors`";
8071 r = do_query(hdb, query, &hrec);
8072 ok(r == ERROR_BAD_QUERY_SYNTAX,
8073 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
8075 query = "DROP TABLE `One`";
8076 r = run_query(hdb, 0, query);
8077 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8079 query = "DROP TABLE `One`";
8080 r = run_query(href, 0, query);
8081 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8083 query = "CREATE TABLE `One` ( `A` INT, `B` INT PRIMARY KEY `A` )";
8084 r = run_query(hdb, 0, query);
8085 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8087 query = "CREATE TABLE `One` ( `A` INT, `B` INT, `C` INT PRIMARY KEY `A` )";
8088 r = run_query(href, 0, query);
8089 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8091 query = "INSERT INTO `One` ( `A`, `B`, `C` ) VALUES ( 1, 2, 3 )";
8092 r = run_query(href, 0, query);
8093 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8095 /* number of columns doesn't match */
8096 r = MsiDatabaseMergeA(hdb, href, "MergeErrors");
8097 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8099 query = "SELECT * FROM `One`";
8100 r = do_query(hdb, query, &hrec);
8101 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8103 r = MsiRecordGetInteger(hrec, 1);
8104 ok(r == 1, "Expected 1, got %d\n", r);
8106 r = MsiRecordGetInteger(hrec, 2);
8107 ok(r == 2, "Expected 2, got %d\n", r);
8109 r = MsiRecordGetInteger(hrec, 3);
8110 ok(r == MSI_NULL_INTEGER, "Expected MSI_NULL_INTEGER, got %d\n", r);
8112 MsiCloseHandle(hrec);
8114 /* nothing in MergeErrors */
8115 query = "SELECT * FROM `MergeErrors`";
8116 r = do_query(hdb, query, &hrec);
8117 ok(r == ERROR_BAD_QUERY_SYNTAX,
8118 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
8120 query = "DROP TABLE `One`";
8121 r = run_query(hdb, 0, query);
8122 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8124 query = "DROP TABLE `One`";
8125 r = run_query(href, 0, query);
8126 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8128 query = "CREATE TABLE `One` ( `A` INT, `B` INT PRIMARY KEY `A` )";
8129 r = run_query(hdb, 0, query);
8130 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8132 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 1, 1 )";
8133 r = run_query(hdb, 0, query);
8134 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8136 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 2, 2 )";
8137 r = run_query(hdb, 0, query);
8138 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8140 query = "CREATE TABLE `One` ( `A` INT, `B` INT PRIMARY KEY `A` )";
8141 r = run_query(href, 0, query);
8142 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8144 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 1, 2 )";
8145 r = run_query(href, 0, query);
8146 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8148 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 2, 3 )";
8149 r = run_query(href, 0, query);
8150 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8152 /* primary keys match, rows do not */
8153 r = MsiDatabaseMergeA(hdb, href, "MergeErrors");
8154 ok(r == ERROR_FUNCTION_FAILED,
8155 "Expected ERROR_FUNCTION_FAILED, got %d\n", r);
8157 /* nothing in MergeErrors */
8158 query = "SELECT * FROM `MergeErrors`";
8159 r = do_query(hdb, query, &hrec);
8160 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8163 r = MsiRecordGetStringA(hrec, 1, buf, &size);
8164 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8165 ok(!lstrcmpA(buf, "One"), "Expected \"One\", got \"%s\"\n", buf);
8167 r = MsiRecordGetInteger(hrec, 2);
8168 ok(r == 2, "Expected 2, got %d\n", r);
8170 MsiCloseHandle(hrec);
8172 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `MergeErrors`", &hview);
8173 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8175 r = MsiViewGetColumnInfo(hview, MSICOLINFO_NAMES, &hrec);
8176 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8179 r = MsiRecordGetString(hrec, 1, buf, &size);
8180 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8181 ok(!lstrcmpA(buf, "Table"), "Expected \"Table\", got \"%s\"\n", buf);
8184 r = MsiRecordGetString(hrec, 2, buf, &size);
8185 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8186 ok(!lstrcmpA(buf, "NumRowMergeConflicts"),
8187 "Expected \"NumRowMergeConflicts\", got \"%s\"\n", buf);
8189 MsiCloseHandle(hrec);
8191 r = MsiViewGetColumnInfo(hview, MSICOLINFO_TYPES, &hrec);
8192 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8195 r = MsiRecordGetString(hrec, 1, buf, &size);
8196 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8197 ok(!lstrcmpA(buf, "s255"), "Expected \"s255\", got \"%s\"\n", buf);
8200 r = MsiRecordGetString(hrec, 2, buf, &size);
8201 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8202 ok(!lstrcmpA(buf, "i2"), "Expected \"i2\", got \"%s\"\n", buf);
8204 MsiCloseHandle(hrec);
8205 MsiViewClose(hview);
8206 MsiCloseHandle(hview);
8208 query = "DROP TABLE `MergeErrors`";
8209 r = run_query(hdb, 0, query);
8210 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8212 query = "DROP TABLE `One`";
8213 r = run_query(hdb, 0, query);
8214 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8216 query = "DROP TABLE `One`";
8217 r = run_query(href, 0, query);
8218 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8220 query = "CREATE TABLE `One` ( `A` INT, `B` CHAR(72) PRIMARY KEY `A` )";
8221 r = run_query(href, 0, query);
8222 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8224 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 1, 'hi' )";
8225 r = run_query(href, 0, query);
8226 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8228 /* table from merged database is not in target database */
8229 r = MsiDatabaseMergeA(hdb, href, "MergeErrors");
8230 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8232 query = "SELECT * FROM `One`";
8233 r = do_query(hdb, query, &hrec);
8234 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8236 r = MsiRecordGetInteger(hrec, 1);
8237 ok(r == 1, "Expected 1, got %d\n", r);
8240 r = MsiRecordGetStringA(hrec, 2, buf, &size);
8241 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8242 ok(!lstrcmpA(buf, "hi"), "Expected \"hi\", got \"%s\"\n", buf);
8244 MsiCloseHandle(hrec);
8246 /* nothing in MergeErrors */
8247 query = "SELECT * FROM `MergeErrors`";
8248 r = do_query(hdb, query, &hrec);
8249 ok(r == ERROR_BAD_QUERY_SYNTAX,
8250 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
8252 query = "DROP TABLE `One`";
8253 r = run_query(hdb, 0, query);
8254 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8256 query = "DROP TABLE `One`";
8257 r = run_query(href, 0, query);
8258 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8260 query = "CREATE TABLE `One` ( "
8261 "`A` CHAR(72), `B` INT PRIMARY KEY `A` )";
8262 r = run_query(hdb, 0, query);
8263 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8265 query = "CREATE TABLE `One` ( "
8266 "`A` CHAR(72), `B` INT PRIMARY KEY `A` )";
8267 r = run_query(href, 0, query);
8268 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8270 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 'hi', 1 )";
8271 r = run_query(href, 0, query);
8272 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8274 /* primary key is string */
8275 r = MsiDatabaseMergeA(hdb, href, "MergeErrors");
8276 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8278 query = "SELECT * FROM `One`";
8279 r = do_query(hdb, query, &hrec);
8280 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8283 r = MsiRecordGetStringA(hrec, 1, buf, &size);
8284 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8285 ok(!lstrcmpA(buf, "hi"), "Expected \"hi\", got \"%s\"\n", buf);
8287 r = MsiRecordGetInteger(hrec, 2);
8288 ok(r == 1, "Expected 1, got %d\n", r);
8290 MsiCloseHandle(hrec);
8292 /* nothing in MergeErrors */
8293 query = "SELECT * FROM `MergeErrors`";
8294 r = do_query(hdb, query, &hrec);
8295 ok(r == ERROR_BAD_QUERY_SYNTAX,
8296 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
8298 create_file_data("codepage.idt", "\r\n\r\n850\t_ForceCodepage\r\n", 0);
8300 GetCurrentDirectoryA(MAX_PATH, buf);
8301 r = MsiDatabaseImportA(hdb, buf, "codepage.idt");
8302 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8304 query = "DROP TABLE `One`";
8305 r = run_query(hdb, 0, query);
8306 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8308 query = "DROP TABLE `One`";
8309 r = run_query(href, 0, query);
8310 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8312 query = "CREATE TABLE `One` ( "
8313 "`A` INT, `B` CHAR(72) LOCALIZABLE PRIMARY KEY `A` )";
8314 r = run_query(hdb, 0, query);
8315 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8317 query = "CREATE TABLE `One` ( "
8318 "`A` INT, `B` CHAR(72) LOCALIZABLE PRIMARY KEY `A` )";
8319 r = run_query(href, 0, query);
8320 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8322 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 1, 'hi' )";
8323 r = run_query(href, 0, query);
8324 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8326 /* code page does not match */
8327 r = MsiDatabaseMergeA(hdb, href, "MergeErrors");
8328 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8330 query = "SELECT * FROM `One`";
8331 r = do_query(hdb, query, &hrec);
8332 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8334 r = MsiRecordGetInteger(hrec, 1);
8335 ok(r == 1, "Expected 1, got %d\n", r);
8338 r = MsiRecordGetStringA(hrec, 2, buf, &size);
8339 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8340 ok(!lstrcmpA(buf, "hi"), "Expected \"hi\", got \"%s\"\n", buf);
8342 MsiCloseHandle(hrec);
8344 /* nothing in MergeErrors */
8345 query = "SELECT * FROM `MergeErrors`";
8346 r = do_query(hdb, query, &hrec);
8347 ok(r == ERROR_BAD_QUERY_SYNTAX,
8348 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
8350 query = "DROP TABLE `One`";
8351 r = run_query(hdb, 0, query);
8352 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8354 query = "DROP TABLE `One`";
8355 r = run_query(href, 0, query);
8356 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8358 query = "CREATE TABLE `One` ( `A` INT, `B` OBJECT PRIMARY KEY `A` )";
8359 r = run_query(hdb, 0, query);
8360 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8362 query = "CREATE TABLE `One` ( `A` INT, `B` OBJECT PRIMARY KEY `A` )";
8363 r = run_query(href, 0, query);
8364 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8366 create_file("binary.dat");
8367 hrec = MsiCreateRecord(1);
8368 MsiRecordSetStreamA(hrec, 1, "binary.dat");
8370 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 1, ? )";
8371 r = run_query(href, hrec, query);
8372 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8374 MsiCloseHandle(hrec);
8376 /* binary data to merge */
8377 r = MsiDatabaseMergeA(hdb, href, "MergeErrors");
8378 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8380 query = "SELECT * FROM `One`";
8381 r = do_query(hdb, query, &hrec);
8382 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8384 r = MsiRecordGetInteger(hrec, 1);
8385 ok(r == 1, "Expected 1, got %d\n", r);
8388 ZeroMemory(buf, MAX_PATH);
8389 r = MsiRecordReadStream(hrec, 2, buf, &size);
8390 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8391 ok(!lstrcmpA(buf, "binary.dat\n"),
8392 "Expected \"binary.dat\\n\", got \"%s\"\n", buf);
8394 MsiCloseHandle(hrec);
8396 /* nothing in MergeErrors */
8397 query = "SELECT * FROM `MergeErrors`";
8398 r = do_query(hdb, query, &hrec);
8399 ok(r == ERROR_BAD_QUERY_SYNTAX,
8400 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
8402 query = "DROP TABLE `One`";
8403 r = run_query(hdb, 0, query);
8404 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8406 query = "DROP TABLE `One`";
8407 r = run_query(href, 0, query);
8408 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8410 query = "CREATE TABLE `One` ( `A` INT, `B` CHAR(72) PRIMARY KEY `A` )";
8411 r = run_query(hdb, 0, query);
8412 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8413 r = run_query(href, 0, query);
8414 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8416 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 1, 'foo' )";
8417 r = run_query(href, 0, query);
8418 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8420 query = "INSERT INTO `One` ( `A`, `B` ) VALUES ( 2, 'bar' )";
8421 r = run_query(href, 0, query);
8422 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8424 r = MsiDatabaseMergeA(hdb, href, "MergeErrors");
8425 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8427 query = "SELECT * FROM `One`";
8428 r = MsiDatabaseOpenViewA(hdb, query, &hview);
8429 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8430 r = MsiViewExecute(hview, 0);
8431 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8433 r = MsiViewFetch(hview, &hrec);
8434 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8436 r = MsiRecordGetInteger(hrec, 1);
8437 ok(r == 1, "Expected 1, got %d\n", r);
8440 r = MsiRecordGetStringA(hrec, 2, buf, &size);
8441 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8442 ok(!lstrcmpA(buf, "foo"), "Expected \"foo\", got \"%s\"\n", buf);
8444 MsiCloseHandle(hrec);
8446 r = MsiViewFetch(hview, &hrec);
8447 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8449 r = MsiRecordGetInteger(hrec, 1);
8450 ok(r == 2, "Expected 2, got %d\n", r);
8453 r = MsiRecordGetStringA(hrec, 2, buf, &size);
8454 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8455 ok(!lstrcmpA(buf, "bar"), "Expected \"bar\", got \"%s\"\n", buf);
8457 MsiCloseHandle(hrec);
8459 r = MsiViewFetch(hview, &hrec);
8460 ok(r == ERROR_NO_MORE_ITEMS,
8461 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8463 MsiViewClose(hview);
8464 MsiCloseHandle(hview);
8466 MsiCloseHandle(hdb);
8467 MsiCloseHandle(href);
8468 DeleteFileA(msifile);
8469 DeleteFileA("refdb.msi");
8470 DeleteFileA("codepage.idt");
8471 DeleteFileA("binary.dat");
8474 static void test_select_with_tablenames(void)
8476 MSIHANDLE hdb, view, rec;
8488 ok(hdb, "failed to create db\n");
8490 /* Build a pair of tables with the same column names, but unique data */
8491 query = "CREATE TABLE `T1` ( `A` SHORT, `B` SHORT PRIMARY KEY `A`)";
8492 r = run_query(hdb, 0, query);
8493 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8495 query = "INSERT INTO `T1` ( `A`, `B` ) VALUES ( 1, 2 )";
8496 r = run_query(hdb, 0, query);
8497 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8499 query = "INSERT INTO `T1` ( `A`, `B` ) VALUES ( 4, 5 )";
8500 r = run_query(hdb, 0, query);
8501 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8503 query = "CREATE TABLE `T2` ( `A` SHORT, `B` SHORT PRIMARY KEY `A`)";
8504 r = run_query(hdb, 0, query);
8505 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8507 query = "INSERT INTO `T2` ( `A`, `B` ) VALUES ( 11, 12 )";
8508 r = run_query(hdb, 0, query);
8509 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8511 query = "INSERT INTO `T2` ( `A`, `B` ) VALUES ( 14, 15 )";
8512 r = run_query(hdb, 0, query);
8513 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8516 /* Test that selection based on prefixing the column with the table
8517 * actually selects the right data */
8519 query = "SELECT T1.A, T2.B FROM T1,T2";
8520 r = MsiDatabaseOpenView(hdb, query, &view);
8521 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8522 r = MsiViewExecute(view, 0);
8523 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8525 for (i = 0; i < 4; i++)
8527 r = MsiViewFetch(view, &rec);
8528 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8530 r = MsiRecordGetInteger(rec, 1);
8531 ok(r == vals[i][0], "Expected %d, got %d\n", vals[i][0], r);
8533 r = MsiRecordGetInteger(rec, 2);
8534 ok(r == vals[i][1], "Expected %d, got %d\n", vals[i][1], r);
8536 MsiCloseHandle(rec);
8539 r = MsiViewFetch(view, &rec);
8540 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8543 MsiCloseHandle(view);
8544 MsiCloseHandle(hdb);
8545 DeleteFileA(msifile);
8548 static const UINT ordervals[6][3] =
8550 { MSI_NULL_INTEGER, 12, 13 },
8554 { 10, 11, MSI_NULL_INTEGER },
8555 { 14, MSI_NULL_INTEGER, 15 }
8558 static void test_insertorder(void)
8560 MSIHANDLE hdb, view, rec;
8566 ok(hdb, "failed to create db\n");
8568 query = "CREATE TABLE `T` ( `A` SHORT, `B` SHORT, `C` SHORT PRIMARY KEY `A`)";
8569 r = run_query(hdb, 0, query);
8570 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8572 query = "INSERT INTO `T` ( `A`, `B`, `C` ) VALUES ( 1, 2, 3 )";
8573 r = run_query(hdb, 0, query);
8574 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8576 query = "INSERT INTO `T` ( `B`, `C`, `A` ) VALUES ( 4, 5, 6 )";
8577 r = run_query(hdb, 0, query);
8578 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8580 query = "INSERT INTO `T` ( `C`, `A`, `B` ) VALUES ( 7, 8, 9 )";
8581 r = run_query(hdb, 0, query);
8582 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8584 query = "INSERT INTO `T` ( `A`, `B` ) VALUES ( 10, 11 )";
8585 r = run_query(hdb, 0, query);
8586 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8588 query = "INSERT INTO `T` ( `B`, `C` ) VALUES ( 12, 13 )";
8589 r = run_query(hdb, 0, query);
8590 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8592 /* fails because the primary key already
8593 * has an MSI_NULL_INTEGER value set above
8595 query = "INSERT INTO `T` ( `C` ) VALUES ( 14 )";
8596 r = run_query(hdb, 0, query);
8597 ok(r == ERROR_FUNCTION_FAILED,
8598 "Expected ERROR_FUNCTION_FAILED, got %d\n", r);
8600 /* replicate the error where primary key is set twice */
8601 query = "INSERT INTO `T` ( `A`, `C` ) VALUES ( 1, 14 )";
8602 r = run_query(hdb, 0, query);
8603 ok(r == ERROR_FUNCTION_FAILED,
8604 "Expected ERROR_FUNCTION_FAILED, got %d\n", r);
8606 query = "INSERT INTO `T` ( `A`, `C` ) VALUES ( 14, 15 )";
8607 r = run_query(hdb, 0, query);
8608 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8610 query = "INSERT INTO `T` VALUES ( 16 )";
8611 r = run_query(hdb, 0, query);
8612 ok(r == ERROR_BAD_QUERY_SYNTAX,
8613 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
8615 query = "INSERT INTO `T` VALUES ( 17, 18 )";
8616 r = run_query(hdb, 0, query);
8617 ok(r == ERROR_BAD_QUERY_SYNTAX,
8618 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
8620 query = "INSERT INTO `T` VALUES ( 19, 20, 21 )";
8621 r = run_query(hdb, 0, query);
8622 ok(r == ERROR_BAD_QUERY_SYNTAX,
8623 "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
8625 query = "SELECT * FROM `T`";
8626 r = MsiDatabaseOpenView(hdb, query, &view);
8627 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8628 r = MsiViewExecute(view, 0);
8629 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8631 for (i = 0; i < 6; i++)
8633 r = MsiViewFetch(view, &rec);
8634 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8636 r = MsiRecordGetInteger(rec, 1);
8637 ok(r == ordervals[i][0], "Expected %d, got %d\n", ordervals[i][0], r);
8639 r = MsiRecordGetInteger(rec, 2);
8640 ok(r == ordervals[i][1], "Expected %d, got %d\n", ordervals[i][1], r);
8642 r = MsiRecordGetInteger(rec, 3);
8643 ok(r == ordervals[i][2], "Expected %d, got %d\n", ordervals[i][2], r);
8645 MsiCloseHandle(rec);
8648 r = MsiViewFetch(view, &rec);
8649 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8652 MsiCloseHandle(view);
8654 query = "DELETE FROM `T` WHERE `A` IS NULL";
8655 r = run_query(hdb, 0, query);
8656 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8658 query = "INSERT INTO `T` ( `B`, `C` ) VALUES ( 12, 13 ) TEMPORARY";
8659 r = run_query(hdb, 0, query);
8660 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8662 query = "SELECT * FROM `T`";
8663 r = MsiDatabaseOpenView(hdb, query, &view);
8664 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8665 r = MsiViewExecute(view, 0);
8666 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8668 for (i = 0; i < 6; i++)
8670 r = MsiViewFetch(view, &rec);
8671 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8673 r = MsiRecordGetInteger(rec, 1);
8674 ok(r == ordervals[i][0], "Expected %d, got %d\n", ordervals[i][0], r);
8676 r = MsiRecordGetInteger(rec, 2);
8677 ok(r == ordervals[i][1], "Expected %d, got %d\n", ordervals[i][1], r);
8679 r = MsiRecordGetInteger(rec, 3);
8680 ok(r == ordervals[i][2], "Expected %d, got %d\n", ordervals[i][2], r);
8682 MsiCloseHandle(rec);
8685 r = MsiViewFetch(view, &rec);
8686 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8689 MsiCloseHandle(view);
8690 MsiCloseHandle(hdb);
8691 DeleteFileA(msifile);
8694 static void test_columnorder(void)
8696 MSIHANDLE hdb, view, rec;
8703 ok(hdb, "failed to create db\n");
8705 /* Each column is a slot:
8706 * ---------------------
8707 * | B | C | A | E | D |
8708 * ---------------------
8710 * When a column is selected as a primary key,
8711 * the column occupying the nth primary key slot is swapped
8712 * with the current position of the primary key in question:
8714 * set primary key `D`
8715 * --------------------- ---------------------
8716 * | B | C | A | E | D | -> | D | C | A | E | B |
8717 * --------------------- ---------------------
8719 * set primary key `E`
8720 * --------------------- ---------------------
8721 * | D | C | A | E | B | -> | D | E | A | C | B |
8722 * --------------------- ---------------------
8725 query = "CREATE TABLE `T` ( `B` SHORT NOT NULL, `C` SHORT NOT NULL, "
8726 "`A` CHAR(255), `E` INT, `D` CHAR(255) NOT NULL "
8727 "PRIMARY KEY `D`, `E`)";
8728 r = run_query(hdb, 0, query);
8729 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8731 query = "SELECT * FROM `T`";
8732 r = MsiDatabaseOpenView(hdb, query, &view);
8733 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8735 r = MsiViewGetColumnInfo(view, MSICOLINFO_TYPES, &rec);
8736 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8739 lstrcpyA(buf, "kiwi");
8740 r = MsiRecordGetString(rec, 1, buf, &sz);
8741 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8742 ok(!lstrcmpA("s255", buf), "Expected \"s255\", got \"%s\"\n", buf);
8745 lstrcpyA(buf, "kiwi");
8746 r = MsiRecordGetString(rec, 2, buf, &sz);
8747 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8748 ok(!lstrcmpA("I2", buf), "Expected \"I2\", got \"%s\"\n", buf);
8751 lstrcpyA(buf, "kiwi");
8752 r = MsiRecordGetString(rec, 3, buf, &sz);
8753 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8754 ok(!lstrcmpA("S255", buf), "Expected \"S255\", got \"%s\"\n", buf);
8757 lstrcpyA(buf, "kiwi");
8758 r = MsiRecordGetString(rec, 4, buf, &sz);
8759 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8760 ok(!lstrcmpA("i2", buf), "Expected \"i2\", got \"%s\"\n", buf);
8763 lstrcpyA(buf, "kiwi");
8764 r = MsiRecordGetString(rec, 5, buf, &sz);
8765 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8766 ok(!lstrcmpA("i2", buf), "Expected \"i2\", got \"%s\"\n", buf);
8768 MsiCloseHandle(rec);
8770 r = MsiViewGetColumnInfo(view, MSICOLINFO_NAMES, &rec);
8771 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8774 lstrcpyA(buf, "kiwi");
8775 r = MsiRecordGetString(rec, 1, buf, &sz);
8776 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8777 ok(!lstrcmpA("D", buf), "Expected \"D\", got \"%s\"\n", buf);
8780 lstrcpyA(buf, "kiwi");
8781 r = MsiRecordGetString(rec, 2, buf, &sz);
8782 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8783 ok(!lstrcmpA("E", buf), "Expected \"E\", got \"%s\"\n", buf);
8786 lstrcpyA(buf, "kiwi");
8787 r = MsiRecordGetString(rec, 3, buf, &sz);
8788 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8789 ok(!lstrcmpA("A", buf), "Expected \"A\", got \"%s\"\n", buf);
8792 lstrcpyA(buf, "kiwi");
8793 r = MsiRecordGetString(rec, 4, buf, &sz);
8794 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8795 ok(!lstrcmpA("C", buf), "Expected \"C\", got \"%s\"\n", buf);
8798 lstrcpyA(buf, "kiwi");
8799 r = MsiRecordGetString(rec, 5, buf, &sz);
8800 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8801 ok(!lstrcmpA("B", buf), "Expected \"B\", got \"%s\"\n", buf);
8803 MsiCloseHandle(rec);
8805 MsiCloseHandle(view);
8807 query = "INSERT INTO `T` ( `B`, `C`, `A`, `E`, `D` ) "
8808 "VALUES ( 1, 2, 'a', 3, 'bc' )";
8809 r = run_query(hdb, 0, query);
8810 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8812 query = "SELECT * FROM `T`";
8813 r = do_query(hdb, query, &rec);
8814 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8817 lstrcpyA(buf, "kiwi");
8818 r = MsiRecordGetString(rec, 1, buf, &sz);
8819 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8820 ok(!lstrcmpA("bc", buf), "Expected \"bc\", got \"%s\"\n", buf);
8822 r = MsiRecordGetInteger(rec, 2);
8823 ok(r == 3, "Expected 3, got %d\n", r);
8826 lstrcpyA(buf, "kiwi");
8827 r = MsiRecordGetString(rec, 3, buf, &sz);
8828 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8829 ok(!lstrcmpA("a", buf), "Expected \"a\", got \"%s\"\n", buf);
8831 r = MsiRecordGetInteger(rec, 4);
8832 ok(r == 2, "Expected 2, got %d\n", r);
8834 r = MsiRecordGetInteger(rec, 5);
8835 ok(r == 1, "Expected 1, got %d\n", r);
8837 MsiCloseHandle(rec);
8839 query = "SELECT * FROM `_Columns` WHERE `Table` = 'T'";
8840 r = MsiDatabaseOpenView(hdb, query, &view);
8841 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8842 r = MsiViewExecute(view, 0);
8843 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8845 r = MsiViewFetch(view, &rec);
8846 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8849 lstrcpyA(buf, "kiwi");
8850 r = MsiRecordGetString(rec, 1, buf, &sz);
8851 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8852 ok(!lstrcmpA("T", buf), "Expected \"T\", got \"%s\"\n", buf);
8854 r = MsiRecordGetInteger(rec, 2);
8855 ok(r == 1, "Expected 1, got %d\n", r);
8858 lstrcpyA(buf, "kiwi");
8859 r = MsiRecordGetString(rec, 3, buf, &sz);
8860 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8861 ok(!lstrcmpA("D", buf), "Expected \"D\", got \"%s\"\n", buf);
8863 MsiCloseHandle(rec);
8865 r = MsiViewFetch(view, &rec);
8866 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8869 lstrcpyA(buf, "kiwi");
8870 r = MsiRecordGetString(rec, 1, buf, &sz);
8871 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8872 ok(!lstrcmpA("T", buf), "Expected \"T\", got \"%s\"\n", buf);
8874 r = MsiRecordGetInteger(rec, 2);
8875 ok(r == 2, "Expected 2, got %d\n", r);
8878 lstrcpyA(buf, "kiwi");
8879 r = MsiRecordGetString(rec, 3, buf, &sz);
8880 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8881 ok(!lstrcmpA("E", buf), "Expected \"E\", got \"%s\"\n", buf);
8883 MsiCloseHandle(rec);
8885 r = MsiViewFetch(view, &rec);
8886 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8889 lstrcpyA(buf, "kiwi");
8890 r = MsiRecordGetString(rec, 1, buf, &sz);
8891 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8892 ok(!lstrcmpA("T", buf), "Expected \"T\", got \"%s\"\n", buf);
8894 r = MsiRecordGetInteger(rec, 2);
8895 ok(r == 3, "Expected 3, got %d\n", r);
8898 lstrcpyA(buf, "kiwi");
8899 r = MsiRecordGetString(rec, 3, buf, &sz);
8900 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8901 ok(!lstrcmpA("A", buf), "Expected \"A\", got \"%s\"\n", buf);
8903 MsiCloseHandle(rec);
8905 r = MsiViewFetch(view, &rec);
8906 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8909 lstrcpyA(buf, "kiwi");
8910 r = MsiRecordGetString(rec, 1, buf, &sz);
8911 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8912 ok(!lstrcmpA("T", buf), "Expected \"T\", got \"%s\"\n", buf);
8914 r = MsiRecordGetInteger(rec, 2);
8915 ok(r == 4, "Expected 4, got %d\n", r);
8918 lstrcpyA(buf, "kiwi");
8919 r = MsiRecordGetString(rec, 3, buf, &sz);
8920 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8921 ok(!lstrcmpA("C", buf), "Expected \"C\", got \"%s\"\n", buf);
8923 MsiCloseHandle(rec);
8925 r = MsiViewFetch(view, &rec);
8926 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8929 lstrcpyA(buf, "kiwi");
8930 r = MsiRecordGetString(rec, 1, buf, &sz);
8931 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8932 ok(!lstrcmpA("T", buf), "Expected \"T\", got \"%s\"\n", buf);
8934 r = MsiRecordGetInteger(rec, 2);
8935 ok(r == 5, "Expected 5, got %d\n", r);
8938 lstrcpyA(buf, "kiwi");
8939 r = MsiRecordGetString(rec, 3, buf, &sz);
8940 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8941 ok(!lstrcmpA("B", buf), "Expected \"B\", got \"%s\"\n", buf);
8943 MsiCloseHandle(rec);
8945 r = MsiViewFetch(view, &rec);
8946 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8949 MsiCloseHandle(view);
8951 query = "CREATE TABLE `Z` ( `B` SHORT NOT NULL, `C` SHORT NOT NULL, "
8952 "`A` CHAR(255), `E` INT, `D` CHAR(255) NOT NULL "
8953 "PRIMARY KEY `C`, `A`, `D`)";
8954 r = run_query(hdb, 0, query);
8955 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8957 query = "SELECT * FROM `Z`";
8958 r = MsiDatabaseOpenView(hdb, query, &view);
8959 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8961 r = MsiViewGetColumnInfo(view, MSICOLINFO_TYPES, &rec);
8962 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8965 lstrcpyA(buf, "kiwi");
8966 r = MsiRecordGetString(rec, 1, buf, &sz);
8967 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8968 ok(!lstrcmpA("i2", buf), "Expected \"i2\", got \"%s\"\n", buf);
8971 lstrcpyA(buf, "kiwi");
8972 r = MsiRecordGetString(rec, 2, buf, &sz);
8973 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8974 ok(!lstrcmpA("S255", buf), "Expected \"S255\", got \"%s\"\n", buf);
8977 lstrcpyA(buf, "kiwi");
8978 r = MsiRecordGetString(rec, 3, buf, &sz);
8979 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8980 ok(!lstrcmpA("s255", buf), "Expected \"s255\", got \"%s\"\n", buf);
8983 lstrcpyA(buf, "kiwi");
8984 r = MsiRecordGetString(rec, 4, buf, &sz);
8985 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8986 ok(!lstrcmpA("I2", buf), "Expected \"I2\", got \"%s\"\n", buf);
8989 lstrcpyA(buf, "kiwi");
8990 r = MsiRecordGetString(rec, 5, buf, &sz);
8991 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8992 ok(!lstrcmpA("i2", buf), "Expected \"i2\", got \"%s\"\n", buf);
8994 MsiCloseHandle(rec);
8996 r = MsiViewGetColumnInfo(view, MSICOLINFO_NAMES, &rec);
8997 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9000 lstrcpyA(buf, "kiwi");
9001 r = MsiRecordGetString(rec, 1, buf, &sz);
9002 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9003 ok(!lstrcmpA("C", buf), "Expected \"C\", got \"%s\"\n", buf);
9006 lstrcpyA(buf, "kiwi");
9007 r = MsiRecordGetString(rec, 2, buf, &sz);
9008 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9009 ok(!lstrcmpA("A", buf), "Expected \"A\", got \"%s\"\n", buf);
9012 lstrcpyA(buf, "kiwi");
9013 r = MsiRecordGetString(rec, 3, buf, &sz);
9014 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9015 ok(!lstrcmpA("D", buf), "Expected \"D\", got \"%s\"\n", buf);
9018 lstrcpyA(buf, "kiwi");
9019 r = MsiRecordGetString(rec, 4, buf, &sz);
9020 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9021 ok(!lstrcmpA("E", buf), "Expected \"E\", got \"%s\"\n", buf);
9024 lstrcpyA(buf, "kiwi");
9025 r = MsiRecordGetString(rec, 5, buf, &sz);
9026 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9027 ok(!lstrcmpA("B", buf), "Expected \"B\", got \"%s\"\n", buf);
9029 MsiCloseHandle(rec);
9031 MsiCloseHandle(view);
9033 query = "INSERT INTO `Z` ( `B`, `C`, `A`, `E`, `D` ) "
9034 "VALUES ( 1, 2, 'a', 3, 'bc' )";
9035 r = run_query(hdb, 0, query);
9036 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9038 query = "SELECT * FROM `Z`";
9039 r = do_query(hdb, query, &rec);
9040 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9042 r = MsiRecordGetInteger(rec, 1);
9043 ok(r == 2, "Expected 2, got %d\n", r);
9046 lstrcpyA(buf, "kiwi");
9047 r = MsiRecordGetString(rec, 2, buf, &sz);
9048 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9049 ok(!lstrcmpA("a", buf), "Expected \"a\", got \"%s\"\n", buf);
9052 lstrcpyA(buf, "kiwi");
9053 r = MsiRecordGetString(rec, 3, buf, &sz);
9054 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9055 ok(!lstrcmpA("bc", buf), "Expected \"bc\", got \"%s\"\n", buf);
9057 r = MsiRecordGetInteger(rec, 4);
9058 ok(r == 3, "Expected 3, got %d\n", r);
9060 r = MsiRecordGetInteger(rec, 5);
9061 ok(r == 1, "Expected 1, got %d\n", r);
9063 MsiCloseHandle(rec);
9065 query = "SELECT * FROM `_Columns` WHERE `Table` = 'T'";
9066 r = MsiDatabaseOpenView(hdb, query, &view);
9067 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9068 r = MsiViewExecute(view, 0);
9069 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9071 r = MsiViewFetch(view, &rec);
9072 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9075 lstrcpyA(buf, "kiwi");
9076 r = MsiRecordGetString(rec, 1, buf, &sz);
9077 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9078 ok(!lstrcmpA("T", buf), "Expected \"T\", got \"%s\"\n", buf);
9080 r = MsiRecordGetInteger(rec, 2);
9081 ok(r == 1, "Expected 1, got %d\n", r);
9084 lstrcpyA(buf, "kiwi");
9085 r = MsiRecordGetString(rec, 3, buf, &sz);
9086 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9087 ok(!lstrcmpA("D", buf), "Expected \"D\", got \"%s\"\n", buf);
9089 MsiCloseHandle(rec);
9091 r = MsiViewFetch(view, &rec);
9092 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9095 lstrcpyA(buf, "kiwi");
9096 r = MsiRecordGetString(rec, 1, buf, &sz);
9097 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9098 ok(!lstrcmpA("T", buf), "Expected \"T\", got \"%s\"\n", buf);
9100 r = MsiRecordGetInteger(rec, 2);
9101 ok(r == 2, "Expected 2, got %d\n", r);
9104 lstrcpyA(buf, "kiwi");
9105 r = MsiRecordGetString(rec, 3, buf, &sz);
9106 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9107 ok(!lstrcmpA("E", buf), "Expected \"E\", got \"%s\"\n", buf);
9109 MsiCloseHandle(rec);
9111 r = MsiViewFetch(view, &rec);
9112 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9115 lstrcpyA(buf, "kiwi");
9116 r = MsiRecordGetString(rec, 1, buf, &sz);
9117 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9118 ok(!lstrcmpA("T", buf), "Expected \"T\", got \"%s\"\n", buf);
9120 r = MsiRecordGetInteger(rec, 2);
9121 ok(r == 3, "Expected 3, got %d\n", r);
9124 lstrcpyA(buf, "kiwi");
9125 r = MsiRecordGetString(rec, 3, buf, &sz);
9126 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9127 ok(!lstrcmpA("A", buf), "Expected \"A\", got \"%s\"\n", buf);
9129 MsiCloseHandle(rec);
9131 r = MsiViewFetch(view, &rec);
9132 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9135 lstrcpyA(buf, "kiwi");
9136 r = MsiRecordGetString(rec, 1, buf, &sz);
9137 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9138 ok(!lstrcmpA("T", buf), "Expected \"T\", got \"%s\"\n", buf);
9140 r = MsiRecordGetInteger(rec, 2);
9141 ok(r == 4, "Expected 4, got %d\n", r);
9144 lstrcpyA(buf, "kiwi");
9145 r = MsiRecordGetString(rec, 3, buf, &sz);
9146 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9147 ok(!lstrcmpA("C", buf), "Expected \"C\", got \"%s\"\n", buf);
9149 MsiCloseHandle(rec);
9151 r = MsiViewFetch(view, &rec);
9152 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9155 lstrcpyA(buf, "kiwi");
9156 r = MsiRecordGetString(rec, 1, buf, &sz);
9157 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9158 ok(!lstrcmpA("T", buf), "Expected \"T\", got \"%s\"\n", buf);
9160 r = MsiRecordGetInteger(rec, 2);
9161 ok(r == 5, "Expected 5, got %d\n", r);
9164 lstrcpyA(buf, "kiwi");
9165 r = MsiRecordGetString(rec, 3, buf, &sz);
9166 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9167 ok(!lstrcmpA("B", buf), "Expected \"B\", got \"%s\"\n", buf);
9169 MsiCloseHandle(rec);
9171 r = MsiViewFetch(view, &rec);
9172 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9175 MsiCloseHandle(view);
9177 MsiCloseHandle(hdb);
9178 DeleteFileA(msifile);
9181 static void test_createtable(void)
9183 MSIHANDLE hdb, htab = 0, hrec = 0;
9190 ok(hdb, "failed to create db\n");
9192 query = "CREATE TABLE `blah` (`foo` CHAR(72) NOT NULL PRIMARY KEY `foo`)";
9193 res = MsiDatabaseOpenView( hdb, query, &htab );
9194 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9195 if(res == ERROR_SUCCESS )
9197 res = MsiViewExecute( htab, hrec );
9198 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9200 res = MsiViewGetColumnInfo( htab, MSICOLINFO_NAMES, &hrec );
9201 todo_wine ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9203 size = sizeof(buffer);
9204 res = MsiRecordGetString(hrec, 1, buffer, &size );
9205 todo_wine ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9206 MsiCloseHandle( hrec );
9208 res = MsiViewClose( htab );
9209 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9211 res = MsiCloseHandle( htab );
9212 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9215 query = "CREATE TABLE `a` (`b` INT PRIMARY KEY `b`)";
9216 res = MsiDatabaseOpenView( hdb, query, &htab );
9217 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9218 if(res == ERROR_SUCCESS )
9220 res = MsiViewExecute( htab, 0 );
9221 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9223 res = MsiViewClose( htab );
9224 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9226 res = MsiCloseHandle( htab );
9227 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9229 query = "SELECT * FROM `a`";
9230 res = MsiDatabaseOpenView( hdb, query, &htab );
9231 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9233 res = MsiViewGetColumnInfo( htab, MSICOLINFO_NAMES, &hrec );
9234 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9237 size = sizeof(buffer);
9238 res = MsiRecordGetString(hrec, 1, buffer, &size );
9239 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9240 ok(!strcmp(buffer,"b"), "b != %s\n", buffer);
9241 MsiCloseHandle( hrec );
9243 res = MsiViewClose( htab );
9244 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9246 res = MsiCloseHandle( htab );
9247 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9249 res = MsiDatabaseCommit(hdb);
9250 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9252 res = MsiCloseHandle(hdb);
9253 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9255 res = MsiOpenDatabase(msifile, MSIDBOPEN_TRANSACT, &hdb );
9256 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9258 query = "SELECT * FROM `a`";
9259 res = MsiDatabaseOpenView( hdb, query, &htab );
9260 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9262 res = MsiViewGetColumnInfo( htab, MSICOLINFO_NAMES, &hrec );
9263 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9266 size = sizeof(buffer);
9267 res = MsiRecordGetString(hrec, 1, buffer, &size );
9268 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9269 todo_wine ok(!strcmp(buffer,"b"), "b != %s\n", buffer);
9271 res = MsiCloseHandle( hrec );
9272 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9274 res = MsiViewClose( htab );
9275 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9277 res = MsiCloseHandle( htab );
9278 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9281 res = MsiDatabaseCommit(hdb);
9282 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9284 res = MsiCloseHandle(hdb);
9285 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9287 DeleteFileA(msifile);
9290 static void test_embedded_nulls(void)
9292 static const char control_table[] =
9296 "LicenseAgreementDlg\ttext\x11\x19text\0text";
9298 MSIHANDLE hdb, hrec;
9301 r = MsiOpenDatabaseA( msifile, MSIDBOPEN_CREATE, &hdb );
9302 ok( r == ERROR_SUCCESS, "failed to open database %u\n", r );
9304 GetCurrentDirectoryA( MAX_PATH, CURR_DIR );
9305 write_file( "temp_file", control_table, sizeof(control_table) );
9306 r = MsiDatabaseImportA( hdb, CURR_DIR, "temp_file" );
9307 ok( r == ERROR_SUCCESS, "failed to import table %u\n", r );
9308 DeleteFileA( "temp_file" );
9310 r = do_query( hdb, "SELECT `Text` FROM `Control` WHERE `Dialog` = 'LicenseAgreementDlg'", &hrec );
9311 ok( r == ERROR_SUCCESS, "query failed %u\n", r );
9314 sz = sizeof(buffer);
9315 r = MsiRecordGetStringA( hrec, 1, buffer, &sz );
9316 ok( r == ERROR_SUCCESS, "failed to get string %u\n", r );
9317 ok( !memcmp( "text\r\ntext\ntext", buffer, sizeof("text\r\ntext\ntext") - 1 ), "wrong buffer contents \"%s\"\n", buffer );
9319 MsiCloseHandle( hrec );
9320 MsiCloseHandle( hdb );
9321 DeleteFileA( msifile );
9328 test_msidecomposedesc();
9329 test_msibadqueries();
9331 test_viewgetcolumninfo();
9337 test_where_not_in_selected();
9340 test_binary_import();
9342 test_handle_limit();
9343 test_try_transform();
9345 test_temporary_table();
9349 test_special_tables();
9350 test_tables_order();
9352 test_select_markers();
9353 test_viewmodify_update();
9354 test_viewmodify_assign();
9356 test_viewmodify_delete();
9357 test_defaultdatabase();
9359 test_viewmodify_delete_temporary();
9362 test_carriagereturn();
9364 test_forcecodepage();
9365 test_viewmodify_refresh();
9366 test_where_viewmodify();
9367 test_storages_table();
9371 test_select_with_tablenames();
9374 test_suminfo_import();
9377 test_embedded_nulls();